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

Side by Side Diff: src/parsing/parser-base.h

Issue 2255353002: [parser] Allow duplicate __proto__ keys in patterns (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: fix rebase issues Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef V8_PARSING_PARSER_BASE_H 5 #ifndef V8_PARSING_PARSER_BASE_H
6 #define V8_PARSING_PARSER_BASE_H 6 #define V8_PARSING_PARSER_BASE_H
7 7
8 #include "src/ast/scopes.h" 8 #include "src/ast/scopes.h"
9 #include "src/bailout-reason.h" 9 #include "src/bailout-reason.h"
10 #include "src/base/hashmap.h" 10 #include "src/base/hashmap.h"
(...skipping 1164 matching lines...) Expand 10 before | Expand all | Expand 10 after
1175 kAccessorProperty, 1175 kAccessorProperty,
1176 kValueProperty, 1176 kValueProperty,
1177 kMethodProperty 1177 kMethodProperty
1178 }; 1178 };
1179 1179
1180 class ObjectLiteralCheckerBase { 1180 class ObjectLiteralCheckerBase {
1181 public: 1181 public:
1182 explicit ObjectLiteralCheckerBase(ParserBase* parser) : parser_(parser) {} 1182 explicit ObjectLiteralCheckerBase(ParserBase* parser) : parser_(parser) {}
1183 1183
1184 virtual void CheckProperty(Token::Value property, PropertyKind type, 1184 virtual void CheckProperty(Token::Value property, PropertyKind type,
1185 MethodKind method_type, bool* ok) = 0; 1185 MethodKind method_type,
1186 ExpressionClassifier* classifier, bool* ok) = 0;
1186 1187
1187 virtual ~ObjectLiteralCheckerBase() {} 1188 virtual ~ObjectLiteralCheckerBase() {}
1188 1189
1189 protected: 1190 protected:
1190 ParserBase* parser() const { return parser_; } 1191 ParserBase* parser() const { return parser_; }
1191 Scanner* scanner() const { return parser_->scanner(); } 1192 Scanner* scanner() const { return parser_->scanner(); }
1192 1193
1193 private: 1194 private:
1194 ParserBase* parser_; 1195 ParserBase* parser_;
1195 }; 1196 };
1196 1197
1197 // Validation per ES6 object literals. 1198 // Validation per ES6 object literals.
1198 class ObjectLiteralChecker : public ObjectLiteralCheckerBase { 1199 class ObjectLiteralChecker : public ObjectLiteralCheckerBase {
1199 public: 1200 public:
1200 explicit ObjectLiteralChecker(ParserBase* parser) 1201 explicit ObjectLiteralChecker(ParserBase* parser)
1201 : ObjectLiteralCheckerBase(parser), has_seen_proto_(false) {} 1202 : ObjectLiteralCheckerBase(parser), has_seen_proto_(false) {}
1202 1203
1203 void CheckProperty(Token::Value property, PropertyKind type, 1204 void CheckProperty(Token::Value property, PropertyKind type,
1204 MethodKind method_type, bool* ok) override; 1205 MethodKind method_type, ExpressionClassifier* classifier,
1206 bool* ok) override;
1205 1207
1206 private: 1208 private:
1207 bool IsProto() { return this->scanner()->LiteralMatches("__proto__", 9); } 1209 bool IsProto() { return this->scanner()->LiteralMatches("__proto__", 9); }
1208 1210
1209 bool has_seen_proto_; 1211 bool has_seen_proto_;
1210 }; 1212 };
1211 1213
1212 // Validation per ES6 class literals. 1214 // Validation per ES6 class literals.
1213 class ClassLiteralChecker : public ObjectLiteralCheckerBase { 1215 class ClassLiteralChecker : public ObjectLiteralCheckerBase {
1214 public: 1216 public:
1215 explicit ClassLiteralChecker(ParserBase* parser) 1217 explicit ClassLiteralChecker(ParserBase* parser)
1216 : ObjectLiteralCheckerBase(parser), has_seen_constructor_(false) {} 1218 : ObjectLiteralCheckerBase(parser), has_seen_constructor_(false) {}
1217 1219
1218 void CheckProperty(Token::Value property, PropertyKind type, 1220 void CheckProperty(Token::Value property, PropertyKind type,
1219 MethodKind method_type, bool* ok) override; 1221 MethodKind method_type, ExpressionClassifier* classifier,
1222 bool* ok) override;
1220 1223
1221 private: 1224 private:
1222 bool IsConstructor() { 1225 bool IsConstructor() {
1223 return this->scanner()->LiteralMatches("constructor", 11); 1226 return this->scanner()->LiteralMatches("constructor", 11);
1224 } 1227 }
1225 bool IsPrototype() { 1228 bool IsPrototype() {
1226 return this->scanner()->LiteralMatches("prototype", 9); 1229 return this->scanner()->LiteralMatches("prototype", 9);
1227 } 1230 }
1228 1231
1229 bool has_seen_constructor_; 1232 bool has_seen_constructor_;
(...skipping 724 matching lines...) Expand 10 before | Expand all | Expand 10 after
1954 } 1957 }
1955 1958
1956 if (!in_class && !is_generator) { 1959 if (!in_class && !is_generator) {
1957 DCHECK(!IsStaticMethod(method_kind)); 1960 DCHECK(!IsStaticMethod(method_kind));
1958 1961
1959 if (peek() == Token::COLON) { 1962 if (peek() == Token::COLON) {
1960 // PropertyDefinition 1963 // PropertyDefinition
1961 // PropertyName ':' AssignmentExpression 1964 // PropertyName ':' AssignmentExpression
1962 if (!*is_computed_name) { 1965 if (!*is_computed_name) {
1963 checker->CheckProperty(name_token, kValueProperty, MethodKind::kNormal, 1966 checker->CheckProperty(name_token, kValueProperty, MethodKind::kNormal,
1967 classifier,
1964 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 1968 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
1965 } 1969 }
1966 Consume(Token::COLON); 1970 Consume(Token::COLON);
1967 int beg_pos = peek_position(); 1971 int beg_pos = peek_position();
1968 ExpressionT value = this->ParseAssignmentExpression( 1972 ExpressionT value = this->ParseAssignmentExpression(
1969 true, classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 1973 true, classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
1970 CheckDestructuringElement(value, classifier, beg_pos, 1974 CheckDestructuringElement(value, classifier, beg_pos,
1971 scanner()->location().end_pos); 1975 scanner()->location().end_pos);
1972 1976
1973 return factory()->NewObjectLiteralProperty(name_expression, value, 1977 return factory()->NewObjectLiteralProperty(name_expression, value,
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
2048 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 2052 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2049 method_kind |= MethodKind::kAsync; 2053 method_kind |= MethodKind::kAsync;
2050 } 2054 }
2051 2055
2052 if (is_generator || peek() == Token::LPAREN) { 2056 if (is_generator || peek() == Token::LPAREN) {
2053 // MethodDefinition 2057 // MethodDefinition
2054 // PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' 2058 // PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}'
2055 // '*' PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' 2059 // '*' PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}'
2056 if (!*is_computed_name) { 2060 if (!*is_computed_name) {
2057 checker->CheckProperty(name_token, kMethodProperty, method_kind, 2061 checker->CheckProperty(name_token, kMethodProperty, method_kind,
2062 classifier,
2058 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 2063 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2059 } 2064 }
2060 2065
2061 FunctionKind kind = is_generator 2066 FunctionKind kind = is_generator
2062 ? FunctionKind::kConciseGeneratorMethod 2067 ? FunctionKind::kConciseGeneratorMethod
2063 : is_async ? FunctionKind::kAsyncConciseMethod 2068 : is_async ? FunctionKind::kAsyncConciseMethod
2064 : FunctionKind::kConciseMethod; 2069 : FunctionKind::kConciseMethod;
2065 2070
2066 if (in_class && !IsStaticMethod(method_kind) && 2071 if (in_class && !IsStaticMethod(method_kind) &&
2067 this->IsConstructor(*name)) { 2072 this->IsConstructor(*name)) {
(...skipping 30 matching lines...) Expand all
2098 *name = this->EmptyIdentifier(); 2103 *name = this->EmptyIdentifier();
2099 bool dont_care = false; 2104 bool dont_care = false;
2100 name_token = peek(); 2105 name_token = peek();
2101 2106
2102 name_expression = ParsePropertyName( 2107 name_expression = ParsePropertyName(
2103 name, &dont_care, &dont_care, &dont_care, is_computed_name, classifier, 2108 name, &dont_care, &dont_care, &dont_care, is_computed_name, classifier,
2104 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 2109 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2105 2110
2106 if (!*is_computed_name) { 2111 if (!*is_computed_name) {
2107 checker->CheckProperty(name_token, kAccessorProperty, method_kind, 2112 checker->CheckProperty(name_token, kAccessorProperty, method_kind,
2113 classifier,
2108 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 2114 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2109 } 2115 }
2110 2116
2111 typename Traits::Type::FunctionLiteral value = this->ParseFunctionLiteral( 2117 typename Traits::Type::FunctionLiteral value = this->ParseFunctionLiteral(
2112 *name, scanner()->location(), kSkipFunctionNameCheck, 2118 *name, scanner()->location(), kSkipFunctionNameCheck,
2113 is_get ? FunctionKind::kGetterFunction : FunctionKind::kSetterFunction, 2119 is_get ? FunctionKind::kGetterFunction : FunctionKind::kSetterFunction,
2114 kNoSourcePosition, FunctionLiteral::kAccessorOrMethod, language_mode(), 2120 kNoSourcePosition, FunctionLiteral::kAccessorOrMethod, language_mode(),
2115 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 2121 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2116 2122
2117 // Make sure the name expression is a string since we need a Name for 2123 // Make sure the name expression is a string since we need a Name for
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after
2402 return expression; 2408 return expression;
2403 } 2409 }
2404 2410
2405 // Now pending non-pattern expressions must be discarded. 2411 // Now pending non-pattern expressions must be discarded.
2406 arrow_formals_classifier.Discard(); 2412 arrow_formals_classifier.Discard();
2407 2413
2408 CheckNoTailCallExpressions(classifier, CHECK_OK); 2414 CheckNoTailCallExpressions(classifier, CHECK_OK);
2409 2415
2410 if (IsValidPattern(expression) && peek() == Token::ASSIGN) { 2416 if (IsValidPattern(expression) && peek() == Token::ASSIGN) {
2411 classifier->ForgiveCoverInitializedNameError(); 2417 classifier->ForgiveCoverInitializedNameError();
2418 classifier->ForgiveExpressionError();
adamk 2016/08/18 20:35:22 Is this necessary? What fails if you don't "forgiv
gsathya 2016/08/19 20:11:18 As discussed offline -- leaving this here.
2412 ValidateAssignmentPattern(classifier, CHECK_OK); 2419 ValidateAssignmentPattern(classifier, CHECK_OK);
2413 is_destructuring_assignment = true; 2420 is_destructuring_assignment = true;
2414 } else { 2421 } else {
2415 expression = this->CheckAndRewriteReferenceExpression( 2422 expression = this->CheckAndRewriteReferenceExpression(
2416 expression, lhs_beg_pos, scanner()->location().end_pos, 2423 expression, lhs_beg_pos, scanner()->location().end_pos,
2417 MessageTemplate::kInvalidLhsInAssignment, CHECK_OK); 2424 MessageTemplate::kInvalidLhsInAssignment, CHECK_OK);
2418 } 2425 }
2419 2426
2420 expression = this->MarkExpressionAsAssigned(expression); 2427 expression = this->MarkExpressionAsAssigned(expression);
2421 2428
(...skipping 10 matching lines...) Expand all
2432 ExpressionT right = 2439 ExpressionT right =
2433 this->ParseAssignmentExpression(accept_IN, &rhs_classifier, CHECK_OK); 2440 this->ParseAssignmentExpression(accept_IN, &rhs_classifier, CHECK_OK);
2434 CheckNoTailCallExpressions(&rhs_classifier, CHECK_OK); 2441 CheckNoTailCallExpressions(&rhs_classifier, CHECK_OK);
2435 Traits::RewriteNonPattern(&rhs_classifier, CHECK_OK); 2442 Traits::RewriteNonPattern(&rhs_classifier, CHECK_OK);
2436 classifier->Accumulate( 2443 classifier->Accumulate(
2437 &rhs_classifier, 2444 &rhs_classifier,
2438 ExpressionClassifier::ExpressionProductions | 2445 ExpressionClassifier::ExpressionProductions |
2439 ExpressionClassifier::CoverInitializedNameProduction | 2446 ExpressionClassifier::CoverInitializedNameProduction |
2440 ExpressionClassifier::AsyncArrowFormalParametersProduction); 2447 ExpressionClassifier::AsyncArrowFormalParametersProduction);
2441 2448
2449 if (!classifier->is_valid_expression())
adamk 2016/08/18 20:35:22 Was this necessary? I wouldn't think you'd need to
gsathya 2016/08/19 20:11:18 Removed.
2450 ReportClassifierError(classifier->expression_error());
2451
2442 // TODO(1231235): We try to estimate the set of properties set by 2452 // TODO(1231235): We try to estimate the set of properties set by
2443 // constructors. We define a new property whenever there is an 2453 // constructors. We define a new property whenever there is an
2444 // assignment to a property of 'this'. We should probably only add 2454 // assignment to a property of 'this'. We should probably only add
2445 // properties if we haven't seen them before. Otherwise we'll 2455 // properties if we haven't seen them before. Otherwise we'll
2446 // probably overestimate the number of properties. 2456 // probably overestimate the number of properties.
2447 if (op == Token::ASSIGN && this->IsThisProperty(expression)) { 2457 if (op == Token::ASSIGN && this->IsThisProperty(expression)) {
2448 function_state_->AddProperty(); 2458 function_state_->AddProperty();
2449 } 2459 }
2450 2460
2451 this->CheckAssigningFunctionLiteralToProperty(expression, right); 2461 this->CheckAssigningFunctionLiteralToProperty(expression, right);
(...skipping 1218 matching lines...) Expand 10 before | Expand all | Expand 10 after
3670 } 3680 }
3671 } 3681 }
3672 3682
3673 3683
3674 #undef CHECK_OK 3684 #undef CHECK_OK
3675 #undef CHECK_OK_CUSTOM 3685 #undef CHECK_OK_CUSTOM
3676 3686
3677 template <typename Traits> 3687 template <typename Traits>
3678 void ParserBase<Traits>::ObjectLiteralChecker::CheckProperty( 3688 void ParserBase<Traits>::ObjectLiteralChecker::CheckProperty(
3679 Token::Value property, PropertyKind type, MethodKind method_type, 3689 Token::Value property, PropertyKind type, MethodKind method_type,
3680 bool* ok) { 3690 ExpressionClassifier* classifier, bool* ok) {
adamk 2016/08/18 20:35:22 Hmm, it's a little strange that this takes "ok" no
gsathya 2016/08/19 20:11:18 Yeah :/ It's the same with classifier being added
3681 DCHECK(!IsStaticMethod(method_type)); 3691 DCHECK(!IsStaticMethod(method_type));
3682 DCHECK(!IsSpecialMethod(method_type) || type == kMethodProperty); 3692 DCHECK(!IsSpecialMethod(method_type) || type == kMethodProperty);
3683 3693
3684 if (property == Token::SMI || property == Token::NUMBER) return; 3694 if (property == Token::SMI || property == Token::NUMBER) return;
3685 3695
3686 if (type == kValueProperty && IsProto()) { 3696 if (type == kValueProperty && IsProto()) {
3687 if (has_seen_proto_) { 3697 if (has_seen_proto_) {
3688 this->parser()->ReportMessage(MessageTemplate::kDuplicateProto); 3698 classifier->RecordExpressionError(this->scanner()->location(),
3689 *ok = false; 3699 MessageTemplate::kDuplicateProto,
3700 kSyntaxError);
3690 return; 3701 return;
3691 } 3702 }
3692 has_seen_proto_ = true; 3703 has_seen_proto_ = true;
3693 return;
3694 } 3704 }
3695 } 3705 }
3696 3706
3697 template <typename Traits> 3707 template <typename Traits>
3698 void ParserBase<Traits>::ClassLiteralChecker::CheckProperty( 3708 void ParserBase<Traits>::ClassLiteralChecker::CheckProperty(
3699 Token::Value property, PropertyKind type, MethodKind method_type, 3709 Token::Value property, PropertyKind type, MethodKind method_type,
3700 bool* ok) { 3710 ExpressionClassifier* classifier, bool* ok) {
3701 DCHECK(type == kMethodProperty || type == kAccessorProperty); 3711 DCHECK(type == kMethodProperty || type == kAccessorProperty);
3702 3712
3703 if (property == Token::SMI || property == Token::NUMBER) return; 3713 if (property == Token::SMI || property == Token::NUMBER) return;
3704 3714
3705 if (IsStaticMethod(method_type)) { 3715 if (IsStaticMethod(method_type)) {
3706 if (IsPrototype()) { 3716 if (IsPrototype()) {
3707 this->parser()->ReportMessage(MessageTemplate::kStaticPrototype); 3717 this->parser()->ReportMessage(MessageTemplate::kStaticPrototype);
3708 *ok = false; 3718 *ok = false;
3709 return; 3719 return;
3710 } 3720 }
(...skipping 17 matching lines...) Expand all
3728 has_seen_constructor_ = true; 3738 has_seen_constructor_ = true;
3729 return; 3739 return;
3730 } 3740 }
3731 } 3741 }
3732 3742
3733 3743
3734 } // namespace internal 3744 } // namespace internal
3735 } // namespace v8 3745 } // namespace v8
3736 3746
3737 #endif // V8_PARSING_PARSER_BASE_H 3747 #endif // V8_PARSING_PARSER_BASE_H
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698