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

Side by Side Diff: src/parsing/preparser.cc

Issue 2297563007: Move ParseVariableDeclarations to ParserBase. (Closed)
Patch Set: comment & whitespace fixes - see try jobs from a previous patch set Created 4 years, 3 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
« src/parsing/parser-base.h ('K') | « src/parsing/preparser.h ('k') | no next file » | 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 413 matching lines...) Expand 10 before | Expand all | Expand 10 after
424 return final; 424 return final;
425 } 425 }
426 426
427 427
428 PreParser::Statement PreParser::ParseVariableStatement( 428 PreParser::Statement PreParser::ParseVariableStatement(
429 VariableDeclarationContext var_context, 429 VariableDeclarationContext var_context,
430 bool* ok) { 430 bool* ok) {
431 // VariableStatement :: 431 // VariableStatement ::
432 // VariableDeclarations ';' 432 // VariableDeclarations ';'
433 433
434 Statement result = ParseVariableDeclarations( 434 Statement result =
435 var_context, nullptr, nullptr, nullptr, nullptr, nullptr, CHECK_OK); 435 ParseVariableDeclarations(var_context, nullptr, nullptr, CHECK_OK);
436 ExpectSemicolon(CHECK_OK); 436 ExpectSemicolon(CHECK_OK);
437 return result; 437 return result;
438 } 438 }
439 439
440
441 // If the variable declaration declares exactly one non-const
442 // variable, then *var is set to that variable. In all other cases,
443 // *var is untouched; in particular, it is the caller's responsibility
444 // to initialize it properly. This mechanism is also used for the parsing
445 // of 'for-in' loops.
446 PreParser::Statement PreParser::ParseVariableDeclarations(
447 VariableDeclarationContext var_context, int* num_decl, bool* is_lexical,
448 bool* is_binding_pattern, Scanner::Location* first_initializer_loc,
449 Scanner::Location* bindings_loc, bool* ok) {
450 // VariableDeclarations ::
451 // ('var' | 'const') (Identifier ('=' AssignmentExpression)?)+[',']
452 //
453 // The ES6 Draft Rev3 specifies the following grammar for const declarations
454 //
455 // ConstDeclaration ::
456 // const ConstBinding (',' ConstBinding)* ';'
457 // ConstBinding ::
458 // Identifier '=' AssignmentExpression
459 //
460 // TODO(ES6):
461 // ConstBinding ::
462 // BindingPattern '=' AssignmentExpression
463 bool require_initializer = false;
464 bool lexical = false;
465 bool is_pattern = false;
466 if (peek() == Token::VAR) {
467 Consume(Token::VAR);
468 } else if (peek() == Token::CONST) {
469 // TODO(ES6): The ES6 Draft Rev4 section 12.2.2 reads:
470 //
471 // ConstDeclaration : const ConstBinding (',' ConstBinding)* ';'
472 //
473 // * It is a Syntax Error if the code that matches this production is not
474 // contained in extended code.
475 //
476 // However disallowing const in sloppy mode will break compatibility with
477 // existing pages. Therefore we keep allowing const with the old
478 // non-harmony semantics in sloppy mode.
479 Consume(Token::CONST);
480 DCHECK(var_context != kStatement);
481 require_initializer = true;
482 lexical = true;
483 } else if (peek() == Token::LET) {
484 Consume(Token::LET);
485 DCHECK(var_context != kStatement);
486 lexical = true;
487 } else {
488 *ok = false;
489 return Statement::Default();
490 }
491
492 // The scope of a var/const declared variable anywhere inside a function
493 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). The scope
494 // of a let declared variable is the scope of the immediately enclosing
495 // block.
496 int nvars = 0; // the number of variables declared
497 int bindings_start = peek_position();
498 do {
499 // Parse binding pattern.
500 if (nvars > 0) Consume(Token::COMMA);
501 int decl_pos = peek_position();
502 PreParserExpression pattern = PreParserExpression::Default();
503 {
504 ExpressionClassifier pattern_classifier(this);
505 pattern = ParsePrimaryExpression(CHECK_OK);
506
507 ValidateBindingPattern(CHECK_OK);
508 if (lexical) ValidateLetPattern(CHECK_OK);
509 }
510
511 is_pattern = pattern.IsObjectLiteral() || pattern.IsArrayLiteral();
512
513 Scanner::Location variable_loc = scanner()->location();
514 nvars++;
515 if (Check(Token::ASSIGN)) {
516 ExpressionClassifier classifier(this);
517 ParseAssignmentExpression(var_context != kForStatement, CHECK_OK);
518 ValidateExpression(CHECK_OK);
519
520 variable_loc.end_pos = scanner()->location().end_pos;
521 if (first_initializer_loc && !first_initializer_loc->IsValid()) {
522 *first_initializer_loc = variable_loc;
523 }
524 } else if ((require_initializer || is_pattern) &&
525 (var_context != kForStatement || !PeekInOrOf())) {
526 ReportMessageAt(
527 Scanner::Location(decl_pos, scanner()->location().end_pos),
528 MessageTemplate::kDeclarationMissingInitializer,
529 is_pattern ? "destructuring" : "const");
530 *ok = false;
531 return Statement::Default();
532 }
533 } while (peek() == Token::COMMA);
534
535 if (bindings_loc) {
536 *bindings_loc =
537 Scanner::Location(bindings_start, scanner()->location().end_pos);
538 }
539
540 if (num_decl != nullptr) *num_decl = nvars;
541 if (is_lexical != nullptr) *is_lexical = lexical;
542 if (is_binding_pattern != nullptr) *is_binding_pattern = is_pattern;
543 return Statement::Default();
544 }
545
546 PreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) { 440 PreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) {
547 Consume(Token::FUNCTION); 441 Consume(Token::FUNCTION);
548 int pos = position(); 442 int pos = position();
549 ParseFunctionFlags flags = ParseFunctionFlags::kIsNormal; 443 ParseFunctionFlags flags = ParseFunctionFlags::kIsNormal;
550 if (Check(Token::MUL)) { 444 if (Check(Token::MUL)) {
551 flags |= ParseFunctionFlags::kIsGenerator; 445 flags |= ParseFunctionFlags::kIsGenerator;
552 if (allow_harmony_restrictive_declarations()) { 446 if (allow_harmony_restrictive_declarations()) {
553 ReportMessageAt(scanner()->location(), 447 ReportMessageAt(scanner()->location(),
554 MessageTemplate::kGeneratorInLegacyContext); 448 MessageTemplate::kGeneratorInLegacyContext);
555 *ok = false; 449 *ok = false;
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after
799 // Create an in-between scope for let-bound iteration variables. 693 // Create an in-between scope for let-bound iteration variables.
800 bool has_lexical = false; 694 bool has_lexical = false;
801 695
802 BlockState block_state(&scope_state_); 696 BlockState block_state(&scope_state_);
803 Expect(Token::FOR, CHECK_OK); 697 Expect(Token::FOR, CHECK_OK);
804 Expect(Token::LPAREN, CHECK_OK); 698 Expect(Token::LPAREN, CHECK_OK);
805 if (peek() != Token::SEMICOLON) { 699 if (peek() != Token::SEMICOLON) {
806 ForEachStatement::VisitMode mode; 700 ForEachStatement::VisitMode mode;
807 if (peek() == Token::VAR || peek() == Token::CONST || 701 if (peek() == Token::VAR || peek() == Token::CONST ||
808 (peek() == Token::LET && IsNextLetKeyword())) { 702 (peek() == Token::LET && IsNextLetKeyword())) {
809 int decl_count; 703 DeclarationParsingResult parsing_result;
810 bool is_lexical; 704
811 bool is_binding_pattern; 705 ParseVariableDeclarations(kForStatement, &parsing_result, nullptr,
812 Scanner::Location first_initializer_loc = Scanner::Location::invalid(); 706 CHECK_OK);
813 Scanner::Location bindings_loc = Scanner::Location::invalid(); 707 if (parsing_result.descriptor.mode == CONST ||
814 ParseVariableDeclarations(kForStatement, &decl_count, &is_lexical, 708 parsing_result.descriptor.mode == LET) {
815 &is_binding_pattern, &first_initializer_loc, 709 has_lexical = true;
816 &bindings_loc, CHECK_OK); 710 }
817 if (is_lexical) has_lexical = true;
818 if (CheckInOrOf(&mode, ok)) { 711 if (CheckInOrOf(&mode, ok)) {
819 if (!*ok) return Statement::Default(); 712 if (!*ok) return Statement::Default();
820 if (decl_count != 1) { 713 if (parsing_result.declarations.length() != 1) {
821 ReportMessageAt(bindings_loc, 714 ReportMessageAt(parsing_result.bindings_loc,
822 MessageTemplate::kForInOfLoopMultiBindings, 715 MessageTemplate::kForInOfLoopMultiBindings,
823 ForEachStatement::VisitModeString(mode)); 716 ForEachStatement::VisitModeString(mode));
824 *ok = false; 717 *ok = false;
825 return Statement::Default(); 718 return Statement::Default();
826 } 719 }
827 if (first_initializer_loc.IsValid() && 720 bool is_binding_pattern =
721 parsing_result.declarations[0].pattern.IsObjectLiteral() ||
722 parsing_result.declarations[0].pattern.IsArrayLiteral();
723 if (parsing_result.first_initializer_loc.IsValid() &&
828 (is_strict(language_mode()) || mode == ForEachStatement::ITERATE || 724 (is_strict(language_mode()) || mode == ForEachStatement::ITERATE ||
829 is_lexical || is_binding_pattern || allow_harmony_for_in())) { 725 has_lexical || is_binding_pattern || allow_harmony_for_in())) {
830 // Only increment the use count if we would have let this through 726 // Only increment the use count if we would have let this through
831 // without the flag. 727 // without the flag.
832 if (use_counts_ != nullptr && allow_harmony_for_in()) { 728 if (use_counts_ != nullptr && allow_harmony_for_in()) {
833 ++use_counts_[v8::Isolate::kForInInitializer]; 729 ++use_counts_[v8::Isolate::kForInInitializer];
834 } 730 }
835 ReportMessageAt(first_initializer_loc, 731 ReportMessageAt(parsing_result.first_initializer_loc,
836 MessageTemplate::kForInOfLoopInitializer, 732 MessageTemplate::kForInOfLoopInitializer,
837 ForEachStatement::VisitModeString(mode)); 733 ForEachStatement::VisitModeString(mode));
838 *ok = false; 734 *ok = false;
839 return Statement::Default(); 735 return Statement::Default();
840 } 736 }
841 737
842 if (mode == ForEachStatement::ITERATE) { 738 if (mode == ForEachStatement::ITERATE) {
843 ExpressionClassifier classifier(this); 739 ExpressionClassifier classifier(this);
844 ParseAssignmentExpression(true, CHECK_OK); 740 ParseAssignmentExpression(true, CHECK_OK);
845 RewriteNonPattern(CHECK_OK); 741 RewriteNonPattern(CHECK_OK);
(...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after
1232 1128
1233 body->Add(PreParserStatement::ExpressionStatement(return_value), zone()); 1129 body->Add(PreParserStatement::ExpressionStatement(return_value), zone());
1234 } 1130 }
1235 1131
1236 #undef CHECK_OK 1132 #undef CHECK_OK
1237 #undef CHECK_OK_CUSTOM 1133 #undef CHECK_OK_CUSTOM
1238 1134
1239 1135
1240 } // namespace internal 1136 } // namespace internal
1241 } // namespace v8 1137 } // namespace v8
OLDNEW
« src/parsing/parser-base.h ('K') | « src/parsing/preparser.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698