Statement: [
o 'Return'
- o 'Comment'
o 'STATEMENT', -> new StatementLiteral $1
o 'Import'
o 'Export'
@@ -404,7 +404,6 @@ Grammatical Rules
Expression: [
o 'Value'
- o 'Invocation'
o 'Code'
o 'Operation'
o 'Assign'
@@ -500,11 +499,11 @@ Grammatical Rules
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 @@ Grammatical Rules
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 @@ Grammatical Rules
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 @@ Grammatical Rules
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 @@ Grammatical Rules
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 @@ Grammatical Rules
- 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 @@
Grammatical Rules
-
+
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 @@
Grammatical Rules
FuncGlyph: [
- o '->', -> 'func'
- o '=>', -> 'boundfunc'
+ o '->', -> new FuncGlyph $1
+ o '=>', -> new FuncGlyph $1
]
-
+
An optional, trailing comma.
@@ -705,11 +694,11 @@
Grammatical Rules
-
+
The list of parameters that a function accepts can be of any length.
@@ -726,11 +715,11 @@
Grammatical Rules
-
+
A single parameter in a function definition can be ordinary, or a splat
that hoovers up the remaining arguments.
@@ -740,6 +729,7 @@
Grammatical Rules
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 @@
Grammatical Rules
-
+
Function Parameters
@@ -767,11 +757,11 @@
Grammatical Rules
-
+
A splat that occurs outside of a parameter list.
@@ -779,16 +769,17 @@
Grammatical Rules
Splat: [
o 'Expression ...', -> new Splat $1
+ o '... Expression', -> new Splat $2
]
-
+
Variables and properties that can be assigned to.
@@ -797,18 +788,17 @@
Grammatical Rules
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 @@
Grammatical Rules
-
+
The types of things that can be treated as values – assigned to, invoked
as functions, indexed into, named as a class, etc.
@@ -839,36 +829,37 @@
Grammatical Rules
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
- o 'SUPER INDEX_START Expression INDEX_END', -> new Super LOC(3) new Index $3
+ 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
]
-
+
The general group of accessors into an object, by property, by prototype
or by array index or slice.
@@ -887,11 +878,11 @@
Grammatical Rules
-
+
Indexing into an object or array using bracket notation.
@@ -899,7 +890,7 @@
Grammatical Rules
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 @@ Grammatical Rules
-
+
In CoffeeScript, an object literal is simply a list of assignments.
@@ -927,11 +918,11 @@
Grammatical Rules
-
+
Assignment of properties within an object literal can be separated by
comma, as in JavaScript, or simply by newline.
@@ -949,11 +940,11 @@
Grammatical Rules
-
+
Class definitions have optional bodies of prototype property assignments,
and optional references to the superclass.
@@ -1038,11 +1029,11 @@
Grammatical Rules
-
+
Ordinary function invocation, or a chained series of calls.
@@ -1051,18 +1042,17 @@
Grammatical Rules
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 @@
Grammatical Rules
-
+
The list of arguments to a function call.
@@ -1094,46 +1084,46 @@
Grammatical Rules
-
+
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), [LOC(2)(new Access($2))], 'this'
+ o '@ Property', -> new Value LOC(1)(new ThisLiteral $1), [LOC(2)(new Access($2))], 'this'
]
-
+
The array literal.
@@ -1147,11 +1137,11 @@
Grammatical Rules
-
+
Inclusive and exclusive range dots.
@@ -1165,11 +1155,11 @@
Grammatical Rules
-
+
The CoffeeScript range literal.
@@ -1182,11 +1172,11 @@
Grammatical Rules
-
+
Array slice literals.
@@ -1202,11 +1192,11 @@
Grammatical Rules
-
+
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 @@
Grammatical Rules
-
+
Valid arguments are Blocks or Splats.
@@ -1244,11 +1234,11 @@
Grammatical Rules
-
+
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 @@
Grammatical Rules
-
+
The variants of try/catch/finally exception handling blocks.
@@ -1284,11 +1274,11 @@
Grammatical Rules
-
+
A catch clause names its error and runs a block of code.
@@ -1303,11 +1293,11 @@
Grammatical Rules
-
+
Throw an exception object.
@@ -1315,16 +1305,17 @@
Grammatical Rules
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 @@
Grammatical Rules
-
+
The condition portion of a while loop.
@@ -1361,11 +1352,11 @@
Grammatical Rules
-
+
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 @@
Grammatical Rules
-
+
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 @@
Grammatical Rules
-
+
An array of all accepted values for a variable inside the loop.
This enables support for pattern matching.
@@ -1440,11 +1431,11 @@
Grammatical Rules
-
+
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 @@
Grammatical Rules
-
+
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 @@
Grammatical Rules
-
+
An individual When clause, with action.
@@ -1517,11 +1508,11 @@
Grammatical Rules
-
+
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 @@
Grammatical Rules
-
+
The full complement of if expressions, including postfix one-liner
if and unless.
@@ -1558,11 +1549,11 @@
Grammatical Rules
-
+
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 @@
Grammatical Rules
-
+
The existential operator.
@@ -1631,11 +1622,11 @@
Grammatical Rules
-
+
Precedence
@@ -1644,11 +1635,11 @@
Precedence
-
+
@@ -1656,11 +1647,11 @@ Precedence
-
+
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:
@@ -1701,11 +1692,11 @@
Precedence
-
+
Wrapping Up
@@ -1714,11 +1705,11 @@
Wrapping Up
-
+
@@ -1726,11 +1717,11 @@ Wrapping Up
-
+
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
@@ -1750,11 +1741,11 @@
Wrapping Up
-
+
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 4622362470..834df0d9d4 100644
--- a/docs/v2/annotated-source/helpers.html
+++ b/docs/v2/annotated-source/helpers.html
@@ -382,7 +382,10 @@
helpers.coffee
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 @@
helpers.coffee
- 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 @@
helpers.coffee
+
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 @@
helpers.coffee
-
+
A .coffee.md
compatible version of basename
, that returns the file sans-extension.
@@ -456,11 +505,11 @@
helpers.coffee
-
+
Determine if a filename represents a CoffeeScript file.
@@ -471,11 +520,11 @@
helpers.coffee
-
+
Determine if a filename represents a Literate CoffeeScript file.
@@ -486,11 +535,11 @@
helpers.coffee
-
+
Throws a SyntaxError from a given location.
The error’s toString
will return an error message following the “standard”
@@ -507,11 +556,11 @@
helpers.coffee
-
+
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 @@
helpers.coffee
-
+
Update a compiler SyntaxError with source code information if it didn’t have
it already.
@@ -542,11 +591,11 @@
helpers.coffee
-
+
Avoid screwing up the stack
property of other errors (i.e. possible bugs).
@@ -572,11 +621,11 @@
helpers.coffee
-
+
Show only the first line on multi-line errors.
@@ -588,11 +637,11 @@
helpers.coffee
-
+
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 12aab1e4c4..2fe6eb2bde 100644
--- a/docs/v2/annotated-source/lexer.html
+++ b/docs/v2/annotated-source/lexer.html
@@ -143,7 +143,7 @@
lexer.coffee
{count, starts, compact, repeat, invertLiterate, merge,
-locationDataToString, throwSyntaxError} = require './helpers'
+attachCommentsToNode, locationDataToString, throwSyntaxError} = require './helpers'
@@ -210,19 +210,20 @@
The Lexer Class
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 @@ The Lexer Class
- Update position
+ Update position.
@@ -392,6 +393,12 @@
Tokenizers
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 @@
Tokenizers
-
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 @@
Tokenizers
+
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 @@ Tokenizers
-
+
Convert escaped backticks to backticks, and escaped backslashes
just before escaped backticks to backslashes
@@ -680,11 +806,11 @@
Tokenizers
-
+
string
is always a value like ‘`‘, ‘\`‘, ‘\\`‘, etc.
By reducing it to its latter half, we turn ‘`‘ to ‘', '\\\
‘ to ‘`‘, etc.
@@ -698,11 +824,11 @@
Tokenizers
-
+
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 @@
Tokenizers
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 @@
Tokenizers
-
+
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 @@
Tokenizers
- 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 @@ Tokenizers
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 @@ Tokenizers
-
+
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 @@
Tokenizers
-
+
pair might call outdentToken, so preserve decreasedIndent
@@ -882,11 +1010,11 @@
Tokenizers
-
+
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 @@
Tokenizers
-
+
Generate a newline token. Consecutive newlines get merged together.
@@ -921,11 +1049,11 @@
Tokenizers
-
+
Use a \
at a line-ending to suppress the newline.
The slash is removed here once its job is done.
@@ -933,24 +1061,59 @@
Tokenizers
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 @@ Tokenizers
-
+
Not the right hand side of an unspaced comparison (i.e. a<b
).
@@ -976,19 +1139,24 @@
Tokenizers
[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 @@
Tokenizers
-
+
Ignore terminators inside a tag.
@pair '/>'
- origin = @token '}', '}'
+ origin = @token ']', ']'
@token ',', ','
{tokens, index: end} =
@matchWithInterpolations INSIDE_CSX, '>', '</', CSX_INTERPOLATION
@@ -1024,11 +1192,11 @@ Tokenizers
-
+
+1 for the closing >
.
@@ -1042,7 +1210,11 @@
Tokenizers
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 @@
Tokenizers
-
+
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 @@
Tokenizers
-
+
Token Manipulators
@@ -1148,11 +1320,11 @@
Token Manipulators
-
+
@@ -1160,11 +1332,11 @@ Token Manipulators
-
+
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 @@
Token Manipulators
-
+
Close up all remaining open blocks at the end of the file.
@@ -1212,11 +1384,11 @@
Token Manipulators
-
+
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 @@
Token Manipulators
-
+
Push a fake 'NEOSTRING'
token, which will get turned into a real string later.
@@ -1275,11 +1447,11 @@
Token Manipulators
-
+
To remove the #
in #{
.
@@ -1294,11 +1466,11 @@
Token Manipulators
-
+
Account for the #
in #{
@@ -1312,11 +1484,11 @@
Token Manipulators
-
+
Turn the leading and trailing {
and }
into parentheses. Unnecessary
parentheses will be removed later.
@@ -1331,11 +1503,11 @@
Token Manipulators
-
+
Remove leading 'TERMINATOR'
(if any).
@@ -1348,11 +1520,11 @@
Token Manipulators
-
+
We are not using {
and }
, so wrap the interpolated tokens instead.
@@ -1365,11 +1537,11 @@
Token Manipulators
-
+
Push a fake 'TOKENS'
token, which will get turned into real tokens later.
@@ -1397,11 +1569,11 @@
Token Manipulators
-
+
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 @@
Token Manipulators
-
+
Optimize out empty interpolations (an empty pair of parentheses).
@@ -1438,11 +1610,11 @@
Token Manipulators
-
+
Push all the tokens in the fake 'TOKENS'
token. These already have
sane location data.
@@ -1456,11 +1628,11 @@
Token Manipulators
-
+
Convert 'NEOSTRING'
into 'STRING'
.
@@ -1471,11 +1643,11 @@
Token Manipulators
-
+
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 @@
Token Manipulators
-
+
However, there is one case where we can optimize away a starting
empty string.
@@ -1514,11 +1686,11 @@
Token Manipulators
-
+
Create a 0-length “+” token.
@@ -1540,6 +1712,7 @@
Token Manipulators
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 @@
Token Manipulators
-
+
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 @@
Token Manipulators
-
+
Auto-close INDENT
to support syntax like this:
el.click((event) ->
@@ -1589,11 +1762,11 @@ Token Manipulators
-
+
Helpers
@@ -1602,11 +1775,11 @@
Helpers
-
+
@@ -1614,11 +1787,11 @@ Helpers
-
+
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 @@
Helpers
-
+
Same as token
, except this just returns the token without adding it
to the results.
@@ -1667,11 +1840,11 @@
Helpers
-
+
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 @@
Helpers
-
+
Add a token to the results.
offset
is the offset into the current @chunk
where the token starts.
@@ -1712,11 +1885,11 @@
Helpers
-
+
Peek at the last tag in the token stream.
@@ -1729,11 +1902,11 @@
Helpers
-
+
Peek at the last value in the token stream.
@@ -1746,11 +1919,11 @@
Helpers
-
+
Get the previous token in the token stream.
@@ -1762,11 +1935,11 @@
Helpers
-
+
Are we in the midst of an unfinished expression?
@@ -1774,9 +1947,7 @@
Helpers
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 @@ Helpers
-
+
surrogate pair
@@ -1813,11 +1984,11 @@
Helpers
-
+
Replace \u{...}
with \uxxxx[\uxxxx]
in regexes without u
flag
@@ -1840,11 +2011,11 @@
Helpers
-
+
Validates escapes in strings and regexes.
@@ -1872,11 +2043,11 @@
Helpers
-
+
Constructs a string or regex by escaping certain characters.
@@ -1896,11 +2067,11 @@
Helpers
-
+
Ignore escaped backslashes.
@@ -1919,11 +2090,11 @@
Helpers
-
+
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 @@
Helpers
-
+
Helper functions
@@ -1955,11 +2126,11 @@
Helper functions
-
+
@@ -1980,11 +2151,11 @@ Helper functions
-
+
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 @@
Helper functions
-
+
for i from from
, for from from iterable
@@ -2016,11 +2187,11 @@
Helper functions
-
+
for i from iterable
@@ -2031,11 +2202,11 @@
Helper functions
-
+
for from…
@@ -2047,11 +2218,11 @@
Helper functions
-
+
for {from}…
, for [from]…
, for {a, from}…
, for {a: from}…
@@ -2065,11 +2236,11 @@
Helper functions
-
+
Constants
@@ -2078,11 +2249,11 @@
Constants
-
+
@@ -2090,11 +2261,11 @@ Constants
-
+
Keywords that CoffeeScript shares in common with JavaScript.
@@ -2112,11 +2283,11 @@
Constants
-
+
CoffeeScript-only keywords.
@@ -2144,11 +2315,11 @@
Constants
-
+
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 @@
Constants
-
+
The superset of both JavaScript keywords and reserved words, none of which may
be used as identifiers or properties.
@@ -2183,11 +2354,11 @@
Constants
-
+
The character code of the nasty Microsoft madness otherwise known as the BOM.
@@ -2198,11 +2369,11 @@
Constants
-
+
Token matching regexes.
@@ -2244,7 +2415,7 @@
Constants
WHITESPACE =
/^[^\n\S]+/
-COMMENT =
/^###([^#][\s\S]*?)(?:###[^\n\S]*|###$)|^(?:\s*#(?!##[^#]).*)+/
+COMMENT =
/^\s*###([^#][\s\S]*?)(?:###[^\n\S]*|###$)|^(?:\s*#(?!##[^#]).*)+/
CODE =
/^[-=]>/
@@ -2256,11 +2427,11 @@
Constants
-
+
String-matching-regexes.
@@ -2294,11 +2465,11 @@
Constants
-
+
Regex-matching-regexes.
@@ -2332,11 +2503,11 @@
Constants
-
+
Other regexes.
@@ -2379,11 +2550,11 @@
Constants
-
+
Compound assignment tokens.
@@ -2397,11 +2568,11 @@
Constants
-
+
Unary tokens.
@@ -2414,11 +2585,11 @@
Constants
-
+
Bit-shifting tokens.
@@ -2429,11 +2600,11 @@
Constants
-
+
Comparison tokens.
@@ -2444,11 +2615,11 @@
Constants
-
+
Mathematical tokens.
@@ -2459,11 +2630,11 @@
Constants
-
+
Relational tokens that are negatable with not
prefix.
@@ -2474,11 +2645,11 @@
Constants
-
+
Boolean tokens.
@@ -2489,11 +2660,11 @@
Constants
-
+
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 @@
Constants
-
+
Tokens which can be the left-hand side of a less-than comparison, i.e. a<b
.
@@ -2525,11 +2696,11 @@
Constants
-
+
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 @@
Constants
-
+
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 @@
Constants
-
+
Additional indent in front of these is ignored.
@@ -2573,6 +2744,23 @@
Constants
+
+
+
+
+
+
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']
+
+
+