src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/AssignSymbols.java

Print this page

        

@@ -311,17 +311,17 @@
      *
      * @return Symbol for given name or null for redefinition.
      */
     private Symbol defineSymbol(final Block block, final String name, final Node origin, final int symbolFlags) {
         int    flags  = symbolFlags;
-        final boolean isBlockScope = (flags & IS_LET) != 0 || (flags & IS_CONST) != 0;
+        final boolean isLexicalScope = (flags & IS_LET) != 0 || (flags & IS_CONST) != 0;
         final boolean isGlobal     = (flags & KINDMASK) == IS_GLOBAL;
 
         Symbol symbol;
         final FunctionNode function;
-        if (isBlockScope) {
-            // block scoped variables always live in current block, no need to look for existing symbols in parent blocks.
+        if (isLexicalScope) {
+            // lexically scoped variables always live in current block, no need to look for existing symbols in parent blocks.
             symbol = block.getExistingSymbol(name);
             function = lc.getCurrentFunction();
         } else {
             symbol = findSymbol(block, name);
             function = lc.getFunction(block);

@@ -348,16 +348,20 @@
                 } else if (symbol.isParam()) {
                     // Duplicate parameter. Null return will force an error.
                     throw new AssertionError("duplicate parameter");
                 }
             } else if (isVar) {
-                if (isBlockScope) {
+                if (isLexicalScope) {
                     // Check redeclaration in same block
                     if (symbol.hasBeenDeclared()) {
                         throwParserException(ECMAErrors.getMessage("syntax.error.redeclare.variable", name), origin);
                     } else {
                         symbol.setHasBeenDeclared();
+                        // Set scope flag on top-level lexical symbols
+                        if (function.isProgram() && function.getBody() == block) {
+                            symbol.setIsScope();
+                        }
                     }
                 } else if ((flags & IS_INTERNAL) != 0) {
                     // Always create a new definition.
                     symbol = null;
                 } else {

@@ -376,11 +380,11 @@
         if (symbol == null) {
             // If not found, then create a new one.
             final Block symbolBlock;
 
             // Determine where to create it.
-            if (isVar && ((flags & IS_INTERNAL) != 0 || isBlockScope)) {
+            if (isVar && ((flags & IS_INTERNAL) != 0 || isLexicalScope)) {
                 symbolBlock = block; //internal vars are always defined in the block closest to them
             } else if (isGlobal) {
                 symbolBlock = lc.getOutermostFunction().getBody();
             } else {
                 symbolBlock = lc.getFunctionBody(function);

@@ -538,11 +542,11 @@
     private void defineVarIdent(final VarNode varNode) {
         final IdentNode ident = varNode.getName();
         final int flags;
         if (varNode.isAnonymousFunctionDeclaration()) {
             flags = IS_INTERNAL;
-        } else if (lc.getCurrentFunction().isProgram()) {
+        } else if (!varNode.isBlockScoped() && lc.getCurrentFunction().isProgram()) {
             flags = IS_SCOPE;
         } else {
             flags = 0;
         }
         defineSymbol(lc.getCurrentBlock(), ident.getName(), ident, varNode.getSymbolFlags() | flags);