src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/Parser.java

Print this page

        

@@ -1064,10 +1064,14 @@
      *
      * Parse a VAR statement.
      * @param isStatement True if a statement (not used in a FOR.)
      */
     private List<VarNode> variableStatement(final TokenType varType, final boolean isStatement) {
+        return variableStatement(varType, isStatement, -1);
+    }
+
+    private List<VarNode> variableStatement(final TokenType varType, final boolean isStatement, final int sourceOrder) {
         // VAR tested in caller.
         next();
 
         final List<VarNode> vars = new ArrayList<>();
         int varFlags = 0;

@@ -1102,11 +1106,11 @@
             } else if (varType == CONST) {
                 throw error(AbstractParser.message("missing.const.assignment", name.getName()));
             }
 
             // Allocate var node.
-            final VarNode var = new VarNode(varLine, varToken, finish, name.setIsDeclaredHere(), init, varFlags);
+            final VarNode var = new VarNode(varLine, varToken, sourceOrder, finish, name.setIsDeclaredHere(), init, varFlags);
             vars.add(var);
             appendStatement(var);
 
             if (type != COMMARIGHT) {
                 break;

@@ -1209,10 +1213,14 @@
      * Parse a FOR statement.
      */
     private void forStatement() {
         final long forToken = token;
         final int forLine = line;
+        // start position of this for statement. This is used
+        // for sort order for variables declared in the initialzer
+        // part of this 'for' statement (if any).
+        final int forStart = Token.descPosition(forToken);
         // When ES6 for-let is enabled we create a container block to capture the LET.
         final int startLine = start;
         final ParserContextBlockNode outer = useBlockScope() ? newBlock() : null;
 
         // Create FOR node, capturing FOR token.

@@ -1241,26 +1249,26 @@
 
 
             switch (type) {
             case VAR:
                 // Var declaration captured in for outer block.
-                vars = variableStatement(type, false);
+                vars = variableStatement(type, false, forStart);
                 break;
             case SEMICOLON:
                 break;
             default:
                 if (useBlockScope() && (type == LET || type == CONST)) {
                     if (type == LET) {
                         flags |= ForNode.PER_ITERATION_SCOPE;
                     }
                     // LET/CONST declaration captured in container block created above.
-                    vars = variableStatement(type, false);
+                    vars = variableStatement(type, false, forStart);
                     break;
                 }
                 if (env._const_as_var && type == CONST) {
                     // Var declaration captured in for outer block.
-                    vars = variableStatement(TokenType.VAR, false);
+                    vars = variableStatement(TokenType.VAR, false, forStart);
                     break;
                 }
 
                 init = expression(unaryExpression(), COMMARIGHT.getPrecedence(), true);
                 break;