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_PREPARSER_H | 5 #ifndef V8_PARSING_PREPARSER_H |
6 #define V8_PARSING_PREPARSER_H | 6 #define V8_PARSING_PREPARSER_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 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
107 scanner_(scanner), | 107 scanner_(scanner), |
108 stack_overflow_(false), | 108 stack_overflow_(false), |
109 allow_lazy_(false), | 109 allow_lazy_(false), |
110 allow_natives_(false), | 110 allow_natives_(false), |
111 allow_harmony_sloppy_(false), | 111 allow_harmony_sloppy_(false), |
112 allow_harmony_sloppy_function_(false), | 112 allow_harmony_sloppy_function_(false), |
113 allow_harmony_sloppy_let_(false), | 113 allow_harmony_sloppy_let_(false), |
114 allow_harmony_rest_parameters_(false), | 114 allow_harmony_rest_parameters_(false), |
115 allow_harmony_default_parameters_(false), | 115 allow_harmony_default_parameters_(false), |
116 allow_harmony_destructuring_bind_(false), | 116 allow_harmony_destructuring_bind_(false), |
| 117 allow_harmony_destructuring_assignment_(false), |
117 allow_strong_mode_(false), | 118 allow_strong_mode_(false), |
118 allow_legacy_const_(true), | 119 allow_legacy_const_(true), |
119 allow_harmony_do_expressions_(false) {} | 120 allow_harmony_do_expressions_(false) {} |
120 | 121 |
121 #define ALLOW_ACCESSORS(name) \ | 122 #define ALLOW_ACCESSORS(name) \ |
122 bool allow_##name() const { return allow_##name##_; } \ | 123 bool allow_##name() const { return allow_##name##_; } \ |
123 void set_allow_##name(bool allow) { allow_##name##_ = allow; } | 124 void set_allow_##name(bool allow) { allow_##name##_ = allow; } |
124 | 125 |
125 ALLOW_ACCESSORS(lazy); | 126 ALLOW_ACCESSORS(lazy); |
126 ALLOW_ACCESSORS(natives); | 127 ALLOW_ACCESSORS(natives); |
127 ALLOW_ACCESSORS(harmony_sloppy); | 128 ALLOW_ACCESSORS(harmony_sloppy); |
128 ALLOW_ACCESSORS(harmony_sloppy_function); | 129 ALLOW_ACCESSORS(harmony_sloppy_function); |
129 ALLOW_ACCESSORS(harmony_sloppy_let); | 130 ALLOW_ACCESSORS(harmony_sloppy_let); |
130 ALLOW_ACCESSORS(harmony_rest_parameters); | 131 ALLOW_ACCESSORS(harmony_rest_parameters); |
131 ALLOW_ACCESSORS(harmony_default_parameters); | 132 ALLOW_ACCESSORS(harmony_default_parameters); |
132 ALLOW_ACCESSORS(harmony_destructuring_bind); | 133 ALLOW_ACCESSORS(harmony_destructuring_bind); |
| 134 ALLOW_ACCESSORS(harmony_destructuring_assignment); |
133 ALLOW_ACCESSORS(strong_mode); | 135 ALLOW_ACCESSORS(strong_mode); |
134 ALLOW_ACCESSORS(legacy_const); | 136 ALLOW_ACCESSORS(legacy_const); |
135 ALLOW_ACCESSORS(harmony_do_expressions); | 137 ALLOW_ACCESSORS(harmony_do_expressions); |
136 #undef ALLOW_ACCESSORS | 138 #undef ALLOW_ACCESSORS |
137 | 139 |
138 uintptr_t stack_limit() const { return stack_limit_; } | 140 uintptr_t stack_limit() const { return stack_limit_; } |
139 | 141 |
140 protected: | 142 protected: |
141 enum AllowRestrictedIdentifiers { | 143 enum AllowRestrictedIdentifiers { |
142 kAllowRestrictedIdentifiers, | 144 kAllowRestrictedIdentifiers, |
(...skipping 25 matching lines...) Expand all Loading... |
168 : scope_stack_(scope_stack), outer_scope_(*scope_stack) { | 170 : scope_stack_(scope_stack), outer_scope_(*scope_stack) { |
169 *scope_stack_ = scope; | 171 *scope_stack_ = scope; |
170 } | 172 } |
171 ~BlockState() { *scope_stack_ = outer_scope_; } | 173 ~BlockState() { *scope_stack_ = outer_scope_; } |
172 | 174 |
173 private: | 175 private: |
174 Scope** scope_stack_; | 176 Scope** scope_stack_; |
175 Scope* outer_scope_; | 177 Scope* outer_scope_; |
176 }; | 178 }; |
177 | 179 |
| 180 struct DestructuringAssignment { |
| 181 public: |
| 182 DestructuringAssignment(ExpressionT expression, Scope* scope) |
| 183 : assignment(expression), scope(scope) {} |
| 184 |
| 185 ExpressionT assignment; |
| 186 Scope* scope; |
| 187 }; |
| 188 |
178 class FunctionState BASE_EMBEDDED { | 189 class FunctionState BASE_EMBEDDED { |
179 public: | 190 public: |
180 FunctionState(FunctionState** function_state_stack, Scope** scope_stack, | 191 FunctionState(FunctionState** function_state_stack, Scope** scope_stack, |
181 Scope* scope, FunctionKind kind, | 192 Scope* scope, FunctionKind kind, |
182 typename Traits::Type::Factory* factory); | 193 typename Traits::Type::Factory* factory); |
183 ~FunctionState(); | 194 ~FunctionState(); |
184 | 195 |
185 int NextMaterializedLiteralIndex() { | 196 int NextMaterializedLiteralIndex() { |
186 return next_materialized_literal_index_++; | 197 return next_materialized_literal_index_++; |
187 } | 198 } |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
220 DCHECK(is_generator()); | 231 DCHECK(is_generator()); |
221 generator_object_variable_ = variable; | 232 generator_object_variable_ = variable; |
222 } | 233 } |
223 typename Traits::Type::GeneratorVariable* generator_object_variable() | 234 typename Traits::Type::GeneratorVariable* generator_object_variable() |
224 const { | 235 const { |
225 return generator_object_variable_; | 236 return generator_object_variable_; |
226 } | 237 } |
227 | 238 |
228 typename Traits::Type::Factory* factory() { return factory_; } | 239 typename Traits::Type::Factory* factory() { return factory_; } |
229 | 240 |
| 241 const List<DestructuringAssignment>& destructuring_assignments_to_rewrite() |
| 242 const { |
| 243 return destructuring_assignments_to_rewrite_; |
| 244 } |
| 245 |
| 246 void AddDestructuringAssignment(DestructuringAssignment pair) { |
| 247 destructuring_assignments_to_rewrite_.Add(pair); |
| 248 } |
| 249 |
230 private: | 250 private: |
231 // Used to assign an index to each literal that needs materialization in | 251 // Used to assign an index to each literal that needs materialization in |
232 // the function. Includes regexp literals, and boilerplate for object and | 252 // the function. Includes regexp literals, and boilerplate for object and |
233 // array literals. | 253 // array literals. |
234 int next_materialized_literal_index_; | 254 int next_materialized_literal_index_; |
235 | 255 |
236 // Properties count estimation. | 256 // Properties count estimation. |
237 int expected_property_count_; | 257 int expected_property_count_; |
238 | 258 |
239 // Location of most recent use of 'this' (invalid if none). | 259 // Location of most recent use of 'this' (invalid if none). |
240 Scanner::Location this_location_; | 260 Scanner::Location this_location_; |
241 | 261 |
242 // Location of most recent 'return' statement (invalid if none). | 262 // Location of most recent 'return' statement (invalid if none). |
243 Scanner::Location return_location_; | 263 Scanner::Location return_location_; |
244 | 264 |
245 // Location of call to the "super" constructor (invalid if none). | 265 // Location of call to the "super" constructor (invalid if none). |
246 Scanner::Location super_location_; | 266 Scanner::Location super_location_; |
247 | 267 |
248 FunctionKind kind_; | 268 FunctionKind kind_; |
249 // For generators, this variable may hold the generator object. It variable | 269 // For generators, this variable may hold the generator object. It variable |
250 // is used by yield expressions and return statements. It is not necessary | 270 // is used by yield expressions and return statements. It is not necessary |
251 // for generator functions to have this variable set. | 271 // for generator functions to have this variable set. |
252 Variable* generator_object_variable_; | 272 Variable* generator_object_variable_; |
253 | 273 |
254 FunctionState** function_state_stack_; | 274 FunctionState** function_state_stack_; |
255 FunctionState* outer_function_state_; | 275 FunctionState* outer_function_state_; |
256 Scope** scope_stack_; | 276 Scope** scope_stack_; |
257 Scope* outer_scope_; | 277 Scope* outer_scope_; |
| 278 |
| 279 List<DestructuringAssignment> destructuring_assignments_to_rewrite_; |
| 280 |
| 281 void RewriteDestructuringAssignments(); |
| 282 |
258 typename Traits::Type::Factory* factory_; | 283 typename Traits::Type::Factory* factory_; |
259 | 284 |
260 friend class ParserTraits; | 285 friend class ParserTraits; |
261 friend class Checkpoint; | 286 friend class Checkpoint; |
262 }; | 287 }; |
263 | 288 |
264 // Annoyingly, arrow functions first parse as comma expressions, then when we | 289 // Annoyingly, arrow functions first parse as comma expressions, then when we |
265 // see the => we have to go back and reinterpret the arguments as being formal | 290 // see the => we have to go back and reinterpret the arguments as being formal |
266 // parameters. To do so we need to reset some of the parser state back to | 291 // parameters. To do so we need to reset some of the parser state back to |
267 // what it was before the arguments were first seen. | 292 // what it was before the arguments were first seen. |
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
453 inline void CheckStrictOctalLiteral(int beg_pos, int end_pos, bool* ok) { | 478 inline void CheckStrictOctalLiteral(int beg_pos, int end_pos, bool* ok) { |
454 CheckOctalLiteral(beg_pos, end_pos, MessageTemplate::kStrictOctalLiteral, | 479 CheckOctalLiteral(beg_pos, end_pos, MessageTemplate::kStrictOctalLiteral, |
455 ok); | 480 ok); |
456 } | 481 } |
457 | 482 |
458 inline void CheckTemplateOctalLiteral(int beg_pos, int end_pos, bool* ok) { | 483 inline void CheckTemplateOctalLiteral(int beg_pos, int end_pos, bool* ok) { |
459 CheckOctalLiteral(beg_pos, end_pos, MessageTemplate::kTemplateOctalLiteral, | 484 CheckOctalLiteral(beg_pos, end_pos, MessageTemplate::kTemplateOctalLiteral, |
460 ok); | 485 ok); |
461 } | 486 } |
462 | 487 |
| 488 void CheckDestructuringElement(ExpressionT element, |
| 489 ExpressionClassifier* classifier, int beg_pos, |
| 490 int end_pos); |
| 491 |
463 // Checking the name of a function literal. This has to be done after parsing | 492 // Checking the name of a function literal. This has to be done after parsing |
464 // the function, since the function can declare itself strict. | 493 // the function, since the function can declare itself strict. |
465 void CheckFunctionName(LanguageMode language_mode, IdentifierT function_name, | 494 void CheckFunctionName(LanguageMode language_mode, IdentifierT function_name, |
466 FunctionNameValidity function_name_validity, | 495 FunctionNameValidity function_name_validity, |
467 const Scanner::Location& function_name_loc, bool* ok) { | 496 const Scanner::Location& function_name_loc, bool* ok) { |
468 if (function_name_validity == kSkipFunctionNameCheck) return; | 497 if (function_name_validity == kSkipFunctionNameCheck) return; |
469 // The function name needs to be checked in strict mode. | 498 // The function name needs to be checked in strict mode. |
470 if (is_sloppy(language_mode)) return; | 499 if (is_sloppy(language_mode)) return; |
471 | 500 |
472 if (this->IsEvalOrArguments(function_name)) { | 501 if (this->IsEvalOrArguments(function_name)) { |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
531 MessageTemplate::Template default_ = MessageTemplate::kUnexpectedToken); | 560 MessageTemplate::Template default_ = MessageTemplate::kUnexpectedToken); |
532 | 561 |
533 void ReportUnexpectedToken(Token::Value token); | 562 void ReportUnexpectedToken(Token::Value token); |
534 void ReportUnexpectedTokenAt( | 563 void ReportUnexpectedTokenAt( |
535 Scanner::Location location, Token::Value token, | 564 Scanner::Location location, Token::Value token, |
536 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken); | 565 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken); |
537 | 566 |
538 | 567 |
539 void ReportClassifierError(const ExpressionClassifier::Error& error) { | 568 void ReportClassifierError(const ExpressionClassifier::Error& error) { |
540 Traits::ReportMessageAt(error.location, error.message, error.arg, | 569 Traits::ReportMessageAt(error.location, error.message, error.arg, |
541 kSyntaxError); | 570 error.type); |
542 } | 571 } |
543 | 572 |
544 void ValidateExpression(const ExpressionClassifier* classifier, bool* ok) { | 573 void ValidateExpression(const ExpressionClassifier* classifier, bool* ok) { |
545 if (!classifier->is_valid_expression()) { | 574 if (!classifier->is_valid_expression() || |
546 ReportClassifierError(classifier->expression_error()); | 575 classifier->has_cover_initialized_name()) { |
| 576 const Scanner::Location& a = classifier->expression_error().location; |
| 577 const Scanner::Location& b = |
| 578 classifier->cover_initialized_name_error().location; |
| 579 if (a.beg_pos < 0 || (b.beg_pos >= 0 && a.beg_pos > b.beg_pos)) { |
| 580 ReportClassifierError(classifier->cover_initialized_name_error()); |
| 581 } else { |
| 582 ReportClassifierError(classifier->expression_error()); |
| 583 } |
547 *ok = false; | 584 *ok = false; |
548 } | 585 } |
549 } | 586 } |
550 | 587 |
551 void ValidateFormalParameterInitializer( | 588 void ValidateFormalParameterInitializer( |
552 const ExpressionClassifier* classifier, bool* ok) { | 589 const ExpressionClassifier* classifier, bool* ok) { |
553 if (!classifier->is_valid_formal_parameter_initializer()) { | 590 if (!classifier->is_valid_formal_parameter_initializer()) { |
554 ReportClassifierError(classifier->formal_parameter_initializer_error()); | 591 ReportClassifierError(classifier->formal_parameter_initializer_error()); |
555 *ok = false; | 592 *ok = false; |
556 } | 593 } |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
685 | 722 |
686 | 723 |
687 ExpressionT ParseRegExpLiteral(bool seen_equal, | 724 ExpressionT ParseRegExpLiteral(bool seen_equal, |
688 ExpressionClassifier* classifier, bool* ok); | 725 ExpressionClassifier* classifier, bool* ok); |
689 | 726 |
690 ExpressionT ParsePrimaryExpression(ExpressionClassifier* classifier, | 727 ExpressionT ParsePrimaryExpression(ExpressionClassifier* classifier, |
691 bool* ok); | 728 bool* ok); |
692 ExpressionT ParseExpression(bool accept_IN, bool* ok); | 729 ExpressionT ParseExpression(bool accept_IN, bool* ok); |
693 ExpressionT ParseExpression(bool accept_IN, ExpressionClassifier* classifier, | 730 ExpressionT ParseExpression(bool accept_IN, ExpressionClassifier* classifier, |
694 bool* ok); | 731 bool* ok); |
| 732 ExpressionT ParseExpression(bool accept_IN, int flags, |
| 733 ExpressionClassifier* classifier, bool* ok); |
695 ExpressionT ParseArrayLiteral(ExpressionClassifier* classifier, bool* ok); | 734 ExpressionT ParseArrayLiteral(ExpressionClassifier* classifier, bool* ok); |
696 ExpressionT ParsePropertyName(IdentifierT* name, bool* is_get, bool* is_set, | 735 ExpressionT ParsePropertyName(IdentifierT* name, bool* is_get, bool* is_set, |
697 bool* is_static, bool* is_computed_name, | 736 bool* is_static, bool* is_computed_name, |
698 bool* is_identifier, bool* is_escaped_keyword, | 737 bool* is_identifier, bool* is_escaped_keyword, |
699 ExpressionClassifier* classifier, bool* ok); | 738 ExpressionClassifier* classifier, bool* ok); |
700 ExpressionT ParseObjectLiteral(ExpressionClassifier* classifier, bool* ok); | 739 ExpressionT ParseObjectLiteral(ExpressionClassifier* classifier, bool* ok); |
701 ObjectLiteralPropertyT ParsePropertyDefinition( | 740 ObjectLiteralPropertyT ParsePropertyDefinition( |
702 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, | 741 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, |
703 bool is_static, bool* is_computed_name, bool* has_seen_constructor, | 742 bool is_static, bool* is_computed_name, bool* has_seen_constructor, |
704 ExpressionClassifier* classifier, bool* ok); | 743 ExpressionClassifier* classifier, bool* ok); |
705 typename Traits::Type::ExpressionList ParseArguments( | 744 typename Traits::Type::ExpressionList ParseArguments( |
706 Scanner::Location* first_spread_pos, ExpressionClassifier* classifier, | 745 Scanner::Location* first_spread_pos, ExpressionClassifier* classifier, |
707 bool* ok); | 746 bool* ok); |
| 747 |
| 748 enum AssignmentExpressionFlags { |
| 749 kIsLeftHandSide = 0, |
| 750 kIsRightHandSide = 1 << 0, |
| 751 kIsPatternElement = 1 << 1, |
| 752 kIsPossibleArrowFormals = 1 << 2 |
| 753 }; |
| 754 |
| 755 ExpressionT ParseAssignmentExpression(bool accept_IN, int flags, |
| 756 ExpressionClassifier* classifier, |
| 757 bool* ok); |
708 ExpressionT ParseAssignmentExpression(bool accept_IN, | 758 ExpressionT ParseAssignmentExpression(bool accept_IN, |
709 ExpressionClassifier* classifier, | 759 ExpressionClassifier* classifier, |
710 bool* ok); | 760 bool* ok) { |
| 761 return ParseAssignmentExpression(accept_IN, kIsLeftHandSide, classifier, |
| 762 ok); |
| 763 } |
711 ExpressionT ParseYieldExpression(ExpressionClassifier* classifier, bool* ok); | 764 ExpressionT ParseYieldExpression(ExpressionClassifier* classifier, bool* ok); |
712 ExpressionT ParseConditionalExpression(bool accept_IN, | 765 ExpressionT ParseConditionalExpression(bool accept_IN, |
713 ExpressionClassifier* classifier, | 766 ExpressionClassifier* classifier, |
714 bool* ok); | 767 bool* ok); |
715 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, | 768 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, |
716 ExpressionClassifier* classifier, bool* ok); | 769 ExpressionClassifier* classifier, bool* ok); |
717 ExpressionT ParseUnaryExpression(ExpressionClassifier* classifier, bool* ok); | 770 ExpressionT ParseUnaryExpression(ExpressionClassifier* classifier, bool* ok); |
718 ExpressionT ParsePostfixExpression(ExpressionClassifier* classifier, | 771 ExpressionT ParsePostfixExpression(ExpressionClassifier* classifier, |
719 bool* ok); | 772 bool* ok); |
720 ExpressionT ParseLeftHandSideExpression(ExpressionClassifier* classifier, | 773 ExpressionT ParseLeftHandSideExpression(ExpressionClassifier* classifier, |
(...skipping 27 matching lines...) Expand all Loading... |
748 bool has_rest, int formals_start_pos, int formals_end_pos, bool* ok); | 801 bool has_rest, int formals_start_pos, int formals_end_pos, bool* ok); |
749 | 802 |
750 bool IsNextLetKeyword(); | 803 bool IsNextLetKeyword(); |
751 | 804 |
752 // Checks if the expression is a valid reference expression (e.g., on the | 805 // Checks if the expression is a valid reference expression (e.g., on the |
753 // left-hand side of assignments). Although ruled out by ECMA as early errors, | 806 // left-hand side of assignments). Although ruled out by ECMA as early errors, |
754 // we allow calls for web compatibility and rewrite them to a runtime throw. | 807 // we allow calls for web compatibility and rewrite them to a runtime throw. |
755 ExpressionT CheckAndRewriteReferenceExpression( | 808 ExpressionT CheckAndRewriteReferenceExpression( |
756 ExpressionT expression, int beg_pos, int end_pos, | 809 ExpressionT expression, int beg_pos, int end_pos, |
757 MessageTemplate::Template message, bool* ok); | 810 MessageTemplate::Template message, bool* ok); |
| 811 ExpressionT ClassifyAndRewriteReferenceExpression( |
| 812 ExpressionClassifier* classifier, ExpressionT expression, int beg_pos, |
| 813 int end_pos, MessageTemplate::Template message, |
| 814 ParseErrorType type = kSyntaxError); |
758 ExpressionT CheckAndRewriteReferenceExpression( | 815 ExpressionT CheckAndRewriteReferenceExpression( |
759 ExpressionT expression, int beg_pos, int end_pos, | 816 ExpressionT expression, int beg_pos, int end_pos, |
760 MessageTemplate::Template message, ParseErrorType type, bool* ok); | 817 MessageTemplate::Template message, ParseErrorType type, bool* ok); |
761 | 818 |
| 819 bool IsValidReferenceExpression(ExpressionT expression); |
| 820 |
| 821 bool IsAssignableIdentifier(ExpressionT expression) { |
| 822 if (!Traits::IsIdentifier(expression)) return false; |
| 823 if (is_strict(language_mode()) && |
| 824 Traits::IsEvalOrArguments(Traits::AsIdentifier(expression))) { |
| 825 return false; |
| 826 } |
| 827 if (is_strong(language_mode()) && |
| 828 Traits::IsUndefined(Traits::AsIdentifier(expression))) { |
| 829 return false; |
| 830 } |
| 831 return true; |
| 832 } |
| 833 |
762 // Used to validate property names in object literals and class literals | 834 // Used to validate property names in object literals and class literals |
763 enum PropertyKind { | 835 enum PropertyKind { |
764 kAccessorProperty, | 836 kAccessorProperty, |
765 kValueProperty, | 837 kValueProperty, |
766 kMethodProperty | 838 kMethodProperty |
767 }; | 839 }; |
768 | 840 |
769 class ObjectLiteralCheckerBase { | 841 class ObjectLiteralCheckerBase { |
770 public: | 842 public: |
771 explicit ObjectLiteralCheckerBase(ParserBase* parser) : parser_(parser) {} | 843 explicit ObjectLiteralCheckerBase(ParserBase* parser) : parser_(parser) {} |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
840 bool stack_overflow_; | 912 bool stack_overflow_; |
841 | 913 |
842 bool allow_lazy_; | 914 bool allow_lazy_; |
843 bool allow_natives_; | 915 bool allow_natives_; |
844 bool allow_harmony_sloppy_; | 916 bool allow_harmony_sloppy_; |
845 bool allow_harmony_sloppy_function_; | 917 bool allow_harmony_sloppy_function_; |
846 bool allow_harmony_sloppy_let_; | 918 bool allow_harmony_sloppy_let_; |
847 bool allow_harmony_rest_parameters_; | 919 bool allow_harmony_rest_parameters_; |
848 bool allow_harmony_default_parameters_; | 920 bool allow_harmony_default_parameters_; |
849 bool allow_harmony_destructuring_bind_; | 921 bool allow_harmony_destructuring_bind_; |
| 922 bool allow_harmony_destructuring_assignment_; |
850 bool allow_strong_mode_; | 923 bool allow_strong_mode_; |
851 bool allow_legacy_const_; | 924 bool allow_legacy_const_; |
852 bool allow_harmony_do_expressions_; | 925 bool allow_harmony_do_expressions_; |
853 }; | 926 }; |
854 | 927 |
855 | 928 |
856 class PreParserIdentifier { | 929 class PreParserIdentifier { |
857 public: | 930 public: |
858 PreParserIdentifier() : type_(kUnknownIdentifier) {} | 931 PreParserIdentifier() : type_(kUnknownIdentifier) {} |
859 static PreParserIdentifier Default() { | 932 static PreParserIdentifier Default() { |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
952 | 1025 |
953 static PreParserExpression BinaryOperation(PreParserExpression left, | 1026 static PreParserExpression BinaryOperation(PreParserExpression left, |
954 Token::Value op, | 1027 Token::Value op, |
955 PreParserExpression right) { | 1028 PreParserExpression right) { |
956 return PreParserExpression( | 1029 return PreParserExpression( |
957 TypeField::encode(kBinaryOperationExpression) | | 1030 TypeField::encode(kBinaryOperationExpression) | |
958 HasRestField::encode(op == Token::COMMA && | 1031 HasRestField::encode(op == Token::COMMA && |
959 right->IsSpreadExpression())); | 1032 right->IsSpreadExpression())); |
960 } | 1033 } |
961 | 1034 |
| 1035 static PreParserExpression AssignmentPattern() { |
| 1036 return PreParserExpression(TypeField::encode(kExpression) | |
| 1037 ExpressionTypeField::encode(kAssignmentPattern)); |
| 1038 } |
| 1039 |
962 static PreParserExpression ObjectLiteral() { | 1040 static PreParserExpression ObjectLiteral() { |
963 return PreParserExpression(TypeField::encode(kObjectLiteralExpression)); | 1041 return PreParserExpression(TypeField::encode(kObjectLiteralExpression)); |
964 } | 1042 } |
965 | 1043 |
966 static PreParserExpression ArrayLiteral() { | 1044 static PreParserExpression ArrayLiteral() { |
967 return PreParserExpression(TypeField::encode(kArrayLiteralExpression)); | 1045 return PreParserExpression(TypeField::encode(kArrayLiteralExpression)); |
968 } | 1046 } |
969 | 1047 |
970 static PreParserExpression StringLiteral() { | 1048 static PreParserExpression StringLiteral() { |
971 return PreParserExpression(TypeField::encode(kStringLiteralExpression)); | 1049 return PreParserExpression(TypeField::encode(kStringLiteralExpression)); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1017 | 1095 |
1018 bool IsIdentifier() const { | 1096 bool IsIdentifier() const { |
1019 return TypeField::decode(code_) == kIdentifierExpression; | 1097 return TypeField::decode(code_) == kIdentifierExpression; |
1020 } | 1098 } |
1021 | 1099 |
1022 PreParserIdentifier AsIdentifier() const { | 1100 PreParserIdentifier AsIdentifier() const { |
1023 DCHECK(IsIdentifier()); | 1101 DCHECK(IsIdentifier()); |
1024 return PreParserIdentifier(IdentifierTypeField::decode(code_)); | 1102 return PreParserIdentifier(IdentifierTypeField::decode(code_)); |
1025 } | 1103 } |
1026 | 1104 |
| 1105 bool IsAssignmentPattern() const { |
| 1106 return TypeField::decode(code_) == kExpression && |
| 1107 ExpressionTypeField::decode(code_) == kAssignmentPattern; |
| 1108 } |
| 1109 |
1027 bool IsObjectLiteral() const { | 1110 bool IsObjectLiteral() const { |
1028 return TypeField::decode(code_) == kObjectLiteralExpression; | 1111 return TypeField::decode(code_) == kObjectLiteralExpression; |
1029 } | 1112 } |
1030 | 1113 |
1031 bool IsArrayLiteral() const { | 1114 bool IsArrayLiteral() const { |
1032 return TypeField::decode(code_) == kArrayLiteralExpression; | 1115 return TypeField::decode(code_) == kArrayLiteralExpression; |
1033 } | 1116 } |
1034 | 1117 |
1035 bool IsStringLiteral() const { | 1118 bool IsStringLiteral() const { |
1036 return TypeField::decode(code_) == kStringLiteralExpression; | 1119 return TypeField::decode(code_) == kStringLiteralExpression; |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1124 kObjectLiteralExpression, | 1207 kObjectLiteralExpression, |
1125 kArrayLiteralExpression | 1208 kArrayLiteralExpression |
1126 }; | 1209 }; |
1127 | 1210 |
1128 enum ExpressionType { | 1211 enum ExpressionType { |
1129 kThisExpression, | 1212 kThisExpression, |
1130 kThisPropertyExpression, | 1213 kThisPropertyExpression, |
1131 kPropertyExpression, | 1214 kPropertyExpression, |
1132 kCallExpression, | 1215 kCallExpression, |
1133 kSuperCallReference, | 1216 kSuperCallReference, |
1134 kNoTemplateTagExpression | 1217 kNoTemplateTagExpression, |
| 1218 kAssignmentPattern |
1135 }; | 1219 }; |
1136 | 1220 |
1137 explicit PreParserExpression(uint32_t expression_code) | 1221 explicit PreParserExpression(uint32_t expression_code) |
1138 : code_(expression_code) {} | 1222 : code_(expression_code) {} |
1139 | 1223 |
1140 // The first three bits are for the Type. | 1224 // The first three bits are for the Type. |
1141 typedef BitField<Type, 0, 3> TypeField; | 1225 typedef BitField<Type, 0, 3> TypeField; |
1142 | 1226 |
1143 // The rest of the bits are interpreted depending on the value | 1227 // The rest of the bits are interpreted depending on the value |
1144 // of the Type field, so they can share the storage. | 1228 // of the Type field, so they can share the storage. |
1145 typedef BitField<ExpressionType, TypeField::kNext, 3> ExpressionTypeField; | 1229 typedef BitField<ExpressionType, TypeField::kNext, 3> ExpressionTypeField; |
1146 typedef BitField<bool, TypeField::kNext, 1> IsUseStrictField; | 1230 typedef BitField<bool, TypeField::kNext, 1> IsUseStrictField; |
1147 typedef BitField<bool, IsUseStrictField::kNext, 1> IsUseStrongField; | 1231 typedef BitField<bool, IsUseStrictField::kNext, 1> IsUseStrongField; |
1148 typedef BitField<PreParserIdentifier::Type, TypeField::kNext, 10> | 1232 typedef BitField<PreParserIdentifier::Type, TypeField::kNext, 10> |
1149 IdentifierTypeField; | 1233 IdentifierTypeField; |
1150 typedef BitField<bool, TypeField::kNext, 1> HasRestField; | 1234 typedef BitField<bool, TypeField::kNext, 1> HasRestField; |
| 1235 typedef BitField<bool, TypeField::kNext, 1> HasCoverInitializedNameField; |
1151 | 1236 |
1152 uint32_t code_; | 1237 uint32_t code_; |
1153 }; | 1238 }; |
1154 | 1239 |
1155 | 1240 |
1156 // The pre-parser doesn't need to build lists of expressions, identifiers, or | 1241 // The pre-parser doesn't need to build lists of expressions, identifiers, or |
1157 // the like. | 1242 // the like. |
1158 template <typename T> | 1243 template <typename T> |
1159 class PreParserList { | 1244 class PreParserList { |
1160 public: | 1245 public: |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1305 PreParserExpression NewBinaryOperation(Token::Value op, | 1390 PreParserExpression NewBinaryOperation(Token::Value op, |
1306 PreParserExpression left, | 1391 PreParserExpression left, |
1307 PreParserExpression right, int pos) { | 1392 PreParserExpression right, int pos) { |
1308 return PreParserExpression::BinaryOperation(left, op, right); | 1393 return PreParserExpression::BinaryOperation(left, op, right); |
1309 } | 1394 } |
1310 PreParserExpression NewCompareOperation(Token::Value op, | 1395 PreParserExpression NewCompareOperation(Token::Value op, |
1311 PreParserExpression left, | 1396 PreParserExpression left, |
1312 PreParserExpression right, int pos) { | 1397 PreParserExpression right, int pos) { |
1313 return PreParserExpression::Default(); | 1398 return PreParserExpression::Default(); |
1314 } | 1399 } |
| 1400 PreParserExpression NewRewritableAssignmentExpression( |
| 1401 PreParserExpression expression) { |
| 1402 return expression; |
| 1403 } |
1315 PreParserExpression NewAssignment(Token::Value op, | 1404 PreParserExpression NewAssignment(Token::Value op, |
1316 PreParserExpression left, | 1405 PreParserExpression left, |
1317 PreParserExpression right, | 1406 PreParserExpression right, |
1318 int pos) { | 1407 int pos) { |
1319 return PreParserExpression::Default(); | 1408 return PreParserExpression::Default(); |
1320 } | 1409 } |
| 1410 PreParserExpression NewAssignmentPattern(PreParserExpression pattern, |
| 1411 int pos) { |
| 1412 DCHECK(pattern->IsObjectLiteral() || pattern->IsArrayLiteral()); |
| 1413 return PreParserExpression::AssignmentPattern(); |
| 1414 } |
1321 PreParserExpression NewYield(PreParserExpression generator_object, | 1415 PreParserExpression NewYield(PreParserExpression generator_object, |
1322 PreParserExpression expression, | 1416 PreParserExpression expression, |
1323 Yield::Kind yield_kind, | 1417 Yield::Kind yield_kind, |
1324 int pos) { | 1418 int pos) { |
1325 return PreParserExpression::Default(); | 1419 return PreParserExpression::Default(); |
1326 } | 1420 } |
1327 PreParserExpression NewConditional(PreParserExpression condition, | 1421 PreParserExpression NewConditional(PreParserExpression condition, |
1328 PreParserExpression then_expression, | 1422 PreParserExpression then_expression, |
1329 PreParserExpression else_expression, | 1423 PreParserExpression else_expression, |
1330 int pos) { | 1424 int pos) { |
(...skipping 411 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1742 | 1836 |
1743 inline void MaterializeUnspreadArgumentsLiterals(int count); | 1837 inline void MaterializeUnspreadArgumentsLiterals(int count); |
1744 | 1838 |
1745 inline PreParserExpression SpreadCall(PreParserExpression function, | 1839 inline PreParserExpression SpreadCall(PreParserExpression function, |
1746 PreParserExpressionList args, int pos); | 1840 PreParserExpressionList args, int pos); |
1747 | 1841 |
1748 inline PreParserExpression SpreadCallNew(PreParserExpression function, | 1842 inline PreParserExpression SpreadCallNew(PreParserExpression function, |
1749 PreParserExpressionList args, | 1843 PreParserExpressionList args, |
1750 int pos); | 1844 int pos); |
1751 | 1845 |
| 1846 inline void RewriteDestructuringAssignments() {} |
| 1847 |
| 1848 inline void QueueDestructuringAssignmentForRewriting(PreParserExpression) {} |
| 1849 |
1752 private: | 1850 private: |
1753 PreParser* pre_parser_; | 1851 PreParser* pre_parser_; |
1754 }; | 1852 }; |
1755 | 1853 |
1756 | 1854 |
1757 // Preparsing checks a JavaScript program and emits preparse-data that helps | 1855 // Preparsing checks a JavaScript program and emits preparse-data that helps |
1758 // a later parsing to be faster. | 1856 // a later parsing to be faster. |
1759 // See preparse-data-format.h for the data format. | 1857 // See preparse-data-format.h for the data format. |
1760 | 1858 |
1761 // The PreParser checks that the syntax follows the grammar for JavaScript, | 1859 // The PreParser checks that the syntax follows the grammar for JavaScript, |
(...skipping 625 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2387 MessageTemplate::kParamAfterRest); | 2485 MessageTemplate::kParamAfterRest); |
2388 *ok = false; | 2486 *ok = false; |
2389 return this->EmptyExpression(); | 2487 return this->EmptyExpression(); |
2390 } | 2488 } |
2391 Expect(Token::RPAREN, CHECK_OK); | 2489 Expect(Token::RPAREN, CHECK_OK); |
2392 return factory()->NewSpread(expr, ellipsis_pos); | 2490 return factory()->NewSpread(expr, ellipsis_pos); |
2393 } | 2491 } |
2394 // Heuristically try to detect immediately called functions before | 2492 // Heuristically try to detect immediately called functions before |
2395 // seeing the call parentheses. | 2493 // seeing the call parentheses. |
2396 parenthesized_function_ = (peek() == Token::FUNCTION); | 2494 parenthesized_function_ = (peek() == Token::FUNCTION); |
2397 ExpressionT expr = this->ParseExpression(true, classifier, CHECK_OK); | 2495 ExpressionT expr = this->ParseExpression(true, kIsPossibleArrowFormals, |
| 2496 classifier, CHECK_OK); |
2398 Expect(Token::RPAREN, CHECK_OK); | 2497 Expect(Token::RPAREN, CHECK_OK); |
| 2498 if (peek() != Token::ARROW) { |
| 2499 ValidateExpression(classifier, CHECK_OK); |
| 2500 } |
2399 return expr; | 2501 return expr; |
2400 } | 2502 } |
2401 | 2503 |
2402 case Token::CLASS: { | 2504 case Token::CLASS: { |
2403 BindingPatternUnexpectedToken(classifier); | 2505 BindingPatternUnexpectedToken(classifier); |
2404 Consume(Token::CLASS); | 2506 Consume(Token::CLASS); |
2405 if (!allow_harmony_sloppy() && is_sloppy(language_mode())) { | 2507 if (!allow_harmony_sloppy() && is_sloppy(language_mode())) { |
2406 ReportMessage(MessageTemplate::kSloppyLexical); | 2508 ReportMessage(MessageTemplate::kSloppyLexical); |
2407 *ok = false; | 2509 *ok = false; |
2408 return this->EmptyExpression(); | 2510 return this->EmptyExpression(); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2456 template <class Traits> | 2558 template <class Traits> |
2457 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( | 2559 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( |
2458 bool accept_IN, bool* ok) { | 2560 bool accept_IN, bool* ok) { |
2459 ExpressionClassifier classifier; | 2561 ExpressionClassifier classifier; |
2460 ExpressionT result = ParseExpression(accept_IN, &classifier, CHECK_OK); | 2562 ExpressionT result = ParseExpression(accept_IN, &classifier, CHECK_OK); |
2461 ValidateExpression(&classifier, CHECK_OK); | 2563 ValidateExpression(&classifier, CHECK_OK); |
2462 return result; | 2564 return result; |
2463 } | 2565 } |
2464 | 2566 |
2465 | 2567 |
2466 // Precedence = 1 | |
2467 template <class Traits> | 2568 template <class Traits> |
2468 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( | 2569 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( |
2469 bool accept_IN, ExpressionClassifier* classifier, bool* ok) { | 2570 bool accept_IN, ExpressionClassifier* classifier, bool* ok) { |
| 2571 return ParseExpression(accept_IN, kIsLeftHandSide, classifier, ok); |
| 2572 } |
| 2573 |
| 2574 |
| 2575 template <class Traits> |
| 2576 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( |
| 2577 bool accept_IN, int flags, ExpressionClassifier* classifier, bool* ok) { |
2470 // Expression :: | 2578 // Expression :: |
2471 // AssignmentExpression | 2579 // AssignmentExpression |
2472 // Expression ',' AssignmentExpression | 2580 // Expression ',' AssignmentExpression |
2473 | 2581 |
2474 ExpressionClassifier binding_classifier; | 2582 ExpressionClassifier binding_classifier; |
2475 ExpressionT result = | 2583 ExpressionT result = this->ParseAssignmentExpression( |
2476 this->ParseAssignmentExpression(accept_IN, &binding_classifier, CHECK_OK); | 2584 accept_IN, flags, &binding_classifier, CHECK_OK); |
2477 classifier->Accumulate(binding_classifier, | 2585 classifier->Accumulate(binding_classifier, |
2478 ExpressionClassifier::AllProductions); | 2586 ExpressionClassifier::AllProductions); |
2479 bool is_simple_parameter_list = this->IsIdentifier(result); | 2587 bool is_simple_parameter_list = this->IsIdentifier(result); |
2480 bool seen_rest = false; | 2588 bool seen_rest = false; |
2481 while (peek() == Token::COMMA) { | 2589 while (peek() == Token::COMMA) { |
2482 if (seen_rest) { | 2590 if (seen_rest) { |
2483 // At this point the production can't possibly be valid, but we don't know | 2591 // At this point the production can't possibly be valid, but we don't know |
2484 // which error to signal. | 2592 // which error to signal. |
2485 classifier->RecordArrowFormalParametersError( | 2593 classifier->RecordArrowFormalParametersError( |
2486 scanner()->peek_location(), MessageTemplate::kParamAfterRest); | 2594 scanner()->peek_location(), MessageTemplate::kParamAfterRest); |
2487 } | 2595 } |
2488 Consume(Token::COMMA); | 2596 Consume(Token::COMMA); |
2489 bool is_rest = false; | 2597 bool is_rest = false; |
2490 if (allow_harmony_rest_parameters() && peek() == Token::ELLIPSIS) { | 2598 if (allow_harmony_rest_parameters() && peek() == Token::ELLIPSIS) { |
2491 // 'x, y, ...z' in CoverParenthesizedExpressionAndArrowParameterList only | 2599 // 'x, y, ...z' in CoverParenthesizedExpressionAndArrowParameterList only |
2492 // as the formal parameters of'(x, y, ...z) => foo', and is not itself a | 2600 // as the formal parameters of'(x, y, ...z) => foo', and is not itself a |
2493 // valid expression or binding pattern. | 2601 // valid expression or binding pattern. |
2494 ExpressionUnexpectedToken(classifier); | 2602 ExpressionUnexpectedToken(classifier); |
2495 BindingPatternUnexpectedToken(classifier); | 2603 BindingPatternUnexpectedToken(classifier); |
2496 Consume(Token::ELLIPSIS); | 2604 Consume(Token::ELLIPSIS); |
2497 seen_rest = is_rest = true; | 2605 seen_rest = is_rest = true; |
2498 } | 2606 } |
2499 int pos = position(); | 2607 int pos = position(); |
2500 ExpressionT right = this->ParseAssignmentExpression( | 2608 ExpressionT right = this->ParseAssignmentExpression( |
2501 accept_IN, &binding_classifier, CHECK_OK); | 2609 accept_IN, flags, &binding_classifier, CHECK_OK); |
2502 if (is_rest) right = factory()->NewSpread(right, pos); | 2610 if (is_rest) right = factory()->NewSpread(right, pos); |
2503 is_simple_parameter_list = | 2611 is_simple_parameter_list = |
2504 is_simple_parameter_list && this->IsIdentifier(right); | 2612 is_simple_parameter_list && this->IsIdentifier(right); |
2505 classifier->Accumulate(binding_classifier, | 2613 classifier->Accumulate(binding_classifier, |
2506 ExpressionClassifier::AllProductions); | 2614 ExpressionClassifier::AllProductions); |
2507 result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos); | 2615 result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos); |
2508 } | 2616 } |
2509 if (!is_simple_parameter_list || seen_rest) { | 2617 if (!is_simple_parameter_list || seen_rest) { |
2510 classifier->RecordNonSimpleParameter(); | 2618 classifier->RecordNonSimpleParameter(); |
2511 } | 2619 } |
| 2620 |
2512 return result; | 2621 return result; |
2513 } | 2622 } |
2514 | 2623 |
2515 | 2624 |
2516 template <class Traits> | 2625 template <class Traits> |
2517 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseArrayLiteral( | 2626 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseArrayLiteral( |
2518 ExpressionClassifier* classifier, bool* ok) { | 2627 ExpressionClassifier* classifier, bool* ok) { |
2519 // ArrayLiteral :: | 2628 // ArrayLiteral :: |
2520 // '[' Expression? (',' Expression?)* ']' | 2629 // '[' Expression? (',' Expression?)* ']' |
2521 | 2630 |
2522 int pos = peek_position(); | 2631 int pos = peek_position(); |
2523 typename Traits::Type::ExpressionList values = | 2632 typename Traits::Type::ExpressionList values = |
2524 this->NewExpressionList(4, zone_); | 2633 this->NewExpressionList(4, zone_); |
2525 int first_spread_index = -1; | 2634 int first_spread_index = -1; |
2526 Expect(Token::LBRACK, CHECK_OK); | 2635 Expect(Token::LBRACK, CHECK_OK); |
2527 while (peek() != Token::RBRACK) { | 2636 while (peek() != Token::RBRACK) { |
2528 bool seen_spread = false; | |
2529 ExpressionT elem = this->EmptyExpression(); | 2637 ExpressionT elem = this->EmptyExpression(); |
2530 if (peek() == Token::COMMA) { | 2638 if (peek() == Token::COMMA) { |
2531 if (is_strong(language_mode())) { | 2639 if (is_strong(language_mode())) { |
2532 ReportMessageAt(scanner()->peek_location(), | 2640 ReportMessageAt(scanner()->peek_location(), |
2533 MessageTemplate::kStrongEllision); | 2641 MessageTemplate::kStrongEllision); |
2534 *ok = false; | 2642 *ok = false; |
2535 return this->EmptyExpression(); | 2643 return this->EmptyExpression(); |
2536 } | 2644 } |
2537 elem = this->GetLiteralTheHole(peek_position(), factory()); | 2645 elem = this->GetLiteralTheHole(peek_position(), factory()); |
2538 } else if (peek() == Token::ELLIPSIS) { | 2646 } else if (peek() == Token::ELLIPSIS) { |
2539 int start_pos = peek_position(); | 2647 int start_pos = peek_position(); |
2540 Consume(Token::ELLIPSIS); | 2648 Consume(Token::ELLIPSIS); |
2541 ExpressionT argument = | 2649 ExpressionT argument = |
2542 this->ParseAssignmentExpression(true, classifier, CHECK_OK); | 2650 this->ParseAssignmentExpression(true, classifier, CHECK_OK); |
2543 elem = factory()->NewSpread(argument, start_pos); | 2651 elem = factory()->NewSpread(argument, start_pos); |
2544 seen_spread = true; | 2652 |
2545 if (first_spread_index < 0) { | 2653 if (first_spread_index < 0) { |
2546 first_spread_index = values->length(); | 2654 first_spread_index = values->length(); |
2547 } | 2655 } |
| 2656 |
| 2657 CheckDestructuringElement(argument, classifier, start_pos, |
| 2658 scanner()->location().end_pos); |
| 2659 |
| 2660 if (peek() == Token::COMMA) { |
| 2661 classifier->RecordPatternError( |
| 2662 Scanner::Location(start_pos, scanner()->location().end_pos), |
| 2663 MessageTemplate::kElementAfterRest); |
| 2664 } |
2548 } else { | 2665 } else { |
2549 elem = this->ParseAssignmentExpression(true, classifier, CHECK_OK); | 2666 elem = this->ParseAssignmentExpression(true, kIsPatternElement, |
| 2667 classifier, CHECK_OK); |
| 2668 if (!this->IsValidReferenceExpression(elem) && |
| 2669 !classifier->is_valid_assignment_pattern()) { |
| 2670 classifier->RecordPatternError( |
| 2671 Scanner::Location(pos, scanner()->location().end_pos), |
| 2672 MessageTemplate::kInvalidDestructuringTarget); |
| 2673 } |
2550 } | 2674 } |
2551 values->Add(elem, zone_); | 2675 values->Add(elem, zone_); |
2552 if (peek() != Token::RBRACK) { | 2676 if (peek() != Token::RBRACK) { |
2553 if (seen_spread) { | |
2554 BindingPatternUnexpectedToken(classifier); | |
2555 } | |
2556 Expect(Token::COMMA, CHECK_OK); | 2677 Expect(Token::COMMA, CHECK_OK); |
2557 } | 2678 } |
2558 } | 2679 } |
2559 Expect(Token::RBRACK, CHECK_OK); | 2680 Expect(Token::RBRACK, CHECK_OK); |
2560 | 2681 |
2561 // Update the scope information before the pre-parsing bailout. | 2682 // Update the scope information before the pre-parsing bailout. |
2562 int literal_index = function_state_->NextMaterializedLiteralIndex(); | 2683 int literal_index = function_state_->NextMaterializedLiteralIndex(); |
2563 | 2684 |
2564 return factory()->NewArrayLiteral(values, first_spread_index, literal_index, | 2685 return factory()->NewArrayLiteral(values, first_spread_index, literal_index, |
2565 is_strong(language_mode()), pos); | 2686 is_strong(language_mode()), pos); |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2669 DCHECK(!is_static); | 2790 DCHECK(!is_static); |
2670 | 2791 |
2671 if (peek() == Token::COLON) { | 2792 if (peek() == Token::COLON) { |
2672 // PropertyDefinition | 2793 // PropertyDefinition |
2673 // PropertyName ':' AssignmentExpression | 2794 // PropertyName ':' AssignmentExpression |
2674 if (!*is_computed_name) { | 2795 if (!*is_computed_name) { |
2675 checker->CheckProperty(name_token, kValueProperty, false, false, | 2796 checker->CheckProperty(name_token, kValueProperty, false, false, |
2676 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2797 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
2677 } | 2798 } |
2678 Consume(Token::COLON); | 2799 Consume(Token::COLON); |
| 2800 int pos = peek_position(); |
2679 value = this->ParseAssignmentExpression( | 2801 value = this->ParseAssignmentExpression( |
2680 true, classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2802 true, kIsPatternElement, classifier, |
| 2803 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 2804 |
| 2805 if (!this->IsValidReferenceExpression(value) && |
| 2806 !classifier->is_valid_assignment_pattern()) { |
| 2807 classifier->RecordPatternError( |
| 2808 Scanner::Location(pos, scanner()->location().end_pos), |
| 2809 MessageTemplate::kInvalidDestructuringTarget); |
| 2810 } |
| 2811 |
2681 return factory()->NewObjectLiteralProperty(name_expression, value, false, | 2812 return factory()->NewObjectLiteralProperty(name_expression, value, false, |
2682 *is_computed_name); | 2813 *is_computed_name); |
2683 } | 2814 } |
2684 | 2815 |
2685 if ((is_identifier || is_escaped_keyword) && | 2816 if ((is_identifier || is_escaped_keyword) && |
2686 (peek() == Token::COMMA || peek() == Token::RBRACE || | 2817 (peek() == Token::COMMA || peek() == Token::RBRACE || |
2687 peek() == Token::ASSIGN)) { | 2818 peek() == Token::ASSIGN)) { |
2688 // PropertyDefinition | 2819 // PropertyDefinition |
2689 // IdentifierReference | 2820 // IdentifierReference |
2690 // CoverInitializedName | 2821 // CoverInitializedName |
(...skipping 14 matching lines...) Expand all Loading... |
2705 } | 2836 } |
2706 if (name_token == Token::LET) { | 2837 if (name_token == Token::LET) { |
2707 classifier->RecordLetPatternError( | 2838 classifier->RecordLetPatternError( |
2708 scanner()->location(), MessageTemplate::kLetInLexicalBinding); | 2839 scanner()->location(), MessageTemplate::kLetInLexicalBinding); |
2709 } | 2840 } |
2710 | 2841 |
2711 ExpressionT lhs = this->ExpressionFromIdentifier( | 2842 ExpressionT lhs = this->ExpressionFromIdentifier( |
2712 name, next_beg_pos, next_end_pos, scope_, factory()); | 2843 name, next_beg_pos, next_end_pos, scope_, factory()); |
2713 | 2844 |
2714 if (peek() == Token::ASSIGN) { | 2845 if (peek() == Token::ASSIGN) { |
2715 this->ExpressionUnexpectedToken(classifier); | |
2716 Consume(Token::ASSIGN); | 2846 Consume(Token::ASSIGN); |
2717 ExpressionClassifier rhs_classifier; | 2847 ExpressionClassifier rhs_classifier; |
2718 ExpressionT rhs = this->ParseAssignmentExpression( | 2848 ExpressionT rhs = this->ParseAssignmentExpression( |
2719 true, &rhs_classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2849 true, &rhs_classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
2720 classifier->Accumulate(rhs_classifier, | 2850 classifier->Accumulate(rhs_classifier, |
2721 ExpressionClassifier::ExpressionProductions); | 2851 ExpressionClassifier::ExpressionProductions); |
2722 value = factory()->NewAssignment(Token::ASSIGN, lhs, rhs, | 2852 value = factory()->NewAssignment(Token::ASSIGN, lhs, rhs, |
2723 RelocInfo::kNoPosition); | 2853 RelocInfo::kNoPosition); |
| 2854 classifier->RecordCoverInitializedNameError( |
| 2855 Scanner::Location(next_beg_pos, scanner()->location().end_pos), |
| 2856 MessageTemplate::kInvalidCoverInitializedName); |
2724 } else { | 2857 } else { |
2725 value = lhs; | 2858 value = lhs; |
2726 } | 2859 } |
2727 | 2860 |
2728 return factory()->NewObjectLiteralProperty( | 2861 return factory()->NewObjectLiteralProperty( |
2729 name_expression, value, ObjectLiteralProperty::COMPUTED, false, | 2862 name_expression, value, ObjectLiteralProperty::COMPUTED, false, |
2730 false); | 2863 false); |
2731 } | 2864 } |
2732 } | 2865 } |
2733 | 2866 |
2734 if (in_class && escaped_static && !is_static) { | 2867 if (in_class && escaped_static && !is_static) { |
2735 ReportUnexpectedTokenAt(scanner()->location(), name_token); | 2868 ReportUnexpectedTokenAt(scanner()->location(), name_token); |
2736 *ok = false; | 2869 *ok = false; |
2737 return this->EmptyObjectLiteralProperty(); | 2870 return this->EmptyObjectLiteralProperty(); |
2738 } | 2871 } |
2739 | 2872 |
2740 BindingPatternUnexpectedToken(classifier); | 2873 // Method definitions are never valid in patterns. |
| 2874 classifier->RecordPatternError( |
| 2875 Scanner::Location(next_beg_pos, scanner()->location().end_pos), |
| 2876 MessageTemplate::kInvalidDestructuringTarget); |
2741 | 2877 |
2742 if (is_generator || peek() == Token::LPAREN) { | 2878 if (is_generator || peek() == Token::LPAREN) { |
2743 // MethodDefinition | 2879 // MethodDefinition |
2744 // PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' | 2880 // PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' |
2745 // '*' PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' | 2881 // '*' PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' |
2746 if (!*is_computed_name) { | 2882 if (!*is_computed_name) { |
2747 checker->CheckProperty(name_token, kMethodProperty, is_static, | 2883 checker->CheckProperty(name_token, kMethodProperty, is_static, |
2748 is_generator, | 2884 is_generator, |
2749 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2885 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
2750 } | 2886 } |
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2954 // the parser and preparser | 3090 // the parser and preparser |
2955 Traits::MaterializeUnspreadArgumentsLiterals(unspread_sequences_count); | 3091 Traits::MaterializeUnspreadArgumentsLiterals(unspread_sequences_count); |
2956 } | 3092 } |
2957 | 3093 |
2958 return result; | 3094 return result; |
2959 } | 3095 } |
2960 | 3096 |
2961 // Precedence = 2 | 3097 // Precedence = 2 |
2962 template <class Traits> | 3098 template <class Traits> |
2963 typename ParserBase<Traits>::ExpressionT | 3099 typename ParserBase<Traits>::ExpressionT |
2964 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, | 3100 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, int flags, |
2965 ExpressionClassifier* classifier, | 3101 ExpressionClassifier* classifier, |
2966 bool* ok) { | 3102 bool* ok) { |
2967 // AssignmentExpression :: | 3103 // AssignmentExpression :: |
2968 // ConditionalExpression | 3104 // ConditionalExpression |
2969 // ArrowFunction | 3105 // ArrowFunction |
2970 // YieldExpression | 3106 // YieldExpression |
2971 // LeftHandSideExpression AssignmentOperator AssignmentExpression | 3107 // LeftHandSideExpression AssignmentOperator AssignmentExpression |
2972 | 3108 bool is_rhs = flags & kIsRightHandSide; |
| 3109 bool is_pattern_element = flags & kIsPatternElement; |
| 3110 bool is_destructuring_assignment = false; |
| 3111 bool is_arrow_formals = flags & kIsPossibleArrowFormals; |
2973 int lhs_beg_pos = peek_position(); | 3112 int lhs_beg_pos = peek_position(); |
2974 | 3113 |
2975 if (peek() == Token::YIELD && is_generator()) { | 3114 if (peek() == Token::YIELD && is_generator()) { |
2976 return this->ParseYieldExpression(classifier, ok); | 3115 return this->ParseYieldExpression(classifier, ok); |
2977 } | 3116 } |
2978 | 3117 |
2979 if (fni_ != NULL) fni_->Enter(); | 3118 if (fni_ != NULL) fni_->Enter(); |
2980 ParserBase<Traits>::Checkpoint checkpoint(this); | 3119 ParserBase<Traits>::Checkpoint checkpoint(this); |
2981 ExpressionClassifier arrow_formals_classifier(classifier->duplicate_finder()); | 3120 ExpressionClassifier arrow_formals_classifier(classifier->duplicate_finder()); |
2982 bool parenthesized_formals = peek() == Token::LPAREN; | 3121 bool parenthesized_formals = peek() == Token::LPAREN; |
(...skipping 25 matching lines...) Expand all Loading... |
3008 | 3147 |
3009 checkpoint.Restore(¶meters.materialized_literals_count); | 3148 checkpoint.Restore(¶meters.materialized_literals_count); |
3010 | 3149 |
3011 scope->set_start_position(lhs_beg_pos); | 3150 scope->set_start_position(lhs_beg_pos); |
3012 if (duplicate_loc.IsValid()) { | 3151 if (duplicate_loc.IsValid()) { |
3013 arrow_formals_classifier.RecordDuplicateFormalParameterError( | 3152 arrow_formals_classifier.RecordDuplicateFormalParameterError( |
3014 duplicate_loc); | 3153 duplicate_loc); |
3015 } | 3154 } |
3016 expression = this->ParseArrowFunctionLiteral( | 3155 expression = this->ParseArrowFunctionLiteral( |
3017 accept_IN, parameters, arrow_formals_classifier, CHECK_OK); | 3156 accept_IN, parameters, arrow_formals_classifier, CHECK_OK); |
| 3157 if (is_pattern_element) { |
| 3158 classifier->RecordPatternError( |
| 3159 Scanner::Location(lhs_beg_pos, scanner()->location().end_pos), |
| 3160 MessageTemplate::kInvalidDestructuringTarget); |
| 3161 } |
3018 return expression; | 3162 return expression; |
3019 } | 3163 } |
3020 | 3164 |
| 3165 if (this->IsValidReferenceExpression(expression)) { |
| 3166 arrow_formals_classifier.ForgiveAssignmentPatternError(); |
| 3167 } |
| 3168 |
3021 // "expression" was not itself an arrow function parameter list, but it might | 3169 // "expression" was not itself an arrow function parameter list, but it might |
3022 // form part of one. Propagate speculative formal parameter error locations. | 3170 // form part of one. Propagate speculative formal parameter error locations. |
3023 classifier->Accumulate(arrow_formals_classifier, | 3171 classifier->Accumulate( |
3024 ExpressionClassifier::StandardProductions | | 3172 arrow_formals_classifier, |
3025 ExpressionClassifier::FormalParametersProductions); | 3173 ExpressionClassifier::StandardProductions | |
| 3174 ExpressionClassifier::FormalParametersProductions | |
| 3175 ExpressionClassifier::CoverInitializedNameProduction); |
| 3176 |
| 3177 bool maybe_pattern = |
| 3178 expression->IsObjectLiteral() || expression->IsArrayLiteral(); |
| 3179 // bool binding_pattern = |
| 3180 // allow_harmony_destructuring_bind() && maybe_pattern && !is_rhs; |
3026 | 3181 |
3027 if (!Token::IsAssignmentOp(peek())) { | 3182 if (!Token::IsAssignmentOp(peek())) { |
3028 if (fni_ != NULL) fni_->Leave(); | 3183 if (fni_ != NULL) fni_->Leave(); |
3029 // Parsed conditional expression only (no assignment). | 3184 // Parsed conditional expression only (no assignment). |
| 3185 if (is_pattern_element && !this->IsValidReferenceExpression(expression) && |
| 3186 !maybe_pattern) { |
| 3187 classifier->RecordPatternError( |
| 3188 Scanner::Location(lhs_beg_pos, scanner()->location().end_pos), |
| 3189 MessageTemplate::kInvalidDestructuringTarget); |
| 3190 } else if (is_rhs && maybe_pattern) { |
| 3191 ValidateExpression(classifier, CHECK_OK); |
| 3192 } |
| 3193 |
3030 return expression; | 3194 return expression; |
3031 } | 3195 } |
3032 | 3196 |
3033 if (!(allow_harmony_destructuring_bind() || | 3197 if (!(allow_harmony_destructuring_bind() || |
3034 allow_harmony_default_parameters())) { | 3198 allow_harmony_default_parameters())) { |
3035 BindingPatternUnexpectedToken(classifier); | 3199 BindingPatternUnexpectedToken(classifier); |
3036 } | 3200 } |
3037 | 3201 |
3038 expression = this->CheckAndRewriteReferenceExpression( | 3202 if (allow_harmony_destructuring_assignment() && maybe_pattern && |
3039 expression, lhs_beg_pos, scanner()->location().end_pos, | 3203 peek() == Token::ASSIGN) { |
3040 MessageTemplate::kInvalidLhsInAssignment, CHECK_OK); | 3204 classifier->ForgiveCoverInitializedNameError(); |
| 3205 ValidateAssignmentPattern(classifier, CHECK_OK); |
| 3206 is_destructuring_assignment = true; |
| 3207 } else if (is_arrow_formals) { |
| 3208 expression = this->ClassifyAndRewriteReferenceExpression( |
| 3209 classifier, expression, lhs_beg_pos, scanner()->location().end_pos, |
| 3210 MessageTemplate::kInvalidLhsInAssignment); |
| 3211 } else { |
| 3212 expression = this->CheckAndRewriteReferenceExpression( |
| 3213 expression, lhs_beg_pos, scanner()->location().end_pos, |
| 3214 MessageTemplate::kInvalidLhsInAssignment, CHECK_OK); |
| 3215 } |
| 3216 |
3041 expression = this->MarkExpressionAsAssigned(expression); | 3217 expression = this->MarkExpressionAsAssigned(expression); |
3042 | 3218 |
3043 Token::Value op = Next(); // Get assignment operator. | 3219 Token::Value op = Next(); // Get assignment operator. |
3044 if (op != Token::ASSIGN) { | 3220 if (op != Token::ASSIGN) { |
3045 classifier->RecordBindingPatternError(scanner()->location(), | 3221 classifier->RecordBindingPatternError(scanner()->location(), |
3046 MessageTemplate::kUnexpectedToken, | 3222 MessageTemplate::kUnexpectedToken, |
3047 Token::String(op)); | 3223 Token::String(op)); |
3048 } | 3224 } |
3049 int pos = position(); | 3225 int pos = position(); |
3050 | 3226 |
3051 ExpressionClassifier rhs_classifier; | 3227 ExpressionClassifier rhs_classifier; |
3052 ExpressionT right = | 3228 |
3053 this->ParseAssignmentExpression(accept_IN, &rhs_classifier, CHECK_OK); | 3229 int rhs_flags = flags; |
3054 classifier->Accumulate(rhs_classifier, | 3230 rhs_flags &= ~(kIsPatternElement | kIsPossibleArrowFormals); |
3055 ExpressionClassifier::ExpressionProductions); | 3231 rhs_flags |= kIsRightHandSide; |
| 3232 ExpressionT right = this->ParseAssignmentExpression( |
| 3233 accept_IN, rhs_flags, &rhs_classifier, CHECK_OK); |
| 3234 classifier->Accumulate( |
| 3235 rhs_classifier, ExpressionClassifier::ExpressionProductions | |
| 3236 ExpressionClassifier::CoverInitializedNameProduction); |
3056 | 3237 |
3057 // TODO(1231235): We try to estimate the set of properties set by | 3238 // TODO(1231235): We try to estimate the set of properties set by |
3058 // constructors. We define a new property whenever there is an | 3239 // constructors. We define a new property whenever there is an |
3059 // assignment to a property of 'this'. We should probably only add | 3240 // assignment to a property of 'this'. We should probably only add |
3060 // properties if we haven't seen them before. Otherwise we'll | 3241 // properties if we haven't seen them before. Otherwise we'll |
3061 // probably overestimate the number of properties. | 3242 // probably overestimate the number of properties. |
3062 if (op == Token::ASSIGN && this->IsThisProperty(expression)) { | 3243 if (op == Token::ASSIGN && this->IsThisProperty(expression)) { |
3063 function_state_->AddProperty(); | 3244 function_state_->AddProperty(); |
3064 } | 3245 } |
3065 | 3246 |
3066 this->CheckAssigningFunctionLiteralToProperty(expression, right); | 3247 this->CheckAssigningFunctionLiteralToProperty(expression, right); |
3067 | 3248 |
3068 if (fni_ != NULL) { | 3249 if (fni_ != NULL) { |
3069 // Check if the right hand side is a call to avoid inferring a | 3250 // Check if the right hand side is a call to avoid inferring a |
3070 // name if we're dealing with "a = function(){...}();"-like | 3251 // name if we're dealing with "a = function(){...}();"-like |
3071 // expression. | 3252 // expression. |
3072 if ((op == Token::INIT || op == Token::ASSIGN) && | 3253 if ((op == Token::INIT || op == Token::ASSIGN) && |
3073 (!right->IsCall() && !right->IsCallNew())) { | 3254 (!right->IsCall() && !right->IsCallNew())) { |
3074 fni_->Infer(); | 3255 fni_->Infer(); |
3075 } else { | 3256 } else { |
3076 fni_->RemoveLastFunction(); | 3257 fni_->RemoveLastFunction(); |
3077 } | 3258 } |
3078 fni_->Leave(); | 3259 fni_->Leave(); |
3079 } | 3260 } |
3080 | 3261 |
3081 return factory()->NewAssignment(op, expression, right, pos); | 3262 ExpressionT result = factory()->NewAssignment(op, expression, right, pos); |
| 3263 |
| 3264 if (is_destructuring_assignment) { |
| 3265 result = factory()->NewRewritableAssignmentExpression(result); |
| 3266 Traits::QueueDestructuringAssignmentForRewriting(result); |
| 3267 } |
| 3268 |
| 3269 return result; |
3082 } | 3270 } |
3083 | 3271 |
3084 template <class Traits> | 3272 template <class Traits> |
3085 typename ParserBase<Traits>::ExpressionT | 3273 typename ParserBase<Traits>::ExpressionT |
3086 ParserBase<Traits>::ParseYieldExpression(ExpressionClassifier* classifier, | 3274 ParserBase<Traits>::ParseYieldExpression(ExpressionClassifier* classifier, |
3087 bool* ok) { | 3275 bool* ok) { |
3088 // YieldExpression :: | 3276 // YieldExpression :: |
3089 // 'yield' ([no line terminator] '*'? AssignmentExpression)? | 3277 // 'yield' ([no line terminator] '*'? AssignmentExpression)? |
3090 int pos = peek_position(); | 3278 int pos = peek_position(); |
3091 BindingPatternUnexpectedToken(classifier); | 3279 BindingPatternUnexpectedToken(classifier); |
(...skipping 942 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4034 allow_duplicate_parameters, CHECK_OK); | 4222 allow_duplicate_parameters, CHECK_OK); |
4035 | 4223 |
4036 // Validate strict mode. | 4224 // Validate strict mode. |
4037 if (is_strict(language_mode())) { | 4225 if (is_strict(language_mode())) { |
4038 CheckStrictOctalLiteral(formal_parameters.scope->start_position(), | 4226 CheckStrictOctalLiteral(formal_parameters.scope->start_position(), |
4039 scanner()->location().end_pos, CHECK_OK); | 4227 scanner()->location().end_pos, CHECK_OK); |
4040 } | 4228 } |
4041 if (is_strict(language_mode()) || allow_harmony_sloppy()) { | 4229 if (is_strict(language_mode()) || allow_harmony_sloppy()) { |
4042 this->CheckConflictingVarDeclarations(formal_parameters.scope, CHECK_OK); | 4230 this->CheckConflictingVarDeclarations(formal_parameters.scope, CHECK_OK); |
4043 } | 4231 } |
| 4232 |
| 4233 Traits::RewriteDestructuringAssignments(); |
4044 } | 4234 } |
4045 | 4235 |
4046 FunctionLiteralT function_literal = factory()->NewFunctionLiteral( | 4236 FunctionLiteralT function_literal = factory()->NewFunctionLiteral( |
4047 this->EmptyIdentifierString(), ast_value_factory(), | 4237 this->EmptyIdentifierString(), ast_value_factory(), |
4048 formal_parameters.scope, body, materialized_literal_count, | 4238 formal_parameters.scope, body, materialized_literal_count, |
4049 expected_property_count, num_parameters, | 4239 expected_property_count, num_parameters, |
4050 FunctionLiteral::kNoDuplicateParameters, | 4240 FunctionLiteral::kNoDuplicateParameters, |
4051 FunctionLiteral::ANONYMOUS_EXPRESSION, FunctionLiteral::kIsFunction, | 4241 FunctionLiteral::ANONYMOUS_EXPRESSION, FunctionLiteral::kIsFunction, |
4052 FunctionLiteral::kShouldLazyCompile, FunctionKind::kArrowFunction, | 4242 FunctionLiteral::kShouldLazyCompile, FunctionKind::kArrowFunction, |
4053 formal_parameters.scope->start_position()); | 4243 formal_parameters.scope->start_position()); |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4165 return this->CheckAndRewriteReferenceExpression(expression, beg_pos, end_pos, | 4355 return this->CheckAndRewriteReferenceExpression(expression, beg_pos, end_pos, |
4166 message, kReferenceError, ok); | 4356 message, kReferenceError, ok); |
4167 } | 4357 } |
4168 | 4358 |
4169 | 4359 |
4170 template <typename Traits> | 4360 template <typename Traits> |
4171 typename ParserBase<Traits>::ExpressionT | 4361 typename ParserBase<Traits>::ExpressionT |
4172 ParserBase<Traits>::CheckAndRewriteReferenceExpression( | 4362 ParserBase<Traits>::CheckAndRewriteReferenceExpression( |
4173 ExpressionT expression, int beg_pos, int end_pos, | 4363 ExpressionT expression, int beg_pos, int end_pos, |
4174 MessageTemplate::Template message, ParseErrorType type, bool* ok) { | 4364 MessageTemplate::Template message, ParseErrorType type, bool* ok) { |
| 4365 ExpressionClassifier classifier; |
| 4366 ExpressionT result = ClassifyAndRewriteReferenceExpression( |
| 4367 &classifier, expression, beg_pos, end_pos, message, type); |
| 4368 ValidateExpression(&classifier, ok); |
| 4369 if (!*ok) return this->EmptyExpression(); |
| 4370 return result; |
| 4371 } |
| 4372 |
| 4373 |
| 4374 template <typename Traits> |
| 4375 typename ParserBase<Traits>::ExpressionT |
| 4376 ParserBase<Traits>::ClassifyAndRewriteReferenceExpression( |
| 4377 ExpressionClassifier* classifier, ExpressionT expression, int beg_pos, |
| 4378 int end_pos, MessageTemplate::Template message, ParseErrorType type) { |
4175 Scanner::Location location(beg_pos, end_pos); | 4379 Scanner::Location location(beg_pos, end_pos); |
4176 if (this->IsIdentifier(expression)) { | 4380 if (this->IsIdentifier(expression)) { |
4177 if (is_strict(language_mode()) && | 4381 if (is_strict(language_mode()) && |
4178 this->IsEvalOrArguments(this->AsIdentifier(expression))) { | 4382 this->IsEvalOrArguments(this->AsIdentifier(expression))) { |
4179 this->ReportMessageAt(location, MessageTemplate::kStrictEvalArguments, | 4383 classifier->RecordExpressionError( |
4180 kSyntaxError); | 4384 location, MessageTemplate::kStrictEvalArguments, kSyntaxError); |
4181 *ok = false; | 4385 return expression; |
4182 return this->EmptyExpression(); | |
4183 } | 4386 } |
4184 if (is_strong(language_mode()) && | 4387 if (is_strong(language_mode()) && |
4185 this->IsUndefined(this->AsIdentifier(expression))) { | 4388 this->IsUndefined(this->AsIdentifier(expression))) { |
4186 this->ReportMessageAt(location, MessageTemplate::kStrongUndefined, | 4389 classifier->RecordExpressionError( |
4187 kSyntaxError); | 4390 location, MessageTemplate::kStrongUndefined, kSyntaxError); |
4188 *ok = false; | 4391 return expression; |
4189 return this->EmptyExpression(); | |
4190 } | 4392 } |
4191 } | 4393 } |
4192 if (expression->IsValidReferenceExpression()) { | 4394 if (expression->IsValidReferenceExpression()) { |
4193 return expression; | 4395 return expression; |
4194 } else if (expression->IsCall()) { | 4396 } else if (expression->IsCall()) { |
4195 // If it is a call, make it a runtime error for legacy web compatibility. | 4397 // If it is a call, make it a runtime error for legacy web compatibility. |
4196 // Rewrite `expr' to `expr[throw ReferenceError]'. | 4398 // Rewrite `expr' to `expr[throw ReferenceError]'. |
4197 int pos = location.beg_pos; | 4399 int pos = location.beg_pos; |
4198 ExpressionT error = this->NewThrowReferenceError(message, pos); | 4400 ExpressionT error = this->NewThrowReferenceError(message, pos); |
4199 return factory()->NewProperty(expression, error, pos); | 4401 return factory()->NewProperty(expression, error, pos); |
4200 } else { | 4402 } else { |
4201 this->ReportMessageAt(location, message, type); | 4403 classifier->RecordExpressionError(location, message, type); |
4202 *ok = false; | 4404 return expression; |
4203 return this->EmptyExpression(); | |
4204 } | 4405 } |
4205 } | 4406 } |
4206 | 4407 |
| 4408 |
| 4409 template <typename Traits> |
| 4410 bool ParserBase<Traits>::IsValidReferenceExpression(ExpressionT expression) { |
| 4411 return this->IsAssignableIdentifier(expression) || expression->IsProperty(); |
| 4412 } |
| 4413 |
| 4414 |
| 4415 template <typename Traits> |
| 4416 void ParserBase<Traits>::CheckDestructuringElement( |
| 4417 ExpressionT expression, ExpressionClassifier* classifier, int begin, |
| 4418 int end) { |
| 4419 static const MessageTemplate::Template message = |
| 4420 MessageTemplate::kInvalidDestructuringTarget; |
| 4421 if (!this->IsAssignableIdentifier(expression)) { |
| 4422 const Scanner::Location location(begin, end); |
| 4423 classifier->RecordBindingPatternError(location, message); |
| 4424 if (!expression->IsProperty() && |
| 4425 !(expression->IsObjectLiteral() || expression->IsArrayLiteral())) { |
| 4426 classifier->RecordAssignmentPatternError(location, message); |
| 4427 } |
| 4428 } |
| 4429 } |
| 4430 |
4207 | 4431 |
4208 #undef CHECK_OK | 4432 #undef CHECK_OK |
4209 #undef CHECK_OK_CUSTOM | 4433 #undef CHECK_OK_CUSTOM |
4210 | 4434 |
4211 | 4435 |
4212 template <typename Traits> | 4436 template <typename Traits> |
4213 void ParserBase<Traits>::ObjectLiteralChecker::CheckProperty( | 4437 void ParserBase<Traits>::ObjectLiteralChecker::CheckProperty( |
4214 Token::Value property, PropertyKind type, bool is_static, bool is_generator, | 4438 Token::Value property, PropertyKind type, bool is_static, bool is_generator, |
4215 bool* ok) { | 4439 bool* ok) { |
4216 DCHECK(!is_static); | 4440 DCHECK(!is_static); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4259 return; | 4483 return; |
4260 } | 4484 } |
4261 has_seen_constructor_ = true; | 4485 has_seen_constructor_ = true; |
4262 return; | 4486 return; |
4263 } | 4487 } |
4264 } | 4488 } |
4265 } // namespace internal | 4489 } // namespace internal |
4266 } // namespace v8 | 4490 } // namespace v8 |
4267 | 4491 |
4268 #endif // V8_PARSING_PREPARSER_H | 4492 #endif // V8_PARSING_PREPARSER_H |
OLD | NEW |