Statement: [
o 'Return'
- o 'Comment'
o 'STATEMENT', -> new StatementLiteral $1
o 'Import'
o 'Export'
@@ -404,7 +404,6 @@ them somewhat circular.
Expression: [
o 'Value'
- o 'Invocation'
o 'Code'
o 'Operation'
o 'Assign'
@@ -500,11 +499,11 @@ through and printed to JavaScript.
o 'AlphaNumeric'
o 'JS', -> new PassthroughLiteral $1
o 'Regex'
- o 'UNDEFINED', -> new UndefinedLiteral
- o 'NULL', -> new NullLiteral
+ o 'UNDEFINED', -> new UndefinedLiteral $1
+ o 'NULL', -> new NullLiteral $1
o 'BOOL', -> new BooleanLiteral $1
o 'INFINITY', -> new InfinityLiteral $1
- o 'NAN', -> new NaNLiteral
+ o 'NAN', -> new NaNLiteral $1
]
@@ -553,7 +552,6 @@ the ordinary Assign is that these allow numbers and strings as
o 'SimpleObjAssignable =
INDENT Expression OUTDENT', -> new Assign LOC(1)(new Value $1), $4, null,
operatorToken: LOC(2)(new Literal $2)
- o 'Comment'
]
SimpleObjAssignable: [
@@ -582,7 +580,9 @@ the ordinary Assign is that these allow numbers and strings as
ObjRestValue: [
o 'SimpleObjAssignable ...', -> new Splat new Value $1
+ o '... SimpleObjAssignable', -> new Splat new Value $2
o 'ObjSpreadExpr ...', -> new Splat $1
+ o '... ObjSpreadExpr', -> new Splat $2
]
ObjSpreadExpr: [
@@ -591,14 +591,19 @@ the ordinary Assign is that these allow numbers and strings as
o 'Parenthetical'
o 'Super'
o 'This'
- o 'SUPER Arguments', -> new SuperCall LOC(1)(new Super), $2
+ o 'SUPER Arguments', -> new SuperCall LOC(1)(new Super), $2, no, $1
o 'SimpleObjAssignable Arguments', -> new Call (new Value $1), $2
o 'ObjSpreadExpr Arguments', -> new Call $1, $2
]
ObjSpreadIdentifier: [
- o 'SimpleObjAssignable . Property', -> (new Value $1).add(new Access $3)
- o 'SimpleObjAssignable INDEX_START IndexValue INDEX_END', -> (new Value $1).add($3)
+ o 'SimpleObjAssignable ObjSpreadAccessor', -> (new Value $1).add $2
+ o 'ObjSpreadExpr ObjSpreadAccessor', -> (new Value $1).add $2
+ ]
+
+ ObjSpreadAccessor: [
+ o '. Property', -> new Access $2
+ o 'INDEX_START IndexValue INDEX_END', -> $2
]
@@ -616,6 +621,7 @@ the ordinary Assign is that these allow numbers and strings as
Return: [
o 'RETURN Expression', -> new Return $2
+ o 'RETURN INDENT Object OUTDENT', -> new Return new Value $3
o 'RETURN', -> new Return
]
@@ -638,23 +644,6 @@ the ordinary Assign is that these allow numbers and strings as
- A block comment.
-
-
-
-
Comment: [
- o 'HERECOMMENT', -> new Comment $1
- ]
-
-
-
-
-
-
-
-
The Code node is the function literal. It’s defined by an indented block
of Block preceded by a function arrow, with an optional parameter list.
@@ -668,11 +657,11 @@ of
Block preceded by a function arrow, with an optional paramet
-
+
CoffeeScript has two different symbols for functions. ->
is for ordinary
functions, and =>
is for functions bound to the current value of this.
@@ -680,18 +669,18 @@ functions, and
=>
is for functions bound to the current value of
FuncGlyph: [
- o '->', -> 'func'
- o '=>', -> 'boundfunc'
+ o '->', -> new FuncGlyph $1
+ o '=>', -> new FuncGlyph $1
]
-
+
An optional, trailing comma.
@@ -705,11 +694,11 @@ functions, and
=>
is for functions bound to the current value of
-
+
The list of parameters that a function accepts can be of any length.
@@ -726,11 +715,11 @@ functions, and
=>
is for functions bound to the current value of
-
+
A single parameter in a function definition can be ordinary, or a splat
that hoovers up the remaining arguments.
@@ -740,6 +729,7 @@ that hoovers up the remaining arguments.
Param: [
o 'ParamVar', -> new Param $1
o 'ParamVar ...', -> new Param $1, null, on
+ o '... ParamVar', -> new Param $2, null, on
o 'ParamVar = Expression', -> new Param $1, $3
o '...', -> new Expansion
]
@@ -747,11 +737,11 @@ that hoovers up the remaining arguments.
-
+
Function Parameters
@@ -767,11 +757,11 @@ that hoovers up the remaining arguments.
-
+
A splat that occurs outside of a parameter list.
@@ -779,6 +769,26 @@ that hoovers up the remaining arguments.
Splat: [
o 'Expression ...', -> new Splat $1
+ o '... Expression', -> new Splat $2
+ ]
+
+
+
+
+
+
+
+
+
Variables and properties that can be assigned to.
+
+
+
+ SimpleAssignable: [
+ o 'Identifier', -> new Value $1
+ o 'Value Accessor', -> $1.add $2
+ o 'ThisProperty'
]
@@ -790,26 +800,6 @@ that hoovers up the remaining arguments.
-
Variables and properties that can be assigned to.
-
-
-
- SimpleAssignable: [
- o 'Identifier', -> new Value $1
- o 'Value Accessor', -> $1.add $2
- o 'Invocation Accessor', -> new Value $1, [].concat $2
- o 'ThisProperty'
- ]
-
-
-
-
-
-
-
-
Everything that can be assigned to.
@@ -823,11 +813,11 @@ that hoovers up the remaining arguments.
-
+
The types of things that can be treated as values – assigned to, invoked
as functions, indexed into, named as a class, etc.
@@ -839,8 +829,27 @@ as functions, indexed into, named as a class, etc.
o
'Literal',
-> new Value $
1
o
'Parenthetical',
-> new Value $
1
o
'Range',
-> new Value $
1
+ o
'Invocation',
-> new Value $
1
o
'This'
- o
'Super'
+ o
'Super',
-> new Value $
1
+ ]
+
+
+
+
+
+
+
+
+
A super
-based expression that can be used as a value.
+
+
+
+ Super: [
+ o 'SUPER . Property', -> new Super LOC(3)(new Access $3), [], no, $1
+ o 'SUPER INDEX_START Expression INDEX_END', -> new Super LOC(3)(new Index $3), [], no, $1
]
@@ -852,24 +861,6 @@ as functions, indexed into, named as a class, etc.
-
A super
-based expression that can be used as a value.
-
-
-
- Super: [
- o 'SUPER . Property', -> new Super LOC(3) new Access $3
- o 'SUPER INDEX_START Expression INDEX_END', -> new Super LOC(3) new Index $3
- ]
-
-
-
-
-
-
-
-
The general group of accessors into an object, by property, by prototype
or by array index or slice.
@@ -887,11 +878,11 @@ or by array index or slice.
-
+
Indexing into an object or array using bracket notation.
@@ -899,7 +890,7 @@ or by array index or slice.
Index: [
o 'INDEX_START IndexValue INDEX_END', -> $2
- o 'INDEX_SOAK Index', -> extend $2, soak : yes
+ o 'INDEX_SOAK Index', -> extend $2, soak: yes
]
IndexValue: [
@@ -910,11 +901,11 @@ or by array index or slice.
-
+
In CoffeeScript, an object literal is simply a list of assignments.
@@ -927,11 +918,11 @@ or by array index or slice.
-
+
Assignment of properties within an object literal can be separated by
comma, as in JavaScript, or simply by newline.
@@ -949,11 +940,11 @@ comma, as in JavaScript, or simply by newline.
-
+
Class definitions have optional bodies of prototype property assignments,
and optional references to the superclass.
@@ -1038,11 +1029,11 @@ and optional references to the superclass.
-
+
Ordinary function invocation, or a chained series of calls.
@@ -1051,18 +1042,17 @@ and optional references to the superclass.
Invocation: [
o 'Value OptFuncExist String', -> new TaggedTemplateCall $1, $3, $2
o 'Value OptFuncExist Arguments', -> new Call $1, $3, $2
- o 'Invocation OptFuncExist Arguments', -> new Call $1, $3, $2
- o 'SUPER OptFuncExist Arguments', -> new SuperCall LOC(1)(new Super), $3, $2
+ o 'SUPER OptFuncExist Arguments', -> new SuperCall LOC(1)(new Super), $3, $2, $1
]
-
+
An optional existence check on a function.
@@ -1076,11 +1066,11 @@ and optional references to the superclass.
-
+
The list of arguments to a function call.
@@ -1094,19 +1084,36 @@ and optional references to the superclass.
-
+
A reference to the this current object.
This: [
- o 'THIS', -> new Value new ThisLiteral
- o '@', -> new Value new ThisLiteral
+ o 'THIS', -> new Value new ThisLiteral $1
+ o '@', -> new Value new ThisLiteral $1
+ ]
+
+
+
+
+
+
+
+
+
A reference to a property on this.
+
+
+
+ ThisProperty: [
+ o '@ Property', -> new Value LOC(1)(new ThisLiteral $1), [LOC(2)(new Access($2))], 'this'
]
@@ -1118,23 +1125,6 @@ and optional references to the superclass.
-
A reference to a property on this.
-
-
-
- ThisProperty: [
- o '@ Property', -> new Value LOC(1)(new ThisLiteral), [LOC(2)(new Access($2))], 'this'
- ]
-
-
-
-
-
-
@@ -1147,11 +1137,11 @@ and optional references to the superclass.
-
+
Inclusive and exclusive range dots.
@@ -1165,11 +1155,11 @@ and optional references to the superclass.
-
+
The CoffeeScript range literal.
@@ -1182,11 +1172,11 @@ and optional references to the superclass.
-
+
Array slice literals.
@@ -1202,11 +1192,11 @@ and optional references to the superclass.
-
+
The ArgList is both the list of objects passed into a function call,
as well as the contents of an array literal
@@ -1225,11 +1215,11 @@ as well as the contents of an array literal
-
+
Valid arguments are Blocks or Splats.
@@ -1244,11 +1234,11 @@ as well as the contents of an array literal
-
+
Just simple, comma-separated, required arguments (no fancy syntax). We need
this to be separate from the ArgList for use in Switch blocks, where
@@ -1264,11 +1254,11 @@ having the newlines wouldn’t make sense.
-
+
The variants of try/catch/finally exception handling blocks.
@@ -1284,11 +1274,11 @@ having the newlines wouldn’t make sense.
-
+
A catch clause names its error and runs a block of code.
@@ -1303,11 +1293,11 @@ having the newlines wouldn’t make sense.
-
+
Throw an exception object.
@@ -1315,16 +1305,17 @@ having the newlines wouldn’t make sense.
Throw: [
o 'THROW Expression', -> new Throw $2
+ o 'THROW INDENT Object OUTDENT', -> new Throw new Value $3
]
-
+
Parenthetical expressions. Note that the Parenthetical is a Value,
not an Expression, so if you need to use an expression in a place
@@ -1341,11 +1332,11 @@ the trick.
-
+
The condition portion of a while loop.
@@ -1361,11 +1352,11 @@ the trick.
-
+
The while loop can either be normal, with a block of expressions to execute,
or postfix, with a single expression. There is no do..while.
@@ -1387,11 +1378,11 @@ or postfix, with a single expression. There is no do..while.
-
+
Array, object, and range comprehensions, at the most generic level.
Comprehensions can either be normal, with a block of expressions to execute,
@@ -1419,11 +1410,11 @@ or postfix, with a single expression.
-
+
An array of all accepted values for a variable inside the loop.
This enables support for pattern matching.
@@ -1440,11 +1431,11 @@ This enables support for pattern matching.
-
+
An array or range comprehension has variables for the current element
and (optional) reference to the current index. Or, key, value, in the case
@@ -1460,11 +1451,11 @@ of object comprehensions.
-
+
The source of a comprehension is an array or object with an optional guard
clause. If it’s an array comprehension, you can also choose to step through
@@ -1499,11 +1490,11 @@ in fixed-size increments.
-
+
An individual When clause, with action.
@@ -1517,11 +1508,11 @@ in fixed-size increments.
-
+
The most basic form of if is a condition and an action. The following
if-related rules are broken up along these lines in order to avoid
@@ -1537,11 +1528,11 @@ ambiguity.
-
+
The full complement of if expressions, including postfix one-liner
if and unless.
@@ -1558,11 +1549,11 @@ ambiguity.
-
+
Arithmetic and logical operators, working on one or more operands.
Here they are grouped by order of precedence. The actual precedence rules
@@ -1589,11 +1580,11 @@ rules are necessary.
-
+
The existential operator.
@@ -1631,14 +1622,26 @@ rules are necessary.
+
+
+
+
+
+
@@ -1650,18 +1653,6 @@ rules are necessary.
-
-
-
-
-
-
-
-
-
-
Operators at the top of this list have higher precedence than the ones lower
down. Following these rules is what makes 2 + 3 * 4
parse as:
2 + (3 * 4)
@@ -1701,14 +1692,26 @@ down. Following these rules is what makes 2 + 3 * 4
parse as:
+
+
+
+
+
+
@@ -1720,18 +1723,6 @@ down. Following these rules is what makes 2 + 3 * 4
parse as:
-
-
-
-
-
-
-
-
-
-
Finally, now that we have our grammar and our operators, we can create
our Jison.Parser. We do this by processing all of our rules, recording all
terminals (every symbol which does not appear as the name of a rule above)
@@ -1750,11 +1741,11 @@ as “tokens”.
-
+
Initialize the Parser with our list of terminal tokens, our grammar
rules, and the name of the root. Reverse the operators because Jison orders
diff --git a/docs/v2/annotated-source/helpers.html b/docs/v2/annotated-source/helpers.html
index 46223624..834df0d9 100644
--- a/docs/v2/annotated-source/helpers.html
+++ b/docs/v2/annotated-source/helpers.html
@@ -382,7 +382,10 @@ If last
is not provided, this will simply return first
first_line: first.first_line
first_column: first.first_column
last_line: last.last_line
- last_column: last.last_column
+ last_column: last.last_column
+
+buildLocationHash = (loc) ->
+ "#{loc.first_line}x#{loc.first_column}-#{loc.last_line}x#{loc.last_column}"
@@ -399,12 +402,8 @@ The object is returned either way.
- exports.addLocationDataFn = (first, last) ->
- (obj) ->
- if ((typeof obj) is 'object') and (!!obj['updateLocationDataIfMissing'])
- obj.updateLocationDataIfMissing buildLocationData(first, last)
-
- return obj
+ exports.addDataToNode = (parserState, first, last) ->
+ (obj) ->
@@ -415,6 +414,56 @@ The object is returned either way.
+
Add location data
+
+
+
+ if obj?.updateLocationDataIfMissing? and first?
+ obj.updateLocationDataIfMissing buildLocationData(first, last)
+
+
+
+
+
+
+
+
+
Add comments data
+
+
+
+ unless parserState.tokenComments
+ parserState.tokenComments = {}
+ for token in parserState.parser.tokens when token.comments
+ tokenHash = buildLocationHash token[2]
+ unless parserState.tokenComments[tokenHash]?
+ parserState.tokenComments[tokenHash] = token.comments
+ else
+ parserState.tokenComments[tokenHash].push token.comments...
+
+ if obj.locationData?
+ objHash = buildLocationHash obj.locationData
+ if parserState.tokenComments[objHash]?
+ attachCommentsToNode parserState.tokenComments[objHash], obj
+
+ obj
+
+exports.attachCommentsToNode = attachCommentsToNode = (comments, node) ->
+ return if not comments? or comments.length is 0
+ node.comments ?= []
+ node.comments.push comments...
+
+
+
+
+
+
+
+
Convert jison location data to a string.
obj
can be a token, or a locationData.
@@ -433,11 +482,11 @@ The object is returned either way.
-
+
A .coffee.md
compatible version of basename
, that returns the file sans-extension.
@@ -456,11 +505,11 @@ The object is returned either way.
-
+
Determine if a filename represents a CoffeeScript file.
@@ -471,11 +520,11 @@ The object is returned either way.
-
+
Determine if a filename represents a Literate CoffeeScript file.
@@ -486,11 +535,11 @@ The object is returned either way.
-
+
Throws a SyntaxError from a given location.
The error’s toString
will return an error message following the “standard”
@@ -507,11 +556,11 @@ marker showing where the error is.
-
+
Instead of showing the compiler’s stacktrace, show our custom error message
(this is useful when the error bubbles up in Node.js applications that
@@ -526,11 +575,11 @@ compile CoffeeScript for example).
-
+
Update a compiler SyntaxError with source code information if it didn’t have
it already.
@@ -542,11 +591,11 @@ it already.
-
+
Avoid screwing up the stack
property of other errors (i.e. possible bugs).
@@ -572,11 +621,11 @@ it already.
-
+
Show only the first line on multi-line errors.
@@ -588,11 +637,11 @@ it already.
-
+
Check to see if we’re running on a color-enabled TTY.
diff --git a/docs/v2/annotated-source/lexer.html b/docs/v2/annotated-source/lexer.html
index 12aab1e4..2fe6eb2b 100644
--- a/docs/v2/annotated-source/lexer.html
+++ b/docs/v2/annotated-source/lexer.html
@@ -143,7 +143,7 @@ are read by jison in the
parser.lexer
function defined in coffeescr
{count, starts, compact, repeat, invertLiterate, merge,
-locationDataToString, throwSyntaxError} = require './helpers'
+attachCommentsToNode, locationDataToString, throwSyntaxError} = require './helpers'
@@ -210,19 +210,20 @@ it has consumed.
tokenize: (code, opts = {}) ->
@literate = opts.literate
@indent = 0
- @baseIndent = 0
+ @baseIndent = 0
@indebt = 0
@outdebt = 0
@indents = []
- @indentLiteral = ''
+ @indentLiteral = ''
@ends = []
@tokens = []
- @seenFor = no
- @seenImport = no
- @seenExport = no
- @importSpecifierList = no
- @exportSpecifierList = no
+ @seenFor = no
+ @seenImport = no
+ @seenExport = no
+ @importSpecifierList = no
+ @exportSpecifierList = no
@csxDepth = 0
+ @csxObjAttribute = {}
@chunkLine =
opts.line or 0
@@ -268,7 +269,7 @@ short-circuiting if any of them succeed. Their order determines precedence:
- Update position
+ Update position.
@@ -392,6 +393,12 @@ though
is
means
===
otherwise.
if id
is 'default' and @seenExport
and @tag()
in [
'EXPORT',
'AS']
@token
'DEFAULT', id
return id.length
+
if id
is 'do' and regExSuper =
/^(\s*super)(?!\(\))/.exec @chunk[
3...]
+ @token
'SUPER',
'super'
+ @token
'CALL_START',
'('
+ @token
'CALL_END',
')'
+ [input, sup] = regExSuper
+
return sup.length +
3
prev = @prev()
@@ -628,21 +635,16 @@ properly tag the
from
.
-
Matches and consumes comments.
+
Matches and consumes comments. The comments are taken out of the token
+stream and saved for later, to be reinserted into the output after
+everything has been parsed and the JavaScript code generated.
-
commentToken: ->
- return 0 unless match = @chunk.match COMMENT
+ commentToken: (chunk = @chunk) ->
+ return 0 unless match = chunk.match COMMENT
[comment, here] = match
- if here
- if match = HERECOMMENT_ILLEGAL.exec comment
- @error "block comments cannot contain #{match[0]}",
- offset: match.index, length: match[0].length
- if here.indexOf('\n') >= 0
- here = here.replace /// \n #{repeat ' ', @indent} ///g, '\n'
- @token 'HERECOMMENT', here, 0, comment.length
- comment.length
+ contents = null
@@ -653,6 +655,130 @@ properly tag the
from
.
+
Does this comment follow code on the same line?
+
+
+
+ newLine = /^\s*\n+\s*#/.test comment
+ if here
+ matchIllegal = HERECOMMENT_ILLEGAL.exec comment
+ if matchIllegal
+ @error "block comments cannot contain #{matchIllegal[0]}",
+ offset: matchIllegal.index, length: matchIllegal[0].length
+
+
+
+
+
+
+
+
+
Parse indentation or outdentation as if this block comment didn’t exist.
+
+
+
+ chunk = chunk.replace "####{here}###", ''
+
+
+
+
+
+
+
+
+
Remove leading newlines, like Rewriter::removeLeadingNewlines
, to
+avoid the creation of unwanted TERMINATOR
tokens.
+
+
+
+ chunk = chunk.replace /^\n+/, ''
+ @lineToken chunk
+
+
+
+
+
+
+
+
+
Pull out the ###-style comment’s content, and format it.
+
+
+
+ content = here
+ if '\n' in content
+ content = content.replace /// \n #{repeat ' ', @indent} ///g, '\n'
+ contents = [content]
+ else
+
+
+
+
+
+
+
+
+
The COMMENT
regex captures successive line comments as one token.
+Remove any leading newlines before the first comment, but preserve
+blank lines between line comments.
+
+
+
+ content = comment.replace /^(\n*)/, ''
+ content = content.replace /^([ |\t]*)#/gm, ''
+ contents = content.split '\n'
+
+ commentAttachments = for content, i in contents
+ content: content
+ here: here?
+ newLine: newLine or i isnt 0
+
+ prev = @prev()
+ unless prev
+
+
+
+
+
+
+
+
+
If there’s no previous token, create a placeholder token to attach
+this comment to; and follow with a newline.
+
+
+
+ commentAttachments[0].newLine = yes
+ @lineToken @chunk[comment.length..]
+ placeholderToken = @makeToken 'JS', ''
+ placeholderToken.generated = yes
+ placeholderToken.comments = commentAttachments
+ @tokens.push placeholderToken
+ @newlineToken 0
+ else
+ attachCommentsToNode commentAttachments, prev
+
+ comment.length
+
+
+
+
+
+
+
+
Matches JavaScript interpolated directly into the source via backticks.
@@ -664,11 +790,11 @@ properly tag the from
.
-
+
Convert escaped backticks to backticks, and escaped backslashes
just before escaped backticks to backslashes
@@ -680,11 +806,11 @@ just before escaped backticks to backslashes
-
+
string
is always a value like ‘`‘, ‘\`‘, ‘\\`‘, etc.
By reducing it to its latter half, we turn ‘`‘ to ‘', '\\\
‘ to ‘`‘, etc.
@@ -698,11 +824,11 @@ By reducing it to its latter half, we turn ‘`‘ to ‘
', '\\\
-
+
Matches regular expression literals, as well as multiline extended ones.
Lexing regular expressions is difficult to distinguish from division, so we
@@ -717,6 +843,8 @@ borrow some basic heuristics from JavaScript and Ruby.
offset: match.index + match[
1].length
when match = @matchWithInterpolations HEREGEX,
'///'
{tokens, index} = match
+ comments = @chunk[
0...index].match
/\s+(#(?!{).*)/g
+ @commentToken comment
for comment
in comments
if comments
when match = REGEX.exec @chunk
[regex, body, closed] = match
@validateEscapes body, isRegex:
yes, offsetInChunk:
1
@@ -760,11 +888,11 @@ borrow some basic heuristics from JavaScript and Ruby.
-
+
Matches newlines, indents, and outdents, and determines which is which.
If we can detect that the current line is continued onto the next line,
@@ -777,8 +905,8 @@ can close multiple indents, so we need to know how far in we happen to be.
- lineToken: ->
- return 0 unless match = MULTI_DENT.exec @chunk
+ lineToken: (chunk = @chunk) ->
+ return 0 unless match = MULTI_DENT.exec chunk
indent = match[0]
@seenFor = no
@@ -803,7 +931,7 @@ can close multiple indents, so we need to know how far in we happen to be.
return indent.length
if size > @indent
- if noNewlines or @tag() is 'RETURN'
+ if noNewlines
@indebt = size - @indent
@suppressNewlines()
return indent.length
@@ -828,11 +956,11 @@ can close multiple indents, so we need to know how far in we happen to be.
-
+
Record an outdent token or multiple tokens, if we happen to be moving back
inwards past several recorded indents. Sets new @indent value.
@@ -858,11 +986,11 @@ inwards past several recorded indents. Sets new @indent value.
-
+
pair might call outdentToken, so preserve decreasedIndent
@@ -882,11 +1010,11 @@ inwards past several recorded indents. Sets new @indent value.
-
+
Matches and consumes non-meaningful whitespace. Tag the previous token
as being “spaced”, because there are some cases where it makes a difference.
@@ -903,11 +1031,11 @@ as being “spaced”, because there are some cases where it makes a difference.
-
+
Generate a newline token. Consecutive newlines get merged together.
@@ -921,11 +1049,11 @@ as being “spaced”, because there are some cases where it makes a difference.
-
+
Use a \
at a line-ending to suppress the newline.
The slash is removed here once its job is done.
@@ -933,24 +1061,59 @@ The slash is removed here once its job is done.
suppressNewlines: ->
- @tokens.pop() if @value() is '\\'
+ prev = @prev()
+ if prev[1] is '\\'
+ if prev.comments and @tokens.length > 1
+
+
+
+
+
+
+
+
+
@tokens.length
should be at least 2 (some code, then \
).
+If something puts a \
after nothing, they deserve to lose any
+comments that trail it.
+
+
+
+ attachCommentsToNode prev.comments, @tokens[@tokens.length - 2]
+ @tokens.pop()
this
-
+
CSX is like JSX but for CoffeeScript.
csxToken: ->
- firstChar = @chunk[0]
+ firstChar = @chunk[0]
+
+
+
+
+
+
+
+
+
Check the previous token to detect if attribute is spread.
+
+
+
+ prevChar = if @tokens.length > 0 then @tokens[@tokens.length - 1][0] else ''
if firstChar is '<'
match = CSX_IDENTIFIER.exec @chunk[1...]
return 0 unless match and (
@@ -959,11 +1122,11 @@ The slash is removed here once its job is done.
-
+
Not the right hand side of an unspaced comparison (i.e. a<b
).
@@ -976,19 +1139,24 @@ The slash is removed here once its job is done.
[input, id, colon] = match
origin = @token
'CSX_TAG', id,
1, id.length
@token
'CALL_START',
'('
- @token
'{',
'{'
+ @token
'[',
'['
@ends.push tag:
'/>', origin: origin, name: id
@csxDepth++
return id.length +
1
else if csxTag = @atCSXTag()
if @chunk[..
.2]
is '/>'
@pair
'/>'
- @token
'}',
'}',
0,
2
+ @token
']',
']',
0,
2
@token
'CALL_END',
')',
0,
2
@csxDepth--
return 2
else if firstChar
is '{'
- token = @token
'(',
'('
+
if prevChar
is ':'
+ token = @token
'(',
'('
+ @csxObjAttribute[@csxDepth] =
no
+
else
+ token = @token
'{',
'{'
+ @csxObjAttribute[@csxDepth] =
yes
@ends.push {tag:
'}', origin: token}
return 1
else if firstChar
is '>'
@@ -996,18 +1164,18 @@ The slash is removed here once its job is done.
-
+
Ignore terminators inside a tag.
@pair '/>'
- origin = @token '}', '}'
+ origin = @token ']', ']'
@token ',', ','
{tokens, index: end} =
@matchWithInterpolations INSIDE_CSX, '>', '</', CSX_INTERPOLATION
@@ -1024,11 +1192,11 @@ The slash is removed here once its job is done.
-
+
+1 for the closing >
.
@@ -1042,7 +1210,11 @@ The slash is removed here once its job is done.
else if @atCSXTag
1
if firstChar
is '}'
@pair firstChar
- @token
')',
')'
+
if @csxObjAttribute[@csxDepth]
+ @token
'}',
'}'
+ @csxObjAttribute[@csxDepth] =
no
+
else
+ @token
')',
')'
@token
',',
','
return 1
else
@@ -1060,11 +1232,11 @@ The slash is removed here once its job is done.
-
+
We treat all other single characters as a token. E.g.: ( ) , . !
Multi-character operators are also literal tokens, so that Jison can assign
@@ -1135,11 +1307,11 @@ parentheses that indicate a method call from regular parentheses, and so on.
-
+
Token Manipulators
@@ -1148,11 +1320,11 @@ parentheses that indicate a method call from regular parentheses, and so on.
-
+
@@ -1160,11 +1332,11 @@ parentheses that indicate a method call from regular parentheses, and so on.
-
+
A source of ambiguity in our grammar used to be parameter lists in function
definitions versus argument lists in function calls. Walk backwards, tagging
@@ -1196,11 +1368,11 @@ parameters specially in order to make things easier for the parser.
-
+
Close up all remaining open blocks at the end of the file.
@@ -1212,11 +1384,11 @@ parameters specially in order to make things easier for the parser.
-
+
Match the contents of a delimited token and expand variables and expressions
inside it using Ruby-like notation for substitution of arbitrary
@@ -1254,11 +1426,11 @@ ad infinitum.
-
+
Push a fake 'NEOSTRING'
token, which will get turned into a real string later.
@@ -1275,11 +1447,11 @@ ad infinitum.
-
+
To remove the #
in #{
.
@@ -1294,11 +1466,11 @@ ad infinitum.
-
+
Account for the #
in #{
@@ -1312,11 +1484,11 @@ ad infinitum.
-
+
Turn the leading and trailing {
and }
into parentheses. Unnecessary
parentheses will be removed later.
@@ -1331,11 +1503,11 @@ parentheses will be removed later.
-
+
Remove leading 'TERMINATOR'
(if any).
@@ -1348,11 +1520,11 @@ parentheses will be removed later.
-
+
We are not using {
and }
, so wrap the interpolated tokens instead.
@@ -1365,11 +1537,11 @@ parentheses will be removed later.
-
+
Push a fake 'TOKENS'
token, which will get turned into real tokens later.
@@ -1397,11 +1569,11 @@ parentheses will be removed later.
-
+
Merge the array tokens
of the fake token types 'TOKENS'
and 'NEOSTRING'
(as returned by matchWithInterpolations
) into the token stream. The value
@@ -1423,11 +1595,11 @@ of 'NEOSTRING'
s are converted using fn
and tur
-
+
Optimize out empty interpolations (an empty pair of parentheses).
@@ -1438,11 +1610,11 @@ of
'NEOSTRING'
s are converted using
fn
and tur
-
+
Push all the tokens in the fake 'TOKENS'
token. These already have
sane location data.
@@ -1456,11 +1628,11 @@ sane location data.
-
+
Convert 'NEOSTRING'
into 'STRING'
.
@@ -1471,11 +1643,11 @@ sane location data.
-
+
Optimize out empty strings. We ensure that the tokens stream always
starts with a string token, though, to make sure that the result
@@ -1492,11 +1664,11 @@ really is a string.
-
+
However, there is one case where we can optimize away a starting
empty string.
@@ -1514,11 +1686,11 @@ empty string.
-
+
Create a 0-length “+” token.
@@ -1540,6 +1712,7 @@ empty string.
last_line: lastToken[
2].last_line
last_column: lastToken[
2].last_column
]
+ lparen[
2] = lparen.origin[
2]
rparen = @token
'STRING_END',
')'
rparen[
2] =
first_line: lastToken[
2].last_line
@@ -1550,11 +1723,11 @@ empty string.
-
+
Pairs up a closing token, ensuring that all listed pairs of tokens are
correctly balanced throughout the course of the token stream.
@@ -1569,11 +1742,11 @@ correctly balanced throughout the course of the token stream.
-
+
Auto-close INDENT
to support syntax like this:
el.click((event) ->
@@ -1589,11 +1762,11 @@ correctly balanced throughout the course of the token stream.
-
+
Helpers
@@ -1602,11 +1775,11 @@ correctly balanced throughout the course of the token stream.
-
+
@@ -1614,11 +1787,11 @@ correctly balanced throughout the course of the token stream.
-
+
Returns the line and column number from an offset into the current chunk.
offset
is a number of characters into @chunk
.
@@ -1648,11 +1821,11 @@ correctly balanced throughout the course of the token stream.
-
+
Same as token
, except this just returns the token without adding it
to the results.
@@ -1667,11 +1840,11 @@ to the results.
-
+
Use length - 1 for the final offset - we’re supplying the last_line and the last_column,
so if last_column == first_column, then we’re looking at a character of length 1.
@@ -1689,11 +1862,11 @@ so if last_column == first_column, then we’re looking at a character of length
-
+
Add a token to the results.
offset
is the offset into the current @chunk
where the token starts.
@@ -1712,11 +1885,11 @@ not specified, the length of value
will be used.
-
+
Peek at the last tag in the token stream.
@@ -1729,11 +1902,11 @@ not specified, the length of
value
will be used.
-
+
Peek at the last value in the token stream.
@@ -1746,11 +1919,11 @@ not specified, the length of
value
will be used.
-
+
Get the previous token in the token stream.
@@ -1762,11 +1935,11 @@ not specified, the length of
value
will be used.
-
+
Are we in the midst of an unfinished expression?
@@ -1774,9 +1947,7 @@ not specified, the length of
value
will be used.
unfinished: ->
LINE_CONTINUER.test(@chunk) or
- @tag() in ['\\', '.', '?.', '?::', 'UNARY', 'MATH', 'UNARY_MATH', '+', '-',
- '**', 'SHIFT', 'RELATION', 'COMPARE', '&', '^', '|', '&&', '||',
- 'BIN?', 'THROW', 'EXTENDS', 'DEFAULT']
+ @tag() in UNFINISHED
formatString: (str, options) ->
@replaceUnicodeCodePointEscapes str.replace(STRING_OMIT, '$1'), options
@@ -1796,11 +1967,11 @@ not specified, the length of value
will be used.
-
+
surrogate pair
@@ -1813,11 +1984,11 @@ not specified, the length of
value
will be used.
-
+
Replace \u{...}
with \uxxxx[\uxxxx]
in regexes without u
flag
@@ -1840,11 +2011,11 @@ not specified, the length of
value
will be used.
-
+
Validates escapes in strings and regexes.
@@ -1872,11 +2043,11 @@ not specified, the length of
value
will be used.
-
+
Constructs a string or regex by escaping certain characters.
@@ -1896,11 +2067,11 @@ not specified, the length of
value
will be used.
-
+
Ignore escaped backslashes.
@@ -1919,11 +2090,11 @@ not specified, the length of
value
will be used.
-
+
Throws an error at either a given offset from the current chunk or at the
location of a token (token[2]
).
@@ -1942,11 +2113,11 @@ location of a token (
token[2]
).
-
+
Helper functions
@@ -1955,11 +2126,11 @@ location of a token (
token[2]
).
-
+
@@ -1980,11 +2151,11 @@ exports.isUnassignable = isUnassignable
-
+
from
isn’t a CoffeeScript keyword, but it behaves like one in import
and
export
statements (handled above) and in the declaration line of a for
@@ -1999,11 +2170,11 @@ loop. Try to detect when from
is a variable identifier and when it
-
+
for i from from
, for from from iterable
@@ -2016,11 +2187,11 @@ loop. Try to detect when
from
is a variable identifier and when it
-
+
for i from iterable
@@ -2031,11 +2202,11 @@ loop. Try to detect when
from
is a variable identifier and when it
-
+
for from…
@@ -2047,11 +2218,11 @@ loop. Try to detect when
from
is a variable identifier and when it
-
+
for {from}…
, for [from]…
, for {a, from}…
, for {a: from}…
@@ -2065,11 +2236,11 @@ loop. Try to detect when
from
is a variable identifier and when it
-
+
Constants
@@ -2078,11 +2249,11 @@ loop. Try to detect when
from
is a variable identifier and when it
-
+
@@ -2090,11 +2261,11 @@ loop. Try to detect when from
is a variable identifier and when it
-
+
Keywords that CoffeeScript shares in common with JavaScript.
@@ -2112,11 +2283,11 @@ loop. Try to detect when
from
is a variable identifier and when it
-
+
CoffeeScript-only keywords.
@@ -2144,11 +2315,11 @@ COFFEE_KEYWORDS = COFFEE_KEYWORDS.concat COFFEE_ALIASES
-
+
The list of keywords that are reserved by JavaScript, but not used, or are
used by CoffeeScript internally. We throw an error when these are encountered,
@@ -2167,11 +2338,11 @@ STRICT_PROSCRIBED = ['arguments',
+
The superset of both JavaScript keywords and reserved words, none of which may
be used as identifiers or properties.
@@ -2183,11 +2354,11 @@ be used as identifiers or properties.
-
+
The character code of the nasty Microsoft madness otherwise known as the BOM.
@@ -2198,11 +2369,11 @@ be used as identifiers or properties.
-
+
Token matching regexes.
@@ -2244,7 +2415,7 @@ OPERATOR =
/// ^ (
WHITESPACE = /^[^\n\S]+/
-COMMENT = /^###([^#][\s\S]*?)(?:###[^\n\S]*|###$)|^(?:\s*#(?!##[^#]).*)+/
+COMMENT = /^\s*###([^#][\s\S]*?)(?:###[^\n\S]*|###$)|^(?:\s*#(?!##[^#]).*)+/
CODE = /^[-=]>/
@@ -2256,11 +2427,11 @@ HERE_JSTOKEN = ///^ ``` ((?: [^`\\] | \\[\s\S] | `
-
+
String-matching-regexes.
@@ -2294,11 +2465,11 @@ HEREDOC_INDENT =
/\n+([^\n\S]*)(?=\S)/g
-
+
Regex-matching-regexes.
@@ -2332,11 +2503,11 @@ POSSIBLY_DIVISION =
/// ^ /=?\s ///
-
+
Other regexes.
@@ -2379,11 +2550,11 @@ TRAILING_SPACES =
/\s+$/
-
+
Compound assignment tokens.
@@ -2397,11 +2568,11 @@ TRAILING_SPACES =
/\s+$/
-
+
Unary tokens.
@@ -2414,11 +2585,11 @@ UNARY_MATH = [
'!',
'~
-
+
Bit-shifting tokens.
@@ -2429,11 +2600,11 @@ UNARY_MATH = [
'!',
'~
-
+
Comparison tokens.
@@ -2444,11 +2615,11 @@ UNARY_MATH = [
'!',
'~
-
+
Mathematical tokens.
@@ -2459,11 +2630,11 @@ UNARY_MATH = [
'!',
'~
-
+
Relational tokens that are negatable with not
prefix.
@@ -2474,11 +2645,11 @@ UNARY_MATH = [
'!',
'~
-
+
Boolean tokens.
@@ -2489,11 +2660,11 @@ UNARY_MATH = [
'!',
'~
-
+
Tokens which could legitimately be invoked or indexed. An opening
parentheses or bracket following these tokens will be recorded as the start
@@ -2510,11 +2681,11 @@ INDEXABLE = CALLABLE.concat [
-
+
Tokens which can be the left-hand side of a less-than comparison, i.e. a<b
.
@@ -2525,11 +2696,11 @@ INDEXABLE = CALLABLE.concat [
-
+
Tokens which a regular expression will never immediately follow (except spaced
CALLABLEs in some cases), but which a division operator can.
@@ -2542,11 +2713,11 @@ CALLABLEs in some cases), but which a division operator can.
-
+
Tokens that, when immediately preceding a WHEN
, indicate that the WHEN
occurs at the start of a line. We disambiguate these from trailing whens to
@@ -2559,11 +2730,11 @@ avoid an ambiguity in the grammar.
-
+
Additional indent in front of these is ignored.
@@ -2573,6 +2744,23 @@ avoid an ambiguity in the grammar.
+
+
+
+
+
+
Tokens that, when appearing at the end of a line, suppress a following TERMINATOR/INDENT token
+
+
+
+ UNFINISHED = ['\\', '.', '?.', '?::', 'UNARY', 'MATH', 'UNARY_MATH', '+', '-',
+ '**', 'SHIFT', 'RELATION', 'COMPARE', '&', '^', '|', '&&', '||',
+ 'BIN?', 'EXTENDS', 'DEFAULT']
+
+
+