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

Unified Diff: src/parsing/parser-base.h

Issue 2315733003: Class fields, part 1 (parsing and infrastructure) (Closed)
Patch Set: whitespace Created 4 years, 3 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/parsing/parser.cc ('k') | src/parsing/preparser.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/parsing/parser-base.h
diff --git a/src/parsing/parser-base.h b/src/parsing/parser-base.h
index 2d669cff1d3812edde56b5161e3bcec4b23b8cf2..f00364750994ff42a7fb81274f61a39cecc8575a 100644
--- a/src/parsing/parser-base.h
+++ b/src/parsing/parser-base.h
@@ -197,7 +197,8 @@ class ParserBase {
allow_harmony_function_sent_(false),
allow_harmony_async_await_(false),
allow_harmony_restrictive_generators_(false),
- allow_harmony_trailing_commas_(false) {}
+ allow_harmony_trailing_commas_(false),
+ allow_harmony_class_fields_(false) {}
#define ALLOW_ACCESSORS(name) \
bool allow_##name() const { return allow_##name##_; } \
@@ -213,6 +214,7 @@ class ParserBase {
ALLOW_ACCESSORS(harmony_async_await);
ALLOW_ACCESSORS(harmony_restrictive_generators);
ALLOW_ACCESSORS(harmony_trailing_commas);
+ ALLOW_ACCESSORS(harmony_class_fields);
#undef ALLOW_ACCESSORS
@@ -1092,6 +1094,7 @@ class ParserBase {
kValueProperty,
kShorthandProperty,
kMethodProperty,
+ kClassField,
kNotSet
};
@@ -1104,6 +1107,8 @@ class ParserBase {
ClassLiteralPropertyT ParseClassPropertyDefinition(
ClassLiteralChecker* checker, bool has_extends, bool* is_computed_name,
bool* has_seen_constructor, bool* ok);
+ FunctionLiteralT ParseClassFieldForInitializer(bool has_initializer,
+ bool* ok);
ObjectLiteralPropertyT ParseObjectPropertyDefinition(
ObjectLiteralChecker* checker, bool* is_computed_name, bool* ok);
ExpressionListT ParseArguments(Scanner::Location* first_spread_pos,
@@ -1335,6 +1340,7 @@ class ParserBase {
bool allow_harmony_async_await_;
bool allow_harmony_restrictive_generators_;
bool allow_harmony_trailing_commas_;
+ bool allow_harmony_class_fields_;
friend class DiscardableZoneScope;
};
@@ -1890,6 +1896,10 @@ bool ParserBase<Impl>::SetPropertyKindFromToken(Token::Value token,
case Token::LPAREN:
*kind = PropertyKind::kMethodProperty;
return true;
+ case Token::MUL:
+ case Token::SEMICOLON:
+ *kind = PropertyKind::kClassField;
+ return true;
default:
break;
}
@@ -2027,6 +2037,10 @@ ParserBase<Impl>::ParseClassPropertyDefinition(ClassLiteralChecker* checker,
kind = PropertyKind::kMethodProperty;
name = impl()->GetSymbol(); // TODO(bakkot) specialize on 'static'
name_expression = factory()->NewStringLiteral(name, position());
+ } else if (peek() == Token::ASSIGN || peek() == Token::SEMICOLON ||
+ peek() == Token::RBRACE) {
+ name = impl()->GetSymbol(); // TODO(bakkot) specialize on 'static'
+ name_expression = factory()->NewStringLiteral(name, position());
} else {
is_static = true;
name_expression = ParsePropertyName(
@@ -2040,11 +2054,29 @@ ParserBase<Impl>::ParseClassPropertyDefinition(ClassLiteralChecker* checker,
}
switch (kind) {
+ case PropertyKind::kClassField:
+ case PropertyKind::kNotSet: // This case is a name followed by a name or
+ // other property. Here we have to assume
+ // that's an uninitialized field followed by a
+ // linebreak followed by a property, with ASI
+ // adding the semicolon. If not, there will be
+ // a syntax error after parsing the first name
+ // as an uninitialized field.
case PropertyKind::kShorthandProperty:
case PropertyKind::kValueProperty:
- ReportUnexpectedToken(Next());
- *ok = false;
- return impl()->EmptyClassLiteralProperty();
+ if (allow_harmony_class_fields()) {
+ bool has_initializer = Check(Token::ASSIGN);
+ ExpressionT function_literal = ParseClassFieldForInitializer(
+ has_initializer, CHECK_OK_CUSTOM(EmptyClassLiteralProperty));
+ ExpectSemicolon(CHECK_OK_CUSTOM(EmptyClassLiteralProperty));
+ return factory()->NewClassLiteralProperty(
+ name_expression, function_literal, ClassLiteralProperty::FIELD,
+ is_static, *is_computed_name);
+ } else {
+ ReportUnexpectedToken(Next());
+ *ok = false;
+ return impl()->EmptyClassLiteralProperty();
+ }
case PropertyKind::kMethodProperty: {
DCHECK(!is_get && !is_set);
@@ -2111,17 +2143,49 @@ ParserBase<Impl>::ParseClassPropertyDefinition(ClassLiteralChecker* checker,
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>::FunctionLiteralT
+ParserBase<Impl>::ParseClassFieldForInitializer(bool has_initializer,
+ bool* ok) {
+ // Makes a concise method which evaluates and returns the initialized value
+ // (or undefined if absent).
+ FunctionKind kind = FunctionKind::kConciseMethod;
+ DeclarationScope* initializer_scope = NewFunctionScope(kind);
+ initializer_scope->set_start_position(scanner()->location().end_pos);
+ FunctionState initializer_state(&function_state_, &scope_state_,
+ initializer_scope, kind);
+ DCHECK(scope() == initializer_scope);
+ scope()->SetLanguageMode(STRICT);
+ ExpressionClassifier expression_classifier(this);
+ ExpressionT value;
+ if (has_initializer) {
+ value = this->ParseAssignmentExpression(
+ true, CHECK_OK_CUSTOM(EmptyFunctionLiteral));
+ impl()->RewriteNonPattern(CHECK_OK_CUSTOM(EmptyFunctionLiteral));
+ } else {
+ value = factory()->NewUndefinedLiteral(kNoSourcePosition);
+ }
+ initializer_scope->set_end_position(scanner()->location().end_pos);
+ typename Types::StatementList body = impl()->NewStatementList(1);
+ body->Add(factory()->NewReturnStatement(value, kNoSourcePosition), zone());
+ FunctionLiteralT function_literal = factory()->NewFunctionLiteral(
+ impl()->EmptyIdentifierString(), initializer_scope, body,
+ initializer_state.materialized_literal_count(),
+ initializer_state.expected_property_count(), 0,
+ FunctionLiteral::kNoDuplicateParameters,
+ FunctionLiteral::kAnonymousExpression,
+ FunctionLiteral::kShouldLazyCompile, kind,
+ initializer_scope->start_position());
+ function_literal->set_is_class_field_initializer(true);
+ return function_literal;
+}
+
+template <typename Impl>
typename ParserBase<Impl>::ObjectLiteralPropertyT
ParserBase<Impl>::ParseObjectPropertyDefinition(ObjectLiteralChecker* checker,
bool* is_computed_name,
@@ -2291,6 +2355,7 @@ ParserBase<Impl>::ParseObjectPropertyDefinition(ObjectLiteralChecker* checker,
*is_computed_name);
}
+ case PropertyKind::kClassField:
case PropertyKind::kNotSet:
ReportUnexpectedToken(Next());
*ok = false;
« no previous file with comments | « src/parsing/parser.cc ('k') | src/parsing/preparser.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698