Chromium Code Reviews| OLD | NEW |
|---|---|
| 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_PARSING_PARSER_BASE_H | 5 #ifndef V8_PARSING_PARSER_BASE_H |
| 6 #define V8_PARSING_PARSER_BASE_H | 6 #define V8_PARSING_PARSER_BASE_H |
| 7 | 7 |
| 8 #include "src/ast/scopes.h" | 8 #include "src/ast/scopes.h" |
| 9 #include "src/bailout-reason.h" | 9 #include "src/bailout-reason.h" |
| 10 #include "src/hashmap.h" | 10 #include "src/hashmap.h" |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 22 kFunctionNameIsStrictReserved, | 22 kFunctionNameIsStrictReserved, |
| 23 kSkipFunctionNameCheck, | 23 kSkipFunctionNameCheck, |
| 24 kFunctionNameValidityUnknown | 24 kFunctionNameValidityUnknown |
| 25 }; | 25 }; |
| 26 | 26 |
| 27 enum AllowLabelledFunctionStatement { | 27 enum AllowLabelledFunctionStatement { |
| 28 kAllowLabelledFunctionStatement, | 28 kAllowLabelledFunctionStatement, |
| 29 kDisallowLabelledFunctionStatement, | 29 kDisallowLabelledFunctionStatement, |
| 30 }; | 30 }; |
| 31 | 31 |
| 32 enum class FunctionBody { Normal, SingleExpression }; | |
| 33 | |
| 34 enum class FunctionParsePhase { Unknown, FormalParameters, FunctionBody }; | |
| 35 | |
| 36 enum class ParseFunctionFlags { | |
| 37 kIsNormal = 0, | |
| 38 kIsGenerator = 1, | |
| 39 kIsAsync = 2, | |
| 40 kIsDefault = 4 | |
| 41 }; | |
| 42 | |
| 43 static inline ParseFunctionFlags operator|(ParseFunctionFlags lhs, | |
| 44 ParseFunctionFlags rhs) { | |
| 45 typedef unsigned char T; | |
| 46 return static_cast<ParseFunctionFlags>(static_cast<T>(lhs) | | |
| 47 static_cast<T>(rhs)); | |
| 48 } | |
| 49 | |
| 50 static inline ParseFunctionFlags& operator|=(ParseFunctionFlags& lhs, | |
| 51 const ParseFunctionFlags& rhs) { | |
| 52 lhs = lhs | rhs; | |
| 53 return lhs; | |
| 54 } | |
| 55 | |
| 56 static inline bool operator&(ParseFunctionFlags bitfield, | |
| 57 ParseFunctionFlags mask) { | |
| 58 typedef unsigned char T; | |
| 59 return static_cast<T>(bitfield) & static_cast<T>(mask); | |
| 60 } | |
| 61 | |
| 62 enum class MethodKind { | |
| 63 Normal = 0, | |
| 64 Static = 1 << 0, | |
| 65 Generator = 1 << 1, | |
| 66 StaticGenerator = Static | Generator, | |
| 67 Async = 1 << 2, | |
| 68 StaticAsync = Static | Async, | |
| 69 | |
| 70 /* Any non-ordinary method kinds */ | |
| 71 SpecialMask = Generator | Async | |
| 72 }; | |
| 73 | |
| 74 inline bool IsValidMethodKind(MethodKind kind) { | |
| 75 return kind == MethodKind::Normal || kind == MethodKind::Static || | |
| 76 kind == MethodKind::Generator || kind == MethodKind::StaticGenerator || | |
| 77 kind == MethodKind::Async || kind == MethodKind::StaticAsync; | |
| 78 } | |
| 79 | |
| 80 static inline MethodKind operator|(MethodKind lhs, MethodKind rhs) { | |
| 81 typedef unsigned char T; | |
| 82 return static_cast<MethodKind>(static_cast<T>(lhs) | static_cast<T>(rhs)); | |
| 83 } | |
| 84 | |
| 85 static inline MethodKind& operator|=(MethodKind& lhs, const MethodKind& rhs) { | |
| 86 lhs = lhs | rhs; | |
| 87 DCHECK(IsValidMethodKind(lhs)); | |
| 88 return lhs; | |
| 89 } | |
| 90 | |
| 91 static inline bool operator&(MethodKind bitfield, MethodKind mask) { | |
| 92 typedef unsigned char T; | |
| 93 return static_cast<T>(bitfield) & static_cast<T>(mask); | |
| 94 } | |
| 95 | |
| 96 inline bool IsNormalMethod(MethodKind kind) { | |
| 97 return kind == MethodKind::Normal; | |
| 98 } | |
| 99 | |
| 100 inline bool IsSpecialMethod(MethodKind kind) { | |
| 101 return kind & MethodKind::SpecialMask; | |
| 102 } | |
| 103 | |
| 104 inline bool IsStaticMethod(MethodKind kind) { | |
| 105 return kind & MethodKind::Static; | |
| 106 } | |
| 107 | |
| 108 inline bool IsGeneratorMethod(MethodKind kind) { | |
| 109 return kind & MethodKind::Generator; | |
| 110 } | |
| 111 | |
| 112 inline bool IsAsyncMethod(MethodKind kind) { return kind & MethodKind::Async; } | |
| 113 | |
| 32 struct FormalParametersBase { | 114 struct FormalParametersBase { |
| 33 explicit FormalParametersBase(Scope* scope) : scope(scope) {} | 115 explicit FormalParametersBase(Scope* scope) : scope(scope) {} |
| 34 Scope* scope; | 116 Scope* scope; |
| 35 bool has_rest = false; | 117 bool has_rest = false; |
| 36 bool is_simple = true; | 118 bool is_simple = true; |
| 37 int materialized_literals_count = 0; | 119 int materialized_literals_count = 0; |
| 38 }; | 120 }; |
| 39 | 121 |
| 40 | 122 |
| 41 // Common base class shared between parser and pre-parser. Traits encapsulate | 123 // Common base class shared between parser and pre-parser. Traits encapsulate |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 110 zone_(zone), | 192 zone_(zone), |
| 111 scanner_(scanner), | 193 scanner_(scanner), |
| 112 stack_overflow_(false), | 194 stack_overflow_(false), |
| 113 allow_lazy_(false), | 195 allow_lazy_(false), |
| 114 allow_natives_(false), | 196 allow_natives_(false), |
| 115 allow_tailcalls_(false), | 197 allow_tailcalls_(false), |
| 116 allow_harmony_restrictive_declarations_(false), | 198 allow_harmony_restrictive_declarations_(false), |
| 117 allow_harmony_do_expressions_(false), | 199 allow_harmony_do_expressions_(false), |
| 118 allow_harmony_for_in_(false), | 200 allow_harmony_for_in_(false), |
| 119 allow_harmony_function_name_(false), | 201 allow_harmony_function_name_(false), |
| 120 allow_harmony_function_sent_(false) {} | 202 allow_harmony_function_sent_(false), |
| 203 allow_harmony_async_await_(false) {} | |
| 121 | 204 |
| 122 #define ALLOW_ACCESSORS(name) \ | 205 #define ALLOW_ACCESSORS(name) \ |
| 123 bool allow_##name() const { return allow_##name##_; } \ | 206 bool allow_##name() const { return allow_##name##_; } \ |
| 124 void set_allow_##name(bool allow) { allow_##name##_ = allow; } | 207 void set_allow_##name(bool allow) { allow_##name##_ = allow; } |
| 125 | 208 |
| 126 #define SCANNER_ACCESSORS(name) \ | 209 #define SCANNER_ACCESSORS(name) \ |
| 127 bool allow_##name() const { return scanner_->allow_##name(); } \ | 210 bool allow_##name() const { return scanner_->allow_##name(); } \ |
| 128 void set_allow_##name(bool allow) { \ | 211 void set_allow_##name(bool allow) { \ |
| 129 return scanner_->set_allow_##name(allow); \ | 212 return scanner_->set_allow_##name(allow); \ |
| 130 } | 213 } |
| 131 | 214 |
| 132 ALLOW_ACCESSORS(lazy); | 215 ALLOW_ACCESSORS(lazy); |
| 133 ALLOW_ACCESSORS(natives); | 216 ALLOW_ACCESSORS(natives); |
| 134 ALLOW_ACCESSORS(tailcalls); | 217 ALLOW_ACCESSORS(tailcalls); |
| 135 ALLOW_ACCESSORS(harmony_restrictive_declarations); | 218 ALLOW_ACCESSORS(harmony_restrictive_declarations); |
| 136 ALLOW_ACCESSORS(harmony_do_expressions); | 219 ALLOW_ACCESSORS(harmony_do_expressions); |
| 137 ALLOW_ACCESSORS(harmony_for_in); | 220 ALLOW_ACCESSORS(harmony_for_in); |
| 138 ALLOW_ACCESSORS(harmony_function_name); | 221 ALLOW_ACCESSORS(harmony_function_name); |
| 139 ALLOW_ACCESSORS(harmony_function_sent); | 222 ALLOW_ACCESSORS(harmony_function_sent); |
| 223 ALLOW_ACCESSORS(harmony_async_await); | |
| 140 SCANNER_ACCESSORS(harmony_exponentiation_operator); | 224 SCANNER_ACCESSORS(harmony_exponentiation_operator); |
| 141 | 225 |
| 142 #undef SCANNER_ACCESSORS | 226 #undef SCANNER_ACCESSORS |
| 143 #undef ALLOW_ACCESSORS | 227 #undef ALLOW_ACCESSORS |
| 144 | 228 |
| 145 uintptr_t stack_limit() const { return stack_limit_; } | 229 uintptr_t stack_limit() const { return stack_limit_; } |
| 146 | 230 |
| 147 protected: | 231 protected: |
| 148 enum AllowRestrictedIdentifiers { | 232 enum AllowRestrictedIdentifiers { |
| 149 kAllowRestrictedIdentifiers, | 233 kAllowRestrictedIdentifiers, |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 277 this_location_ = location; | 361 this_location_ = location; |
| 278 } | 362 } |
| 279 void set_super_location(Scanner::Location location) { | 363 void set_super_location(Scanner::Location location) { |
| 280 super_location_ = location; | 364 super_location_ = location; |
| 281 } | 365 } |
| 282 void set_return_location(Scanner::Location location) { | 366 void set_return_location(Scanner::Location location) { |
| 283 return_location_ = location; | 367 return_location_ = location; |
| 284 } | 368 } |
| 285 | 369 |
| 286 bool is_generator() const { return IsGeneratorFunction(kind_); } | 370 bool is_generator() const { return IsGeneratorFunction(kind_); } |
| 371 bool is_async_function() const { return IsAsyncFunction(kind_); } | |
| 372 bool is_resumable() const { return is_generator() || is_async_function(); } | |
| 287 | 373 |
| 288 FunctionKind kind() const { return kind_; } | 374 FunctionKind kind() const { return kind_; } |
| 289 FunctionState* outer() const { return outer_function_state_; } | 375 FunctionState* outer() const { return outer_function_state_; } |
| 290 | 376 |
| 377 bool is_async_function_body() const { | |
| 378 return is_async_function() && | |
| 379 parse_phase() == FunctionParsePhase::FunctionBody; | |
| 380 } | |
| 381 | |
| 382 FunctionParsePhase parse_phase() const { return parse_phase_; } | |
| 383 | |
| 384 void set_parse_phase(FunctionParsePhase parse_phase) { | |
| 385 parse_phase_ = parse_phase; | |
| 386 } | |
| 387 | |
| 291 void set_generator_object_variable( | 388 void set_generator_object_variable( |
| 292 typename Traits::Type::GeneratorVariable* variable) { | 389 typename Traits::Type::GeneratorVariable* variable) { |
| 293 DCHECK(variable != NULL); | 390 DCHECK(variable != NULL); |
| 294 DCHECK(is_generator()); | 391 DCHECK(is_resumable()); |
| 295 generator_object_variable_ = variable; | 392 generator_object_variable_ = variable; |
| 296 } | 393 } |
| 297 typename Traits::Type::GeneratorVariable* generator_object_variable() | 394 typename Traits::Type::GeneratorVariable* generator_object_variable() |
| 298 const { | 395 const { |
| 299 return generator_object_variable_; | 396 return generator_object_variable_; |
| 300 } | 397 } |
| 301 | 398 |
| 302 typename Traits::Type::Factory* factory() { return factory_; } | 399 typename Traits::Type::Factory* factory() { return factory_; } |
| 303 | 400 |
| 304 const List<DestructuringAssignment>& destructuring_assignments_to_rewrite() | 401 const List<DestructuringAssignment>& destructuring_assignments_to_rewrite() |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 390 typename Traits::Type::Factory* factory_; | 487 typename Traits::Type::Factory* factory_; |
| 391 | 488 |
| 392 // If true, the next (and immediately following) function literal is | 489 // If true, the next (and immediately following) function literal is |
| 393 // preceded by a parenthesis. | 490 // preceded by a parenthesis. |
| 394 bool next_function_is_parenthesized_; | 491 bool next_function_is_parenthesized_; |
| 395 | 492 |
| 396 // The value of the parents' next_function_is_parenthesized_, as it applies | 493 // The value of the parents' next_function_is_parenthesized_, as it applies |
| 397 // to this function. Filled in by constructor. | 494 // to this function. Filled in by constructor. |
| 398 bool this_function_is_parenthesized_; | 495 bool this_function_is_parenthesized_; |
| 399 | 496 |
| 497 FunctionParsePhase parse_phase_ = FunctionParsePhase::Unknown; | |
| 498 | |
| 400 friend class ParserTraits; | 499 friend class ParserTraits; |
| 401 friend class PreParserTraits; | 500 friend class PreParserTraits; |
| 402 friend class Checkpoint; | 501 friend class Checkpoint; |
| 403 }; | 502 }; |
| 404 | 503 |
| 405 // This scope sets current ReturnExprContext to given value. | 504 // This scope sets current ReturnExprContext to given value. |
| 406 class ReturnExprScope { | 505 class ReturnExprScope { |
| 407 public: | 506 public: |
| 408 explicit ReturnExprScope(FunctionState* function_state, | 507 explicit ReturnExprScope(FunctionState* function_state, |
| 409 ReturnExprContext return_expr_context) | 508 ReturnExprContext return_expr_context) |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 570 tok == Token::RBRACE || | 669 tok == Token::RBRACE || |
| 571 tok == Token::EOS) { | 670 tok == Token::EOS) { |
| 572 return; | 671 return; |
| 573 } | 672 } |
| 574 Expect(Token::SEMICOLON, ok); | 673 Expect(Token::SEMICOLON, ok); |
| 575 } | 674 } |
| 576 | 675 |
| 577 bool peek_any_identifier() { | 676 bool peek_any_identifier() { |
| 578 Token::Value next = peek(); | 677 Token::Value next = peek(); |
| 579 return next == Token::IDENTIFIER || next == Token::AWAIT || | 678 return next == Token::IDENTIFIER || next == Token::AWAIT || |
| 580 next == Token::ENUM || next == Token::FUTURE_STRICT_RESERVED_WORD || | 679 next == Token::ENUM || next == Token::ASYNC || |
|
Dan Ehrenberg
2016/05/12 19:24:32
Nit: put async next to await
| |
| 581 next == Token::LET || next == Token::STATIC || next == Token::YIELD; | 680 next == Token::FUTURE_STRICT_RESERVED_WORD || next == Token::LET || |
| 681 next == Token::STATIC || next == Token::YIELD; | |
| 582 } | 682 } |
| 583 | 683 |
| 584 bool CheckContextualKeyword(Vector<const char> keyword) { | 684 bool CheckContextualKeyword(Vector<const char> keyword) { |
| 585 if (PeekContextualKeyword(keyword)) { | 685 if (PeekContextualKeyword(keyword)) { |
| 586 Consume(Token::IDENTIFIER); | 686 Consume(Token::IDENTIFIER); |
| 587 return true; | 687 return true; |
| 588 } | 688 } |
| 589 return false; | 689 return false; |
| 590 } | 690 } |
| 591 | 691 |
| 592 bool PeekContextualKeyword(Vector<const char> keyword) { | 692 bool PeekContextualKeyword(Vector<const char> keyword) { |
| 593 return peek() == Token::IDENTIFIER && | 693 return peek() == Token::IDENTIFIER && |
| 594 scanner()->is_next_contextual_keyword(keyword); | 694 scanner()->is_next_contextual_keyword(keyword); |
| 595 } | 695 } |
| 596 | 696 |
| 697 bool PeekAheadContextualKeyword(Vector<const char> keyword) { | |
| 698 return PeekAhead() == Token::IDENTIFIER && | |
| 699 scanner()->is_next_next_contextual_keyword(keyword); | |
| 700 } | |
|
Dan Ehrenberg
2016/05/12 19:24:32
Dead code
| |
| 701 | |
| 597 void ExpectMetaProperty(Vector<const char> property_name, | 702 void ExpectMetaProperty(Vector<const char> property_name, |
| 598 const char* full_name, int pos, bool* ok); | 703 const char* full_name, int pos, bool* ok); |
| 599 | 704 |
| 600 void ExpectContextualKeyword(Vector<const char> keyword, bool* ok) { | 705 void ExpectContextualKeyword(Vector<const char> keyword, bool* ok) { |
| 601 Expect(Token::IDENTIFIER, ok); | 706 Expect(Token::IDENTIFIER, ok); |
| 602 if (!*ok) return; | 707 if (!*ok) return; |
| 603 if (!scanner()->is_literal_contextual_keyword(keyword)) { | 708 if (!scanner()->is_literal_contextual_keyword(keyword)) { |
| 604 ReportUnexpectedToken(scanner()->current_token()); | 709 ReportUnexpectedToken(scanner()->current_token()); |
| 605 *ok = false; | 710 *ok = false; |
| 606 } | 711 } |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 677 return 0; // 0 precedence will terminate binary expression parsing | 782 return 0; // 0 precedence will terminate binary expression parsing |
| 678 return Token::Precedence(token); | 783 return Token::Precedence(token); |
| 679 } | 784 } |
| 680 | 785 |
| 681 typename Traits::Type::Factory* factory() { | 786 typename Traits::Type::Factory* factory() { |
| 682 return function_state_->factory(); | 787 return function_state_->factory(); |
| 683 } | 788 } |
| 684 | 789 |
| 685 LanguageMode language_mode() { return scope_->language_mode(); } | 790 LanguageMode language_mode() { return scope_->language_mode(); } |
| 686 bool is_generator() const { return function_state_->is_generator(); } | 791 bool is_generator() const { return function_state_->is_generator(); } |
| 792 bool is_async_function() const { | |
| 793 return function_state_->is_async_function(); | |
| 794 } | |
| 795 bool is_resumable() const { return function_state_->is_resumable(); } | |
| 687 | 796 |
| 688 // Report syntax errors. | 797 // Report syntax errors. |
| 689 void ReportMessage(MessageTemplate::Template message, const char* arg = NULL, | 798 void ReportMessage(MessageTemplate::Template message, const char* arg = NULL, |
| 690 ParseErrorType error_type = kSyntaxError) { | 799 ParseErrorType error_type = kSyntaxError) { |
| 691 Scanner::Location source_location = scanner()->location(); | 800 Scanner::Location source_location = scanner()->location(); |
| 692 Traits::ReportMessageAt(source_location, message, arg, error_type); | 801 Traits::ReportMessageAt(source_location, message, arg, error_type); |
| 693 } | 802 } |
| 694 | 803 |
| 695 void ReportMessageAt(Scanner::Location location, | 804 void ReportMessageAt(Scanner::Location location, |
| 696 MessageTemplate::Template message, | 805 MessageTemplate::Template message, |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 733 void ValidateFormalParameterInitializer( | 842 void ValidateFormalParameterInitializer( |
| 734 const ExpressionClassifier* classifier, bool* ok) { | 843 const ExpressionClassifier* classifier, bool* ok) { |
| 735 if (!classifier->is_valid_formal_parameter_initializer()) { | 844 if (!classifier->is_valid_formal_parameter_initializer()) { |
| 736 ReportClassifierError(classifier->formal_parameter_initializer_error()); | 845 ReportClassifierError(classifier->formal_parameter_initializer_error()); |
| 737 *ok = false; | 846 *ok = false; |
| 738 } | 847 } |
| 739 } | 848 } |
| 740 | 849 |
| 741 void ValidateBindingPattern(const ExpressionClassifier* classifier, | 850 void ValidateBindingPattern(const ExpressionClassifier* classifier, |
| 742 bool* ok) { | 851 bool* ok) { |
| 743 if (!classifier->is_valid_binding_pattern()) { | 852 if (!classifier->is_valid_binding_pattern() || |
| 744 ReportClassifierError(classifier->binding_pattern_error()); | 853 !classifier->is_valid_async_binding_pattern()) { |
| 854 const Scanner::Location& a = classifier->binding_pattern_error().location; | |
| 855 const Scanner::Location& b = | |
| 856 classifier->async_binding_pattern_error().location; | |
| 857 if (a.beg_pos < 0 || (b.beg_pos >= 0 && a.beg_pos > b.beg_pos)) { | |
| 858 ReportClassifierError(classifier->async_binding_pattern_error()); | |
| 859 } else { | |
| 860 ReportClassifierError(classifier->binding_pattern_error()); | |
| 861 } | |
| 745 *ok = false; | 862 *ok = false; |
| 746 } | 863 } |
| 747 } | 864 } |
| 748 | 865 |
| 749 void ValidateAssignmentPattern(const ExpressionClassifier* classifier, | 866 void ValidateAssignmentPattern(const ExpressionClassifier* classifier, |
| 750 bool* ok) { | 867 bool* ok) { |
| 751 if (!classifier->is_valid_assignment_pattern()) { | 868 if (!classifier->is_valid_assignment_pattern()) { |
| 752 ReportClassifierError(classifier->assignment_pattern_error()); | 869 ReportClassifierError(classifier->assignment_pattern_error()); |
| 753 *ok = false; | 870 *ok = false; |
| 754 } | 871 } |
| 755 } | 872 } |
| 756 | 873 |
| 757 void ValidateFormalParameters(const ExpressionClassifier* classifier, | 874 void ValidateFormalParameters(const ExpressionClassifier* classifier, |
| 758 LanguageMode language_mode, | 875 LanguageMode language_mode, |
| 759 bool allow_duplicates, bool* ok) { | 876 bool allow_duplicates, bool* ok) { |
| 760 if (!allow_duplicates && | 877 if (!allow_duplicates && |
| 761 !classifier->is_valid_formal_parameter_list_without_duplicates()) { | 878 !classifier->is_valid_formal_parameter_list_without_duplicates()) { |
| 762 ReportClassifierError(classifier->duplicate_formal_parameter_error()); | 879 ReportClassifierError(classifier->duplicate_formal_parameter_error()); |
| 763 *ok = false; | 880 *ok = false; |
| 764 } else if (is_strict(language_mode) && | 881 } else if (is_strict(language_mode) && |
| 765 !classifier->is_valid_strict_mode_formal_parameters()) { | 882 !classifier->is_valid_strict_mode_formal_parameters()) { |
| 766 ReportClassifierError(classifier->strict_mode_formal_parameter_error()); | 883 ReportClassifierError(classifier->strict_mode_formal_parameter_error()); |
| 767 *ok = false; | 884 *ok = false; |
| 768 } | 885 } |
| 769 } | 886 } |
| 770 | 887 |
| 771 void ValidateArrowFormalParameters(const ExpressionClassifier* classifier, | 888 void ValidateArrowFormalParameters(const ExpressionClassifier* classifier, |
| 772 ExpressionT expr, | 889 ExpressionT expr, |
| 773 bool parenthesized_formals, bool* ok) { | 890 bool parenthesized_formals, bool is_async, |
| 891 bool* ok) { | |
| 774 if (classifier->is_valid_binding_pattern()) { | 892 if (classifier->is_valid_binding_pattern()) { |
| 775 // A simple arrow formal parameter: IDENTIFIER => BODY. | 893 // A simple arrow formal parameter: IDENTIFIER => BODY. |
| 776 if (!this->IsIdentifier(expr)) { | 894 if (!this->IsIdentifier(expr)) { |
| 777 Traits::ReportMessageAt(scanner()->location(), | 895 Traits::ReportMessageAt(scanner()->location(), |
| 778 MessageTemplate::kUnexpectedToken, | 896 MessageTemplate::kUnexpectedToken, |
| 779 Token::String(scanner()->current_token())); | 897 Token::String(scanner()->current_token())); |
| 780 *ok = false; | 898 *ok = false; |
| 781 } | 899 } |
| 782 } else if (!classifier->is_valid_arrow_formal_parameters()) { | 900 } else if (!classifier->is_valid_arrow_formal_parameters()) { |
| 783 // If after parsing the expr, we see an error but the expression is | 901 // If after parsing the expr, we see an error but the expression is |
| 784 // neither a valid binding pattern nor a valid parenthesized formal | 902 // neither a valid binding pattern nor a valid parenthesized formal |
| 785 // parameter list, show the "arrow formal parameters" error if the formals | 903 // parameter list, show the "arrow formal parameters" error if the formals |
| 786 // started with a parenthesis, and the binding pattern error otherwise. | 904 // started with a parenthesis, and the binding pattern error otherwise. |
| 787 const typename ExpressionClassifier::Error& error = | 905 const typename ExpressionClassifier::Error& error = |
| 788 parenthesized_formals ? classifier->arrow_formal_parameters_error() | 906 parenthesized_formals ? classifier->arrow_formal_parameters_error() |
| 789 : classifier->binding_pattern_error(); | 907 : classifier->binding_pattern_error(); |
| 790 ReportClassifierError(error); | 908 ReportClassifierError(error); |
| 791 *ok = false; | 909 *ok = false; |
| 792 } | 910 } |
| 911 if (is_async && !classifier->is_valid_async_arrow_formal_parameters()) { | |
| 912 const typename ExpressionClassifier::Error& error = | |
| 913 classifier->async_arrow_formal_parameters_error(); | |
| 914 ReportClassifierError(error); | |
| 915 *ok = false; | |
| 916 } | |
| 793 } | 917 } |
| 794 | 918 |
| 795 void ValidateLetPattern(const ExpressionClassifier* classifier, bool* ok) { | 919 void ValidateLetPattern(const ExpressionClassifier* classifier, bool* ok) { |
| 796 if (!classifier->is_valid_let_pattern()) { | 920 if (!classifier->is_valid_let_pattern()) { |
| 797 ReportClassifierError(classifier->let_pattern_error()); | 921 ReportClassifierError(classifier->let_pattern_error()); |
| 798 *ok = false; | 922 *ok = false; |
| 799 } | 923 } |
| 800 } | 924 } |
| 801 | 925 |
| 802 void CheckNoTailCallExpressions(const ExpressionClassifier* classifier, | 926 void CheckNoTailCallExpressions(const ExpressionClassifier* classifier, |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 856 return ParseIdentifierOrStrictReservedWord(this->is_generator(), | 980 return ParseIdentifierOrStrictReservedWord(this->is_generator(), |
| 857 is_strict_reserved, ok); | 981 is_strict_reserved, ok); |
| 858 } | 982 } |
| 859 | 983 |
| 860 IdentifierT ParseIdentifierName(bool* ok); | 984 IdentifierT ParseIdentifierName(bool* ok); |
| 861 | 985 |
| 862 ExpressionT ParseRegExpLiteral(bool seen_equal, | 986 ExpressionT ParseRegExpLiteral(bool seen_equal, |
| 863 ExpressionClassifier* classifier, bool* ok); | 987 ExpressionClassifier* classifier, bool* ok); |
| 864 | 988 |
| 865 ExpressionT ParsePrimaryExpression(ExpressionClassifier* classifier, | 989 ExpressionT ParsePrimaryExpression(ExpressionClassifier* classifier, |
| 866 bool* ok); | 990 bool* is_async, bool* ok); |
| 991 ExpressionT ParsePrimaryExpression(ExpressionClassifier* classifier, | |
| 992 bool* ok) { | |
| 993 bool is_async; | |
| 994 return ParsePrimaryExpression(classifier, &is_async, ok); | |
| 995 } | |
| 867 ExpressionT ParseExpression(bool accept_IN, bool* ok); | 996 ExpressionT ParseExpression(bool accept_IN, bool* ok); |
| 868 ExpressionT ParseExpression(bool accept_IN, ExpressionClassifier* classifier, | 997 ExpressionT ParseExpression(bool accept_IN, ExpressionClassifier* classifier, |
| 869 bool* ok); | 998 bool* ok); |
| 870 ExpressionT ParseArrayLiteral(ExpressionClassifier* classifier, bool* ok); | 999 ExpressionT ParseArrayLiteral(ExpressionClassifier* classifier, bool* ok); |
| 871 ExpressionT ParsePropertyName(IdentifierT* name, bool* is_get, bool* is_set, | 1000 ExpressionT ParsePropertyName(IdentifierT* name, bool* is_get, bool* is_set, |
| 872 bool* is_computed_name, | 1001 bool* is_await, bool* is_computed_name, |
| 873 ExpressionClassifier* classifier, bool* ok); | 1002 ExpressionClassifier* classifier, bool* ok); |
| 874 ExpressionT ParseObjectLiteral(ExpressionClassifier* classifier, bool* ok); | 1003 ExpressionT ParseObjectLiteral(ExpressionClassifier* classifier, bool* ok); |
| 875 ObjectLiteralPropertyT ParsePropertyDefinition( | 1004 ObjectLiteralPropertyT ParsePropertyDefinition( |
| 876 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, | 1005 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, |
| 877 bool is_static, bool* is_computed_name, bool* has_seen_constructor, | 1006 MethodKind kind, bool* is_computed_name, bool* has_seen_constructor, |
| 878 ExpressionClassifier* classifier, IdentifierT* name, bool* ok); | 1007 ExpressionClassifier* classifier, IdentifierT* name, bool* ok); |
| 879 typename Traits::Type::ExpressionList ParseArguments( | 1008 typename Traits::Type::ExpressionList ParseArguments( |
| 1009 Scanner::Location* first_spread_pos, bool maybe_arrow, | |
| 1010 ExpressionClassifier* classifier, bool* ok); | |
| 1011 typename Traits::Type::ExpressionList ParseArguments( | |
| 880 Scanner::Location* first_spread_pos, ExpressionClassifier* classifier, | 1012 Scanner::Location* first_spread_pos, ExpressionClassifier* classifier, |
| 881 bool* ok); | 1013 bool* ok) { |
| 1014 return ParseArguments(first_spread_pos, false, classifier, ok); | |
| 1015 } | |
| 882 | 1016 |
| 883 ExpressionT ParseAssignmentExpression(bool accept_IN, | 1017 ExpressionT ParseAssignmentExpression(bool accept_IN, |
| 884 ExpressionClassifier* classifier, | 1018 ExpressionClassifier* classifier, |
| 885 bool* ok); | 1019 bool* ok); |
| 886 ExpressionT ParseYieldExpression(bool accept_IN, | 1020 ExpressionT ParseYieldExpression(bool accept_IN, |
| 887 ExpressionClassifier* classifier, bool* ok); | 1021 ExpressionClassifier* classifier, bool* ok); |
| 888 ExpressionT ParseTailCallExpression(ExpressionClassifier* classifier, | 1022 ExpressionT ParseTailCallExpression(ExpressionClassifier* classifier, |
| 889 bool* ok); | 1023 bool* ok); |
| 890 ExpressionT ParseConditionalExpression(bool accept_IN, | 1024 ExpressionT ParseConditionalExpression(bool accept_IN, |
| 891 ExpressionClassifier* classifier, | 1025 ExpressionClassifier* classifier, |
| 892 bool* ok); | 1026 bool* ok); |
| 893 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, | 1027 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, |
| 894 ExpressionClassifier* classifier, bool* ok); | 1028 ExpressionClassifier* classifier, bool* ok); |
| 895 ExpressionT ParseUnaryExpression(ExpressionClassifier* classifier, bool* ok); | 1029 ExpressionT ParseUnaryExpression(ExpressionClassifier* classifier, bool* ok); |
| 896 ExpressionT ParsePostfixExpression(ExpressionClassifier* classifier, | 1030 ExpressionT ParsePostfixExpression(ExpressionClassifier* classifier, |
| 897 bool* ok); | 1031 bool* ok); |
| 898 ExpressionT ParseLeftHandSideExpression(ExpressionClassifier* classifier, | 1032 ExpressionT ParseLeftHandSideExpression(ExpressionClassifier* classifier, |
| 899 bool* ok); | 1033 bool* ok); |
| 900 ExpressionT ParseMemberWithNewPrefixesExpression( | 1034 ExpressionT ParseMemberWithNewPrefixesExpression( |
| 901 ExpressionClassifier* classifier, bool* ok); | 1035 ExpressionClassifier* classifier, bool* is_async, bool* ok); |
| 902 ExpressionT ParseMemberExpression(ExpressionClassifier* classifier, bool* ok); | 1036 ExpressionT ParseMemberExpression(ExpressionClassifier* classifier, |
| 1037 bool* is_async, bool* ok); | |
| 903 ExpressionT ParseMemberExpressionContinuation( | 1038 ExpressionT ParseMemberExpressionContinuation( |
| 904 ExpressionT expression, ExpressionClassifier* classifier, bool* ok); | 1039 ExpressionT expression, bool* is_async, ExpressionClassifier* classifier, |
| 1040 bool* ok); | |
| 905 ExpressionT ParseArrowFunctionLiteral(bool accept_IN, | 1041 ExpressionT ParseArrowFunctionLiteral(bool accept_IN, |
| 906 const FormalParametersT& parameters, | 1042 const FormalParametersT& parameters, |
| 1043 bool is_async, | |
| 907 const ExpressionClassifier& classifier, | 1044 const ExpressionClassifier& classifier, |
| 908 bool* ok); | 1045 bool* ok); |
| 909 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, | 1046 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, |
| 910 ExpressionClassifier* classifier, bool* ok); | 1047 ExpressionClassifier* classifier, bool* ok); |
| 911 void AddTemplateExpression(ExpressionT); | 1048 void AddTemplateExpression(ExpressionT); |
| 912 ExpressionT ParseSuperExpression(bool is_new, | 1049 ExpressionT ParseSuperExpression(bool is_new, |
| 913 ExpressionClassifier* classifier, bool* ok); | 1050 ExpressionClassifier* classifier, bool* ok); |
| 914 ExpressionT ParseNewTargetExpression(bool* ok); | 1051 ExpressionT ParseNewTargetExpression(bool* ok); |
| 915 | 1052 |
| 916 void ParseFormalParameter(FormalParametersT* parameters, | 1053 void ParseFormalParameter(FormalParametersT* parameters, |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 968 kAccessorProperty, | 1105 kAccessorProperty, |
| 969 kValueProperty, | 1106 kValueProperty, |
| 970 kMethodProperty | 1107 kMethodProperty |
| 971 }; | 1108 }; |
| 972 | 1109 |
| 973 class ObjectLiteralCheckerBase { | 1110 class ObjectLiteralCheckerBase { |
| 974 public: | 1111 public: |
| 975 explicit ObjectLiteralCheckerBase(ParserBase* parser) : parser_(parser) {} | 1112 explicit ObjectLiteralCheckerBase(ParserBase* parser) : parser_(parser) {} |
| 976 | 1113 |
| 977 virtual void CheckProperty(Token::Value property, PropertyKind type, | 1114 virtual void CheckProperty(Token::Value property, PropertyKind type, |
| 978 bool is_static, bool is_generator, bool* ok) = 0; | 1115 MethodKind method_type, bool* ok) = 0; |
| 979 | 1116 |
| 980 virtual ~ObjectLiteralCheckerBase() {} | 1117 virtual ~ObjectLiteralCheckerBase() {} |
| 981 | 1118 |
| 982 protected: | 1119 protected: |
| 983 ParserBase* parser() const { return parser_; } | 1120 ParserBase* parser() const { return parser_; } |
| 984 Scanner* scanner() const { return parser_->scanner(); } | 1121 Scanner* scanner() const { return parser_->scanner(); } |
| 985 | 1122 |
| 986 private: | 1123 private: |
| 987 ParserBase* parser_; | 1124 ParserBase* parser_; |
| 988 }; | 1125 }; |
| 989 | 1126 |
| 990 // Validation per ES6 object literals. | 1127 // Validation per ES6 object literals. |
| 991 class ObjectLiteralChecker : public ObjectLiteralCheckerBase { | 1128 class ObjectLiteralChecker : public ObjectLiteralCheckerBase { |
| 992 public: | 1129 public: |
| 993 explicit ObjectLiteralChecker(ParserBase* parser) | 1130 explicit ObjectLiteralChecker(ParserBase* parser) |
| 994 : ObjectLiteralCheckerBase(parser), has_seen_proto_(false) {} | 1131 : ObjectLiteralCheckerBase(parser), has_seen_proto_(false) {} |
| 995 | 1132 |
| 996 void CheckProperty(Token::Value property, PropertyKind type, bool is_static, | 1133 void CheckProperty(Token::Value property, PropertyKind type, |
| 997 bool is_generator, bool* ok) override; | 1134 MethodKind method_type, bool* ok) override; |
| 998 | 1135 |
| 999 private: | 1136 private: |
| 1000 bool IsProto() { return this->scanner()->LiteralMatches("__proto__", 9); } | 1137 bool IsProto() { return this->scanner()->LiteralMatches("__proto__", 9); } |
| 1001 | 1138 |
| 1002 bool has_seen_proto_; | 1139 bool has_seen_proto_; |
| 1003 }; | 1140 }; |
| 1004 | 1141 |
| 1005 // Validation per ES6 class literals. | 1142 // Validation per ES6 class literals. |
| 1006 class ClassLiteralChecker : public ObjectLiteralCheckerBase { | 1143 class ClassLiteralChecker : public ObjectLiteralCheckerBase { |
| 1007 public: | 1144 public: |
| 1008 explicit ClassLiteralChecker(ParserBase* parser) | 1145 explicit ClassLiteralChecker(ParserBase* parser) |
| 1009 : ObjectLiteralCheckerBase(parser), has_seen_constructor_(false) {} | 1146 : ObjectLiteralCheckerBase(parser), has_seen_constructor_(false) {} |
| 1010 | 1147 |
| 1011 void CheckProperty(Token::Value property, PropertyKind type, bool is_static, | 1148 void CheckProperty(Token::Value property, PropertyKind type, |
| 1012 bool is_generator, bool* ok) override; | 1149 MethodKind method_type, bool* ok) override; |
| 1013 | 1150 |
| 1014 private: | 1151 private: |
| 1015 bool IsConstructor() { | 1152 bool IsConstructor() { |
| 1016 return this->scanner()->LiteralMatches("constructor", 11); | 1153 return this->scanner()->LiteralMatches("constructor", 11); |
| 1017 } | 1154 } |
| 1018 bool IsPrototype() { | 1155 bool IsPrototype() { |
| 1019 return this->scanner()->LiteralMatches("prototype", 9); | 1156 return this->scanner()->LiteralMatches("prototype", 9); |
| 1020 } | 1157 } |
| 1021 | 1158 |
| 1022 bool has_seen_constructor_; | 1159 bool has_seen_constructor_; |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 1039 bool stack_overflow_; | 1176 bool stack_overflow_; |
| 1040 | 1177 |
| 1041 bool allow_lazy_; | 1178 bool allow_lazy_; |
| 1042 bool allow_natives_; | 1179 bool allow_natives_; |
| 1043 bool allow_tailcalls_; | 1180 bool allow_tailcalls_; |
| 1044 bool allow_harmony_restrictive_declarations_; | 1181 bool allow_harmony_restrictive_declarations_; |
| 1045 bool allow_harmony_do_expressions_; | 1182 bool allow_harmony_do_expressions_; |
| 1046 bool allow_harmony_for_in_; | 1183 bool allow_harmony_for_in_; |
| 1047 bool allow_harmony_function_name_; | 1184 bool allow_harmony_function_name_; |
| 1048 bool allow_harmony_function_sent_; | 1185 bool allow_harmony_function_sent_; |
| 1186 bool allow_harmony_async_await_; | |
| 1049 }; | 1187 }; |
| 1050 | 1188 |
| 1051 template <class Traits> | 1189 template <class Traits> |
| 1052 ParserBase<Traits>::FunctionState::FunctionState( | 1190 ParserBase<Traits>::FunctionState::FunctionState( |
| 1053 FunctionState** function_state_stack, Scope** scope_stack, Scope* scope, | 1191 FunctionState** function_state_stack, Scope** scope_stack, Scope* scope, |
| 1054 FunctionKind kind, typename Traits::Type::Factory* factory) | 1192 FunctionKind kind, typename Traits::Type::Factory* factory) |
| 1055 : next_materialized_literal_index_(0), | 1193 : next_materialized_literal_index_(0), |
| 1056 expected_property_count_(0), | 1194 expected_property_count_(0), |
| 1057 this_location_(Scanner::Location::invalid()), | 1195 this_location_(Scanner::Location::invalid()), |
| 1058 return_location_(Scanner::Location::invalid()), | 1196 return_location_(Scanner::Location::invalid()), |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1174 | 1312 |
| 1175 return result; | 1313 return result; |
| 1176 } | 1314 } |
| 1177 | 1315 |
| 1178 | 1316 |
| 1179 template <class Traits> | 1317 template <class Traits> |
| 1180 typename ParserBase<Traits>::IdentifierT | 1318 typename ParserBase<Traits>::IdentifierT |
| 1181 ParserBase<Traits>::ParseAndClassifyIdentifier(ExpressionClassifier* classifier, | 1319 ParserBase<Traits>::ParseAndClassifyIdentifier(ExpressionClassifier* classifier, |
| 1182 bool* ok) { | 1320 bool* ok) { |
| 1183 Token::Value next = Next(); | 1321 Token::Value next = Next(); |
| 1184 if (next == Token::IDENTIFIER || (next == Token::AWAIT && !parsing_module_)) { | 1322 if (next == Token::IDENTIFIER || next == Token::ASYNC || |
| 1323 (next == Token::AWAIT && !parsing_module_)) { | |
| 1185 IdentifierT name = this->GetSymbol(scanner()); | 1324 IdentifierT name = this->GetSymbol(scanner()); |
| 1186 // When this function is used to read a formal parameter, we don't always | 1325 // When this function is used to read a formal parameter, we don't always |
| 1187 // know whether the function is going to be strict or sloppy. Indeed for | 1326 // know whether the function is going to be strict or sloppy. Indeed for |
| 1188 // arrow functions we don't always know that the identifier we are reading | 1327 // arrow functions we don't always know that the identifier we are reading |
| 1189 // is actually a formal parameter. Therefore besides the errors that we | 1328 // is actually a formal parameter. Therefore besides the errors that we |
| 1190 // must detect because we know we're in strict mode, we also record any | 1329 // must detect because we know we're in strict mode, we also record any |
| 1191 // error that we might make in the future once we know the language mode. | 1330 // error that we might make in the future once we know the language mode. |
| 1192 if (this->IsEval(name)) { | 1331 if (this->IsEval(name)) { |
| 1193 classifier->RecordStrictModeFormalParameterError( | 1332 classifier->RecordStrictModeFormalParameterError( |
| 1194 scanner()->location(), MessageTemplate::kStrictEvalArguments); | 1333 scanner()->location(), MessageTemplate::kStrictEvalArguments); |
| 1195 if (is_strict(language_mode())) { | 1334 if (is_strict(language_mode())) { |
| 1196 classifier->RecordBindingPatternError( | 1335 classifier->RecordBindingPatternError( |
| 1197 scanner()->location(), MessageTemplate::kStrictEvalArguments); | 1336 scanner()->location(), MessageTemplate::kStrictEvalArguments); |
| 1198 } | 1337 } |
| 1199 } | 1338 } |
| 1200 if (this->IsArguments(name)) { | 1339 if (this->IsArguments(name)) { |
| 1201 scope_->RecordArgumentsUsage(); | 1340 scope_->RecordArgumentsUsage(); |
| 1202 classifier->RecordStrictModeFormalParameterError( | 1341 classifier->RecordStrictModeFormalParameterError( |
| 1203 scanner()->location(), MessageTemplate::kStrictEvalArguments); | 1342 scanner()->location(), MessageTemplate::kStrictEvalArguments); |
| 1204 if (is_strict(language_mode())) { | 1343 if (is_strict(language_mode())) { |
| 1205 classifier->RecordBindingPatternError( | 1344 classifier->RecordBindingPatternError( |
| 1206 scanner()->location(), MessageTemplate::kStrictEvalArguments); | 1345 scanner()->location(), MessageTemplate::kStrictEvalArguments); |
| 1207 } | 1346 } |
| 1208 } | 1347 } |
| 1348 if (this->IsAwait(name)) { | |
| 1349 if (is_async_function()) { | |
| 1350 classifier->RecordPatternError( | |
| 1351 scanner()->location(), MessageTemplate::kAwaitBindingIdentifier); | |
| 1352 } | |
| 1353 classifier->RecordAsyncArrowFormalParametersError( | |
| 1354 scanner()->location(), MessageTemplate::kAwaitBindingIdentifier); | |
| 1355 } | |
| 1209 | 1356 |
| 1210 if (classifier->duplicate_finder() != nullptr && | 1357 if (classifier->duplicate_finder() != nullptr && |
| 1211 scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) { | 1358 scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) { |
| 1212 classifier->RecordDuplicateFormalParameterError(scanner()->location()); | 1359 classifier->RecordDuplicateFormalParameterError(scanner()->location()); |
| 1213 } | 1360 } |
| 1214 return name; | 1361 return name; |
| 1215 } else if (is_sloppy(language_mode()) && | 1362 } else if (is_sloppy(language_mode()) && |
| 1216 (next == Token::FUTURE_STRICT_RESERVED_WORD || | 1363 (next == Token::FUTURE_STRICT_RESERVED_WORD || |
| 1217 next == Token::ESCAPED_STRICT_RESERVED_WORD || | 1364 next == Token::ESCAPED_STRICT_RESERVED_WORD || |
| 1218 next == Token::LET || next == Token::STATIC || | 1365 next == Token::LET || next == Token::STATIC || |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 1238 return Traits::EmptyIdentifier(); | 1385 return Traits::EmptyIdentifier(); |
| 1239 } | 1386 } |
| 1240 } | 1387 } |
| 1241 | 1388 |
| 1242 | 1389 |
| 1243 template <class Traits> | 1390 template <class Traits> |
| 1244 typename ParserBase<Traits>::IdentifierT | 1391 typename ParserBase<Traits>::IdentifierT |
| 1245 ParserBase<Traits>::ParseIdentifierOrStrictReservedWord( | 1392 ParserBase<Traits>::ParseIdentifierOrStrictReservedWord( |
| 1246 bool is_generator, bool* is_strict_reserved, bool* ok) { | 1393 bool is_generator, bool* is_strict_reserved, bool* ok) { |
| 1247 Token::Value next = Next(); | 1394 Token::Value next = Next(); |
| 1248 if (next == Token::IDENTIFIER || (next == Token::AWAIT && !parsing_module_)) { | 1395 if (next == Token::IDENTIFIER || (next == Token::AWAIT && !parsing_module_) || |
| 1396 next == Token::ASYNC) { | |
| 1249 *is_strict_reserved = false; | 1397 *is_strict_reserved = false; |
| 1250 } else if (next == Token::FUTURE_STRICT_RESERVED_WORD || next == Token::LET || | 1398 } else if (next == Token::FUTURE_STRICT_RESERVED_WORD || next == Token::LET || |
| 1251 next == Token::STATIC || (next == Token::YIELD && !is_generator)) { | 1399 next == Token::STATIC || (next == Token::YIELD && !is_generator)) { |
| 1252 *is_strict_reserved = true; | 1400 *is_strict_reserved = true; |
| 1253 } else { | 1401 } else { |
| 1254 ReportUnexpectedToken(next); | 1402 ReportUnexpectedToken(next); |
| 1255 *ok = false; | 1403 *ok = false; |
| 1256 return Traits::EmptyIdentifier(); | 1404 return Traits::EmptyIdentifier(); |
| 1257 } | 1405 } |
| 1258 | 1406 |
| 1259 IdentifierT name = this->GetSymbol(scanner()); | 1407 IdentifierT name = this->GetSymbol(scanner()); |
| 1260 if (this->IsArguments(name)) scope_->RecordArgumentsUsage(); | 1408 if (this->IsArguments(name)) scope_->RecordArgumentsUsage(); |
| 1261 return name; | 1409 return name; |
| 1262 } | 1410 } |
| 1263 | 1411 |
| 1264 template <class Traits> | 1412 template <class Traits> |
| 1265 typename ParserBase<Traits>::IdentifierT | 1413 typename ParserBase<Traits>::IdentifierT |
| 1266 ParserBase<Traits>::ParseIdentifierName(bool* ok) { | 1414 ParserBase<Traits>::ParseIdentifierName(bool* ok) { |
| 1267 Token::Value next = Next(); | 1415 Token::Value next = Next(); |
| 1268 if (next != Token::IDENTIFIER && next != Token::ENUM && | 1416 if (next != Token::IDENTIFIER && next != Token::ASYNC && |
| 1269 next != Token::AWAIT && next != Token::LET && next != Token::STATIC && | 1417 next != Token::ENUM && next != Token::AWAIT && next != Token::LET && |
| 1270 next != Token::YIELD && next != Token::FUTURE_STRICT_RESERVED_WORD && | 1418 next != Token::STATIC && next != Token::YIELD && |
| 1419 next != Token::FUTURE_STRICT_RESERVED_WORD && | |
| 1271 next != Token::ESCAPED_KEYWORD && | 1420 next != Token::ESCAPED_KEYWORD && |
| 1272 next != Token::ESCAPED_STRICT_RESERVED_WORD && !Token::IsKeyword(next)) { | 1421 next != Token::ESCAPED_STRICT_RESERVED_WORD && !Token::IsKeyword(next)) { |
| 1273 this->ReportUnexpectedToken(next); | 1422 this->ReportUnexpectedToken(next); |
| 1274 *ok = false; | 1423 *ok = false; |
| 1275 return Traits::EmptyIdentifier(); | 1424 return Traits::EmptyIdentifier(); |
| 1276 } | 1425 } |
| 1277 | 1426 |
| 1278 IdentifierT name = this->GetSymbol(scanner()); | 1427 IdentifierT name = this->GetSymbol(scanner()); |
| 1279 if (this->IsArguments(name)) scope_->RecordArgumentsUsage(); | 1428 if (this->IsArguments(name)) scope_->RecordArgumentsUsage(); |
| 1280 return name; | 1429 return name; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1314 #define DUMMY ) // to make indentation work | 1463 #define DUMMY ) // to make indentation work |
| 1315 #undef DUMMY | 1464 #undef DUMMY |
| 1316 | 1465 |
| 1317 // Used in functions where the return type is not ExpressionT. | 1466 // Used in functions where the return type is not ExpressionT. |
| 1318 #define CHECK_OK_CUSTOM(x) ok); \ | 1467 #define CHECK_OK_CUSTOM(x) ok); \ |
| 1319 if (!*ok) return this->x(); \ | 1468 if (!*ok) return this->x(); \ |
| 1320 ((void)0 | 1469 ((void)0 |
| 1321 #define DUMMY ) // to make indentation work | 1470 #define DUMMY ) // to make indentation work |
| 1322 #undef DUMMY | 1471 #undef DUMMY |
| 1323 | 1472 |
| 1324 | |
| 1325 template <class Traits> | 1473 template <class Traits> |
| 1326 typename ParserBase<Traits>::ExpressionT | 1474 typename ParserBase<Traits>::ExpressionT |
| 1327 ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier, | 1475 ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier, |
| 1328 bool* ok) { | 1476 bool* is_async, bool* ok) { |
| 1329 // PrimaryExpression :: | 1477 // PrimaryExpression :: |
| 1330 // 'this' | 1478 // 'this' |
| 1331 // 'null' | 1479 // 'null' |
| 1332 // 'true' | 1480 // 'true' |
| 1333 // 'false' | 1481 // 'false' |
| 1334 // Identifier | 1482 // Identifier |
| 1335 // Number | 1483 // Number |
| 1336 // String | 1484 // String |
| 1337 // ArrayLiteral | 1485 // ArrayLiteral |
| 1338 // ObjectLiteral | 1486 // ObjectLiteral |
| 1339 // RegExpLiteral | 1487 // RegExpLiteral |
| 1340 // ClassLiteral | 1488 // ClassLiteral |
| 1341 // '(' Expression ')' | 1489 // '(' Expression ')' |
| 1342 // TemplateLiteral | 1490 // TemplateLiteral |
| 1343 // do Block | 1491 // do Block |
| 1492 // AsyncFunctionExpression | |
| 1344 | 1493 |
| 1345 int beg_pos = peek_position(); | 1494 int beg_pos = peek_position(); |
| 1346 switch (peek()) { | 1495 switch (peek()) { |
| 1347 case Token::THIS: { | 1496 case Token::THIS: { |
| 1348 BindingPatternUnexpectedToken(classifier); | 1497 BindingPatternUnexpectedToken(classifier); |
| 1349 Consume(Token::THIS); | 1498 Consume(Token::THIS); |
| 1350 return this->ThisExpression(scope_, factory(), beg_pos); | 1499 return this->ThisExpression(scope_, factory(), beg_pos); |
| 1351 } | 1500 } |
| 1352 | 1501 |
| 1353 case Token::NULL_LITERAL: | 1502 case Token::NULL_LITERAL: |
| 1354 case Token::TRUE_LITERAL: | 1503 case Token::TRUE_LITERAL: |
| 1355 case Token::FALSE_LITERAL: | 1504 case Token::FALSE_LITERAL: |
| 1356 BindingPatternUnexpectedToken(classifier); | 1505 BindingPatternUnexpectedToken(classifier); |
| 1357 return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory()); | 1506 return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory()); |
| 1358 case Token::SMI: | 1507 case Token::SMI: |
| 1359 case Token::NUMBER: | 1508 case Token::NUMBER: |
| 1360 BindingPatternUnexpectedToken(classifier); | 1509 BindingPatternUnexpectedToken(classifier); |
| 1361 return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory()); | 1510 return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory()); |
| 1362 | 1511 |
| 1512 case Token::ASYNC: | |
| 1513 if (allow_harmony_async_await() && | |
| 1514 !scanner()->HasAnyLineTerminatorAfterNext() && | |
| 1515 PeekAhead() == Token::FUNCTION) { | |
| 1516 Consume(Token::ASYNC); | |
| 1517 return this->ParseAsyncFunctionExpression(CHECK_OK); | |
| 1518 } | |
| 1519 // CoverCallExpressionAndAsyncArrowHead | |
| 1520 *is_async = true; | |
| 1521 /* falls through */ | |
| 1363 case Token::IDENTIFIER: | 1522 case Token::IDENTIFIER: |
| 1364 case Token::LET: | 1523 case Token::LET: |
| 1365 case Token::STATIC: | 1524 case Token::STATIC: |
| 1366 case Token::YIELD: | 1525 case Token::YIELD: |
| 1367 case Token::AWAIT: | 1526 case Token::AWAIT: |
| 1368 case Token::ESCAPED_STRICT_RESERVED_WORD: | 1527 case Token::ESCAPED_STRICT_RESERVED_WORD: |
| 1369 case Token::FUTURE_STRICT_RESERVED_WORD: { | 1528 case Token::FUTURE_STRICT_RESERVED_WORD: { |
| 1370 // Using eval or arguments in this context is OK even in strict mode. | 1529 // Using eval or arguments in this context is OK even in strict mode. |
| 1371 IdentifierT name = ParseAndClassifyIdentifier(classifier, CHECK_OK); | 1530 IdentifierT name = ParseAndClassifyIdentifier(classifier, CHECK_OK); |
| 1372 return this->ExpressionFromIdentifier( | 1531 return this->ExpressionFromIdentifier( |
| (...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1624 | 1783 |
| 1625 ExpressionT result = factory()->NewArrayLiteral(values, first_spread_index, | 1784 ExpressionT result = factory()->NewArrayLiteral(values, first_spread_index, |
| 1626 literal_index, pos); | 1785 literal_index, pos); |
| 1627 if (first_spread_index >= 0) { | 1786 if (first_spread_index >= 0) { |
| 1628 result = factory()->NewRewritableExpression(result); | 1787 result = factory()->NewRewritableExpression(result); |
| 1629 Traits::QueueNonPatternForRewriting(result); | 1788 Traits::QueueNonPatternForRewriting(result); |
| 1630 } | 1789 } |
| 1631 return result; | 1790 return result; |
| 1632 } | 1791 } |
| 1633 | 1792 |
| 1634 | |
| 1635 template <class Traits> | 1793 template <class Traits> |
| 1636 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParsePropertyName( | 1794 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParsePropertyName( |
| 1637 IdentifierT* name, bool* is_get, bool* is_set, bool* is_computed_name, | 1795 IdentifierT* name, bool* is_get, bool* is_set, bool* is_await, |
| 1638 ExpressionClassifier* classifier, bool* ok) { | 1796 bool* is_computed_name, ExpressionClassifier* classifier, bool* ok) { |
| 1639 Token::Value token = peek(); | 1797 Token::Value token = peek(); |
| 1640 int pos = peek_position(); | 1798 int pos = peek_position(); |
| 1641 | 1799 |
| 1642 // For non computed property names we normalize the name a bit: | 1800 // For non computed property names we normalize the name a bit: |
| 1643 // | 1801 // |
| 1644 // "12" -> 12 | 1802 // "12" -> 12 |
| 1645 // 12.3 -> "12.3" | 1803 // 12.3 -> "12.3" |
| 1646 // 12.30 -> "12.3" | 1804 // 12.30 -> "12.3" |
| 1647 // identifier -> "identifier" | 1805 // identifier -> "identifier" |
| 1648 // | 1806 // |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 1673 Traits::RewriteNonPattern(&computed_name_classifier, CHECK_OK); | 1831 Traits::RewriteNonPattern(&computed_name_classifier, CHECK_OK); |
| 1674 classifier->Accumulate(&computed_name_classifier, | 1832 classifier->Accumulate(&computed_name_classifier, |
| 1675 ExpressionClassifier::ExpressionProductions); | 1833 ExpressionClassifier::ExpressionProductions); |
| 1676 Expect(Token::RBRACK, CHECK_OK); | 1834 Expect(Token::RBRACK, CHECK_OK); |
| 1677 return expression; | 1835 return expression; |
| 1678 } | 1836 } |
| 1679 | 1837 |
| 1680 default: | 1838 default: |
| 1681 *name = ParseIdentifierName(CHECK_OK); | 1839 *name = ParseIdentifierName(CHECK_OK); |
| 1682 scanner()->IsGetOrSet(is_get, is_set); | 1840 scanner()->IsGetOrSet(is_get, is_set); |
| 1841 if (this->IsAwait(*name)) { | |
| 1842 *is_await = true; | |
| 1843 } | |
| 1683 break; | 1844 break; |
| 1684 } | 1845 } |
| 1685 | 1846 |
| 1686 uint32_t index; | 1847 uint32_t index; |
| 1687 return this->IsArrayIndex(*name, &index) | 1848 return this->IsArrayIndex(*name, &index) |
| 1688 ? factory()->NewNumberLiteral(index, pos) | 1849 ? factory()->NewNumberLiteral(index, pos) |
| 1689 : factory()->NewStringLiteral(*name, pos); | 1850 : factory()->NewStringLiteral(*name, pos); |
| 1690 } | 1851 } |
| 1691 | 1852 |
| 1692 | |
| 1693 template <class Traits> | 1853 template <class Traits> |
| 1694 typename ParserBase<Traits>::ObjectLiteralPropertyT | 1854 typename ParserBase<Traits>::ObjectLiteralPropertyT |
| 1695 ParserBase<Traits>::ParsePropertyDefinition( | 1855 ParserBase<Traits>::ParsePropertyDefinition( |
| 1696 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, | 1856 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, |
| 1697 bool is_static, bool* is_computed_name, bool* has_seen_constructor, | 1857 MethodKind method_kind, bool* is_computed_name, bool* has_seen_constructor, |
| 1698 ExpressionClassifier* classifier, IdentifierT* name, bool* ok) { | 1858 ExpressionClassifier* classifier, IdentifierT* name, bool* ok) { |
| 1699 DCHECK(!in_class || is_static || has_seen_constructor != nullptr); | 1859 DCHECK(!in_class || IsStaticMethod(method_kind) || |
| 1860 has_seen_constructor != nullptr); | |
| 1700 ExpressionT value = this->EmptyExpression(); | 1861 ExpressionT value = this->EmptyExpression(); |
| 1701 bool is_get = false; | 1862 bool is_get = false; |
| 1702 bool is_set = false; | 1863 bool is_set = false; |
| 1864 bool is_await = false; | |
| 1703 bool is_generator = Check(Token::MUL); | 1865 bool is_generator = Check(Token::MUL); |
| 1866 bool is_async = false; | |
| 1867 const bool is_static = IsStaticMethod(method_kind); | |
| 1704 | 1868 |
| 1705 Token::Value name_token = peek(); | 1869 Token::Value name_token = peek(); |
| 1870 | |
| 1871 if (is_generator) { | |
| 1872 method_kind |= MethodKind::Generator; | |
| 1873 } else if (allow_harmony_async_await() && name_token == Token::ASYNC && | |
| 1874 !scanner()->HasAnyLineTerminatorAfterNext() && | |
| 1875 PeekAhead() != Token::LPAREN && PeekAhead()) { | |
| 1876 is_async = true; | |
| 1877 } | |
| 1878 | |
| 1706 int next_beg_pos = scanner()->peek_location().beg_pos; | 1879 int next_beg_pos = scanner()->peek_location().beg_pos; |
| 1707 int next_end_pos = scanner()->peek_location().end_pos; | 1880 int next_end_pos = scanner()->peek_location().end_pos; |
| 1708 ExpressionT name_expression = | 1881 ExpressionT name_expression = ParsePropertyName( |
| 1709 ParsePropertyName(name, &is_get, &is_set, is_computed_name, classifier, | 1882 name, &is_get, &is_set, &is_await, is_computed_name, classifier, |
| 1710 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 1883 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 1711 | 1884 |
| 1712 if (fni_ != nullptr && !*is_computed_name) { | 1885 if (fni_ != nullptr && !*is_computed_name) { |
| 1713 this->PushLiteralName(fni_, *name); | 1886 this->PushLiteralName(fni_, *name); |
| 1714 } | 1887 } |
| 1715 | 1888 |
| 1716 if (!in_class && !is_generator) { | 1889 if (!in_class && !is_generator) { |
| 1717 DCHECK(!is_static); | 1890 DCHECK(!IsStaticMethod(method_kind)); |
| 1718 | 1891 |
| 1719 if (peek() == Token::COLON) { | 1892 if (peek() == Token::COLON) { |
| 1720 // PropertyDefinition | 1893 // PropertyDefinition |
| 1721 // PropertyName ':' AssignmentExpression | 1894 // PropertyName ':' AssignmentExpression |
| 1722 if (!*is_computed_name) { | 1895 if (!*is_computed_name) { |
| 1723 checker->CheckProperty(name_token, kValueProperty, false, false, | 1896 checker->CheckProperty(name_token, kValueProperty, MethodKind::Normal, |
| 1724 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 1897 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 1725 } | 1898 } |
| 1726 Consume(Token::COLON); | 1899 Consume(Token::COLON); |
| 1727 int beg_pos = peek_position(); | 1900 int beg_pos = peek_position(); |
| 1728 value = this->ParseAssignmentExpression( | 1901 value = this->ParseAssignmentExpression( |
| 1729 true, classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 1902 true, classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 1730 CheckDestructuringElement(value, classifier, beg_pos, | 1903 CheckDestructuringElement(value, classifier, beg_pos, |
| 1731 scanner()->location().end_pos); | 1904 scanner()->location().end_pos); |
| 1732 | 1905 |
| 1733 return factory()->NewObjectLiteralProperty(name_expression, value, false, | 1906 return factory()->NewObjectLiteralProperty(name_expression, value, |
| 1734 *is_computed_name); | 1907 is_static, *is_computed_name); |
| 1735 } | 1908 } |
| 1736 | 1909 |
| 1737 if (Token::IsIdentifier(name_token, language_mode(), this->is_generator(), | 1910 if (Token::IsIdentifier(name_token, language_mode(), this->is_generator(), |
| 1738 parsing_module_) && | 1911 parsing_module_) && |
| 1739 (peek() == Token::COMMA || peek() == Token::RBRACE || | 1912 (peek() == Token::COMMA || peek() == Token::RBRACE || |
| 1740 peek() == Token::ASSIGN)) { | 1913 peek() == Token::ASSIGN)) { |
| 1741 // PropertyDefinition | 1914 // PropertyDefinition |
| 1742 // IdentifierReference | 1915 // IdentifierReference |
| 1743 // CoverInitializedName | 1916 // CoverInitializedName |
| 1744 // | 1917 // |
| 1745 // CoverInitializedName | 1918 // CoverInitializedName |
| 1746 // IdentifierReference Initializer? | 1919 // IdentifierReference Initializer? |
| 1747 if (classifier->duplicate_finder() != nullptr && | 1920 if (classifier->duplicate_finder() != nullptr && |
| 1748 scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) { | 1921 scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) { |
| 1749 classifier->RecordDuplicateFormalParameterError(scanner()->location()); | 1922 classifier->RecordDuplicateFormalParameterError(scanner()->location()); |
| 1750 } | 1923 } |
| 1751 if (name_token == Token::LET) { | 1924 if (name_token == Token::LET) { |
| 1752 classifier->RecordLetPatternError( | 1925 classifier->RecordLetPatternError( |
| 1753 scanner()->location(), MessageTemplate::kLetInLexicalBinding); | 1926 scanner()->location(), MessageTemplate::kLetInLexicalBinding); |
| 1754 } | 1927 } |
| 1755 | 1928 if (is_await && is_async_function()) { |
| 1929 classifier->RecordPatternError( | |
| 1930 Scanner::Location(next_beg_pos, next_end_pos), | |
| 1931 MessageTemplate::kAwaitBindingIdentifier); | |
| 1932 } | |
| 1756 ExpressionT lhs = this->ExpressionFromIdentifier( | 1933 ExpressionT lhs = this->ExpressionFromIdentifier( |
| 1757 *name, next_beg_pos, next_end_pos, scope_, factory()); | 1934 *name, next_beg_pos, next_end_pos, scope_, factory()); |
| 1758 CheckDestructuringElement(lhs, classifier, next_beg_pos, next_end_pos); | 1935 CheckDestructuringElement(lhs, classifier, next_beg_pos, next_end_pos); |
| 1759 | 1936 |
| 1760 if (peek() == Token::ASSIGN) { | 1937 if (peek() == Token::ASSIGN) { |
| 1761 Consume(Token::ASSIGN); | 1938 Consume(Token::ASSIGN); |
| 1762 ExpressionClassifier rhs_classifier(this); | 1939 ExpressionClassifier rhs_classifier(this); |
| 1763 ExpressionT rhs = this->ParseAssignmentExpression( | 1940 ExpressionT rhs = this->ParseAssignmentExpression( |
| 1764 true, &rhs_classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 1941 true, &rhs_classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 1765 Traits::RewriteNonPattern(&rhs_classifier, | 1942 Traits::RewriteNonPattern(&rhs_classifier, |
| 1766 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 1943 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 1767 classifier->Accumulate(&rhs_classifier, | 1944 classifier->Accumulate(&rhs_classifier, |
| 1768 ExpressionClassifier::ExpressionProductions); | 1945 ExpressionClassifier::ExpressionProductions); |
| 1769 value = factory()->NewAssignment(Token::ASSIGN, lhs, rhs, | 1946 value = factory()->NewAssignment(Token::ASSIGN, lhs, rhs, |
| 1770 RelocInfo::kNoPosition); | 1947 RelocInfo::kNoPosition); |
| 1771 classifier->RecordCoverInitializedNameError( | 1948 classifier->RecordCoverInitializedNameError( |
| 1772 Scanner::Location(next_beg_pos, scanner()->location().end_pos), | 1949 Scanner::Location(next_beg_pos, scanner()->location().end_pos), |
| 1773 MessageTemplate::kInvalidCoverInitializedName); | 1950 MessageTemplate::kInvalidCoverInitializedName); |
| 1774 | 1951 |
| 1775 if (allow_harmony_function_name()) { | 1952 if (allow_harmony_function_name()) { |
| 1776 Traits::SetFunctionNameFromIdentifierRef(rhs, lhs); | 1953 Traits::SetFunctionNameFromIdentifierRef(rhs, lhs); |
| 1777 } | 1954 } |
| 1778 } else { | 1955 } else { |
| 1779 value = lhs; | 1956 value = lhs; |
| 1780 } | 1957 } |
| 1781 | 1958 |
| 1782 return factory()->NewObjectLiteralProperty( | 1959 return factory()->NewObjectLiteralProperty( |
| 1783 name_expression, value, ObjectLiteralProperty::COMPUTED, false, | 1960 name_expression, value, ObjectLiteralProperty::COMPUTED, is_static, |
| 1784 false); | 1961 false); |
| 1785 } | 1962 } |
| 1786 } | 1963 } |
| 1787 | 1964 |
| 1788 // Method definitions are never valid in patterns. | 1965 // Method definitions are never valid in patterns. |
| 1789 classifier->RecordPatternError( | 1966 classifier->RecordPatternError( |
| 1790 Scanner::Location(next_beg_pos, scanner()->location().end_pos), | 1967 Scanner::Location(next_beg_pos, scanner()->location().end_pos), |
| 1791 MessageTemplate::kInvalidDestructuringTarget); | 1968 MessageTemplate::kInvalidDestructuringTarget); |
| 1792 | 1969 |
| 1970 if (is_async && !IsSpecialMethod(method_kind)) { | |
| 1971 DCHECK(!is_get); | |
| 1972 DCHECK(!is_set); | |
| 1973 bool dont_care; | |
| 1974 name_expression = ParsePropertyName( | |
| 1975 name, &dont_care, &dont_care, &dont_care, is_computed_name, classifier, | |
| 1976 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | |
| 1977 method_kind |= MethodKind::Async; | |
| 1978 } | |
| 1979 | |
| 1793 if (is_generator || peek() == Token::LPAREN) { | 1980 if (is_generator || peek() == Token::LPAREN) { |
| 1794 // MethodDefinition | 1981 // MethodDefinition |
| 1795 // PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' | 1982 // PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' |
| 1796 // '*' PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' | 1983 // '*' PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' |
| 1797 if (!*is_computed_name) { | 1984 if (!*is_computed_name) { |
| 1798 checker->CheckProperty(name_token, kMethodProperty, is_static, | 1985 checker->CheckProperty(name_token, kMethodProperty, method_kind, |
| 1799 is_generator, | |
| 1800 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 1986 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 1801 } | 1987 } |
| 1802 | 1988 |
| 1803 FunctionKind kind = is_generator ? FunctionKind::kConciseGeneratorMethod | 1989 FunctionKind kind = is_generator |
| 1804 : FunctionKind::kConciseMethod; | 1990 ? FunctionKind::kConciseGeneratorMethod |
| 1991 : is_async ? FunctionKind::kAsyncConciseMethod | |
| 1992 : FunctionKind::kConciseMethod; | |
| 1805 | 1993 |
| 1806 if (in_class && !is_static && this->IsConstructor(*name)) { | 1994 if (in_class && !IsStaticMethod(method_kind) && |
| 1995 this->IsConstructor(*name)) { | |
| 1807 *has_seen_constructor = true; | 1996 *has_seen_constructor = true; |
| 1808 kind = has_extends ? FunctionKind::kSubclassConstructor | 1997 kind = has_extends ? FunctionKind::kSubclassConstructor |
| 1809 : FunctionKind::kBaseConstructor; | 1998 : FunctionKind::kBaseConstructor; |
| 1810 } | 1999 } |
| 1811 | 2000 |
| 1812 value = this->ParseFunctionLiteral( | 2001 value = this->ParseFunctionLiteral( |
| 1813 *name, scanner()->location(), kSkipFunctionNameCheck, kind, | 2002 *name, scanner()->location(), kSkipFunctionNameCheck, kind, |
| 1814 RelocInfo::kNoPosition, FunctionLiteral::kAccessorOrMethod, | 2003 RelocInfo::kNoPosition, FunctionLiteral::kAccessorOrMethod, |
| 1815 language_mode(), CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2004 language_mode(), CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 1816 | 2005 |
| 1817 return factory()->NewObjectLiteralProperty(name_expression, value, | 2006 return factory()->NewObjectLiteralProperty(name_expression, value, |
| 1818 ObjectLiteralProperty::COMPUTED, | 2007 ObjectLiteralProperty::COMPUTED, |
| 1819 is_static, *is_computed_name); | 2008 is_static, *is_computed_name); |
| 1820 } | 2009 } |
| 1821 | 2010 |
| 1822 if (in_class && name_token == Token::STATIC && !is_static) { | 2011 if (in_class && name_token == Token::STATIC && IsNormalMethod(method_kind)) { |
| 1823 // ClassElement (static) | 2012 // ClassElement (static) |
| 1824 // 'static' MethodDefinition | 2013 // 'static' MethodDefinition |
| 1825 *name = this->EmptyIdentifier(); | 2014 *name = this->EmptyIdentifier(); |
| 1826 ObjectLiteralPropertyT property = ParsePropertyDefinition( | 2015 ObjectLiteralPropertyT property = ParsePropertyDefinition( |
| 1827 checker, true, has_extends, true, is_computed_name, nullptr, classifier, | 2016 checker, true, has_extends, MethodKind::Static, is_computed_name, |
| 1828 name, ok); | 2017 nullptr, classifier, name, ok); |
| 1829 Traits::RewriteNonPattern(classifier, ok); | 2018 Traits::RewriteNonPattern(classifier, ok); |
| 1830 return property; | 2019 return property; |
| 1831 } | 2020 } |
| 1832 | 2021 |
| 1833 if (is_get || is_set) { | 2022 if (is_get || is_set) { |
| 1834 // MethodDefinition (Accessors) | 2023 // MethodDefinition (Accessors) |
| 1835 // get PropertyName '(' ')' '{' FunctionBody '}' | 2024 // get PropertyName '(' ')' '{' FunctionBody '}' |
| 1836 // set PropertyName '(' PropertySetParameterList ')' '{' FunctionBody '}' | 2025 // set PropertyName '(' PropertySetParameterList ')' '{' FunctionBody '}' |
| 1837 *name = this->EmptyIdentifier(); | 2026 *name = this->EmptyIdentifier(); |
| 1838 bool dont_care = false; | 2027 bool dont_care = false; |
| 1839 name_token = peek(); | 2028 name_token = peek(); |
| 1840 | 2029 |
| 1841 name_expression = ParsePropertyName( | 2030 name_expression = ParsePropertyName( |
| 1842 name, &dont_care, &dont_care, is_computed_name, classifier, | 2031 name, &dont_care, &dont_care, &dont_care, is_computed_name, classifier, |
| 1843 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2032 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 1844 | 2033 |
| 1845 if (!*is_computed_name) { | 2034 if (!*is_computed_name) { |
| 1846 checker->CheckProperty(name_token, kAccessorProperty, is_static, | 2035 checker->CheckProperty(name_token, kAccessorProperty, method_kind, |
| 1847 is_generator, | |
| 1848 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2036 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 1849 } | 2037 } |
| 1850 | 2038 |
| 1851 typename Traits::Type::FunctionLiteral value = this->ParseFunctionLiteral( | 2039 typename Traits::Type::FunctionLiteral value = this->ParseFunctionLiteral( |
| 1852 *name, scanner()->location(), kSkipFunctionNameCheck, | 2040 *name, scanner()->location(), kSkipFunctionNameCheck, |
| 1853 is_get ? FunctionKind::kGetterFunction : FunctionKind::kSetterFunction, | 2041 is_get ? FunctionKind::kGetterFunction : FunctionKind::kSetterFunction, |
| 1854 RelocInfo::kNoPosition, FunctionLiteral::kAccessorOrMethod, | 2042 RelocInfo::kNoPosition, FunctionLiteral::kAccessorOrMethod, |
| 1855 language_mode(), CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2043 language_mode(), CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 1856 | 2044 |
| 1857 // Make sure the name expression is a string since we need a Name for | 2045 // Make sure the name expression is a string since we need a Name for |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 1887 int number_of_boilerplate_properties = 0; | 2075 int number_of_boilerplate_properties = 0; |
| 1888 bool has_computed_names = false; | 2076 bool has_computed_names = false; |
| 1889 ObjectLiteralChecker checker(this); | 2077 ObjectLiteralChecker checker(this); |
| 1890 | 2078 |
| 1891 Expect(Token::LBRACE, CHECK_OK); | 2079 Expect(Token::LBRACE, CHECK_OK); |
| 1892 | 2080 |
| 1893 while (peek() != Token::RBRACE) { | 2081 while (peek() != Token::RBRACE) { |
| 1894 FuncNameInferrer::State fni_state(fni_); | 2082 FuncNameInferrer::State fni_state(fni_); |
| 1895 | 2083 |
| 1896 const bool in_class = false; | 2084 const bool in_class = false; |
| 1897 const bool is_static = false; | |
| 1898 const bool has_extends = false; | 2085 const bool has_extends = false; |
| 1899 bool is_computed_name = false; | 2086 bool is_computed_name = false; |
| 1900 IdentifierT name = this->EmptyIdentifier(); | 2087 IdentifierT name = this->EmptyIdentifier(); |
| 1901 ObjectLiteralPropertyT property = this->ParsePropertyDefinition( | 2088 ObjectLiteralPropertyT property = this->ParsePropertyDefinition( |
| 1902 &checker, in_class, has_extends, is_static, &is_computed_name, NULL, | 2089 &checker, in_class, has_extends, MethodKind::Normal, &is_computed_name, |
| 1903 classifier, &name, CHECK_OK); | 2090 NULL, classifier, &name, CHECK_OK); |
| 1904 | 2091 |
| 1905 if (is_computed_name) { | 2092 if (is_computed_name) { |
| 1906 has_computed_names = true; | 2093 has_computed_names = true; |
| 1907 } | 2094 } |
| 1908 | 2095 |
| 1909 // Count CONSTANT or COMPUTED properties to maintain the enumeration order. | 2096 // Count CONSTANT or COMPUTED properties to maintain the enumeration order. |
| 1910 if (!has_computed_names && this->IsBoilerplateProperty(property)) { | 2097 if (!has_computed_names && this->IsBoilerplateProperty(property)) { |
| 1911 number_of_boilerplate_properties++; | 2098 number_of_boilerplate_properties++; |
| 1912 } | 2099 } |
| 1913 properties->Add(property, zone()); | 2100 properties->Add(property, zone()); |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 1927 | 2114 |
| 1928 // Computation of literal_index must happen before pre parse bailout. | 2115 // Computation of literal_index must happen before pre parse bailout. |
| 1929 int literal_index = function_state_->NextMaterializedLiteralIndex(); | 2116 int literal_index = function_state_->NextMaterializedLiteralIndex(); |
| 1930 | 2117 |
| 1931 return factory()->NewObjectLiteral(properties, | 2118 return factory()->NewObjectLiteral(properties, |
| 1932 literal_index, | 2119 literal_index, |
| 1933 number_of_boilerplate_properties, | 2120 number_of_boilerplate_properties, |
| 1934 pos); | 2121 pos); |
| 1935 } | 2122 } |
| 1936 | 2123 |
| 1937 | |
| 1938 template <class Traits> | 2124 template <class Traits> |
| 1939 typename Traits::Type::ExpressionList ParserBase<Traits>::ParseArguments( | 2125 typename Traits::Type::ExpressionList ParserBase<Traits>::ParseArguments( |
| 1940 Scanner::Location* first_spread_arg_loc, ExpressionClassifier* classifier, | 2126 Scanner::Location* first_spread_arg_loc, bool maybe_arrow, |
| 1941 bool* ok) { | 2127 ExpressionClassifier* classifier, bool* ok) { |
| 1942 // Arguments :: | 2128 // Arguments :: |
| 1943 // '(' (AssignmentExpression)*[','] ')' | 2129 // '(' (AssignmentExpression)*[','] ')' |
| 1944 | 2130 |
| 1945 Scanner::Location spread_arg = Scanner::Location::invalid(); | 2131 Scanner::Location spread_arg = Scanner::Location::invalid(); |
| 1946 typename Traits::Type::ExpressionList result = | 2132 typename Traits::Type::ExpressionList result = |
| 1947 this->NewExpressionList(4, zone_); | 2133 this->NewExpressionList(4, zone_); |
| 1948 Expect(Token::LPAREN, CHECK_OK_CUSTOM(NullExpressionList)); | 2134 Expect(Token::LPAREN, CHECK_OK_CUSTOM(NullExpressionList)); |
| 1949 bool done = (peek() == Token::RPAREN); | 2135 bool done = (peek() == Token::RPAREN); |
| 1950 bool was_unspread = false; | 2136 bool was_unspread = false; |
| 1951 int unspread_sequences_count = 0; | 2137 int unspread_sequences_count = 0; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1987 } | 2173 } |
| 1988 } | 2174 } |
| 1989 Scanner::Location location = scanner_->location(); | 2175 Scanner::Location location = scanner_->location(); |
| 1990 if (Token::RPAREN != Next()) { | 2176 if (Token::RPAREN != Next()) { |
| 1991 ReportMessageAt(location, MessageTemplate::kUnterminatedArgList); | 2177 ReportMessageAt(location, MessageTemplate::kUnterminatedArgList); |
| 1992 *ok = false; | 2178 *ok = false; |
| 1993 return this->NullExpressionList(); | 2179 return this->NullExpressionList(); |
| 1994 } | 2180 } |
| 1995 *first_spread_arg_loc = spread_arg; | 2181 *first_spread_arg_loc = spread_arg; |
| 1996 | 2182 |
| 1997 if (spread_arg.IsValid()) { | 2183 if ((!maybe_arrow || peek() != Token::ARROW) && spread_arg.IsValid()) { |
| 1998 // Unspread parameter sequences are translated into array literals in the | 2184 // Unspread parameter sequences are translated into array literals in the |
| 1999 // parser. Ensure that the number of materialized literals matches between | 2185 // parser. Ensure that the number of materialized literals matches between |
| 2000 // the parser and preparser | 2186 // the parser and preparser |
| 2001 Traits::MaterializeUnspreadArgumentsLiterals(unspread_sequences_count); | 2187 Traits::MaterializeUnspreadArgumentsLiterals(unspread_sequences_count); |
| 2002 } | 2188 } |
| 2003 | 2189 |
| 2004 return result; | 2190 return result; |
| 2005 } | 2191 } |
| 2006 | 2192 |
| 2007 // Precedence = 2 | 2193 // Precedence = 2 |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 2019 int lhs_beg_pos = peek_position(); | 2205 int lhs_beg_pos = peek_position(); |
| 2020 | 2206 |
| 2021 if (peek() == Token::YIELD && is_generator()) { | 2207 if (peek() == Token::YIELD && is_generator()) { |
| 2022 return this->ParseYieldExpression(accept_IN, classifier, ok); | 2208 return this->ParseYieldExpression(accept_IN, classifier, ok); |
| 2023 } | 2209 } |
| 2024 | 2210 |
| 2025 FuncNameInferrer::State fni_state(fni_); | 2211 FuncNameInferrer::State fni_state(fni_); |
| 2026 ParserBase<Traits>::Checkpoint checkpoint(this); | 2212 ParserBase<Traits>::Checkpoint checkpoint(this); |
| 2027 ExpressionClassifier arrow_formals_classifier(this, | 2213 ExpressionClassifier arrow_formals_classifier(this, |
| 2028 classifier->duplicate_finder()); | 2214 classifier->duplicate_finder()); |
| 2215 | |
| 2216 bool is_async = allow_harmony_async_await() && peek() == Token::ASYNC && | |
| 2217 !scanner()->HasAnyLineTerminatorAfterNext(); | |
| 2218 | |
| 2029 bool parenthesized_formals = peek() == Token::LPAREN; | 2219 bool parenthesized_formals = peek() == Token::LPAREN; |
| 2030 if (!parenthesized_formals) { | 2220 if (!is_async && !parenthesized_formals) { |
| 2031 ArrowFormalParametersUnexpectedToken(&arrow_formals_classifier); | 2221 ArrowFormalParametersUnexpectedToken(&arrow_formals_classifier); |
| 2032 } | 2222 } |
| 2033 ExpressionT expression = this->ParseConditionalExpression( | 2223 ExpressionT expression = this->ParseConditionalExpression( |
| 2034 accept_IN, &arrow_formals_classifier, CHECK_OK); | 2224 accept_IN, &arrow_formals_classifier, CHECK_OK); |
| 2225 | |
| 2226 if (is_async && peek_any_identifier() && PeekAhead() == Token::ARROW) { | |
| 2227 // async Identifier => AsyncConciseBody | |
| 2228 IdentifierT name = | |
| 2229 ParseAndClassifyIdentifier(&arrow_formals_classifier, CHECK_OK); | |
| 2230 expression = this->ExpressionFromIdentifier( | |
| 2231 name, position(), scanner()->location().end_pos, scope_, factory()); | |
| 2232 } | |
| 2233 | |
| 2035 if (peek() == Token::ARROW) { | 2234 if (peek() == Token::ARROW) { |
| 2036 classifier->RecordPatternError(scanner()->peek_location(), | 2235 classifier->RecordPatternError(scanner()->peek_location(), |
| 2037 MessageTemplate::kUnexpectedToken, | 2236 MessageTemplate::kUnexpectedToken, |
| 2038 Token::String(Token::ARROW)); | 2237 Token::String(Token::ARROW)); |
| 2039 ValidateArrowFormalParameters(&arrow_formals_classifier, expression, | 2238 ValidateArrowFormalParameters(&arrow_formals_classifier, expression, |
| 2040 parenthesized_formals, CHECK_OK); | 2239 parenthesized_formals, is_async, CHECK_OK); |
| 2041 // This reads strangely, but is correct: it checks whether any | 2240 // This reads strangely, but is correct: it checks whether any |
| 2042 // sub-expression of the parameter list failed to be a valid formal | 2241 // sub-expression of the parameter list failed to be a valid formal |
| 2043 // parameter initializer. Since YieldExpressions are banned anywhere | 2242 // parameter initializer. Since YieldExpressions are banned anywhere |
| 2044 // in an arrow parameter list, this is correct. | 2243 // in an arrow parameter list, this is correct. |
| 2045 // TODO(adamk): Rename "FormalParameterInitializerError" to refer to | 2244 // TODO(adamk): Rename "FormalParameterInitializerError" to refer to |
| 2046 // "YieldExpression", which is its only use. | 2245 // "YieldExpression", which is its only use. |
| 2047 ValidateFormalParameterInitializer(&arrow_formals_classifier, ok); | 2246 ValidateFormalParameterInitializer(&arrow_formals_classifier, ok); |
| 2247 | |
| 2048 Scanner::Location loc(lhs_beg_pos, scanner()->location().end_pos); | 2248 Scanner::Location loc(lhs_beg_pos, scanner()->location().end_pos); |
| 2049 Scope* scope = | 2249 Scope* scope = this->NewScope(scope_, FUNCTION_SCOPE, |
| 2050 this->NewScope(scope_, FUNCTION_SCOPE, FunctionKind::kArrowFunction); | 2250 is_async ? FunctionKind::kAsyncArrowFunction |
| 2251 : FunctionKind::kArrowFunction); | |
| 2051 // Because the arrow's parameters were parsed in the outer scope, any | 2252 // Because the arrow's parameters were parsed in the outer scope, any |
| 2052 // usage flags that might have been triggered there need to be copied | 2253 // usage flags that might have been triggered there need to be copied |
| 2053 // to the arrow scope. | 2254 // to the arrow scope. |
| 2054 scope_->PropagateUsageFlagsToScope(scope); | 2255 scope_->PropagateUsageFlagsToScope(scope); |
| 2055 FormalParametersT parameters(scope); | 2256 FormalParametersT parameters(scope); |
| 2056 if (!arrow_formals_classifier.is_simple_parameter_list()) { | 2257 if (!arrow_formals_classifier.is_simple_parameter_list()) { |
| 2057 scope->SetHasNonSimpleParameters(); | 2258 scope->SetHasNonSimpleParameters(); |
| 2058 parameters.is_simple = false; | 2259 parameters.is_simple = false; |
| 2059 } | 2260 } |
| 2060 | 2261 |
| 2061 checkpoint.Restore(¶meters.materialized_literals_count); | 2262 checkpoint.Restore(¶meters.materialized_literals_count); |
| 2062 | 2263 |
| 2063 scope->set_start_position(lhs_beg_pos); | 2264 scope->set_start_position(lhs_beg_pos); |
| 2064 Scanner::Location duplicate_loc = Scanner::Location::invalid(); | 2265 Scanner::Location duplicate_loc = Scanner::Location::invalid(); |
| 2065 this->ParseArrowFunctionFormalParameterList(¶meters, expression, loc, | 2266 this->ParseArrowFunctionFormalParameterList(¶meters, expression, loc, |
| 2066 &duplicate_loc, CHECK_OK); | 2267 &duplicate_loc, CHECK_OK); |
| 2067 if (duplicate_loc.IsValid()) { | 2268 if (duplicate_loc.IsValid()) { |
| 2068 arrow_formals_classifier.RecordDuplicateFormalParameterError( | 2269 arrow_formals_classifier.RecordDuplicateFormalParameterError( |
| 2069 duplicate_loc); | 2270 duplicate_loc); |
| 2070 } | 2271 } |
| 2071 expression = this->ParseArrowFunctionLiteral( | 2272 expression = this->ParseArrowFunctionLiteral( |
| 2072 accept_IN, parameters, arrow_formals_classifier, CHECK_OK); | 2273 accept_IN, parameters, is_async, arrow_formals_classifier, CHECK_OK); |
| 2073 | 2274 |
| 2074 if (fni_ != nullptr) fni_->Infer(); | 2275 if (fni_ != nullptr) fni_->Infer(); |
| 2075 | 2276 |
| 2076 return expression; | 2277 return expression; |
| 2077 } | 2278 } |
| 2078 | 2279 |
| 2079 if (this->IsValidReferenceExpression(expression)) { | 2280 if (this->IsValidReferenceExpression(expression)) { |
| 2080 arrow_formals_classifier.ForgiveAssignmentPatternError(); | 2281 arrow_formals_classifier.ForgiveAssignmentPatternError(); |
| 2081 } | 2282 } |
| 2082 | 2283 |
| 2083 // "expression" was not itself an arrow function parameter list, but it might | 2284 // "expression" was not itself an arrow function parameter list, but it might |
| 2084 // form part of one. Propagate speculative formal parameter error locations. | 2285 // form part of one. Propagate speculative formal parameter error locations. |
| 2085 // Do not merge pending non-pattern expressions yet! | 2286 // Do not merge pending non-pattern expressions yet! |
| 2086 classifier->Accumulate( | 2287 classifier->Accumulate( |
| 2087 &arrow_formals_classifier, | 2288 &arrow_formals_classifier, |
| 2088 ExpressionClassifier::StandardProductions | | 2289 ExpressionClassifier::StandardProductions | |
| 2089 ExpressionClassifier::FormalParametersProductions | | 2290 ExpressionClassifier::FormalParametersProductions | |
| 2090 ExpressionClassifier::CoverInitializedNameProduction, | 2291 ExpressionClassifier::CoverInitializedNameProduction | |
| 2292 ExpressionClassifier::AsyncArrowFormalParametersProduction | | |
| 2293 ExpressionClassifier::AsyncBindingPatternProduction, | |
| 2091 false); | 2294 false); |
| 2092 | 2295 |
| 2093 if (!Token::IsAssignmentOp(peek())) { | 2296 if (!Token::IsAssignmentOp(peek())) { |
| 2094 // Parsed conditional expression only (no assignment). | 2297 // Parsed conditional expression only (no assignment). |
| 2095 // Now pending non-pattern expressions must be merged. | 2298 // Now pending non-pattern expressions must be merged. |
| 2096 classifier->MergeNonPatterns(&arrow_formals_classifier); | 2299 classifier->MergeNonPatterns(&arrow_formals_classifier); |
| 2097 return expression; | 2300 return expression; |
| 2098 } | 2301 } |
| 2099 | 2302 |
| 2100 // Now pending non-pattern expressions must be discarded. | 2303 // Now pending non-pattern expressions must be discarded. |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 2122 } | 2325 } |
| 2123 int pos = position(); | 2326 int pos = position(); |
| 2124 | 2327 |
| 2125 ExpressionClassifier rhs_classifier(this); | 2328 ExpressionClassifier rhs_classifier(this); |
| 2126 | 2329 |
| 2127 ExpressionT right = | 2330 ExpressionT right = |
| 2128 this->ParseAssignmentExpression(accept_IN, &rhs_classifier, CHECK_OK); | 2331 this->ParseAssignmentExpression(accept_IN, &rhs_classifier, CHECK_OK); |
| 2129 CheckNoTailCallExpressions(&rhs_classifier, CHECK_OK); | 2332 CheckNoTailCallExpressions(&rhs_classifier, CHECK_OK); |
| 2130 Traits::RewriteNonPattern(&rhs_classifier, CHECK_OK); | 2333 Traits::RewriteNonPattern(&rhs_classifier, CHECK_OK); |
| 2131 classifier->Accumulate( | 2334 classifier->Accumulate( |
| 2132 &rhs_classifier, ExpressionClassifier::ExpressionProductions | | 2335 &rhs_classifier, |
| 2133 ExpressionClassifier::CoverInitializedNameProduction); | 2336 ExpressionClassifier::ExpressionProductions | |
| 2337 ExpressionClassifier::CoverInitializedNameProduction | | |
| 2338 ExpressionClassifier::AsyncArrowFormalParametersProduction); | |
| 2134 | 2339 |
| 2135 // TODO(1231235): We try to estimate the set of properties set by | 2340 // TODO(1231235): We try to estimate the set of properties set by |
| 2136 // constructors. We define a new property whenever there is an | 2341 // constructors. We define a new property whenever there is an |
| 2137 // assignment to a property of 'this'. We should probably only add | 2342 // assignment to a property of 'this'. We should probably only add |
| 2138 // properties if we haven't seen them before. Otherwise we'll | 2343 // properties if we haven't seen them before. Otherwise we'll |
| 2139 // probably overestimate the number of properties. | 2344 // probably overestimate the number of properties. |
| 2140 if (op == Token::ASSIGN && this->IsThisProperty(expression)) { | 2345 if (op == Token::ASSIGN && this->IsThisProperty(expression)) { |
| 2141 function_state_->AddProperty(); | 2346 function_state_->AddProperty(); |
| 2142 } | 2347 } |
| 2143 | 2348 |
| (...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2394 // PostfixExpression | 2599 // PostfixExpression |
| 2395 // 'delete' UnaryExpression | 2600 // 'delete' UnaryExpression |
| 2396 // 'void' UnaryExpression | 2601 // 'void' UnaryExpression |
| 2397 // 'typeof' UnaryExpression | 2602 // 'typeof' UnaryExpression |
| 2398 // '++' UnaryExpression | 2603 // '++' UnaryExpression |
| 2399 // '--' UnaryExpression | 2604 // '--' UnaryExpression |
| 2400 // '+' UnaryExpression | 2605 // '+' UnaryExpression |
| 2401 // '-' UnaryExpression | 2606 // '-' UnaryExpression |
| 2402 // '~' UnaryExpression | 2607 // '~' UnaryExpression |
| 2403 // '!' UnaryExpression | 2608 // '!' UnaryExpression |
| 2609 // [+Await] AwaitExpression[?Yield] | |
| 2404 | 2610 |
| 2405 Token::Value op = peek(); | 2611 Token::Value op = peek(); |
| 2406 if (Token::IsUnaryOp(op)) { | 2612 if (Token::IsUnaryOp(op)) { |
| 2407 BindingPatternUnexpectedToken(classifier); | 2613 BindingPatternUnexpectedToken(classifier); |
| 2408 ArrowFormalParametersUnexpectedToken(classifier); | 2614 ArrowFormalParametersUnexpectedToken(classifier); |
| 2409 | 2615 |
| 2410 op = Next(); | 2616 op = Next(); |
| 2411 int pos = position(); | 2617 int pos = position(); |
| 2412 ExpressionT expression = ParseUnaryExpression(classifier, CHECK_OK); | 2618 ExpressionT expression = ParseUnaryExpression(classifier, CHECK_OK); |
| 2413 CheckNoTailCallExpressions(classifier, CHECK_OK); | 2619 CheckNoTailCallExpressions(classifier, CHECK_OK); |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 2441 expression, beg_pos, scanner()->location().end_pos, | 2647 expression, beg_pos, scanner()->location().end_pos, |
| 2442 MessageTemplate::kInvalidLhsInPrefixOp, CHECK_OK); | 2648 MessageTemplate::kInvalidLhsInPrefixOp, CHECK_OK); |
| 2443 this->MarkExpressionAsAssigned(expression); | 2649 this->MarkExpressionAsAssigned(expression); |
| 2444 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2650 Traits::RewriteNonPattern(classifier, CHECK_OK); |
| 2445 | 2651 |
| 2446 return factory()->NewCountOperation(op, | 2652 return factory()->NewCountOperation(op, |
| 2447 true /* prefix */, | 2653 true /* prefix */, |
| 2448 expression, | 2654 expression, |
| 2449 position()); | 2655 position()); |
| 2450 | 2656 |
| 2657 } else if (is_async_function() && peek() == Token::AWAIT) { | |
| 2658 int beg_pos = peek_position(); | |
| 2659 switch (PeekAhead()) { | |
| 2660 case Token::RPAREN: | |
| 2661 case Token::RBRACK: | |
| 2662 case Token::RBRACE: | |
| 2663 case Token::ASSIGN: | |
| 2664 case Token::COMMA: { | |
| 2665 Next(); | |
| 2666 IdentifierT name = this->GetSymbol(scanner()); | |
| 2667 | |
| 2668 // Possibly async arrow formals --- record ExpressionError just in case. | |
| 2669 ExpressionUnexpectedToken(classifier); | |
| 2670 classifier->RecordAsyncBindingPatternError( | |
| 2671 Scanner::Location(beg_pos, scanner()->location().end_pos), | |
| 2672 MessageTemplate::kAwaitBindingIdentifier); | |
| 2673 classifier->RecordAsyncArrowFormalParametersError( | |
| 2674 Scanner::Location(beg_pos, scanner()->location().end_pos), | |
| 2675 MessageTemplate::kAwaitBindingIdentifier); | |
| 2676 | |
| 2677 return this->ExpressionFromIdentifier( | |
| 2678 name, beg_pos, scanner()->location().end_pos, scope_, factory()); | |
| 2679 } | |
| 2680 default: | |
| 2681 break; | |
| 2682 } | |
| 2683 Consume(Token::AWAIT); | |
| 2684 | |
| 2685 ExpressionT value = ParseUnaryExpression(classifier, CHECK_OK); | |
| 2686 if (!function_state_->is_async_function_body()) { | |
| 2687 // Not currently parsing function body --- must have occurred within | |
| 2688 // formal parameter parsing. | |
| 2689 ReportMessageAt(Scanner::Location(beg_pos, scanner()->location().end_pos), | |
| 2690 MessageTemplate::kAwaitExpressionFormalParameter); | |
| 2691 *ok = false; | |
| 2692 return this->EmptyExpression(); | |
| 2693 } | |
| 2694 return Traits::RewriteAwaitExpression(value, beg_pos); | |
| 2451 } else { | 2695 } else { |
| 2452 return this->ParsePostfixExpression(classifier, ok); | 2696 return this->ParsePostfixExpression(classifier, ok); |
| 2453 } | 2697 } |
| 2454 } | 2698 } |
| 2455 | 2699 |
| 2456 | 2700 |
| 2457 template <class Traits> | 2701 template <class Traits> |
| 2458 typename ParserBase<Traits>::ExpressionT | 2702 typename ParserBase<Traits>::ExpressionT |
| 2459 ParserBase<Traits>::ParsePostfixExpression(ExpressionClassifier* classifier, | 2703 ParserBase<Traits>::ParsePostfixExpression(ExpressionClassifier* classifier, |
| 2460 bool* ok) { | 2704 bool* ok) { |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 2490 typename ParserBase<Traits>::ExpressionT | 2734 typename ParserBase<Traits>::ExpressionT |
| 2491 ParserBase<Traits>::ParseLeftHandSideExpression( | 2735 ParserBase<Traits>::ParseLeftHandSideExpression( |
| 2492 ExpressionClassifier* classifier, bool* ok) { | 2736 ExpressionClassifier* classifier, bool* ok) { |
| 2493 // LeftHandSideExpression :: | 2737 // LeftHandSideExpression :: |
| 2494 // (NewExpression | MemberExpression) ... | 2738 // (NewExpression | MemberExpression) ... |
| 2495 | 2739 |
| 2496 if (FLAG_harmony_explicit_tailcalls && peek() == Token::CONTINUE) { | 2740 if (FLAG_harmony_explicit_tailcalls && peek() == Token::CONTINUE) { |
| 2497 return this->ParseTailCallExpression(classifier, ok); | 2741 return this->ParseTailCallExpression(classifier, ok); |
| 2498 } | 2742 } |
| 2499 | 2743 |
| 2500 ExpressionT result = | 2744 bool is_async = false; |
| 2501 this->ParseMemberWithNewPrefixesExpression(classifier, CHECK_OK); | 2745 ExpressionT result = this->ParseMemberWithNewPrefixesExpression( |
| 2746 classifier, &is_async, CHECK_OK); | |
| 2502 | 2747 |
| 2503 while (true) { | 2748 while (true) { |
| 2504 switch (peek()) { | 2749 switch (peek()) { |
| 2505 case Token::LBRACK: { | 2750 case Token::LBRACK: { |
| 2506 CheckNoTailCallExpressions(classifier, CHECK_OK); | 2751 CheckNoTailCallExpressions(classifier, CHECK_OK); |
| 2507 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2752 Traits::RewriteNonPattern(classifier, CHECK_OK); |
| 2508 BindingPatternUnexpectedToken(classifier); | 2753 BindingPatternUnexpectedToken(classifier); |
| 2509 ArrowFormalParametersUnexpectedToken(classifier); | 2754 ArrowFormalParametersUnexpectedToken(classifier); |
| 2510 Consume(Token::LBRACK); | 2755 Consume(Token::LBRACK); |
| 2511 int pos = position(); | 2756 int pos = position(); |
| 2512 ExpressionT index = ParseExpression(true, classifier, CHECK_OK); | 2757 ExpressionT index = ParseExpression(true, classifier, CHECK_OK); |
| 2513 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2758 Traits::RewriteNonPattern(classifier, CHECK_OK); |
| 2514 result = factory()->NewProperty(result, index, pos); | 2759 result = factory()->NewProperty(result, index, pos); |
| 2515 Expect(Token::RBRACK, CHECK_OK); | 2760 Expect(Token::RBRACK, CHECK_OK); |
| 2516 break; | 2761 break; |
| 2517 } | 2762 } |
| 2518 | 2763 |
| 2519 case Token::LPAREN: { | 2764 case Token::LPAREN: { |
| 2520 CheckNoTailCallExpressions(classifier, CHECK_OK); | 2765 CheckNoTailCallExpressions(classifier, CHECK_OK); |
| 2766 int pos; | |
| 2521 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2767 Traits::RewriteNonPattern(classifier, CHECK_OK); |
| 2522 BindingPatternUnexpectedToken(classifier); | 2768 BindingPatternUnexpectedToken(classifier); |
| 2523 ArrowFormalParametersUnexpectedToken(classifier); | |
| 2524 | |
| 2525 int pos; | |
| 2526 if (scanner()->current_token() == Token::IDENTIFIER || | 2769 if (scanner()->current_token() == Token::IDENTIFIER || |
| 2527 scanner()->current_token() == Token::SUPER) { | 2770 scanner()->current_token() == Token::SUPER || |
| 2771 scanner()->current_token() == Token::ASYNC) { | |
| 2528 // For call of an identifier we want to report position of | 2772 // For call of an identifier we want to report position of |
| 2529 // the identifier as position of the call in the stack trace. | 2773 // the identifier as position of the call in the stack trace. |
| 2530 pos = position(); | 2774 pos = position(); |
| 2531 } else { | 2775 } else { |
| 2532 // For other kinds of calls we record position of the parenthesis as | 2776 // For other kinds of calls we record position of the parenthesis as |
| 2533 // position of the call. Note that this is extremely important for | 2777 // position of the call. Note that this is extremely important for |
| 2534 // expressions of the form function(){...}() for which call position | 2778 // expressions of the form function(){...}() for which call position |
| 2535 // should not point to the closing brace otherwise it will intersect | 2779 // should not point to the closing brace otherwise it will intersect |
| 2536 // with positions recorded for function literal and confuse debugger. | 2780 // with positions recorded for function literal and confuse debugger. |
| 2537 pos = peek_position(); | 2781 pos = peek_position(); |
| 2538 // Also the trailing parenthesis are a hint that the function will | 2782 // Also the trailing parenthesis are a hint that the function will |
| 2539 // be called immediately. If we happen to have parsed a preceding | 2783 // be called immediately. If we happen to have parsed a preceding |
| 2540 // function literal eagerly, we can also compile it eagerly. | 2784 // function literal eagerly, we can also compile it eagerly. |
| 2541 if (result->IsFunctionLiteral() && mode() == PARSE_EAGERLY) { | 2785 if (result->IsFunctionLiteral() && mode() == PARSE_EAGERLY) { |
| 2542 result->AsFunctionLiteral()->set_should_eager_compile(); | 2786 result->AsFunctionLiteral()->set_should_eager_compile(); |
| 2543 } | 2787 } |
| 2544 } | 2788 } |
| 2545 Scanner::Location spread_pos; | 2789 Scanner::Location spread_pos; |
| 2546 typename Traits::Type::ExpressionList args = | 2790 typename Traits::Type::ExpressionList args = |
| 2547 ParseArguments(&spread_pos, classifier, CHECK_OK); | 2791 ParseArguments(&spread_pos, is_async, classifier, CHECK_OK); |
| 2792 | |
| 2793 if (V8_UNLIKELY(is_async && peek() == Token::ARROW)) { | |
| 2794 if (args->length()) { | |
| 2795 // async ( Arguments ) => ... | |
| 2796 return Traits::ExpressionListToExpression(args); | |
| 2797 } | |
| 2798 // async () => ... | |
| 2799 return factory()->NewEmptyParentheses(pos); | |
| 2800 } | |
| 2801 | |
| 2802 ArrowFormalParametersUnexpectedToken(classifier); | |
| 2548 | 2803 |
| 2549 // Keep track of eval() calls since they disable all local variable | 2804 // Keep track of eval() calls since they disable all local variable |
| 2550 // optimizations. | 2805 // optimizations. |
| 2551 // The calls that need special treatment are the | 2806 // The calls that need special treatment are the |
| 2552 // direct eval calls. These calls are all of the form eval(...), with | 2807 // direct eval calls. These calls are all of the form eval(...), with |
| 2553 // no explicit receiver. | 2808 // no explicit receiver. |
| 2554 // These calls are marked as potentially direct eval calls. Whether | 2809 // These calls are marked as potentially direct eval calls. Whether |
| 2555 // they are actually direct calls to eval is determined at run time. | 2810 // they are actually direct calls to eval is determined at run time. |
| 2556 this->CheckPossibleEvalCall(result, scope_); | 2811 this->CheckPossibleEvalCall(result, scope_); |
| 2557 | 2812 |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2598 result = ParseTemplateLiteral(result, position(), classifier, CHECK_OK); | 2853 result = ParseTemplateLiteral(result, position(), classifier, CHECK_OK); |
| 2599 break; | 2854 break; |
| 2600 } | 2855 } |
| 2601 | 2856 |
| 2602 default: | 2857 default: |
| 2603 return result; | 2858 return result; |
| 2604 } | 2859 } |
| 2605 } | 2860 } |
| 2606 } | 2861 } |
| 2607 | 2862 |
| 2608 | |
| 2609 template <class Traits> | 2863 template <class Traits> |
| 2610 typename ParserBase<Traits>::ExpressionT | 2864 typename ParserBase<Traits>::ExpressionT |
| 2611 ParserBase<Traits>::ParseMemberWithNewPrefixesExpression( | 2865 ParserBase<Traits>::ParseMemberWithNewPrefixesExpression( |
| 2612 ExpressionClassifier* classifier, bool* ok) { | 2866 ExpressionClassifier* classifier, bool* is_async, bool* ok) { |
| 2613 // NewExpression :: | 2867 // NewExpression :: |
| 2614 // ('new')+ MemberExpression | 2868 // ('new')+ MemberExpression |
| 2615 // | 2869 // |
| 2616 // NewTarget :: | 2870 // NewTarget :: |
| 2617 // 'new' '.' 'target' | 2871 // 'new' '.' 'target' |
| 2618 | 2872 |
| 2619 // The grammar for new expressions is pretty warped. We can have several 'new' | 2873 // The grammar for new expressions is pretty warped. We can have several 'new' |
| 2620 // keywords following each other, and then a MemberExpression. When we see '(' | 2874 // keywords following each other, and then a MemberExpression. When we see '(' |
| 2621 // after the MemberExpression, it's associated with the rightmost unassociated | 2875 // after the MemberExpression, it's associated with the rightmost unassociated |
| 2622 // 'new' to create a NewExpression with arguments. However, a NewExpression | 2876 // 'new' to create a NewExpression with arguments. However, a NewExpression |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 2635 ArrowFormalParametersUnexpectedToken(classifier); | 2889 ArrowFormalParametersUnexpectedToken(classifier); |
| 2636 Consume(Token::NEW); | 2890 Consume(Token::NEW); |
| 2637 int new_pos = position(); | 2891 int new_pos = position(); |
| 2638 ExpressionT result = this->EmptyExpression(); | 2892 ExpressionT result = this->EmptyExpression(); |
| 2639 if (peek() == Token::SUPER) { | 2893 if (peek() == Token::SUPER) { |
| 2640 const bool is_new = true; | 2894 const bool is_new = true; |
| 2641 result = ParseSuperExpression(is_new, classifier, CHECK_OK); | 2895 result = ParseSuperExpression(is_new, classifier, CHECK_OK); |
| 2642 } else if (peek() == Token::PERIOD) { | 2896 } else if (peek() == Token::PERIOD) { |
| 2643 return ParseNewTargetExpression(CHECK_OK); | 2897 return ParseNewTargetExpression(CHECK_OK); |
| 2644 } else { | 2898 } else { |
| 2645 result = this->ParseMemberWithNewPrefixesExpression(classifier, CHECK_OK); | 2899 result = this->ParseMemberWithNewPrefixesExpression(classifier, is_async, |
| 2900 CHECK_OK); | |
| 2646 } | 2901 } |
| 2647 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2902 Traits::RewriteNonPattern(classifier, CHECK_OK); |
| 2648 if (peek() == Token::LPAREN) { | 2903 if (peek() == Token::LPAREN) { |
| 2649 // NewExpression with arguments. | 2904 // NewExpression with arguments. |
| 2650 Scanner::Location spread_pos; | 2905 Scanner::Location spread_pos; |
| 2651 typename Traits::Type::ExpressionList args = | 2906 typename Traits::Type::ExpressionList args = |
| 2652 this->ParseArguments(&spread_pos, classifier, CHECK_OK); | 2907 this->ParseArguments(&spread_pos, classifier, CHECK_OK); |
| 2653 | 2908 |
| 2654 if (spread_pos.IsValid()) { | 2909 if (spread_pos.IsValid()) { |
| 2655 args = Traits::PrepareSpreadArguments(args); | 2910 args = Traits::PrepareSpreadArguments(args); |
| 2656 result = Traits::SpreadCallNew(result, args, new_pos); | 2911 result = Traits::SpreadCallNew(result, args, new_pos); |
| 2657 } else { | 2912 } else { |
| 2658 result = factory()->NewCallNew(result, args, new_pos); | 2913 result = factory()->NewCallNew(result, args, new_pos); |
| 2659 } | 2914 } |
| 2660 // The expression can still continue with . or [ after the arguments. | 2915 // The expression can still continue with . or [ after the arguments. |
| 2661 result = | 2916 result = this->ParseMemberExpressionContinuation(result, is_async, |
| 2662 this->ParseMemberExpressionContinuation(result, classifier, CHECK_OK); | 2917 classifier, CHECK_OK); |
| 2663 return result; | 2918 return result; |
| 2664 } | 2919 } |
| 2665 // NewExpression without arguments. | 2920 // NewExpression without arguments. |
| 2666 return factory()->NewCallNew(result, this->NewExpressionList(0, zone_), | 2921 return factory()->NewCallNew(result, this->NewExpressionList(0, zone_), |
| 2667 new_pos); | 2922 new_pos); |
| 2668 } | 2923 } |
| 2669 // No 'new' or 'super' keyword. | 2924 // No 'new' or 'super' keyword. |
| 2670 return this->ParseMemberExpression(classifier, ok); | 2925 return this->ParseMemberExpression(classifier, is_async, ok); |
| 2671 } | 2926 } |
| 2672 | 2927 |
| 2673 | |
| 2674 template <class Traits> | 2928 template <class Traits> |
| 2675 typename ParserBase<Traits>::ExpressionT | 2929 typename ParserBase<Traits>::ExpressionT |
| 2676 ParserBase<Traits>::ParseMemberExpression(ExpressionClassifier* classifier, | 2930 ParserBase<Traits>::ParseMemberExpression(ExpressionClassifier* classifier, |
| 2677 bool* ok) { | 2931 bool* is_async, bool* ok) { |
| 2678 // MemberExpression :: | 2932 // MemberExpression :: |
| 2679 // (PrimaryExpression | FunctionLiteral | ClassLiteral) | 2933 // (PrimaryExpression | FunctionLiteral | ClassLiteral) |
| 2680 // ('[' Expression ']' | '.' Identifier | Arguments | TemplateLiteral)* | 2934 // ('[' Expression ']' | '.' Identifier | Arguments | TemplateLiteral)* |
| 2681 | 2935 |
| 2682 // The '[' Expression ']' and '.' Identifier parts are parsed by | 2936 // The '[' Expression ']' and '.' Identifier parts are parsed by |
| 2683 // ParseMemberExpressionContinuation, and the Arguments part is parsed by the | 2937 // ParseMemberExpressionContinuation, and the Arguments part is parsed by the |
| 2684 // caller. | 2938 // caller. |
| 2685 | 2939 |
| 2686 // Parse the initial primary or function expression. | 2940 // Parse the initial primary or function expression. |
| 2687 ExpressionT result = this->EmptyExpression(); | 2941 ExpressionT result = this->EmptyExpression(); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2724 name, function_name_location, | 2978 name, function_name_location, |
| 2725 is_strict_reserved_name ? kFunctionNameIsStrictReserved | 2979 is_strict_reserved_name ? kFunctionNameIsStrictReserved |
| 2726 : kFunctionNameValidityUnknown, | 2980 : kFunctionNameValidityUnknown, |
| 2727 is_generator ? FunctionKind::kGeneratorFunction | 2981 is_generator ? FunctionKind::kGeneratorFunction |
| 2728 : FunctionKind::kNormalFunction, | 2982 : FunctionKind::kNormalFunction, |
| 2729 function_token_position, function_type, language_mode(), CHECK_OK); | 2983 function_token_position, function_type, language_mode(), CHECK_OK); |
| 2730 } else if (peek() == Token::SUPER) { | 2984 } else if (peek() == Token::SUPER) { |
| 2731 const bool is_new = false; | 2985 const bool is_new = false; |
| 2732 result = ParseSuperExpression(is_new, classifier, CHECK_OK); | 2986 result = ParseSuperExpression(is_new, classifier, CHECK_OK); |
| 2733 } else { | 2987 } else { |
| 2734 result = ParsePrimaryExpression(classifier, CHECK_OK); | 2988 result = ParsePrimaryExpression(classifier, is_async, CHECK_OK); |
| 2735 } | 2989 } |
| 2736 | 2990 |
| 2737 result = ParseMemberExpressionContinuation(result, classifier, CHECK_OK); | 2991 result = |
| 2992 ParseMemberExpressionContinuation(result, is_async, classifier, CHECK_OK); | |
| 2738 return result; | 2993 return result; |
| 2739 } | 2994 } |
| 2740 | 2995 |
| 2741 | 2996 |
| 2742 template <class Traits> | 2997 template <class Traits> |
| 2743 typename ParserBase<Traits>::ExpressionT | 2998 typename ParserBase<Traits>::ExpressionT |
| 2744 ParserBase<Traits>::ParseSuperExpression(bool is_new, | 2999 ParserBase<Traits>::ParseSuperExpression(bool is_new, |
| 2745 ExpressionClassifier* classifier, | 3000 ExpressionClassifier* classifier, |
| 2746 bool* ok) { | 3001 bool* ok) { |
| 2747 Expect(Token::SUPER, CHECK_OK); | 3002 Expect(Token::SUPER, CHECK_OK); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2794 if (!scope_->ReceiverScope()->is_function_scope()) { | 3049 if (!scope_->ReceiverScope()->is_function_scope()) { |
| 2795 ReportMessageAt(scanner()->location(), | 3050 ReportMessageAt(scanner()->location(), |
| 2796 MessageTemplate::kUnexpectedNewTarget); | 3051 MessageTemplate::kUnexpectedNewTarget); |
| 2797 *ok = false; | 3052 *ok = false; |
| 2798 return this->EmptyExpression(); | 3053 return this->EmptyExpression(); |
| 2799 } | 3054 } |
| 2800 | 3055 |
| 2801 return this->NewTargetExpression(scope_, factory(), pos); | 3056 return this->NewTargetExpression(scope_, factory(), pos); |
| 2802 } | 3057 } |
| 2803 | 3058 |
| 2804 | |
| 2805 template <class Traits> | 3059 template <class Traits> |
| 2806 typename ParserBase<Traits>::ExpressionT | 3060 typename ParserBase<Traits>::ExpressionT |
| 2807 ParserBase<Traits>::ParseMemberExpressionContinuation( | 3061 ParserBase<Traits>::ParseMemberExpressionContinuation( |
| 2808 ExpressionT expression, ExpressionClassifier* classifier, bool* ok) { | 3062 ExpressionT expression, bool* is_async, ExpressionClassifier* classifier, |
| 3063 bool* ok) { | |
| 2809 // Parses this part of MemberExpression: | 3064 // Parses this part of MemberExpression: |
| 2810 // ('[' Expression ']' | '.' Identifier | TemplateLiteral)* | 3065 // ('[' Expression ']' | '.' Identifier | TemplateLiteral)* |
| 2811 while (true) { | 3066 while (true) { |
| 2812 switch (peek()) { | 3067 switch (peek()) { |
| 2813 case Token::LBRACK: { | 3068 case Token::LBRACK: { |
| 3069 *is_async = false; | |
| 2814 Traits::RewriteNonPattern(classifier, CHECK_OK); | 3070 Traits::RewriteNonPattern(classifier, CHECK_OK); |
| 2815 BindingPatternUnexpectedToken(classifier); | 3071 BindingPatternUnexpectedToken(classifier); |
| 2816 ArrowFormalParametersUnexpectedToken(classifier); | 3072 ArrowFormalParametersUnexpectedToken(classifier); |
| 2817 | 3073 |
| 2818 Consume(Token::LBRACK); | 3074 Consume(Token::LBRACK); |
| 2819 int pos = position(); | 3075 int pos = position(); |
| 2820 ExpressionT index = this->ParseExpression(true, classifier, CHECK_OK); | 3076 ExpressionT index = this->ParseExpression(true, classifier, CHECK_OK); |
| 2821 Traits::RewriteNonPattern(classifier, CHECK_OK); | 3077 Traits::RewriteNonPattern(classifier, CHECK_OK); |
| 2822 expression = factory()->NewProperty(expression, index, pos); | 3078 expression = factory()->NewProperty(expression, index, pos); |
| 2823 if (fni_ != NULL) { | 3079 if (fni_ != NULL) { |
| 2824 this->PushPropertyName(fni_, index); | 3080 this->PushPropertyName(fni_, index); |
| 2825 } | 3081 } |
| 2826 Expect(Token::RBRACK, CHECK_OK); | 3082 Expect(Token::RBRACK, CHECK_OK); |
| 2827 break; | 3083 break; |
| 2828 } | 3084 } |
| 2829 case Token::PERIOD: { | 3085 case Token::PERIOD: { |
| 3086 *is_async = false; | |
| 2830 Traits::RewriteNonPattern(classifier, CHECK_OK); | 3087 Traits::RewriteNonPattern(classifier, CHECK_OK); |
| 2831 BindingPatternUnexpectedToken(classifier); | 3088 BindingPatternUnexpectedToken(classifier); |
| 2832 ArrowFormalParametersUnexpectedToken(classifier); | 3089 ArrowFormalParametersUnexpectedToken(classifier); |
| 2833 | 3090 |
| 2834 Consume(Token::PERIOD); | 3091 Consume(Token::PERIOD); |
| 2835 int pos = position(); | 3092 int pos = position(); |
| 2836 IdentifierT name = ParseIdentifierName(CHECK_OK); | 3093 IdentifierT name = ParseIdentifierName(CHECK_OK); |
| 2837 expression = factory()->NewProperty( | 3094 expression = factory()->NewProperty( |
| 2838 expression, factory()->NewStringLiteral(name, pos), pos); | 3095 expression, factory()->NewStringLiteral(name, pos), pos); |
| 2839 if (fni_ != NULL) { | 3096 if (fni_ != NULL) { |
| 2840 this->PushLiteralName(fni_, name); | 3097 this->PushLiteralName(fni_, name); |
| 2841 } | 3098 } |
| 2842 break; | 3099 break; |
| 2843 } | 3100 } |
| 2844 case Token::TEMPLATE_SPAN: | 3101 case Token::TEMPLATE_SPAN: |
| 2845 case Token::TEMPLATE_TAIL: { | 3102 case Token::TEMPLATE_TAIL: { |
| 3103 *is_async = false; | |
| 2846 Traits::RewriteNonPattern(classifier, CHECK_OK); | 3104 Traits::RewriteNonPattern(classifier, CHECK_OK); |
| 2847 BindingPatternUnexpectedToken(classifier); | 3105 BindingPatternUnexpectedToken(classifier); |
| 2848 ArrowFormalParametersUnexpectedToken(classifier); | 3106 ArrowFormalParametersUnexpectedToken(classifier); |
| 2849 int pos; | 3107 int pos; |
| 2850 if (scanner()->current_token() == Token::IDENTIFIER) { | 3108 if (scanner()->current_token() == Token::IDENTIFIER) { |
| 2851 pos = position(); | 3109 pos = position(); |
| 2852 } else { | 3110 } else { |
| 2853 pos = peek_position(); | 3111 pos = peek_position(); |
| 2854 if (expression->IsFunctionLiteral() && mode() == PARSE_EAGERLY) { | 3112 if (expression->IsFunctionLiteral() && mode() == PARSE_EAGERLY) { |
| 2855 // If the tag function looks like an IIFE, set_parenthesized() to | 3113 // If the tag function looks like an IIFE, set_parenthesized() to |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2998 DCHECK(peek() == Token::LET); | 3256 DCHECK(peek() == Token::LET); |
| 2999 Token::Value next_next = PeekAhead(); | 3257 Token::Value next_next = PeekAhead(); |
| 3000 switch (next_next) { | 3258 switch (next_next) { |
| 3001 case Token::LBRACE: | 3259 case Token::LBRACE: |
| 3002 case Token::LBRACK: | 3260 case Token::LBRACK: |
| 3003 case Token::IDENTIFIER: | 3261 case Token::IDENTIFIER: |
| 3004 case Token::STATIC: | 3262 case Token::STATIC: |
| 3005 case Token::LET: // Yes, you can do let let = ... in sloppy mode | 3263 case Token::LET: // Yes, you can do let let = ... in sloppy mode |
| 3006 case Token::YIELD: | 3264 case Token::YIELD: |
| 3007 case Token::AWAIT: | 3265 case Token::AWAIT: |
| 3266 case Token::ASYNC: | |
| 3008 return true; | 3267 return true; |
| 3009 default: | 3268 default: |
| 3010 return false; | 3269 return false; |
| 3011 } | 3270 } |
| 3012 } | 3271 } |
| 3013 | 3272 |
| 3014 | |
| 3015 template <class Traits> | 3273 template <class Traits> |
| 3016 typename ParserBase<Traits>::ExpressionT | 3274 typename ParserBase<Traits>::ExpressionT |
| 3017 ParserBase<Traits>::ParseArrowFunctionLiteral( | 3275 ParserBase<Traits>::ParseArrowFunctionLiteral( |
| 3018 bool accept_IN, const FormalParametersT& formal_parameters, | 3276 bool accept_IN, const FormalParametersT& formal_parameters, bool is_async, |
| 3019 const ExpressionClassifier& formals_classifier, bool* ok) { | 3277 const ExpressionClassifier& formals_classifier, bool* ok) { |
| 3020 if (peek() == Token::ARROW && scanner_->HasAnyLineTerminatorBeforeNext()) { | 3278 if (peek() == Token::ARROW && scanner_->HasAnyLineTerminatorBeforeNext()) { |
| 3021 // ASI inserts `;` after arrow parameters if a line terminator is found. | 3279 // ASI inserts `;` after arrow parameters if a line terminator is found. |
| 3022 // `=> ...` is never a valid expression, so report as syntax error. | 3280 // `=> ...` is never a valid expression, so report as syntax error. |
| 3023 // If next token is not `=>`, it's a syntax error anyways. | 3281 // If next token is not `=>`, it's a syntax error anyways. |
| 3024 ReportUnexpectedTokenAt(scanner_->peek_location(), Token::ARROW); | 3282 ReportUnexpectedTokenAt(scanner_->peek_location(), Token::ARROW); |
| 3025 *ok = false; | 3283 *ok = false; |
| 3026 return this->EmptyExpression(); | 3284 return this->EmptyExpression(); |
| 3027 } | 3285 } |
| 3028 | 3286 |
| 3029 typename Traits::Type::StatementList body; | 3287 typename Traits::Type::StatementList body; |
| 3030 int num_parameters = formal_parameters.scope->num_parameters(); | 3288 int num_parameters = formal_parameters.scope->num_parameters(); |
| 3031 int materialized_literal_count = -1; | 3289 int materialized_literal_count = -1; |
| 3032 int expected_property_count = -1; | 3290 int expected_property_count = -1; |
| 3033 Scanner::Location super_loc; | 3291 Scanner::Location super_loc; |
| 3034 | 3292 |
| 3293 FunctionKind arrow_kind = is_async ? kAsyncArrowFunction : kArrowFunction; | |
| 3035 { | 3294 { |
| 3036 typename Traits::Type::Factory function_factory(ast_value_factory()); | 3295 typename Traits::Type::Factory function_factory(ast_value_factory()); |
| 3037 FunctionState function_state(&function_state_, &scope_, | 3296 FunctionState function_state(&function_state_, &scope_, |
| 3038 formal_parameters.scope, kArrowFunction, | 3297 formal_parameters.scope, arrow_kind, |
| 3039 &function_factory); | 3298 &function_factory); |
| 3040 | 3299 |
| 3041 function_state.SkipMaterializedLiterals( | 3300 function_state.SkipMaterializedLiterals( |
| 3042 formal_parameters.materialized_literals_count); | 3301 formal_parameters.materialized_literals_count); |
| 3043 | 3302 |
| 3044 this->ReindexLiterals(formal_parameters); | 3303 this->ReindexLiterals(formal_parameters); |
| 3045 | 3304 |
| 3046 Expect(Token::ARROW, CHECK_OK); | 3305 Expect(Token::ARROW, CHECK_OK); |
| 3306 function_state.set_parse_phase(FunctionParsePhase::FunctionBody); | |
| 3047 | 3307 |
| 3048 if (peek() == Token::LBRACE) { | 3308 if (peek() == Token::LBRACE) { |
| 3049 // Multiple statement body | 3309 // Multiple statement body |
| 3050 Consume(Token::LBRACE); | 3310 Consume(Token::LBRACE); |
| 3051 bool is_lazily_parsed = | 3311 bool is_lazily_parsed = |
| 3052 (mode() == PARSE_LAZILY && scope_->AllowsLazyParsing()); | 3312 (mode() == PARSE_LAZILY && scope_->AllowsLazyParsing()); |
| 3053 if (is_lazily_parsed) { | 3313 if (is_lazily_parsed) { |
| 3054 body = this->NewStatementList(0, zone()); | 3314 body = this->NewStatementList(0, zone()); |
| 3055 this->SkipLazyFunctionBody(&materialized_literal_count, | 3315 this->SkipLazyFunctionBody(&materialized_literal_count, |
| 3056 &expected_property_count, CHECK_OK); | 3316 &expected_property_count, CHECK_OK); |
| 3057 if (formal_parameters.materialized_literals_count > 0) { | 3317 if (formal_parameters.materialized_literals_count > 0) { |
| 3058 materialized_literal_count += | 3318 materialized_literal_count += |
| 3059 formal_parameters.materialized_literals_count; | 3319 formal_parameters.materialized_literals_count; |
| 3060 } | 3320 } |
| 3061 } else { | 3321 } else { |
| 3062 body = this->ParseEagerFunctionBody( | 3322 body = this->ParseEagerFunctionBody( |
| 3063 this->EmptyIdentifier(), RelocInfo::kNoPosition, formal_parameters, | 3323 this->EmptyIdentifier(), RelocInfo::kNoPosition, formal_parameters, |
| 3064 kArrowFunction, FunctionLiteral::kAnonymousExpression, CHECK_OK); | 3324 arrow_kind, FunctionLiteral::kAnonymousExpression, CHECK_OK); |
| 3065 materialized_literal_count = | 3325 materialized_literal_count = |
| 3066 function_state.materialized_literal_count(); | 3326 function_state.materialized_literal_count(); |
| 3067 expected_property_count = function_state.expected_property_count(); | 3327 expected_property_count = function_state.expected_property_count(); |
| 3068 } | 3328 } |
| 3069 } else { | 3329 } else { |
| 3070 // Single-expression body | 3330 // Single-expression body |
| 3071 int pos = position(); | 3331 int pos = position(); |
| 3072 ExpressionClassifier classifier(this); | 3332 ExpressionClassifier classifier(this); |
| 3073 DCHECK(ReturnExprContext::kInsideValidBlock == | 3333 DCHECK(ReturnExprContext::kInsideValidBlock == |
| 3074 function_state_->return_expr_context()); | 3334 function_state_->return_expr_context()); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3108 this->CheckConflictingVarDeclarations(formal_parameters.scope, CHECK_OK); | 3368 this->CheckConflictingVarDeclarations(formal_parameters.scope, CHECK_OK); |
| 3109 | 3369 |
| 3110 Traits::RewriteDestructuringAssignments(); | 3370 Traits::RewriteDestructuringAssignments(); |
| 3111 } | 3371 } |
| 3112 | 3372 |
| 3113 FunctionLiteralT function_literal = factory()->NewFunctionLiteral( | 3373 FunctionLiteralT function_literal = factory()->NewFunctionLiteral( |
| 3114 this->EmptyIdentifierString(), formal_parameters.scope, body, | 3374 this->EmptyIdentifierString(), formal_parameters.scope, body, |
| 3115 materialized_literal_count, expected_property_count, num_parameters, | 3375 materialized_literal_count, expected_property_count, num_parameters, |
| 3116 FunctionLiteral::kNoDuplicateParameters, | 3376 FunctionLiteral::kNoDuplicateParameters, |
| 3117 FunctionLiteral::kAnonymousExpression, | 3377 FunctionLiteral::kAnonymousExpression, |
| 3118 FunctionLiteral::kShouldLazyCompile, FunctionKind::kArrowFunction, | 3378 FunctionLiteral::kShouldLazyCompile, arrow_kind, |
| 3119 formal_parameters.scope->start_position()); | 3379 formal_parameters.scope->start_position()); |
| 3120 | 3380 |
| 3121 function_literal->set_function_token_position( | 3381 function_literal->set_function_token_position( |
| 3122 formal_parameters.scope->start_position()); | 3382 formal_parameters.scope->start_position()); |
| 3123 if (super_loc.IsValid()) function_state_->set_super_location(super_loc); | 3383 if (super_loc.IsValid()) function_state_->set_super_location(super_loc); |
| 3124 | 3384 |
| 3125 if (fni_ != NULL) this->InferFunctionName(fni_, function_literal); | 3385 if (fni_ != NULL) this->InferFunctionName(fni_, function_literal); |
| 3126 | 3386 |
| 3127 return function_literal; | 3387 return function_literal; |
| 3128 } | 3388 } |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3277 classifier->RecordAssignmentPatternError( | 3537 classifier->RecordAssignmentPatternError( |
| 3278 Scanner::Location(begin, end), | 3538 Scanner::Location(begin, end), |
| 3279 MessageTemplate::kInvalidDestructuringTarget); | 3539 MessageTemplate::kInvalidDestructuringTarget); |
| 3280 } | 3540 } |
| 3281 } | 3541 } |
| 3282 | 3542 |
| 3283 | 3543 |
| 3284 #undef CHECK_OK | 3544 #undef CHECK_OK |
| 3285 #undef CHECK_OK_CUSTOM | 3545 #undef CHECK_OK_CUSTOM |
| 3286 | 3546 |
| 3287 | |
| 3288 template <typename Traits> | 3547 template <typename Traits> |
| 3289 void ParserBase<Traits>::ObjectLiteralChecker::CheckProperty( | 3548 void ParserBase<Traits>::ObjectLiteralChecker::CheckProperty( |
| 3290 Token::Value property, PropertyKind type, bool is_static, bool is_generator, | 3549 Token::Value property, PropertyKind type, MethodKind method_type, |
| 3291 bool* ok) { | 3550 bool* ok) { |
| 3292 DCHECK(!is_static); | 3551 DCHECK(!IsStaticMethod(method_type)); |
| 3293 DCHECK(!is_generator || type == kMethodProperty); | 3552 DCHECK(!IsSpecialMethod(method_type) || type == kMethodProperty); |
| 3294 | 3553 |
| 3295 if (property == Token::SMI || property == Token::NUMBER) return; | 3554 if (property == Token::SMI || property == Token::NUMBER) return; |
| 3296 | 3555 |
| 3297 if (type == kValueProperty && IsProto()) { | 3556 if (type == kValueProperty && IsProto()) { |
| 3298 if (has_seen_proto_) { | 3557 if (has_seen_proto_) { |
| 3299 this->parser()->ReportMessage(MessageTemplate::kDuplicateProto); | 3558 this->parser()->ReportMessage(MessageTemplate::kDuplicateProto); |
| 3300 *ok = false; | 3559 *ok = false; |
| 3301 return; | 3560 return; |
| 3302 } | 3561 } |
| 3303 has_seen_proto_ = true; | 3562 has_seen_proto_ = true; |
| 3304 return; | 3563 return; |
| 3305 } | 3564 } |
| 3306 } | 3565 } |
| 3307 | 3566 |
| 3308 | |
| 3309 template <typename Traits> | 3567 template <typename Traits> |
| 3310 void ParserBase<Traits>::ClassLiteralChecker::CheckProperty( | 3568 void ParserBase<Traits>::ClassLiteralChecker::CheckProperty( |
| 3311 Token::Value property, PropertyKind type, bool is_static, bool is_generator, | 3569 Token::Value property, PropertyKind type, MethodKind method_type, |
| 3312 bool* ok) { | 3570 bool* ok) { |
| 3313 DCHECK(type == kMethodProperty || type == kAccessorProperty); | 3571 DCHECK(type == kMethodProperty || type == kAccessorProperty); |
| 3314 | 3572 |
| 3315 if (property == Token::SMI || property == Token::NUMBER) return; | 3573 if (property == Token::SMI || property == Token::NUMBER) return; |
| 3316 | 3574 |
| 3317 if (is_static) { | 3575 if (IsStaticMethod(method_type)) { |
| 3318 if (IsPrototype()) { | 3576 if (IsPrototype()) { |
| 3319 this->parser()->ReportMessage(MessageTemplate::kStaticPrototype); | 3577 this->parser()->ReportMessage(MessageTemplate::kStaticPrototype); |
| 3320 *ok = false; | 3578 *ok = false; |
| 3321 return; | 3579 return; |
| 3322 } | 3580 } |
| 3323 } else if (IsConstructor()) { | 3581 } else if (IsConstructor()) { |
| 3324 if (is_generator || type == kAccessorProperty) { | 3582 const bool is_generator = IsGeneratorMethod(method_type); |
| 3583 const bool is_async = IsAsyncMethod(method_type); | |
| 3584 if (is_generator || is_async || type == kAccessorProperty) { | |
| 3325 MessageTemplate::Template msg = | 3585 MessageTemplate::Template msg = |
| 3326 is_generator ? MessageTemplate::kConstructorIsGenerator | 3586 is_generator ? MessageTemplate::kConstructorIsGenerator |
| 3327 : MessageTemplate::kConstructorIsAccessor; | 3587 : is_async ? MessageTemplate::kConstructorIsAsync |
| 3588 : MessageTemplate::kConstructorIsAccessor; | |
| 3328 this->parser()->ReportMessage(msg); | 3589 this->parser()->ReportMessage(msg); |
| 3329 *ok = false; | 3590 *ok = false; |
| 3330 return; | 3591 return; |
| 3331 } | 3592 } |
| 3332 if (has_seen_constructor_) { | 3593 if (has_seen_constructor_) { |
| 3333 this->parser()->ReportMessage(MessageTemplate::kDuplicateConstructor); | 3594 this->parser()->ReportMessage(MessageTemplate::kDuplicateConstructor); |
| 3334 *ok = false; | 3595 *ok = false; |
| 3335 return; | 3596 return; |
| 3336 } | 3597 } |
| 3337 has_seen_constructor_ = true; | 3598 has_seen_constructor_ = true; |
| 3338 return; | 3599 return; |
| 3339 } | 3600 } |
| 3340 } | 3601 } |
| 3341 | 3602 |
| 3342 | 3603 |
| 3343 } // namespace internal | 3604 } // namespace internal |
| 3344 } // namespace v8 | 3605 } // namespace v8 |
| 3345 | 3606 |
| 3346 #endif // V8_PARSING_PARSER_BASE_H | 3607 #endif // V8_PARSING_PARSER_BASE_H |
| OLD | NEW |