diff --git a/lib/coffee_script/rewriter.rb b/lib/coffee_script/rewriter.rb index ae1a62aa..3510a6f3 100644 --- a/lib/coffee_script/rewriter.rb +++ b/lib/coffee_script/rewriter.rb @@ -17,6 +17,10 @@ module CoffeeScript # Tokens that indicate the close of a clause of an expression. EXPRESSION_CLOSE = [:CATCH, :WHEN, :ELSE, :FINALLY] + EXPRESSION_TAIL + # Tokens that, when immediately following an identifier, activate an + # implicit method call. + IMPLICIT_CALL = [:IDENTIFIER, :NUMBER, :STRING, :JS, :REGEX] + # The inverse mappings of token pairs we're trying to fix up. INVERSES = BALANCED_PAIRS.inject({}) do |memo, pair| memo[pair.first] = pair.last @@ -39,6 +43,7 @@ module CoffeeScript remove_mid_expression_newlines move_commas_outside_outdents add_implicit_indentation + add_implicit_parentheses ensure_balance(*BALANCED_PAIRS) rewrite_closing_parens @tokens @@ -140,6 +145,24 @@ module CoffeeScript end end + # Methods may be optionally called without parentheses, for simple cases. + # Insert the implicit parentheses here, so that the parser doesn't have to + # deal with them. + def add_implicit_parentheses + open = false + scan_tokens do |prev, token, post, i| + if open && token[0] == "\n" + @tokens.insert(i, [')', Value.new(')', token[1].line)]) + open = false + next 2 + end + next 1 unless prev[0] == :IDENTIFIER && IMPLICIT_CALL.include?(token[0]) + @tokens.insert(i, ['(', Value.new('(', token[1].line)]) + open = true + next 2 + end + end + # Ensure that all listed pairs of tokens are correctly balanced throughout # the course of the token stream. def ensure_balance(*pairs) diff --git a/test/fixtures/execution/test_arguments.coffee b/test/fixtures/execution/test_arguments.coffee index ecaf118a..dcfb7d28 100644 --- a/test/fixtures/execution/test_arguments.coffee +++ b/test/fixtures/execution/test_arguments.coffee @@ -4,7 +4,7 @@ area: x, y, x1, y1 => x: y: 10 x1: y1: 20 -print(area(x, y, x1, y1) is 100) +print area(x, y, x1, y1) is 100 print(area(x, y, x1, y1) is 100) @@ -19,9 +19,9 @@ print(area( # Arguments are turned into arrays. curried: => - print(area.apply(this, arguments.concat(20, 20)) is 100) + print area.apply(this, arguments.concat(20, 20)) is 100 -curried(10, 10) +curried 10, 10 # Arguments is not a special keyword -- it can be assigned to: @@ -29,4 +29,4 @@ func: => arguments: 25 arguments -print(func(100) is 25) +print func(100) is 25 diff --git a/test/fixtures/execution/test_array_comprehension.coffee b/test/fixtures/execution/test_array_comprehension.coffee index 5eb6fa4b..b5005bd6 100644 --- a/test/fixtures/execution/test_array_comprehension.coffee +++ b/test/fixtures/execution/test_array_comprehension.coffee @@ -1,15 +1,15 @@ nums: n * n for n in [1, 2, 3] when n % 2 isnt 0 results: n * 2 for n in nums -print(results.join(',') is '2,18') +print results.join(',') is '2,18' obj: {one: 1, two: 2, three: 3} names: prop + '!' for prop of obj odds: prop + '!' for prop, value of obj when value % 2 isnt 0 -print(names.join(' ') is "one! two! three!") -print(odds.join(' ') is "one! three!") +print names.join(' ') is "one! two! three!" +print odds.join(' ') is "one! three!" evens: for num in [1, 2, 3, 4, 5, 6] when num % 2 is 0 @@ -17,12 +17,12 @@ evens: for num in [1, 2, 3, 4, 5, 6] when num % 2 is 0 num -= 2 num * -1 -print(evens.join(', ') is '4, 6, 8') +print evens.join(', ') is '4, 6, 8' # Make sure that the "in" operator still works. -print(2 in evens) +print 2 in evens # When functions are being defined within the body of a comprehension, make @@ -37,6 +37,6 @@ for method in methods obj[name]: => "I'm " + name -print(obj.one() is "I'm one") -print(obj.two() is "I'm two") -print(obj.three() is "I'm three") +print obj.one() is "I'm one" +print obj.two() is "I'm two" +print obj.three() is "I'm three" diff --git a/test/fixtures/execution/test_assignment.coffee b/test/fixtures/execution/test_assignment.coffee index 550f7d5c..c1b5d127 100644 --- a/test/fixtures/execution/test_assignment.coffee +++ b/test/fixtures/execution/test_assignment.coffee @@ -7,7 +7,7 @@ catch error result2: try nonexistent * missing catch error then true -print(result is true and result2 is true) +print result is true and result2 is true # Assign to conditional. @@ -16,8 +16,8 @@ get_x: => 10 if x: get_x() then 100 -print(x is 10) +print x is 10 x: if get_x() then 100 -print(x is 100) \ No newline at end of file +print x is 100 \ No newline at end of file