Skip to content

Commit ee9febe

Browse files
committed
Handle nested calls and function oneliners when chaining
1 parent 15a70f8 commit ee9febe

File tree

3 files changed

+56
-16
lines changed

3 files changed

+56
-16
lines changed

lib/coffee-script/rewriter.js

+23-7
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/rewriter.coffee

+16-5
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,10 @@ class exports.Rewriter
159159
tokens.splice i, 0, generate 'CALL_END', ')'
160160
i += 1
161161

162+
endAllImplicitCalls = ->
163+
while inImplicitCall()
164+
endImplicitCall()
165+
162166
startImplicitObject = (j, startsLine = yes) ->
163167
idx = j ? i
164168
stack.push ['{', idx, sameLine: yes, startsLine: startsLine, ours: yes]
@@ -281,10 +285,13 @@ class exports.Rewriter
281285
# .g b
282286
# .h a
283287
#
284-
if (prevTag is 'OUTDENT' or prevToken.newLine) and inImplicitCall() and
285-
tag in ['.', '?.', '::', '?::']
286-
endImplicitCall()
287-
return forward(1)
288+
if inImplicitCall() and tag in CALL_CLOSERS
289+
if prevTag is 'OUTDENT'
290+
endImplicitCall()
291+
return forward(1)
292+
if prevToken.newLine
293+
endAllImplicitCalls()
294+
return forward(1)
288295

289296
stackTop()[2].sameLine = no if inImplicitObject() and tag in LINEBREAKS
290297

@@ -363,7 +370,8 @@ class exports.Rewriter
363370
token[1] isnt ';' and token[0] in SINGLE_CLOSERS and
364371
not (token[0] is 'TERMINATOR' and @tag(i + 1) in EXPRESSION_CLOSE) and
365372
not (token[0] is 'ELSE' and starter isnt 'THEN') and
366-
not (token[0] in ['CATCH', 'FINALLY'] and starter in ['->', '=>'])
373+
not (token[0] in ['CATCH', 'FINALLY'] and starter in ['->', '=>']) or
374+
token[0] in CALL_CLOSERS and @tokens[i - 1].newLine
367375

368376
action = (token, i) ->
369377
@tokens.splice (if @tag(i - 1) is ',' then i - 1 else i), 0, outdent
@@ -478,3 +486,6 @@ SINGLE_CLOSERS = ['TERMINATOR', 'CATCH', 'FINALLY', 'ELSE', 'OUTDENT', 'LEADIN
478486

479487
# Tokens that end a line.
480488
LINEBREAKS = ['TERMINATOR', 'INDENT', 'OUTDENT']
489+
490+
# Tokens that close open calls when they follow a newline.
491+
CALL_CLOSERS = ['.', '?.', '::', '?::']

test/formatting.coffee

+17-4
Original file line numberDiff line numberDiff line change
@@ -78,11 +78,24 @@ test "#1495, method call chaining", ->
7878
'aaabbbccc'.replace /(\w)\1\1/g, '$1$1'
7979
.replace /([abc])\1/g, '$1'
8080

81-
# Unreadable code, not a real-life use case
82-
result = str.split ''.
81+
# Nested calls
82+
result = [1..3]
83+
.slice Math.max 0, 1
84+
.concat [3]
85+
arrayEq result, [2, 3, 3]
86+
87+
# Single line function arguments.
88+
result = [1..6]
89+
.map (x) -> x * x
90+
.filter (x) -> x % 2 is 0
91+
.reverse()
92+
arrayEq result, [36, 16, 4]
93+
94+
# The parens are forced
95+
result = str.split(''.
8396
split ''
84-
.join('')
85-
.join ', '
97+
.join ''
98+
).join ', '
8699
eq 'a, b, c', result
87100

88101
# Operators

0 commit comments

Comments
 (0)