Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef V8_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 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_; | |
|
adamk
2015/11/25 21:05:28
Please move this to Parser unless there's some rea
caitp (gmail)
2015/11/25 21:41:52
The list lives in FunctionState, so each FunctionS
| |
| 280 | |
| 281 void RewriteDestructuringAssignments(); | |
|
adamk
2015/11/25 21:05:28
I don't see this defined anywhere (and I don't thi
caitp (gmail)
2015/11/25 21:41:52
Acknowledged.
| |
| 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 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1313 PreParserExpression left, | 1398 PreParserExpression left, |
| 1314 PreParserExpression right, int pos) { | 1399 PreParserExpression right, int pos) { |
| 1315 return PreParserExpression::Default(); | 1400 return PreParserExpression::Default(); |
| 1316 } | 1401 } |
| 1317 PreParserExpression NewAssignment(Token::Value op, | 1402 PreParserExpression NewAssignment(Token::Value op, |
| 1318 PreParserExpression left, | 1403 PreParserExpression left, |
| 1319 PreParserExpression right, | 1404 PreParserExpression right, |
| 1320 int pos) { | 1405 int pos) { |
| 1321 return PreParserExpression::Default(); | 1406 return PreParserExpression::Default(); |
| 1322 } | 1407 } |
| 1408 PreParserExpression NewAssignmentPattern(PreParserExpression pattern, | |
| 1409 int pos) { | |
| 1410 DCHECK(pattern->IsObjectLiteral() || pattern->IsArrayLiteral()); | |
| 1411 return PreParserExpression::AssignmentPattern(); | |
| 1412 } | |
| 1323 PreParserExpression NewYield(PreParserExpression generator_object, | 1413 PreParserExpression NewYield(PreParserExpression generator_object, |
| 1324 PreParserExpression expression, | 1414 PreParserExpression expression, |
| 1325 Yield::Kind yield_kind, | 1415 Yield::Kind yield_kind, |
| 1326 int pos) { | 1416 int pos) { |
| 1327 return PreParserExpression::Default(); | 1417 return PreParserExpression::Default(); |
| 1328 } | 1418 } |
| 1329 PreParserExpression NewConditional(PreParserExpression condition, | 1419 PreParserExpression NewConditional(PreParserExpression condition, |
| 1330 PreParserExpression then_expression, | 1420 PreParserExpression then_expression, |
| 1331 PreParserExpression else_expression, | 1421 PreParserExpression else_expression, |
| 1332 int pos) { | 1422 int pos) { |
| (...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1743 | 1833 |
| 1744 inline void MaterializeUnspreadArgumentsLiterals(int count); | 1834 inline void MaterializeUnspreadArgumentsLiterals(int count); |
| 1745 | 1835 |
| 1746 inline PreParserExpression SpreadCall(PreParserExpression function, | 1836 inline PreParserExpression SpreadCall(PreParserExpression function, |
| 1747 PreParserExpressionList args, int pos); | 1837 PreParserExpressionList args, int pos); |
| 1748 | 1838 |
| 1749 inline PreParserExpression SpreadCallNew(PreParserExpression function, | 1839 inline PreParserExpression SpreadCallNew(PreParserExpression function, |
| 1750 PreParserExpressionList args, | 1840 PreParserExpressionList args, |
| 1751 int pos); | 1841 int pos); |
| 1752 | 1842 |
| 1843 inline void RewriteDestructuringAssignments() {} | |
| 1844 | |
| 1845 inline void ShouldRewriteDestructuringAssignment(PreParserExpression) {} | |
| 1846 | |
| 1753 private: | 1847 private: |
| 1754 PreParser* pre_parser_; | 1848 PreParser* pre_parser_; |
| 1755 }; | 1849 }; |
| 1756 | 1850 |
| 1757 | 1851 |
| 1758 // Preparsing checks a JavaScript program and emits preparse-data that helps | 1852 // Preparsing checks a JavaScript program and emits preparse-data that helps |
| 1759 // a later parsing to be faster. | 1853 // a later parsing to be faster. |
| 1760 // See preparse-data-format.h for the data format. | 1854 // See preparse-data-format.h for the data format. |
| 1761 | 1855 |
| 1762 // The PreParser checks that the syntax follows the grammar for JavaScript, | 1856 // The PreParser checks that the syntax follows the grammar for JavaScript, |
| (...skipping 623 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2386 MessageTemplate::kParamAfterRest); | 2480 MessageTemplate::kParamAfterRest); |
| 2387 *ok = false; | 2481 *ok = false; |
| 2388 return this->EmptyExpression(); | 2482 return this->EmptyExpression(); |
| 2389 } | 2483 } |
| 2390 Expect(Token::RPAREN, CHECK_OK); | 2484 Expect(Token::RPAREN, CHECK_OK); |
| 2391 return factory()->NewSpread(expr, ellipsis_pos); | 2485 return factory()->NewSpread(expr, ellipsis_pos); |
| 2392 } | 2486 } |
| 2393 // Heuristically try to detect immediately called functions before | 2487 // Heuristically try to detect immediately called functions before |
| 2394 // seeing the call parentheses. | 2488 // seeing the call parentheses. |
| 2395 parenthesized_function_ = (peek() == Token::FUNCTION); | 2489 parenthesized_function_ = (peek() == Token::FUNCTION); |
| 2396 ExpressionT expr = this->ParseExpression(true, classifier, CHECK_OK); | 2490 ExpressionT expr = this->ParseExpression(true, kIsPossibleArrowFormals, |
| 2491 classifier, CHECK_OK); | |
| 2397 Expect(Token::RPAREN, CHECK_OK); | 2492 Expect(Token::RPAREN, CHECK_OK); |
| 2493 if (peek() != Token::ARROW) { | |
|
adamk
2015/11/25 21:05:28
Sorry, I've forgotten if you've answered this alre
caitp (gmail)
2015/11/25 21:41:52
```
// Valid if: --harmony-destructuring-assignme
adamk
2015/11/25 21:54:20
Thanks!
| |
| 2494 ValidateExpression(classifier, CHECK_OK); | |
| 2495 } | |
| 2398 return expr; | 2496 return expr; |
| 2399 } | 2497 } |
| 2400 | 2498 |
| 2401 case Token::CLASS: { | 2499 case Token::CLASS: { |
| 2402 BindingPatternUnexpectedToken(classifier); | 2500 BindingPatternUnexpectedToken(classifier); |
| 2403 Consume(Token::CLASS); | 2501 Consume(Token::CLASS); |
| 2404 if (!allow_harmony_sloppy() && is_sloppy(language_mode())) { | 2502 if (!allow_harmony_sloppy() && is_sloppy(language_mode())) { |
| 2405 ReportMessage(MessageTemplate::kSloppyLexical); | 2503 ReportMessage(MessageTemplate::kSloppyLexical); |
| 2406 *ok = false; | 2504 *ok = false; |
| 2407 return this->EmptyExpression(); | 2505 return this->EmptyExpression(); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2455 template <class Traits> | 2553 template <class Traits> |
| 2456 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( | 2554 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( |
| 2457 bool accept_IN, bool* ok) { | 2555 bool accept_IN, bool* ok) { |
| 2458 ExpressionClassifier classifier; | 2556 ExpressionClassifier classifier; |
| 2459 ExpressionT result = ParseExpression(accept_IN, &classifier, CHECK_OK); | 2557 ExpressionT result = ParseExpression(accept_IN, &classifier, CHECK_OK); |
| 2460 ValidateExpression(&classifier, CHECK_OK); | 2558 ValidateExpression(&classifier, CHECK_OK); |
| 2461 return result; | 2559 return result; |
| 2462 } | 2560 } |
| 2463 | 2561 |
| 2464 | 2562 |
| 2465 // Precedence = 1 | |
| 2466 template <class Traits> | 2563 template <class Traits> |
| 2467 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( | 2564 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( |
| 2468 bool accept_IN, ExpressionClassifier* classifier, bool* ok) { | 2565 bool accept_IN, ExpressionClassifier* classifier, bool* ok) { |
| 2566 return ParseExpression(accept_IN, kIsLeftHandSide, classifier, ok); | |
| 2567 } | |
| 2568 | |
| 2569 | |
| 2570 template <class Traits> | |
| 2571 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( | |
| 2572 bool accept_IN, int flags, ExpressionClassifier* classifier, bool* ok) { | |
| 2469 // Expression :: | 2573 // Expression :: |
| 2470 // AssignmentExpression | 2574 // AssignmentExpression |
| 2471 // Expression ',' AssignmentExpression | 2575 // Expression ',' AssignmentExpression |
| 2472 | 2576 |
| 2473 ExpressionClassifier binding_classifier; | 2577 ExpressionClassifier binding_classifier; |
| 2474 ExpressionT result = | 2578 ExpressionT result = this->ParseAssignmentExpression( |
| 2475 this->ParseAssignmentExpression(accept_IN, &binding_classifier, CHECK_OK); | 2579 accept_IN, flags, &binding_classifier, CHECK_OK); |
| 2476 classifier->Accumulate(binding_classifier, | 2580 classifier->Accumulate(binding_classifier, |
| 2477 ExpressionClassifier::AllProductions); | 2581 ExpressionClassifier::AllProductions); |
| 2478 bool is_simple_parameter_list = this->IsIdentifier(result); | 2582 bool is_simple_parameter_list = this->IsIdentifier(result); |
| 2479 bool seen_rest = false; | 2583 bool seen_rest = false; |
| 2480 while (peek() == Token::COMMA) { | 2584 while (peek() == Token::COMMA) { |
| 2481 if (seen_rest) { | 2585 if (seen_rest) { |
| 2482 // At this point the production can't possibly be valid, but we don't know | 2586 // At this point the production can't possibly be valid, but we don't know |
| 2483 // which error to signal. | 2587 // which error to signal. |
| 2484 classifier->RecordArrowFormalParametersError( | 2588 classifier->RecordArrowFormalParametersError( |
| 2485 scanner()->peek_location(), MessageTemplate::kParamAfterRest); | 2589 scanner()->peek_location(), MessageTemplate::kParamAfterRest); |
| 2486 } | 2590 } |
| 2487 Consume(Token::COMMA); | 2591 Consume(Token::COMMA); |
| 2488 bool is_rest = false; | 2592 bool is_rest = false; |
| 2489 if (allow_harmony_rest_parameters() && peek() == Token::ELLIPSIS) { | 2593 if (allow_harmony_rest_parameters() && peek() == Token::ELLIPSIS) { |
| 2490 // 'x, y, ...z' in CoverParenthesizedExpressionAndArrowParameterList only | 2594 // 'x, y, ...z' in CoverParenthesizedExpressionAndArrowParameterList only |
| 2491 // as the formal parameters of'(x, y, ...z) => foo', and is not itself a | 2595 // as the formal parameters of'(x, y, ...z) => foo', and is not itself a |
| 2492 // valid expression or binding pattern. | 2596 // valid expression or binding pattern. |
| 2493 ExpressionUnexpectedToken(classifier); | 2597 ExpressionUnexpectedToken(classifier); |
| 2494 BindingPatternUnexpectedToken(classifier); | 2598 BindingPatternUnexpectedToken(classifier); |
| 2495 Consume(Token::ELLIPSIS); | 2599 Consume(Token::ELLIPSIS); |
| 2496 seen_rest = is_rest = true; | 2600 seen_rest = is_rest = true; |
| 2497 } | 2601 } |
| 2498 int pos = position(); | 2602 int pos = position(); |
| 2499 ExpressionT right = this->ParseAssignmentExpression( | 2603 ExpressionT right = this->ParseAssignmentExpression( |
| 2500 accept_IN, &binding_classifier, CHECK_OK); | 2604 accept_IN, flags, &binding_classifier, CHECK_OK); |
| 2501 if (is_rest) right = factory()->NewSpread(right, pos); | 2605 if (is_rest) right = factory()->NewSpread(right, pos); |
| 2502 is_simple_parameter_list = | 2606 is_simple_parameter_list = |
| 2503 is_simple_parameter_list && this->IsIdentifier(right); | 2607 is_simple_parameter_list && this->IsIdentifier(right); |
| 2504 classifier->Accumulate(binding_classifier, | 2608 classifier->Accumulate(binding_classifier, |
| 2505 ExpressionClassifier::AllProductions); | 2609 ExpressionClassifier::AllProductions); |
| 2506 result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos); | 2610 result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos); |
| 2507 } | 2611 } |
| 2508 if (!is_simple_parameter_list || seen_rest) { | 2612 if (!is_simple_parameter_list || seen_rest) { |
| 2509 classifier->RecordNonSimpleParameter(); | 2613 classifier->RecordNonSimpleParameter(); |
| 2510 } | 2614 } |
| 2615 | |
| 2511 return result; | 2616 return result; |
| 2512 } | 2617 } |
| 2513 | 2618 |
| 2514 | 2619 |
| 2515 template <class Traits> | 2620 template <class Traits> |
| 2516 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseArrayLiteral( | 2621 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseArrayLiteral( |
| 2517 ExpressionClassifier* classifier, bool* ok) { | 2622 ExpressionClassifier* classifier, bool* ok) { |
| 2518 // ArrayLiteral :: | 2623 // ArrayLiteral :: |
| 2519 // '[' Expression? (',' Expression?)* ']' | 2624 // '[' Expression? (',' Expression?)* ']' |
| 2520 | 2625 |
| 2521 int pos = peek_position(); | 2626 int pos = peek_position(); |
| 2522 typename Traits::Type::ExpressionList values = | 2627 typename Traits::Type::ExpressionList values = |
| 2523 this->NewExpressionList(4, zone_); | 2628 this->NewExpressionList(4, zone_); |
| 2524 int first_spread_index = -1; | 2629 int first_spread_index = -1; |
| 2525 Expect(Token::LBRACK, CHECK_OK); | 2630 Expect(Token::LBRACK, CHECK_OK); |
| 2526 while (peek() != Token::RBRACK) { | 2631 while (peek() != Token::RBRACK) { |
| 2527 bool seen_spread = false; | 2632 bool seen_spread = false; |
|
adamk
2015/11/25 21:05:28
This bool is now unused.
caitp (gmail)
2015/11/25 21:41:52
Acknowledged.
| |
| 2528 ExpressionT elem = this->EmptyExpression(); | 2633 ExpressionT elem = this->EmptyExpression(); |
| 2529 if (peek() == Token::COMMA) { | 2634 if (peek() == Token::COMMA) { |
| 2530 if (is_strong(language_mode())) { | 2635 if (is_strong(language_mode())) { |
| 2531 ReportMessageAt(scanner()->peek_location(), | 2636 ReportMessageAt(scanner()->peek_location(), |
| 2532 MessageTemplate::kStrongEllision); | 2637 MessageTemplate::kStrongEllision); |
| 2533 *ok = false; | 2638 *ok = false; |
| 2534 return this->EmptyExpression(); | 2639 return this->EmptyExpression(); |
| 2535 } | 2640 } |
| 2536 elem = this->GetLiteralTheHole(peek_position(), factory()); | 2641 elem = this->GetLiteralTheHole(peek_position(), factory()); |
| 2537 } else if (peek() == Token::ELLIPSIS) { | 2642 } else if (peek() == Token::ELLIPSIS) { |
| 2538 int start_pos = peek_position(); | 2643 int start_pos = peek_position(); |
| 2539 Consume(Token::ELLIPSIS); | 2644 Consume(Token::ELLIPSIS); |
| 2540 ExpressionT argument = | 2645 ExpressionT argument = |
| 2541 this->ParseAssignmentExpression(true, classifier, CHECK_OK); | 2646 this->ParseAssignmentExpression(true, classifier, CHECK_OK); |
| 2542 elem = factory()->NewSpread(argument, start_pos); | 2647 elem = factory()->NewSpread(argument, start_pos); |
| 2543 seen_spread = true; | 2648 seen_spread = true; |
| 2544 if (first_spread_index < 0) { | 2649 if (first_spread_index < 0) { |
| 2545 first_spread_index = values->length(); | 2650 first_spread_index = values->length(); |
| 2546 } | 2651 } |
| 2652 | |
| 2653 CheckDestructuringElement(argument, classifier, start_pos, | |
| 2654 scanner()->location().end_pos); | |
| 2655 | |
| 2656 if (peek() == Token::COMMA) { | |
| 2657 classifier->RecordPatternError( | |
| 2658 Scanner::Location(start_pos, scanner()->location().end_pos), | |
| 2659 MessageTemplate::kElementAfterRest); | |
| 2660 } | |
| 2547 } else { | 2661 } else { |
| 2548 elem = this->ParseAssignmentExpression(true, classifier, CHECK_OK); | 2662 elem = this->ParseAssignmentExpression(true, kIsPatternElement, |
| 2663 classifier, CHECK_OK); | |
| 2664 if (!this->IsValidReferenceExpression(elem) && | |
| 2665 !classifier->is_valid_assignment_pattern()) { | |
| 2666 classifier->RecordPatternError( | |
| 2667 Scanner::Location(pos, scanner()->location().end_pos), | |
| 2668 MessageTemplate::kInvalidDestructuringTarget); | |
| 2669 } | |
| 2549 } | 2670 } |
| 2550 values->Add(elem, zone_); | 2671 values->Add(elem, zone_); |
| 2551 if (peek() != Token::RBRACK) { | 2672 if (peek() != Token::RBRACK) { |
| 2552 if (seen_spread) { | |
| 2553 BindingPatternUnexpectedToken(classifier); | |
| 2554 } | |
| 2555 Expect(Token::COMMA, CHECK_OK); | 2673 Expect(Token::COMMA, CHECK_OK); |
| 2556 } | 2674 } |
| 2557 } | 2675 } |
| 2558 Expect(Token::RBRACK, CHECK_OK); | 2676 Expect(Token::RBRACK, CHECK_OK); |
| 2559 | 2677 |
| 2560 // Update the scope information before the pre-parsing bailout. | 2678 // Update the scope information before the pre-parsing bailout. |
| 2561 int literal_index = function_state_->NextMaterializedLiteralIndex(); | 2679 int literal_index = function_state_->NextMaterializedLiteralIndex(); |
| 2562 | 2680 |
| 2563 return factory()->NewArrayLiteral(values, first_spread_index, literal_index, | 2681 return factory()->NewArrayLiteral(values, first_spread_index, literal_index, |
| 2564 is_strong(language_mode()), pos); | 2682 is_strong(language_mode()), pos); |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2668 DCHECK(!is_static); | 2786 DCHECK(!is_static); |
| 2669 | 2787 |
| 2670 if (peek() == Token::COLON) { | 2788 if (peek() == Token::COLON) { |
| 2671 // PropertyDefinition | 2789 // PropertyDefinition |
| 2672 // PropertyName ':' AssignmentExpression | 2790 // PropertyName ':' AssignmentExpression |
| 2673 if (!*is_computed_name) { | 2791 if (!*is_computed_name) { |
| 2674 checker->CheckProperty(name_token, kValueProperty, false, false, | 2792 checker->CheckProperty(name_token, kValueProperty, false, false, |
| 2675 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2793 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 2676 } | 2794 } |
| 2677 Consume(Token::COLON); | 2795 Consume(Token::COLON); |
| 2796 int pos = peek_position(); | |
| 2678 value = this->ParseAssignmentExpression( | 2797 value = this->ParseAssignmentExpression( |
| 2679 true, classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2798 true, kIsPatternElement, classifier, |
| 2799 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | |
| 2800 | |
| 2801 if (!this->IsValidReferenceExpression(value) && | |
| 2802 !classifier->is_valid_assignment_pattern()) { | |
| 2803 classifier->RecordPatternError( | |
| 2804 Scanner::Location(pos, scanner()->location().end_pos), | |
| 2805 MessageTemplate::kInvalidDestructuringTarget); | |
| 2806 } | |
| 2807 | |
| 2680 return factory()->NewObjectLiteralProperty(name_expression, value, false, | 2808 return factory()->NewObjectLiteralProperty(name_expression, value, false, |
| 2681 *is_computed_name); | 2809 *is_computed_name); |
| 2682 } | 2810 } |
| 2683 | 2811 |
| 2684 if ((is_identifier || is_escaped_keyword) && | 2812 if ((is_identifier || is_escaped_keyword) && |
| 2685 (peek() == Token::COMMA || peek() == Token::RBRACE || | 2813 (peek() == Token::COMMA || peek() == Token::RBRACE || |
| 2686 peek() == Token::ASSIGN)) { | 2814 peek() == Token::ASSIGN)) { |
| 2687 // PropertyDefinition | 2815 // PropertyDefinition |
| 2688 // IdentifierReference | 2816 // IdentifierReference |
| 2689 // CoverInitializedName | 2817 // CoverInitializedName |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 2704 } | 2832 } |
| 2705 if (name_token == Token::LET) { | 2833 if (name_token == Token::LET) { |
| 2706 classifier->RecordLetPatternError( | 2834 classifier->RecordLetPatternError( |
| 2707 scanner()->location(), MessageTemplate::kLetInLexicalBinding); | 2835 scanner()->location(), MessageTemplate::kLetInLexicalBinding); |
| 2708 } | 2836 } |
| 2709 | 2837 |
| 2710 ExpressionT lhs = this->ExpressionFromIdentifier( | 2838 ExpressionT lhs = this->ExpressionFromIdentifier( |
| 2711 name, next_beg_pos, next_end_pos, scope_, factory()); | 2839 name, next_beg_pos, next_end_pos, scope_, factory()); |
| 2712 | 2840 |
| 2713 if (peek() == Token::ASSIGN) { | 2841 if (peek() == Token::ASSIGN) { |
| 2714 this->ExpressionUnexpectedToken(classifier); | |
| 2715 Consume(Token::ASSIGN); | 2842 Consume(Token::ASSIGN); |
| 2716 ExpressionClassifier rhs_classifier; | 2843 ExpressionClassifier rhs_classifier; |
| 2717 ExpressionT rhs = this->ParseAssignmentExpression( | 2844 ExpressionT rhs = this->ParseAssignmentExpression( |
| 2718 true, &rhs_classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2845 true, &rhs_classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 2719 classifier->Accumulate(rhs_classifier, | 2846 classifier->Accumulate(rhs_classifier, |
| 2720 ExpressionClassifier::ExpressionProductions); | 2847 ExpressionClassifier::ExpressionProductions); |
| 2721 value = factory()->NewAssignment(Token::ASSIGN, lhs, rhs, | 2848 value = factory()->NewAssignment(Token::ASSIGN, lhs, rhs, |
| 2722 RelocInfo::kNoPosition); | 2849 RelocInfo::kNoPosition); |
| 2850 classifier->RecordCoverInitializedNameError( | |
| 2851 Scanner::Location(next_beg_pos, scanner()->location().end_pos), | |
| 2852 MessageTemplate::kInvalidCoverInitializedName); | |
| 2723 } else { | 2853 } else { |
| 2724 value = lhs; | 2854 value = lhs; |
| 2725 } | 2855 } |
| 2726 | 2856 |
| 2727 return factory()->NewObjectLiteralProperty( | 2857 return factory()->NewObjectLiteralProperty( |
| 2728 name_expression, value, ObjectLiteralProperty::COMPUTED, false, | 2858 name_expression, value, ObjectLiteralProperty::COMPUTED, false, |
| 2729 false); | 2859 false); |
| 2730 } | 2860 } |
| 2731 } | 2861 } |
| 2732 | 2862 |
| 2733 if (in_class && escaped_static && !is_static) { | 2863 if (in_class && escaped_static && !is_static) { |
| 2734 ReportUnexpectedTokenAt(scanner()->location(), name_token); | 2864 ReportUnexpectedTokenAt(scanner()->location(), name_token); |
| 2735 *ok = false; | 2865 *ok = false; |
| 2736 return this->EmptyObjectLiteralProperty(); | 2866 return this->EmptyObjectLiteralProperty(); |
| 2737 } | 2867 } |
| 2738 | 2868 |
| 2869 // Method definitions are never valid in patterns. | |
| 2870 classifier->RecordPatternError( | |
| 2871 Scanner::Location(next_beg_pos, scanner()->location().end_pos), | |
| 2872 MessageTemplate::kInvalidDestructuringTarget); | |
| 2873 | |
| 2739 if (is_generator || peek() == Token::LPAREN) { | 2874 if (is_generator || peek() == Token::LPAREN) { |
| 2740 // MethodDefinition | 2875 // MethodDefinition |
| 2741 // PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' | 2876 // PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' |
| 2742 // '*' PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' | 2877 // '*' PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' |
| 2743 if (!*is_computed_name) { | 2878 if (!*is_computed_name) { |
| 2744 checker->CheckProperty(name_token, kMethodProperty, is_static, | 2879 checker->CheckProperty(name_token, kMethodProperty, is_static, |
| 2745 is_generator, | 2880 is_generator, |
| 2746 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2881 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 2747 } | 2882 } |
| 2748 | 2883 |
| (...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2951 // the parser and preparser | 3086 // the parser and preparser |
| 2952 Traits::MaterializeUnspreadArgumentsLiterals(unspread_sequences_count); | 3087 Traits::MaterializeUnspreadArgumentsLiterals(unspread_sequences_count); |
| 2953 } | 3088 } |
| 2954 | 3089 |
| 2955 return result; | 3090 return result; |
| 2956 } | 3091 } |
| 2957 | 3092 |
| 2958 // Precedence = 2 | 3093 // Precedence = 2 |
| 2959 template <class Traits> | 3094 template <class Traits> |
| 2960 typename ParserBase<Traits>::ExpressionT | 3095 typename ParserBase<Traits>::ExpressionT |
| 2961 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, | 3096 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, int flags, |
| 2962 ExpressionClassifier* classifier, | 3097 ExpressionClassifier* classifier, |
| 2963 bool* ok) { | 3098 bool* ok) { |
| 2964 // AssignmentExpression :: | 3099 // AssignmentExpression :: |
| 2965 // ConditionalExpression | 3100 // ConditionalExpression |
| 2966 // ArrowFunction | 3101 // ArrowFunction |
| 2967 // YieldExpression | 3102 // YieldExpression |
| 2968 // LeftHandSideExpression AssignmentOperator AssignmentExpression | 3103 // LeftHandSideExpression AssignmentOperator AssignmentExpression |
| 2969 | 3104 bool is_rhs = flags & kIsRightHandSide; |
| 3105 bool is_pattern_element = flags & kIsPatternElement; | |
| 3106 bool is_destructuring_assignment = false; | |
| 3107 bool is_arrow_formals = flags & kIsPossibleArrowFormals; | |
| 3108 USE(is_arrow_formals); | |
|
adamk
2015/11/25 21:05:28
This USE is not needed.
caitp (gmail)
2015/11/25 21:41:52
Acknowledged.
| |
| 2970 int lhs_beg_pos = peek_position(); | 3109 int lhs_beg_pos = peek_position(); |
| 2971 | 3110 |
| 2972 if (peek() == Token::YIELD && is_generator()) { | 3111 if (peek() == Token::YIELD && is_generator()) { |
| 2973 return this->ParseYieldExpression(classifier, ok); | 3112 return this->ParseYieldExpression(classifier, ok); |
| 2974 } | 3113 } |
| 2975 | 3114 |
| 2976 if (fni_ != NULL) fni_->Enter(); | 3115 if (fni_ != NULL) fni_->Enter(); |
| 2977 ParserBase<Traits>::Checkpoint checkpoint(this); | 3116 ParserBase<Traits>::Checkpoint checkpoint(this); |
| 2978 ExpressionClassifier arrow_formals_classifier(classifier->duplicate_finder()); | 3117 ExpressionClassifier arrow_formals_classifier(classifier->duplicate_finder()); |
| 2979 bool parenthesized_formals = peek() == Token::LPAREN; | 3118 bool parenthesized_formals = peek() == Token::LPAREN; |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 3005 | 3144 |
| 3006 checkpoint.Restore(¶meters.materialized_literals_count); | 3145 checkpoint.Restore(¶meters.materialized_literals_count); |
| 3007 | 3146 |
| 3008 scope->set_start_position(lhs_beg_pos); | 3147 scope->set_start_position(lhs_beg_pos); |
| 3009 if (duplicate_loc.IsValid()) { | 3148 if (duplicate_loc.IsValid()) { |
| 3010 arrow_formals_classifier.RecordDuplicateFormalParameterError( | 3149 arrow_formals_classifier.RecordDuplicateFormalParameterError( |
| 3011 duplicate_loc); | 3150 duplicate_loc); |
| 3012 } | 3151 } |
| 3013 expression = this->ParseArrowFunctionLiteral( | 3152 expression = this->ParseArrowFunctionLiteral( |
| 3014 accept_IN, parameters, arrow_formals_classifier, CHECK_OK); | 3153 accept_IN, parameters, arrow_formals_classifier, CHECK_OK); |
| 3154 if (is_pattern_element) { | |
| 3155 classifier->RecordPatternError( | |
| 3156 Scanner::Location(lhs_beg_pos, scanner()->location().end_pos), | |
| 3157 MessageTemplate::kInvalidDestructuringTarget); | |
| 3158 } | |
| 3015 return expression; | 3159 return expression; |
| 3016 } | 3160 } |
| 3017 | 3161 |
| 3162 if (this->IsValidReferenceExpression(expression)) { | |
| 3163 arrow_formals_classifier.ForgiveAssignmentPatternError(); | |
| 3164 } | |
| 3165 | |
| 3018 // "expression" was not itself an arrow function parameter list, but it might | 3166 // "expression" was not itself an arrow function parameter list, but it might |
| 3019 // form part of one. Propagate speculative formal parameter error locations. | 3167 // form part of one. Propagate speculative formal parameter error locations. |
| 3020 classifier->Accumulate(arrow_formals_classifier, | 3168 classifier->Accumulate( |
| 3021 ExpressionClassifier::StandardProductions | | 3169 arrow_formals_classifier, |
| 3022 ExpressionClassifier::FormalParametersProductions); | 3170 ExpressionClassifier::StandardProductions | |
| 3171 ExpressionClassifier::FormalParametersProductions | | |
| 3172 ExpressionClassifier::CoverInitializedNameProduction); | |
| 3173 | |
| 3174 bool maybe_pattern = | |
| 3175 expression->IsObjectLiteral() || expression->IsArrayLiteral(); | |
| 3176 // bool binding_pattern = | |
| 3177 // allow_harmony_destructuring_bind() && maybe_pattern && !is_rhs; | |
| 3023 | 3178 |
| 3024 if (!Token::IsAssignmentOp(peek())) { | 3179 if (!Token::IsAssignmentOp(peek())) { |
| 3025 if (fni_ != NULL) fni_->Leave(); | 3180 if (fni_ != NULL) fni_->Leave(); |
| 3026 // Parsed conditional expression only (no assignment). | 3181 // Parsed conditional expression only (no assignment). |
| 3182 if (is_pattern_element && !this->IsValidReferenceExpression(expression) && | |
| 3183 !maybe_pattern) { | |
| 3184 classifier->RecordPatternError( | |
| 3185 Scanner::Location(lhs_beg_pos, scanner()->location().end_pos), | |
| 3186 MessageTemplate::kInvalidDestructuringTarget); | |
| 3187 } else if (is_rhs && maybe_pattern) { | |
| 3188 ValidateExpression(classifier, CHECK_OK); | |
| 3189 } | |
| 3190 | |
| 3027 return expression; | 3191 return expression; |
| 3028 } | 3192 } |
| 3029 | 3193 |
| 3030 if (!(allow_harmony_destructuring_bind() || | 3194 if (!(allow_harmony_destructuring_bind() || |
| 3031 allow_harmony_default_parameters())) { | 3195 allow_harmony_default_parameters())) { |
| 3032 BindingPatternUnexpectedToken(classifier); | 3196 BindingPatternUnexpectedToken(classifier); |
| 3033 } | 3197 } |
| 3034 | 3198 |
| 3035 expression = this->CheckAndRewriteReferenceExpression( | 3199 if (allow_harmony_destructuring_assignment() && maybe_pattern && |
| 3036 expression, lhs_beg_pos, scanner()->location().end_pos, | 3200 peek() == Token::ASSIGN) { |
| 3037 MessageTemplate::kInvalidLhsInAssignment, CHECK_OK); | 3201 classifier->ForgiveCoverInitializedNameError(); |
| 3202 ValidateAssignmentPattern(classifier, CHECK_OK); | |
| 3203 is_destructuring_assignment = true; | |
| 3204 } else if (is_arrow_formals) { | |
| 3205 expression = this->ClassifyAndRewriteReferenceExpression( | |
| 3206 classifier, expression, lhs_beg_pos, scanner()->location().end_pos, | |
| 3207 MessageTemplate::kInvalidLhsInAssignment); | |
| 3208 } else { | |
| 3209 expression = this->CheckAndRewriteReferenceExpression( | |
| 3210 expression, lhs_beg_pos, scanner()->location().end_pos, | |
| 3211 MessageTemplate::kInvalidLhsInAssignment, CHECK_OK); | |
| 3212 } | |
| 3213 | |
| 3038 expression = this->MarkExpressionAsAssigned(expression); | 3214 expression = this->MarkExpressionAsAssigned(expression); |
| 3039 | 3215 |
| 3040 Token::Value op = Next(); // Get assignment operator. | 3216 Token::Value op = Next(); // Get assignment operator. |
| 3041 if (op != Token::ASSIGN) { | 3217 if (op != Token::ASSIGN) { |
| 3042 classifier->RecordBindingPatternError(scanner()->location(), | 3218 classifier->RecordBindingPatternError(scanner()->location(), |
| 3043 MessageTemplate::kUnexpectedToken, | 3219 MessageTemplate::kUnexpectedToken, |
| 3044 Token::String(op)); | 3220 Token::String(op)); |
| 3045 } | 3221 } |
| 3046 int pos = position(); | 3222 int pos = position(); |
| 3047 | 3223 |
| 3048 ExpressionClassifier rhs_classifier; | 3224 ExpressionClassifier rhs_classifier; |
| 3049 ExpressionT right = | 3225 |
| 3050 this->ParseAssignmentExpression(accept_IN, &rhs_classifier, CHECK_OK); | 3226 int rhs_flags = flags; |
| 3051 classifier->Accumulate(rhs_classifier, | 3227 rhs_flags &= ~(kIsPatternElement | kIsPossibleArrowFormals); |
| 3052 ExpressionClassifier::ExpressionProductions); | 3228 rhs_flags |= kIsRightHandSide; |
| 3229 ExpressionT right = this->ParseAssignmentExpression( | |
| 3230 accept_IN, rhs_flags, &rhs_classifier, CHECK_OK); | |
| 3231 classifier->Accumulate( | |
| 3232 rhs_classifier, ExpressionClassifier::ExpressionProductions | | |
| 3233 ExpressionClassifier::CoverInitializedNameProduction); | |
| 3053 | 3234 |
| 3054 // TODO(1231235): We try to estimate the set of properties set by | 3235 // TODO(1231235): We try to estimate the set of properties set by |
| 3055 // constructors. We define a new property whenever there is an | 3236 // constructors. We define a new property whenever there is an |
| 3056 // assignment to a property of 'this'. We should probably only add | 3237 // assignment to a property of 'this'. We should probably only add |
| 3057 // properties if we haven't seen them before. Otherwise we'll | 3238 // properties if we haven't seen them before. Otherwise we'll |
| 3058 // probably overestimate the number of properties. | 3239 // probably overestimate the number of properties. |
| 3059 if (op == Token::ASSIGN && this->IsThisProperty(expression)) { | 3240 if (op == Token::ASSIGN && this->IsThisProperty(expression)) { |
| 3060 function_state_->AddProperty(); | 3241 function_state_->AddProperty(); |
| 3061 } | 3242 } |
| 3062 | 3243 |
| 3063 this->CheckAssigningFunctionLiteralToProperty(expression, right); | 3244 this->CheckAssigningFunctionLiteralToProperty(expression, right); |
| 3064 | 3245 |
| 3065 if (fni_ != NULL) { | 3246 if (fni_ != NULL) { |
| 3066 // Check if the right hand side is a call to avoid inferring a | 3247 // Check if the right hand side is a call to avoid inferring a |
| 3067 // name if we're dealing with "a = function(){...}();"-like | 3248 // name if we're dealing with "a = function(){...}();"-like |
| 3068 // expression. | 3249 // expression. |
| 3069 if ((op == Token::INIT || op == Token::ASSIGN) && | 3250 if ((op == Token::INIT || op == Token::ASSIGN) && |
| 3070 (!right->IsCall() && !right->IsCallNew())) { | 3251 (!right->IsCall() && !right->IsCallNew())) { |
| 3071 fni_->Infer(); | 3252 fni_->Infer(); |
| 3072 } else { | 3253 } else { |
| 3073 fni_->RemoveLastFunction(); | 3254 fni_->RemoveLastFunction(); |
| 3074 } | 3255 } |
| 3075 fni_->Leave(); | 3256 fni_->Leave(); |
| 3076 } | 3257 } |
| 3077 | 3258 |
| 3078 return factory()->NewAssignment(op, expression, right, pos); | 3259 ExpressionT result = factory()->NewAssignment(op, expression, right, pos); |
| 3260 | |
| 3261 if (is_destructuring_assignment) { | |
| 3262 Traits::ShouldRewriteDestructuringAssignment(result); | |
| 3263 } | |
| 3264 | |
| 3265 return result; | |
| 3079 } | 3266 } |
| 3080 | 3267 |
| 3081 template <class Traits> | 3268 template <class Traits> |
| 3082 typename ParserBase<Traits>::ExpressionT | 3269 typename ParserBase<Traits>::ExpressionT |
| 3083 ParserBase<Traits>::ParseYieldExpression(ExpressionClassifier* classifier, | 3270 ParserBase<Traits>::ParseYieldExpression(ExpressionClassifier* classifier, |
| 3084 bool* ok) { | 3271 bool* ok) { |
| 3085 // YieldExpression :: | 3272 // YieldExpression :: |
| 3086 // 'yield' ([no line terminator] '*'? AssignmentExpression)? | 3273 // 'yield' ([no line terminator] '*'? AssignmentExpression)? |
| 3087 int pos = peek_position(); | 3274 int pos = peek_position(); |
| 3088 BindingPatternUnexpectedToken(classifier); | 3275 BindingPatternUnexpectedToken(classifier); |
| (...skipping 937 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4026 allow_duplicate_parameters, CHECK_OK); | 4213 allow_duplicate_parameters, CHECK_OK); |
| 4027 | 4214 |
| 4028 // Validate strict mode. | 4215 // Validate strict mode. |
| 4029 if (is_strict(language_mode())) { | 4216 if (is_strict(language_mode())) { |
| 4030 CheckStrictOctalLiteral(formal_parameters.scope->start_position(), | 4217 CheckStrictOctalLiteral(formal_parameters.scope->start_position(), |
| 4031 scanner()->location().end_pos, CHECK_OK); | 4218 scanner()->location().end_pos, CHECK_OK); |
| 4032 } | 4219 } |
| 4033 if (is_strict(language_mode()) || allow_harmony_sloppy()) { | 4220 if (is_strict(language_mode()) || allow_harmony_sloppy()) { |
| 4034 this->CheckConflictingVarDeclarations(formal_parameters.scope, CHECK_OK); | 4221 this->CheckConflictingVarDeclarations(formal_parameters.scope, CHECK_OK); |
| 4035 } | 4222 } |
| 4223 | |
| 4224 Traits::RewriteDestructuringAssignments(); | |
| 4036 } | 4225 } |
| 4037 | 4226 |
| 4038 FunctionLiteralT function_literal = factory()->NewFunctionLiteral( | 4227 FunctionLiteralT function_literal = factory()->NewFunctionLiteral( |
| 4039 this->EmptyIdentifierString(), ast_value_factory(), | 4228 this->EmptyIdentifierString(), ast_value_factory(), |
| 4040 formal_parameters.scope, body, materialized_literal_count, | 4229 formal_parameters.scope, body, materialized_literal_count, |
| 4041 expected_property_count, num_parameters, | 4230 expected_property_count, num_parameters, |
| 4042 FunctionLiteral::kNoDuplicateParameters, | 4231 FunctionLiteral::kNoDuplicateParameters, |
| 4043 FunctionLiteral::ANONYMOUS_EXPRESSION, FunctionLiteral::kIsFunction, | 4232 FunctionLiteral::ANONYMOUS_EXPRESSION, FunctionLiteral::kIsFunction, |
| 4044 FunctionLiteral::kShouldLazyCompile, FunctionKind::kArrowFunction, | 4233 FunctionLiteral::kShouldLazyCompile, FunctionKind::kArrowFunction, |
| 4045 formal_parameters.scope->start_position()); | 4234 formal_parameters.scope->start_position()); |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4157 return this->CheckAndRewriteReferenceExpression(expression, beg_pos, end_pos, | 4346 return this->CheckAndRewriteReferenceExpression(expression, beg_pos, end_pos, |
| 4158 message, kReferenceError, ok); | 4347 message, kReferenceError, ok); |
| 4159 } | 4348 } |
| 4160 | 4349 |
| 4161 | 4350 |
| 4162 template <typename Traits> | 4351 template <typename Traits> |
| 4163 typename ParserBase<Traits>::ExpressionT | 4352 typename ParserBase<Traits>::ExpressionT |
| 4164 ParserBase<Traits>::CheckAndRewriteReferenceExpression( | 4353 ParserBase<Traits>::CheckAndRewriteReferenceExpression( |
| 4165 ExpressionT expression, int beg_pos, int end_pos, | 4354 ExpressionT expression, int beg_pos, int end_pos, |
| 4166 MessageTemplate::Template message, ParseErrorType type, bool* ok) { | 4355 MessageTemplate::Template message, ParseErrorType type, bool* ok) { |
| 4356 ExpressionClassifier classifier; | |
| 4357 ExpressionT result = ClassifyAndRewriteReferenceExpression( | |
| 4358 &classifier, expression, beg_pos, end_pos, message, type); | |
| 4359 ValidateExpression(&classifier, ok); | |
| 4360 if (!*ok) return this->EmptyExpression(); | |
| 4361 return result; | |
| 4362 } | |
| 4363 | |
| 4364 | |
| 4365 template <typename Traits> | |
| 4366 typename ParserBase<Traits>::ExpressionT | |
| 4367 ParserBase<Traits>::ClassifyAndRewriteReferenceExpression( | |
| 4368 ExpressionClassifier* classifier, ExpressionT expression, int beg_pos, | |
| 4369 int end_pos, MessageTemplate::Template message, ParseErrorType type) { | |
| 4167 Scanner::Location location(beg_pos, end_pos); | 4370 Scanner::Location location(beg_pos, end_pos); |
| 4168 if (this->IsIdentifier(expression)) { | 4371 if (this->IsIdentifier(expression)) { |
| 4169 if (is_strict(language_mode()) && | 4372 if (is_strict(language_mode()) && |
| 4170 this->IsEvalOrArguments(this->AsIdentifier(expression))) { | 4373 this->IsEvalOrArguments(this->AsIdentifier(expression))) { |
| 4171 this->ReportMessageAt(location, MessageTemplate::kStrictEvalArguments, | 4374 classifier->RecordExpressionError( |
| 4172 kSyntaxError); | 4375 location, MessageTemplate::kStrictEvalArguments, kSyntaxError); |
| 4173 *ok = false; | 4376 return expression; |
| 4174 return this->EmptyExpression(); | |
| 4175 } | 4377 } |
| 4176 if (is_strong(language_mode()) && | 4378 if (is_strong(language_mode()) && |
| 4177 this->IsUndefined(this->AsIdentifier(expression))) { | 4379 this->IsUndefined(this->AsIdentifier(expression))) { |
| 4178 this->ReportMessageAt(location, MessageTemplate::kStrongUndefined, | 4380 classifier->RecordExpressionError( |
| 4179 kSyntaxError); | 4381 location, MessageTemplate::kStrongUndefined, kSyntaxError); |
| 4180 *ok = false; | 4382 return expression; |
| 4181 return this->EmptyExpression(); | |
| 4182 } | 4383 } |
| 4183 } | 4384 } |
| 4184 if (expression->IsValidReferenceExpression()) { | 4385 if (expression->IsValidReferenceExpression()) { |
| 4185 return expression; | 4386 return expression; |
| 4186 } else if (expression->IsCall()) { | 4387 } else if (expression->IsCall()) { |
| 4187 // If it is a call, make it a runtime error for legacy web compatibility. | 4388 // If it is a call, make it a runtime error for legacy web compatibility. |
| 4188 // Rewrite `expr' to `expr[throw ReferenceError]'. | 4389 // Rewrite `expr' to `expr[throw ReferenceError]'. |
| 4189 int pos = location.beg_pos; | 4390 int pos = location.beg_pos; |
| 4190 ExpressionT error = this->NewThrowReferenceError(message, pos); | 4391 ExpressionT error = this->NewThrowReferenceError(message, pos); |
| 4191 return factory()->NewProperty(expression, error, pos); | 4392 return factory()->NewProperty(expression, error, pos); |
| 4192 } else { | 4393 } else { |
| 4193 this->ReportMessageAt(location, message, type); | 4394 classifier->RecordExpressionError(location, message, type); |
| 4194 *ok = false; | 4395 return expression; |
| 4195 return this->EmptyExpression(); | |
| 4196 } | 4396 } |
| 4197 } | 4397 } |
| 4198 | 4398 |
| 4399 | |
| 4400 template <typename Traits> | |
| 4401 bool ParserBase<Traits>::IsValidReferenceExpression(ExpressionT expression) { | |
| 4402 return this->IsAssignableIdentifier(expression) || expression->IsProperty(); | |
| 4403 } | |
| 4404 | |
| 4405 | |
| 4406 template <typename Traits> | |
| 4407 void ParserBase<Traits>::CheckDestructuringElement( | |
| 4408 ExpressionT expression, ExpressionClassifier* classifier, int begin, | |
| 4409 int end) { | |
| 4410 static const MessageTemplate::Template message = | |
| 4411 MessageTemplate::kInvalidDestructuringTarget; | |
| 4412 if (!this->IsAssignableIdentifier(expression)) { | |
| 4413 const Scanner::Location location(begin, end); | |
| 4414 classifier->RecordBindingPatternError(location, message); | |
| 4415 if (!expression->IsProperty() && | |
| 4416 !(expression->IsObjectLiteral() || expression->IsArrayLiteral())) { | |
| 4417 classifier->RecordAssignmentPatternError(location, message); | |
| 4418 } | |
| 4419 } | |
| 4420 } | |
| 4421 | |
| 4199 | 4422 |
| 4200 #undef CHECK_OK | 4423 #undef CHECK_OK |
| 4201 #undef CHECK_OK_CUSTOM | 4424 #undef CHECK_OK_CUSTOM |
| 4202 | 4425 |
| 4203 | 4426 |
| 4204 template <typename Traits> | 4427 template <typename Traits> |
| 4205 void ParserBase<Traits>::ObjectLiteralChecker::CheckProperty( | 4428 void ParserBase<Traits>::ObjectLiteralChecker::CheckProperty( |
| 4206 Token::Value property, PropertyKind type, bool is_static, bool is_generator, | 4429 Token::Value property, PropertyKind type, bool is_static, bool is_generator, |
| 4207 bool* ok) { | 4430 bool* ok) { |
| 4208 DCHECK(!is_static); | 4431 DCHECK(!is_static); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4251 return; | 4474 return; |
| 4252 } | 4475 } |
| 4253 has_seen_constructor_ = true; | 4476 has_seen_constructor_ = true; |
| 4254 return; | 4477 return; |
| 4255 } | 4478 } |
| 4256 } | 4479 } |
| 4257 } // namespace internal | 4480 } // namespace internal |
| 4258 } // namespace v8 | 4481 } // namespace v8 |
| 4259 | 4482 |
| 4260 #endif // V8_PREPARSER_H | 4483 #endif // V8_PREPARSER_H |
| OLD | NEW |