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

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: 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
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(
659 language_mode(), this->is_generator(), allow_harmony_sloppy_let());
caitp (gmail) 2015/11/03 17:19:12 It would be really helpful if there was an easier
660 }
661
662 void CheckNextEscapedKeyword(bool* ok) {
663 if (IsNextEscapedReservedWord()) {
caitp (gmail) 2015/11/03 17:19:13 Just used to shrink a bit of code in parser.cc / p
664 ReportMessageAt(scanner()->peek_location(),
665 MessageTemplate::kInvalidEscapedReservedWord);
666 *ok = false;
667 }
668 }
669
657 // Recursive descent functions: 670 // Recursive descent functions:
658 671
659 // Parses an identifier that is valid for the current scope, in particular it 672 // 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 673 // fails on strict mode future reserved keywords in a strict scope. If
661 // allow_eval_or_arguments is kAllowEvalOrArguments, we allow "eval" or 674 // allow_eval_or_arguments is kAllowEvalOrArguments, we allow "eval" or
662 // "arguments" as identifier even in strict mode (this is needed in cases like 675 // "arguments" as identifier even in strict mode (this is needed in cases like
663 // "var foo = eval;"). 676 // "var foo = eval;").
664 IdentifierT ParseIdentifier(AllowRestrictedIdentifiers, bool* ok); 677 IdentifierT ParseIdentifier(AllowRestrictedIdentifiers, bool* ok);
665 IdentifierT ParseAndClassifyIdentifier(ExpressionClassifier* classifier, 678 IdentifierT ParseAndClassifyIdentifier(ExpressionClassifier* classifier,
666 bool* ok); 679 bool* ok);
(...skipping 11 matching lines...) Expand all
678 ExpressionClassifier* classifier, bool* ok); 691 ExpressionClassifier* classifier, bool* ok);
679 692
680 ExpressionT ParsePrimaryExpression(ExpressionClassifier* classifier, 693 ExpressionT ParsePrimaryExpression(ExpressionClassifier* classifier,
681 bool* ok); 694 bool* ok);
682 ExpressionT ParseExpression(bool accept_IN, bool* ok); 695 ExpressionT ParseExpression(bool accept_IN, bool* ok);
683 ExpressionT ParseExpression(bool accept_IN, ExpressionClassifier* classifier, 696 ExpressionT ParseExpression(bool accept_IN, ExpressionClassifier* classifier,
684 bool* ok); 697 bool* ok);
685 ExpressionT ParseArrayLiteral(ExpressionClassifier* classifier, bool* ok); 698 ExpressionT ParseArrayLiteral(ExpressionClassifier* classifier, bool* ok);
686 ExpressionT ParsePropertyName(IdentifierT* name, bool* is_get, bool* is_set, 699 ExpressionT ParsePropertyName(IdentifierT* name, bool* is_get, bool* is_set,
687 bool* is_static, bool* is_computed_name, 700 bool* is_static, bool* is_computed_name,
701 bool* is_identifier, bool* is_escaped_keyword,
caitp (gmail) 2015/11/03 17:19:12 I originally wrote a second method for testing thi
688 ExpressionClassifier* classifier, bool* ok); 702 ExpressionClassifier* classifier, bool* ok);
689 ExpressionT ParseObjectLiteral(ExpressionClassifier* classifier, bool* ok); 703 ExpressionT ParseObjectLiteral(ExpressionClassifier* classifier, bool* ok);
690 ObjectLiteralPropertyT ParsePropertyDefinition( 704 ObjectLiteralPropertyT ParsePropertyDefinition(
691 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, 705 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends,
692 bool is_static, bool* is_computed_name, bool* has_seen_constructor, 706 bool is_static, bool* is_computed_name, bool* has_seen_constructor,
693 ExpressionClassifier* classifier, bool* ok); 707 ExpressionClassifier* classifier, bool* ok);
694 typename Traits::Type::ExpressionList ParseArguments( 708 typename Traits::Type::ExpressionList ParseArguments(
695 Scanner::Location* first_spread_pos, ExpressionClassifier* classifier, 709 Scanner::Location* first_spread_pos, ExpressionClassifier* classifier,
696 bool* ok); 710 bool* ok);
697 ExpressionT ParseAssignmentExpression(bool accept_IN, 711 ExpressionT ParseAssignmentExpression(bool accept_IN,
(...skipping 1563 matching lines...) Expand 10 before | Expand all | Expand 10 after
2261 case Token::SMI: 2275 case Token::SMI:
2262 case Token::NUMBER: 2276 case Token::NUMBER:
2263 classifier->RecordBindingPatternError( 2277 classifier->RecordBindingPatternError(
2264 scanner()->peek_location(), MessageTemplate::kUnexpectedTokenNumber); 2278 scanner()->peek_location(), MessageTemplate::kUnexpectedTokenNumber);
2265 Next(); 2279 Next();
2266 result = 2280 result =
2267 this->ExpressionFromLiteral(token, beg_pos, scanner(), factory()); 2281 this->ExpressionFromLiteral(token, beg_pos, scanner(), factory());
2268 break; 2282 break;
2269 2283
2270 case Token::IDENTIFIER: 2284 case Token::IDENTIFIER:
2285 if (IsNextEscapedReservedWord()) {
caitp (gmail) 2015/11/03 17:19:12 IdentifierReference --- Escaped reserved words are
2286 classifier->RecordExpressionError(
2287 scanner()->peek_location(),
2288 MessageTemplate::kInvalidEscapedReservedWord);
2289 classifier->RecordBindingPatternError(
2290 scanner()->peek_location(),
2291 MessageTemplate::kInvalidEscapedReservedWord);
2292 }
2271 case Token::LET: 2293 case Token::LET:
2272 case Token::STATIC: 2294 case Token::STATIC:
2273 case Token::YIELD: 2295 case Token::YIELD:
2274 case Token::FUTURE_STRICT_RESERVED_WORD: { 2296 case Token::FUTURE_STRICT_RESERVED_WORD: {
2275 // Using eval or arguments in this context is OK even in strict mode. 2297 // Using eval or arguments in this context is OK even in strict mode.
2276 IdentifierT name = ParseAndClassifyIdentifier(classifier, CHECK_OK); 2298 IdentifierT name = ParseAndClassifyIdentifier(classifier, CHECK_OK);
2277 result = this->ExpressionFromIdentifier(name, beg_pos, end_pos, scope_, 2299 result = this->ExpressionFromIdentifier(name, beg_pos, end_pos, scope_,
2278 factory()); 2300 factory());
2279 break; 2301 break;
2280 } 2302 }
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after
2540 int literal_index = function_state_->NextMaterializedLiteralIndex(); 2562 int literal_index = function_state_->NextMaterializedLiteralIndex();
2541 2563
2542 return factory()->NewArrayLiteral(values, first_spread_index, literal_index, 2564 return factory()->NewArrayLiteral(values, first_spread_index, literal_index,
2543 is_strong(language_mode()), pos); 2565 is_strong(language_mode()), pos);
2544 } 2566 }
2545 2567
2546 2568
2547 template <class Traits> 2569 template <class Traits>
2548 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParsePropertyName( 2570 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParsePropertyName(
2549 IdentifierT* name, bool* is_get, bool* is_set, bool* is_static, 2571 IdentifierT* name, bool* is_get, bool* is_set, bool* is_static,
2550 bool* is_computed_name, ExpressionClassifier* classifier, bool* ok) { 2572 bool* is_computed_name, bool* is_id, bool* is_escaped_keyword,
adamk 2015/11/03 23:00:57 Please keep the "is_identifier" name here as in th
caitp (gmail) 2015/11/04 04:49:24 Done.
2573 ExpressionClassifier* classifier, bool* ok) {
2551 Token::Value token = peek(); 2574 Token::Value token = peek();
2552 int pos = peek_position(); 2575 int pos = peek_position();
2553 2576
2554 // For non computed property names we normalize the name a bit: 2577 // For non computed property names we normalize the name a bit:
2555 // 2578 //
2556 // "12" -> 12 2579 // "12" -> 12
2557 // 12.3 -> "12.3" 2580 // 12.3 -> "12.3"
2558 // 12.30 -> "12.3" 2581 // 12.30 -> "12.3"
2559 // identifier -> "identifier" 2582 // identifier -> "identifier"
2560 // 2583 //
(...skipping 25 matching lines...) Expand all
2586 ExpressionClassifier::ExpressionProductions); 2609 ExpressionClassifier::ExpressionProductions);
2587 Expect(Token::RBRACK, CHECK_OK); 2610 Expect(Token::RBRACK, CHECK_OK);
2588 return expression; 2611 return expression;
2589 } 2612 }
2590 2613
2591 case Token::STATIC: 2614 case Token::STATIC:
2592 *is_static = true; 2615 *is_static = true;
2593 2616
2594 // Fall through. 2617 // Fall through.
2595 default: 2618 default:
2619 *is_id = true;
2620 *is_escaped_keyword = IsNextEscapedReservedWord();
2596 *name = ParseIdentifierNameOrGetOrSet(is_get, is_set, CHECK_OK); 2621 *name = ParseIdentifierNameOrGetOrSet(is_get, is_set, CHECK_OK);
2597 break; 2622 break;
2598 } 2623 }
2599 2624
2600 uint32_t index; 2625 uint32_t index;
2601 return this->IsArrayIndex(*name, &index) 2626 return this->IsArrayIndex(*name, &index)
2602 ? factory()->NewNumberLiteral(index, pos) 2627 ? factory()->NewNumberLiteral(index, pos)
2603 : factory()->NewStringLiteral(*name, pos); 2628 : factory()->NewStringLiteral(*name, pos);
2604 } 2629 }
2605 2630
2606 2631
2607 template <class Traits> 2632 template <class Traits>
2608 typename ParserBase<Traits>::ObjectLiteralPropertyT 2633 typename ParserBase<Traits>::ObjectLiteralPropertyT
2609 ParserBase<Traits>::ParsePropertyDefinition( 2634 ParserBase<Traits>::ParsePropertyDefinition(
2610 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, 2635 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends,
2611 bool is_static, bool* is_computed_name, bool* has_seen_constructor, 2636 bool is_static, bool* is_computed_name, bool* has_seen_constructor,
2612 ExpressionClassifier* classifier, bool* ok) { 2637 ExpressionClassifier* classifier, bool* ok) {
2613 DCHECK(!in_class || is_static || has_seen_constructor != nullptr); 2638 DCHECK(!in_class || is_static || has_seen_constructor != nullptr);
2614 ExpressionT value = this->EmptyExpression(); 2639 ExpressionT value = this->EmptyExpression();
2615 IdentifierT name = this->EmptyIdentifier(); 2640 IdentifierT name = this->EmptyIdentifier();
2616 bool is_get = false; 2641 bool is_get = false;
2617 bool is_set = false; 2642 bool is_set = false;
2618 bool name_is_static = false; 2643 bool name_is_static = false;
2619 bool is_generator = Check(Token::MUL); 2644 bool is_generator = Check(Token::MUL);
2620 2645
2621 Token::Value name_token = peek(); 2646 Token::Value name_token = peek();
2622 int next_beg_pos = scanner()->peek_location().beg_pos; 2647 int next_beg_pos = scanner()->peek_location().beg_pos;
2623 int next_end_pos = scanner()->peek_location().end_pos; 2648 int next_end_pos = scanner()->peek_location().end_pos;
2649 bool is_ident = false;
adamk 2015/11/03 23:00:57 Please use "is_identifier" here too for consistenc
caitp (gmail) 2015/11/04 04:49:24 Done.
2650 bool is_escaped_keyword = false;
2624 ExpressionT name_expression = ParsePropertyName( 2651 ExpressionT name_expression = ParsePropertyName(
2625 &name, &is_get, &is_set, &name_is_static, is_computed_name, classifier, 2652 &name, &is_get, &is_set, &name_is_static, is_computed_name, &is_ident,
2653 &is_escaped_keyword, classifier,
2626 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 2654 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2627 2655
2628 if (fni_ != nullptr && !*is_computed_name) { 2656 if (fni_ != nullptr && !*is_computed_name) {
2629 this->PushLiteralName(fni_, name); 2657 this->PushLiteralName(fni_, name);
2630 } 2658 }
2631 2659
2632 if (!in_class && !is_generator) { 2660 if (!in_class && !is_generator) {
2633 DCHECK(!is_static); 2661 DCHECK(!is_static);
2634 2662
2635 if (peek() == Token::COLON) { 2663 if (peek() == Token::COLON) {
2636 // PropertyDefinition 2664 // PropertyDefinition
2637 // PropertyName ':' AssignmentExpression 2665 // PropertyName ':' AssignmentExpression
2638 if (!*is_computed_name) { 2666 if (!*is_computed_name) {
2639 checker->CheckProperty(name_token, kValueProperty, false, false, 2667 checker->CheckProperty(name_token, kValueProperty, false, false,
2640 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 2668 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2641 } 2669 }
2642 Consume(Token::COLON); 2670 Consume(Token::COLON);
2643 value = this->ParseAssignmentExpression( 2671 value = this->ParseAssignmentExpression(
2644 true, classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 2672 true, classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2645 return factory()->NewObjectLiteralProperty(name_expression, value, false, 2673 return factory()->NewObjectLiteralProperty(name_expression, value, false,
2646 *is_computed_name); 2674 *is_computed_name);
2647 } 2675 }
2648 2676
2649 if (Token::IsIdentifier(name_token, language_mode(), 2677 if (is_ident && (peek() == Token::COMMA || peek() == Token::RBRACE ||
2650 this->is_generator()) && 2678 peek() == Token::ASSIGN)) {
2651 (peek() == Token::COMMA || peek() == Token::RBRACE ||
2652 peek() == Token::ASSIGN)) {
2653 // PropertyDefinition 2679 // PropertyDefinition
2654 // IdentifierReference 2680 // IdentifierReference
2655 // CoverInitializedName 2681 // CoverInitializedName
2656 // 2682 //
2657 // CoverInitializedName 2683 // CoverInitializedName
2658 // IdentifierReference Initializer? 2684 // IdentifierReference Initializer?
2685 if (!Token::IsIdentifier(name_token, language_mode(),
2686 this->is_generator())) {
2687 ReportUnexpectedTokenAt(scanner()->location(), name_token);
2688 *ok = false;
2689 return this->EmptyObjectLiteralProperty();
2690 }
2691 if (is_escaped_keyword) {
2692 classifier->RecordExpressionError(
2693 scanner()->location(),
2694 MessageTemplate::kInvalidEscapedReservedWord);
2695 classifier->RecordBindingPatternError(
2696 scanner()->location(),
2697 MessageTemplate::kInvalidEscapedReservedWord);
2698 }
2659 if (classifier->duplicate_finder() != nullptr && 2699 if (classifier->duplicate_finder() != nullptr &&
2660 scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) { 2700 scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) {
2661 classifier->RecordDuplicateFormalParameterError(scanner()->location()); 2701 classifier->RecordDuplicateFormalParameterError(scanner()->location());
2662 } 2702 }
2663 if (name_token == Token::LET) { 2703 if (name_token == Token::LET) {
2664 classifier->RecordLetPatternError( 2704 classifier->RecordLetPatternError(
2665 scanner()->location(), MessageTemplate::kLetInLexicalBinding); 2705 scanner()->location(), MessageTemplate::kLetInLexicalBinding);
2666 } 2706 }
2667 2707
2668 ExpressionT lhs = this->ExpressionFromIdentifier( 2708 ExpressionT lhs = this->ExpressionFromIdentifier(
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
2731 if (is_get || is_set) { 2771 if (is_get || is_set) {
2732 // MethodDefinition (Accessors) 2772 // MethodDefinition (Accessors)
2733 // get PropertyName '(' ')' '{' FunctionBody '}' 2773 // get PropertyName '(' ')' '{' FunctionBody '}'
2734 // set PropertyName '(' PropertySetParameterList ')' '{' FunctionBody '}' 2774 // set PropertyName '(' PropertySetParameterList ')' '{' FunctionBody '}'
2735 name = this->EmptyIdentifier(); 2775 name = this->EmptyIdentifier();
2736 bool dont_care = false; 2776 bool dont_care = false;
2737 name_token = peek(); 2777 name_token = peek();
2738 2778
2739 name_expression = ParsePropertyName( 2779 name_expression = ParsePropertyName(
2740 &name, &dont_care, &dont_care, &dont_care, is_computed_name, classifier, 2780 &name, &dont_care, &dont_care, &dont_care, is_computed_name, classifier,
2741 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 2781 &dont_care, &dont_care, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
caitp (gmail) 2015/11/03 17:19:13 MethodDefinitions and accessors use the PropertyNa
2742 2782
2743 if (!*is_computed_name) { 2783 if (!*is_computed_name) {
2744 checker->CheckProperty(name_token, kAccessorProperty, is_static, 2784 checker->CheckProperty(name_token, kAccessorProperty, is_static,
2745 is_generator, 2785 is_generator,
2746 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 2786 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2747 } 2787 }
2748 2788
2749 FunctionKind kind = FunctionKind::kAccessorFunction; 2789 FunctionKind kind = FunctionKind::kAccessorFunction;
2750 if (!in_class) kind = WithObjectLiteralBit(kind); 2790 if (!in_class) kind = WithObjectLiteralBit(kind);
2751 typename Traits::Type::FunctionLiteral value = this->ParseFunctionLiteral( 2791 typename Traits::Type::FunctionLiteral value = this->ParseFunctionLiteral(
(...skipping 1452 matching lines...) Expand 10 before | Expand all | Expand 10 after
4204 return; 4244 return;
4205 } 4245 }
4206 has_seen_constructor_ = true; 4246 has_seen_constructor_ = true;
4207 return; 4247 return;
4208 } 4248 }
4209 } 4249 }
4210 } // namespace internal 4250 } // namespace internal
4211 } // namespace v8 4251 } // namespace v8
4212 4252
4213 #endif // V8_PREPARSER_H 4253 #endif // V8_PREPARSER_H
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698