1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 21:17:44 +00:00

LibJS: Allow methods in classes named 'async'

Also add tests for all static, setter and getter cases.
This commit is contained in:
davidot 2022-02-17 18:03:41 +01:00 committed by Linus Groh
parent 65bebb5241
commit 2c6183da1e
8 changed files with 85 additions and 1 deletions

View file

@ -1086,7 +1086,9 @@ NonnullRefPtr<ClassExpression> Parser::parse_class_expression(bool expect_class_
if (match(TokenType::Async)) {
auto lookahead_token = next_token();
if (lookahead_token.type() != TokenType::Semicolon && lookahead_token.type() != TokenType::CurlyClose
// If async is followed by a Semicolon or CurlyClose it is a field (CurlyClose indicates end of class)
// Otherwise if it is followed by a ParenOpen it is a function named async
if (lookahead_token.type() != TokenType::Semicolon && lookahead_token.type() != TokenType::CurlyClose && lookahead_token.type() != TokenType::ParenOpen
&& !lookahead_token.trivia_contains_line_terminator()) {
consume();
is_async = true;

View file

@ -65,3 +65,10 @@ test("implicit constructor", () => {
expect(new A()).toBeInstanceOf(A);
});
test("can call constructor without parentheses", () => {
class A {}
// prettier-ignore
expect(new A).toBeInstanceOf(A);
});

View file

@ -73,3 +73,15 @@ test("inherited getter overriding", () => {
expect(new Child().x).toBe(10);
});
test("static getter named 'async'", () => {
class A {
get async() {
return "getter named async";
}
}
const a = new A();
expect("async" in a).toBeTrue();
expect(a.async).toBe("getter named async");
});

View file

@ -49,3 +49,15 @@ test("extended name syntax", () => {
expect(a[12]()).toBe(2);
expect(a.hello()).toBe(3);
});
test("method named 'async'", () => {
class A {
async() {
return "function named async";
}
}
const a = new A();
expect("async" in a).toBeTrue();
expect(a.async()).toBe("function named async");
});

View file

@ -106,3 +106,18 @@ test("inherited static setter overriding", () => {
c.x = 10;
expect(c.x).toBe(30);
});
test("static setter named 'async'", () => {
let called = false;
class A {
set async(value) {
called = true;
expect(value).toBe("value set on setter named async");
}
}
const a = new A();
expect("async" in a).toBeTrue();
a.async = "value set on setter named async";
expect(called).toBeTrue();
});

View file

@ -85,3 +85,14 @@ describe("errors", () => {
}`).not.toEval();
});
});
test("static getter named 'async'", () => {
class A {
static get async() {
return "static getter named async";
}
}
expect("async" in A).toBeTrue();
expect(A.async).toBe("static getter named async");
});

View file

@ -110,3 +110,17 @@ describe("errors", () => {
}`).not.toEval();
});
});
test("static setter named 'async'", () => {
let called = false;
class A {
static set async(value) {
called = true;
expect(value).toBe("value set on static setter named async");
}
}
expect("async" in A).toBeTrue();
A.async = "value set on static setter named async";
expect(called).toBeTrue();
});

View file

@ -70,3 +70,14 @@ test("static method overriding", () => {
expect(Parent.method()).toBe(3);
expect(Child.method()).toBe(10);
});
test("static function named 'async'", () => {
class A {
static async() {
return "static function named async";
}
}
expect("async" in A).toBeTrue();
expect(A.async()).toBe("static function named async");
});