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 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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_spread_calls_(false), | 116 allow_harmony_spread_calls_(false), |
117 allow_harmony_destructuring_(false), | 117 allow_harmony_destructuring_(false), |
| 118 allow_harmony_destructuring_assignment_(false), |
118 allow_harmony_spread_arrays_(false), | 119 allow_harmony_spread_arrays_(false), |
119 allow_harmony_new_target_(false), | 120 allow_harmony_new_target_(false), |
120 allow_strong_mode_(false), | 121 allow_strong_mode_(false), |
121 allow_legacy_const_(true), | 122 allow_legacy_const_(true), |
122 allow_harmony_do_expressions_(false) {} | 123 allow_harmony_do_expressions_(false) {} |
123 | 124 |
124 #define ALLOW_ACCESSORS(name) \ | 125 #define ALLOW_ACCESSORS(name) \ |
125 bool allow_##name() const { return allow_##name##_; } \ | 126 bool allow_##name() const { return allow_##name##_; } \ |
126 void set_allow_##name(bool allow) { allow_##name##_ = allow; } | 127 void set_allow_##name(bool allow) { allow_##name##_ = allow; } |
127 | 128 |
128 ALLOW_ACCESSORS(lazy); | 129 ALLOW_ACCESSORS(lazy); |
129 ALLOW_ACCESSORS(natives); | 130 ALLOW_ACCESSORS(natives); |
130 ALLOW_ACCESSORS(harmony_sloppy); | 131 ALLOW_ACCESSORS(harmony_sloppy); |
131 ALLOW_ACCESSORS(harmony_sloppy_function); | 132 ALLOW_ACCESSORS(harmony_sloppy_function); |
132 ALLOW_ACCESSORS(harmony_sloppy_let); | 133 ALLOW_ACCESSORS(harmony_sloppy_let); |
133 ALLOW_ACCESSORS(harmony_rest_parameters); | 134 ALLOW_ACCESSORS(harmony_rest_parameters); |
134 ALLOW_ACCESSORS(harmony_default_parameters); | 135 ALLOW_ACCESSORS(harmony_default_parameters); |
135 ALLOW_ACCESSORS(harmony_spread_calls); | 136 ALLOW_ACCESSORS(harmony_spread_calls); |
136 ALLOW_ACCESSORS(harmony_destructuring); | 137 ALLOW_ACCESSORS(harmony_destructuring); |
| 138 ALLOW_ACCESSORS(harmony_destructuring_assignment); |
137 ALLOW_ACCESSORS(harmony_spread_arrays); | 139 ALLOW_ACCESSORS(harmony_spread_arrays); |
138 ALLOW_ACCESSORS(harmony_new_target); | 140 ALLOW_ACCESSORS(harmony_new_target); |
139 ALLOW_ACCESSORS(strong_mode); | 141 ALLOW_ACCESSORS(strong_mode); |
140 ALLOW_ACCESSORS(legacy_const); | 142 ALLOW_ACCESSORS(legacy_const); |
141 ALLOW_ACCESSORS(harmony_do_expressions); | 143 ALLOW_ACCESSORS(harmony_do_expressions); |
142 #undef ALLOW_ACCESSORS | 144 #undef ALLOW_ACCESSORS |
143 | 145 |
144 uintptr_t stack_limit() const { return stack_limit_; } | 146 uintptr_t stack_limit() const { return stack_limit_; } |
145 | 147 |
146 protected: | 148 protected: |
(...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
542 Scanner::Location location, Token::Value token, | 544 Scanner::Location location, Token::Value token, |
543 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken); | 545 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken); |
544 | 546 |
545 | 547 |
546 void ReportClassifierError(const ExpressionClassifier::Error& error) { | 548 void ReportClassifierError(const ExpressionClassifier::Error& error) { |
547 Traits::ReportMessageAt(error.location, error.message, error.arg, | 549 Traits::ReportMessageAt(error.location, error.message, error.arg, |
548 kSyntaxError); | 550 kSyntaxError); |
549 } | 551 } |
550 | 552 |
551 void ValidateExpression(const ExpressionClassifier* classifier, bool* ok) { | 553 void ValidateExpression(const ExpressionClassifier* classifier, bool* ok) { |
552 if (!classifier->is_valid_expression()) { | 554 if (!classifier->is_valid_expression() || |
553 ReportClassifierError(classifier->expression_error()); | 555 classifier->has_cover_initialized_name()) { |
| 556 ReportClassifierError(ExpressionClassifier::FirdRecorded( |
| 557 classifier->expression_error(), |
| 558 classifier->cover_initialized_name_error())); |
554 *ok = false; | 559 *ok = false; |
555 } | 560 } |
556 } | 561 } |
557 | 562 |
558 void ValidateFormalParameterInitializer( | 563 void ValidateFormalParameterInitializer( |
559 const ExpressionClassifier* classifier, bool* ok) { | 564 const ExpressionClassifier* classifier, bool* ok) { |
560 if (!classifier->is_valid_formal_parameter_initializer()) { | 565 if (!classifier->is_valid_formal_parameter_initializer()) { |
561 ReportClassifierError(classifier->formal_parameter_initializer_error()); | 566 ReportClassifierError(classifier->formal_parameter_initializer_error()); |
562 *ok = false; | 567 *ok = false; |
563 } | 568 } |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
681 | 686 |
682 | 687 |
683 ExpressionT ParseRegExpLiteral(bool seen_equal, | 688 ExpressionT ParseRegExpLiteral(bool seen_equal, |
684 ExpressionClassifier* classifier, bool* ok); | 689 ExpressionClassifier* classifier, bool* ok); |
685 | 690 |
686 ExpressionT ParsePrimaryExpression(ExpressionClassifier* classifier, | 691 ExpressionT ParsePrimaryExpression(ExpressionClassifier* classifier, |
687 bool* ok); | 692 bool* ok); |
688 ExpressionT ParseExpression(bool accept_IN, bool* ok); | 693 ExpressionT ParseExpression(bool accept_IN, bool* ok); |
689 ExpressionT ParseExpression(bool accept_IN, ExpressionClassifier* classifier, | 694 ExpressionT ParseExpression(bool accept_IN, ExpressionClassifier* classifier, |
690 bool* ok); | 695 bool* ok); |
| 696 ExpressionT ParseExpression(bool accept_IN, int flags, |
| 697 ExpressionClassifier* classifier, bool* ok); |
691 ExpressionT ParseArrayLiteral(ExpressionClassifier* classifier, bool* ok); | 698 ExpressionT ParseArrayLiteral(ExpressionClassifier* classifier, bool* ok); |
692 ExpressionT ParsePropertyName(IdentifierT* name, bool* is_get, bool* is_set, | 699 ExpressionT ParsePropertyName(IdentifierT* name, bool* is_get, bool* is_set, |
693 bool* is_static, bool* is_computed_name, | 700 bool* is_static, bool* is_computed_name, |
694 ExpressionClassifier* classifier, bool* ok); | 701 ExpressionClassifier* classifier, bool* ok); |
695 ExpressionT ParseObjectLiteral(ExpressionClassifier* classifier, bool* ok); | 702 ExpressionT ParseObjectLiteral(ExpressionClassifier* classifier, bool* ok); |
696 ObjectLiteralPropertyT ParsePropertyDefinition( | 703 ObjectLiteralPropertyT ParsePropertyDefinition( |
697 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, | 704 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, |
698 bool is_static, bool* is_computed_name, bool* has_seen_constructor, | 705 bool is_static, bool* is_computed_name, bool* has_seen_constructor, |
699 ExpressionClassifier* classifier, bool* ok); | 706 ExpressionClassifier* classifier, bool* ok); |
700 typename Traits::Type::ExpressionList ParseArguments( | 707 typename Traits::Type::ExpressionList ParseArguments( |
701 Scanner::Location* first_spread_pos, ExpressionClassifier* classifier, | 708 Scanner::Location* first_spread_pos, ExpressionClassifier* classifier, |
702 bool* ok); | 709 bool* ok); |
| 710 |
| 711 enum AssignmentFlags { |
| 712 kIsRightHandSide = 1 << 0, |
| 713 kIsPatternElement = 1 << 1, |
| 714 kMaybeBindingPattern = 1 << 2 |
| 715 }; |
703 ExpressionT ParseAssignmentExpression(bool accept_IN, | 716 ExpressionT ParseAssignmentExpression(bool accept_IN, |
704 ExpressionClassifier* classifier, | 717 ExpressionClassifier* classifier, |
| 718 bool* ok) { |
| 719 bool seen_destructuring = false; |
| 720 return ParseAssignmentExpression(accept_IN, 0, &seen_destructuring, |
| 721 classifier, ok); |
| 722 } |
| 723 ExpressionT ParseAssignmentExpression(bool accept_IN, int flags, |
| 724 ExpressionClassifier* classifier, |
| 725 bool* ok) { |
| 726 bool seen_destructuring = false; |
| 727 return ParseAssignmentExpression(accept_IN, flags, &seen_destructuring, |
| 728 classifier, ok); |
| 729 } |
| 730 ExpressionT ParseAssignmentExpression(bool accept_IN, int flags, |
| 731 bool* seen_destructuring, |
| 732 ExpressionClassifier* classifier, |
705 bool* ok); | 733 bool* ok); |
706 ExpressionT ParseYieldExpression(ExpressionClassifier* classifier, bool* ok); | 734 ExpressionT ParseYieldExpression(ExpressionClassifier* classifier, bool* ok); |
707 ExpressionT ParseConditionalExpression(bool accept_IN, | 735 ExpressionT ParseConditionalExpression(bool accept_IN, |
708 ExpressionClassifier* classifier, | 736 ExpressionClassifier* classifier, |
709 bool* ok); | 737 bool* ok); |
710 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, | 738 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, |
711 ExpressionClassifier* classifier, bool* ok); | 739 ExpressionClassifier* classifier, bool* ok); |
712 ExpressionT ParseUnaryExpression(ExpressionClassifier* classifier, bool* ok); | 740 ExpressionT ParseUnaryExpression(ExpressionClassifier* classifier, bool* ok); |
713 ExpressionT ParsePostfixExpression(ExpressionClassifier* classifier, | 741 ExpressionT ParsePostfixExpression(ExpressionClassifier* classifier, |
714 bool* ok); | 742 bool* ok); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
747 // Checks if the expression is a valid reference expression (e.g., on the | 775 // Checks if the expression is a valid reference expression (e.g., on the |
748 // left-hand side of assignments). Although ruled out by ECMA as early errors, | 776 // left-hand side of assignments). Although ruled out by ECMA as early errors, |
749 // we allow calls for web compatibility and rewrite them to a runtime throw. | 777 // we allow calls for web compatibility and rewrite them to a runtime throw. |
750 ExpressionT CheckAndRewriteReferenceExpression( | 778 ExpressionT CheckAndRewriteReferenceExpression( |
751 ExpressionT expression, int beg_pos, int end_pos, | 779 ExpressionT expression, int beg_pos, int end_pos, |
752 MessageTemplate::Template message, bool* ok); | 780 MessageTemplate::Template message, bool* ok); |
753 ExpressionT CheckAndRewriteReferenceExpression( | 781 ExpressionT CheckAndRewriteReferenceExpression( |
754 ExpressionT expression, int beg_pos, int end_pos, | 782 ExpressionT expression, int beg_pos, int end_pos, |
755 MessageTemplate::Template message, ParseErrorType type, bool* ok); | 783 MessageTemplate::Template message, ParseErrorType type, bool* ok); |
756 | 784 |
| 785 bool IsValidReferenceExpression(ExpressionT expression); |
| 786 |
757 // Used to validate property names in object literals and class literals | 787 // Used to validate property names in object literals and class literals |
758 enum PropertyKind { | 788 enum PropertyKind { |
759 kAccessorProperty, | 789 kAccessorProperty, |
760 kValueProperty, | 790 kValueProperty, |
761 kMethodProperty | 791 kMethodProperty |
762 }; | 792 }; |
763 | 793 |
764 class ObjectLiteralCheckerBase { | 794 class ObjectLiteralCheckerBase { |
765 public: | 795 public: |
766 explicit ObjectLiteralCheckerBase(ParserBase* parser) : parser_(parser) {} | 796 explicit ObjectLiteralCheckerBase(ParserBase* parser) : parser_(parser) {} |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
836 | 866 |
837 bool allow_lazy_; | 867 bool allow_lazy_; |
838 bool allow_natives_; | 868 bool allow_natives_; |
839 bool allow_harmony_sloppy_; | 869 bool allow_harmony_sloppy_; |
840 bool allow_harmony_sloppy_function_; | 870 bool allow_harmony_sloppy_function_; |
841 bool allow_harmony_sloppy_let_; | 871 bool allow_harmony_sloppy_let_; |
842 bool allow_harmony_rest_parameters_; | 872 bool allow_harmony_rest_parameters_; |
843 bool allow_harmony_default_parameters_; | 873 bool allow_harmony_default_parameters_; |
844 bool allow_harmony_spread_calls_; | 874 bool allow_harmony_spread_calls_; |
845 bool allow_harmony_destructuring_; | 875 bool allow_harmony_destructuring_; |
| 876 bool allow_harmony_destructuring_assignment_; |
846 bool allow_harmony_spread_arrays_; | 877 bool allow_harmony_spread_arrays_; |
847 bool allow_harmony_new_target_; | 878 bool allow_harmony_new_target_; |
848 bool allow_strong_mode_; | 879 bool allow_strong_mode_; |
849 bool allow_legacy_const_; | 880 bool allow_legacy_const_; |
850 bool allow_harmony_do_expressions_; | 881 bool allow_harmony_do_expressions_; |
851 }; | 882 }; |
852 | 883 |
853 | 884 |
854 class PreParserIdentifier { | 885 class PreParserIdentifier { |
855 public: | 886 public: |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
950 | 981 |
951 static PreParserExpression BinaryOperation(PreParserExpression left, | 982 static PreParserExpression BinaryOperation(PreParserExpression left, |
952 Token::Value op, | 983 Token::Value op, |
953 PreParserExpression right) { | 984 PreParserExpression right) { |
954 return PreParserExpression( | 985 return PreParserExpression( |
955 TypeField::encode(kBinaryOperationExpression) | | 986 TypeField::encode(kBinaryOperationExpression) | |
956 HasRestField::encode(op == Token::COMMA && | 987 HasRestField::encode(op == Token::COMMA && |
957 right->IsSpreadExpression())); | 988 right->IsSpreadExpression())); |
958 } | 989 } |
959 | 990 |
| 991 static PreParserExpression Assignment() { |
| 992 return PreParserExpression(TypeField::encode(kAssignmentExpression)); |
| 993 } |
| 994 |
| 995 static PreParserExpression ObjectLiteral( |
| 996 bool has_cover_initialized_name = false) { |
| 997 return PreParserExpression( |
| 998 TypeField::encode(kObjectLiteralExpression) | |
| 999 HasCoverInitializedNameField::encode(has_cover_initialized_name)); |
| 1000 } |
| 1001 |
960 static PreParserExpression StringLiteral() { | 1002 static PreParserExpression StringLiteral() { |
961 return PreParserExpression(TypeField::encode(kStringLiteralExpression)); | 1003 return PreParserExpression(TypeField::encode(kStringLiteralExpression)); |
962 } | 1004 } |
963 | 1005 |
964 static PreParserExpression UseStrictStringLiteral() { | 1006 static PreParserExpression UseStrictStringLiteral() { |
965 return PreParserExpression(TypeField::encode(kStringLiteralExpression) | | 1007 return PreParserExpression(TypeField::encode(kStringLiteralExpression) | |
966 IsUseStrictField::encode(true)); | 1008 IsUseStrictField::encode(true)); |
967 } | 1009 } |
968 | 1010 |
969 static PreParserExpression UseStrongStringLiteral() { | 1011 static PreParserExpression UseStrongStringLiteral() { |
(...skipping 28 matching lines...) Expand all Loading... |
998 TypeField::encode(kExpression) | | 1040 TypeField::encode(kExpression) | |
999 ExpressionTypeField::encode(kSuperCallReference)); | 1041 ExpressionTypeField::encode(kSuperCallReference)); |
1000 } | 1042 } |
1001 | 1043 |
1002 static PreParserExpression NoTemplateTag() { | 1044 static PreParserExpression NoTemplateTag() { |
1003 return PreParserExpression( | 1045 return PreParserExpression( |
1004 TypeField::encode(kExpression) | | 1046 TypeField::encode(kExpression) | |
1005 ExpressionTypeField::encode(kNoTemplateTagExpression)); | 1047 ExpressionTypeField::encode(kNoTemplateTagExpression)); |
1006 } | 1048 } |
1007 | 1049 |
| 1050 bool IsAssignment() const { |
| 1051 return TypeField::decode(code_) == kAssignmentExpression; |
| 1052 } |
| 1053 |
1008 bool IsIdentifier() const { | 1054 bool IsIdentifier() const { |
1009 return TypeField::decode(code_) == kIdentifierExpression; | 1055 return TypeField::decode(code_) == kIdentifierExpression; |
1010 } | 1056 } |
1011 | 1057 |
1012 PreParserIdentifier AsIdentifier() const { | 1058 PreParserIdentifier AsIdentifier() const { |
1013 DCHECK(IsIdentifier()); | 1059 DCHECK(IsIdentifier()); |
1014 return PreParserIdentifier(IdentifierTypeField::decode(code_)); | 1060 return PreParserIdentifier(IdentifierTypeField::decode(code_)); |
1015 } | 1061 } |
1016 | 1062 |
| 1063 PreParserExpression AsObjectLiteral() const { |
| 1064 DCHECK(IsObjectLiteral()); |
| 1065 return *this; |
| 1066 } |
| 1067 |
| 1068 bool IsObjectLiteral() const { |
| 1069 return TypeField::decode(code_) == kObjectLiteralExpression; |
| 1070 } |
| 1071 |
| 1072 bool IsArrayLiteral() const { |
| 1073 return TypeField::decode(code_) == kObjectLiteralExpression; |
| 1074 } |
| 1075 |
1017 bool IsStringLiteral() const { | 1076 bool IsStringLiteral() const { |
1018 return TypeField::decode(code_) == kStringLiteralExpression; | 1077 return TypeField::decode(code_) == kStringLiteralExpression; |
1019 } | 1078 } |
1020 | 1079 |
1021 bool IsUseStrictLiteral() const { | 1080 bool IsUseStrictLiteral() const { |
1022 return TypeField::decode(code_) == kStringLiteralExpression && | 1081 return TypeField::decode(code_) == kStringLiteralExpression && |
1023 IsUseStrictField::decode(code_); | 1082 IsUseStrictField::decode(code_); |
1024 } | 1083 } |
1025 | 1084 |
1026 bool IsUseStrongLiteral() const { | 1085 bool IsUseStrongLiteral() const { |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1095 | 1154 |
1096 int position() const { return RelocInfo::kNoPosition; } | 1155 int position() const { return RelocInfo::kNoPosition; } |
1097 void set_function_token_position(int position) {} | 1156 void set_function_token_position(int position) {} |
1098 | 1157 |
1099 private: | 1158 private: |
1100 enum Type { | 1159 enum Type { |
1101 kExpression, | 1160 kExpression, |
1102 kIdentifierExpression, | 1161 kIdentifierExpression, |
1103 kStringLiteralExpression, | 1162 kStringLiteralExpression, |
1104 kBinaryOperationExpression, | 1163 kBinaryOperationExpression, |
1105 kSpreadExpression | 1164 kSpreadExpression, |
| 1165 kObjectLiteralExpression, |
| 1166 kAssignmentExpression |
1106 }; | 1167 }; |
1107 | 1168 |
1108 enum ExpressionType { | 1169 enum ExpressionType { |
1109 kThisExpression, | 1170 kThisExpression, |
1110 kThisPropertyExpression, | 1171 kThisPropertyExpression, |
1111 kPropertyExpression, | 1172 kPropertyExpression, |
1112 kCallExpression, | 1173 kCallExpression, |
1113 kSuperCallReference, | 1174 kSuperCallReference, |
1114 kNoTemplateTagExpression | 1175 kNoTemplateTagExpression |
1115 }; | 1176 }; |
1116 | 1177 |
1117 explicit PreParserExpression(uint32_t expression_code) | 1178 explicit PreParserExpression(uint32_t expression_code) |
1118 : code_(expression_code) {} | 1179 : code_(expression_code) {} |
1119 | 1180 |
1120 // The first three bits are for the Type. | 1181 // The first three bits are for the Type. |
1121 typedef BitField<Type, 0, 3> TypeField; | 1182 typedef BitField<Type, 0, 3> TypeField; |
1122 | 1183 |
1123 // The rest of the bits are interpreted depending on the value | 1184 // The rest of the bits are interpreted depending on the value |
1124 // of the Type field, so they can share the storage. | 1185 // of the Type field, so they can share the storage. |
1125 typedef BitField<ExpressionType, TypeField::kNext, 3> ExpressionTypeField; | 1186 typedef BitField<ExpressionType, TypeField::kNext, 3> ExpressionTypeField; |
1126 typedef BitField<bool, TypeField::kNext, 1> IsUseStrictField; | 1187 typedef BitField<bool, TypeField::kNext, 1> IsUseStrictField; |
1127 typedef BitField<bool, IsUseStrictField::kNext, 1> IsUseStrongField; | 1188 typedef BitField<bool, IsUseStrictField::kNext, 1> IsUseStrongField; |
1128 typedef BitField<PreParserIdentifier::Type, TypeField::kNext, 10> | 1189 typedef BitField<PreParserIdentifier::Type, TypeField::kNext, 10> |
1129 IdentifierTypeField; | 1190 IdentifierTypeField; |
1130 typedef BitField<bool, TypeField::kNext, 1> HasRestField; | 1191 typedef BitField<bool, TypeField::kNext, 1> HasRestField; |
| 1192 typedef BitField<bool, TypeField::kNext, 1> HasCoverInitializedNameField; |
1131 | 1193 |
1132 uint32_t code_; | 1194 uint32_t code_; |
1133 }; | 1195 }; |
1134 | 1196 |
1135 | 1197 |
1136 // The pre-parser doesn't need to build lists of expressions, identifiers, or | 1198 // The pre-parser doesn't need to build lists of expressions, identifiers, or |
1137 // the like. | 1199 // the like. |
1138 template <typename T> | 1200 template <typename T> |
1139 class PreParserList { | 1201 class PreParserList { |
1140 public: | 1202 public: |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1233 PreParserIdentifier js_flags, | 1295 PreParserIdentifier js_flags, |
1234 int literal_index, | 1296 int literal_index, |
1235 bool is_strong, | 1297 bool is_strong, |
1236 int pos) { | 1298 int pos) { |
1237 return PreParserExpression::Default(); | 1299 return PreParserExpression::Default(); |
1238 } | 1300 } |
1239 PreParserExpression NewArrayLiteral(PreParserExpressionList values, | 1301 PreParserExpression NewArrayLiteral(PreParserExpressionList values, |
1240 int literal_index, | 1302 int literal_index, |
1241 bool is_strong, | 1303 bool is_strong, |
1242 int pos) { | 1304 int pos) { |
1243 return PreParserExpression::Default(); | 1305 return PreParserExpression::ObjectLiteral(); |
1244 } | 1306 } |
1245 PreParserExpression NewArrayLiteral(PreParserExpressionList values, | 1307 PreParserExpression NewArrayLiteral(PreParserExpressionList values, |
1246 int first_spread_index, int literal_index, | 1308 int first_spread_index, int literal_index, |
1247 bool is_strong, int pos) { | 1309 bool is_strong, int pos) { |
1248 return PreParserExpression::Default(); | 1310 return PreParserExpression::ObjectLiteral(); |
1249 } | 1311 } |
1250 PreParserExpression NewObjectLiteralProperty(PreParserExpression key, | 1312 PreParserExpression NewObjectLiteralProperty(PreParserExpression key, |
1251 PreParserExpression value, | 1313 PreParserExpression value, |
1252 ObjectLiteralProperty::Kind kind, | 1314 ObjectLiteralProperty::Kind kind, |
1253 bool is_static, | 1315 bool is_static, |
1254 bool is_computed_name) { | 1316 bool is_computed_name) { |
1255 return PreParserExpression::Default(); | 1317 return PreParserExpression::Default(); |
1256 } | 1318 } |
1257 PreParserExpression NewObjectLiteralProperty(PreParserExpression key, | 1319 PreParserExpression NewObjectLiteralProperty(PreParserExpression key, |
1258 PreParserExpression value, | 1320 PreParserExpression value, |
1259 bool is_static, | 1321 bool is_static, |
1260 bool is_computed_name) { | 1322 bool is_computed_name) { |
1261 return PreParserExpression::Default(); | 1323 return PreParserExpression::Default(); |
1262 } | 1324 } |
1263 PreParserExpression NewObjectLiteral(PreParserExpressionList properties, | 1325 PreParserExpression NewObjectLiteral(PreParserExpressionList properties, |
1264 int literal_index, | 1326 int literal_index, |
1265 int boilerplate_properties, | 1327 int boilerplate_properties, |
1266 bool has_function, | 1328 bool has_function, |
1267 bool is_strong, | 1329 bool is_strong, |
1268 int pos) { | 1330 int pos) { |
1269 return PreParserExpression::Default(); | 1331 return PreParserExpression::ObjectLiteral(); |
1270 } | 1332 } |
1271 PreParserExpression NewVariableProxy(void* variable) { | 1333 PreParserExpression NewVariableProxy(void* variable) { |
1272 return PreParserExpression::Default(); | 1334 return PreParserExpression::Default(); |
1273 } | 1335 } |
1274 PreParserExpression NewProperty(PreParserExpression obj, | 1336 PreParserExpression NewProperty(PreParserExpression obj, |
1275 PreParserExpression key, | 1337 PreParserExpression key, |
1276 int pos) { | 1338 int pos) { |
1277 if (obj.IsThis()) { | 1339 if (obj.IsThis()) { |
1278 return PreParserExpression::ThisProperty(); | 1340 return PreParserExpression::ThisProperty(); |
1279 } | 1341 } |
(...skipping 11 matching lines...) Expand all Loading... |
1291 } | 1353 } |
1292 PreParserExpression NewCompareOperation(Token::Value op, | 1354 PreParserExpression NewCompareOperation(Token::Value op, |
1293 PreParserExpression left, | 1355 PreParserExpression left, |
1294 PreParserExpression right, int pos) { | 1356 PreParserExpression right, int pos) { |
1295 return PreParserExpression::Default(); | 1357 return PreParserExpression::Default(); |
1296 } | 1358 } |
1297 PreParserExpression NewAssignment(Token::Value op, | 1359 PreParserExpression NewAssignment(Token::Value op, |
1298 PreParserExpression left, | 1360 PreParserExpression left, |
1299 PreParserExpression right, | 1361 PreParserExpression right, |
1300 int pos) { | 1362 int pos) { |
1301 return PreParserExpression::Default(); | 1363 return PreParserExpression::Assignment(); |
1302 } | 1364 } |
1303 PreParserExpression NewYield(PreParserExpression generator_object, | 1365 PreParserExpression NewYield(PreParserExpression generator_object, |
1304 PreParserExpression expression, | 1366 PreParserExpression expression, |
1305 Yield::Kind yield_kind, | 1367 Yield::Kind yield_kind, |
1306 int pos) { | 1368 int pos) { |
1307 return PreParserExpression::Default(); | 1369 return PreParserExpression::Default(); |
1308 } | 1370 } |
1309 PreParserExpression NewConditional(PreParserExpression condition, | 1371 PreParserExpression NewConditional(PreParserExpression condition, |
1310 PreParserExpression then_expression, | 1372 PreParserExpression then_expression, |
1311 PreParserExpression else_expression, | 1373 PreParserExpression else_expression, |
(...skipping 411 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1723 | 1785 |
1724 inline void MaterializeUnspreadArgumentsLiterals(int count); | 1786 inline void MaterializeUnspreadArgumentsLiterals(int count); |
1725 | 1787 |
1726 inline PreParserExpression SpreadCall(PreParserExpression function, | 1788 inline PreParserExpression SpreadCall(PreParserExpression function, |
1727 PreParserExpressionList args, int pos); | 1789 PreParserExpressionList args, int pos); |
1728 | 1790 |
1729 inline PreParserExpression SpreadCallNew(PreParserExpression function, | 1791 inline PreParserExpression SpreadCallNew(PreParserExpression function, |
1730 PreParserExpressionList args, | 1792 PreParserExpressionList args, |
1731 int pos); | 1793 int pos); |
1732 | 1794 |
| 1795 inline PreParserExpression RewriteDestructuringAssignmentExpression( |
| 1796 PreParserExpression expr) { |
| 1797 return expr; |
| 1798 } |
| 1799 |
1733 private: | 1800 private: |
1734 PreParser* pre_parser_; | 1801 PreParser* pre_parser_; |
1735 }; | 1802 }; |
1736 | 1803 |
1737 | 1804 |
1738 // Preparsing checks a JavaScript program and emits preparse-data that helps | 1805 // Preparsing checks a JavaScript program and emits preparse-data that helps |
1739 // a later parsing to be faster. | 1806 // a later parsing to be faster. |
1740 // See preparse-data-format.h for the data format. | 1807 // See preparse-data-format.h for the data format. |
1741 | 1808 |
1742 // The PreParser checks that the syntax follows the grammar for JavaScript, | 1809 // The PreParser checks that the syntax follows the grammar for JavaScript, |
(...skipping 625 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2368 ReportMessageAt(scanner()->peek_location(), | 2435 ReportMessageAt(scanner()->peek_location(), |
2369 MessageTemplate::kParamAfterRest); | 2436 MessageTemplate::kParamAfterRest); |
2370 *ok = false; | 2437 *ok = false; |
2371 return this->EmptyExpression(); | 2438 return this->EmptyExpression(); |
2372 } | 2439 } |
2373 Expect(Token::RPAREN, CHECK_OK); | 2440 Expect(Token::RPAREN, CHECK_OK); |
2374 } else { | 2441 } else { |
2375 // Heuristically try to detect immediately called functions before | 2442 // Heuristically try to detect immediately called functions before |
2376 // seeing the call parentheses. | 2443 // seeing the call parentheses. |
2377 parenthesized_function_ = (peek() == Token::FUNCTION); | 2444 parenthesized_function_ = (peek() == Token::FUNCTION); |
2378 result = this->ParseExpression(true, classifier, CHECK_OK); | 2445 result = this->ParseExpression(true, kMaybeBindingPattern, classifier, |
| 2446 CHECK_OK); |
2379 Expect(Token::RPAREN, CHECK_OK); | 2447 Expect(Token::RPAREN, CHECK_OK); |
| 2448 |
| 2449 if (peek() != Token::ARROW) { |
| 2450 if (allow_harmony_destructuring_assignment()) { |
| 2451 ValidateAssignmentPattern(classifier, CHECK_OK); |
| 2452 } else { |
| 2453 ValidateExpression(classifier, CHECK_OK); |
| 2454 } |
| 2455 } |
2380 } | 2456 } |
2381 break; | 2457 break; |
2382 | 2458 |
2383 case Token::CLASS: { | 2459 case Token::CLASS: { |
2384 BindingPatternUnexpectedToken(classifier); | 2460 BindingPatternUnexpectedToken(classifier); |
2385 Consume(Token::CLASS); | 2461 Consume(Token::CLASS); |
2386 if (!allow_harmony_sloppy() && is_sloppy(language_mode())) { | 2462 if (!allow_harmony_sloppy() && is_sloppy(language_mode())) { |
2387 ReportMessage(MessageTemplate::kSloppyLexical); | 2463 ReportMessage(MessageTemplate::kSloppyLexical); |
2388 *ok = false; | 2464 *ok = false; |
2389 break; | 2465 break; |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2443 template <class Traits> | 2519 template <class Traits> |
2444 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( | 2520 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( |
2445 bool accept_IN, bool* ok) { | 2521 bool accept_IN, bool* ok) { |
2446 ExpressionClassifier classifier; | 2522 ExpressionClassifier classifier; |
2447 ExpressionT result = ParseExpression(accept_IN, &classifier, CHECK_OK); | 2523 ExpressionT result = ParseExpression(accept_IN, &classifier, CHECK_OK); |
2448 ValidateExpression(&classifier, CHECK_OK); | 2524 ValidateExpression(&classifier, CHECK_OK); |
2449 return result; | 2525 return result; |
2450 } | 2526 } |
2451 | 2527 |
2452 | 2528 |
| 2529 template <class Traits> |
| 2530 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( |
| 2531 bool accept_IN, ExpressionClassifier* classifier, bool* ok) { |
| 2532 ExpressionT result = ParseExpression(accept_IN, 0, classifier, CHECK_OK); |
| 2533 return result; |
| 2534 } |
| 2535 |
| 2536 |
2453 // Precedence = 1 | 2537 // Precedence = 1 |
2454 template <class Traits> | 2538 template <class Traits> |
2455 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( | 2539 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( |
2456 bool accept_IN, ExpressionClassifier* classifier, bool* ok) { | 2540 bool accept_IN, int flags, ExpressionClassifier* classifier, bool* ok) { |
2457 // Expression :: | 2541 // Expression :: |
2458 // AssignmentExpression | 2542 // AssignmentExpression |
2459 // Expression ',' AssignmentExpression | 2543 // Expression ',' AssignmentExpression |
2460 | 2544 |
2461 ExpressionClassifier binding_classifier; | 2545 ExpressionClassifier binding_classifier; |
2462 ExpressionT result = | 2546 bool seen_destructuring = false; |
2463 this->ParseAssignmentExpression(accept_IN, &binding_classifier, CHECK_OK); | 2547 ExpressionT result = this->ParseAssignmentExpression( |
| 2548 accept_IN, flags, &seen_destructuring, &binding_classifier, CHECK_OK); |
2464 classifier->Accumulate(binding_classifier, | 2549 classifier->Accumulate(binding_classifier, |
2465 ExpressionClassifier::AllProductions); | 2550 ExpressionClassifier::AllProductions); |
2466 bool is_simple_parameter_list = this->IsIdentifier(result); | 2551 bool is_simple_parameter_list = this->IsIdentifier(result); |
2467 bool seen_rest = false; | 2552 bool seen_rest = false; |
2468 while (peek() == Token::COMMA) { | 2553 while (peek() == Token::COMMA) { |
2469 if (seen_rest) { | 2554 if (seen_rest) { |
2470 // At this point the production can't possibly be valid, but we don't know | 2555 // At this point the production can't possibly be valid, but we don't know |
2471 // which error to signal. | 2556 // which error to signal. |
2472 classifier->RecordArrowFormalParametersError( | 2557 classifier->RecordArrowFormalParametersError( |
2473 scanner()->peek_location(), MessageTemplate::kParamAfterRest); | 2558 scanner()->peek_location(), MessageTemplate::kParamAfterRest); |
2474 } | 2559 } |
2475 Consume(Token::COMMA); | 2560 Consume(Token::COMMA); |
2476 bool is_rest = false; | 2561 bool is_rest = false; |
2477 if (allow_harmony_rest_parameters() && peek() == Token::ELLIPSIS) { | 2562 if (allow_harmony_rest_parameters() && peek() == Token::ELLIPSIS) { |
2478 // 'x, y, ...z' in CoverParenthesizedExpressionAndArrowParameterList only | 2563 // 'x, y, ...z' in CoverParenthesizedExpressionAndArrowParameterList only |
2479 // as the formal parameters of'(x, y, ...z) => foo', and is not itself a | 2564 // as the formal parameters of'(x, y, ...z) => foo', and is not itself a |
2480 // valid expression or binding pattern. | 2565 // valid expression or binding pattern. |
2481 ExpressionUnexpectedToken(classifier); | 2566 ExpressionUnexpectedToken(classifier); |
2482 BindingPatternUnexpectedToken(classifier); | 2567 BindingPatternUnexpectedToken(classifier); |
2483 Consume(Token::ELLIPSIS); | 2568 Consume(Token::ELLIPSIS); |
2484 seen_rest = is_rest = true; | 2569 seen_rest = is_rest = true; |
2485 } | 2570 } |
2486 int pos = position(); | 2571 int pos = position(); |
2487 ExpressionT right = this->ParseAssignmentExpression( | 2572 ExpressionT right = this->ParseAssignmentExpression( |
2488 accept_IN, &binding_classifier, CHECK_OK); | 2573 accept_IN, flags, &seen_destructuring, &binding_classifier, CHECK_OK); |
2489 if (is_rest) right = factory()->NewSpread(right, pos); | 2574 if (is_rest) right = factory()->NewSpread(right, pos); |
2490 is_simple_parameter_list = | 2575 is_simple_parameter_list = |
2491 is_simple_parameter_list && this->IsIdentifier(right); | 2576 is_simple_parameter_list && this->IsIdentifier(right); |
2492 classifier->Accumulate(binding_classifier, | 2577 classifier->Accumulate(binding_classifier, |
2493 ExpressionClassifier::AllProductions); | 2578 ExpressionClassifier::AllProductions); |
2494 result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos); | 2579 result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos); |
2495 } | 2580 } |
2496 if (!is_simple_parameter_list || seen_rest) { | 2581 if (!is_simple_parameter_list || seen_rest) { |
2497 classifier->RecordNonSimpleParameter(); | 2582 classifier->RecordNonSimpleParameter(); |
2498 } | 2583 } |
| 2584 |
2499 return result; | 2585 return result; |
2500 } | 2586 } |
2501 | 2587 |
2502 | 2588 |
2503 template <class Traits> | 2589 template <class Traits> |
2504 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseArrayLiteral( | 2590 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseArrayLiteral( |
2505 ExpressionClassifier* classifier, bool* ok) { | 2591 ExpressionClassifier* classifier, bool* ok) { |
2506 // ArrayLiteral :: | 2592 // ArrayLiteral :: |
2507 // '[' Expression? (',' Expression?)* ']' | 2593 // '[' Expression? (',' Expression?)* ']' |
2508 | 2594 |
2509 int pos = peek_position(); | 2595 int pos = peek_position(); |
2510 typename Traits::Type::ExpressionList values = | 2596 typename Traits::Type::ExpressionList values = |
2511 this->NewExpressionList(4, zone_); | 2597 this->NewExpressionList(4, zone_); |
2512 int first_spread_index = -1; | 2598 int first_spread_index = -1; |
2513 Expect(Token::LBRACK, CHECK_OK); | 2599 Expect(Token::LBRACK, CHECK_OK); |
2514 while (peek() != Token::RBRACK) { | 2600 while (peek() != Token::RBRACK) { |
2515 bool seen_spread = false; | 2601 bool seen_spread = false; |
2516 ExpressionT elem = this->EmptyExpression(); | 2602 ExpressionT elem = this->EmptyExpression(); |
2517 if (peek() == Token::COMMA) { | 2603 if (peek() == Token::COMMA) { |
2518 if (is_strong(language_mode())) { | 2604 if (is_strong(language_mode())) { |
2519 ReportMessageAt(scanner()->peek_location(), | 2605 ReportMessageAt(scanner()->peek_location(), |
2520 MessageTemplate::kStrongEllision); | 2606 MessageTemplate::kStrongEllision); |
2521 *ok = false; | 2607 *ok = false; |
2522 return this->EmptyExpression(); | 2608 return this->EmptyExpression(); |
2523 } | 2609 } |
2524 elem = this->GetLiteralTheHole(peek_position(), factory()); | 2610 elem = this->GetLiteralTheHole(peek_position(), factory()); |
2525 } else if (peek() == Token::ELLIPSIS) { | 2611 } else if (peek() == Token::ELLIPSIS) { |
2526 if (!allow_harmony_spread_arrays()) { | 2612 if (!allow_harmony_spread_arrays() && !allow_harmony_destructuring() && |
| 2613 !allow_harmony_destructuring_assignment()) { |
2527 ExpressionUnexpectedToken(classifier); | 2614 ExpressionUnexpectedToken(classifier); |
2528 } | 2615 } |
2529 int start_pos = peek_position(); | 2616 int start_pos = peek_position(); |
2530 Consume(Token::ELLIPSIS); | 2617 Consume(Token::ELLIPSIS); |
2531 ExpressionT argument = | 2618 ExpressionT argument = |
2532 this->ParseAssignmentExpression(true, classifier, CHECK_OK); | 2619 this->ParseAssignmentExpression(true, classifier, CHECK_OK); |
| 2620 if ((argument->IsArrayLiteral() || argument->IsObjectLiteral()) && |
| 2621 !classifier->is_valid_assignment_pattern()) { |
| 2622 classifier->RecordPatternError( |
| 2623 Scanner::Location(start_pos, scanner()->location().end_pos), |
| 2624 MessageTemplate::kInvalidDestructuringTarget); |
| 2625 } |
2533 elem = factory()->NewSpread(argument, start_pos); | 2626 elem = factory()->NewSpread(argument, start_pos); |
2534 seen_spread = true; | 2627 seen_spread = true; |
2535 if (first_spread_index < 0) { | 2628 if (first_spread_index < 0) { |
2536 first_spread_index = values->length(); | 2629 first_spread_index = values->length(); |
2537 } | 2630 } |
| 2631 if (argument->IsAssignment()) { |
| 2632 classifier->RecordPatternError( |
| 2633 Scanner::Location(start_pos, scanner()->location().end_pos), |
| 2634 MessageTemplate::kInvalidRestInitializer); |
| 2635 } else if (peek() == Token::COMMA) { |
| 2636 classifier->RecordPatternError( |
| 2637 Scanner::Location(start_pos, scanner()->location().end_pos), |
| 2638 MessageTemplate::kElementAfterRest); |
| 2639 } |
2538 } else { | 2640 } else { |
2539 elem = this->ParseAssignmentExpression(true, classifier, CHECK_OK); | 2641 elem = this->ParseAssignmentExpression(true, kIsPatternElement, |
| 2642 classifier, CHECK_OK); |
| 2643 if (!this->IsValidReferenceExpression(elem) && |
| 2644 !classifier->is_valid_assignment_pattern()) { |
| 2645 classifier->RecordPatternError( |
| 2646 Scanner::Location(pos, scanner()->location().end_pos), |
| 2647 MessageTemplate::kInvalidDestructuringTarget); |
| 2648 } |
2540 } | 2649 } |
2541 values->Add(elem, zone_); | 2650 values->Add(elem, zone_); |
2542 if (peek() != Token::RBRACK) { | 2651 if (peek() != Token::RBRACK) { |
2543 if (seen_spread) { | 2652 if (seen_spread) { |
2544 BindingPatternUnexpectedToken(classifier); | 2653 BindingPatternUnexpectedToken(classifier); |
2545 } | 2654 } |
2546 Expect(Token::COMMA, CHECK_OK); | 2655 Expect(Token::COMMA, CHECK_OK); |
2547 } | 2656 } |
2548 } | 2657 } |
2549 Expect(Token::RBRACK, CHECK_OK); | 2658 Expect(Token::RBRACK, CHECK_OK); |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2645 DCHECK(!is_static); | 2754 DCHECK(!is_static); |
2646 | 2755 |
2647 if (peek() == Token::COLON) { | 2756 if (peek() == Token::COLON) { |
2648 // PropertyDefinition | 2757 // PropertyDefinition |
2649 // PropertyName ':' AssignmentExpression | 2758 // PropertyName ':' AssignmentExpression |
2650 if (!*is_computed_name) { | 2759 if (!*is_computed_name) { |
2651 checker->CheckProperty(name_token, kValueProperty, false, false, | 2760 checker->CheckProperty(name_token, kValueProperty, false, false, |
2652 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2761 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
2653 } | 2762 } |
2654 Consume(Token::COLON); | 2763 Consume(Token::COLON); |
| 2764 int pos = peek_position(); |
2655 value = this->ParseAssignmentExpression( | 2765 value = this->ParseAssignmentExpression( |
2656 true, classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2766 true, kIsPatternElement, classifier, |
| 2767 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 2768 |
| 2769 if (!this->IsValidReferenceExpression(value) && |
| 2770 !classifier->is_valid_assignment_pattern()) { |
| 2771 classifier->RecordPatternError( |
| 2772 Scanner::Location(pos, scanner()->location().end_pos), |
| 2773 MessageTemplate::kInvalidDestructuringTarget); |
| 2774 } |
| 2775 |
2657 return factory()->NewObjectLiteralProperty(name_expression, value, false, | 2776 return factory()->NewObjectLiteralProperty(name_expression, value, false, |
2658 *is_computed_name); | 2777 *is_computed_name); |
2659 } | 2778 } |
2660 | 2779 |
2661 if (Token::IsIdentifier(name_token, language_mode(), | 2780 if (Token::IsIdentifier(name_token, language_mode(), |
2662 this->is_generator()) && | 2781 this->is_generator()) && |
2663 (peek() == Token::COMMA || peek() == Token::RBRACE || | 2782 (peek() == Token::COMMA || peek() == Token::RBRACE || |
2664 peek() == Token::ASSIGN)) { | 2783 peek() == Token::ASSIGN)) { |
2665 // PropertyDefinition | 2784 // PropertyDefinition |
2666 // IdentifierReference | 2785 // IdentifierReference |
2667 // CoverInitializedName | 2786 // CoverInitializedName |
2668 // | 2787 // |
2669 // CoverInitializedName | 2788 // CoverInitializedName |
2670 // IdentifierReference Initializer? | 2789 // IdentifierReference Initializer? |
2671 if (classifier->duplicate_finder() != nullptr && | 2790 if (classifier->duplicate_finder() != nullptr && |
2672 scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) { | 2791 scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) { |
2673 classifier->RecordDuplicateFormalParameterError(scanner()->location()); | 2792 classifier->RecordDuplicateFormalParameterError(scanner()->location()); |
2674 } | 2793 } |
2675 if (name_token == Token::LET) { | 2794 if (name_token == Token::LET) { |
2676 classifier->RecordLetPatternError( | 2795 classifier->RecordLetPatternError( |
2677 scanner()->location(), MessageTemplate::kLetInLexicalBinding); | 2796 scanner()->location(), MessageTemplate::kLetInLexicalBinding); |
2678 } | 2797 } |
2679 | 2798 |
2680 ExpressionT lhs = this->ExpressionFromIdentifier( | 2799 ExpressionT lhs = this->ExpressionFromIdentifier( |
2681 name, next_beg_pos, next_end_pos, scope_, factory()); | 2800 name, next_beg_pos, next_end_pos, scope_, factory()); |
2682 | 2801 |
2683 if (peek() == Token::ASSIGN) { | 2802 if (peek() == Token::ASSIGN) { |
2684 this->ExpressionUnexpectedToken(classifier); | |
2685 Consume(Token::ASSIGN); | 2803 Consume(Token::ASSIGN); |
2686 ExpressionClassifier rhs_classifier; | 2804 ExpressionClassifier rhs_classifier; |
2687 ExpressionT rhs = this->ParseAssignmentExpression( | 2805 ExpressionT rhs = this->ParseAssignmentExpression( |
2688 true, &rhs_classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2806 true, kIsRightHandSide, &rhs_classifier, |
| 2807 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
2689 classifier->Accumulate(rhs_classifier, | 2808 classifier->Accumulate(rhs_classifier, |
2690 ExpressionClassifier::ExpressionProductions); | 2809 ExpressionClassifier::ExpressionProductions); |
2691 value = factory()->NewAssignment(Token::ASSIGN, lhs, rhs, | 2810 value = factory()->NewAssignment(Token::ASSIGN, lhs, rhs, |
2692 RelocInfo::kNoPosition); | 2811 RelocInfo::kNoPosition); |
| 2812 classifier->RecordCoverInitializedNameError( |
| 2813 Scanner::Location(next_beg_pos, scanner()->location().end_pos), |
| 2814 MessageTemplate::kInvalidCoverInitializedName); |
2693 } else { | 2815 } else { |
2694 value = lhs; | 2816 value = lhs; |
2695 } | 2817 } |
2696 | 2818 |
2697 return factory()->NewObjectLiteralProperty( | 2819 return factory()->NewObjectLiteralProperty( |
2698 name_expression, value, ObjectLiteralProperty::COMPUTED, false, | 2820 name_expression, value, ObjectLiteralProperty::COMPUTED, false, |
2699 false); | 2821 false); |
2700 } | 2822 } |
2701 } | 2823 } |
2702 | 2824 |
| 2825 // Method definitions are never valid in patterns. |
| 2826 classifier->RecordPatternError( |
| 2827 Scanner::Location(next_beg_pos, scanner()->location().end_pos), |
| 2828 MessageTemplate::kInvalidDestructuringTarget); |
| 2829 |
2703 | 2830 |
2704 if (is_generator || peek() == Token::LPAREN) { | 2831 if (is_generator || peek() == Token::LPAREN) { |
2705 // MethodDefinition | 2832 // MethodDefinition |
2706 // PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' | 2833 // PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' |
2707 // '*' PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' | 2834 // '*' PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' |
2708 if (!*is_computed_name) { | 2835 if (!*is_computed_name) { |
2709 checker->CheckProperty(name_token, kMethodProperty, is_static, | 2836 checker->CheckProperty(name_token, kMethodProperty, is_static, |
2710 is_generator, | 2837 is_generator, |
2711 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2838 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
2712 } | 2839 } |
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2918 // the parser and preparser | 3045 // the parser and preparser |
2919 Traits::MaterializeUnspreadArgumentsLiterals(unspread_sequences_count); | 3046 Traits::MaterializeUnspreadArgumentsLiterals(unspread_sequences_count); |
2920 } | 3047 } |
2921 | 3048 |
2922 return result; | 3049 return result; |
2923 } | 3050 } |
2924 | 3051 |
2925 // Precedence = 2 | 3052 // Precedence = 2 |
2926 template <class Traits> | 3053 template <class Traits> |
2927 typename ParserBase<Traits>::ExpressionT | 3054 typename ParserBase<Traits>::ExpressionT |
2928 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, | 3055 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, int flags, |
| 3056 bool* seen_destructuring, |
2929 ExpressionClassifier* classifier, | 3057 ExpressionClassifier* classifier, |
2930 bool* ok) { | 3058 bool* ok) { |
2931 // AssignmentExpression :: | 3059 // AssignmentExpression :: |
2932 // ConditionalExpression | 3060 // ConditionalExpression |
2933 // ArrowFunction | 3061 // ArrowFunction |
2934 // YieldExpression | 3062 // YieldExpression |
2935 // LeftHandSideExpression AssignmentOperator AssignmentExpression | 3063 // LeftHandSideExpression AssignmentOperator AssignmentExpression |
2936 | 3064 |
2937 int lhs_beg_pos = peek_position(); | 3065 int lhs_beg_pos = peek_position(); |
| 3066 bool is_rhs = flags & kIsRightHandSide; |
| 3067 bool is_pattern_element = flags & kIsPatternElement; |
| 3068 bool maybe_binding_pattern = flags & kMaybeBindingPattern; |
| 3069 USE(maybe_binding_pattern); |
| 3070 flags = |
| 3071 flags & ~(kIsPatternElement | kMaybeBindingPattern) | kIsRightHandSide; |
2938 | 3072 |
2939 if (peek() == Token::YIELD && is_generator()) { | 3073 if (peek() == Token::YIELD && is_generator()) { |
2940 return this->ParseYieldExpression(classifier, ok); | 3074 return this->ParseYieldExpression(classifier, ok); |
2941 } | 3075 } |
2942 | 3076 |
2943 if (fni_ != NULL) fni_->Enter(); | 3077 if (fni_ != NULL) fni_->Enter(); |
2944 ParserBase<Traits>::Checkpoint checkpoint(this); | 3078 ParserBase<Traits>::Checkpoint checkpoint(this); |
2945 ExpressionClassifier arrow_formals_classifier(classifier->duplicate_finder()); | 3079 ExpressionClassifier arrow_formals_classifier(classifier->duplicate_finder()); |
2946 bool parenthesized_formals = peek() == Token::LPAREN; | 3080 bool parenthesized_formals = peek() == Token::LPAREN; |
2947 if (!parenthesized_formals) { | 3081 if (!parenthesized_formals) { |
(...skipping 20 matching lines...) Expand all Loading... |
2968 | 3102 |
2969 checkpoint.Restore(¶meters.materialized_literals_count); | 3103 checkpoint.Restore(¶meters.materialized_literals_count); |
2970 | 3104 |
2971 scope->set_start_position(lhs_beg_pos); | 3105 scope->set_start_position(lhs_beg_pos); |
2972 if (duplicate_loc.IsValid()) { | 3106 if (duplicate_loc.IsValid()) { |
2973 arrow_formals_classifier.RecordDuplicateFormalParameterError( | 3107 arrow_formals_classifier.RecordDuplicateFormalParameterError( |
2974 duplicate_loc); | 3108 duplicate_loc); |
2975 } | 3109 } |
2976 expression = this->ParseArrowFunctionLiteral( | 3110 expression = this->ParseArrowFunctionLiteral( |
2977 accept_IN, parameters, arrow_formals_classifier, CHECK_OK); | 3111 accept_IN, parameters, arrow_formals_classifier, CHECK_OK); |
| 3112 if (is_pattern_element) { |
| 3113 classifier->RecordPatternError( |
| 3114 Scanner::Location(lhs_beg_pos, scanner()->location().end_pos), |
| 3115 MessageTemplate::kInvalidDestructuringTarget); |
| 3116 } |
2978 return expression; | 3117 return expression; |
2979 } | 3118 } |
2980 | 3119 |
2981 // "expression" was not itself an arrow function parameter list, but it might | 3120 // "expression" was not itself an arrow function parameter list, but it might |
2982 // form part of one. Propagate speculative formal parameter error locations. | 3121 // form part of one. Propagate speculative formal parameter error locations. |
2983 classifier->Accumulate(arrow_formals_classifier, | 3122 classifier->Accumulate( |
2984 ExpressionClassifier::StandardProductions | | 3123 arrow_formals_classifier, |
2985 ExpressionClassifier::FormalParametersProductions); | 3124 ExpressionClassifier::StandardProductions | |
| 3125 ExpressionClassifier::FormalParametersProductions | |
| 3126 ExpressionClassifier::CoverInitializedNameProduction); |
| 3127 |
| 3128 bool maybe_pattern = |
| 3129 expression->IsObjectLiteral() || expression->IsArrayLiteral(); |
2986 | 3130 |
2987 if (!Token::IsAssignmentOp(peek())) { | 3131 if (!Token::IsAssignmentOp(peek())) { |
2988 if (fni_ != NULL) fni_->Leave(); | 3132 if (fni_ != NULL) fni_->Leave(); |
2989 // Parsed conditional expression only (no assignment). | 3133 // Parsed conditional expression only (no assignment). |
| 3134 if (is_pattern_element && !this->IsValidReferenceExpression(expression) && |
| 3135 !maybe_pattern) { |
| 3136 classifier->RecordPatternError( |
| 3137 Scanner::Location(lhs_beg_pos, scanner()->location().end_pos), |
| 3138 MessageTemplate::kInvalidDestructuringTarget); |
| 3139 } else if (is_rhs && !is_pattern_element && maybe_pattern) { |
| 3140 ValidateExpression(classifier, CHECK_OK); |
| 3141 } |
| 3142 |
2990 return expression; | 3143 return expression; |
2991 } | 3144 } |
2992 | 3145 |
2993 if (!(allow_harmony_destructuring() || allow_harmony_default_parameters())) { | 3146 if (!(allow_harmony_destructuring() || allow_harmony_default_parameters())) { |
2994 BindingPatternUnexpectedToken(classifier); | 3147 BindingPatternUnexpectedToken(classifier); |
2995 } | 3148 } |
2996 | 3149 |
2997 expression = this->CheckAndRewriteReferenceExpression( | 3150 bool maybe_destructuring_assignment = |
2998 expression, lhs_beg_pos, scanner()->location().end_pos, | 3151 allow_harmony_destructuring_assignment() && maybe_pattern && |
2999 MessageTemplate::kInvalidLhsInAssignment, CHECK_OK); | 3152 peek() == Token::ASSIGN; |
| 3153 bool maybe_destructuring_binding = allow_harmony_destructuring() && |
| 3154 maybe_pattern && !is_rhs && |
| 3155 peek() == Token::ASSIGN; |
| 3156 |
| 3157 if (maybe_destructuring_assignment) { |
| 3158 classifier->ForgiveCoverInitializedNameError(); |
| 3159 ValidateAssignmentPattern(classifier, CHECK_OK); |
| 3160 if (!is_pattern_element) *seen_destructuring = true; |
| 3161 } else if (!maybe_destructuring_binding) { |
| 3162 expression = this->CheckAndRewriteReferenceExpression( |
| 3163 expression, lhs_beg_pos, scanner()->location().end_pos, |
| 3164 MessageTemplate::kInvalidLhsInAssignment, CHECK_OK); |
| 3165 } |
3000 expression = this->MarkExpressionAsAssigned(expression); | 3166 expression = this->MarkExpressionAsAssigned(expression); |
3001 | 3167 |
3002 Token::Value op = Next(); // Get assignment operator. | 3168 Token::Value op = Next(); // Get assignment operator. |
3003 if (op != Token::ASSIGN) { | 3169 if (op != Token::ASSIGN) { |
3004 classifier->RecordBindingPatternError(scanner()->location(), | 3170 classifier->RecordBindingPatternError(scanner()->location(), |
3005 MessageTemplate::kUnexpectedToken, | 3171 MessageTemplate::kUnexpectedToken, |
3006 Token::String(op)); | 3172 Token::String(op)); |
3007 } | 3173 } |
3008 int pos = position(); | 3174 int pos = position(); |
3009 | 3175 |
3010 ExpressionClassifier rhs_classifier; | 3176 ExpressionClassifier rhs_classifier; |
3011 ExpressionT right = | 3177 ExpressionT right = this->ParseAssignmentExpression( |
3012 this->ParseAssignmentExpression(accept_IN, &rhs_classifier, CHECK_OK); | 3178 accept_IN, flags, seen_destructuring, &rhs_classifier, CHECK_OK); |
3013 classifier->Accumulate(rhs_classifier, | 3179 classifier->Accumulate( |
3014 ExpressionClassifier::ExpressionProductions); | 3180 rhs_classifier, ExpressionClassifier::ExpressionProductions | |
| 3181 ExpressionClassifier::CoverInitializedNameProduction); |
3015 | 3182 |
3016 // TODO(1231235): We try to estimate the set of properties set by | 3183 // TODO(1231235): We try to estimate the set of properties set by |
3017 // constructors. We define a new property whenever there is an | 3184 // constructors. We define a new property whenever there is an |
3018 // assignment to a property of 'this'. We should probably only add | 3185 // assignment to a property of 'this'. We should probably only add |
3019 // properties if we haven't seen them before. Otherwise we'll | 3186 // properties if we haven't seen them before. Otherwise we'll |
3020 // probably overestimate the number of properties. | 3187 // probably overestimate the number of properties. |
3021 if (op == Token::ASSIGN && this->IsThisProperty(expression)) { | 3188 if (op == Token::ASSIGN && this->IsThisProperty(expression)) { |
3022 function_state_->AddProperty(); | 3189 function_state_->AddProperty(); |
3023 } | 3190 } |
3024 | 3191 |
3025 this->CheckAssigningFunctionLiteralToProperty(expression, right); | 3192 this->CheckAssigningFunctionLiteralToProperty(expression, right); |
3026 | 3193 |
3027 if (fni_ != NULL) { | 3194 if (fni_ != NULL) { |
3028 // Check if the right hand side is a call to avoid inferring a | 3195 // Check if the right hand side is a call to avoid inferring a |
3029 // name if we're dealing with "a = function(){...}();"-like | 3196 // name if we're dealing with "a = function(){...}();"-like |
3030 // expression. | 3197 // expression. |
3031 if ((op == Token::INIT_VAR | 3198 if ((op == Token::INIT_VAR |
3032 || op == Token::INIT_CONST_LEGACY | 3199 || op == Token::INIT_CONST_LEGACY |
3033 || op == Token::ASSIGN) | 3200 || op == Token::ASSIGN) |
3034 && (!right->IsCall() && !right->IsCallNew())) { | 3201 && (!right->IsCall() && !right->IsCallNew())) { |
3035 fni_->Infer(); | 3202 fni_->Infer(); |
3036 } else { | 3203 } else { |
3037 fni_->RemoveLastFunction(); | 3204 fni_->RemoveLastFunction(); |
3038 } | 3205 } |
3039 fni_->Leave(); | 3206 fni_->Leave(); |
3040 } | 3207 } |
3041 | 3208 |
3042 return factory()->NewAssignment(op, expression, right, pos); | 3209 ExpressionT result = factory()->NewAssignment(op, expression, right, pos); |
| 3210 |
| 3211 if (!is_rhs && *seen_destructuring && !maybe_binding_pattern && |
| 3212 !is_pattern_element) { |
| 3213 return Traits::RewriteDestructuringAssignmentExpression(result); |
| 3214 } |
| 3215 |
| 3216 return result; |
3043 } | 3217 } |
3044 | 3218 |
3045 template <class Traits> | 3219 template <class Traits> |
3046 typename ParserBase<Traits>::ExpressionT | 3220 typename ParserBase<Traits>::ExpressionT |
3047 ParserBase<Traits>::ParseYieldExpression(ExpressionClassifier* classifier, | 3221 ParserBase<Traits>::ParseYieldExpression(ExpressionClassifier* classifier, |
3048 bool* ok) { | 3222 bool* ok) { |
3049 // YieldExpression :: | 3223 // YieldExpression :: |
3050 // 'yield' ([no line terminator] '*'? AssignmentExpression)? | 3224 // 'yield' ([no line terminator] '*'? AssignmentExpression)? |
3051 int pos = peek_position(); | 3225 int pos = peek_position(); |
3052 BindingPatternUnexpectedToken(classifier); | 3226 BindingPatternUnexpectedToken(classifier); |
(...skipping 1100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4153 ExpressionT error = this->NewThrowReferenceError(message, pos); | 4327 ExpressionT error = this->NewThrowReferenceError(message, pos); |
4154 return factory()->NewProperty(expression, error, pos); | 4328 return factory()->NewProperty(expression, error, pos); |
4155 } else { | 4329 } else { |
4156 this->ReportMessageAt(location, message, type); | 4330 this->ReportMessageAt(location, message, type); |
4157 *ok = false; | 4331 *ok = false; |
4158 return this->EmptyExpression(); | 4332 return this->EmptyExpression(); |
4159 } | 4333 } |
4160 } | 4334 } |
4161 | 4335 |
4162 | 4336 |
| 4337 template <typename Traits> |
| 4338 bool ParserBase<Traits>::IsValidReferenceExpression(ExpressionT expression) { |
| 4339 // TODO(caitp): do this in a less redundant way :( |
| 4340 if (expression->IsValidReferenceExpression()) { |
| 4341 if (this->IsIdentifier(expression)) { |
| 4342 if (is_strict(language_mode()) && |
| 4343 this->IsEvalOrArguments(this->AsIdentifier(expression))) { |
| 4344 return false; |
| 4345 } |
| 4346 if (is_strong(language_mode()) && |
| 4347 this->IsUndefined(this->AsIdentifier(expression))) { |
| 4348 return false; |
| 4349 } |
| 4350 } |
| 4351 return true; |
| 4352 } |
| 4353 return false; |
| 4354 } |
| 4355 |
| 4356 |
4163 #undef CHECK_OK | 4357 #undef CHECK_OK |
4164 #undef CHECK_OK_CUSTOM | 4358 #undef CHECK_OK_CUSTOM |
4165 | 4359 |
4166 | 4360 |
4167 template <typename Traits> | 4361 template <typename Traits> |
4168 void ParserBase<Traits>::ObjectLiteralChecker::CheckProperty( | 4362 void ParserBase<Traits>::ObjectLiteralChecker::CheckProperty( |
4169 Token::Value property, PropertyKind type, bool is_static, bool is_generator, | 4363 Token::Value property, PropertyKind type, bool is_static, bool is_generator, |
4170 bool* ok) { | 4364 bool* ok) { |
4171 DCHECK(!is_static); | 4365 DCHECK(!is_static); |
4172 DCHECK(!is_generator || type == kMethodProperty); | 4366 DCHECK(!is_generator || type == kMethodProperty); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4214 return; | 4408 return; |
4215 } | 4409 } |
4216 has_seen_constructor_ = true; | 4410 has_seen_constructor_ = true; |
4217 return; | 4411 return; |
4218 } | 4412 } |
4219 } | 4413 } |
4220 } // namespace internal | 4414 } // namespace internal |
4221 } // namespace v8 | 4415 } // namespace v8 |
4222 | 4416 |
4223 #endif // V8_PREPARSER_H | 4417 #endif // V8_PREPARSER_H |
OLD | NEW |