diff --git a/lib/rewriter.js b/lib/rewriter.js index cb571dcb..6999fc88 100644 --- a/lib/rewriter.js +++ b/lib/rewriter.js @@ -1,5 +1,5 @@ (function() { - var BALANCED_PAIRS, EXPRESSION_CLOSE, EXPRESSION_END, EXPRESSION_START, IMPLICIT_BLOCK, IMPLICIT_CALL, IMPLICIT_END, IMPLICIT_FUNC, INVERSES, LINEBREAKS, SINGLE_CLOSERS, SINGLE_LINERS, _i, _len, _ref, include, left, rite; + var BALANCED_PAIRS, EXPRESSION_CLOSE, EXPRESSION_END, EXPRESSION_START, IMPLICIT_BLOCK, IMPLICIT_CALL, IMPLICIT_END, IMPLICIT_FUNC, IMPLICIT_UNSPACED_CALL, INVERSES, LINEBREAKS, SINGLE_CLOSERS, SINGLE_LINERS, _i, _len, _ref, include, left, rite; include = require('./helpers').include; exports.Rewriter = (function() { function Rewriter() { @@ -197,7 +197,7 @@ if (prev && !prev.spaced && tag === '?') { token.call = true; } - if (!(callObject || ((prev != null) ? prev.spaced : undefined) && (prev.call || include(IMPLICIT_FUNC, prev[0])) && include(IMPLICIT_CALL, tag))) { + if (!(callObject || ((prev != null) ? prev.spaced : undefined) && (prev.call || include(IMPLICIT_FUNC, prev[0])) && (include(IMPLICIT_CALL, tag) || include(IMPLICIT_UNSPACED_CALL, tag) && !token.spaced))) { return 1; } tokens.splice(i, 0, ['CALL_START', '(', token[2]]); @@ -368,7 +368,8 @@ } EXPRESSION_CLOSE = ['CATCH', 'WHEN', 'ELSE', 'FINALLY'].concat(EXPRESSION_END); IMPLICIT_FUNC = ['IDENTIFIER', 'SUPER', ')', 'CALL_END', ']', 'INDEX_END', '@', 'THIS']; - IMPLICIT_CALL = ['IDENTIFIER', 'NUMBER', 'STRING', 'JS', 'REGEX', 'NEW', 'PARAM_START', 'CLASS', 'IF', 'UNLESS', 'TRY', 'SWITCH', 'THIS', 'BOOL', 'UNARY', '@', '->', '=>', '[', '(', '{']; + IMPLICIT_CALL = ['IDENTIFIER', 'NUMBER', 'STRING', 'JS', 'REGEX', 'NEW', 'PARAM_START', 'CLASS', 'IF', 'UNLESS', 'TRY', 'SWITCH', 'THIS', 'BOOL', 'UNARY', '@', '->', '=>', '[', '(', '{', '--', '++']; + IMPLICIT_UNSPACED_CALL = ['+', '-']; IMPLICIT_BLOCK = ['->', '=>', '{', '[', ',']; IMPLICIT_END = ['POST_IF', 'POST_UNLESS', 'FOR', 'WHILE', 'UNTIL', 'LOOP', 'TERMINATOR', 'INDENT']; SINGLE_LINERS = ['ELSE', '->', '=>', 'TRY', 'FINALLY', 'THEN']; diff --git a/src/rewriter.coffee b/src/rewriter.coffee index 627ac515..5ea02984 100644 --- a/src/rewriter.coffee +++ b/src/rewriter.coffee @@ -168,7 +168,7 @@ class exports.Rewriter token.call = yes if prev and not prev.spaced and tag is '?' return 1 unless callObject or prev?.spaced and (prev.call or include(IMPLICIT_FUNC, prev[0])) and - include(IMPLICIT_CALL, tag) + (include(IMPLICIT_CALL, tag) or include(IMPLICIT_UNSPACED_CALL, tag) and not token.spaced) tokens.splice i, 0, ['CALL_START', '(', token[2]] @detectEnd i + (if callObject then 2 else 1), (token, i) -> return yes if not seenSingle and token.fromThen @@ -329,9 +329,11 @@ IMPLICIT_FUNC = ['IDENTIFIER', 'SUPER', ')', 'CALL_END', ']', 'INDEX_END', '@ IMPLICIT_CALL = [ 'IDENTIFIER', 'NUMBER', 'STRING', 'JS', 'REGEX', 'NEW', 'PARAM_START', 'CLASS' 'IF', 'UNLESS', 'TRY', 'SWITCH', 'THIS', 'BOOL', 'UNARY', - '@', '->', '=>', '[', '(', '{' + '@', '->', '=>', '[', '(', '{', '--', '++' ] +IMPLICIT_UNSPACED_CALL = ['+', '-'] + # Tokens indicating that the implicit call must enclose a block of expressions. IMPLICIT_BLOCK = ['->', '=>', '{', '[', ','] diff --git a/test/test_functions.coffee b/test/test_functions.coffee index 7bd3dd17..c39e6c0f 100644 --- a/test/test_functions.coffee +++ b/test/test_functions.coffee @@ -317,19 +317,30 @@ func = -> eq func(), 101 -#619: `new` shouldn't add extra parens +# `new` shouldn't add extra parens ok new Date().constructor is Date -#717: `new` works against bare function +# `new` works against bare function eq Date, new -> eq this, new => this Date -#751: Implicit objects with number arguments. +# Implicit objects with number arguments. func = (x, y) -> y obj = prop: func "a", 1 ok obj.prop is 1 + + +# Non-spaced unary and binary operators should cause a function call. +func = (val) -> val + 1 +ok (func +5) is 6 +ok (func -5) is -4 + + +# Prefix unary assignment operators are allowed in parenless calls. +val = 5 +ok (func --val) is 5