diff --git a/lib/rewriter.js b/lib/rewriter.js index 86cecec1..ee9e3042 100644 --- a/lib/rewriter.js +++ b/lib/rewriter.js @@ -138,7 +138,7 @@ }); }; exports.Rewriter.prototype.addImplicitBraces = function() { - var action, condition, stack; + var action, condition, stack, start; stack = []; condition = function(token, i) { var _ref, _ref2, one, tag, three, two; @@ -147,26 +147,27 @@ } _ref = this.tokens.slice(i + 1, i + 4), one = _ref[0], two = _ref[1], three = _ref[2]; tag = token[0]; - return (tag === 'TERMINATOR' || tag === 'OUTDENT') && !((two != null ? two[0] : undefined) === ':' || (one != null ? one[0] : undefined) === '@' && (three != null ? three[0] : undefined) === ':') || tag === ',' && ((_ref2 = one != null ? one[0] : undefined) !== 'IDENTIFIER' && _ref2 !== 'NUMBER' && _ref2 !== 'STRING' && _ref2 !== '@' && _ref2 !== 'TERMINATOR' && _ref2 !== 'OUTDENT'); + return (tag === 'TERMINATOR' || tag === 'OUTDENT') && !((two != null ? two[0] : undefined) === ':' || (one != null ? one[0] : undefined) === '@' && (three != null ? three[0] : undefined) === ':' || (one != null ? one[0] : undefined) === '(') || tag === ',' && one && ((_ref2 = one[0]) !== 'IDENTIFIER' && _ref2 !== 'NUMBER' && _ref2 !== 'STRING' && _ref2 !== '@' && _ref2 !== 'TERMINATOR' && _ref2 !== 'OUTDENT' && _ref2 !== '('); }; action = function(token, i) { return this.tokens.splice(i, 0, ['}', '}', token[2]]); }; + start = null; return this.scanTokens(function(token, i, tokens) { - var _ref, idx, tag, tok; + var _ref, _ref2, idx, tag, tok; if (_ref = (tag = token[0]), __indexOf.call(EXPRESSION_START, _ref) >= 0) { - stack.push(tag === 'INDENT' && this.tag(i - 1) === '{' ? '{' : tag); + stack.push([(tag === 'INDENT' && this.tag(i - 1) === '{' ? '{' : tag), i]); return 1; } if (__indexOf.call(EXPRESSION_END, tag) >= 0) { - stack.pop(); + start = stack.pop(); return 1; } - if (!(tag === ':' && stack[stack.length - 1] !== '{')) { + if (!(tag === ':' && ((_ref2 = stack[stack.length - 1]) != null ? _ref2[0] : undefined) !== '{')) { return 1; } - stack.push('{'); - idx = this.tag(i - 2) === '@' ? i - 2 : i - 1; + stack.push(['{']); + idx = this.tag(i - 1) === ')' ? start[1] : this.tag(i - 2) === '@' ? i - 2 : i - 1; if (this.tag(idx - 2) === 'HERECOMMENT') { idx -= 2; } diff --git a/src/rewriter.coffee b/src/rewriter.coffee index 501653cf..dbe6bb8e 100644 --- a/src/rewriter.coffee +++ b/src/rewriter.coffee @@ -124,19 +124,27 @@ class exports.Rewriter return false if 'HERECOMMENT' in [@tag(i + 1), @tag(i - 1)] [one, two, three] = @tokens.slice i + 1, i + 4 [tag] = token - tag in ['TERMINATOR', 'OUTDENT'] and not (two?[0] is ':' or one?[0] is '@' and three?[0] is ':') or - tag is ',' and one?[0] not in ['IDENTIFIER', 'NUMBER', 'STRING', '@', 'TERMINATOR', 'OUTDENT'] + tag in ['TERMINATOR', 'OUTDENT'] and + not (two?[0] is ':' or one?[0] is '@' and three?[0] is ':' or one?[0] is '(') or + tag is ',' and one and + one[0] not in ['IDENTIFIER', 'NUMBER', 'STRING', '@', 'TERMINATOR', 'OUTDENT', '('] action = (token, i) -> @tokens.splice i, 0, ['}', '}', token[2]] + start = null @scanTokens (token, i, tokens) -> if (tag = token[0]) in EXPRESSION_START - stack.push if tag is 'INDENT' and @tag(i - 1) is '{' then '{' else tag + stack.push [(if tag is 'INDENT' and @tag(i - 1) is '{' then '{' else tag), i] return 1 if tag in EXPRESSION_END - stack.pop() + start = stack.pop() return 1 - return 1 unless tag is ':' and stack[stack.length - 1] isnt '{' - stack.push '{' - idx = if @tag(i - 2) is '@' then i - 2 else i - 1 + return 1 unless tag is ':' and stack[stack.length - 1]?[0] isnt '{' + stack.push ['{'] + idx = if @tag(i - 1) is ')' + start[1] + else if @tag(i - 2) is '@' + i - 2 + else + i - 1 idx -= 2 if @tag(idx - 2) is 'HERECOMMENT' tok = ['{', '{', token[2]] tok.generated = yes diff --git a/test/test_literals.coffee b/test/test_literals.coffee index c7010caf..5658a4b2 100644 --- a/test/test_literals.coffee +++ b/test/test_literals.coffee @@ -245,6 +245,9 @@ eq obj.interpolatedkey, 123 eq obj[8], 8 eq obj[1], 1 +eq 'braceless dynamic key', + (key for key of """braceless #{ 0 of ((0):(0)) and 'dynamic' } key""": 0)[0] + #542: Objects leading expression statement should be parenthesized. {f: -> ok yes }.f() + 1