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

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: delete decl_props Created 5 years, 8 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
« no previous file with comments | « src/preparser.h ('k') | test/message/for-in-let-loop-initializers-strict.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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, nullptr, nullptr, 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, int* num_decl,
429 VariableDeclarationProperties* decl_props, 427 Scanner::Location* first_initializer_loc, bool* ok) {
430 int* num_decl,
431 bool* ok) {
432 // VariableDeclarations :: 428 // VariableDeclarations ::
433 // ('var' | 'const') (Identifier ('=' AssignmentExpression)?)+[','] 429 // ('var' | 'const') (Identifier ('=' AssignmentExpression)?)+[',']
434 // 430 //
435 // The ES6 Draft Rev3 specifies the following grammar for const declarations 431 // The ES6 Draft Rev3 specifies the following grammar for const declarations
436 // 432 //
437 // ConstDeclaration :: 433 // ConstDeclaration ::
438 // const ConstBinding (',' ConstBinding)* ';' 434 // const ConstBinding (',' ConstBinding)* ';'
439 // ConstBinding :: 435 // ConstBinding ::
440 // Identifier '=' AssignmentExpression 436 // Identifier '=' AssignmentExpression
441 // 437 //
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
479 475
480 // The scope of a var/const declared variable anywhere inside a function 476 // 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 477 // 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 478 // of a let declared variable is the scope of the immediately enclosing
483 // block. 479 // block.
484 int nvars = 0; // the number of variables declared 480 int nvars = 0; // the number of variables declared
485 do { 481 do {
486 // Parse variable name. 482 // Parse variable name.
487 if (nvars > 0) Consume(Token::COMMA); 483 if (nvars > 0) Consume(Token::COMMA);
488 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); 484 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
485 Scanner::Location variable_loc = scanner()->location();
489 nvars++; 486 nvars++;
490 if (peek() == Token::ASSIGN || require_initializer || 487 if (peek() == Token::ASSIGN || require_initializer ||
491 // require initializers for multiple consts. 488 // require initializers for multiple consts.
492 (is_strict_const && peek() == Token::COMMA)) { 489 (is_strict_const && peek() == Token::COMMA)) {
493 Expect(Token::ASSIGN, CHECK_OK); 490 Expect(Token::ASSIGN, CHECK_OK);
494 ParseAssignmentExpression(var_context != kForStatement, CHECK_OK); 491 ParseAssignmentExpression(var_context != kForStatement, CHECK_OK);
495 if (decl_props != NULL) *decl_props = kHasInitializers; 492
493 variable_loc.end_pos = scanner()->location().end_pos;
494 if (first_initializer_loc && !first_initializer_loc->IsValid()) {
495 *first_initializer_loc = variable_loc;
496 }
496 } 497 }
497 } while (peek() == Token::COMMA); 498 } while (peek() == Token::COMMA);
498 499
499 if (num_decl != NULL) *num_decl = nvars; 500 if (num_decl != NULL) *num_decl = nvars;
500 return Statement::Default(); 501 return Statement::Default();
501 } 502 }
502 503
503 504
504 PreParser::Statement PreParser::ParseExpressionOrLabelledStatement(bool* ok) { 505 PreParser::Statement PreParser::ParseExpressionOrLabelledStatement(bool* ok) {
505 // ExpressionStatement | LabelledStatement :: 506 // ExpressionStatement | LabelledStatement ::
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after
721 722
722 723
723 PreParser::Statement PreParser::ParseForStatement(bool* ok) { 724 PreParser::Statement PreParser::ParseForStatement(bool* ok) {
724 // ForStatement :: 725 // ForStatement ::
725 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement 726 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement
726 727
727 Expect(Token::FOR, CHECK_OK); 728 Expect(Token::FOR, CHECK_OK);
728 Expect(Token::LPAREN, CHECK_OK); 729 Expect(Token::LPAREN, CHECK_OK);
729 bool is_let_identifier_expression = false; 730 bool is_let_identifier_expression = false;
730 if (peek() != Token::SEMICOLON) { 731 if (peek() != Token::SEMICOLON) {
731 ForEachStatement::VisitMode visit_mode; 732 ForEachStatement::VisitMode mode;
732 if (peek() == Token::VAR || peek() == Token::CONST || 733 if (peek() == Token::VAR || peek() == Token::CONST ||
733 (peek() == Token::LET && is_strict(language_mode()))) { 734 (peek() == Token::LET && is_strict(language_mode()))) {
734 bool is_lexical = peek() == Token::LET || 735 bool is_lexical = peek() == Token::LET ||
735 (peek() == Token::CONST && is_strict(language_mode())); 736 (peek() == Token::CONST && is_strict(language_mode()));
736 int decl_count; 737 int decl_count;
737 VariableDeclarationProperties decl_props = kHasNoInitializers; 738 Scanner::Location first_initializer_loc = Scanner::Location::invalid();
738 ParseVariableDeclarations( 739 ParseVariableDeclarations(kForStatement, &decl_count,
739 kForStatement, &decl_props, &decl_count, CHECK_OK); 740 &first_initializer_loc, CHECK_OK);
740 bool has_initializers = decl_props == kHasInitializers; 741 bool has_initializers = first_initializer_loc.IsValid();
741 bool accept_IN = decl_count == 1 && !(is_lexical && has_initializers); 742 bool accept_IN = decl_count == 1 && !(is_lexical && has_initializers);
742 bool accept_OF = !has_initializers; 743 bool accept_OF = true;
743 if (accept_IN && CheckInOrOf(accept_OF, &visit_mode, ok)) { 744 if (accept_IN && CheckInOrOf(accept_OF, &mode, ok)) {
744 if (!*ok) return Statement::Default(); 745 if (!*ok) return Statement::Default();
746 if (first_initializer_loc.IsValid() &&
747 (is_strict(language_mode()) || mode == ForEachStatement::ITERATE)) {
748 if (mode == ForEachStatement::ITERATE) {
749 ReportMessageAt(first_initializer_loc, "for_of_loop_initializer");
750 } else {
751 // TODO(caitp): This should be an error in sloppy mode, too.
752 ReportMessageAt(first_initializer_loc, "for_in_loop_initializer");
753 }
754 *ok = false;
755 return Statement::Default();
756 }
745 ParseExpression(true, CHECK_OK); 757 ParseExpression(true, CHECK_OK);
746 Expect(Token::RPAREN, CHECK_OK); 758 Expect(Token::RPAREN, CHECK_OK);
747 ParseSubStatement(CHECK_OK); 759 ParseSubStatement(CHECK_OK);
748 return Statement::Default(); 760 return Statement::Default();
749 } 761 }
750 } else { 762 } else {
751 Expression lhs = ParseExpression(false, CHECK_OK); 763 Expression lhs = ParseExpression(false, CHECK_OK);
752 is_let_identifier_expression = 764 is_let_identifier_expression =
753 lhs.IsIdentifier() && lhs.AsIdentifier().IsLet(); 765 lhs.IsIdentifier() && lhs.AsIdentifier().IsLet();
754 if (CheckInOrOf(lhs.IsIdentifier(), &visit_mode, ok)) { 766 if (CheckInOrOf(lhs.IsIdentifier(), &mode, ok)) {
755 if (!*ok) return Statement::Default(); 767 if (!*ok) return Statement::Default();
756 ParseExpression(true, CHECK_OK); 768 ParseExpression(true, CHECK_OK);
757 Expect(Token::RPAREN, CHECK_OK); 769 Expect(Token::RPAREN, CHECK_OK);
758 ParseSubStatement(CHECK_OK); 770 ParseSubStatement(CHECK_OK);
759 return Statement::Default(); 771 return Statement::Default();
760 } 772 }
761 } 773 }
762 } 774 }
763 775
764 // Parsed initializer at this point. 776 // Parsed initializer at this point.
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after
1045 ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); 1057 ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
1046 ParseArguments(ok); 1058 ParseArguments(ok);
1047 1059
1048 return Expression::Default(); 1060 return Expression::Default();
1049 } 1061 }
1050 1062
1051 #undef CHECK_OK 1063 #undef CHECK_OK
1052 1064
1053 1065
1054 } } // v8::internal 1066 } } // v8::internal
OLDNEW
« no previous file with comments | « src/preparser.h ('k') | test/message/for-in-let-loop-initializers-strict.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698