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

LibJS: Allow defining class fields with "keyword" names

This commit is contained in:
davidot 2021-11-26 23:30:29 +01:00 committed by Linus Groh
parent cbbfcd35e7
commit e491fc0e81
2 changed files with 49 additions and 3 deletions

View file

@ -945,8 +945,12 @@ NonnullRefPtr<ClassExpression> Parser::parse_class_expression(bool expect_class_
} }
if (match(TokenType::Async)) { if (match(TokenType::Async)) {
consume(); auto lookahead_token = next_token();
is_async = true; 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)) { if (match(TokenType::Asterisk)) {
@ -1042,7 +1046,7 @@ NonnullRefPtr<ClassExpression> Parser::parse_class_expression(bool expect_class_
// It is a Syntax Error if PropName of MethodDefinition is "prototype". // It is a Syntax Error if PropName of MethodDefinition is "prototype".
if (is_static && name == "prototype"sv) if (is_static && name == "prototype"sv)
syntax_error("Classes may not have a static property named 'prototype'"); 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) { switch (method_kind) {
case ClassMethod::Kind::Method: case ClassMethod::Kind::Method:
if (is_async) { if (is_async) {

View file

@ -85,3 +85,45 @@ test("with super class", () => {
b.arrow_ref_super(); b.arrow_ref_super();
expect(b.super_field).toBe(4); 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();
});
});