Explorar o código

LibJS: Treat private identifier as divisible token

And also make sure private identifiers are correctly checked when
synthesizing a binding pattern.
davidot %!s(int64=3) %!d(string=hai) anos
pai
achega
e751dcea43

+ 1 - 0
Userland/Libraries/LibJS/Lexer.cpp

@@ -498,6 +498,7 @@ bool Lexer::slash_means_division() const
         || type == TokenType::NumericLiteral
         || type == TokenType::ParenClose
         || type == TokenType::PlusPlus
+        || type == TokenType::PrivateIdentifier
         || type == TokenType::RegexLiteral
         || type == TokenType::StringLiteral
         || type == TokenType::TemplateLiteralEnd

+ 1 - 0
Userland/Libraries/LibJS/Parser.cpp

@@ -1989,6 +1989,7 @@ RefPtr<BindingPattern> Parser::synthesize_binding_pattern(Expression const& expr
     parser.m_state.string_legacy_octal_escape_sequence_in_scope = m_state.string_legacy_octal_escape_sequence_in_scope;
     parser.m_state.in_class_field_initializer = m_state.in_class_field_initializer;
     parser.m_state.in_class_static_init_block = m_state.in_class_static_init_block;
+    parser.m_state.referenced_private_names = m_state.referenced_private_names;
 
     auto result = parser.parse_binding_pattern(AllowDuplicates::Yes, AllowMemberExpressions::Yes);
     if (parser.has_errors())

+ 13 - 0
Userland/Libraries/LibJS/Tests/classes/class-private-fields.js

@@ -83,6 +83,19 @@ test("static fields", () => {
     expect("A.#simple").not.toEval();
 });
 
+test("slash after private identifier is treated as division", () => {
+    class A {
+        static #field = 4;
+        static #divided = this.#field / 2;
+
+        static getDivided() {
+            return this.#divided;
+        }
+    }
+
+    expect(A.getDivided()).toBe(2);
+});
+
 test("cannot have static and non static field with the same description", () => {
     expect("class A { static #simple; #simple; }").not.toEval();
 });

+ 1 - 0
Userland/Libraries/LibJS/Tests/syntax/slash-after-block.js

@@ -17,6 +17,7 @@ test("slash token resolution in lexer", () => {
     expect("+a-- / 1").toEval();
     expect("a.in / b").toEval();
     expect("a.instanceof / b").toEval();
+    expect("class A { #name; d = a.#name / b; }").toEval();
 
     // FIXME: Even more 'reserved' words are valid however the cases below do still need to pass.
     //expect("a.void / b").toEval();