src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/Parser.java
Print this page
*** 1064,1073 ****
--- 1064,1077 ----
*
* 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,1112 ****
} 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);
vars.add(var);
appendStatement(var);
if (type != COMMARIGHT) {
break;
--- 1106,1116 ----
} else if (varType == CONST) {
throw error(AbstractParser.message("missing.const.assignment", name.getName()));
}
// Allocate var node.
! final VarNode var = new VarNode(varLine, varToken, sourceOrder, finish, name.setIsDeclaredHere(), init, varFlags);
vars.add(var);
appendStatement(var);
if (type != COMMARIGHT) {
break;
*** 1209,1218 ****
--- 1213,1226 ----
* 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,1266 ****
switch (type) {
case VAR:
// Var declaration captured in for outer block.
! vars = variableStatement(type, false);
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);
break;
}
if (env._const_as_var && type == CONST) {
// Var declaration captured in for outer block.
! vars = variableStatement(TokenType.VAR, false);
break;
}
init = expression(unaryExpression(), COMMARIGHT.getPrecedence(), true);
break;
--- 1249,1274 ----
switch (type) {
case VAR:
// Var declaration captured in for outer block.
! 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, forStart);
break;
}
if (env._const_as_var && type == CONST) {
// Var declaration captured in for outer block.
! vars = variableStatement(TokenType.VAR, false, forStart);
break;
}
init = expression(unaryExpression(), COMMARIGHT.getPrecedence(), true);
break;