diff --git a/Libraries/LibJS/Parser.cpp b/Libraries/LibJS/Parser.cpp index bed169e778b..b2e59213589 100644 --- a/Libraries/LibJS/Parser.cpp +++ b/Libraries/LibJS/Parser.cpp @@ -2025,6 +2025,7 @@ NonnullRefPtr Parser::parse_object_expression() function_kind = FunctionKind::Async; } } + if (match(TokenType::Asterisk)) { consume(); property_type = ObjectProperty::Type::KeyValue; @@ -2058,6 +2059,7 @@ NonnullRefPtr Parser::parse_object_expression() continue; } } + if (match(TokenType::Equals)) { // Not a valid object literal, but a valid assignment target consume(); @@ -2078,6 +2080,11 @@ NonnullRefPtr Parser::parse_object_expression() parse_options |= FunctionNodeParseOptions::IsAsyncFunction; auto function = parse_function_node(parse_options, function_start); properties.append(create_ast_node({ m_source_code, rule_start.position(), position() }, *property_key, function, property_type, true)); + } else if (function_kind == FunctionKind::Async) { + // If we previously parsed an `async` keyword, then a function must follow. + syntax_error("Expected function after async keyword"); + skip_to_next_property(); + continue; } else if (match(TokenType::Colon)) { if (!property_key) { expected("a property name"); diff --git a/Libraries/LibJS/Tests/object-basic.js b/Libraries/LibJS/Tests/object-basic.js index a81908a82f3..01e7b369557 100644 --- a/Libraries/LibJS/Tests/object-basic.js +++ b/Libraries/LibJS/Tests/object-basic.js @@ -205,6 +205,14 @@ describe("shorthanded properties with special names", () => { expect('"use strict"; var await = 8; ({ await, })').toEval(); expect('"use strict"; var async = 7; ({ async, })').toEval(); }); + + test("async functions as properties", () => { + expect("({ async foo });").not.toEval(); + expect("({ async foo, });").not.toEval(); + expect("({ async foo() });").not.toEval(); + expect("({ async foo: 0 });").not.toEval(); + expect("({ async foo = 0 });").not.toEval(); + }); }); describe("errors", () => {