New implementation of Rewriter#addImplicitBraces -- uses detectEnd..
This commit is contained in:
parent
0231f8da1b
commit
d0b918e083
|
@ -47,9 +47,12 @@
|
|||
if (!(token = this.tokens[i])) {
|
||||
break;
|
||||
}
|
||||
if (!levels && condition(token, i)) {
|
||||
if (levels === 0 && condition(token, i)) {
|
||||
return action(token, i);
|
||||
}
|
||||
if (levels < 0) {
|
||||
return action(token, i - 1);
|
||||
}
|
||||
if (include(EXPRESSION_START, token[0])) {
|
||||
levels += 1;
|
||||
}
|
||||
|
@ -104,14 +107,14 @@
|
|||
Rewriter.prototype.closeOpenCalls = function() {
|
||||
return this.scanTokens(__bind(function(prev, token, post, i) {
|
||||
var action, condition;
|
||||
condition = function(token, i) {
|
||||
var _c;
|
||||
return (')' === (_c = token[0]) || 'CALL_END' === _c);
|
||||
};
|
||||
action = function(token, i) {
|
||||
return (token[0] = 'CALL_END');
|
||||
};
|
||||
if (token[0] === 'CALL_START') {
|
||||
condition = function(token, i) {
|
||||
var _c;
|
||||
return (')' === (_c = token[0]) || 'CALL_END' === _c);
|
||||
};
|
||||
action = function(token, i) {
|
||||
return (token[0] = 'CALL_END');
|
||||
};
|
||||
this.detectEnd(i + 1, condition, action);
|
||||
}
|
||||
return 1;
|
||||
|
@ -120,68 +123,44 @@
|
|||
Rewriter.prototype.closeOpenIndexes = function() {
|
||||
return this.scanTokens(__bind(function(prev, token, post, i) {
|
||||
var action, condition;
|
||||
condition = function(token, i) {
|
||||
var _c;
|
||||
return (']' === (_c = token[0]) || 'INDEX_END' === _c);
|
||||
};
|
||||
action = function(token, i) {
|
||||
return (token[0] = 'INDEX_END');
|
||||
};
|
||||
if (token[0] === 'INDEX_START') {
|
||||
condition = function(token, i) {
|
||||
var _c;
|
||||
return (']' === (_c = token[0]) || 'INDEX_END' === _c);
|
||||
};
|
||||
action = function(token, i) {
|
||||
return (token[0] = 'INDEX_END');
|
||||
};
|
||||
this.detectEnd(i + 1, condition, action);
|
||||
}
|
||||
return 1;
|
||||
}, this));
|
||||
};
|
||||
Rewriter.prototype.addImplicitBraces = function() {
|
||||
var closeBrackets, running, stack;
|
||||
stack = [0];
|
||||
running = false;
|
||||
closeBrackets = __bind(function(i) {
|
||||
var _c, len, size, tmp;
|
||||
len = stack.length - 1;
|
||||
_c = stack[len];
|
||||
for (tmp = 0; (0 <= _c ? tmp < _c : tmp > _c); (0 <= _c ? tmp += 1 : tmp -= 1)) {
|
||||
this.tokens.splice(i, 0, ['}', '}', this.tokens[i][2]]);
|
||||
}
|
||||
size = stack[len] + 1;
|
||||
stack[len] = 0;
|
||||
return size;
|
||||
}, this);
|
||||
var stack;
|
||||
stack = [];
|
||||
return this.scanTokens(__bind(function(prev, token, post, i) {
|
||||
var _c, after, before, idx, len, open, size, tag;
|
||||
tag = token[0];
|
||||
len = stack.length - 1;
|
||||
var action, before, condition, idx, last;
|
||||
include(EXPRESSION_START, token[0]) ? stack.push((token[0] === 'INDENT' && (prev && prev[0] === '{')) ? '{' : token[0]) : null;
|
||||
include(EXPRESSION_END, token[0]) ? stack.pop() : null;
|
||||
last = stack[stack.length - 1];
|
||||
before = this.tokens[i - 2];
|
||||
after = this.tokens[i + 2];
|
||||
open = stack[len] > 0;
|
||||
if ((tag === 'TERMINATOR' && !((after && after[0] === ':') || (post && post[0] === '@' && this.tokens[i + 3] && this.tokens[i + 3][0] === ':'))) || (running && tag === ',' && post && (!('IDENTIFIER' === (_c = post[0]) || 'STRING' === _c || '@' === _c || 'TERMINATOR' === _c)))) {
|
||||
running = false;
|
||||
return closeBrackets(post && post[0] === 'OUTDENT' ? i + 1 : i);
|
||||
} else if (include(EXPRESSION_START, tag)) {
|
||||
stack.push(tag === '{' ? 1 : 0);
|
||||
if (tag === '{' && post && post[0] === 'INDENT') {
|
||||
return 2;
|
||||
}
|
||||
} else if (include(EXPRESSION_END, tag)) {
|
||||
if (tag === 'OUTDENT' && post && post[0] === '}') {
|
||||
return 1;
|
||||
}
|
||||
if (tag === 'OUTDENT') {
|
||||
size = closeBrackets(i);
|
||||
}
|
||||
stack[len - 1] += stack.pop();
|
||||
if (tag === '}') {
|
||||
stack[len - 1] -= 1;
|
||||
}
|
||||
if (tag === 'OUTDENT') {
|
||||
return size;
|
||||
}
|
||||
} else if (tag === ':' && !open) {
|
||||
idx = before && before[0] === '@' ? i - 2 : i - 1;
|
||||
if (token[0] === ':' && (!last || last[0] !== '{')) {
|
||||
stack.push('{');
|
||||
idx = before[0] === '@' ? i - 2 : i - 1;
|
||||
this.tokens.splice(idx, 0, ['{', '{', token[2]]);
|
||||
stack[stack.length - 1] += 1;
|
||||
running = true;
|
||||
condition = __bind(function(token, i) {
|
||||
var _c, _d, _e, one, three, two;
|
||||
_c = this.tokens.slice(i + 1, i + 4);
|
||||
one = _c[0];
|
||||
two = _c[1];
|
||||
three = _c[2];
|
||||
return ((('TERMINATOR' === (_d = token[0]) || 'OUTDENT' === _d)) && !((two && two[0] === ':') || (one && one[0] === '@' && three && three[0] === ':'))) || (token[0] === ',' && one && (!('IDENTIFIER' === (_e = one[0]) || 'STRING' === _e || '@' === _e || 'TERMINATOR' === _e || 'OUTDENT' === _e)));
|
||||
}, this);
|
||||
action = __bind(function(token, i) {
|
||||
return this.tokens.splice(i, 0, ['}', '}', token[2]]);
|
||||
}, this);
|
||||
this.detectEnd(i + 2, condition, action);
|
||||
return 2;
|
||||
}
|
||||
return 1;
|
||||
|
|
|
@ -58,7 +58,8 @@ exports.Rewriter = class Rewriter
|
|||
levels = 0
|
||||
loop
|
||||
break unless token = @tokens[i]
|
||||
return action token, i if !levels and condition token, i
|
||||
return action token, i if levels is 0 and condition token, i
|
||||
return action token, i - 1 if levels < 0
|
||||
levels += 1 if include EXPRESSION_START, token[0]
|
||||
levels -= 1 if include EXPRESSION_END, token[0]
|
||||
i += 1
|
||||
|
@ -103,56 +104,44 @@ exports.Rewriter = class Rewriter
|
|||
# its paired close.
|
||||
closeOpenCalls: ->
|
||||
@scanTokens (prev, token, post, i) =>
|
||||
condition = (token, i) -> token[0] in [')', 'CALL_END']
|
||||
action = (token, i) -> token[0] = 'CALL_END'
|
||||
@detectEnd(i + 1, condition, action) if token[0] is 'CALL_START'
|
||||
if token[0] is 'CALL_START'
|
||||
condition = (token, i) -> token[0] in [')', 'CALL_END']
|
||||
action = (token, i) -> token[0] = 'CALL_END'
|
||||
@detectEnd i + 1, condition, action
|
||||
return 1
|
||||
|
||||
# The lexer has tagged the opening parenthesis of an indexing operation call.
|
||||
# Match it with its paired close.
|
||||
closeOpenIndexes: ->
|
||||
@scanTokens (prev, token, post, i) =>
|
||||
condition = (token, i) -> token[0] in [']', 'INDEX_END']
|
||||
action = (token, i) -> token[0] = 'INDEX_END'
|
||||
@detectEnd(i + 1, condition, action) if token[0] is 'INDEX_START'
|
||||
if token[0] is 'INDEX_START'
|
||||
condition = (token, i) -> token[0] in [']', 'INDEX_END']
|
||||
action = (token, i) -> token[0] = 'INDEX_END'
|
||||
@detectEnd i + 1, condition, action
|
||||
return 1
|
||||
|
||||
# Object literals may be written with implicit braces, for simple cases.
|
||||
# Insert the missing braces here, so that the parser doesn't have to.
|
||||
addImplicitBraces: ->
|
||||
stack = [0]
|
||||
running = no
|
||||
closeBrackets = (i) =>
|
||||
len = stack.length - 1
|
||||
for tmp in [0...stack[len]]
|
||||
@tokens.splice(i, 0, ['}', '}', @tokens[i][2]])
|
||||
size = stack[len] + 1
|
||||
stack[len] = 0
|
||||
size
|
||||
stack = []
|
||||
@scanTokens (prev, token, post, i) =>
|
||||
tag = token[0]
|
||||
len = stack.length - 1
|
||||
if include EXPRESSION_START, token[0]
|
||||
stack.push(if (token[0] is 'INDENT' and (prev and prev[0] is '{')) then '{' else token[0])
|
||||
if include EXPRESSION_END, token[0]
|
||||
stack.pop()
|
||||
last = stack[stack.length - 1]
|
||||
before = @tokens[i - 2]
|
||||
after = @tokens[i + 2]
|
||||
open = stack[len] > 0
|
||||
if (tag is 'TERMINATOR' and not ((after and after[0] is ':') or (post and post[0] is '@' and @tokens[i + 3] and @tokens[i + 3][0] is ':'))) or
|
||||
(running and tag is ',' and post and (post[0] not in ['IDENTIFIER', 'STRING', '@', 'TERMINATOR']))
|
||||
running = no
|
||||
return closeBrackets(if post and post[0] is 'OUTDENT' then i + 1 else i)
|
||||
else if include EXPRESSION_START, tag
|
||||
stack.push(if tag is '{' then 1 else 0)
|
||||
return 2 if tag is '{' and post and post[0] is 'INDENT'
|
||||
else if include EXPRESSION_END, tag
|
||||
return 1 if tag is 'OUTDENT' and post and post[0] is '}'
|
||||
size = closeBrackets(i) if tag is 'OUTDENT'
|
||||
stack[len - 1] += stack.pop()
|
||||
stack[len - 1] -= 1 if tag is '}'
|
||||
return size if tag is 'OUTDENT'
|
||||
else if tag is ':' and not open
|
||||
idx = if before and before[0] is '@' then i - 2 else i - 1
|
||||
if token[0] is ':' and (not last or last[0] isnt '{')
|
||||
stack.push '{'
|
||||
idx = if before[0] is '@' then i - 2 else i - 1
|
||||
@tokens.splice idx, 0, ['{', '{', token[2]]
|
||||
stack[stack.length - 1] += 1
|
||||
running = yes
|
||||
condition = (token, i) =>
|
||||
[one, two, three] = @tokens.slice(i + 1, i + 4)
|
||||
((token[0] in ['TERMINATOR', 'OUTDENT']) and not ((two and two[0] is ':') or (one and one[0] is '@' and three and three[0] is ':'))) or
|
||||
(token[0] is ',' and one and (one[0] not in ['IDENTIFIER', 'STRING', '@', 'TERMINATOR', 'OUTDENT']))
|
||||
action = (token, i) =>
|
||||
@tokens.splice i, 0, ['}', '}', token[2]]
|
||||
@detectEnd i + 2, condition, action
|
||||
return 2
|
||||
return 1
|
||||
|
||||
|
|
Loading…
Reference in New Issue