summaryrefslogtreecommitdiff
path: root/Userland/Libraries
diff options
context:
space:
mode:
authordavidot <davidot@serenityos.org>2021-11-27 00:16:01 +0100
committerLinus Groh <mail@linusgroh.de>2021-11-30 17:05:32 +0000
commitc2ebaa9d87fc896623c09fcf299284b1ae5a8ba0 (patch)
tree71d8bd1b03645d5d909091a94b9845f004b7952f /Userland/Libraries
parentb7c7d54167d8c743cf91975fd3f073b65290b469 (diff)
downloadserenity-c2ebaa9d87fc896623c09fcf299284b1ae5a8ba0.zip
LibJS: Replace the verify in private identifier with a syntax error
Since sometimes expressions are parsed without checking we can hit this expression without it being followed by an 'in'.
Diffstat (limited to 'Userland/Libraries')
-rw-r--r--Userland/Libraries/LibJS/Parser.cpp5
-rw-r--r--Userland/Libraries/LibJS/Tests/classes/class-private-fields.js12
2 files changed, 15 insertions, 2 deletions
diff --git a/Userland/Libraries/LibJS/Parser.cpp b/Userland/Libraries/LibJS/Parser.cpp
index 4ea3b10a9a..184571ba31 100644
--- a/Userland/Libraries/LibJS/Parser.cpp
+++ b/Userland/Libraries/LibJS/Parser.cpp
@@ -1439,7 +1439,8 @@ Parser::PrimaryExpressionParseResult Parser::parse_primary_expression()
goto read_as_identifier;
return { parse_await_expression() };
case TokenType::PrivateIdentifier:
- VERIFY(next_token().type() == TokenType::In);
+ if (next_token().type() != TokenType::In)
+ syntax_error("Cannot have a private identifier in expression if not followed by 'in'");
if (!is_private_identifier_valid())
syntax_error(String::formatted("Reference to undeclared private field or method '{}'", m_state.current_token.value()));
return { create_ast_node<PrivateIdentifier>({ m_state.current_token.filename(), rule_start.position(), position() }, consume().value()) };
@@ -3483,7 +3484,7 @@ bool Parser::match_expression() const
|| type == TokenType::TemplateLiteralStart
|| type == TokenType::NullLiteral
|| match_identifier()
- || (type == TokenType::PrivateIdentifier && next_token().type() == TokenType::In)
+ || type == TokenType::PrivateIdentifier
|| type == TokenType::Await
|| type == TokenType::New
|| type == TokenType::Class
diff --git a/Userland/Libraries/LibJS/Tests/classes/class-private-fields.js b/Userland/Libraries/LibJS/Tests/classes/class-private-fields.js
index 286019a538..2eebaa6245 100644
--- a/Userland/Libraries/LibJS/Tests/classes/class-private-fields.js
+++ b/Userland/Libraries/LibJS/Tests/classes/class-private-fields.js
@@ -96,6 +96,18 @@ test("slash after private identifier is treated as division", () => {
expect(A.getDivided()).toBe(2);
});
+test("private identifier not followed by 'in' throws", () => {
+ expect(`class A { #field = 2; method() { return #field instanceof 1; }}`).not.toEval();
+ expect(`class A { #field = 2; method() { return #field < 1; }}`).not.toEval();
+ expect(`class A { #field = 2; method() { return #field + 1; }}`).not.toEval();
+ expect(`class A { #field = 2; method() { return #field ** 1; }}`).not.toEval();
+ expect(`class A { #field = 2; method() { return !#field; } }`).not.toEval();
+ expect(`class A { #field = 2; method() { return ~#field; } }`).not.toEval();
+ expect(`class A { #field = 2; method() { return ++#field; } }`).not.toEval();
+
+ expect(`class A { #field = 2; method() { return #field in 1; }}`).toEval();
+});
+
test("cannot have static and non static field with the same description", () => {
expect("class A { static #simple; #simple; }").not.toEval();
});