summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordavidot <davidot@serenityos.org>2022-08-20 00:24:30 +0200
committerLinus Groh <mail@linusgroh.de>2022-08-24 23:27:17 +0100
commitfce2b33758586d9d928e14416815b8feba55c953 (patch)
tree62be01ef34384078bf3f6693f16c33f017670685
parente663504df13029bf1e6656bcb3ae5074d978694a (diff)
downloadserenity-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.
-rw-r--r--Userland/Libraries/LibJS/Parser.cpp8
-rw-r--r--Userland/Libraries/LibJS/Tests/object-expression-numeric-property.js23
-rw-r--r--Userland/Libraries/LibJS/Tests/syntax/destructuring-assignment.js7
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);
+ });
});