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