Skip to content

Commit 0853b41

Browse files
authored
Merge pull request #4296 from alangpierce/move-outdents-to-previous-token
Change OUTDENT tokens to be positioned at the end of the previous token
2 parents a75fe28 + 88693e4 commit 0853b41

File tree

3 files changed

+93
-0
lines changed

3 files changed

+93
-0
lines changed

lib/coffee-script/rewriter.js

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

src/rewriter.coffee

+16
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ class exports.Rewriter
3333
@tagPostfixConditionals()
3434
@addImplicitBracesAndParens()
3535
@addLocationDataToGeneratedTokens()
36+
@fixOutdentLocationData()
3637
@tokens
3738

3839
# Rewrite the token stream, looking one token ahead and behind.
@@ -368,6 +369,21 @@ class exports.Rewriter
368369
last_column: column
369370
return 1
370371

372+
# OUTDENT tokens should always be positioned at the last character of the
373+
# previous token, so that AST nodes ending in an OUTDENT token end up with a
374+
# location corresponding to the last "real" token under the node.
375+
fixOutdentLocationData: ->
376+
@scanTokens (token, i, tokens) ->
377+
return 1 unless token[0] is 'OUTDENT' or
378+
(token.generated and token[0] is 'CALL_END')
379+
prevLocationData = tokens[i - 1][2]
380+
token[2] =
381+
first_line: prevLocationData.last_line
382+
first_column: prevLocationData.last_column
383+
last_line: prevLocationData.last_line
384+
last_column: prevLocationData.last_column
385+
return 1
386+
371387
# Because our grammar is LALR(1), it can't handle some single-line
372388
# expressions that lack ending delimiters. The **Rewriter** adds the implicit
373389
# blocks, so it doesn't need to. To keep the grammar clean and tidy, trailing

test/location.coffee

+59
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,65 @@ test "Verify tokens have locations that are in order", ->
469469
ok token[2].first_column >= lastToken[2].last_column
470470
lastToken = token
471471

472+
test "Verify OUTDENT tokens are located at the end of the previous token", ->
473+
source = '''
474+
SomeArr = [ ->
475+
if something
476+
lol =
477+
count: 500
478+
]
479+
'''
480+
tokens = CoffeeScript.tokens source
481+
[..., number, curly, outdent1, outdent2, outdent3, bracket, terminator] = tokens
482+
eq number[0], 'NUMBER'
483+
for outdent in [outdent1, outdent2, outdent3]
484+
eq outdent[0], 'OUTDENT'
485+
eq outdent[2].first_line, number[2].last_line
486+
eq outdent[2].first_column, number[2].last_column
487+
eq outdent[2].last_line, number[2].last_line
488+
eq outdent[2].last_column, number[2].last_column
489+
490+
test "Verify OUTDENT and CALL_END tokens are located at the end of the previous token", ->
491+
source = '''
492+
a = b {
493+
c: ->
494+
d e,
495+
if f
496+
g {},
497+
if h
498+
i {}
499+
}
500+
'''
501+
tokens = CoffeeScript.tokens source
502+
[..., closeCurly1, callEnd1, outdent1, outdent2, callEnd2, outdent3, outdent4,
503+
callEnd3, outdent5, outdent6, closeCurly2, callEnd4, terminator] = tokens
504+
eq closeCurly1[0], '}'
505+
assertAtCloseCurly = (token) ->
506+
eq token[2].first_line, closeCurly1[2].last_line
507+
eq token[2].first_column, closeCurly1[2].last_column
508+
eq token[2].last_line, closeCurly1[2].last_line
509+
eq token[2].last_column, closeCurly1[2].last_column
510+
511+
for token in [outdent1, outdent2, outdent3, outdent4, outdent5, outdent6]
512+
eq token[0], 'OUTDENT'
513+
assertAtCloseCurly(token)
514+
for token in [callEnd1, callEnd2, callEnd3]
515+
eq token[0], 'CALL_END'
516+
assertAtCloseCurly(token)
517+
518+
test "Verify real CALL_END tokens have the right position", ->
519+
source = '''
520+
a()
521+
'''
522+
tokens = CoffeeScript.tokens source
523+
[identifier, callStart, callEnd, terminator] = tokens
524+
startIndex = identifier[2].first_column
525+
eq identifier[2].last_column, startIndex
526+
eq callStart[2].first_column, startIndex + 1
527+
eq callStart[2].last_column, startIndex + 1
528+
eq callEnd[2].first_column, startIndex + 2
529+
eq callEnd[2].last_column, startIndex + 2
530+
472531
test "Verify all tokens get a location", ->
473532
doesNotThrow ->
474533
tokens = CoffeeScript.tokens testScript

0 commit comments

Comments
 (0)