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

Side by Side Diff: src/preparser.cc

Issue 1065983005: Introduce "expression classifier" to the parser. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Added operator== and operator!= to Scanner::Location 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') | src/scanner.h » ('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 502 matching lines...) Expand 10 before | Expand all | Expand 10 after
513 do { 513 do {
514 // Parse variable name. 514 // Parse variable name.
515 if (nvars > 0) Consume(Token::COMMA); 515 if (nvars > 0) Consume(Token::COMMA);
516 ParseIdentifier(kDontAllowRestrictedIdentifiers, CHECK_OK); 516 ParseIdentifier(kDontAllowRestrictedIdentifiers, CHECK_OK);
517 Scanner::Location variable_loc = scanner()->location(); 517 Scanner::Location variable_loc = scanner()->location();
518 nvars++; 518 nvars++;
519 if (peek() == Token::ASSIGN || require_initializer || 519 if (peek() == Token::ASSIGN || require_initializer ||
520 // require initializers for multiple consts. 520 // require initializers for multiple consts.
521 (is_strict_const && peek() == Token::COMMA)) { 521 (is_strict_const && peek() == Token::COMMA)) {
522 Expect(Token::ASSIGN, CHECK_OK); 522 Expect(Token::ASSIGN, CHECK_OK);
523 ParseAssignmentExpression(var_context != kForStatement, CHECK_OK); 523 ExpressionClassifier classifier;
524 ParseAssignmentExpression(var_context != kForStatement, &classifier,
525 CHECK_OK);
526 // TODO(dslomov): report error if not valid expression.
524 527
525 variable_loc.end_pos = scanner()->location().end_pos; 528 variable_loc.end_pos = scanner()->location().end_pos;
526 if (first_initializer_loc && !first_initializer_loc->IsValid()) { 529 if (first_initializer_loc && !first_initializer_loc->IsValid()) {
527 *first_initializer_loc = variable_loc; 530 *first_initializer_loc = variable_loc;
528 } 531 }
529 } 532 }
530 } while (peek() == Token::COMMA); 533 } while (peek() == Token::COMMA);
531 534
532 if (bindings_loc) { 535 if (bindings_loc) {
533 *bindings_loc = 536 *bindings_loc =
(...skipping 18 matching lines...) Expand all
552 ReportUnexpectedToken(Next()); 555 ReportUnexpectedToken(Next());
553 *ok = false; 556 *ok = false;
554 return Statement::Default(); 557 return Statement::Default();
555 558
556 case Token::THIS: 559 case Token::THIS:
557 case Token::SUPER: 560 case Token::SUPER:
558 if (is_strong(language_mode()) && 561 if (is_strong(language_mode()) &&
559 i::IsConstructor(function_state_->kind())) { 562 i::IsConstructor(function_state_->kind())) {
560 bool is_this = peek() == Token::THIS; 563 bool is_this = peek() == Token::THIS;
561 Expression expr = Expression::Default(); 564 Expression expr = Expression::Default();
565 ExpressionClassifier classifier;
562 if (is_this) { 566 if (is_this) {
563 expr = ParseStrongInitializationExpression(CHECK_OK); 567 expr = ParseStrongInitializationExpression(&classifier, CHECK_OK);
564 } else { 568 } else {
565 expr = ParseStrongSuperCallExpression(CHECK_OK); 569 expr = ParseStrongSuperCallExpression(&classifier, CHECK_OK);
566 } 570 }
571 // TODO(dslomov): report error if not a valid expression.
567 switch (peek()) { 572 switch (peek()) {
568 case Token::SEMICOLON: 573 case Token::SEMICOLON:
569 Consume(Token::SEMICOLON); 574 Consume(Token::SEMICOLON);
570 break; 575 break;
571 case Token::RBRACE: 576 case Token::RBRACE:
572 case Token::EOS: 577 case Token::EOS:
573 break; 578 break;
574 default: 579 default:
575 if (!scanner()->HasAnyLineTerminatorBeforeNext()) { 580 if (!scanner()->HasAnyLineTerminatorBeforeNext()) {
576 ReportMessageAt(function_state_->this_location(), 581 ReportMessageAt(function_state_->this_location(),
577 is_this ? "strong_constructor_this" 582 is_this ? "strong_constructor_this"
578 : "strong_constructor_super"); 583 : "strong_constructor_super");
579 *ok = false; 584 *ok = false;
580 return Statement::Default(); 585 return Statement::Default();
581 } 586 }
582 } 587 }
583 return Statement::ExpressionStatement(expr); 588 return Statement::ExpressionStatement(expr);
584 } 589 }
585 break; 590 break;
586 591
587 // TODO(arv): Handle `let [` 592 // TODO(arv): Handle `let [`
588 // https://code.google.com/p/v8/issues/detail?id=3847 593 // https://code.google.com/p/v8/issues/detail?id=3847
589 594
590 default: 595 default:
591 break; 596 break;
592 } 597 }
593 598
594 bool starts_with_identifier = peek_any_identifier(); 599 bool starts_with_identifier = peek_any_identifier();
595 Expression expr = ParseExpression(true, CHECK_OK); 600 ExpressionClassifier classifier;
601 Expression expr = ParseExpression(true, &classifier, CHECK_OK);
602 // TODO(dslomov): report error if not a valid expression.
603
596 // Even if the expression starts with an identifier, it is not necessarily an 604 // Even if the expression starts with an identifier, it is not necessarily an
597 // identifier. For example, "foo + bar" starts with an identifier but is not 605 // identifier. For example, "foo + bar" starts with an identifier but is not
598 // an identifier. 606 // an identifier.
599 if (starts_with_identifier && expr.IsIdentifier() && peek() == Token::COLON) { 607 if (starts_with_identifier && expr.IsIdentifier() && peek() == Token::COLON) {
600 // Expression is a single identifier, and not, e.g., a parenthesized 608 // Expression is a single identifier, and not, e.g., a parenthesized
601 // identifier. 609 // identifier.
602 DCHECK(!expr.AsIdentifier().IsFutureReserved()); 610 DCHECK(!expr.AsIdentifier().IsFutureReserved());
603 DCHECK(is_sloppy(language_mode()) || 611 DCHECK(is_sloppy(language_mode()) ||
604 !IsFutureStrictReserved(expr.AsIdentifier())); 612 !IsFutureStrictReserved(expr.AsIdentifier()));
605 Consume(Token::COLON); 613 Consume(Token::COLON);
(...skipping 468 matching lines...) Expand 10 before | Expand all | Expand 10 after
1074 1082
1075 Scope* scope = NewScope(scope_, BLOCK_SCOPE); 1083 Scope* scope = NewScope(scope_, BLOCK_SCOPE);
1076 BlockState block_state(&scope_, scope); 1084 BlockState block_state(&scope_, scope);
1077 scope_->SetLanguageMode( 1085 scope_->SetLanguageMode(
1078 static_cast<LanguageMode>(class_language_mode | STRICT_BIT)); 1086 static_cast<LanguageMode>(class_language_mode | STRICT_BIT));
1079 // TODO(marja): Make PreParser use scope names too. 1087 // TODO(marja): Make PreParser use scope names too.
1080 // scope_->SetScopeName(name); 1088 // scope_->SetScopeName(name);
1081 1089
1082 bool has_extends = Check(Token::EXTENDS); 1090 bool has_extends = Check(Token::EXTENDS);
1083 if (has_extends) { 1091 if (has_extends) {
1084 ParseLeftHandSideExpression(CHECK_OK); 1092 ExpressionClassifier classifier;
1093 ParseLeftHandSideExpression(&classifier, CHECK_OK);
1094 // TODO(dslomov): report error if not a valid expression.
1085 } 1095 }
1086 1096
1087 ClassLiteralChecker checker(this); 1097 ClassLiteralChecker checker(this);
1088 bool has_seen_constructor = false; 1098 bool has_seen_constructor = false;
1089 1099
1090 Expect(Token::LBRACE, CHECK_OK); 1100 Expect(Token::LBRACE, CHECK_OK);
1091 while (peek() != Token::RBRACE) { 1101 while (peek() != Token::RBRACE) {
1092 if (Check(Token::SEMICOLON)) continue; 1102 if (Check(Token::SEMICOLON)) continue;
1093 const bool in_class = true; 1103 const bool in_class = true;
1094 const bool is_static = false; 1104 const bool is_static = false;
1095 bool is_computed_name = false; // Classes do not care about computed 1105 bool is_computed_name = false; // Classes do not care about computed
1096 // property names here. 1106 // property names here.
1107 ExpressionClassifier classifier;
1097 ParsePropertyDefinition(&checker, in_class, has_extends, is_static, 1108 ParsePropertyDefinition(&checker, in_class, has_extends, is_static,
1098 &is_computed_name, &has_seen_constructor, CHECK_OK); 1109 &is_computed_name, &has_seen_constructor,
1110 &classifier, CHECK_OK);
1111 // TODO(dslomov): report error if not a valid expression.
1099 } 1112 }
1100 1113
1101 Expect(Token::RBRACE, CHECK_OK); 1114 Expect(Token::RBRACE, CHECK_OK);
1102 1115
1103 return Expression::Default(); 1116 return Expression::Default();
1104 } 1117 }
1105 1118
1106 1119
1107 PreParser::Expression PreParser::ParseV8Intrinsic(bool* ok) { 1120 PreParser::Expression PreParser::ParseV8Intrinsic(bool* ok) {
1108 // CallRuntime :: 1121 // CallRuntime ::
1109 // '%' Identifier Arguments 1122 // '%' Identifier Arguments
1110 Expect(Token::MOD, CHECK_OK); 1123 Expect(Token::MOD, CHECK_OK);
1111 if (!allow_natives()) { 1124 if (!allow_natives()) {
1112 *ok = false; 1125 *ok = false;
1113 return Expression::Default(); 1126 return Expression::Default();
1114 } 1127 }
1115 // Allow "eval" or "arguments" for backward compatibility. 1128 // Allow "eval" or "arguments" for backward compatibility.
1116 ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK); 1129 ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK);
1117 Scanner::Location spread_pos; 1130 Scanner::Location spread_pos;
1118 ParseArguments(&spread_pos, ok); 1131 ExpressionClassifier classifier;
1132 ParseArguments(&spread_pos, &classifier, ok);
1133 // TODO(dslomov): report error if not a valid expression.
1119 1134
1120 DCHECK(!spread_pos.IsValid()); 1135 DCHECK(!spread_pos.IsValid());
1121 1136
1122 return Expression::Default(); 1137 return Expression::Default();
1123 } 1138 }
1124 1139
1125 #undef CHECK_OK 1140 #undef CHECK_OK
1126 1141
1127 1142
1128 } } // v8::internal 1143 } } // v8::internal
OLDNEW
« no previous file with comments | « src/preparser.h ('k') | src/scanner.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698