diff --git a/Userland/Libraries/LibJS/Parser.cpp b/Userland/Libraries/LibJS/Parser.cpp index f2c91390eaa..6a43b178244 100644 --- a/Userland/Libraries/LibJS/Parser.cpp +++ b/Userland/Libraries/LibJS/Parser.cpp @@ -945,8 +945,12 @@ NonnullRefPtr Parser::parse_class_expression(bool expect_class_ } if (match(TokenType::Async)) { - consume(); - is_async = true; + auto lookahead_token = next_token(); + if (lookahead_token.type() != TokenType::Semicolon && lookahead_token.type() != TokenType::CurlyClose + && !lookahead_token.trivia_contains_line_terminator()) { + consume(); + is_async = true; + } } if (match(TokenType::Asterisk)) { @@ -1042,7 +1046,7 @@ NonnullRefPtr Parser::parse_class_expression(bool expect_class_ // It is a Syntax Error if PropName of MethodDefinition is "prototype". if (is_static && name == "prototype"sv) syntax_error("Classes may not have a static property named 'prototype'"); - } else if ((match(TokenType::ParenOpen) || match(TokenType::Equals)) && (is_static || is_async || method_kind != ClassMethod::Kind::Method)) { + } else if ((match(TokenType::ParenOpen) || match(TokenType::Equals) || match(TokenType::Semicolon) || match(TokenType::CurlyClose)) && (is_static || is_async || method_kind != ClassMethod::Kind::Method)) { switch (method_kind) { case ClassMethod::Kind::Method: if (is_async) { diff --git a/Userland/Libraries/LibJS/Tests/classes/class-public-fields.js b/Userland/Libraries/LibJS/Tests/classes/class-public-fields.js index 86c1e86de78..4bc405e362d 100644 --- a/Userland/Libraries/LibJS/Tests/classes/class-public-fields.js +++ b/Userland/Libraries/LibJS/Tests/classes/class-public-fields.js @@ -85,3 +85,45 @@ test("with super class", () => { b.arrow_ref_super(); expect(b.super_field).toBe(4); }); + +describe("class fields with a 'special' name", () => { + test("static", () => { + class A { + static; + } + expect("static" in new A()).toBeTrue(); + + class B { + static; + } + expect("static" in new B()).toBeTrue(); + + class C { + static a; + } + expect("static" in new C()).toBeFalse(); + expect("a" in new C()).toBeFalse(); + + expect("a" in C).toBeTrue(); + expect("static" in C).toBeFalse(); + }); + + test("async", () => { + class A { + async; + } + expect("async" in new A()).toBeTrue(); + + class B { + async; + } + expect("async" in new B()).toBeTrue(); + + class C { + async; + a; + } + expect("async" in new C()).toBeTrue(); + expect("a" in new C()).toBeTrue(); + }); +});