1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 14:27:35 +00:00

LibJS: Parse generator functions in class expressions too

This commit is contained in:
Ali Mohammad Pur 2021-07-02 14:37:00 +04:30 committed by Andreas Kling
parent 609a0aa75d
commit 46ef333e9c
2 changed files with 29 additions and 3 deletions

View file

@ -512,6 +512,7 @@ NonnullRefPtr<ClassExpression> Parser::parse_class_expression(bool expect_class_
RefPtr<Expression> property_key; RefPtr<Expression> property_key;
bool is_static = false; bool is_static = false;
bool is_constructor = false; bool is_constructor = false;
bool is_generator = false;
auto method_kind = ClassMethod::Kind::Method; auto method_kind = ClassMethod::Kind::Method;
if (match(TokenType::Semicolon)) { if (match(TokenType::Semicolon)) {
@ -519,11 +520,22 @@ NonnullRefPtr<ClassExpression> Parser::parse_class_expression(bool expect_class_
continue; continue;
} }
if (match(TokenType::Asterisk)) {
consume();
is_generator = true;
}
if (match_property_key()) { if (match_property_key()) {
StringView name; StringView name;
if (match(TokenType::Identifier) && m_state.current_token.value() == "static") { if (!is_generator && m_state.current_token.value() == "static"sv) {
consume(); if (match(TokenType::Identifier)) {
is_static = true; consume();
is_static = true;
if (match(TokenType::Asterisk)) {
consume();
is_generator = true;
}
}
} }
if (match(TokenType::Identifier)) { if (match(TokenType::Identifier)) {
@ -565,6 +577,8 @@ NonnullRefPtr<ClassExpression> Parser::parse_class_expression(bool expect_class_
syntax_error("Class constructor may not be an accessor"); syntax_error("Class constructor may not be an accessor");
if (!constructor.is_null()) if (!constructor.is_null())
syntax_error("Classes may not have more than one constructor"); syntax_error("Classes may not have more than one constructor");
if (is_generator)
syntax_error("Class constructor may not be a generator");
is_constructor = true; is_constructor = true;
} }
@ -578,6 +592,8 @@ NonnullRefPtr<ClassExpression> Parser::parse_class_expression(bool expect_class_
parse_options |= FunctionNodeParseOptions::IsGetterFunction; parse_options |= FunctionNodeParseOptions::IsGetterFunction;
if (method_kind == ClassMethod::Kind::Setter) if (method_kind == ClassMethod::Kind::Setter)
parse_options |= FunctionNodeParseOptions::IsSetterFunction; parse_options |= FunctionNodeParseOptions::IsSetterFunction;
if (is_generator)
parse_options |= FunctionNodeParseOptions::IsGeneratorFunction;
auto function = parse_function_node<FunctionExpression>(parse_options); auto function = parse_function_node<FunctionExpression>(parse_options);
if (is_constructor) { if (is_constructor) {
constructor = move(function); constructor = move(function);

View file

@ -39,3 +39,13 @@ describe("parsing object literal generator functions", () => {
foo() { yield (yield); } }`).toEval(); foo() { yield (yield); } }`).toEval();
}); });
}); });
describe("parsing classes with generator methods", () => {
test("simple", () => {
expect(`class Foo { *foo() {} }`).toEval();
expect(`class Foo { static *foo() {} }`).toEval();
expect(`class Foo { *foo() { yield; } }`).toEval();
expect(`class Foo { *foo() { yield 42; } }`).toEval();
expect(`class Foo { *constructor() { yield 42; } }`).not.toEval();
});
});