in Ox.doc, simplify and speed up parseTokens()

This commit is contained in:
rolux 2012-05-30 19:19:51 +02:00
parent af6c58bcaa
commit e9fb83c578

View file

@ -195,13 +195,12 @@ Ox.doc = (function() {
}
});
blocks.forEach(function(block, i) {
var item, lastItem,
var item, lastItem, lastToken,
lines = block
.replace(re.script, encodeLinebreaks)
.replace(re.test, encodeLinebreaks)
.split('\n'),
parent,
tree = parseTree(lines);
parent, tree = parseTree(lines);
if (re.item.test(tree.line)) {
// parse the tree's root node
item = parseNode(tree);
@ -211,13 +210,13 @@ Ox.doc = (function() {
}
if (/^[A-Z]/.test(item.name)) {
// main item
// include leading whitespace
// remove leading linebreaks and whitespace
item.source = parseTokens(tokens[i]);
item.line = item.source[0].line;
items.push(item);
} else {
// property of a function item
lastItem = items[items.length - 1];
// property of an item
lastItem = Ox.last(items);
parent = lastItem.types[0] == 'function'
&& lastItem.returns
&& lastItem.returns[0].types[0] == 'object'
@ -229,8 +228,16 @@ Ox.doc = (function() {
) {
parent.order.push('properties');
}
// include leading linebreaks and whitespace
// add a linebreak, and the property's source without
// leading whitespace, to the last item's source
lastToken = Ox.last(lastItem.source);
lastItem.source = lastItem.source.concat(
{
column: lastToken.column + lastToken.value.length,
line: lastToken.line,
type: 'linebreak',
value: '\n'
},
parseTokens(tokens[i], true)
);
}
@ -248,36 +255,31 @@ Ox.doc = (function() {
expected: lines[1].trim()
};
}
function parseTokens(tokens, includeLeadingLinebreaks) {
var isLeading = true,
isTrailing = false,
tokens_ = [],
function parseTokens(tokens, includeLeading) {
// removes leading and trailing linebreaks and whitespace
var start = 0, stop = tokens.length,
types = ['linebreak', 'whitespace'];
tokens.forEach(function(token) {
if (isLeading && types.indexOf(token.type) > -1) {
if (token.type == 'linebreak') {
if (includeLeadingLinebreaks) {
tokens_.push(token);
} else {
tokens_ = [];
}
} else {
tokens_.push(token);
}
} else {
tokens_.push(token);
isLeading = false;
if (types.indexOf(token.type) == -1) {
isTrailing = true;
}
if (includeLeading) {
// for properties, whose tokens belong to the main item, we only
// remove leading whitespace
while (tokens[start].type == 'whitespace') {
start++;
}
});
if (isTrailing) {
while (types.indexOf(tokens_[tokens_.length - 1].type) > -1) {
tokens_.pop();
} else {
// remove leading linebreaks and whitespace
while (types.indexOf(tokens[start].type) > -1) {
start++;
}
// but keep leading whitespace in the first significant line
while (start && tokens[start - 1].type == 'whitespace') {
start--;
}
}
return tokens_;
// remove trailing linebreaks and whitespace
while (stop > start && types.indexOf(tokens[stop - 1].type) > -1) {
stop--;
}
return tokens.slice(start, stop);
}
function parseTree(lines) {
// parses indented lines into a tree structure, like