Skip to content

Commit 2b7725f

Browse files
committed
suppress indents
1 parent c85e6c0 commit 2b7725f

File tree

5 files changed

+220
-27
lines changed

5 files changed

+220
-27
lines changed

lib/coffeescript/lexer.js

Lines changed: 14 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/coffeescript/rewriter.js

Lines changed: 17 additions & 15 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/lexer.coffee

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,7 @@ exports.Lexer = class Lexer
446446

447447
size = indent.length - 1 - indent.lastIndexOf '\n'
448448
noNewlines = @unfinished()
449+
noIndents = @shouldSuppressIndents()
449450

450451
newIndentLiteral = if size > 0 then indent[-size..] else ''
451452
unless /^(.?)\1*$/.exec newIndentLiteral
@@ -466,6 +467,9 @@ exports.Lexer = class Lexer
466467
@indebt = size - @indent unless backslash
467468
@suppressNewlines()
468469
return indent.length
470+
if noIndents
471+
@newlineToken 0
472+
return indent.length
469473
unless @tokens.length
470474
@baseIndent = @indent = size
471475
@indentLiteral = newIndentLiteral
@@ -1028,6 +1032,10 @@ exports.Lexer = class Lexer
10281032
validateUnicodeCodePointEscapes: (str, options) ->
10291033
replaceUnicodeCodePointEscapes str, merge options, {@error}
10301034

1035+
# Should an indent be treated as just a TERMINATOR?
1036+
shouldSuppressIndents: ->
1037+
INDENT_SUPPRESSOR.test @chunk
1038+
10311039
# Validates escapes in strings and regexes.
10321040
validateEscapes: (str, options = {}) ->
10331041
invalidEscapeRegex =
@@ -1263,6 +1271,7 @@ POSSIBLY_DIVISION = /// ^ /=?\s ///
12631271
HERECOMMENT_ILLEGAL = /\*\//
12641272
12651273
LINE_CONTINUER = /// ^ \s* (?: , | \??\.(?![.\d]) | \??:: ) ///
1274+
INDENT_SUPPRESSOR = /// ^ \s* (?: and\s+(?!:)\S | or\s+(?!:)\S | && | \|\| ) ///
12661275
12671276
STRING_INVALID_ESCAPE = ///
12681277
( (?:^|[^\\]) (?:\\\\)* ) # Make sure the escape isn’t escaped.

src/rewriter.coffee

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -129,16 +129,6 @@ exports.Rewriter = class Rewriter
129129
@detectEnd i + 1, condition, action if token[0] is 'INDEX_START'
130130
1
131131

132-
tagLeadingLogical: ->
133-
@scanTokens (token, i, tokens) ->
134-
return 1 unless token[0] is 'TERMINATOR' and tokens.length >= i + 2 and (operatorToken = tokens[i + 1])[0] in ['&&', '||']
135-
token[0] = "LEADING_#{operatorToken[0]}"
136-
token[1] = operatorToken[1]
137-
token[2].last_line = operatorToken[2].last_line
138-
token[2].last_column = operatorToken[2].last_column
139-
tokens.splice i + 1, 1
140-
1
141-
142132
# Match tags in token stream starting at `i` with `pattern`.
143133
# `pattern` may consist of strings (equality), an array of strings (one of)
144134
# or null (wildcard). Returns the index of the match or -1 if no match.
@@ -680,6 +670,18 @@ exports.Rewriter = class Rewriter
680670
token[1].generated = yes if token.generated
681671
1
682672

673+
# Convert TERMINATOR followed by && or || into a single LEADING_&& or
674+
# LEADING_|| token to disambiguate grammar.
675+
tagLeadingLogical: ->
676+
@scanTokens (token, i, tokens) ->
677+
return 1 unless token[0] is 'TERMINATOR' and tokens.length >= i + 2 and (operatorToken = tokens[i + 1])[0] in ['&&', '||']
678+
token[0] = "LEADING_#{operatorToken[0]}"
679+
token[1] = operatorToken[1]
680+
token[2].last_line = operatorToken[2].last_line
681+
token[2].last_column = operatorToken[2].last_column
682+
tokens.splice i + 1, 1
683+
1
684+
683685
# Generate the indentation tokens, based on another token on the same line.
684686
indentation: (origin) ->
685687
indent = ['INDENT', 2]

test/formatting.coffee

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -470,3 +470,171 @@ test "#3736: chaining after do IIFE", ->
470470
eq 4,
471471
do b
472472
.c
473+
474+
test "logical and/or should continue lines", ->
475+
ok not (
476+
yes
477+
and no
478+
)
479+
480+
ok not (
481+
1
482+
and 0
483+
)
484+
485+
ok 'abc'
486+
&& 123
487+
488+
ok 'abc'
489+
&& 123
490+
491+
ok 'abc'
492+
or 123
493+
494+
ok 'abc'
495+
or 123
496+
497+
ok 'abc'
498+
|| 123
499+
500+
ok 'abc'
501+
|| 123
502+
503+
a =
504+
and : 'b'
505+
or : 'a'
506+
ok 'a' is a.or
507+
508+
b =
509+
or : 'b'
510+
and : 'a'
511+
ok 'a' is b.and
512+
513+
yup = -> yes
514+
nope = -> no
515+
516+
eq 3,
517+
yes
518+
and yup
519+
c: 2
520+
and 3
521+
522+
eq 3,
523+
yes
524+
and yup
525+
c: 2
526+
and 3
527+
528+
eq 3,
529+
no
530+
or nope
531+
c: 2
532+
or 3
533+
534+
eq 3,
535+
no
536+
or nope
537+
c: 2
538+
or 3
539+
540+
eq 5,
541+
yes
542+
and yup
543+
c: 2
544+
if yes
545+
3
546+
else
547+
4
548+
and 5
549+
550+
eq 5,
551+
yes
552+
and yup
553+
c: 2
554+
if yes
555+
3
556+
else
557+
4
558+
and 5
559+
560+
eq yes,
561+
yes
562+
and yup
563+
c: 2
564+
if yes
565+
3
566+
else
567+
4
568+
and 5
569+
570+
eq yes,
571+
yes
572+
and yup
573+
c: 2
574+
if yes
575+
3
576+
else
577+
4
578+
and 5
579+
580+
eq 2,
581+
no
582+
or nope -> 1
583+
or 2
584+
585+
eq 2,
586+
no
587+
or nope -> 1
588+
or 2
589+
590+
eq 2,
591+
no
592+
or nope ->
593+
1
594+
or 2
595+
596+
eq 2,
597+
no
598+
or nope ->
599+
1
600+
or 2
601+
602+
eq no,
603+
no
604+
or nope ->
605+
1
606+
or 2
607+
608+
eq no,
609+
no
610+
or nope ->
611+
1
612+
or 2
613+
614+
eq no,
615+
no
616+
or nope ->
617+
1
618+
or 2
619+
620+
f = ({c}) -> c
621+
eq 3,
622+
yes
623+
and f
624+
c:
625+
no
626+
or 3
627+
628+
eq 3,
629+
yes
630+
and f
631+
c:
632+
no
633+
or 3
634+
635+
eq 1,
636+
yes
637+
and f
638+
c:
639+
1
640+
or 3

0 commit comments

Comments
 (0)