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

Side by Side Diff: src/preparser.h

Issue 1429983002: [es6] early error when Identifier is an escaped reserved word (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Bunch of comments addressed + mozilla/test262 statuses updated Created 5 years, 1 month 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/parser.cc ('k') | src/preparser.cc » ('j') | src/scanner.cc » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 #ifndef V8_PREPARSER_H 5 #ifndef V8_PREPARSER_H
6 #define V8_PREPARSER_H 6 #define V8_PREPARSER_H
7 7
8 #include "src/bailout-reason.h" 8 #include "src/bailout-reason.h"
9 #include "src/expression-classifier.h" 9 #include "src/expression-classifier.h"
10 #include "src/func-name-inferrer.h" 10 #include "src/func-name-inferrer.h"
(...skipping 636 matching lines...) Expand 10 before | Expand all | Expand 10 after
647 647
648 void FormalParameterInitializerUnexpectedToken( 648 void FormalParameterInitializerUnexpectedToken(
649 ExpressionClassifier* classifier) { 649 ExpressionClassifier* classifier) {
650 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken; 650 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken;
651 const char* arg; 651 const char* arg;
652 GetUnexpectedTokenMessage(peek(), &message, &arg); 652 GetUnexpectedTokenMessage(peek(), &message, &arg);
653 classifier->RecordFormalParameterInitializerError( 653 classifier->RecordFormalParameterInitializerError(
654 scanner()->peek_location(), message, arg); 654 scanner()->peek_location(), message, arg);
655 } 655 }
656 656
657 bool IsNextEscapedReservedWord() {
658 return scanner()->IsNextEscapedReservedWord(language_mode(),
659 this->is_generator());
660 }
661
662 void CheckNextEscapedKeyword(bool* ok) {
663 if (IsNextEscapedReservedWord()) {
664 Next();
caitp (gmail) 2015/11/04 05:03:37 Next() added to prevent a DCHECK() from crashing t
665 ReportMessageAt(scanner()->location(),
666 MessageTemplate::kInvalidEscapedReservedWord);
667 *ok = false;
668 }
669 }
670
657 // Recursive descent functions: 671 // Recursive descent functions:
658 672
659 // Parses an identifier that is valid for the current scope, in particular it 673 // Parses an identifier that is valid for the current scope, in particular it
660 // fails on strict mode future reserved keywords in a strict scope. If 674 // fails on strict mode future reserved keywords in a strict scope. If
661 // allow_eval_or_arguments is kAllowEvalOrArguments, we allow "eval" or 675 // allow_eval_or_arguments is kAllowEvalOrArguments, we allow "eval" or
662 // "arguments" as identifier even in strict mode (this is needed in cases like 676 // "arguments" as identifier even in strict mode (this is needed in cases like
663 // "var foo = eval;"). 677 // "var foo = eval;").
664 IdentifierT ParseIdentifier(AllowRestrictedIdentifiers, bool* ok); 678 IdentifierT ParseIdentifier(AllowRestrictedIdentifiers, bool* ok);
665 IdentifierT ParseAndClassifyIdentifier(ExpressionClassifier* classifier, 679 IdentifierT ParseAndClassifyIdentifier(ExpressionClassifier* classifier,
666 bool* ok); 680 bool* ok);
(...skipping 11 matching lines...) Expand all
678 ExpressionClassifier* classifier, bool* ok); 692 ExpressionClassifier* classifier, bool* ok);
679 693
680 ExpressionT ParsePrimaryExpression(ExpressionClassifier* classifier, 694 ExpressionT ParsePrimaryExpression(ExpressionClassifier* classifier,
681 bool* ok); 695 bool* ok);
682 ExpressionT ParseExpression(bool accept_IN, bool* ok); 696 ExpressionT ParseExpression(bool accept_IN, bool* ok);
683 ExpressionT ParseExpression(bool accept_IN, ExpressionClassifier* classifier, 697 ExpressionT ParseExpression(bool accept_IN, ExpressionClassifier* classifier,
684 bool* ok); 698 bool* ok);
685 ExpressionT ParseArrayLiteral(ExpressionClassifier* classifier, bool* ok); 699 ExpressionT ParseArrayLiteral(ExpressionClassifier* classifier, bool* ok);
686 ExpressionT ParsePropertyName(IdentifierT* name, bool* is_get, bool* is_set, 700 ExpressionT ParsePropertyName(IdentifierT* name, bool* is_get, bool* is_set,
687 bool* is_static, bool* is_computed_name, 701 bool* is_static, bool* is_computed_name,
702 bool* is_identifier, bool* is_escaped_keyword,
688 ExpressionClassifier* classifier, bool* ok); 703 ExpressionClassifier* classifier, bool* ok);
689 ExpressionT ParseObjectLiteral(ExpressionClassifier* classifier, bool* ok); 704 ExpressionT ParseObjectLiteral(ExpressionClassifier* classifier, bool* ok);
690 ObjectLiteralPropertyT ParsePropertyDefinition( 705 ObjectLiteralPropertyT ParsePropertyDefinition(
691 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, 706 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends,
692 bool is_static, bool* is_computed_name, bool* has_seen_constructor, 707 bool is_static, bool* is_computed_name, bool* has_seen_constructor,
693 ExpressionClassifier* classifier, bool* ok); 708 ExpressionClassifier* classifier, bool* ok);
694 typename Traits::Type::ExpressionList ParseArguments( 709 typename Traits::Type::ExpressionList ParseArguments(
695 Scanner::Location* first_spread_pos, ExpressionClassifier* classifier, 710 Scanner::Location* first_spread_pos, ExpressionClassifier* classifier,
696 bool* ok); 711 bool* ok);
697 ExpressionT ParseAssignmentExpression(bool accept_IN, 712 ExpressionT ParseAssignmentExpression(bool accept_IN,
(...skipping 1563 matching lines...) Expand 10 before | Expand all | Expand 10 after
2261 case Token::SMI: 2276 case Token::SMI:
2262 case Token::NUMBER: 2277 case Token::NUMBER:
2263 classifier->RecordBindingPatternError( 2278 classifier->RecordBindingPatternError(
2264 scanner()->peek_location(), MessageTemplate::kUnexpectedTokenNumber); 2279 scanner()->peek_location(), MessageTemplate::kUnexpectedTokenNumber);
2265 Next(); 2280 Next();
2266 result = 2281 result =
2267 this->ExpressionFromLiteral(token, beg_pos, scanner(), factory()); 2282 this->ExpressionFromLiteral(token, beg_pos, scanner(), factory());
2268 break; 2283 break;
2269 2284
2270 case Token::IDENTIFIER: 2285 case Token::IDENTIFIER:
2286 if (IsNextEscapedReservedWord()) {
2287 classifier->RecordExpressionError(
2288 scanner()->peek_location(),
2289 MessageTemplate::kInvalidEscapedReservedWord);
2290 classifier->RecordBindingPatternError(
2291 scanner()->peek_location(),
2292 MessageTemplate::kInvalidEscapedReservedWord);
2293 }
2271 case Token::LET: 2294 case Token::LET:
2272 case Token::STATIC: 2295 case Token::STATIC:
2273 case Token::YIELD: 2296 case Token::YIELD:
2274 case Token::FUTURE_STRICT_RESERVED_WORD: { 2297 case Token::FUTURE_STRICT_RESERVED_WORD: {
2275 // Using eval or arguments in this context is OK even in strict mode. 2298 // Using eval or arguments in this context is OK even in strict mode.
2276 IdentifierT name = ParseAndClassifyIdentifier(classifier, CHECK_OK); 2299 IdentifierT name = ParseAndClassifyIdentifier(classifier, CHECK_OK);
2277 result = this->ExpressionFromIdentifier(name, beg_pos, end_pos, scope_, 2300 result = this->ExpressionFromIdentifier(name, beg_pos, end_pos, scope_,
2278 factory()); 2301 factory());
2279 break; 2302 break;
2280 } 2303 }
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after
2540 int literal_index = function_state_->NextMaterializedLiteralIndex(); 2563 int literal_index = function_state_->NextMaterializedLiteralIndex();
2541 2564
2542 return factory()->NewArrayLiteral(values, first_spread_index, literal_index, 2565 return factory()->NewArrayLiteral(values, first_spread_index, literal_index,
2543 is_strong(language_mode()), pos); 2566 is_strong(language_mode()), pos);
2544 } 2567 }
2545 2568
2546 2569
2547 template <class Traits> 2570 template <class Traits>
2548 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParsePropertyName( 2571 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParsePropertyName(
2549 IdentifierT* name, bool* is_get, bool* is_set, bool* is_static, 2572 IdentifierT* name, bool* is_get, bool* is_set, bool* is_static,
2550 bool* is_computed_name, ExpressionClassifier* classifier, bool* ok) { 2573 bool* is_computed_name, bool* is_identifier, bool* is_escaped_keyword,
2574 ExpressionClassifier* classifier, bool* ok) {
2551 Token::Value token = peek(); 2575 Token::Value token = peek();
2552 int pos = peek_position(); 2576 int pos = peek_position();
2553 2577
2554 // For non computed property names we normalize the name a bit: 2578 // For non computed property names we normalize the name a bit:
2555 // 2579 //
2556 // "12" -> 12 2580 // "12" -> 12
2557 // 12.3 -> "12.3" 2581 // 12.3 -> "12.3"
2558 // 12.30 -> "12.3" 2582 // 12.30 -> "12.3"
2559 // identifier -> "identifier" 2583 // identifier -> "identifier"
2560 // 2584 //
(...skipping 25 matching lines...) Expand all
2586 ExpressionClassifier::ExpressionProductions); 2610 ExpressionClassifier::ExpressionProductions);
2587 Expect(Token::RBRACK, CHECK_OK); 2611 Expect(Token::RBRACK, CHECK_OK);
2588 return expression; 2612 return expression;
2589 } 2613 }
2590 2614
2591 case Token::STATIC: 2615 case Token::STATIC:
2592 *is_static = true; 2616 *is_static = true;
2593 2617
2594 // Fall through. 2618 // Fall through.
2595 default: 2619 default:
2620 *is_identifier = true;
2621 *is_escaped_keyword = IsNextEscapedReservedWord();
2596 *name = ParseIdentifierNameOrGetOrSet(is_get, is_set, CHECK_OK); 2622 *name = ParseIdentifierNameOrGetOrSet(is_get, is_set, CHECK_OK);
2597 break; 2623 break;
2598 } 2624 }
2599 2625
2600 uint32_t index; 2626 uint32_t index;
2601 return this->IsArrayIndex(*name, &index) 2627 return this->IsArrayIndex(*name, &index)
2602 ? factory()->NewNumberLiteral(index, pos) 2628 ? factory()->NewNumberLiteral(index, pos)
2603 : factory()->NewStringLiteral(*name, pos); 2629 : factory()->NewStringLiteral(*name, pos);
2604 } 2630 }
2605 2631
2606 2632
2607 template <class Traits> 2633 template <class Traits>
2608 typename ParserBase<Traits>::ObjectLiteralPropertyT 2634 typename ParserBase<Traits>::ObjectLiteralPropertyT
2609 ParserBase<Traits>::ParsePropertyDefinition( 2635 ParserBase<Traits>::ParsePropertyDefinition(
2610 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, 2636 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends,
2611 bool is_static, bool* is_computed_name, bool* has_seen_constructor, 2637 bool is_static, bool* is_computed_name, bool* has_seen_constructor,
2612 ExpressionClassifier* classifier, bool* ok) { 2638 ExpressionClassifier* classifier, bool* ok) {
2613 DCHECK(!in_class || is_static || has_seen_constructor != nullptr); 2639 DCHECK(!in_class || is_static || has_seen_constructor != nullptr);
2614 ExpressionT value = this->EmptyExpression(); 2640 ExpressionT value = this->EmptyExpression();
2615 IdentifierT name = this->EmptyIdentifier(); 2641 IdentifierT name = this->EmptyIdentifier();
2616 bool is_get = false; 2642 bool is_get = false;
2617 bool is_set = false; 2643 bool is_set = false;
2618 bool name_is_static = false; 2644 bool name_is_static = false;
2619 bool is_generator = Check(Token::MUL); 2645 bool is_generator = Check(Token::MUL);
2620 2646
2621 Token::Value name_token = peek(); 2647 Token::Value name_token = peek();
2622 int next_beg_pos = scanner()->peek_location().beg_pos; 2648 int next_beg_pos = scanner()->peek_location().beg_pos;
2623 int next_end_pos = scanner()->peek_location().end_pos; 2649 int next_end_pos = scanner()->peek_location().end_pos;
2650 bool is_identifier = false;
2651 bool is_escaped_keyword = false;
2624 ExpressionT name_expression = ParsePropertyName( 2652 ExpressionT name_expression = ParsePropertyName(
2625 &name, &is_get, &is_set, &name_is_static, is_computed_name, classifier, 2653 &name, &is_get, &is_set, &name_is_static, is_computed_name,
2654 &is_identifier, &is_escaped_keyword, classifier,
2626 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 2655 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2627 2656
2628 if (fni_ != nullptr && !*is_computed_name) { 2657 if (fni_ != nullptr && !*is_computed_name) {
2629 this->PushLiteralName(fni_, name); 2658 this->PushLiteralName(fni_, name);
2630 } 2659 }
2631 2660
2632 if (!in_class && !is_generator) { 2661 if (!in_class && !is_generator) {
2633 DCHECK(!is_static); 2662 DCHECK(!is_static);
2634 2663
2635 if (peek() == Token::COLON) { 2664 if (peek() == Token::COLON) {
2636 // PropertyDefinition 2665 // PropertyDefinition
2637 // PropertyName ':' AssignmentExpression 2666 // PropertyName ':' AssignmentExpression
2638 if (!*is_computed_name) { 2667 if (!*is_computed_name) {
2639 checker->CheckProperty(name_token, kValueProperty, false, false, 2668 checker->CheckProperty(name_token, kValueProperty, false, false,
2640 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 2669 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2641 } 2670 }
2642 Consume(Token::COLON); 2671 Consume(Token::COLON);
2643 value = this->ParseAssignmentExpression( 2672 value = this->ParseAssignmentExpression(
2644 true, classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 2673 true, classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2645 return factory()->NewObjectLiteralProperty(name_expression, value, false, 2674 return factory()->NewObjectLiteralProperty(name_expression, value, false,
2646 *is_computed_name); 2675 *is_computed_name);
2647 } 2676 }
2648 2677
2649 if (Token::IsIdentifier(name_token, language_mode(), 2678 if (is_identifier && (peek() == Token::COMMA || peek() == Token::RBRACE ||
2650 this->is_generator()) && 2679 peek() == Token::ASSIGN)) {
2651 (peek() == Token::COMMA || peek() == Token::RBRACE ||
2652 peek() == Token::ASSIGN)) {
2653 // PropertyDefinition 2680 // PropertyDefinition
2654 // IdentifierReference 2681 // IdentifierReference
2655 // CoverInitializedName 2682 // CoverInitializedName
2656 // 2683 //
2657 // CoverInitializedName 2684 // CoverInitializedName
2658 // IdentifierReference Initializer? 2685 // IdentifierReference Initializer?
2686 if (!Token::IsIdentifier(name_token, language_mode(),
2687 this->is_generator())) {
2688 ReportUnexpectedTokenAt(scanner()->location(), name_token);
2689 *ok = false;
2690 return this->EmptyObjectLiteralProperty();
2691 }
2692 if (is_escaped_keyword) {
2693 classifier->RecordExpressionError(
2694 scanner()->location(),
2695 MessageTemplate::kInvalidEscapedReservedWord);
2696 classifier->RecordBindingPatternError(
2697 scanner()->location(),
2698 MessageTemplate::kInvalidEscapedReservedWord);
2699 }
2659 if (classifier->duplicate_finder() != nullptr && 2700 if (classifier->duplicate_finder() != nullptr &&
2660 scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) { 2701 scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) {
2661 classifier->RecordDuplicateFormalParameterError(scanner()->location()); 2702 classifier->RecordDuplicateFormalParameterError(scanner()->location());
2662 } 2703 }
2663 if (name_token == Token::LET) { 2704 if (name_token == Token::LET) {
2664 classifier->RecordLetPatternError( 2705 classifier->RecordLetPatternError(
2665 scanner()->location(), MessageTemplate::kLetInLexicalBinding); 2706 scanner()->location(), MessageTemplate::kLetInLexicalBinding);
2666 } 2707 }
2667 2708
2668 ExpressionT lhs = this->ExpressionFromIdentifier( 2709 ExpressionT lhs = this->ExpressionFromIdentifier(
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
2730 2771
2731 if (is_get || is_set) { 2772 if (is_get || is_set) {
2732 // MethodDefinition (Accessors) 2773 // MethodDefinition (Accessors)
2733 // get PropertyName '(' ')' '{' FunctionBody '}' 2774 // get PropertyName '(' ')' '{' FunctionBody '}'
2734 // set PropertyName '(' PropertySetParameterList ')' '{' FunctionBody '}' 2775 // set PropertyName '(' PropertySetParameterList ')' '{' FunctionBody '}'
2735 name = this->EmptyIdentifier(); 2776 name = this->EmptyIdentifier();
2736 bool dont_care = false; 2777 bool dont_care = false;
2737 name_token = peek(); 2778 name_token = peek();
2738 2779
2739 name_expression = ParsePropertyName( 2780 name_expression = ParsePropertyName(
2740 &name, &dont_care, &dont_care, &dont_care, is_computed_name, classifier, 2781 &name, &dont_care, &dont_care, &dont_care, is_computed_name, &dont_care,
2741 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 2782 &dont_care, classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2742 2783
2743 if (!*is_computed_name) { 2784 if (!*is_computed_name) {
2744 checker->CheckProperty(name_token, kAccessorProperty, is_static, 2785 checker->CheckProperty(name_token, kAccessorProperty, is_static,
2745 is_generator, 2786 is_generator,
2746 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 2787 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2747 } 2788 }
2748 2789
2749 FunctionKind kind = FunctionKind::kAccessorFunction; 2790 FunctionKind kind = FunctionKind::kAccessorFunction;
2750 if (!in_class) kind = WithObjectLiteralBit(kind); 2791 if (!in_class) kind = WithObjectLiteralBit(kind);
2751 typename Traits::Type::FunctionLiteral value = this->ParseFunctionLiteral( 2792 typename Traits::Type::FunctionLiteral value = this->ParseFunctionLiteral(
(...skipping 1452 matching lines...) Expand 10 before | Expand all | Expand 10 after
4204 return; 4245 return;
4205 } 4246 }
4206 has_seen_constructor_ = true; 4247 has_seen_constructor_ = true;
4207 return; 4248 return;
4208 } 4249 }
4209 } 4250 }
4210 } // namespace internal 4251 } // namespace internal
4211 } // namespace v8 4252 } // namespace v8
4212 4253
4213 #endif // V8_PREPARSER_H 4254 #endif // V8_PREPARSER_H
OLDNEW
« no previous file with comments | « src/parser.cc ('k') | src/preparser.cc » ('j') | src/scanner.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698