@@ -361,9 +361,18 @@ exports.Base = class Base
361
361
else
362
362
return true if children .replaceInContext match, replacement
363
363
364
- findReferencedVars : (scopes ) ->
364
+ # `findReferencedVars` recurses through the source parse tree to mark every
365
+ # "scope" parse node (`Root` and `Code`s) with all referenced
366
+ # (accessed or assigned) variables in that source scope, so that every scope
367
+ # knows what to avoid when generating new variable names.
368
+ # Specifically, it takes in an array of `scopeNodes`,
369
+ # each of which already has a `@referencedVars` attribute that is a `Set`.
370
+ # For each found reference to an identifier (see `IdentifierLiteral`'s
371
+ # override for `findReferencedVars`), it adds the name (as a `String`)
372
+ # to each scope node's `referencedVars` Set.
373
+ findReferencedVars : (scopeNodes ) ->
365
374
@eachChild (child ) ->
366
- child .findReferencedVars scopes
375
+ child .findReferencedVars scopeNodes
367
376
368
377
invert : ->
369
378
new Op ' !' , this
@@ -519,12 +528,15 @@ exports.Root = class Root extends Base
519
528
super ()
520
529
521
530
@isAsync = (new Code [], @body ).isAsync
522
- @referencedVars = new Set
531
+ @referencedVars = new Set # all referenced variable names in this scope
523
532
524
533
children : [' body' ]
525
534
526
- findReferencedVars : (scopes = []) ->
527
- super scopes .concat @
535
+ findReferencedVars : (scopeNodes = []) ->
536
+ # This is called at the top level to start the recursion,
537
+ # so initialize `scopeNodes` to the empty array.
538
+ # Also, Root is a scope node, so add self to the (possibly empty) array.
539
+ super scopeNodes .concat @
528
540
529
541
# Wrap everything in a safety closure, unless requested not to. It would be
530
542
# better not to generate them in the first place, but for now, clean up
@@ -1180,8 +1192,10 @@ exports.IdentifierLiteral = class IdentifierLiteral extends Literal
1180
1192
name : @value
1181
1193
declaration : !! @isDeclaration
1182
1194
1183
- findReferencedVars : (scopes ) ->
1184
- scope .referencedVars .add @value for scope in scopes
1195
+ findReferencedVars : (scopeNodes ) ->
1196
+ # Add this identifier name to the `referencedVars` `Set` of all
1197
+ # containing scopeNodes, to avoid generating a conflicting variable name.
1198
+ scopeNode .referencedVars .add @value for scopeNode in scopeNodes
1185
1199
1186
1200
exports .PropertyName = class PropertyName extends Literal
1187
1201
isAssignable : YES
@@ -3915,7 +3929,7 @@ exports.Code = class Code extends Base
3915
3929
@isGenerator = no
3916
3930
@isAsync = no
3917
3931
@isMethod = no
3918
- @referencedVars = new Set
3932
+ @referencedVars = new Set # all referenced variable names in this scope
3919
3933
3920
3934
@body .traverseChildren no , (node ) =>
3921
3935
if (node instanceof Op and node .isYield ()) or node instanceof YieldReturn
@@ -3933,8 +3947,9 @@ exports.Code = class Code extends Base
3933
3947
3934
3948
jumps : NO
3935
3949
3936
- findReferencedVars : (scopes ) ->
3937
- super scopes .concat @
3950
+ findReferencedVars : (scopeNodes ) ->
3951
+ # Code is a scope node, so add self to the `scopeNodes` array.
3952
+ super scopeNodes .concat @
3938
3953
3939
3954
makeScope : (parentScope ) ->
3940
3955
new Scope parentScope, @body , this , @referencedVars
0 commit comments