diff options
author | Ali Mohammad Pur <ali.mpfard@gmail.com> | 2021-07-02 14:37:00 +0430 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-07-02 14:59:03 +0200 |
commit | 46ef333e9cd86d8976bdd544bafd9f120355980d (patch) | |
tree | 344aad07a538bd4644ffefcecd454004f6f7a604 | |
parent | 609a0aa75d94b510e48fe595096e5c0e8c9b3b14 (diff) | |
download | serenity-46ef333e9cd86d8976bdd544bafd9f120355980d.zip |
LibJS: Parse generator functions in class expressions too
-rw-r--r-- | Userland/Libraries/LibJS/Parser.cpp | 22 | ||||
-rw-r--r-- | Userland/Libraries/LibJS/Tests/syntax/generators.js | 10 |
2 files changed, 29 insertions, 3 deletions
diff --git a/Userland/Libraries/LibJS/Parser.cpp b/Userland/Libraries/LibJS/Parser.cpp index e1f9671c28..2c03379728 100644 --- a/Userland/Libraries/LibJS/Parser.cpp +++ b/Userland/Libraries/LibJS/Parser.cpp @@ -512,6 +512,7 @@ NonnullRefPtr<ClassExpression> Parser::parse_class_expression(bool expect_class_ RefPtr<Expression> property_key; bool is_static = false; bool is_constructor = false; + bool is_generator = false; auto method_kind = ClassMethod::Kind::Method; if (match(TokenType::Semicolon)) { @@ -519,11 +520,22 @@ NonnullRefPtr<ClassExpression> Parser::parse_class_expression(bool expect_class_ continue; } + if (match(TokenType::Asterisk)) { + consume(); + is_generator = true; + } + if (match_property_key()) { StringView name; - if (match(TokenType::Identifier) && m_state.current_token.value() == "static") { - consume(); - is_static = true; + if (!is_generator && m_state.current_token.value() == "static"sv) { + if (match(TokenType::Identifier)) { + consume(); + is_static = true; + if (match(TokenType::Asterisk)) { + consume(); + is_generator = true; + } + } } 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"); if (!constructor.is_null()) 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; } @@ -578,6 +592,8 @@ NonnullRefPtr<ClassExpression> Parser::parse_class_expression(bool expect_class_ parse_options |= FunctionNodeParseOptions::IsGetterFunction; if (method_kind == ClassMethod::Kind::Setter) parse_options |= FunctionNodeParseOptions::IsSetterFunction; + if (is_generator) + parse_options |= FunctionNodeParseOptions::IsGeneratorFunction; auto function = parse_function_node<FunctionExpression>(parse_options); if (is_constructor) { constructor = move(function); diff --git a/Userland/Libraries/LibJS/Tests/syntax/generators.js b/Userland/Libraries/LibJS/Tests/syntax/generators.js index 76c91b6dcb..ba521f9fed 100644 --- a/Userland/Libraries/LibJS/Tests/syntax/generators.js +++ b/Userland/Libraries/LibJS/Tests/syntax/generators.js @@ -39,3 +39,13 @@ describe("parsing object literal generator functions", () => { 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(); + }); +}); |