< prev index next >
src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/Parser.java
Print this page
*** 890,900 ****
switch (type) {
case LBRACE:
block();
break;
case VAR:
! variableStatement(type, true);
break;
case SEMICOLON:
emptyStatement();
break;
case IF:
--- 890,900 ----
switch (type) {
case LBRACE:
block();
break;
case VAR:
! variableStatement(type);
break;
case SEMICOLON:
emptyStatement();
break;
case IF:
*** 944,958 ****
default:
if (useBlockScope() && (type == LET || type == CONST)) {
if (singleStatement) {
throw error(AbstractParser.message("expected.stmt", type.getName() + " declaration"), token);
}
! variableStatement(type, true);
break;
}
if (env._const_as_var && type == CONST) {
! variableStatement(TokenType.VAR, true);
break;
}
if (type == IDENT || isNonStrictModeIdent()) {
if (T(k + 1) == COLON) {
--- 944,958 ----
default:
if (useBlockScope() && (type == LET || type == CONST)) {
if (singleStatement) {
throw error(AbstractParser.message("expected.stmt", type.getName() + " declaration"), token);
}
! variableStatement(type);
break;
}
if (env._const_as_var && type == CONST) {
! variableStatement(TokenType.VAR);
break;
}
if (type == IDENT || isNonStrictModeIdent()) {
if (T(k + 1) == COLON) {
*** 1045,1055 ****
throw error(AbstractParser.message("strict.name", ident.getName(), contextString), ident.getToken());
}
}
}
! /**
* VariableStatement :
* var VariableDeclarationList ;
*
* VariableDeclarationList :
* VariableDeclaration
--- 1045,1055 ----
throw error(AbstractParser.message("strict.name", ident.getName(), contextString), ident.getToken());
}
}
}
! /*
* VariableStatement :
* var VariableDeclarationList ;
*
* VariableDeclarationList :
* VariableDeclaration
*** 1064,1075 ****
* See 12.2
*
* 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();
--- 1064,1075 ----
* See 12.2
*
* Parse a VAR statement.
* @param isStatement True if a statement (not used in a FOR.)
*/
! private List<VarNode> variableStatement(final TokenType varType) {
! return variableStatement(varType, true, -1);
}
private List<VarNode> variableStatement(final TokenType varType, final boolean isStatement, final int sourceOrder) {
// VAR tested in caller.
next();
*** 1213,1222 ****
--- 1213,1223 ----
*
* See 12.6
*
* Parse a FOR statement.
*/
+ @SuppressWarnings("fallthrough")
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 initializer
*** 1233,1242 ****
--- 1234,1244 ----
Expression init = null;
JoinPredecessorExpression test = null;
JoinPredecessorExpression modify = null;
int flags = 0;
+ boolean isForOf = false;
try {
// FOR tested in caller.
next();
*** 1290,1334 ****
if (type != RPAREN) {
modify = joinPredecessorExpression();
}
break;
case IN:
! flags |= ForNode.IS_FOR_IN;
test = new JoinPredecessorExpression();
if (vars != null) {
// for (var i in obj)
if (vars.size() == 1) {
init = new IdentNode(vars.get(0).getName());
} else {
// for (var i, j in obj) is invalid
! throw error(AbstractParser.message("many.vars.in.for.in.loop"), vars.get(1).getToken());
}
-
} else {
// for (expr in obj)
! assert init != null : "for..in init expression can not be null here";
// check if initial expression is a valid L-value
if (!(init instanceof AccessNode ||
init instanceof IndexNode ||
init instanceof IdentNode)) {
! throw error(AbstractParser.message("not.lvalue.for.in.loop"), init.getToken());
}
if (init instanceof IdentNode) {
if (!checkIdentLValue((IdentNode)init)) {
! throw error(AbstractParser.message("not.lvalue.for.in.loop"), init.getToken());
}
! verifyStrictIdent((IdentNode)init, "for-in iterator");
}
}
next();
! // Get the collection expression.
! modify = joinPredecessorExpression();
break;
default:
expect(SEMICOLON);
break;
--- 1292,1344 ----
if (type != RPAREN) {
modify = joinPredecessorExpression();
}
break;
+ case IDENT:
+ if (env._es6 && "of".equals(getValue())) {
+ isForOf = true;
+ // fall through
+ } else {
+ expect(SEMICOLON); // fail with expected message
+ break;
+ }
case IN:
!
! flags |= isForOf ? ForNode.IS_FOR_OF : ForNode.IS_FOR_IN;
test = new JoinPredecessorExpression();
if (vars != null) {
// for (var i in obj)
if (vars.size() == 1) {
init = new IdentNode(vars.get(0).getName());
} else {
// for (var i, j in obj) is invalid
! throw error(AbstractParser.message("many.vars.in.for.in.loop", isForOf ? "of" : "in"), vars.get(1).getToken());
}
} else {
// for (expr in obj)
! assert init != null : "for..in/of init expression can not be null here";
// check if initial expression is a valid L-value
if (!(init instanceof AccessNode ||
init instanceof IndexNode ||
init instanceof IdentNode)) {
! throw error(AbstractParser.message("not.lvalue.for.in.loop", isForOf ? "of" : "in"), init.getToken());
}
if (init instanceof IdentNode) {
if (!checkIdentLValue((IdentNode)init)) {
! throw error(AbstractParser.message("not.lvalue.for.in.loop", isForOf ? "of" : "in"), init.getToken());
}
! verifyStrictIdent((IdentNode)init, isForOf ? "for-of iterator" : "for-in iterator");
}
}
next();
! // For-of only allows AssignmentExpression.
! modify = isForOf ? new JoinPredecessorExpression(assignmentExpression(false)) : joinPredecessorExpression();
break;
default:
expect(SEMICOLON);
break;
< prev index next >