@@ -361,9 +361,18 @@ exports.Base = class Base
361361 else
362362 return true if children .replaceInContext match, replacement
363363
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 ) ->
365374 @eachChild (child ) ->
366- child .findReferencedVars scopes
375+ child .findReferencedVars scopeNodes
367376
368377 invert : ->
369378 new Op ' !' , this
@@ -519,12 +528,15 @@ exports.Root = class Root extends Base
519528 super ()
520529
521530 @isAsync = (new Code [], @body ).isAsync
522- @referencedVars = new Set
531+ @referencedVars = new Set # all referenced variable names in this scope
523532
524533 children : [' body' ]
525534
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 @
528540
529541 # Wrap everything in a safety closure, unless requested not to. It would be
530542 # better not to generate them in the first place, but for now, clean up
@@ -1180,8 +1192,10 @@ exports.IdentifierLiteral = class IdentifierLiteral extends Literal
11801192 name : @value
11811193 declaration : !! @isDeclaration
11821194
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
11851199
11861200exports .PropertyName = class PropertyName extends Literal
11871201 isAssignable : YES
@@ -3915,7 +3929,7 @@ exports.Code = class Code extends Base
39153929 @isGenerator = no
39163930 @isAsync = no
39173931 @isMethod = no
3918- @referencedVars = new Set
3932+ @referencedVars = new Set # all referenced variable names in this scope
39193933
39203934 @body .traverseChildren no , (node ) =>
39213935 if (node instanceof Op and node .isYield ()) or node instanceof YieldReturn
@@ -3933,8 +3947,9 @@ exports.Code = class Code extends Base
39333947
39343948 jumps : NO
39353949
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 @
39383953
39393954 makeScope : (parentScope ) ->
39403955 new Scope parentScope, @body , this , @referencedVars
0 commit comments