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

Side by Side Diff: src/preparser.h

Issue 1411203002: [es6] implement destructuring assignment [clean diff] (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: rename `recorded_first()` to `FirstRecorded()` because non-accessor Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/parser.cc ('k') | test/cctest/test-parsing.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef V8_PREPARSER_H 5 #ifndef V8_PREPARSER_H
6 #define V8_PREPARSER_H 6 #define V8_PREPARSER_H
7 7
8 #include "src/bailout-reason.h" 8 #include "src/bailout-reason.h"
9 #include "src/expression-classifier.h" 9 #include "src/expression-classifier.h"
10 #include "src/func-name-inferrer.h" 10 #include "src/func-name-inferrer.h"
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
2968 3102
2969 checkpoint.Restore(&parameters.materialized_literals_count); 3103 checkpoint.Restore(&parameters.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
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
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
OLDNEW
« no previous file with comments | « src/parser.cc ('k') | test/cctest/test-parsing.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698