diff options
author | davidot <davidot@serenityos.org> | 2022-08-20 00:24:30 +0200 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2022-08-24 23:27:17 +0100 |
commit | fce2b33758586d9d928e14416815b8feba55c953 (patch) | |
tree | 62be01ef34384078bf3f6693f16c33f017670685 | |
parent | e663504df13029bf1e6656bcb3ae5074d978694a (diff) | |
download | serenity-fce2b33758586d9d928e14416815b8feba55c953.zip |
LibJS: Allow BigInts as destructuring property names
These are simply treated as their numerical value which means that above
2^32 - 1 they are strings.
3 files changed, 37 insertions, 1 deletions
diff --git a/Userland/Libraries/LibJS/Parser.cpp b/Userland/Libraries/LibJS/Parser.cpp index a30d5e5cd1..a9cd247d63 100644 --- a/Userland/Libraries/LibJS/Parser.cpp +++ b/Userland/Libraries/LibJS/Parser.cpp @@ -2762,7 +2762,7 @@ RefPtr<BindingPattern> Parser::parse_binding_pattern(Parser::AllowDuplicates all name = static_ptr_cast<Identifier>(expression); else syntax_error("Invalid destructuring assignment target", expression_position); - } else if (match_identifier_name() || match(TokenType::StringLiteral) || match(TokenType::NumericLiteral)) { + } else if (match_identifier_name() || match(TokenType::StringLiteral) || match(TokenType::NumericLiteral) || match(TokenType::BigIntLiteral)) { if (match(TokenType::StringLiteral) || match(TokenType::NumericLiteral)) needs_alias = true; @@ -2773,6 +2773,12 @@ RefPtr<BindingPattern> Parser::parse_binding_pattern(Parser::AllowDuplicates all name = create_ast_node<Identifier>( { m_state.current_token.filename(), rule_start.position(), position() }, string_literal->value()); + } else if (match(TokenType::BigIntLiteral)) { + auto string_value = consume().flystring_value(); + VERIFY(string_value.ends_with("n"sv)); + name = create_ast_node<Identifier>( + { m_state.current_token.filename(), rule_start.position(), position() }, + FlyString(string_value.view().substring_view(0, string_value.length() - 1))); } else { name = create_ast_node<Identifier>( { m_state.current_token.filename(), rule_start.position(), position() }, diff --git a/Userland/Libraries/LibJS/Tests/object-expression-numeric-property.js b/Userland/Libraries/LibJS/Tests/object-expression-numeric-property.js index 575e658390..9d4653fa43 100644 --- a/Userland/Libraries/LibJS/Tests/object-expression-numeric-property.js +++ b/Userland/Libraries/LibJS/Tests/object-expression-numeric-property.js @@ -28,3 +28,26 @@ test("numeric properties", () => { "4294967296", // >= 2^32 - 1 ]); }); + +test("big int properties", () => { + const o = { + [-1n]: "foo", + 0n: "foo", + 1n: "foo", + [12345678901n]: "foo", + [4294967294n]: "foo", + [4294967295n]: "foo", + }; + // Numeric properties come first in Object.getOwnPropertyNames()'s output, + // which means we can test what each is treated as internally. + expect(Object.getOwnPropertyNames(o)).toEqual([ + // Numeric properties + "0", + "1", + "4294967294", + // Non-numeric properties + "-1", + "12345678901", // >= 2^32 - 1 + "4294967295", // >= 2^32 - 1 + ]); +}); diff --git a/Userland/Libraries/LibJS/Tests/syntax/destructuring-assignment.js b/Userland/Libraries/LibJS/Tests/syntax/destructuring-assignment.js index 9a7682ddbc..5654568a83 100644 --- a/Userland/Libraries/LibJS/Tests/syntax/destructuring-assignment.js +++ b/Userland/Libraries/LibJS/Tests/syntax/destructuring-assignment.js @@ -223,4 +223,11 @@ describe("evaluating", () => { expect(x).toBe("foo"); expect(a).toBe(o.a); }); + + test("can use big int values as number-like properties", () => { + let o = { "99999999999999999": 1 }; + let { 123n: a = "foo", 99999999999999999n: b = "bar" } = o; + expect(a).toBe("foo"); + expect(b).toBe(1); + }); }); |