diff --git a/Libraries/LibJS/Parser.cpp b/Libraries/LibJS/Parser.cpp index df5330af58..c06028f5a9 100644 --- a/Libraries/LibJS/Parser.cpp +++ b/Libraries/LibJS/Parser.cpp @@ -893,8 +893,7 @@ NonnullRefPtr Parser::parse_new_expression() { consume(TokenType::New); - // FIXME: Support full expressions as the callee as well. - auto callee = create_ast_node(consume(TokenType::Identifier).value()); + auto callee = parse_expression(g_operator_precedence.get(TokenType::New).value(), Associativity::Right, { TokenType::ParenOpen }); Vector arguments; diff --git a/Libraries/LibJS/Tests/new-expression.js b/Libraries/LibJS/Tests/new-expression.js new file mode 100644 index 0000000000..7b1f6917fb --- /dev/null +++ b/Libraries/LibJS/Tests/new-expression.js @@ -0,0 +1,51 @@ +load("test-common.js"); + +try { + function Foo() { this.x = 1; } + + let foo = new Foo(); + assert(foo.x === 1); + + foo = new Foo + assert(foo.x === 1); + + foo = new + Foo + () + assert(foo.x === 1); + + foo = new Foo + 2 + assert(foo === "[object Object]2"); + + let a = { + b: function() { + this.x = 2; + }, + }; + + foo = new a.b(); + assert(foo.x === 2); + + foo = new a.b; + assert(foo.x === 2); + + foo = new + a.b(); + assert(foo.x === 2); + + function funcGetter() { + return function(a, b) { + this.x = a + b; + }; + }; + + foo = new funcGetter()(1, 5); + assert(foo === undefined); + + foo = new (funcGetter())(1, 5); + assert(foo.x === 6); + + console.log("PASS"); +} catch (e) { + console.log("FAIL: " + e); +}