src/jdk/nashorn/internal/parser/Parser.java

Print this page

        

*** 557,567 **** return getBlock(true); } // Set up new block. Captures first token. Block newBlock = newBlock(); try { ! statement(); } finally { newBlock = restoreBlock(newBlock); } return newBlock; } --- 557,567 ---- return getBlock(true); } // Set up new block. Captures first token. Block newBlock = newBlock(); try { ! statement(false, false, true); } finally { newBlock = restoreBlock(newBlock); } return newBlock; }
*** 770,780 **** break; } try { // Get the next element. ! statement(true, allowPropertyFunction); allowPropertyFunction = false; // check for directive prologues if (checkDirective) { // skip any debug statement like line number to get actual first line --- 770,780 ---- break; } try { // Get the next element. ! statement(true, allowPropertyFunction, false); allowPropertyFunction = false; // check for directive prologues if (checkDirective) { // skip any debug statement like line number to get actual first line
*** 860,876 **** * see 12 * * Parse any of the basic statement types. */ private void statement() { ! statement(false, false); } /** * @param topLevel does this statement occur at the "top level" of a script or a function? */ ! private void statement(final boolean topLevel, final boolean allowPropertyFunction) { if (type == FUNCTION) { // As per spec (ECMA section 12), function declarations as arbitrary statement // is not "portable". Implementation can issue a warning or disallow the same. functionExpression(true, topLevel); return; --- 860,878 ---- * see 12 * * Parse any of the basic statement types. */ private void statement() { ! statement(false, false, false); } /** * @param topLevel does this statement occur at the "top level" of a script or a function? + * @param allowPropertyFunction allow property "get" and "set" functions? + * @param singleStatement are we in a single statement context? */ ! private void statement(final boolean topLevel, final boolean allowPropertyFunction, final boolean singleStatement) { if (type == FUNCTION) { // As per spec (ECMA section 12), function declarations as arbitrary statement // is not "portable". Implementation can issue a warning or disallow the same. functionExpression(true, topLevel); return;
*** 930,939 **** --- 932,944 ---- case EOF: expect(SEMICOLON); break; 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);
*** 1055,1065 **** private List<VarNode> variableStatement(final TokenType varType, final boolean isStatement) { // VAR tested in caller. next(); final List<VarNode> vars = new ArrayList<>(); ! int varFlags = VarNode.IS_STATEMENT; if (varType == LET) { varFlags |= VarNode.IS_LET; } else if (varType == CONST) { varFlags |= VarNode.IS_CONST; } --- 1060,1070 ---- private List<VarNode> variableStatement(final TokenType varType, final boolean isStatement) { // VAR tested in caller. next(); final List<VarNode> vars = new ArrayList<>(); ! int varFlags = 0; if (varType == LET) { varFlags |= VarNode.IS_LET; } else if (varType == CONST) { varFlags |= VarNode.IS_CONST; }
*** 1208,1218 **** // When ES6 for-let is enabled we create a container block to capture the LET. final int startLine = start; Block outer = useBlockScope() ? newBlock() : null; // Create FOR node, capturing FOR token. ! ForNode forNode = new ForNode(line, token, Token.descPosition(token), null, ForNode.IS_FOR); lc.push(forNode); try { // FOR tested in caller. next(); --- 1213,1223 ---- // When ES6 for-let is enabled we create a container block to capture the LET. final int startLine = start; Block outer = useBlockScope() ? newBlock() : null; // Create FOR node, capturing FOR token. ! ForNode forNode = new ForNode(line, token, Token.descPosition(token), null, 0); lc.push(forNode); try { // FOR tested in caller. next();
*** 1228,1250 **** List<VarNode> vars = null; switch (type) { case VAR: ! // Var statements captured in for outer block. vars = variableStatement(type, false); break; case SEMICOLON: break; default: if (useBlockScope() && (type == LET || type == CONST)) { ! // LET/CONST captured in container block created above. vars = variableStatement(type, false); break; } if (env._const_as_var && type == CONST) { ! // Var statements captured in for outer block. vars = variableStatement(TokenType.VAR, false); break; } final Expression expression = expression(unaryExpression(), COMMARIGHT.getPrecedence(), true); --- 1233,1258 ---- List<VarNode> vars = null; 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) { ! forNode = forNode.setPerIterationScope(lc); ! } ! // 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; } final Expression expression = expression(unaryExpression(), COMMARIGHT.getPrecedence(), true);
*** 1321,1337 **** forNode.setFinish(body.getFinish()); appendStatement(forNode); } finally { lc.pop(forNode); if (outer != null) { outer.setFinish(forNode.getFinish()); outer = restoreBlock(outer); appendStatement(new BlockStatement(startLine, outer)); } } - } /** * ... IterationStatement : * ... * Expression[NoIn]?; Expression? ; Expression? --- 1329,1346 ---- forNode.setFinish(body.getFinish()); appendStatement(forNode); } finally { lc.pop(forNode); + } + if (outer != null) { outer.setFinish(forNode.getFinish()); outer = restoreBlock(outer); appendStatement(new BlockStatement(startLine, outer)); } } /** * ... IterationStatement : * ... * Expression[NoIn]?; Expression? ; Expression?
*** 2697,2711 **** functionNode = functionNode.setFlag(lc, FunctionNode.DEFINES_ARGUMENTS); } } if (isStatement) { ! int varFlags = VarNode.IS_STATEMENT; ! if (!topLevel && useBlockScope()) { ! // mark ES6 block functions as lexically scoped ! varFlags |= VarNode.IS_LET; ! } final VarNode varNode = new VarNode(functionLine, functionToken, finish, name, functionNode, varFlags); if (topLevel) { functionDeclarations.add(varNode); } else if (useBlockScope()) { prependStatement(varNode); // Hoist to beginning of current block --- 2706,2716 ---- functionNode = functionNode.setFlag(lc, FunctionNode.DEFINES_ARGUMENTS); } } if (isStatement) { ! final int varFlags = (topLevel || !useBlockScope()) ? 0 : VarNode.IS_LET; final VarNode varNode = new VarNode(functionLine, functionToken, finish, name, functionNode, varFlags); if (topLevel) { functionDeclarations.add(varNode); } else if (useBlockScope()) { prependStatement(varNode); // Hoist to beginning of current block