Skip to content

Commit 2a7d1fe

Browse files
committed
suppress indents
1 parent 53b46da commit 2a7d1fe

File tree

5 files changed

+220
-27
lines changed

5 files changed

+220
-27
lines changed

lib/coffeescript/lexer.js

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

lib/coffeescript/rewriter.js

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

src/lexer.coffee

+9
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,7 @@ exports.Lexer = class Lexer
462462

463463
size = indent.length - 1 - indent.lastIndexOf '\n'
464464
noNewlines = @unfinished()
465+
noIndents = @shouldSuppressIndents()
465466

466467
newIndentLiteral = if size > 0 then indent[-size..] else ''
467468
unless /^(.?)\1*$/.exec newIndentLiteral
@@ -482,6 +483,9 @@ exports.Lexer = class Lexer
482483
@indebt = size - @indent unless backslash
483484
@suppressNewlines()
484485
return indent.length
486+
if noIndents
487+
@newlineToken 0
488+
return indent.length
485489
unless @tokens.length
486490
@baseIndent = @indent = size
487491
@indentLiteral = newIndentLiteral
@@ -995,6 +999,10 @@ exports.Lexer = class Lexer
995999
LINE_CONTINUER.test(@chunk) or
9961000
@tag() in UNFINISHED
9971001

1002+
# Should an indent be treated as just a TERMINATOR?
1003+
shouldSuppressIndents: ->
1004+
INDENT_SUPPRESSOR.test @chunk
1005+
9981006
formatString: (str, options) ->
9991007
@replaceUnicodeCodePointEscapes str.replace(STRING_OMIT, '$1'), options
10001008

@@ -1294,6 +1302,7 @@ POSSIBLY_DIVISION = /// ^ /=?\s ///
12941302
HERECOMMENT_ILLEGAL = /\*\//
12951303
12961304
LINE_CONTINUER = /// ^ \s* (?: , | \??\.(?![.\d]) | \??:: ) ///
1305+
INDENT_SUPPRESSOR = /// ^ \s* (?: and\s+(?!:)\S | or\s+(?!:)\S | && | \|\| ) ///
12971306
12981307
STRING_INVALID_ESCAPE = ///
12991308
( (?:^|[^\\]) (?:\\\\)* ) # Make sure the escape isn’t escaped.

src/rewriter.coffee

+12-10
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.
@@ -672,6 +662,18 @@ exports.Rewriter = class Rewriter
672662
@detectEnd i + 1, condition, action
673663
return 1
674664

665+
# Convert TERMINATOR followed by && or || into a single LEADING_&& or
666+
# LEADING_|| token to disambiguate grammar.
667+
tagLeadingLogical: ->
668+
@scanTokens (token, i, tokens) ->
669+
return 1 unless token[0] is 'TERMINATOR' and tokens.length >= i + 2 and (operatorToken = tokens[i + 1])[0] in ['&&', '||']
670+
token[0] = "LEADING_#{operatorToken[0]}"
671+
token[1] = operatorToken[1]
672+
token[2].last_line = operatorToken[2].last_line
673+
token[2].last_column = operatorToken[2].last_column
674+
tokens.splice i + 1, 1
675+
1
676+
675677
# Generate the indentation tokens, based on another token on the same line.
676678
indentation: (origin) ->
677679
indent = ['INDENT', 2]

test/formatting.coffee

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

0 commit comments

Comments
 (0)