private void visitBlockScopedName ( NodeTraversal t , Node decl , Node nameNode ) { Scope scope = t . getScope ( ) ; Node parent = decl . getParent ( ) ; // Normalize "let x;" to "let x = undefined;" if in a loop, since we later convert x // to be $jscomp$loop$0.x and want to reset the property to undefined every loop iteration. if ( ( decl . isLet ( ) || decl . isConst ( ) ) && ! nameNode . hasChildren ( ) && ( parent == null || ! parent . isForIn ( ) ) && inLoop ( decl ) ) { Node undefined = createUndefinedNode ( ) . srcref ( nameNode ) ; nameNode . addChildToFront ( undefined ) ; compiler . reportChangeToEnclosingScope ( undefined ) ; } String oldName = nameNode . getString ( ) ; Scope hoistScope = scope . getClosestHoistScope ( ) ; if ( scope != hoistScope ) { String newName = oldName ; if ( hoistScope . hasSlot ( oldName ) || undeclaredNames . contains ( oldName ) ) { do { newName = oldName + "$" + compiler . getUniqueNameIdSupplier ( ) . get ( ) ; } while ( hoistScope . hasSlot ( newName ) ) ; nameNode . setString ( newName ) ; compiler . reportChangeToEnclosingScope ( nameNode ) ; Node scopeRoot = scope . getRootNode ( ) ; renameTable . put ( scopeRoot , oldName , newName ) ; } Var oldVar = scope . getVar ( oldName ) ; scope . undeclare ( oldVar ) ; hoistScope . declare ( newName , nameNode , oldVar . input ) ; } }
Renames block - scoped declarations that shadow a variable in an outer scope