o.scope.get(@value)?
+
eachName: (iterator) ->
iterator @
@@ -2446,6 +2465,24 @@ Literal
exports.PropertyName = class PropertyName extends Literal
isAssignable: YES
+ isDeclarable: (o) ->
diff --git a/docs/v2/annotated-source/nodes.html b/docs/v2/annotated-source/nodes.html index bfb3d6d80a..80947405a0 100644 --- a/docs/v2/annotated-source/nodes.html +++ b/docs/v2/annotated-source/nodes.html @@ -1045,6 +1045,7 @@
Can declare this variable only if we’re at the right scope. +(If it’s in a parent scope, declaring here would shadow.)
+ + o.scope.get(@value)?
+
eachName: (iterator) ->
iterator @
@@ -2446,6 +2465,24 @@ Literal
exports.PropertyName = class PropertyName extends Literal
isAssignable: YES
+ isDeclarable: (o) ->
Can declare this variable only if we’re at the right scope. +(If it’s in a parent scope, declaring here would shadow.)
+ + o.scope.get(@value)?
+
astType: ->
if @jsx
'JSXIdentifier'
@@ -2535,11 +2572,11 @@ Literal
-
A return
is a pureStatement—wrapping it in a closure wouldn’t make sense.
TODO: If we call expression.compile()
here twice, we’ll sometimes
get back different results!
Since the return
got indented by @tab
, preceding comments that are
multiline need to be indented.
don’t flag return
from await return
/yield return
as invalid.
Parent class for YieldReturn
/AwaitReturn
.
yield return
works exactly like return
, except that it turns the function
into a generator.
A value, variable or literal or parenthesized, indexed or dotted into, or vanilla.
@@ -2743,11 +2780,11 @@If this is a @foo =
assignment, if there are comments on @
move them
to be on foo
.
Add a property (or properties ) Access
to the list.
Some boolean checks for the benefit of other nodes.
@@ -2800,6 +2837,7 @@The value can be unwrapped as its inner node, if there are no attached properties.
@@ -2858,11 +2896,11 @@A reference has base part (this
value) and name part.
We cache them separately for compiling complex expressions.
@@ -2888,11 +2926,11 @@
We compile a value to JavaScript by compiling and joining each property. Things get much more interesting if the chain of properties has soak @@ -2909,11 +2947,11 @@
Cached fragments enable correct order of the compilation, and reuse of variables in the scope. @@ -2937,11 +2975,11 @@
Unfold a soak into an If
: a?.b
-> a.b if a?
For AST generation, we need an object
that’s this Value
minus its last
property, if it has properties.
Get all properties except the last one; for a Value
with only one
property, initialProperties
is an empty array.
Create the object
that becomes the new “base” for the split-off final
property.
Add location data to our new node, so that it has correct location data for source maps or later conversion into AST location data.
@@ -3041,11 +3079,11 @@This new Value
has only one property, so the location data is just
that of the parent Value
’s base.
This new Value
has multiple properties, so the location data spans
from the parent Value
’s base to the last property that’s included
@@ -3088,11 +3126,11 @@
If the Value
has no properties, the AST node is just whatever this
node’s base
is.
Otherwise, call Base::ast
which in turn calls the astType
and
astProperties
methods below.
If this Value
has properties, the last property (e.g. c
in a.b.c
)
becomes the property
, and the preceding properties (e.g. a.b
) become
@@ -3158,11 +3196,11 @@
don’t include leading < of JSX tag in location data
@@ -3207,11 +3245,11 @@Comment delimited by ###
(becoming /* */
).
Unindent multiline comments. They will be reindented later.
@@ -3270,11 +3308,11 @@Don’t rely on fragment.type
, which can break when the compiler is minified.
Comment running from #
to the end of a line (becoming //
).
Don’t rely on fragment.type
, which can break when the compiler is minified.
attribute with no value eg disabled
@@ -3468,11 +3506,11 @@object spread attribute eg {…props}
@@ -3487,11 +3525,11 @@Obj containing attributes with values eg a=”b” c={d}
@@ -3512,11 +3550,11 @@Catch invalid attributes:
@@ -3558,11 +3596,11 @@Node for a JSX element
@@ -3595,11 +3633,11 @@The location data spanning the opening element < … > is captured by the generated Arr which contains the element’s attributes
@@ -3716,11 +3754,11 @@distinguish <a><b /></a>
from <a>{<b />}</a>
Node for a function invocation.
@@ -3794,11 +3832,11 @@@variable
never gets output as a result of this node getting created as
part of RegexWithInterpolations
, so for that case move any comments to
@@ -3815,11 +3853,11 @@
When setting the location, we sometimes need to update the start location to
account for a newly-discovered new
operator to the left of us. This
@@ -3854,11 +3892,11 @@
Tag this invocation as creating a new instance.
@@ -3876,11 +3914,11 @@Soaked chained invocations unfold into if/else ternary structures.
@@ -3921,11 +3959,11 @@Compile a vanilla function call.
@@ -3939,11 +3977,11 @@If variable is Accessor
fragments are cached and used later
in Value::compileNode
to ensure correct order of the compilation,
@@ -4005,11 +4043,11 @@
Takes care of converting super()
calls into calls against the prototype’s
function of the same name.
@@ -4049,11 +4087,11 @@
If we might be in an expression we need to cache and return the result
@@ -4087,11 +4125,11 @@A super()
call gets compiled to e.g. super.method()
, which means
the method
property name gets compiled for the first time here, and
@@ -4131,11 +4169,11 @@
Regexes with interpolations are in fact just a variation of a Call
(a
RegExp()
call to be precise) with a StringWithInterpolations
inside.
Node to extend an object’s prototype with an ancestor object.
After goog.inherits
from the
@@ -4242,11 +4280,11 @@
Hooks one constructor into another’s prototype chain.
@@ -4258,11 +4296,11 @@A .
access into a property of a value, or the ::
shorthand for
an access into the object’s prototype.
Babel doesn’t have an AST node for Access
, but rather just includes
this Access node’s child name
Identifier node as the property
of
@@ -4320,11 +4358,11 @@
A [ ... ]
indexed access into an array or object.
Babel doesn’t have an AST node for Index
, but rather just includes
this Index node’s child index
Identifier node as the property
of
@@ -4379,11 +4417,11 @@
A range literal. Ranges can be used to extract portions (slices) of arrays, to specify a range for comprehensions, or as a value, to be expanded into the @@ -4417,11 +4455,11 @@
Compiles the range’s source variables – where it starts and where it ends. But only if they need to be cached to avoid double evaluation.
@@ -4441,11 +4479,11 @@When compiled normally, the range returns the contents of the for loop needed to iterate over the values in the range. Used by comprehensions.
@@ -4459,11 +4497,11 @@Set up endpoints.
@@ -4473,23 +4511,86 @@Can do var declaration only if all relevant variables are in this scope. +If we declare @fromVar, @toVar, or @stepVar, they’re guaranteed +to be in scope (generated in @compileVariables), so don’t check those.
+ + canDeclare = o.scope.get(idx)? and
+ (not namedIndex or o.scope.get(idxName)?)
Want to do var declaration if at least one of those variables needs +declaration. Also keep track of which variables need declaration.
+ + if canDeclare
+ declare = yes if o.scope.laterVar idx
+ declare = yes if namedIndex and o.scope.laterVar idxName
+ if declare
+ o.scope.laterVar @fromVar if @fromC isnt @fromVar
+ o.scope.laterVar @toVar if @toC isnt @toVar
+ o.scope.laterVar @stepVar if @stepC isnt @stepVar
+ varPart = if declare then "var " else ''
+ if @fromC isnt @fromVar
+ varPart += "#{@fromC}, #{idx} = #{@fromVar}"
+ else
+ varPart += "#{idx} = #{@fromC}"
+ if namedIndex
+ if declare
+ varPart += ", #{idxName} = #{idx}"
else
- "#{idx} = #{@fromC}"
+ varPart = "#{idxName} = #{varPart}"
varPart += ", #{@toC}" if @toC isnt @toVar
- varPart += ", #{@step}" if @step isnt @stepVar
- [lt, gt] = ["#{idx} <#{@equals}", "#{idx} >#{@equals}"]
[lt, gt] = ["#{idx} <#{@equals}", "#{idx} >#{@equals}"]
Generate the condition.
@@ -4500,11 +4601,11 @@Always check if the step
isn’t zero to avoid the infinite loop.
The final loop body.
@@ -4575,11 +4674,11 @@When used as a value, expand the range into the equivalent array.
@@ -4597,6 +4696,7 @@An array slice literal. Unlike JavaScript’s Array#slice
, the second parameter
specifies the index of the end of the slice, just as the first parameter
@@ -4652,11 +4752,11 @@
We have to be careful when trying to slice through the end of the array,
9e9
is used because not all implementations respect undefined
or 1/0
.
@@ -4670,11 +4770,11 @@
Handle an expression in the property access, e.g. a[!b in c..]
.
An object literal, nothing fancy.
@@ -4741,11 +4841,11 @@Check if object contains splat.
@@ -4783,11 +4887,11 @@Move rest property to the end of the list.
{a, rest..., b} = obj
-> {a, b, rest...} = obj
@@ -4814,11 +4918,11 @@
If this object is the left-hand side of an assignment, all its children are too.
@@ -4866,11 +4970,11 @@{ [foo()] }
output as { [ref = foo()]: ref }
.
{ [expression] }
output as { [expression]: expression }
.
Convert “bare” properties to ObjectProperty
s (or Splat
s).
Shorthand property with default, e.g. {a = 1} = b
.
All non-shorthand properties (i.e. includes :
).
Left-hand-side shorthand with default e.g. {a = 1} = b
.
Shorthand without default e.g. {a}
or {@a}
or {[a]}
.
An array literal.
@@ -5124,6 +5228,10 @@Detect if Elision
s at the beginning of the array are processed (e.g. [, , , a]).
Let compileCommentFragments
know to intersperse block comments
into the fragments created when compiling this array.
If compiledObjs
includes newlines, we will output this as a multiline
array (i.e. with a newline and indentation after the [
). If an element
@@ -5204,11 +5312,11 @@
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 this array is the left-hand side of an assignment, all its children are too.
@@ -5282,11 +5390,11 @@The CoffeeScript class definition. Initialize a Class with its name, an optional superclass, and a body.
@@ -5323,11 +5431,11 @@Special handling to allow class expr.A extends A
declarations
Anonymous classes are only valid in expressions
@@ -5398,11 +5506,11 @@Figure out the appropriate name for this class
@@ -5474,11 +5582,11 @@Add an expression to the class initializer
This is the key method for determining whether an expression in a class @@ -5511,11 +5619,11 @@
Checks if the given node is a valid ES class initializer method.
@@ -5529,11 +5637,11 @@Returns a configured class initializer method
@@ -5696,11 +5804,11 @@Traverse the class’s children and:
Make class/prototype assignments for invalid ES properties
@@ -5772,11 +5880,11 @@The class scope is not available yet, so return the assignment to update later
@@ -5833,11 +5941,11 @@TODO: would be appropriate to flag this error during AST generation (as
well as when compiling to JS). But o.indent
isn’t tracked during AST
@@ -5942,11 +6050,11 @@
The AST for ImportClause
is the non-nested list of import specifiers
that will be the specifiers
property of an ImportDeclaration
AST
Prevent exporting an anonymous class; all exported members must be named
@@ -6075,11 +6185,11 @@The name of the variable entering the local scope
@@ -6112,11 +6222,11 @@Per the spec, symbols can’t be imported multiple times
(e.g. import { foo, foo } from 'lib'
is invalid)
The Assign is used to assign a local variable to value, or to set the property of an object – including within object literals.
@@ -6206,6 +6316,7 @@During AST generation, we need to allow assignment to these constructs that are considered “unassignable” during compile-to-JS, while still @@ -6267,11 +6378,11 @@
moduleDeclaration
can be 'import'
or 'export'
.
If this assignment identifier has one or more herecomments attached, output them as part of the declarations line (unless @@ -6309,23 +6420,45 @@
if name.comments and not o.scope.comments[name.value] and
+ if name.comments and not o.scope.hasComment(name.value) and
@value not instanceof Class and
name.comments.every((comment) -> comment.here and not comment.multiline)
commentsNode = new IdentifierLiteral name.value
commentsNode.comments = name.comments
commentFragments = []
@compileCommentFragments o, commentsNode, commentFragments
- o.scope.comments[name.value] = commentFragments
+ o.scope.comment name.value, commentFragments
+
+ makeDeclaration: (o) ->
Consider adding ‘var’ prefix to this assignment. Only works at top level +and if LHS is a valid declaration, and assignment is ‘=’ not another op.
+ + return unless o.level == LEVEL_TOP and not o.undeclarable and
+ @variable.isDeclarable(o) and not @context?
+ @eachName (name) =>
+ if o.scope.laterVar name.value
+ @declaration = yes # at least one variable freshly declared
Compile an assignment, delegating to compileDestructuring
or
compileSplice
if appropriate. Keep track of the name of the base object
@@ -6341,11 +6474,11 @@
If @variable
is an array or an object, we’re destructuring;
if it’s also isAssignable()
, the destructuring syntax is supported
@@ -6375,6 +6508,7 @@
Per https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#assignment_separate_from_declaration_2 if we’re destructuring without declaring, the destructuring assignment must be wrapped in parentheses. The assignment is wrapped in parentheses if ‘o.level’ has lower precedence than LEVEL_LIST (3) (i.e. LEVEL_COND (4), LEVEL_OP (5) or LEVEL_ACCESS (6)), or if we’re destructuring object, e.g. {a,b} = obj.
if o.level > LEVEL_LIST or isValue and @variable.base instanceof Obj and not @nestedLhs and not (@param is yes)
+ else if o.level > LEVEL_LIST or isValue and @variable.base instanceof Obj and not @nestedLhs and not (@param is yes)
@wrapInParentheses answer
else
answer
@@ -6408,11 +6544,11 @@ Assign
-
Object rest property is not assignable: {{a}...}
Brief implementation of recursive pattern matching, when assigning array or object literals to a value. Peeks at their properties to assign inner names.
@@ -6453,11 +6589,11 @@Special-case for {} = a
and [] = a
(empty patterns).
Compile to simply a
.
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
@@ -6519,11 +6655,11 @@
Helper which outputs [].slice
code.
Helper which outputs [].splice
code.
Check if objects
array contains any instance of Assign
, e.g. {a:1}.
Check if objects
array contains any unassignable object.
objects
are complex when there is object assign ({a:1}),
unassignable object, or just a single node.