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

Print this page




1049     /**
1050      * VariableStatement :
1051      *      var VariableDeclarationList ;
1052      *
1053      * VariableDeclarationList :
1054      *      VariableDeclaration
1055      *      VariableDeclarationList , VariableDeclaration
1056      *
1057      * VariableDeclaration :
1058      *      Identifier Initializer?
1059      *
1060      * Initializer :
1061      *      = AssignmentExpression
1062      *
1063      * See 12.2
1064      *
1065      * Parse a VAR statement.
1066      * @param isStatement True if a statement (not used in a FOR.)
1067      */
1068     private List<VarNode> variableStatement(final TokenType varType, final boolean isStatement) {




1069         // VAR tested in caller.
1070         next();
1071 
1072         final List<VarNode> vars = new ArrayList<>();
1073         int varFlags = 0;
1074         if (varType == LET) {
1075             varFlags |= VarNode.IS_LET;
1076         } else if (varType == CONST) {
1077             varFlags |= VarNode.IS_CONST;
1078         }
1079 
1080         while (true) {
1081             // Get starting token.
1082             final int  varLine  = line;
1083             final long varToken = token;
1084             // Get name of var.
1085             final IdentNode name = getIdent();
1086             verifyStrictIdent(name, "variable name");
1087 
1088             // Assume no init.
1089             Expression init = null;
1090 
1091             // Look for initializer assignment.
1092             if (type == ASSIGN) {
1093                 next();
1094 
1095                 // Get initializer expression. Suppress IN if not statement.
1096                 defaultNames.push(name);
1097                 try {
1098                     init = assignmentExpression(!isStatement);
1099                 } finally {
1100                     defaultNames.pop();
1101                 }
1102             } else if (varType == CONST) {
1103                 throw error(AbstractParser.message("missing.const.assignment", name.getName()));
1104             }
1105 
1106             // Allocate var node.
1107             final VarNode var = new VarNode(varLine, varToken, finish, name.setIsDeclaredHere(), init, varFlags);
1108             vars.add(var);
1109             appendStatement(var);
1110 
1111             if (type != COMMARIGHT) {
1112                 break;
1113             }
1114             next();
1115         }
1116 
1117         // If is a statement then handle end of line.
1118         if (isStatement) {
1119             endOfLine();
1120         }
1121 
1122         return vars;
1123     }
1124 
1125     /**
1126      * EmptyStatement :
1127      *      ;


1194         }
1195 
1196         appendStatement(new IfNode(ifLine, ifToken, fail != null ? fail.getFinish() : pass.getFinish(), test, pass, fail));
1197     }
1198 
1199     /**
1200      * ... IterationStatement:
1201      *           ...
1202      *           for ( Expression[NoIn]?; Expression? ; Expression? ) Statement
1203      *           for ( var VariableDeclarationList[NoIn]; Expression? ; Expression? ) Statement
1204      *           for ( LeftHandSideExpression in Expression ) Statement
1205      *           for ( var VariableDeclaration[NoIn] in Expression ) Statement
1206      *
1207      * See 12.6
1208      *
1209      * Parse a FOR statement.
1210      */
1211     private void forStatement() {
1212         final long forToken = token;
1213         final int forLine = line;




1214         // When ES6 for-let is enabled we create a container block to capture the LET.
1215         final int startLine = start;
1216         final ParserContextBlockNode outer = useBlockScope() ? newBlock() : null;
1217 
1218         // Create FOR node, capturing FOR token.
1219         final ParserContextLoopNode forNode = new ParserContextLoopNode();
1220         lc.push(forNode);
1221         Block body = null;
1222         List<VarNode> vars = null;
1223         Expression init = null;
1224         JoinPredecessorExpression test = null;
1225         JoinPredecessorExpression modify = null;
1226 
1227         int flags = 0;
1228 
1229         try {
1230             // FOR tested in caller.
1231             next();
1232 
1233             // Nashorn extension: for each expression.
1234             // iterate property values rather than property names.
1235             if (!env._no_syntax_extensions && type == IDENT && "each".equals(getValue())) {
1236                 flags |= ForNode.IS_FOR_EACH;
1237                 next();
1238             }
1239 
1240             expect(LPAREN);
1241 
1242 
1243             switch (type) {
1244             case VAR:
1245                 // Var declaration captured in for outer block.
1246                 vars = variableStatement(type, false);
1247                 break;
1248             case SEMICOLON:
1249                 break;
1250             default:
1251                 if (useBlockScope() && (type == LET || type == CONST)) {
1252                     if (type == LET) {
1253                         flags |= ForNode.PER_ITERATION_SCOPE;
1254                     }
1255                     // LET/CONST declaration captured in container block created above.
1256                     vars = variableStatement(type, false);
1257                     break;
1258                 }
1259                 if (env._const_as_var && type == CONST) {
1260                     // Var declaration captured in for outer block.
1261                     vars = variableStatement(TokenType.VAR, false);
1262                     break;
1263                 }
1264 
1265                 init = expression(unaryExpression(), COMMARIGHT.getPrecedence(), true);
1266                 break;
1267             }
1268 
1269             switch (type) {
1270             case SEMICOLON:
1271                 // for (init; test; modify)
1272 
1273                 // for each (init; test; modify) is invalid
1274                 if ((flags & ForNode.IS_FOR_EACH) != 0) {
1275                     throw error(AbstractParser.message("for.each.without.in"), token);
1276                 }
1277 
1278                 expect(SEMICOLON);
1279                 if (type != SEMICOLON) {
1280                     test = joinPredecessorExpression();
1281                 }




1049     /**
1050      * VariableStatement :
1051      *      var VariableDeclarationList ;
1052      *
1053      * VariableDeclarationList :
1054      *      VariableDeclaration
1055      *      VariableDeclarationList , VariableDeclaration
1056      *
1057      * VariableDeclaration :
1058      *      Identifier Initializer?
1059      *
1060      * Initializer :
1061      *      = AssignmentExpression
1062      *
1063      * See 12.2
1064      *
1065      * Parse a VAR statement.
1066      * @param isStatement True if a statement (not used in a FOR.)
1067      */
1068     private List<VarNode> variableStatement(final TokenType varType, final boolean isStatement) {
1069         return variableStatement(varType, isStatement, -1);
1070     }
1071 
1072     private List<VarNode> variableStatement(final TokenType varType, final boolean isStatement, final int sourceOrder) {
1073         // VAR tested in caller.
1074         next();
1075 
1076         final List<VarNode> vars = new ArrayList<>();
1077         int varFlags = 0;
1078         if (varType == LET) {
1079             varFlags |= VarNode.IS_LET;
1080         } else if (varType == CONST) {
1081             varFlags |= VarNode.IS_CONST;
1082         }
1083 
1084         while (true) {
1085             // Get starting token.
1086             final int  varLine  = line;
1087             final long varToken = token;
1088             // Get name of var.
1089             final IdentNode name = getIdent();
1090             verifyStrictIdent(name, "variable name");
1091 
1092             // Assume no init.
1093             Expression init = null;
1094 
1095             // Look for initializer assignment.
1096             if (type == ASSIGN) {
1097                 next();
1098 
1099                 // Get initializer expression. Suppress IN if not statement.
1100                 defaultNames.push(name);
1101                 try {
1102                     init = assignmentExpression(!isStatement);
1103                 } finally {
1104                     defaultNames.pop();
1105                 }
1106             } else if (varType == CONST) {
1107                 throw error(AbstractParser.message("missing.const.assignment", name.getName()));
1108             }
1109 
1110             // Allocate var node.
1111             final VarNode var = new VarNode(varLine, varToken, sourceOrder, finish, name.setIsDeclaredHere(), init, varFlags);
1112             vars.add(var);
1113             appendStatement(var);
1114 
1115             if (type != COMMARIGHT) {
1116                 break;
1117             }
1118             next();
1119         }
1120 
1121         // If is a statement then handle end of line.
1122         if (isStatement) {
1123             endOfLine();
1124         }
1125 
1126         return vars;
1127     }
1128 
1129     /**
1130      * EmptyStatement :
1131      *      ;


1198         }
1199 
1200         appendStatement(new IfNode(ifLine, ifToken, fail != null ? fail.getFinish() : pass.getFinish(), test, pass, fail));
1201     }
1202 
1203     /**
1204      * ... IterationStatement:
1205      *           ...
1206      *           for ( Expression[NoIn]?; Expression? ; Expression? ) Statement
1207      *           for ( var VariableDeclarationList[NoIn]; Expression? ; Expression? ) Statement
1208      *           for ( LeftHandSideExpression in Expression ) Statement
1209      *           for ( var VariableDeclaration[NoIn] in Expression ) Statement
1210      *
1211      * See 12.6
1212      *
1213      * Parse a FOR statement.
1214      */
1215     private void forStatement() {
1216         final long forToken = token;
1217         final int forLine = line;
1218         // start position of this for statement. This is used
1219         // for sort order for variables declared in the initialzer
1220         // part of this 'for' statement (if any).
1221         final int forStart = Token.descPosition(forToken);
1222         // When ES6 for-let is enabled we create a container block to capture the LET.
1223         final int startLine = start;
1224         final ParserContextBlockNode outer = useBlockScope() ? newBlock() : null;
1225 
1226         // Create FOR node, capturing FOR token.
1227         final ParserContextLoopNode forNode = new ParserContextLoopNode();
1228         lc.push(forNode);
1229         Block body = null;
1230         List<VarNode> vars = null;
1231         Expression init = null;
1232         JoinPredecessorExpression test = null;
1233         JoinPredecessorExpression modify = null;
1234 
1235         int flags = 0;
1236 
1237         try {
1238             // FOR tested in caller.
1239             next();
1240 
1241             // Nashorn extension: for each expression.
1242             // iterate property values rather than property names.
1243             if (!env._no_syntax_extensions && type == IDENT && "each".equals(getValue())) {
1244                 flags |= ForNode.IS_FOR_EACH;
1245                 next();
1246             }
1247 
1248             expect(LPAREN);
1249 
1250 
1251             switch (type) {
1252             case VAR:
1253                 // Var declaration captured in for outer block.
1254                 vars = variableStatement(type, false, forStart);
1255                 break;
1256             case SEMICOLON:
1257                 break;
1258             default:
1259                 if (useBlockScope() && (type == LET || type == CONST)) {
1260                     if (type == LET) {
1261                         flags |= ForNode.PER_ITERATION_SCOPE;
1262                     }
1263                     // LET/CONST declaration captured in container block created above.
1264                     vars = variableStatement(type, false, forStart);
1265                     break;
1266                 }
1267                 if (env._const_as_var && type == CONST) {
1268                     // Var declaration captured in for outer block.
1269                     vars = variableStatement(TokenType.VAR, false, forStart);
1270                     break;
1271                 }
1272 
1273                 init = expression(unaryExpression(), COMMARIGHT.getPrecedence(), true);
1274                 break;
1275             }
1276 
1277             switch (type) {
1278             case SEMICOLON:
1279                 // for (init; test; modify)
1280 
1281                 // for each (init; test; modify) is invalid
1282                 if ((flags & ForNode.IS_FOR_EACH) != 0) {
1283                     throw error(AbstractParser.message("for.each.without.in"), token);
1284                 }
1285 
1286                 expect(SEMICOLON);
1287                 if (type != SEMICOLON) {
1288                     test = joinPredecessorExpression();
1289                 }