| Index: src/preparser.cc
|
| diff --git a/src/preparser.cc b/src/preparser.cc
|
| index 5a6a094f6af52b7ba025e9d4ff9c0450499497f7..f145d7681902d3d098830579791b738da5a2f256 100644
|
| --- a/src/preparser.cc
|
| +++ b/src/preparser.cc
|
| @@ -410,10 +410,8 @@ PreParser::Statement PreParser::ParseVariableStatement(
|
| // VariableStatement ::
|
| // VariableDeclarations ';'
|
|
|
| - Statement result = ParseVariableDeclarations(var_context,
|
| - NULL,
|
| - NULL,
|
| - CHECK_OK);
|
| + Statement result =
|
| + ParseVariableDeclarations(var_context, NULL, NULL, NULL, CHECK_OK);
|
| ExpectSemicolon(CHECK_OK);
|
| return result;
|
| }
|
| @@ -426,9 +424,8 @@ PreParser::Statement PreParser::ParseVariableStatement(
|
| // of 'for-in' loops.
|
| PreParser::Statement PreParser::ParseVariableDeclarations(
|
| VariableDeclarationContext var_context,
|
| - VariableDeclarationProperties* decl_props,
|
| - int* num_decl,
|
| - bool* ok) {
|
| + VariableDeclarationProperties* decl_props, int* num_decl,
|
| + Scanner::Location* first_initializer_loc, bool* ok) {
|
| // VariableDeclarations ::
|
| // ('var' | 'const') (Identifier ('=' AssignmentExpression)?)+[',']
|
| //
|
| @@ -482,16 +479,25 @@ PreParser::Statement PreParser::ParseVariableDeclarations(
|
| // of a let declared variable is the scope of the immediately enclosing
|
| // block.
|
| int nvars = 0; // the number of variables declared
|
| + bool initializer_recorded = false;
|
| do {
|
| // Parse variable name.
|
| if (nvars > 0) Consume(Token::COMMA);
|
| ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
|
| + Scanner::Location variable_loc = scanner()->location();
|
| nvars++;
|
| if (peek() == Token::ASSIGN || require_initializer ||
|
| // require initializers for multiple consts.
|
| (is_strict_const && peek() == Token::COMMA)) {
|
| Expect(Token::ASSIGN, CHECK_OK);
|
| ParseAssignmentExpression(var_context != kForStatement, CHECK_OK);
|
| +
|
| + variable_loc.end_pos = scanner()->location().end_pos;
|
| + if (first_initializer_loc && !initializer_recorded) {
|
| + *first_initializer_loc = variable_loc;
|
| + initializer_recorded = true;
|
| + }
|
| +
|
| if (decl_props != NULL) *decl_props = kHasInitializers;
|
| }
|
| } while (peek() == Token::COMMA);
|
| @@ -735,13 +741,26 @@ PreParser::Statement PreParser::ParseForStatement(bool* ok) {
|
| (peek() == Token::CONST && is_strict(language_mode()));
|
| int decl_count;
|
| VariableDeclarationProperties decl_props = kHasNoInitializers;
|
| - ParseVariableDeclarations(
|
| - kForStatement, &decl_props, &decl_count, CHECK_OK);
|
| + Scanner::Location first_initializer_loc = Scanner::Location::invalid();
|
| + ParseVariableDeclarations(kForStatement, &decl_props, &decl_count,
|
| + &first_initializer_loc, CHECK_OK);
|
| bool has_initializers = decl_props == kHasInitializers;
|
| bool accept_IN = decl_count == 1 && !(is_lexical && has_initializers);
|
| - bool accept_OF = !has_initializers;
|
| + bool accept_OF = true;
|
| if (accept_IN && CheckInOrOf(accept_OF, &visit_mode, ok)) {
|
| if (!*ok) return Statement::Default();
|
| + if (first_initializer_loc.IsValid() &&
|
| + (is_strict(language_mode()) ||
|
| + visit_mode == ForEachStatement::ITERATE)) {
|
| + if (visit_mode == ForEachStatement::ITERATE) {
|
| + ReportMessageAt(first_initializer_loc, "for_of_loop_initializer");
|
| + } else {
|
| + ReportMessageAt(first_initializer_loc,
|
| + "strict_for_in_loop_initializer");
|
| + }
|
| + *ok = false;
|
| + return Statement::Default();
|
| + }
|
| ParseExpression(true, CHECK_OK);
|
| Expect(Token::RPAREN, CHECK_OK);
|
| ParseSubStatement(CHECK_OK);
|
|
|