Skip to content

Commit

Permalink
suppress indents
Browse files Browse the repository at this point in the history
  • Loading branch information
helixbass committed May 19, 2018
1 parent 53b46da commit 2a7d1fe
Show file tree
Hide file tree
Showing 5 changed files with 220 additions and 27 deletions.
16 changes: 14 additions & 2 deletions lib/coffeescript/lexer.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

32 changes: 17 additions & 15 deletions lib/coffeescript/rewriter.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions src/lexer.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,7 @@ exports.Lexer = class Lexer

size = indent.length - 1 - indent.lastIndexOf '\n'
noNewlines = @unfinished()
noIndents = @shouldSuppressIndents()

newIndentLiteral = if size > 0 then indent[-size..] else ''
unless /^(.?)\1*$/.exec newIndentLiteral
Expand All @@ -482,6 +483,9 @@ exports.Lexer = class Lexer
@indebt = size - @indent unless backslash
@suppressNewlines()
return indent.length
if noIndents
@newlineToken 0
return indent.length
unless @tokens.length
@baseIndent = @indent = size
@indentLiteral = newIndentLiteral
Expand Down Expand Up @@ -995,6 +999,10 @@ exports.Lexer = class Lexer
LINE_CONTINUER.test(@chunk) or
@tag() in UNFINISHED

# Should an indent be treated as just a TERMINATOR?
shouldSuppressIndents: ->
INDENT_SUPPRESSOR.test @chunk

formatString: (str, options) ->
@replaceUnicodeCodePointEscapes str.replace(STRING_OMIT, '$1'), options

Expand Down Expand Up @@ -1294,6 +1302,7 @@ POSSIBLY_DIVISION = /// ^ /=?\s ///
HERECOMMENT_ILLEGAL = /\*\//
LINE_CONTINUER = /// ^ \s* (?: , | \??\.(?![.\d]) | \??:: ) ///
INDENT_SUPPRESSOR = /// ^ \s* (?: and\s+(?!:)\S | or\s+(?!:)\S | && | \|\| ) ///
STRING_INVALID_ESCAPE = ///
( (?:^|[^\\]) (?:\\\\)* ) # Make sure the escape isn’t escaped.
Expand Down
22 changes: 12 additions & 10 deletions src/rewriter.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -129,16 +129,6 @@ exports.Rewriter = class Rewriter
@detectEnd i + 1, condition, action if token[0] is 'INDEX_START'
1

tagLeadingLogical: ->
@scanTokens (token, i, tokens) ->
return 1 unless token[0] is 'TERMINATOR' and tokens.length >= i + 2 and (operatorToken = tokens[i + 1])[0] in ['&&', '||']
token[0] = "LEADING_#{operatorToken[0]}"
token[1] = operatorToken[1]
token[2].last_line = operatorToken[2].last_line
token[2].last_column = operatorToken[2].last_column
tokens.splice i + 1, 1
1

# Match tags in token stream starting at `i` with `pattern`.
# `pattern` may consist of strings (equality), an array of strings (one of)
# or null (wildcard). Returns the index of the match or -1 if no match.
Expand Down Expand Up @@ -672,6 +662,18 @@ exports.Rewriter = class Rewriter
@detectEnd i + 1, condition, action
return 1

# Convert TERMINATOR followed by && or || into a single LEADING_&& or
# LEADING_|| token to disambiguate grammar.
tagLeadingLogical: ->
@scanTokens (token, i, tokens) ->
return 1 unless token[0] is 'TERMINATOR' and tokens.length >= i + 2 and (operatorToken = tokens[i + 1])[0] in ['&&', '||']
token[0] = "LEADING_#{operatorToken[0]}"
token[1] = operatorToken[1]
token[2].last_line = operatorToken[2].last_line
token[2].last_column = operatorToken[2].last_column
tokens.splice i + 1, 1
1

# Generate the indentation tokens, based on another token on the same line.
indentation: (origin) ->
indent = ['INDENT', 2]
Expand Down
168 changes: 168 additions & 0 deletions test/formatting.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -454,3 +454,171 @@ test "#3736: chaining after do IIFE", ->
eq 4,
do b
.c

test "logical and/or should continue lines", ->
ok not (
yes
and no
)

ok not (
1
and 0
)

ok 'abc'
&& 123

ok 'abc'
&& 123

ok 'abc'
or 123

ok 'abc'
or 123

ok 'abc'
|| 123

ok 'abc'
|| 123

a =
and : 'b'
or : 'a'
ok 'a' is a.or

b =
or : 'b'
and : 'a'
ok 'a' is b.and

yup = -> yes
nope = -> no

eq 3,
yes
and yup
c: 2
and 3

eq 3,
yes
and yup
c: 2
and 3

eq 3,
no
or nope
c: 2
or 3

eq 3,
no
or nope
c: 2
or 3

eq 5,
yes
and yup
c: 2
if yes
3
else
4
and 5

eq 5,
yes
and yup
c: 2
if yes
3
else
4
and 5

eq yes,
yes
and yup
c: 2
if yes
3
else
4
and 5

eq yes,
yes
and yup
c: 2
if yes
3
else
4
and 5

eq 2,
no
or nope -> 1
or 2

eq 2,
no
or nope -> 1
or 2

eq 2,
no
or nope ->
1
or 2

eq 2,
no
or nope ->
1
or 2

eq no,
no
or nope ->
1
or 2

eq no,
no
or nope ->
1
or 2

eq no,
no
or nope ->
1
or 2

f = ({c}) -> c
eq 3,
yes
and f
c:
no
or 3

eq 3,
yes
and f
c:
no
or 3

eq 1,
yes
and f
c:
1
or 3

0 comments on commit 2a7d1fe

Please sign in to comment.