Index: src/preparser.h |
diff --git a/src/preparser.h b/src/preparser.h |
index a53abfe4ff3af732cd2cd46ac79db8c35264f698..2db88e7bc2687cd7bfdc3399665934c6a77ae100 100644 |
--- a/src/preparser.h |
+++ b/src/preparser.h |
@@ -476,6 +476,7 @@ class ParserBase : public Traits { |
ExpressionT ParseObjectLiteral(bool* ok); |
ObjectLiteralPropertyT ParsePropertyDefinition(ObjectLiteralChecker* checker, |
bool in_class, bool is_static, |
+ bool* has_seen_constructor, |
bool* ok); |
typename Traits::Type::ExpressionList ParseArguments(bool* ok); |
ExpressionT ParseAssignmentExpression(bool accept_IN, bool* ok); |
@@ -1183,10 +1184,7 @@ class PreParserTraits { |
return false; |
} |
- bool IsConstructorProperty(PreParserExpression property) { return false; } |
- |
static PreParserExpression GetPropertyValue(PreParserExpression property) { |
- UNREACHABLE(); |
return PreParserExpression::Default(); |
} |
@@ -1925,7 +1923,9 @@ typename ParserBase<Traits>::IdentifierT ParserBase<Traits>::ParsePropertyName( |
template <class Traits> |
typename ParserBase<Traits>::ObjectLiteralPropertyT ParserBase< |
Traits>::ParsePropertyDefinition(ObjectLiteralChecker* checker, |
- bool in_class, bool is_static, bool* ok) { |
+ bool in_class, bool is_static, |
+ bool* has_seen_constructor, bool* ok) { |
+ DCHECK(!in_class || is_static || has_seen_constructor != NULL); |
ExpressionT value = this->EmptyExpression(); |
bool is_get = false; |
bool is_set = false; |
@@ -1942,8 +1942,10 @@ typename ParserBase<Traits>::ObjectLiteralPropertyT ParserBase< |
if (!in_class && !is_generator && peek() == Token::COLON) { |
// PropertyDefinition : PropertyName ':' AssignmentExpression |
- checker->CheckProperty(name_token, kValueProperty, |
- CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
+ if (checker != NULL) { |
+ checker->CheckProperty(name_token, kValueProperty, |
+ CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
+ } |
Consume(Token::COLON); |
value = this->ParseAssignmentExpression( |
true, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
@@ -1968,11 +1970,20 @@ typename ParserBase<Traits>::ObjectLiteralPropertyT ParserBase< |
return this->EmptyObjectLiteralProperty(); |
} |
+ if (*has_seen_constructor) { |
+ ReportMessageAt(scanner()->location(), "duplicate_constructor"); |
+ *ok = false; |
+ return this->EmptyObjectLiteralProperty(); |
+ } |
+ |
+ *has_seen_constructor = true; |
kind = FunctionKind::kNormalFunction; |
} |
- checker->CheckProperty(name_token, kValueProperty, |
- CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
+ if (checker != NULL) { |
+ checker->CheckProperty(name_token, kValueProperty, |
+ CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
+ } |
value = this->ParseFunctionLiteral( |
name, scanner()->location(), |
@@ -1983,7 +1994,7 @@ typename ParserBase<Traits>::ObjectLiteralPropertyT ParserBase< |
} else if (in_class && name_is_static && !is_static) { |
// static MethodDefinition |
- return ParsePropertyDefinition(checker, true, true, ok); |
+ return ParsePropertyDefinition(checker, true, true, NULL, ok); |
} else if (is_get || is_set) { |
// Accessor |
@@ -1998,16 +2009,15 @@ typename ParserBase<Traits>::ObjectLiteralPropertyT ParserBase< |
*ok = false; |
return this->EmptyObjectLiteralProperty(); |
} else if (in_class && !is_static && this->IsConstructor(name)) { |
- // ES6, spec draft rev 27, treats static get constructor as an error too. |
- // https://bugs.ecmascript.org/show_bug.cgi?id=3223 |
- // TODO(arv): Update when bug is resolved. |
ReportMessageAt(scanner()->location(), "constructor_special_method"); |
*ok = false; |
return this->EmptyObjectLiteralProperty(); |
} |
- checker->CheckProperty(name_token, |
- is_get ? kGetterProperty : kSetterProperty, |
- CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
+ if (checker != NULL) { |
+ checker->CheckProperty(name_token, |
+ is_get ? kGetterProperty : kSetterProperty, |
+ CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
+ } |
typename Traits::Type::FunctionLiteral value = this->ParseFunctionLiteral( |
name, scanner()->location(), |
@@ -2061,8 +2071,8 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseObjectLiteral( |
const bool in_class = false; |
const bool is_static = false; |
- ObjectLiteralPropertyT property = |
- this->ParsePropertyDefinition(&checker, in_class, is_static, CHECK_OK); |
+ ObjectLiteralPropertyT property = this->ParsePropertyDefinition( |
+ &checker, in_class, is_static, NULL, CHECK_OK); |
// Mark top-level object literals that contain function literals and |
// pretenure the literal so it can be added as a constant function |
@@ -2744,22 +2754,22 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseClassLiteral( |
scope_->SetStrictMode(STRICT); |
scope_->SetScopeName(name); |
- ObjectLiteralChecker checker(this, STRICT); |
typename Traits::Type::PropertyList properties = |
this->NewPropertyList(4, zone_); |
ExpressionT constructor = this->EmptyExpression(); |
+ bool has_seen_constructor = false; |
Expect(Token::LBRACE, CHECK_OK); |
while (peek() != Token::RBRACE) { |
if (Check(Token::SEMICOLON)) continue; |
if (fni_ != NULL) fni_->Enter(); |
- |
const bool in_class = true; |
const bool is_static = false; |
- ObjectLiteralPropertyT property = |
- this->ParsePropertyDefinition(&checker, in_class, is_static, CHECK_OK); |
+ bool old_has_seen_constructor = has_seen_constructor; |
+ ObjectLiteralPropertyT property = this->ParsePropertyDefinition( |
+ NULL, in_class, is_static, &has_seen_constructor, CHECK_OK); |
- if (this->IsConstructorProperty(property)) { |
+ if (has_seen_constructor != old_has_seen_constructor) { |
constructor = this->GetPropertyValue(property); |
} else { |
properties->Add(property, zone()); |