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