CSX_FRAGMENT_IDENTIFIER = /// ^
+ ()>
///
CSX_ATTRIBUTE = /// ^
@@ -2497,11 +2514,11 @@ HERE_JSTOKEN = ///^ ``` ((?: [^`\\] | \\[\s\S] | `
-
+
String-matching-regexes.
@@ -2535,11 +2552,11 @@ HEREDOC_INDENT =
/\n+([^\n\S]*)(?=\S)/g
-
+
Regex-matching-regexes.
@@ -2558,7 +2575,86 @@ HEREDOC_INDENT =
/\n+([^\n\S]*)(?=\S)/g/^\w*/
VALID_FLAGS =
/^(?!.*(.).*\1)[imguy]*$/
-HEREGEX =
/// ^(?: [^\\/
+HEREGEX = /// ^
+ (?:
+
+
+
+
+
+
+
+
+
+
Match any character, except those that need special handling below.
+
+
+
+
+
+
+
+
+
+
+
+
+
Match \ followed by any character.
+
+
+
+
+
+
+
+
+
+
+
+
+
Match any / except ///.
+
+
+
+
+
+
+
+
+
+
+
+
+
Match # which is not part of interpolation, e.g. #{}.
+
+
+
+
+
+
+
+
+
+
+
+
+
Comments consume everything until the end of the line, including ///.
+
+
+
+ | \s+(?:
+ )*
+///
HEREGEX_OMIT = ///
((?:\\\\)+)
@@ -2573,11 +2669,11 @@ POSSIBLY_DIVISION = /// ^ /=?\s ///
-
+
Other regexes.
@@ -2620,11 +2716,11 @@ TRAILING_SPACES =
/\s+$/
-
+
Compound assignment tokens.
@@ -2638,11 +2734,11 @@ TRAILING_SPACES =
/\s+$/
-
+
Unary tokens.
@@ -2655,11 +2751,11 @@ UNARY_MATH = [
'!',
'~
-
+
Bit-shifting tokens.
@@ -2670,11 +2766,11 @@ UNARY_MATH = [
'!',
'~
-
+
Comparison tokens.
@@ -2685,11 +2781,11 @@ UNARY_MATH = [
'!',
'~
-
+
Mathematical tokens.
@@ -2700,11 +2796,11 @@ UNARY_MATH = [
'!',
'~
-
+
Relational tokens that are negatable with not prefix.
@@ -2715,11 +2811,11 @@ UNARY_MATH = [
'!',
'~
-
+
Boolean tokens.
@@ -2730,11 +2826,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
@@ -2751,11 +2847,11 @@ INDEXABLE = CALLABLE.concat [
-
+
Tokens which can be the left-hand side of a less-than comparison, i.e. a<b.
@@ -2766,11 +2862,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.
@@ -2783,11 +2879,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
@@ -2800,11 +2896,11 @@ avoid an ambiguity in the grammar.
-
+
Additional indent in front of these is ignored.
@@ -2815,11 +2911,11 @@ avoid an ambiguity in the grammar.
-
+
Tokens that, when appearing at the end of a line, suppress a following TERMINATOR/INDENT token
diff --git a/docs/v2/annotated-source/nodes.html b/docs/v2/annotated-source/nodes.html
index d3ebd8eb..488b3c13 100644
--- a/docs/v2/annotated-source/nodes.html
+++ b/docs/v2/annotated-source/nodes.html
@@ -1748,6 +1748,10 @@ exports.CSXTag =
classclass PropertyName extends Literal
isAssignable: YES
+exports.ComputedPropertyName =
class ComputedPropertyName extends PropertyName
+ compileNode:
(o) ->
+ [@makeCode(
'['), @value.compileToFragments(o, LEVEL_LIST)..., @makeCode(
']')]
+
exports.StatementLiteral =
class StatementLiteral extends Literal
isStatement: YES
@@ -2013,6 +2017,10 @@ to be on
foo.
return no if @properties.length
(@base
instanceof Obj)
and (
not onlyGenerated
or @base.generated)
+ isElision:
->
+
return no unless @base
instanceof Arr
+ @base.hasElision()
+
isSplice:
->
[..., lastProp] = @properties
lastProp
instanceof Slice
@@ -3231,6 +3239,41 @@ are too.
[key, value] = prop.base.cache o
key =
new PropertyName key.value
if key
instanceof IdentifierLiteral
prop =
new Assign key, value,
'object'
+
else if key
instanceof Value
and key.base
instanceof ComputedPropertyName
+
+
+
+
+
+
+
+
+
{ [foo()] } output as { [ref = foo()]: ref }.
+
+
+
+ if prop.base.value.shouldCache()
+ [key, value] = prop.base.value.cache o
+ key = new ComputedPropertyName key.value if key instanceof IdentifierLiteral
+ prop = new Assign key, value, 'object'
+ else
+
+
+
+
+
+
+
+
+
{ [expression] } output as { [expression]: expression }.
+
+
+
+ prop = new Assign key, prop.base.value, 'object'
else if not prop.bareLiteral?(IdentifierLiteral)
prop = new Assign prop, prop, 'object'
if indent then answer.push @makeCode indent
@@ -3253,11 +3296,11 @@ are too.
-
+
Object spread properties. https://github.com/tc39/proposal-object-rest-spread/blob/master/Spread.md
obj2 = {a: 1, obj..., c: 3, d: 4} → obj2 = _extends({}, {a: 1}, obj, {c: 3, d: 4})
@@ -3270,11 +3313,11 @@ are too.
-
+
Store object spreads.
@@ -3313,11 +3356,11 @@ are too.
-
+
Arr
@@ -3326,11 +3369,11 @@ are too.
-
+
An array literal.
@@ -3343,6 +3386,10 @@ are too.
children: [
'objects']
+ hasElision:
->
+
return yes for obj
in @objects
when obj
instanceof Elision
+
no
+
isAssignable:
->
return no unless @objects.length
@@ -3357,6 +3404,22 @@ are too.
compileNode:
(o) ->
return [@makeCode
'[]']
unless @objects.length
o.indent += TAB
+
fragmentIsElision = (fragment) -> fragmentsToText(fragment).trim()
is ','
+
+
+
+
+
+
+
+
+
Detect if Elisions at the beginning of the array are processed (e.g. [, , , a]).
+
+
+
+ passedElision = no
answer = []
for obj, objIndex in @objects
@@ -3365,11 +3428,11 @@ are too.
-
+
Let compileCommentFragments know to intersperse block comments
into the fragments created when compiling this array.
@@ -3383,11 +3446,11 @@ into the fragments created when compiling this array.
-
+
If this array is the left-hand side of an assignment, all its children
are too.
@@ -3397,16 +3460,17 @@ are too.
if @lhs
unwrappedObj.lhs = yes if unwrappedObj instanceof Arr or unwrappedObj instanceof Obj
- compiledObjs = (obj.compileToFragments o, LEVEL_LIST for obj in @objects)
+ compiledObjs = (obj.compileToFragments o, LEVEL_LIST
for obj
in @objects)
+ olen = compiledObjs.length
-
+
If compiledObjs includes newlines, we will output this as a multiline
array (i.e. with a newline and indentation after the [). If an element
@@ -3424,15 +3488,31 @@ first element’s line comments get output before or after the array.
if fragment.isHereComment
fragment.code = fragment.code.trim()
else if index
isnt 0 and includesLineCommentsOnNonFirstElement
is no and hasLineComments fragment
- includesLineCommentsOnNonFirstElement =
yes
-
if index
isnt 0
+ includesLineCommentsOnNonFirstElement =
yes
+
+
+
+
+
+
+
+
+
Add ‘, ‘ if all Elisions from the beginning of the array are processed (e.g. [, , , a]) and
+element isn’t Elision or last element is Elision (e.g. [a,,b,,])
+
+
+
+ if index isnt 0 and passedElision and (not fragmentIsElision(fragments) or index is olen - 1)
answer.push @makeCode ', '
+ passedElision = passedElision or not fragmentIsElision fragments
answer.push fragments...
if includesLineCommentsOnNonFirstElement or '\n' in fragmentsToText(answer)
for fragment, fragmentIndex in answer
if fragment.isHereComment
fragment.code = "#{multident(fragment.code, o.indent, no)}\n#{o.indent}"
- else if fragment.code is ', '
+ else if fragment.code is ', ' and not fragment?.isElision
fragment.code = ",\n#{o.indent}"
answer.unshift @makeCode "[\n#{o.indent}"
answer.push @makeCode "\n#{@tab}]"
@@ -3455,11 +3535,11 @@ first element’s line comments get output before or after the array.
-
+
Class
@@ -3468,11 +3548,11 @@ first element’s line comments get output before or after the array.
-
+
The CoffeeScript class definition.
Initialize a Class with its name, an optional superclass, and a body.
@@ -3493,11 +3573,11 @@ exports.Class =
class
-
+
Special handling to allow class expr.A extends A declarations
@@ -3515,11 +3595,11 @@ exports.Class =
class
-
+
Anonymous classes are only valid in expressions
@@ -3568,11 +3648,11 @@ exports.Class =
class
-
+
Figure out the appropriate name for this class
@@ -3643,11 +3723,11 @@ exports.Class =
class
-
+
Add an expression to the class initializer
This is the key method for determining whether an expression in a class
@@ -3676,11 +3756,11 @@ opposed to the Object.defineProperty method).
-
+
Checks if the given node is a valid ES class initializer method.
@@ -3694,11 +3774,11 @@ opposed to the
Object.defineProperty method).
-
+
Returns a configured class initializer method
@@ -3795,11 +3875,11 @@ exports.ExecutableClassBody =
+
Traverse the class’s children and:
@@ -3847,11 +3927,11 @@ exports.ExecutableClassBody =
+ -
Make class/prototype assignments for invalid ES properties
@@ -3871,11 +3951,11 @@ exports.ExecutableClassBody =
+ -
The class scope is not available yet, so return the assignment to update later
@@ -3897,11 +3977,11 @@ exports.ExecutableClassBody =
+ -
Import and Export
@@ -3975,11 +4055,11 @@ exports.ExportDeclaration =
- -
+
-
Prevent exporting an anonymous class; all exported members must be named
@@ -4043,11 +4123,11 @@ exports.ModuleSpecifier =
cl
- -
+
-
The name of the variable entering the local scope
@@ -4073,11 +4153,11 @@ exports.ImportSpecifier =
cl
- -
+
-
Per the spec, symbols can’t be imported multiple times
(e.g. import { foo, foo } from 'lib' is invalid)
@@ -4101,11 +4181,11 @@ exports.ExportSpecifier =
cl
- -
+
-
Assign
@@ -4114,11 +4194,11 @@ exports.ExportSpecifier =
cl
- -
+
-
The Assign is used to assign a local variable to value, or to set the
property of an object – including within object literals.
@@ -4151,11 +4231,11 @@ property of an object – including within object literals.
-
-
+
-
Compile an assignment, delegating to compileDestructuring or
compileSplice if appropriate. Keep track of the name of the base object
@@ -4171,11 +4251,11 @@ has not been seen yet within the current scope, declare it.
-
-
+
-
When compiling @variable, remember if it is part of a function parameter.
@@ -4186,11 +4266,11 @@ has not been seen yet within the current scope, declare it.
-
-
+
-
If @variable is an array or an object, we’re destructuring;
if it’s also isAssignable(), the destructuring syntax is supported
@@ -4204,11 +4284,11 @@ and convert this ES-unsupported destructuring into acceptable output.
-
-
+
-
This is the left-hand side of an assignment; let Arr and Obj
know that, so that those nodes know that they’re assignable as
@@ -4216,24 +4296,38 @@ destructured variables.
- @variable.base.lhs = yes
- return @compileDestructuring o unless @variable.isAssignable()
+
-
-
+
-
+
Check if @variable contains Obj with splats.
+
+
+
+ hasSplat = @variable.contains (node) -> node instanceof Obj and node.hasSplat()
+ return @compileDestructuring o if not @variable.isAssignable() or @variable.isArray() and hasSplat
+
+
+
+
+
-
+
+
+
Object destructuring. Can be removed once ES proposal hits Stage 4.
- objDestructAnswer = @compileObjectDestruct(o) if @variable.isObject() and @variable.contains (node) ->
- node instanceof Obj and node.hasSplat()
+ objDestructAnswer = @compileObjectDestruct(o) if @variable.isObject() and hasSplat
return objDestructAnswer if objDestructAnswer
return @compileSplice o if @variable.isSplice()
@@ -4254,11 +4348,11 @@ destructured variables.
- -
+
-
moduleDeclaration can be 'import' or 'export'.
@@ -4279,11 +4373,11 @@ destructured variables.
-
-
+
-
If this assignment identifier has one or more herecomments
attached, output them as part of the declarations line (unless
@@ -4325,11 +4419,11 @@ the comment to be between the class name and the {.
-
-
+
-
Per https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Assignment_without_declaration,
if we’re destructuring without declaring, the destructuring assignment must be wrapped in parentheses.
@@ -4346,11 +4440,11 @@ The assignment is wrapped in parentheses if ‘o.level’ has lower precedence t
-
-
+
-
Check object destructuring variable for rest elements;
can be removed once ES proposal hits Stage 4.
@@ -4362,11 +4456,11 @@ can be removed once ES proposal hits Stage 4.
-
-
+
-
Returns a safe (cached) reference to the key for a given property
@@ -4382,11 +4476,11 @@ can be removed once ES proposal hits Stage 4.
-
-
+
-
Returns the name of a given property for use with excludeProps
Property names are quoted (e.g. a: b -> ‘a’), and everything else uses the key reference
@@ -4405,11 +4499,11 @@ Property names are quoted (e.g. a: b -> ‘a’), and everything
-
-
+
-
Recursive function for searching and storing rest elements in objects.
e.g. {[properties...]} = source.
@@ -4428,11 +4522,11 @@ e.g.
{[properties...]} = source.
-
-
+
-
prop is k: expr, we need to check expr for nested splats
@@ -4443,11 +4537,11 @@ e.g.
{[properties...]} = source.
-
-
+
-
prop is k = {...}
@@ -4458,11 +4552,11 @@ e.g.
{[properties...]} = source.
-
-
+
-
prop is k: {...}
@@ -4474,11 +4568,11 @@ e.g.
{[properties...]} = source.
-
-
+
-
prop is k: {...} = default
@@ -4504,11 +4598,11 @@ e.g.
{[properties...]} = source.
-
-
+
-
Remove rest element from the properties after iteration
@@ -4521,11 +4615,11 @@ e.g.
{[properties...]} = source.
-
-
+
-
Cache the value for reuse with rest elements.
@@ -4540,11 +4634,11 @@ e.g.
{[properties...]} = source.
-
-
+
-
Find all rest elements.
@@ -4566,11 +4660,11 @@ e.g.
{[properties...]} = source.
-
-
+
-
Remove leading tab and trailing semicolon
@@ -4584,11 +4678,11 @@ e.g.
{[properties...]} = source.
-
-
+
-
Brief implementation of recursive pattern matching, when assigning array or
object literals to a value. Peeks at their properties to assign inner names.
@@ -4604,11 +4698,11 @@ object literals to a value. Peeks at their properties to assign inner names.
-
-
+
-
Special-case for {} = a and [] = a (empty patterns).
Compile to simply a.
@@ -4623,11 +4717,11 @@ Compile to simply
a.
-
-
+
-
Disallow [...] = a for some reason. (Could be equivalent to [] = a?)
@@ -4641,11 +4735,11 @@ Compile to simply
a.
-
-
+
-
Special case for when there’s only one thing destructured off of
something. {a} = b, [a] = b, {a: b} = c
@@ -4657,11 +4751,11 @@ something.
{a} = b,
[a] = b,
{a: b} = c
-
-
+
-
Pick the property straight off the value when there’s just one to pick
(no need to cache the value into a variable).
@@ -4674,11 +4768,11 @@ something.
{a} = b,
[a] = b,
{a: b} = c
-
-
+
-
A regular object pattern-match.
@@ -4697,11 +4791,11 @@ something.
{a} = b,
[a] = b,
{a: b} = c
-
-
+
-
A shorthand {a, b, @c} = val pattern-match.
@@ -4716,11 +4810,11 @@ something.
{a} = b,
[a] = b,
{a: b} = c
-
-
+
-
A regular array pattern-match.
@@ -4745,11 +4839,11 @@ something.
{a} = b,
[a] = b,
{a: b} = c
-
-
+
-
At this point, there are several things to destructure. So the fn() in
{a, b} = fn() must be cached, for example. Make vvar into a simple
@@ -4766,11 +4860,11 @@ variable if it isn’t already.
-
-
+
-
And here comes the big loop that handles all of these cases:
[a, b] = c
@@ -4819,11 +4913,11 @@ etc.
-
-
+
-
A regular object pattern-match.
@@ -4842,11 +4936,11 @@ etc.
-
-
+
-
A shorthand {a, b, @c} = val pattern-match.
@@ -4861,11 +4955,11 @@ etc.
-
-
+
-
A regular array pattern-match.
@@ -4881,7 +4975,24 @@ etc.
if name?
message = isUnassignable name
obj.error message
if message
- assigns.push
new Assign(obj, val,
null, param: @param, subpattern:
yes).compileToFragments o, LEVEL_LIST
+
unless obj
instanceof Elision
+ assigns.push
new Assign(obj, val,
null, param: @param, subpattern:
yes).compileToFragments o, LEVEL_LIST
+
else
+
+
+
+
+
-
+
+
+
+
Output Elision only if idx is i++, e.g. expandedIdx.
+
+
+
+ assigns.push idx.compileToFragments o, LEVEL_LIST if expandedIdx
assigns.push vvar unless top or @subpattern
fragments = @joinFragmentArrays assigns, ', '
@@ -4890,11 +5001,11 @@ etc.
- -
+
-
When compiling a conditional assignment, take care to ensure that the
operands are only evaluated once, even though we have to reference them
@@ -4908,11 +5019,11 @@ more than once.
-
-
+
-
Disallow conditional assignment of undefined variables.
@@ -4931,11 +5042,11 @@ more than once.
-
-
+
-
Convert special math assignment operators like a **= b to the equivalent
extended form a = a ** b and then compiles that.
@@ -4949,11 +5060,11 @@ extended form
a = a ** b and then compiles that.
-
-
+
-
Compile the assignment from an array splice literal, using JavaScript’s
Array#splice method.
@@ -4990,11 +5101,11 @@ extended form
a = a ** b and then compiles that.
-
-
+
-
FuncGlyph
@@ -5008,11 +5119,11 @@ exports.FuncGlyph =
class
- -
+
-
Code
@@ -5021,11 +5132,11 @@ exports.FuncGlyph =
class
- -
+
-
A function definition. This is the only node that creates a new Scope.
When for the purposes of walking the contents of a function body, the Code
@@ -5063,11 +5174,11 @@ has no children – they’re within the inner scope.
-
-
+
-
Compilation creates a new scope unless explicitly asked to share with the
outer scope. Handles splat parameters in the parameter list by setting
@@ -5102,11 +5213,11 @@ function body.
-
-
+
-
Check for duplicate parameters and separate this assignments.
@@ -5126,11 +5237,11 @@ function body.
-
-
+
-
Parse the parameters, adding them to the list of parameters to put in the
function definition; and dealing with splats or expansions, including
@@ -5148,11 +5259,11 @@ any non-idempotent parameters are evaluated in the correct order.
-
-
+
-
Was ... used with this parameter? (Only one such parameter is allowed
per function.) Splat/expansion parameters cannot have default values,
@@ -5172,11 +5283,11 @@ so we need not worry about that.
-
-
+
-
Splat arrays are treated oddly by ES; deal with them the legacy
way in the function body. TODO: Should this be handled in the
@@ -5201,11 +5312,11 @@ function parameter list, and if so, how?
-
-
+
-
Parse all other parameters; if a splat paramater has not yet been
encountered, add these other parameters to the list to be output in
@@ -5221,11 +5332,11 @@ the function definition.
-
-
+
-
This parameter cannot be declared or assigned in the parameter
list. So put a reference in the parameter list and add a statement
@@ -5244,11 +5355,11 @@ to the function body assigning it, e.g.
-
-
+
-
If this parameter comes before the splat or expansion, it will go
in the function definition parameter list.
@@ -5260,11 +5371,11 @@ in the function definition parameter list.
-
-
+
-
If this parameter has a default value, and it hasn’t already been
set by the shouldCache() block above, define it as a statement in
@@ -5284,11 +5395,11 @@ so we can’t define its default value in the parameter list.
-
-
+
-
Add this parameter’s reference(s) to the function scope.
@@ -5299,11 +5410,11 @@ so we can’t define its default value in the parameter list.
-
-
+
-
This parameter is destructured.
@@ -5314,11 +5425,11 @@ so we can’t define its default value in the parameter list.
-
-
+
-
Compile foo({a, b...}) -> to foo(arg) -> {a, b...} = arg.
Can be removed once ES proposal hits Stage 4.
@@ -5334,11 +5445,11 @@ Can be removed once ES proposal hits Stage 4.
-
-
+
-
Compile foo({a, b...} = {}) -> to foo(arg = {}) -> {a, b...} = arg.
@@ -5354,11 +5465,11 @@ Can be removed once ES proposal hits Stage 4.
-
-
+
-
This compilation of the parameter is only to get its name to add
to the scope name tracking; since the compilation output here
@@ -5377,11 +5488,11 @@ is compiled.
-
-
+
-
If this parameter had a default value, since it’s no longer in the
function parameter list we need to assign its default value
@@ -5397,11 +5508,11 @@ function parameter list we need to assign its default value
-
-
+
-
Add this parameter to the scope, since it wouldn’t have been added
yet since it was skipped earlier.
@@ -5413,11 +5524,11 @@ yet since it was skipped earlier.
-
-
+
-
If there were parameters after the splat or expansion parameter, those
parameters need to be assigned in the body of the function.
@@ -5429,11 +5540,11 @@ parameters need to be assigned in the body of the function.
-
-
+
-
Create a destructured assignment, e.g. [a, b, c] = [args..., b, c]
@@ -5446,11 +5557,11 @@ parameters need to be assigned in the body of the function.
-
-
+
-