Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(21)

Side by Side Diff: src/preparser.cc

Issue 1033823002: [es6] emit error when for-in loop declarations are initialized in strict mode (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <cmath> 5 #include <cmath>
6 6
7 #include "src/allocation.h" 7 #include "src/allocation.h"
8 #include "src/base/logging.h" 8 #include "src/base/logging.h"
9 #include "src/conversions-inl.h" 9 #include "src/conversions-inl.h"
10 #include "src/conversions.h" 10 #include "src/conversions.h"
(...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after
403 return Statement::Default(); 403 return Statement::Default();
404 } 404 }
405 405
406 406
407 PreParser::Statement PreParser::ParseVariableStatement( 407 PreParser::Statement PreParser::ParseVariableStatement(
408 VariableDeclarationContext var_context, 408 VariableDeclarationContext var_context,
409 bool* ok) { 409 bool* ok) {
410 // VariableStatement :: 410 // VariableStatement ::
411 // VariableDeclarations ';' 411 // VariableDeclarations ';'
412 412
413 Statement result = ParseVariableDeclarations(var_context, 413 Statement result =
414 NULL, 414 ParseVariableDeclarations(var_context, NULL, NULL, NULL, CHECK_OK);
415 NULL,
416 CHECK_OK);
417 ExpectSemicolon(CHECK_OK); 415 ExpectSemicolon(CHECK_OK);
418 return result; 416 return result;
419 } 417 }
420 418
421 419
422 // If the variable declaration declares exactly one non-const 420 // If the variable declaration declares exactly one non-const
423 // variable, then *var is set to that variable. In all other cases, 421 // variable, then *var is set to that variable. In all other cases,
424 // *var is untouched; in particular, it is the caller's responsibility 422 // *var is untouched; in particular, it is the caller's responsibility
425 // to initialize it properly. This mechanism is also used for the parsing 423 // to initialize it properly. This mechanism is also used for the parsing
426 // of 'for-in' loops. 424 // of 'for-in' loops.
427 PreParser::Statement PreParser::ParseVariableDeclarations( 425 PreParser::Statement PreParser::ParseVariableDeclarations(
428 VariableDeclarationContext var_context, 426 VariableDeclarationContext var_context,
429 VariableDeclarationProperties* decl_props, 427 VariableDeclarationProperties* decl_props, int* num_decl,
430 int* num_decl, 428 Scanner::Location* first_initializer_loc, bool* ok) {
431 bool* ok) {
432 // VariableDeclarations :: 429 // VariableDeclarations ::
433 // ('var' | 'const') (Identifier ('=' AssignmentExpression)?)+[','] 430 // ('var' | 'const') (Identifier ('=' AssignmentExpression)?)+[',']
434 // 431 //
435 // The ES6 Draft Rev3 specifies the following grammar for const declarations 432 // The ES6 Draft Rev3 specifies the following grammar for const declarations
436 // 433 //
437 // ConstDeclaration :: 434 // ConstDeclaration ::
438 // const ConstBinding (',' ConstBinding)* ';' 435 // const ConstBinding (',' ConstBinding)* ';'
439 // ConstBinding :: 436 // ConstBinding ::
440 // Identifier '=' AssignmentExpression 437 // Identifier '=' AssignmentExpression
441 // 438 //
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
475 } else { 472 } else {
476 *ok = false; 473 *ok = false;
477 return Statement::Default(); 474 return Statement::Default();
478 } 475 }
479 476
480 // The scope of a var/const declared variable anywhere inside a function 477 // The scope of a var/const declared variable anywhere inside a function
481 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). The scope 478 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). The scope
482 // of a let declared variable is the scope of the immediately enclosing 479 // of a let declared variable is the scope of the immediately enclosing
483 // block. 480 // block.
484 int nvars = 0; // the number of variables declared 481 int nvars = 0; // the number of variables declared
482 bool initializer_recorded = false;
485 do { 483 do {
486 // Parse variable name. 484 // Parse variable name.
487 if (nvars > 0) Consume(Token::COMMA); 485 if (nvars > 0) Consume(Token::COMMA);
488 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); 486 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
487 Scanner::Location variable_loc = scanner()->location();
489 nvars++; 488 nvars++;
490 if (peek() == Token::ASSIGN || require_initializer || 489 if (peek() == Token::ASSIGN || require_initializer ||
491 // require initializers for multiple consts. 490 // require initializers for multiple consts.
492 (is_strict_const && peek() == Token::COMMA)) { 491 (is_strict_const && peek() == Token::COMMA)) {
493 Expect(Token::ASSIGN, CHECK_OK); 492 Expect(Token::ASSIGN, CHECK_OK);
494 ParseAssignmentExpression(var_context != kForStatement, CHECK_OK); 493 ParseAssignmentExpression(var_context != kForStatement, CHECK_OK);
494
495 variable_loc.end_pos = scanner()->location().end_pos;
496 if (first_initializer_loc && !initializer_recorded) {
497 *first_initializer_loc = variable_loc;
498 initializer_recorded = true;
499 }
500
495 if (decl_props != NULL) *decl_props = kHasInitializers; 501 if (decl_props != NULL) *decl_props = kHasInitializers;
496 } 502 }
497 } while (peek() == Token::COMMA); 503 } while (peek() == Token::COMMA);
498 504
499 if (num_decl != NULL) *num_decl = nvars; 505 if (num_decl != NULL) *num_decl = nvars;
500 return Statement::Default(); 506 return Statement::Default();
501 } 507 }
502 508
503 509
504 PreParser::Statement PreParser::ParseExpressionOrLabelledStatement(bool* ok) { 510 PreParser::Statement PreParser::ParseExpressionOrLabelledStatement(bool* ok) {
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after
728 Expect(Token::LPAREN, CHECK_OK); 734 Expect(Token::LPAREN, CHECK_OK);
729 bool is_let_identifier_expression = false; 735 bool is_let_identifier_expression = false;
730 if (peek() != Token::SEMICOLON) { 736 if (peek() != Token::SEMICOLON) {
731 ForEachStatement::VisitMode visit_mode; 737 ForEachStatement::VisitMode visit_mode;
732 if (peek() == Token::VAR || peek() == Token::CONST || 738 if (peek() == Token::VAR || peek() == Token::CONST ||
733 (peek() == Token::LET && is_strict(language_mode()))) { 739 (peek() == Token::LET && is_strict(language_mode()))) {
734 bool is_lexical = peek() == Token::LET || 740 bool is_lexical = peek() == Token::LET ||
735 (peek() == Token::CONST && is_strict(language_mode())); 741 (peek() == Token::CONST && is_strict(language_mode()));
736 int decl_count; 742 int decl_count;
737 VariableDeclarationProperties decl_props = kHasNoInitializers; 743 VariableDeclarationProperties decl_props = kHasNoInitializers;
738 ParseVariableDeclarations( 744 Scanner::Location first_initializer_loc = Scanner::Location::invalid();
739 kForStatement, &decl_props, &decl_count, CHECK_OK); 745 ParseVariableDeclarations(kForStatement, &decl_props, &decl_count,
746 &first_initializer_loc, CHECK_OK);
740 bool has_initializers = decl_props == kHasInitializers; 747 bool has_initializers = decl_props == kHasInitializers;
741 bool accept_IN = decl_count == 1 && !(is_lexical && has_initializers); 748 bool accept_IN = decl_count == 1 && !(is_lexical && has_initializers);
742 bool accept_OF = !has_initializers; 749 bool accept_OF = true;
743 if (accept_IN && CheckInOrOf(accept_OF, &visit_mode, ok)) { 750 if (accept_IN && CheckInOrOf(accept_OF, &visit_mode, ok)) {
744 if (!*ok) return Statement::Default(); 751 if (!*ok) return Statement::Default();
752 if (first_initializer_loc.IsValid() &&
753 (is_strict(language_mode()) ||
754 visit_mode == ForEachStatement::ITERATE)) {
755 if (visit_mode == ForEachStatement::ITERATE) {
756 ReportMessageAt(first_initializer_loc, "for_of_loop_initializer");
757 } else {
758 ReportMessageAt(first_initializer_loc,
759 "strict_for_in_loop_initializer");
760 }
761 *ok = false;
762 return Statement::Default();
763 }
745 ParseExpression(true, CHECK_OK); 764 ParseExpression(true, CHECK_OK);
746 Expect(Token::RPAREN, CHECK_OK); 765 Expect(Token::RPAREN, CHECK_OK);
747 ParseSubStatement(CHECK_OK); 766 ParseSubStatement(CHECK_OK);
748 return Statement::Default(); 767 return Statement::Default();
749 } 768 }
750 } else { 769 } else {
751 Expression lhs = ParseExpression(false, CHECK_OK); 770 Expression lhs = ParseExpression(false, CHECK_OK);
752 is_let_identifier_expression = 771 is_let_identifier_expression =
753 lhs.IsIdentifier() && lhs.AsIdentifier().IsLet(); 772 lhs.IsIdentifier() && lhs.AsIdentifier().IsLet();
754 if (CheckInOrOf(lhs.IsIdentifier(), &visit_mode, ok)) { 773 if (CheckInOrOf(lhs.IsIdentifier(), &visit_mode, ok)) {
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after
1045 ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); 1064 ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
1046 ParseArguments(ok); 1065 ParseArguments(ok);
1047 1066
1048 return Expression::Default(); 1067 return Expression::Default();
1049 } 1068 }
1050 1069
1051 #undef CHECK_OK 1070 #undef CHECK_OK
1052 1071
1053 1072
1054 } } // v8::internal 1073 } } // v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698