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

Side by Side Diff: src/preparser.h

Issue 1309813007: [es6] implement destructuring assignment (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: An implementation Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef V8_PREPARSER_H 5 #ifndef V8_PREPARSER_H
6 #define V8_PREPARSER_H 6 #define V8_PREPARSER_H
7 7
8 #include "src/bailout-reason.h" 8 #include "src/bailout-reason.h"
9 #include "src/expression-classifier.h" 9 #include "src/expression-classifier.h"
10 #include "src/func-name-inferrer.h" 10 #include "src/func-name-inferrer.h"
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
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_(false), 116 allow_harmony_destructuring_(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); 133 ALLOW_ACCESSORS(harmony_destructuring);
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
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
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_;
adamk 2015/11/20 22:42:59 Why does ParserBase need this List? Couldn't it ju
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
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 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 kSyntaxError);
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 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
686 bool* is_static, bool* is_computed_name, 723 bool* is_static, bool* is_computed_name,
687 ExpressionClassifier* classifier, bool* ok); 724 ExpressionClassifier* classifier, bool* ok);
688 ExpressionT ParseObjectLiteral(ExpressionClassifier* classifier, bool* ok); 725 ExpressionT ParseObjectLiteral(ExpressionClassifier* classifier, bool* ok);
689 ObjectLiteralPropertyT ParsePropertyDefinition( 726 ObjectLiteralPropertyT ParsePropertyDefinition(
690 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, 727 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends,
691 bool is_static, bool* is_computed_name, bool* has_seen_constructor, 728 bool is_static, bool* is_computed_name, bool* has_seen_constructor,
692 ExpressionClassifier* classifier, bool* ok); 729 ExpressionClassifier* classifier, bool* ok);
693 typename Traits::Type::ExpressionList ParseArguments( 730 typename Traits::Type::ExpressionList ParseArguments(
694 Scanner::Location* first_spread_pos, ExpressionClassifier* classifier, 731 Scanner::Location* first_spread_pos, ExpressionClassifier* classifier,
695 bool* ok); 732 bool* ok);
733
734 enum AssignmentExpressionFlags {
735 kIsLeftHandSide = 0,
736 kIsRightHandSide = 1 << 0,
737 kIsPatternElement = 1 << 1
738 };
739
740 ExpressionT ParseAssignmentExpression(bool accept_IN, int flags,
741 ExpressionClassifier* classifier,
742 bool* ok);
696 ExpressionT ParseAssignmentExpression(bool accept_IN, 743 ExpressionT ParseAssignmentExpression(bool accept_IN,
697 ExpressionClassifier* classifier, 744 ExpressionClassifier* classifier,
698 bool* ok); 745 bool* ok) {
746 return ParseAssignmentExpression(accept_IN, kIsLeftHandSide, classifier,
747 ok);
748 }
699 ExpressionT ParseYieldExpression(ExpressionClassifier* classifier, bool* ok); 749 ExpressionT ParseYieldExpression(ExpressionClassifier* classifier, bool* ok);
700 ExpressionT ParseConditionalExpression(bool accept_IN, 750 ExpressionT ParseConditionalExpression(bool accept_IN,
701 ExpressionClassifier* classifier, 751 ExpressionClassifier* classifier,
702 bool* ok); 752 bool* ok);
703 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, 753 ExpressionT ParseBinaryExpression(int prec, bool accept_IN,
704 ExpressionClassifier* classifier, bool* ok); 754 ExpressionClassifier* classifier, bool* ok);
705 ExpressionT ParseUnaryExpression(ExpressionClassifier* classifier, bool* ok); 755 ExpressionT ParseUnaryExpression(ExpressionClassifier* classifier, bool* ok);
706 ExpressionT ParsePostfixExpression(ExpressionClassifier* classifier, 756 ExpressionT ParsePostfixExpression(ExpressionClassifier* classifier,
707 bool* ok); 757 bool* ok);
708 ExpressionT ParseLeftHandSideExpression(ExpressionClassifier* classifier, 758 ExpressionT ParseLeftHandSideExpression(ExpressionClassifier* classifier,
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
740 // Checks if the expression is a valid reference expression (e.g., on the 790 // Checks if the expression is a valid reference expression (e.g., on the
741 // left-hand side of assignments). Although ruled out by ECMA as early errors, 791 // left-hand side of assignments). Although ruled out by ECMA as early errors,
742 // we allow calls for web compatibility and rewrite them to a runtime throw. 792 // we allow calls for web compatibility and rewrite them to a runtime throw.
743 ExpressionT CheckAndRewriteReferenceExpression( 793 ExpressionT CheckAndRewriteReferenceExpression(
744 ExpressionT expression, int beg_pos, int end_pos, 794 ExpressionT expression, int beg_pos, int end_pos,
745 MessageTemplate::Template message, bool* ok); 795 MessageTemplate::Template message, bool* ok);
746 ExpressionT CheckAndRewriteReferenceExpression( 796 ExpressionT CheckAndRewriteReferenceExpression(
747 ExpressionT expression, int beg_pos, int end_pos, 797 ExpressionT expression, int beg_pos, int end_pos,
748 MessageTemplate::Template message, ParseErrorType type, bool* ok); 798 MessageTemplate::Template message, ParseErrorType type, bool* ok);
749 799
800 bool IsValidReferenceExpression(ExpressionT expression);
801
802 bool IsAssignableIdentifier(ExpressionT expression) {
803 if (!Traits::IsIdentifier(expression)) return false;
804 if (is_strict(language_mode()) &&
805 Traits::IsEvalOrArguments(Traits::AsIdentifier(expression))) {
806 return false;
807 }
808 if (is_strong(language_mode()) &&
809 Traits::IsUndefined(Traits::AsIdentifier(expression))) {
810 return false;
811 }
812 return true;
813 }
814
750 // Used to validate property names in object literals and class literals 815 // Used to validate property names in object literals and class literals
751 enum PropertyKind { 816 enum PropertyKind {
752 kAccessorProperty, 817 kAccessorProperty,
753 kValueProperty, 818 kValueProperty,
754 kMethodProperty 819 kMethodProperty
755 }; 820 };
756 821
757 class ObjectLiteralCheckerBase { 822 class ObjectLiteralCheckerBase {
758 public: 823 public:
759 explicit ObjectLiteralCheckerBase(ParserBase* parser) : parser_(parser) {} 824 explicit ObjectLiteralCheckerBase(ParserBase* parser) : parser_(parser) {}
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
828 bool stack_overflow_; 893 bool stack_overflow_;
829 894
830 bool allow_lazy_; 895 bool allow_lazy_;
831 bool allow_natives_; 896 bool allow_natives_;
832 bool allow_harmony_sloppy_; 897 bool allow_harmony_sloppy_;
833 bool allow_harmony_sloppy_function_; 898 bool allow_harmony_sloppy_function_;
834 bool allow_harmony_sloppy_let_; 899 bool allow_harmony_sloppy_let_;
835 bool allow_harmony_rest_parameters_; 900 bool allow_harmony_rest_parameters_;
836 bool allow_harmony_default_parameters_; 901 bool allow_harmony_default_parameters_;
837 bool allow_harmony_destructuring_; 902 bool allow_harmony_destructuring_;
903 bool allow_harmony_destructuring_assignment_;
838 bool allow_strong_mode_; 904 bool allow_strong_mode_;
839 bool allow_legacy_const_; 905 bool allow_legacy_const_;
840 bool allow_harmony_do_expressions_; 906 bool allow_harmony_do_expressions_;
841 }; 907 };
842 908
843 909
844 class PreParserIdentifier { 910 class PreParserIdentifier {
845 public: 911 public:
846 PreParserIdentifier() : type_(kUnknownIdentifier) {} 912 PreParserIdentifier() : type_(kUnknownIdentifier) {}
847 static PreParserIdentifier Default() { 913 static PreParserIdentifier Default() {
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
940 1006
941 static PreParserExpression BinaryOperation(PreParserExpression left, 1007 static PreParserExpression BinaryOperation(PreParserExpression left,
942 Token::Value op, 1008 Token::Value op,
943 PreParserExpression right) { 1009 PreParserExpression right) {
944 return PreParserExpression( 1010 return PreParserExpression(
945 TypeField::encode(kBinaryOperationExpression) | 1011 TypeField::encode(kBinaryOperationExpression) |
946 HasRestField::encode(op == Token::COMMA && 1012 HasRestField::encode(op == Token::COMMA &&
947 right->IsSpreadExpression())); 1013 right->IsSpreadExpression()));
948 } 1014 }
949 1015
1016 static PreParserExpression AssignmentPattern() {
1017 return PreParserExpression(TypeField::encode(kExpression) |
1018 ExpressionTypeField::encode(kAssignmentPattern));
1019 }
1020
950 static PreParserExpression ObjectLiteral() { 1021 static PreParserExpression ObjectLiteral() {
951 return PreParserExpression(TypeField::encode(kObjectLiteralExpression)); 1022 return PreParserExpression(TypeField::encode(kObjectLiteralExpression));
952 } 1023 }
953 1024
954 static PreParserExpression ArrayLiteral() { 1025 static PreParserExpression ArrayLiteral() {
955 return PreParserExpression(TypeField::encode(kArrayLiteralExpression)); 1026 return PreParserExpression(TypeField::encode(kArrayLiteralExpression));
956 } 1027 }
957 1028
958 static PreParserExpression StringLiteral() { 1029 static PreParserExpression StringLiteral() {
959 return PreParserExpression(TypeField::encode(kStringLiteralExpression)); 1030 return PreParserExpression(TypeField::encode(kStringLiteralExpression));
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
1005 1076
1006 bool IsIdentifier() const { 1077 bool IsIdentifier() const {
1007 return TypeField::decode(code_) == kIdentifierExpression; 1078 return TypeField::decode(code_) == kIdentifierExpression;
1008 } 1079 }
1009 1080
1010 PreParserIdentifier AsIdentifier() const { 1081 PreParserIdentifier AsIdentifier() const {
1011 DCHECK(IsIdentifier()); 1082 DCHECK(IsIdentifier());
1012 return PreParserIdentifier(IdentifierTypeField::decode(code_)); 1083 return PreParserIdentifier(IdentifierTypeField::decode(code_));
1013 } 1084 }
1014 1085
1086 bool IsAssignmentPattern() const {
1087 return TypeField::decode(code_) == kExpression &&
1088 ExpressionTypeField::decode(code_) == kAssignmentPattern;
1089 }
1090
1015 bool IsObjectLiteral() const { 1091 bool IsObjectLiteral() const {
1016 return TypeField::decode(code_) == kObjectLiteralExpression; 1092 return TypeField::decode(code_) == kObjectLiteralExpression;
1017 } 1093 }
1018 1094
1019 bool IsArrayLiteral() const { 1095 bool IsArrayLiteral() const {
1020 return TypeField::decode(code_) == kArrayLiteralExpression; 1096 return TypeField::decode(code_) == kArrayLiteralExpression;
1021 } 1097 }
1022 1098
1023 bool IsStringLiteral() const { 1099 bool IsStringLiteral() const {
1024 return TypeField::decode(code_) == kStringLiteralExpression; 1100 return TypeField::decode(code_) == kStringLiteralExpression;
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
1112 kObjectLiteralExpression, 1188 kObjectLiteralExpression,
1113 kArrayLiteralExpression 1189 kArrayLiteralExpression
1114 }; 1190 };
1115 1191
1116 enum ExpressionType { 1192 enum ExpressionType {
1117 kThisExpression, 1193 kThisExpression,
1118 kThisPropertyExpression, 1194 kThisPropertyExpression,
1119 kPropertyExpression, 1195 kPropertyExpression,
1120 kCallExpression, 1196 kCallExpression,
1121 kSuperCallReference, 1197 kSuperCallReference,
1122 kNoTemplateTagExpression 1198 kNoTemplateTagExpression,
1199 kAssignmentPattern
1123 }; 1200 };
1124 1201
1125 explicit PreParserExpression(uint32_t expression_code) 1202 explicit PreParserExpression(uint32_t expression_code)
1126 : code_(expression_code) {} 1203 : code_(expression_code) {}
1127 1204
1128 // The first three bits are for the Type. 1205 // The first three bits are for the Type.
1129 typedef BitField<Type, 0, 3> TypeField; 1206 typedef BitField<Type, 0, 3> TypeField;
1130 1207
1131 // The rest of the bits are interpreted depending on the value 1208 // The rest of the bits are interpreted depending on the value
1132 // of the Type field, so they can share the storage. 1209 // of the Type field, so they can share the storage.
1133 typedef BitField<ExpressionType, TypeField::kNext, 3> ExpressionTypeField; 1210 typedef BitField<ExpressionType, TypeField::kNext, 3> ExpressionTypeField;
1134 typedef BitField<bool, TypeField::kNext, 1> IsUseStrictField; 1211 typedef BitField<bool, TypeField::kNext, 1> IsUseStrictField;
1135 typedef BitField<bool, IsUseStrictField::kNext, 1> IsUseStrongField; 1212 typedef BitField<bool, IsUseStrictField::kNext, 1> IsUseStrongField;
1136 typedef BitField<PreParserIdentifier::Type, TypeField::kNext, 10> 1213 typedef BitField<PreParserIdentifier::Type, TypeField::kNext, 10>
1137 IdentifierTypeField; 1214 IdentifierTypeField;
1138 typedef BitField<bool, TypeField::kNext, 1> HasRestField; 1215 typedef BitField<bool, TypeField::kNext, 1> HasRestField;
1216 typedef BitField<bool, TypeField::kNext, 1> HasCoverInitializedNameField;
1139 1217
1140 uint32_t code_; 1218 uint32_t code_;
1141 }; 1219 };
1142 1220
1143 1221
1144 // The pre-parser doesn't need to build lists of expressions, identifiers, or 1222 // The pre-parser doesn't need to build lists of expressions, identifiers, or
1145 // the like. 1223 // the like.
1146 template <typename T> 1224 template <typename T>
1147 class PreParserList { 1225 class PreParserList {
1148 public: 1226 public:
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
1301 PreParserExpression left, 1379 PreParserExpression left,
1302 PreParserExpression right, int pos) { 1380 PreParserExpression right, int pos) {
1303 return PreParserExpression::Default(); 1381 return PreParserExpression::Default();
1304 } 1382 }
1305 PreParserExpression NewAssignment(Token::Value op, 1383 PreParserExpression NewAssignment(Token::Value op,
1306 PreParserExpression left, 1384 PreParserExpression left,
1307 PreParserExpression right, 1385 PreParserExpression right,
1308 int pos) { 1386 int pos) {
1309 return PreParserExpression::Default(); 1387 return PreParserExpression::Default();
1310 } 1388 }
1389 PreParserExpression NewAssignmentPattern(PreParserExpression pattern,
1390 int pos) {
1391 DCHECK(pattern->IsObjectLiteral() || pattern->IsArrayLiteral());
1392 return PreParserExpression::AssignmentPattern();
1393 }
1311 PreParserExpression NewYield(PreParserExpression generator_object, 1394 PreParserExpression NewYield(PreParserExpression generator_object,
1312 PreParserExpression expression, 1395 PreParserExpression expression,
1313 Yield::Kind yield_kind, 1396 Yield::Kind yield_kind,
1314 int pos) { 1397 int pos) {
1315 return PreParserExpression::Default(); 1398 return PreParserExpression::Default();
1316 } 1399 }
1317 PreParserExpression NewConditional(PreParserExpression condition, 1400 PreParserExpression NewConditional(PreParserExpression condition,
1318 PreParserExpression then_expression, 1401 PreParserExpression then_expression,
1319 PreParserExpression else_expression, 1402 PreParserExpression else_expression,
1320 int pos) { 1403 int pos) {
(...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after
1731 1814
1732 inline void MaterializeUnspreadArgumentsLiterals(int count); 1815 inline void MaterializeUnspreadArgumentsLiterals(int count);
1733 1816
1734 inline PreParserExpression SpreadCall(PreParserExpression function, 1817 inline PreParserExpression SpreadCall(PreParserExpression function,
1735 PreParserExpressionList args, int pos); 1818 PreParserExpressionList args, int pos);
1736 1819
1737 inline PreParserExpression SpreadCallNew(PreParserExpression function, 1820 inline PreParserExpression SpreadCallNew(PreParserExpression function,
1738 PreParserExpressionList args, 1821 PreParserExpressionList args,
1739 int pos); 1822 int pos);
1740 1823
1824 inline PreParserExpression RewriteDestructuringAssignmentExpression(
1825 PreParserExpression expr) {
1826 return expr;
1827 }
1828
1829 inline void RewriteDestructuringAssignments() {}
1830
1831 inline void ShouldRewriteDestructuringAssignment(PreParserExpression) {}
1832
1741 private: 1833 private:
1742 PreParser* pre_parser_; 1834 PreParser* pre_parser_;
1743 }; 1835 };
1744 1836
1745 1837
1746 // Preparsing checks a JavaScript program and emits preparse-data that helps 1838 // Preparsing checks a JavaScript program and emits preparse-data that helps
1747 // a later parsing to be faster. 1839 // a later parsing to be faster.
1748 // See preparse-data-format.h for the data format. 1840 // See preparse-data-format.h for the data format.
1749 1841
1750 // The PreParser checks that the syntax follows the grammar for JavaScript, 1842 // The PreParser checks that the syntax follows the grammar for JavaScript,
(...skipping 611 matching lines...) Expand 10 before | Expand all | Expand 10 after
2362 return this->EmptyExpression(); 2454 return this->EmptyExpression();
2363 } 2455 }
2364 Expect(Token::RPAREN, CHECK_OK); 2456 Expect(Token::RPAREN, CHECK_OK);
2365 return factory()->NewSpread(expr, ellipsis_pos); 2457 return factory()->NewSpread(expr, ellipsis_pos);
2366 } 2458 }
2367 // Heuristically try to detect immediately called functions before 2459 // Heuristically try to detect immediately called functions before
2368 // seeing the call parentheses. 2460 // seeing the call parentheses.
2369 parenthesized_function_ = (peek() == Token::FUNCTION); 2461 parenthesized_function_ = (peek() == Token::FUNCTION);
2370 ExpressionT expr = this->ParseExpression(true, classifier, CHECK_OK); 2462 ExpressionT expr = this->ParseExpression(true, classifier, CHECK_OK);
2371 Expect(Token::RPAREN, CHECK_OK); 2463 Expect(Token::RPAREN, CHECK_OK);
2464 if (peek() != Token::ARROW) {
2465 ValidateExpression(classifier, CHECK_OK);
2466 }
2372 return expr; 2467 return expr;
2373 } 2468 }
2374 2469
2375 case Token::CLASS: { 2470 case Token::CLASS: {
2376 BindingPatternUnexpectedToken(classifier); 2471 BindingPatternUnexpectedToken(classifier);
2377 Consume(Token::CLASS); 2472 Consume(Token::CLASS);
2378 if (!allow_harmony_sloppy() && is_sloppy(language_mode())) { 2473 if (!allow_harmony_sloppy() && is_sloppy(language_mode())) {
2379 ReportMessage(MessageTemplate::kSloppyLexical); 2474 ReportMessage(MessageTemplate::kSloppyLexical);
2380 *ok = false; 2475 *ok = false;
2381 return this->EmptyExpression(); 2476 return this->EmptyExpression();
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
2429 template <class Traits> 2524 template <class Traits>
2430 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( 2525 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression(
2431 bool accept_IN, bool* ok) { 2526 bool accept_IN, bool* ok) {
2432 ExpressionClassifier classifier; 2527 ExpressionClassifier classifier;
2433 ExpressionT result = ParseExpression(accept_IN, &classifier, CHECK_OK); 2528 ExpressionT result = ParseExpression(accept_IN, &classifier, CHECK_OK);
2434 ValidateExpression(&classifier, CHECK_OK); 2529 ValidateExpression(&classifier, CHECK_OK);
2435 return result; 2530 return result;
2436 } 2531 }
2437 2532
2438 2533
2439 // Precedence = 1
2440 template <class Traits> 2534 template <class Traits>
2441 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( 2535 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression(
2442 bool accept_IN, ExpressionClassifier* classifier, bool* ok) { 2536 bool accept_IN, ExpressionClassifier* classifier, bool* ok) {
2443 // Expression :: 2537 // Expression ::
2444 // AssignmentExpression 2538 // AssignmentExpression
2445 // Expression ',' AssignmentExpression 2539 // Expression ',' AssignmentExpression
2446 2540
2447 ExpressionClassifier binding_classifier; 2541 ExpressionClassifier binding_classifier;
2448 ExpressionT result = 2542 ExpressionT result =
2449 this->ParseAssignmentExpression(accept_IN, &binding_classifier, CHECK_OK); 2543 this->ParseAssignmentExpression(accept_IN, &binding_classifier, CHECK_OK);
(...skipping 25 matching lines...) Expand all
2475 if (is_rest) right = factory()->NewSpread(right, pos); 2569 if (is_rest) right = factory()->NewSpread(right, pos);
2476 is_simple_parameter_list = 2570 is_simple_parameter_list =
2477 is_simple_parameter_list && this->IsIdentifier(right); 2571 is_simple_parameter_list && this->IsIdentifier(right);
2478 classifier->Accumulate(binding_classifier, 2572 classifier->Accumulate(binding_classifier,
2479 ExpressionClassifier::AllProductions); 2573 ExpressionClassifier::AllProductions);
2480 result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos); 2574 result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos);
2481 } 2575 }
2482 if (!is_simple_parameter_list || seen_rest) { 2576 if (!is_simple_parameter_list || seen_rest) {
2483 classifier->RecordNonSimpleParameter(); 2577 classifier->RecordNonSimpleParameter();
2484 } 2578 }
2579
2485 return result; 2580 return result;
2486 } 2581 }
2487 2582
2488 2583
2489 template <class Traits> 2584 template <class Traits>
2490 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseArrayLiteral( 2585 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseArrayLiteral(
2491 ExpressionClassifier* classifier, bool* ok) { 2586 ExpressionClassifier* classifier, bool* ok) {
2492 // ArrayLiteral :: 2587 // ArrayLiteral ::
2493 // '[' Expression? (',' Expression?)* ']' 2588 // '[' Expression? (',' Expression?)* ']'
2494 2589
(...skipping 16 matching lines...) Expand all
2511 } else if (peek() == Token::ELLIPSIS) { 2606 } else if (peek() == Token::ELLIPSIS) {
2512 int start_pos = peek_position(); 2607 int start_pos = peek_position();
2513 Consume(Token::ELLIPSIS); 2608 Consume(Token::ELLIPSIS);
2514 ExpressionT argument = 2609 ExpressionT argument =
2515 this->ParseAssignmentExpression(true, classifier, CHECK_OK); 2610 this->ParseAssignmentExpression(true, classifier, CHECK_OK);
2516 elem = factory()->NewSpread(argument, start_pos); 2611 elem = factory()->NewSpread(argument, start_pos);
2517 seen_spread = true; 2612 seen_spread = true;
2518 if (first_spread_index < 0) { 2613 if (first_spread_index < 0) {
2519 first_spread_index = values->length(); 2614 first_spread_index = values->length();
2520 } 2615 }
2616
2617 CheckDestructuringElement(argument, classifier, start_pos,
2618 scanner()->location().end_pos);
2619
2620 if (peek() == Token::COMMA) {
2621 classifier->RecordPatternError(
2622 Scanner::Location(start_pos, scanner()->location().end_pos),
2623 MessageTemplate::kElementAfterRest);
2624 }
2521 } else { 2625 } else {
2522 elem = this->ParseAssignmentExpression(true, classifier, CHECK_OK); 2626 elem = this->ParseAssignmentExpression(true, kIsPatternElement,
2627 classifier, CHECK_OK);
2628 if (!this->IsValidReferenceExpression(elem) &&
2629 !classifier->is_valid_assignment_pattern()) {
2630 classifier->RecordPatternError(
2631 Scanner::Location(pos, scanner()->location().end_pos),
2632 MessageTemplate::kInvalidDestructuringTarget);
2633 }
2523 } 2634 }
2524 values->Add(elem, zone_); 2635 values->Add(elem, zone_);
2525 if (peek() != Token::RBRACK) { 2636 if (peek() != Token::RBRACK) {
2526 if (seen_spread) {
2527 BindingPatternUnexpectedToken(classifier);
2528 }
2529 Expect(Token::COMMA, CHECK_OK); 2637 Expect(Token::COMMA, CHECK_OK);
2530 } 2638 }
2531 } 2639 }
2532 Expect(Token::RBRACK, CHECK_OK); 2640 Expect(Token::RBRACK, CHECK_OK);
2533 2641
2534 // Update the scope information before the pre-parsing bailout. 2642 // Update the scope information before the pre-parsing bailout.
2535 int literal_index = function_state_->NextMaterializedLiteralIndex(); 2643 int literal_index = function_state_->NextMaterializedLiteralIndex();
2536 2644
2537 return factory()->NewArrayLiteral(values, first_spread_index, literal_index, 2645 return factory()->NewArrayLiteral(values, first_spread_index, literal_index,
2538 is_strong(language_mode()), pos); 2646 is_strong(language_mode()), pos);
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
2628 DCHECK(!is_static); 2736 DCHECK(!is_static);
2629 2737
2630 if (peek() == Token::COLON) { 2738 if (peek() == Token::COLON) {
2631 // PropertyDefinition 2739 // PropertyDefinition
2632 // PropertyName ':' AssignmentExpression 2740 // PropertyName ':' AssignmentExpression
2633 if (!*is_computed_name) { 2741 if (!*is_computed_name) {
2634 checker->CheckProperty(name_token, kValueProperty, false, false, 2742 checker->CheckProperty(name_token, kValueProperty, false, false,
2635 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 2743 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2636 } 2744 }
2637 Consume(Token::COLON); 2745 Consume(Token::COLON);
2746 int pos = peek_position();
2638 value = this->ParseAssignmentExpression( 2747 value = this->ParseAssignmentExpression(
2639 true, classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 2748 true, kIsPatternElement, classifier,
2749 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2750
2751 if (!this->IsValidReferenceExpression(value) &&
2752 !classifier->is_valid_assignment_pattern()) {
2753 classifier->RecordPatternError(
2754 Scanner::Location(pos, scanner()->location().end_pos),
2755 MessageTemplate::kInvalidDestructuringTarget);
2756 }
2757
2640 return factory()->NewObjectLiteralProperty(name_expression, value, false, 2758 return factory()->NewObjectLiteralProperty(name_expression, value, false,
2641 *is_computed_name); 2759 *is_computed_name);
2642 } 2760 }
2643 2761
2644 if (Token::IsIdentifier(name_token, language_mode(), 2762 if (Token::IsIdentifier(name_token, language_mode(),
2645 this->is_generator()) && 2763 this->is_generator()) &&
2646 (peek() == Token::COMMA || peek() == Token::RBRACE || 2764 (peek() == Token::COMMA || peek() == Token::RBRACE ||
2647 peek() == Token::ASSIGN)) { 2765 peek() == Token::ASSIGN)) {
2648 // PropertyDefinition 2766 // PropertyDefinition
2649 // IdentifierReference 2767 // IdentifierReference
2650 // CoverInitializedName 2768 // CoverInitializedName
2651 // 2769 //
2652 // CoverInitializedName 2770 // CoverInitializedName
2653 // IdentifierReference Initializer? 2771 // IdentifierReference Initializer?
2654 if (classifier->duplicate_finder() != nullptr && 2772 if (classifier->duplicate_finder() != nullptr &&
2655 scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) { 2773 scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) {
2656 classifier->RecordDuplicateFormalParameterError(scanner()->location()); 2774 classifier->RecordDuplicateFormalParameterError(scanner()->location());
2657 } 2775 }
2658 if (name_token == Token::LET) { 2776 if (name_token == Token::LET) {
2659 classifier->RecordLetPatternError( 2777 classifier->RecordLetPatternError(
2660 scanner()->location(), MessageTemplate::kLetInLexicalBinding); 2778 scanner()->location(), MessageTemplate::kLetInLexicalBinding);
2661 } 2779 }
2662 2780
2663 ExpressionT lhs = this->ExpressionFromIdentifier( 2781 ExpressionT lhs = this->ExpressionFromIdentifier(
2664 name, next_beg_pos, next_end_pos, scope_, factory()); 2782 name, next_beg_pos, next_end_pos, scope_, factory());
2665 2783
2666 if (peek() == Token::ASSIGN) { 2784 if (peek() == Token::ASSIGN) {
2667 this->ExpressionUnexpectedToken(classifier);
2668 Consume(Token::ASSIGN); 2785 Consume(Token::ASSIGN);
2669 ExpressionClassifier rhs_classifier; 2786 ExpressionClassifier rhs_classifier;
2670 ExpressionT rhs = this->ParseAssignmentExpression( 2787 ExpressionT rhs = this->ParseAssignmentExpression(
2671 true, &rhs_classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 2788 true, &rhs_classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2672 classifier->Accumulate(rhs_classifier, 2789 classifier->Accumulate(rhs_classifier,
2673 ExpressionClassifier::ExpressionProductions); 2790 ExpressionClassifier::ExpressionProductions);
2674 value = factory()->NewAssignment(Token::ASSIGN, lhs, rhs, 2791 value = factory()->NewAssignment(Token::ASSIGN, lhs, rhs,
2675 RelocInfo::kNoPosition); 2792 RelocInfo::kNoPosition);
2793 classifier->RecordCoverInitializedNameError(
2794 Scanner::Location(next_beg_pos, scanner()->location().end_pos),
2795 MessageTemplate::kInvalidCoverInitializedName);
2676 } else { 2796 } else {
2677 value = lhs; 2797 value = lhs;
2678 } 2798 }
2679 2799
2680 return factory()->NewObjectLiteralProperty( 2800 return factory()->NewObjectLiteralProperty(
2681 name_expression, value, ObjectLiteralProperty::COMPUTED, false, 2801 name_expression, value, ObjectLiteralProperty::COMPUTED, false,
2682 false); 2802 false);
2683 } 2803 }
2684 } 2804 }
2685 2805
2806 // Method definitions are never valid in patterns.
2807 classifier->RecordPatternError(
2808 Scanner::Location(next_beg_pos, scanner()->location().end_pos),
2809 MessageTemplate::kInvalidDestructuringTarget);
2810
2686 2811
2687 if (is_generator || peek() == Token::LPAREN) { 2812 if (is_generator || peek() == Token::LPAREN) {
2688 // MethodDefinition 2813 // MethodDefinition
2689 // PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' 2814 // PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}'
2690 // '*' PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' 2815 // '*' PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}'
2691 if (!*is_computed_name) { 2816 if (!*is_computed_name) {
2692 checker->CheckProperty(name_token, kMethodProperty, is_static, 2817 checker->CheckProperty(name_token, kMethodProperty, is_static,
2693 is_generator, 2818 is_generator,
2694 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 2819 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2695 } 2820 }
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
2899 // the parser and preparser 3024 // the parser and preparser
2900 Traits::MaterializeUnspreadArgumentsLiterals(unspread_sequences_count); 3025 Traits::MaterializeUnspreadArgumentsLiterals(unspread_sequences_count);
2901 } 3026 }
2902 3027
2903 return result; 3028 return result;
2904 } 3029 }
2905 3030
2906 // Precedence = 2 3031 // Precedence = 2
2907 template <class Traits> 3032 template <class Traits>
2908 typename ParserBase<Traits>::ExpressionT 3033 typename ParserBase<Traits>::ExpressionT
2909 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, 3034 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, int flags,
2910 ExpressionClassifier* classifier, 3035 ExpressionClassifier* classifier,
2911 bool* ok) { 3036 bool* ok) {
2912 // AssignmentExpression :: 3037 // AssignmentExpression ::
2913 // ConditionalExpression 3038 // ConditionalExpression
2914 // ArrowFunction 3039 // ArrowFunction
2915 // YieldExpression 3040 // YieldExpression
2916 // LeftHandSideExpression AssignmentOperator AssignmentExpression 3041 // LeftHandSideExpression AssignmentOperator AssignmentExpression
2917 3042 bool is_rhs = flags & kIsRightHandSide;
3043 bool is_pattern_element = flags & kIsPatternElement;
2918 int lhs_beg_pos = peek_position(); 3044 int lhs_beg_pos = peek_position();
2919 3045
2920 if (peek() == Token::YIELD && is_generator()) { 3046 if (peek() == Token::YIELD && is_generator()) {
2921 return this->ParseYieldExpression(classifier, ok); 3047 return this->ParseYieldExpression(classifier, ok);
2922 } 3048 }
2923 3049
2924 if (fni_ != NULL) fni_->Enter(); 3050 if (fni_ != NULL) fni_->Enter();
2925 ParserBase<Traits>::Checkpoint checkpoint(this); 3051 ParserBase<Traits>::Checkpoint checkpoint(this);
2926 ExpressionClassifier arrow_formals_classifier(classifier->duplicate_finder()); 3052 ExpressionClassifier arrow_formals_classifier(classifier->duplicate_finder());
2927 bool parenthesized_formals = peek() == Token::LPAREN; 3053 bool parenthesized_formals = peek() == Token::LPAREN;
(...skipping 25 matching lines...) Expand all
2953 3079
2954 checkpoint.Restore(&parameters.materialized_literals_count); 3080 checkpoint.Restore(&parameters.materialized_literals_count);
2955 3081
2956 scope->set_start_position(lhs_beg_pos); 3082 scope->set_start_position(lhs_beg_pos);
2957 if (duplicate_loc.IsValid()) { 3083 if (duplicate_loc.IsValid()) {
2958 arrow_formals_classifier.RecordDuplicateFormalParameterError( 3084 arrow_formals_classifier.RecordDuplicateFormalParameterError(
2959 duplicate_loc); 3085 duplicate_loc);
2960 } 3086 }
2961 expression = this->ParseArrowFunctionLiteral( 3087 expression = this->ParseArrowFunctionLiteral(
2962 accept_IN, parameters, arrow_formals_classifier, CHECK_OK); 3088 accept_IN, parameters, arrow_formals_classifier, CHECK_OK);
3089 if (is_pattern_element) {
3090 classifier->RecordPatternError(
3091 Scanner::Location(lhs_beg_pos, scanner()->location().end_pos),
3092 MessageTemplate::kInvalidDestructuringTarget);
3093 }
2963 return expression; 3094 return expression;
2964 } 3095 }
2965 3096
3097 if (this->IsValidReferenceExpression(expression)) {
3098 arrow_formals_classifier.ForgiveAssignmentPatternError();
3099 }
3100
2966 // "expression" was not itself an arrow function parameter list, but it might 3101 // "expression" was not itself an arrow function parameter list, but it might
2967 // form part of one. Propagate speculative formal parameter error locations. 3102 // form part of one. Propagate speculative formal parameter error locations.
2968 classifier->Accumulate(arrow_formals_classifier, 3103 classifier->Accumulate(
2969 ExpressionClassifier::StandardProductions | 3104 arrow_formals_classifier,
2970 ExpressionClassifier::FormalParametersProductions); 3105 ExpressionClassifier::StandardProductions |
3106 ExpressionClassifier::FormalParametersProductions |
3107 ExpressionClassifier::CoverInitializedNameProduction);
3108
3109 bool maybe_pattern =
3110 expression->IsObjectLiteral() || expression->IsArrayLiteral();
3111 bool binding_pattern =
3112 allow_harmony_destructuring() && maybe_pattern && !is_rhs;
2971 3113
2972 if (!Token::IsAssignmentOp(peek())) { 3114 if (!Token::IsAssignmentOp(peek())) {
2973 if (fni_ != NULL) fni_->Leave(); 3115 if (fni_ != NULL) fni_->Leave();
2974 // Parsed conditional expression only (no assignment). 3116 // Parsed conditional expression only (no assignment).
3117 if (is_pattern_element && !this->IsValidReferenceExpression(expression) &&
3118 !maybe_pattern) {
3119 classifier->RecordPatternError(
3120 Scanner::Location(lhs_beg_pos, scanner()->location().end_pos),
3121 MessageTemplate::kInvalidDestructuringTarget);
3122 } else if (is_rhs && maybe_pattern) {
3123 ValidateExpression(classifier, CHECK_OK);
3124 }
3125
2975 return expression; 3126 return expression;
2976 } 3127 }
2977 3128
2978 if (!(allow_harmony_destructuring() || allow_harmony_default_parameters())) { 3129 if (!(allow_harmony_destructuring() || allow_harmony_default_parameters())) {
2979 BindingPatternUnexpectedToken(classifier); 3130 BindingPatternUnexpectedToken(classifier);
2980 } 3131 }
2981 3132
2982 expression = this->CheckAndRewriteReferenceExpression( 3133 if (allow_harmony_destructuring_assignment() && maybe_pattern &&
2983 expression, lhs_beg_pos, scanner()->location().end_pos, 3134 peek() == Token::ASSIGN) {
2984 MessageTemplate::kInvalidLhsInAssignment, CHECK_OK); 3135 classifier->ForgiveCoverInitializedNameError();
3136 ValidateAssignmentPattern(classifier, CHECK_OK);
3137 expression = factory()->NewAssignmentPattern(expression, lhs_beg_pos);
3138 } else if (!binding_pattern) {
3139 expression = this->CheckAndRewriteReferenceExpression(
3140 expression, lhs_beg_pos, scanner()->location().end_pos,
3141 MessageTemplate::kInvalidLhsInAssignment, CHECK_OK);
3142 }
3143
2985 expression = this->MarkExpressionAsAssigned(expression); 3144 expression = this->MarkExpressionAsAssigned(expression);
2986 3145
2987 Token::Value op = Next(); // Get assignment operator. 3146 Token::Value op = Next(); // Get assignment operator.
2988 if (op != Token::ASSIGN) { 3147 if (op != Token::ASSIGN) {
2989 classifier->RecordBindingPatternError(scanner()->location(), 3148 classifier->RecordBindingPatternError(scanner()->location(),
2990 MessageTemplate::kUnexpectedToken, 3149 MessageTemplate::kUnexpectedToken,
2991 Token::String(op)); 3150 Token::String(op));
2992 } 3151 }
2993 int pos = position(); 3152 int pos = position();
2994 3153
2995 ExpressionClassifier rhs_classifier; 3154 ExpressionClassifier rhs_classifier;
2996 ExpressionT right = 3155
2997 this->ParseAssignmentExpression(accept_IN, &rhs_classifier, CHECK_OK); 3156 int rhs_flags = flags;
2998 classifier->Accumulate(rhs_classifier, 3157 rhs_flags &= ~kIsPatternElement;
2999 ExpressionClassifier::ExpressionProductions); 3158 rhs_flags |= kIsRightHandSide;
3159 ExpressionT right = this->ParseAssignmentExpression(
3160 accept_IN, rhs_flags, &rhs_classifier, CHECK_OK);
3161 classifier->Accumulate(
3162 rhs_classifier, ExpressionClassifier::ExpressionProductions |
3163 ExpressionClassifier::CoverInitializedNameProduction);
3000 3164
3001 // TODO(1231235): We try to estimate the set of properties set by 3165 // TODO(1231235): We try to estimate the set of properties set by
3002 // constructors. We define a new property whenever there is an 3166 // constructors. We define a new property whenever there is an
3003 // assignment to a property of 'this'. We should probably only add 3167 // assignment to a property of 'this'. We should probably only add
3004 // properties if we haven't seen them before. Otherwise we'll 3168 // properties if we haven't seen them before. Otherwise we'll
3005 // probably overestimate the number of properties. 3169 // probably overestimate the number of properties.
3006 if (op == Token::ASSIGN && this->IsThisProperty(expression)) { 3170 if (op == Token::ASSIGN && this->IsThisProperty(expression)) {
3007 function_state_->AddProperty(); 3171 function_state_->AddProperty();
3008 } 3172 }
3009 3173
3010 this->CheckAssigningFunctionLiteralToProperty(expression, right); 3174 this->CheckAssigningFunctionLiteralToProperty(expression, right);
3011 3175
3012 if (fni_ != NULL) { 3176 if (fni_ != NULL) {
3013 // Check if the right hand side is a call to avoid inferring a 3177 // Check if the right hand side is a call to avoid inferring a
3014 // name if we're dealing with "a = function(){...}();"-like 3178 // name if we're dealing with "a = function(){...}();"-like
3015 // expression. 3179 // expression.
3016 if ((op == Token::INIT_VAR 3180 if ((op == Token::INIT_VAR
3017 || op == Token::INIT_CONST_LEGACY 3181 || op == Token::INIT_CONST_LEGACY
3018 || op == Token::ASSIGN) 3182 || op == Token::ASSIGN)
3019 && (!right->IsCall() && !right->IsCallNew())) { 3183 && (!right->IsCall() && !right->IsCallNew())) {
3020 fni_->Infer(); 3184 fni_->Infer();
3021 } else { 3185 } else {
3022 fni_->RemoveLastFunction(); 3186 fni_->RemoveLastFunction();
3023 } 3187 }
3024 fni_->Leave(); 3188 fni_->Leave();
3025 } 3189 }
3026 3190
3027 return factory()->NewAssignment(op, expression, right, pos); 3191 ExpressionT result = factory()->NewAssignment(op, expression, right, pos);
3192
3193 if (expression->IsAssignmentPattern()) {
3194 Traits::ShouldRewriteDestructuringAssignment(result);
3195 }
3196
3197 return result;
3028 } 3198 }
3029 3199
3030 template <class Traits> 3200 template <class Traits>
3031 typename ParserBase<Traits>::ExpressionT 3201 typename ParserBase<Traits>::ExpressionT
3032 ParserBase<Traits>::ParseYieldExpression(ExpressionClassifier* classifier, 3202 ParserBase<Traits>::ParseYieldExpression(ExpressionClassifier* classifier,
3033 bool* ok) { 3203 bool* ok) {
3034 // YieldExpression :: 3204 // YieldExpression ::
3035 // 'yield' ([no line terminator] '*'? AssignmentExpression)? 3205 // 'yield' ([no line terminator] '*'? AssignmentExpression)?
3036 int pos = peek_position(); 3206 int pos = peek_position();
3037 BindingPatternUnexpectedToken(classifier); 3207 BindingPatternUnexpectedToken(classifier);
(...skipping 936 matching lines...) Expand 10 before | Expand all | Expand 10 after
3974 allow_duplicate_parameters, CHECK_OK); 4144 allow_duplicate_parameters, CHECK_OK);
3975 4145
3976 // Validate strict mode. 4146 // Validate strict mode.
3977 if (is_strict(language_mode())) { 4147 if (is_strict(language_mode())) {
3978 CheckStrictOctalLiteral(formal_parameters.scope->start_position(), 4148 CheckStrictOctalLiteral(formal_parameters.scope->start_position(),
3979 scanner()->location().end_pos, CHECK_OK); 4149 scanner()->location().end_pos, CHECK_OK);
3980 } 4150 }
3981 if (is_strict(language_mode()) || allow_harmony_sloppy()) { 4151 if (is_strict(language_mode()) || allow_harmony_sloppy()) {
3982 this->CheckConflictingVarDeclarations(formal_parameters.scope, CHECK_OK); 4152 this->CheckConflictingVarDeclarations(formal_parameters.scope, CHECK_OK);
3983 } 4153 }
4154
4155 Traits::RewriteDestructuringAssignments();
3984 } 4156 }
3985 4157
3986 FunctionLiteralT function_literal = factory()->NewFunctionLiteral( 4158 FunctionLiteralT function_literal = factory()->NewFunctionLiteral(
3987 this->EmptyIdentifierString(), ast_value_factory(), 4159 this->EmptyIdentifierString(), ast_value_factory(),
3988 formal_parameters.scope, body, materialized_literal_count, 4160 formal_parameters.scope, body, materialized_literal_count,
3989 expected_property_count, num_parameters, 4161 expected_property_count, num_parameters,
3990 FunctionLiteral::kNoDuplicateParameters, 4162 FunctionLiteral::kNoDuplicateParameters,
3991 FunctionLiteral::ANONYMOUS_EXPRESSION, FunctionLiteral::kIsFunction, 4163 FunctionLiteral::ANONYMOUS_EXPRESSION, FunctionLiteral::kIsFunction,
3992 FunctionLiteral::kShouldLazyCompile, FunctionKind::kArrowFunction, 4164 FunctionLiteral::kShouldLazyCompile, FunctionKind::kArrowFunction,
3993 formal_parameters.scope->start_position()); 4165 formal_parameters.scope->start_position());
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
4122 return this->EmptyExpression(); 4294 return this->EmptyExpression();
4123 } 4295 }
4124 if (is_strong(language_mode()) && 4296 if (is_strong(language_mode()) &&
4125 this->IsUndefined(this->AsIdentifier(expression))) { 4297 this->IsUndefined(this->AsIdentifier(expression))) {
4126 this->ReportMessageAt(location, MessageTemplate::kStrongUndefined, 4298 this->ReportMessageAt(location, MessageTemplate::kStrongUndefined,
4127 kSyntaxError); 4299 kSyntaxError);
4128 *ok = false; 4300 *ok = false;
4129 return this->EmptyExpression(); 4301 return this->EmptyExpression();
4130 } 4302 }
4131 } 4303 }
4132 if (expression->IsValidReferenceExpression()) { 4304 if (expression->IsValidReferenceExpression() ||
4305 expression->IsAssignmentPattern()) {
4133 return expression; 4306 return expression;
4134 } else if (expression->IsCall()) { 4307 } else if (expression->IsCall()) {
4135 // If it is a call, make it a runtime error for legacy web compatibility. 4308 // If it is a call, make it a runtime error for legacy web compatibility.
4136 // Rewrite `expr' to `expr[throw ReferenceError]'. 4309 // Rewrite `expr' to `expr[throw ReferenceError]'.
4137 int pos = location.beg_pos; 4310 int pos = location.beg_pos;
4138 ExpressionT error = this->NewThrowReferenceError(message, pos); 4311 ExpressionT error = this->NewThrowReferenceError(message, pos);
4139 return factory()->NewProperty(expression, error, pos); 4312 return factory()->NewProperty(expression, error, pos);
4140 } else { 4313 } else {
4141 this->ReportMessageAt(location, message, type); 4314 this->ReportMessageAt(location, message, type);
4142 *ok = false; 4315 *ok = false;
4143 return this->EmptyExpression(); 4316 return this->EmptyExpression();
4144 } 4317 }
4145 } 4318 }
4146 4319
4147 4320
4321 template <typename Traits>
4322 bool ParserBase<Traits>::IsValidReferenceExpression(ExpressionT expression) {
4323 return this->IsAssignableIdentifier(expression) || expression->IsProperty();
4324 }
4325
4326
4327 template <typename Traits>
4328 void ParserBase<Traits>::CheckDestructuringElement(
4329 ExpressionT expression, ExpressionClassifier* classifier, int begin,
4330 int end) {
4331 static const MessageTemplate::Template message =
4332 MessageTemplate::kInvalidDestructuringTarget;
4333 if (!this->IsAssignableIdentifier(expression)) {
4334 const Scanner::Location location(begin, end);
4335 classifier->RecordBindingPatternError(location, message);
4336 if (!expression->IsProperty()) {
4337 classifier->RecordAssignmentPatternError(location, message);
4338 }
4339 }
4340 }
4341
4342
4148 #undef CHECK_OK 4343 #undef CHECK_OK
4149 #undef CHECK_OK_CUSTOM 4344 #undef CHECK_OK_CUSTOM
4150 4345
4151 4346
4152 template <typename Traits> 4347 template <typename Traits>
4153 void ParserBase<Traits>::ObjectLiteralChecker::CheckProperty( 4348 void ParserBase<Traits>::ObjectLiteralChecker::CheckProperty(
4154 Token::Value property, PropertyKind type, bool is_static, bool is_generator, 4349 Token::Value property, PropertyKind type, bool is_static, bool is_generator,
4155 bool* ok) { 4350 bool* ok) {
4156 DCHECK(!is_static); 4351 DCHECK(!is_static);
4157 DCHECK(!is_generator || type == kMethodProperty); 4352 DCHECK(!is_generator || type == kMethodProperty);
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
4199 return; 4394 return;
4200 } 4395 }
4201 has_seen_constructor_ = true; 4396 has_seen_constructor_ = true;
4202 return; 4397 return;
4203 } 4398 }
4204 } 4399 }
4205 } // namespace internal 4400 } // namespace internal
4206 } // namespace v8 4401 } // namespace v8
4207 4402
4208 #endif // V8_PREPARSER_H 4403 #endif // V8_PREPARSER_H
OLDNEW
« src/pattern-rewriter.cc ('K') | « src/pattern-rewriter.cc ('k') | src/prettyprinter.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698