| Index: src/parsing/parser-base.h
|
| diff --git a/src/parsing/parser-base.h b/src/parsing/parser-base.h
|
| index bdb2cad9c31162df670ea7c0cc0d7f2f8c7d99da..517b04a4b049bb10c4847ed7777fa602c09362c4 100644
|
| --- a/src/parsing/parser-base.h
|
| +++ b/src/parsing/parser-base.h
|
| @@ -57,59 +57,6 @@ static inline bool operator&(ParseFunctionFlags bitfield,
|
| return static_cast<T>(bitfield) & static_cast<T>(mask);
|
| }
|
|
|
| -enum class MethodKind {
|
| - kNormal = 0,
|
| - kStatic = 1 << 0,
|
| - kGenerator = 1 << 1,
|
| - kStaticGenerator = kStatic | kGenerator,
|
| - kAsync = 1 << 2,
|
| - kStaticAsync = kStatic | kAsync,
|
| -
|
| - /* Any non-ordinary method kinds */
|
| - kSpecialMask = kGenerator | kAsync
|
| -};
|
| -
|
| -inline bool IsValidMethodKind(MethodKind kind) {
|
| - return kind == MethodKind::kNormal || kind == MethodKind::kStatic ||
|
| - kind == MethodKind::kGenerator ||
|
| - kind == MethodKind::kStaticGenerator || kind == MethodKind::kAsync ||
|
| - kind == MethodKind::kStaticAsync;
|
| -}
|
| -
|
| -static inline MethodKind operator|(MethodKind lhs, MethodKind rhs) {
|
| - typedef unsigned char T;
|
| - return static_cast<MethodKind>(static_cast<T>(lhs) | static_cast<T>(rhs));
|
| -}
|
| -
|
| -static inline MethodKind& operator|=(MethodKind& lhs, const MethodKind& rhs) {
|
| - lhs = lhs | rhs;
|
| - DCHECK(IsValidMethodKind(lhs));
|
| - return lhs;
|
| -}
|
| -
|
| -static inline bool operator&(MethodKind bitfield, MethodKind mask) {
|
| - typedef unsigned char T;
|
| - return static_cast<T>(bitfield) & static_cast<T>(mask);
|
| -}
|
| -
|
| -inline bool IsNormalMethod(MethodKind kind) {
|
| - return kind == MethodKind::kNormal;
|
| -}
|
| -
|
| -inline bool IsSpecialMethod(MethodKind kind) {
|
| - return kind & MethodKind::kSpecialMask;
|
| -}
|
| -
|
| -inline bool IsStaticMethod(MethodKind kind) {
|
| - return kind & MethodKind::kStatic;
|
| -}
|
| -
|
| -inline bool IsGeneratorMethod(MethodKind kind) {
|
| - return kind & MethodKind::kGenerator;
|
| -}
|
| -
|
| -inline bool IsAsyncMethod(MethodKind kind) { return kind & MethodKind::kAsync; }
|
| -
|
| struct FormalParametersBase {
|
| explicit FormalParametersBase(DeclarationScope* scope) : scope(scope) {}
|
| DeclarationScope* scope;
|
| @@ -184,6 +131,7 @@ struct FormalParametersBase {
|
| // typedef Expression;
|
| // typedef FunctionLiteral;
|
| // typedef ObjectLiteralProperty;
|
| +// typedef ClassLiteralProperty;
|
| // typedef ExpressionList;
|
| // typedef PropertyList;
|
| // typedef FormalParameters;
|
| @@ -209,6 +157,7 @@ class ParserBase {
|
| typedef typename Types::Expression ExpressionT;
|
| typedef typename Types::FunctionLiteral FunctionLiteralT;
|
| typedef typename Types::ObjectLiteralProperty ObjectLiteralPropertyT;
|
| + typedef typename Types::ClassLiteralProperty ClassLiteralPropertyT;
|
| typedef typename Types::ExpressionList ExpressionListT;
|
| typedef typename Types::PropertyList PropertyListT;
|
| typedef typename Types::FormalParameters FormalParametersT;
|
| @@ -300,7 +249,8 @@ class ParserBase {
|
| // clang-format on
|
|
|
| class Checkpoint;
|
| - class ObjectLiteralCheckerBase;
|
| + class ClassLiteralChecker;
|
| + class ObjectLiteralChecker;
|
|
|
| // ---------------------------------------------------------------------------
|
| // ScopeState and its subclasses implement the parser's scope stack.
|
| @@ -1147,14 +1097,15 @@ class ParserBase {
|
|
|
| bool SetPropertyKindFromToken(Token::Value token, PropertyKind* kind);
|
| ExpressionT ParsePropertyName(IdentifierT* name, PropertyKind* kind,
|
| - bool in_class, bool* is_generator, bool* is_get,
|
| - bool* is_set, bool* is_async, bool* is_static,
|
| - bool* is_computed_name, bool* ok);
|
| -
|
| + bool* is_generator, bool* is_get, bool* is_set,
|
| + bool* is_async, bool* is_computed_name,
|
| + bool* ok);
|
| ExpressionT ParseObjectLiteral(bool* ok);
|
| - ObjectLiteralPropertyT ParsePropertyDefinition(
|
| - ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends,
|
| - bool* is_computed_name, bool* has_seen_constructor, IdentifierT* name,
|
| + ClassLiteralPropertyT ParseClassPropertyDefinition(
|
| + ClassLiteralChecker* checker, bool has_extends, bool* is_computed_name,
|
| + bool* has_seen_constructor, IdentifierT* name, bool* ok);
|
| + ObjectLiteralPropertyT ParseObjectPropertyDefinition(
|
| + ObjectLiteralChecker* checker, bool* is_computed_name, IdentifierT* name,
|
| bool* ok);
|
| ExpressionListT ParseArguments(Scanner::Location* first_spread_pos,
|
| bool maybe_arrow, bool* ok);
|
| @@ -1266,46 +1217,33 @@ class ParserBase {
|
| return Call::NOT_EVAL;
|
| }
|
|
|
| - class ObjectLiteralCheckerBase {
|
| - public:
|
| - explicit ObjectLiteralCheckerBase(ParserBase* parser) : parser_(parser) {}
|
| -
|
| - virtual void CheckProperty(Token::Value property, PropertyKind type,
|
| - MethodKind method_type, bool* ok) = 0;
|
| -
|
| - virtual ~ObjectLiteralCheckerBase() {}
|
| -
|
| - protected:
|
| - ParserBase* parser() const { return parser_; }
|
| - Scanner* scanner() const { return parser_->scanner(); }
|
| -
|
| - private:
|
| - ParserBase* parser_;
|
| - };
|
| -
|
| // Validation per ES6 object literals.
|
| - class ObjectLiteralChecker : public ObjectLiteralCheckerBase {
|
| + class ObjectLiteralChecker {
|
| public:
|
| explicit ObjectLiteralChecker(ParserBase* parser)
|
| - : ObjectLiteralCheckerBase(parser), has_seen_proto_(false) {}
|
| + : parser_(parser), has_seen_proto_(false) {}
|
|
|
| - void CheckProperty(Token::Value property, PropertyKind type,
|
| - MethodKind method_type, bool* ok) override;
|
| + void CheckDuplicateProto(Token::Value property);
|
|
|
| private:
|
| bool IsProto() { return this->scanner()->LiteralMatches("__proto__", 9); }
|
|
|
| + ParserBase* parser() const { return parser_; }
|
| + Scanner* scanner() const { return parser_->scanner(); }
|
| +
|
| + ParserBase* parser_;
|
| bool has_seen_proto_;
|
| };
|
|
|
| // Validation per ES6 class literals.
|
| - class ClassLiteralChecker : public ObjectLiteralCheckerBase {
|
| + class ClassLiteralChecker {
|
| public:
|
| explicit ClassLiteralChecker(ParserBase* parser)
|
| - : ObjectLiteralCheckerBase(parser), has_seen_constructor_(false) {}
|
| + : parser_(parser), has_seen_constructor_(false) {}
|
|
|
| - void CheckProperty(Token::Value property, PropertyKind type,
|
| - MethodKind method_type, bool* ok) override;
|
| + void CheckClassMethodName(Token::Value property, PropertyKind type,
|
| + bool is_generator, bool is_async, bool is_static,
|
| + bool* ok);
|
|
|
| private:
|
| bool IsConstructor() {
|
| @@ -1315,6 +1253,10 @@ class ParserBase {
|
| return this->scanner()->LiteralMatches("prototype", 9);
|
| }
|
|
|
| + ParserBase* parser() const { return parser_; }
|
| + Scanner* scanner() const { return parser_->scanner(); }
|
| +
|
| + ParserBase* parser_;
|
| bool has_seen_constructor_;
|
| };
|
|
|
| @@ -1957,15 +1899,13 @@ bool ParserBase<Impl>::SetPropertyKindFromToken(Token::Value token,
|
|
|
| template <class Impl>
|
| typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParsePropertyName(
|
| - IdentifierT* name, PropertyKind* kind, bool in_class, bool* is_generator,
|
| - bool* is_get, bool* is_set, bool* is_async, bool* is_static,
|
| - bool* is_computed_name, bool* ok) {
|
| + IdentifierT* name, PropertyKind* kind, bool* is_generator, bool* is_get,
|
| + bool* is_set, bool* is_async, bool* is_computed_name, bool* ok) {
|
| DCHECK(*kind == PropertyKind::kNotSet);
|
| DCHECK(!*is_generator);
|
| DCHECK(!*is_get);
|
| DCHECK(!*is_set);
|
| DCHECK(!*is_async);
|
| - DCHECK(!*is_static);
|
| DCHECK(!*is_computed_name);
|
|
|
| *is_generator = Check(Token::MUL);
|
| @@ -1976,19 +1916,6 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParsePropertyName(
|
| Token::Value token = peek();
|
| int pos = peek_position();
|
|
|
| - if (in_class && !*is_generator && token == Token::STATIC) {
|
| - Consume(Token::STATIC);
|
| - *kind = PropertyKind::kMethodProperty;
|
| - if (peek() == Token::LPAREN) {
|
| - *name = impl()->GetSymbol(); // TODO(bakkot) specialize on 'static'
|
| - return factory()->NewStringLiteral(*name, pos);
|
| - }
|
| - *is_generator = Check(Token::MUL);
|
| - *is_static = true;
|
| - token = peek();
|
| - pos = peek_position();
|
| - }
|
| -
|
| if (allow_harmony_async_await() && !*is_generator && token == Token::ASYNC &&
|
| !scanner()->HasAnyLineTerminatorAfterNext()) {
|
| Consume(Token::ASYNC);
|
| @@ -2004,23 +1931,15 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParsePropertyName(
|
| }
|
|
|
| if (token == Token::IDENTIFIER && !*is_generator && !*is_async) {
|
| - // This is checking for 'get' and 'set' in particular. Any other identifier
|
| - // must be the property name, and so SetPropertyKindFromToken will return
|
| - // true (unless there's a syntax error).
|
| + // This is checking for 'get' and 'set' in particular.
|
| Consume(Token::IDENTIFIER);
|
| token = peek();
|
| - if (SetPropertyKindFromToken(token, kind)) {
|
| + if (SetPropertyKindFromToken(token, kind) ||
|
| + !scanner()->IsGetOrSet(is_get, is_set)) {
|
| *name = impl()->GetSymbol();
|
| impl()->PushLiteralName(*name);
|
| return factory()->NewStringLiteral(*name, pos);
|
| }
|
| - scanner()->IsGetOrSet(is_get, is_set);
|
| - if (!*is_get && !*is_set) { // TODO(bakkot) have IsGetOrSet return a bool
|
| - Token::Value next = Next();
|
| - ReportUnexpectedToken(next);
|
| - *ok = false;
|
| - return impl()->EmptyExpression();
|
| - }
|
| *kind = PropertyKind::kAccessorProperty;
|
| pos = peek_position();
|
| }
|
| @@ -2069,17 +1988,8 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParsePropertyName(
|
| }
|
|
|
| if (*kind == PropertyKind::kNotSet) {
|
| - if (!SetPropertyKindFromToken(peek(), kind) ||
|
| - (*kind == PropertyKind::kShorthandProperty &&
|
| - !Token::IsIdentifier(token, language_mode(), this->is_generator(),
|
| - parsing_module_ || is_async_function()))) {
|
| - Token::Value next = Next();
|
| - ReportUnexpectedToken(next);
|
| - *ok = false;
|
| - return impl()->EmptyExpression();
|
| - }
|
| + SetPropertyKindFromToken(peek(), kind);
|
| }
|
| - DCHECK(*kind != PropertyKind::kNotSet);
|
|
|
| if (*is_computed_name) {
|
| return expression;
|
| @@ -2094,13 +2004,13 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParsePropertyName(
|
| }
|
|
|
| template <typename Impl>
|
| -typename ParserBase<Impl>::ObjectLiteralPropertyT
|
| -ParserBase<Impl>::ParsePropertyDefinition(ObjectLiteralCheckerBase* checker,
|
| - bool in_class, bool has_extends,
|
| - bool* is_computed_name,
|
| - bool* has_seen_constructor,
|
| - IdentifierT* name, bool* ok) {
|
| - DCHECK(!in_class || has_seen_constructor != nullptr);
|
| +typename ParserBase<Impl>::ClassLiteralPropertyT
|
| +ParserBase<Impl>::ParseClassPropertyDefinition(ClassLiteralChecker* checker,
|
| + bool has_extends,
|
| + bool* is_computed_name,
|
| + bool* has_seen_constructor,
|
| + IdentifierT* name, bool* ok) {
|
| + DCHECK(has_seen_constructor != nullptr);
|
| bool is_get = false;
|
| bool is_set = false;
|
| bool is_generator = false;
|
| @@ -2109,29 +2019,129 @@ ParserBase<Impl>::ParsePropertyDefinition(ObjectLiteralCheckerBase* checker,
|
| PropertyKind kind = PropertyKind::kNotSet;
|
|
|
| Token::Value name_token = peek();
|
| +
|
| + ExpressionT name_expression;
|
| + if (name_token == Token::STATIC) {
|
| + Consume(Token::STATIC);
|
| + if (peek() == Token::LPAREN) {
|
| + kind = PropertyKind::kMethodProperty;
|
| + *name = impl()->GetSymbol(); // TODO(bakkot) specialize on 'static'
|
| + name_expression = factory()->NewStringLiteral(*name, position());
|
| + } else {
|
| + is_static = true;
|
| + name_expression = ParsePropertyName(
|
| + name, &kind, &is_generator, &is_get, &is_set, &is_async,
|
| + is_computed_name, CHECK_OK_CUSTOM(EmptyClassLiteralProperty));
|
| + }
|
| + } else {
|
| + name_expression = ParsePropertyName(
|
| + name, &kind, &is_generator, &is_get, &is_set, &is_async,
|
| + is_computed_name, CHECK_OK_CUSTOM(EmptyClassLiteralProperty));
|
| + }
|
| +
|
| + switch (kind) {
|
| + case PropertyKind::kShorthandProperty:
|
| + case PropertyKind::kValueProperty:
|
| + ReportUnexpectedToken(Next());
|
| + *ok = false;
|
| + return impl()->EmptyClassLiteralProperty();
|
| +
|
| + case PropertyKind::kMethodProperty: {
|
| + DCHECK(!is_get && !is_set);
|
| +
|
| + // MethodDefinition
|
| + // PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}'
|
| + // '*' PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}'
|
| +
|
| + if (!*is_computed_name) {
|
| + checker->CheckClassMethodName(
|
| + name_token, PropertyKind::kMethodProperty, is_generator, is_async,
|
| + is_static, CHECK_OK_CUSTOM(EmptyClassLiteralProperty));
|
| + }
|
| +
|
| + FunctionKind kind = is_generator
|
| + ? FunctionKind::kConciseGeneratorMethod
|
| + : is_async ? FunctionKind::kAsyncConciseMethod
|
| + : FunctionKind::kConciseMethod;
|
| +
|
| + if (!is_static && impl()->IsConstructor(*name)) {
|
| + *has_seen_constructor = true;
|
| + kind = has_extends ? FunctionKind::kSubclassConstructor
|
| + : FunctionKind::kBaseConstructor;
|
| + }
|
| +
|
| + ExpressionT value = impl()->ParseFunctionLiteral(
|
| + *name, scanner()->location(), kSkipFunctionNameCheck, kind,
|
| + kNoSourcePosition, FunctionLiteral::kAccessorOrMethod,
|
| + language_mode(), CHECK_OK_CUSTOM(EmptyClassLiteralProperty));
|
| +
|
| + return factory()->NewClassLiteralProperty(name_expression, value,
|
| + ClassLiteralProperty::METHOD,
|
| + is_static, *is_computed_name);
|
| + }
|
| +
|
| + case PropertyKind::kAccessorProperty: {
|
| + DCHECK((is_get || is_set) && !is_generator && !is_async);
|
| +
|
| + if (!*is_computed_name) {
|
| + checker->CheckClassMethodName(
|
| + name_token, PropertyKind::kAccessorProperty, false, false,
|
| + is_static, CHECK_OK_CUSTOM(EmptyClassLiteralProperty));
|
| + // Make sure the name expression is a string since we need a Name for
|
| + // Runtime_DefineAccessorPropertyUnchecked and since we can determine
|
| + // this statically we can skip the extra runtime check.
|
| + name_expression =
|
| + factory()->NewStringLiteral(*name, name_expression->position());
|
| + }
|
| +
|
| + FunctionKind kind = is_get ? FunctionKind::kGetterFunction
|
| + : FunctionKind::kSetterFunction;
|
| +
|
| + ExpressionT value = impl()->ParseFunctionLiteral(
|
| + *name, scanner()->location(), kSkipFunctionNameCheck, kind,
|
| + kNoSourcePosition, FunctionLiteral::kAccessorOrMethod,
|
| + language_mode(), CHECK_OK_CUSTOM(EmptyClassLiteralProperty));
|
| +
|
| + return factory()->NewClassLiteralProperty(
|
| + name_expression, value,
|
| + is_get ? ClassLiteralProperty::GETTER : ClassLiteralProperty::SETTER,
|
| + is_static, *is_computed_name);
|
| + }
|
| +
|
| + case PropertyKind::kNotSet:
|
| + ReportUnexpectedToken(Next());
|
| + *ok = false;
|
| + return impl()->EmptyClassLiteralProperty();
|
| + }
|
| + UNREACHABLE();
|
| + return impl()->EmptyClassLiteralProperty();
|
| +}
|
| +
|
| +template <typename Impl>
|
| +typename ParserBase<Impl>::ObjectLiteralPropertyT
|
| +ParserBase<Impl>::ParseObjectPropertyDefinition(ObjectLiteralChecker* checker,
|
| + bool* is_computed_name,
|
| + IdentifierT* name, bool* ok) {
|
| + bool is_get = false;
|
| + bool is_set = false;
|
| + bool is_generator = false;
|
| + bool is_async = false;
|
| + PropertyKind kind = PropertyKind::kNotSet;
|
| +
|
| + Token::Value name_token = peek();
|
| int next_beg_pos = scanner()->peek_location().beg_pos;
|
| int next_end_pos = scanner()->peek_location().end_pos;
|
|
|
| - ExpressionT name_expression =
|
| - ParsePropertyName(name, &kind, in_class, &is_generator, &is_get, &is_set,
|
| - &is_async, &is_static, is_computed_name,
|
| - CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
|
| + ExpressionT name_expression = ParsePropertyName(
|
| + name, &kind, &is_generator, &is_get, &is_set, &is_async, is_computed_name,
|
| + CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
|
|
|
| switch (kind) {
|
| case PropertyKind::kValueProperty: {
|
| - if (in_class) {
|
| - Token::Value next = Next();
|
| - ReportUnexpectedToken(next);
|
| - *ok = false;
|
| - return impl()->EmptyObjectLiteralProperty();
|
| - }
|
| -
|
| - DCHECK(!is_get && !is_set && !is_generator && !is_async && !is_static);
|
| + DCHECK(!is_get && !is_set && !is_generator && !is_async);
|
|
|
| if (!*is_computed_name) {
|
| - checker->CheckProperty(name_token, PropertyKind::kValueProperty,
|
| - MethodKind::kNormal,
|
| - CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
|
| + checker->CheckDuplicateProto(name_token);
|
| }
|
| Consume(Token::COLON);
|
| int beg_pos = peek_position();
|
| @@ -2140,7 +2150,7 @@ ParserBase<Impl>::ParsePropertyDefinition(ObjectLiteralCheckerBase* checker,
|
| CheckDestructuringElement(value, beg_pos, scanner()->location().end_pos);
|
|
|
| return factory()->NewObjectLiteralProperty(name_expression, value,
|
| - is_static, *is_computed_name);
|
| + *is_computed_name);
|
| }
|
|
|
| case PropertyKind::kShorthandProperty: {
|
| @@ -2150,15 +2160,17 @@ ParserBase<Impl>::ParsePropertyDefinition(ObjectLiteralCheckerBase* checker,
|
| //
|
| // CoverInitializedName
|
| // IdentifierReference Initializer?
|
| - if (in_class) {
|
| - Token::Value next = Next();
|
| - ReportUnexpectedToken(next);
|
| + DCHECK(!is_get && !is_set && !is_generator && !is_async);
|
| +
|
| + if (!Token::IsIdentifier(name_token, language_mode(),
|
| + this->is_generator(),
|
| + parsing_module_ || is_async_function())) {
|
| + ReportUnexpectedToken(Next());
|
| *ok = false;
|
| return impl()->EmptyObjectLiteralProperty();
|
| }
|
|
|
| - DCHECK(!is_get && !is_set && !is_generator && !is_async && !is_static &&
|
| - !*is_computed_name);
|
| + DCHECK(!*is_computed_name);
|
|
|
| if (classifier()->duplicate_finder() != nullptr &&
|
| scanner()->FindSymbol(classifier()->duplicate_finder(), 1) != 0) {
|
| @@ -2205,24 +2217,12 @@ ParserBase<Impl>::ParsePropertyDefinition(ObjectLiteralCheckerBase* checker,
|
| }
|
|
|
| return factory()->NewObjectLiteralProperty(
|
| - name_expression, value, ObjectLiteralProperty::COMPUTED, is_static,
|
| - false);
|
| + name_expression, value, ObjectLiteralProperty::COMPUTED, false);
|
| }
|
|
|
| case PropertyKind::kMethodProperty: {
|
| DCHECK(!is_get && !is_set);
|
|
|
| - MethodKind method_kind = MethodKind::kNormal;
|
| - if (is_generator) {
|
| - method_kind |= MethodKind::kGenerator;
|
| - }
|
| - if (is_async) {
|
| - method_kind |= MethodKind::kAsync;
|
| - }
|
| - if (is_static) {
|
| - method_kind |= MethodKind::kStatic;
|
| - }
|
| -
|
| // MethodDefinition
|
| // PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}'
|
| // '*' PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}'
|
| @@ -2231,74 +2231,55 @@ ParserBase<Impl>::ParsePropertyDefinition(ObjectLiteralCheckerBase* checker,
|
| Scanner::Location(next_beg_pos, scanner()->location().end_pos),
|
| MessageTemplate::kInvalidDestructuringTarget);
|
|
|
| - if (!*is_computed_name) {
|
| - checker->CheckProperty(name_token, PropertyKind::kMethodProperty,
|
| - method_kind,
|
| - CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
|
| - }
|
| -
|
| FunctionKind kind = is_generator
|
| ? FunctionKind::kConciseGeneratorMethod
|
| : is_async ? FunctionKind::kAsyncConciseMethod
|
| : FunctionKind::kConciseMethod;
|
|
|
| - if (in_class && !is_static && impl()->IsConstructor(*name)) {
|
| - *has_seen_constructor = true;
|
| - kind = has_extends ? FunctionKind::kSubclassConstructor
|
| - : FunctionKind::kBaseConstructor;
|
| - }
|
| -
|
| ExpressionT value = impl()->ParseFunctionLiteral(
|
| *name, scanner()->location(), kSkipFunctionNameCheck, kind,
|
| kNoSourcePosition, FunctionLiteral::kAccessorOrMethod,
|
| language_mode(), CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
|
|
|
| return factory()->NewObjectLiteralProperty(
|
| - name_expression, value, ObjectLiteralProperty::COMPUTED, is_static,
|
| + name_expression, value, ObjectLiteralProperty::COMPUTED,
|
| *is_computed_name);
|
| }
|
|
|
| case PropertyKind::kAccessorProperty: {
|
| - DCHECK((is_get || is_set) && !is_generator && !is_async);
|
| -
|
| - MethodKind method_kind = MethodKind::kNormal;
|
| - if (is_static) {
|
| - DCHECK(in_class);
|
| - method_kind |= MethodKind::kStatic;
|
| - }
|
| + DCHECK((is_get || is_set) && !(is_set && is_get) && !is_generator &&
|
| + !is_async);
|
|
|
| classifier()->RecordPatternError(
|
| Scanner::Location(next_beg_pos, scanner()->location().end_pos),
|
| MessageTemplate::kInvalidDestructuringTarget);
|
| - if (!*is_computed_name) {
|
| - checker->CheckProperty(name_token, PropertyKind::kAccessorProperty,
|
| - method_kind,
|
| - CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
|
| - }
|
|
|
| - FunctionLiteralT value = impl()->ParseFunctionLiteral(
|
| - *name, scanner()->location(), kSkipFunctionNameCheck,
|
| - is_get ? FunctionKind::kGetterFunction
|
| - : FunctionKind::kSetterFunction,
|
| - kNoSourcePosition, FunctionLiteral::kAccessorOrMethod,
|
| - language_mode(), CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
|
| -
|
| - // Make sure the name expression is a string since we need a Name for
|
| - // Runtime_DefineAccessorPropertyUnchecked and since we can determine this
|
| - // statically we can skip the extra runtime check.
|
| if (!*is_computed_name) {
|
| + // Make sure the name expression is a string since we need a Name for
|
| + // Runtime_DefineAccessorPropertyUnchecked and since we can determine
|
| + // this statically we can skip the extra runtime check.
|
| name_expression =
|
| factory()->NewStringLiteral(*name, name_expression->position());
|
| }
|
|
|
| + FunctionKind kind = is_get ? FunctionKind::kGetterFunction
|
| + : FunctionKind::kSetterFunction;
|
| +
|
| + ExpressionT value = impl()->ParseFunctionLiteral(
|
| + *name, scanner()->location(), kSkipFunctionNameCheck, kind,
|
| + kNoSourcePosition, FunctionLiteral::kAccessorOrMethod,
|
| + language_mode(), CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
|
| +
|
| return factory()->NewObjectLiteralProperty(
|
| name_expression, value, is_get ? ObjectLiteralProperty::GETTER
|
| : ObjectLiteralProperty::SETTER,
|
| - is_static, *is_computed_name);
|
| + *is_computed_name);
|
| }
|
|
|
| case PropertyKind::kNotSet:
|
| - UNREACHABLE();
|
| + ReportUnexpectedToken(Next());
|
| + *ok = false;
|
| + return impl()->EmptyObjectLiteralProperty();
|
| }
|
| UNREACHABLE();
|
| return impl()->EmptyObjectLiteralProperty();
|
| @@ -2321,13 +2302,10 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseObjectLiteral(
|
| while (peek() != Token::RBRACE) {
|
| FuncNameInferrer::State fni_state(fni_);
|
|
|
| - const bool in_class = false;
|
| - const bool has_extends = false;
|
| bool is_computed_name = false;
|
| IdentifierT name = impl()->EmptyIdentifier();
|
| - ObjectLiteralPropertyT property =
|
| - ParsePropertyDefinition(&checker, in_class, has_extends,
|
| - &is_computed_name, nullptr, &name, CHECK_OK);
|
| + ObjectLiteralPropertyT property = ParseObjectPropertyDefinition(
|
| + &checker, &is_computed_name, &name, CHECK_OK);
|
|
|
| if (is_computed_name) {
|
| has_computed_names = true;
|
| @@ -4205,16 +4183,11 @@ ParserBase<Impl>::ParseStatementAsUnlabelled(
|
| #undef CHECK_OK_CUSTOM
|
|
|
| template <typename Impl>
|
| -void ParserBase<Impl>::ObjectLiteralChecker::CheckProperty(
|
| - Token::Value property, PropertyKind type, MethodKind method_type,
|
| - bool* ok) {
|
| - DCHECK(!IsStaticMethod(method_type));
|
| - DCHECK(!IsSpecialMethod(method_type) ||
|
| - type == PropertyKind::kMethodProperty);
|
| -
|
| +void ParserBase<Impl>::ObjectLiteralChecker::CheckDuplicateProto(
|
| + Token::Value property) {
|
| if (property == Token::SMI || property == Token::NUMBER) return;
|
|
|
| - if (type == PropertyKind::kValueProperty && IsProto()) {
|
| + if (IsProto()) {
|
| if (has_seen_proto_) {
|
| this->parser()->classifier()->RecordExpressionError(
|
| this->scanner()->location(), MessageTemplate::kDuplicateProto);
|
| @@ -4225,23 +4198,21 @@ void ParserBase<Impl>::ObjectLiteralChecker::CheckProperty(
|
| }
|
|
|
| template <typename Impl>
|
| -void ParserBase<Impl>::ClassLiteralChecker::CheckProperty(
|
| - Token::Value property, PropertyKind type, MethodKind method_type,
|
| - bool* ok) {
|
| +void ParserBase<Impl>::ClassLiteralChecker::CheckClassMethodName(
|
| + Token::Value property, PropertyKind type, bool is_generator, bool is_async,
|
| + bool is_static, bool* ok) {
|
| DCHECK(type == PropertyKind::kMethodProperty ||
|
| type == PropertyKind::kAccessorProperty);
|
|
|
| if (property == Token::SMI || property == Token::NUMBER) return;
|
|
|
| - if (IsStaticMethod(method_type)) {
|
| + if (is_static) {
|
| if (IsPrototype()) {
|
| this->parser()->ReportMessage(MessageTemplate::kStaticPrototype);
|
| *ok = false;
|
| return;
|
| }
|
| } else if (IsConstructor()) {
|
| - const bool is_generator = IsGeneratorMethod(method_type);
|
| - const bool is_async = IsAsyncMethod(method_type);
|
| if (is_generator || is_async || type == PropertyKind::kAccessorProperty) {
|
| MessageTemplate::Template msg =
|
| is_generator ? MessageTemplate::kConstructorIsGenerator
|
|
|