1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 07:08:10 +00:00

LibJS: Make RefPtr and NonnullRefPtr usage const-correct

This mainly affected the AST, which is now const throughout.
This commit is contained in:
Andreas Kling 2023-02-19 22:07:52 +01:00
parent b2b942b4ec
commit bd5d8e9d35
15 changed files with 505 additions and 494 deletions

View file

@ -87,7 +87,7 @@ static Result<void, TestError> run_program(InterpreterT& interpreter, ScriptOrMo
}); });
} else { } else {
auto program_node = program.visit( auto program_node = program.visit(
[](auto& visitor) -> NonnullRefPtr<JS::Program> { [](auto& visitor) -> NonnullRefPtr<JS::Program const> {
return visitor->parse_node(); return visitor->parse_node();
}); });

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2020-2021, Andreas Kling <kling@serenityos.org> * Copyright (c) 2020-2023, Andreas Kling <kling@serenityos.org>
* Copyright (c) 2020-2023, Linus Groh <linusg@serenityos.org> * Copyright (c) 2020-2023, Linus Groh <linusg@serenityos.org>
* Copyright (c) 2021-2022, David Tuin <davidot@serenityos.org> * Copyright (c) 2021-2022, David Tuin <davidot@serenityos.org>
* *
@ -914,21 +914,21 @@ Completion ForStatement::for_body_evaluation(JS::Interpreter& interpreter, Vecto
} }
struct ForInOfHeadState { struct ForInOfHeadState {
explicit ForInOfHeadState(Variant<NonnullRefPtr<ASTNode>, NonnullRefPtr<BindingPattern>> lhs) explicit ForInOfHeadState(Variant<NonnullRefPtr<ASTNode const>, NonnullRefPtr<BindingPattern const>> lhs)
{ {
lhs.visit( lhs.visit(
[&](NonnullRefPtr<ASTNode>& ast_node) { [&](NonnullRefPtr<ASTNode const>& ast_node) {
expression_lhs = ast_node.ptr(); expression_lhs = ast_node.ptr();
}, },
[&](NonnullRefPtr<BindingPattern>& pattern) { [&](NonnullRefPtr<BindingPattern const>& pattern) {
pattern_lhs = pattern.ptr(); pattern_lhs = pattern.ptr();
destructuring = true; destructuring = true;
lhs_kind = Assignment; lhs_kind = Assignment;
}); });
} }
ASTNode* expression_lhs = nullptr; ASTNode const* expression_lhs = nullptr;
BindingPattern* pattern_lhs = nullptr; BindingPattern const* pattern_lhs = nullptr;
enum LhsKind { enum LhsKind {
Assignment, Assignment,
VarBinding, VarBinding,
@ -956,12 +956,12 @@ struct ForInOfHeadState {
VERIFY(expression_lhs); VERIFY(expression_lhs);
if (is<VariableDeclaration>(*expression_lhs)) { if (is<VariableDeclaration>(*expression_lhs)) {
auto& declaration = static_cast<VariableDeclaration const&>(*expression_lhs); auto& declaration = static_cast<VariableDeclaration const&>(*expression_lhs);
VERIFY(declaration.declarations().first().target().has<NonnullRefPtr<Identifier>>()); VERIFY(declaration.declarations().first().target().has<NonnullRefPtr<Identifier const>>());
lhs_reference = TRY(declaration.declarations().first().target().get<NonnullRefPtr<Identifier>>()->to_reference(interpreter)); lhs_reference = TRY(declaration.declarations().first().target().get<NonnullRefPtr<Identifier const>>()->to_reference(interpreter));
} else if (is<UsingDeclaration>(*expression_lhs)) { } else if (is<UsingDeclaration>(*expression_lhs)) {
auto& declaration = static_cast<UsingDeclaration const&>(*expression_lhs); auto& declaration = static_cast<UsingDeclaration const&>(*expression_lhs);
VERIFY(declaration.declarations().first().target().has<NonnullRefPtr<Identifier>>()); VERIFY(declaration.declarations().first().target().has<NonnullRefPtr<Identifier const>>());
lhs_reference = TRY(declaration.declarations().first().target().get<NonnullRefPtr<Identifier>>()->to_reference(interpreter)); lhs_reference = TRY(declaration.declarations().first().target().get<NonnullRefPtr<Identifier const>>()->to_reference(interpreter));
} else { } else {
VERIFY(is<Identifier>(*expression_lhs) || is<MemberExpression>(*expression_lhs) || is<CallExpression>(*expression_lhs)); VERIFY(is<Identifier>(*expression_lhs) || is<MemberExpression>(*expression_lhs) || is<CallExpression>(*expression_lhs));
auto& expression = static_cast<Expression const&>(*expression_lhs); auto& expression = static_cast<Expression const&>(*expression_lhs);
@ -1028,7 +1028,7 @@ struct ForInOfHeadState {
} }
VERIFY(expression_lhs && is<VariableDeclaration>(*expression_lhs)); VERIFY(expression_lhs && is<VariableDeclaration>(*expression_lhs));
auto& for_declaration = static_cast<VariableDeclaration const&>(*expression_lhs); auto& for_declaration = static_cast<VariableDeclaration const&>(*expression_lhs);
auto& binding_pattern = for_declaration.declarations().first().target().get<NonnullRefPtr<BindingPattern>>(); auto& binding_pattern = for_declaration.declarations().first().target().get<NonnullRefPtr<BindingPattern const>>();
VERIFY(lhs_kind == VarBinding || iteration_environment); VERIFY(lhs_kind == VarBinding || iteration_environment);
// At this point iteration_environment is undefined if lhs_kind == VarBinding which means this does both // At this point iteration_environment is undefined if lhs_kind == VarBinding which means this does both
@ -1041,12 +1041,12 @@ struct ForInOfHeadState {
// 14.7.5.6 ForIn/OfHeadEvaluation ( uninitializedBoundNames, expr, iterationKind ), https://tc39.es/ecma262/#sec-runtime-semantics-forinofheadevaluation // 14.7.5.6 ForIn/OfHeadEvaluation ( uninitializedBoundNames, expr, iterationKind ), https://tc39.es/ecma262/#sec-runtime-semantics-forinofheadevaluation
// This method combines ForInOfLoopEvaluation and ForIn/OfHeadEvaluation for similar reason as ForIn/OfBodyEvaluation, to prevent code duplication. // This method combines ForInOfLoopEvaluation and ForIn/OfHeadEvaluation for similar reason as ForIn/OfBodyEvaluation, to prevent code duplication.
// For the same reason we also skip step 6 and 7 of ForIn/OfHeadEvaluation as this is done by the appropriate for loop type. // For the same reason we also skip step 6 and 7 of ForIn/OfHeadEvaluation as this is done by the appropriate for loop type.
static ThrowCompletionOr<ForInOfHeadState> for_in_of_head_execute(Interpreter& interpreter, Variant<NonnullRefPtr<ASTNode>, NonnullRefPtr<BindingPattern>> lhs, Expression const& rhs) static ThrowCompletionOr<ForInOfHeadState> for_in_of_head_execute(Interpreter& interpreter, Variant<NonnullRefPtr<ASTNode const>, NonnullRefPtr<BindingPattern const>> lhs, Expression const& rhs)
{ {
auto& vm = interpreter.vm(); auto& vm = interpreter.vm();
ForInOfHeadState state(lhs); ForInOfHeadState state(lhs);
if (auto* ast_ptr = lhs.get_pointer<NonnullRefPtr<ASTNode>>(); ast_ptr && is<Declaration>(ast_ptr->ptr())) { if (auto* ast_ptr = lhs.get_pointer<NonnullRefPtr<ASTNode const>>(); ast_ptr && is<Declaration>(ast_ptr->ptr())) {
// Runtime Semantics: ForInOfLoopEvaluation, for any of: // Runtime Semantics: ForInOfLoopEvaluation, for any of:
// ForInOfStatement : for ( var ForBinding in Expression ) Statement // ForInOfStatement : for ( var ForBinding in Expression ) Statement
// ForInOfStatement : for ( ForDeclaration in Expression ) Statement // ForInOfStatement : for ( ForDeclaration in Expression ) Statement
@ -1059,14 +1059,14 @@ static ThrowCompletionOr<ForInOfHeadState> for_in_of_head_execute(Interpreter& i
if (is<VariableDeclaration>(ast_ptr->ptr())) { if (is<VariableDeclaration>(ast_ptr->ptr())) {
auto& variable_declaration = static_cast<VariableDeclaration const&>(*(*ast_ptr)); auto& variable_declaration = static_cast<VariableDeclaration const&>(*(*ast_ptr));
VERIFY(variable_declaration.declarations().size() == 1); VERIFY(variable_declaration.declarations().size() == 1);
state.destructuring = variable_declaration.declarations().first().target().has<NonnullRefPtr<BindingPattern>>(); state.destructuring = variable_declaration.declarations().first().target().has<NonnullRefPtr<BindingPattern const>>();
if (variable_declaration.declaration_kind() == DeclarationKind::Var) { if (variable_declaration.declaration_kind() == DeclarationKind::Var) {
state.lhs_kind = ForInOfHeadState::VarBinding; state.lhs_kind = ForInOfHeadState::VarBinding;
auto& variable = variable_declaration.declarations().first(); auto& variable = variable_declaration.declarations().first();
// B.3.5 Initializers in ForIn Statement Heads, https://tc39.es/ecma262/#sec-initializers-in-forin-statement-heads // B.3.5 Initializers in ForIn Statement Heads, https://tc39.es/ecma262/#sec-initializers-in-forin-statement-heads
if (variable.init()) { if (variable.init()) {
VERIFY(variable.target().has<NonnullRefPtr<Identifier>>()); VERIFY(variable.target().has<NonnullRefPtr<Identifier const>>());
auto& binding_id = variable.target().get<NonnullRefPtr<Identifier>>()->string(); auto& binding_id = variable.target().get<NonnullRefPtr<Identifier const>>()->string();
auto reference = TRY(interpreter.vm().resolve_binding(binding_id)); auto reference = TRY(interpreter.vm().resolve_binding(binding_id));
auto result = TRY(interpreter.vm().named_evaluation_if_anonymous_function(*variable.init(), binding_id)); auto result = TRY(interpreter.vm().named_evaluation_if_anonymous_function(*variable.init(), binding_id));
TRY(reference.put_value(vm, result)); TRY(reference.put_value(vm, result));
@ -1742,7 +1742,7 @@ ThrowCompletionOr<ClassElement::ClassValue> ClassMethod::class_element_evaluatio
// 10.2.1.3 Runtime Semantics: EvaluateBody, https://tc39.es/ecma262/#sec-runtime-semantics-evaluatebody // 10.2.1.3 Runtime Semantics: EvaluateBody, https://tc39.es/ecma262/#sec-runtime-semantics-evaluatebody
class ClassFieldInitializerStatement : public Statement { class ClassFieldInitializerStatement : public Statement {
public: public:
ClassFieldInitializerStatement(SourceRange source_range, NonnullRefPtr<Expression> expression, DeprecatedFlyString field_name) ClassFieldInitializerStatement(SourceRange source_range, NonnullRefPtr<Expression const> expression, DeprecatedFlyString field_name)
: Statement(source_range) : Statement(source_range)
, m_expression(move(expression)) , m_expression(move(expression))
, m_class_field_identifier_name(move(field_name)) , m_class_field_identifier_name(move(field_name))
@ -1775,7 +1775,7 @@ public:
} }
private: private:
NonnullRefPtr<Expression> m_expression; NonnullRefPtr<Expression const> m_expression;
DeprecatedFlyString m_class_field_identifier_name; // [[ClassFieldIdentifierName]] DeprecatedFlyString m_class_field_identifier_name; // [[ClassFieldIdentifierName]]
}; };
@ -2414,7 +2414,7 @@ bool BindingPattern::contains_expression() const
for (auto& entry : entries) { for (auto& entry : entries) {
if (entry.initializer) if (entry.initializer)
return true; return true;
if (auto binding_ptr = entry.alias.get_pointer<NonnullRefPtr<BindingPattern>>(); binding_ptr && (*binding_ptr)->contains_expression()) if (auto binding_ptr = entry.alias.get_pointer<NonnullRefPtr<BindingPattern const>>(); binding_ptr && (*binding_ptr)->contains_expression())
return true; return true;
} }
return false; return false;
@ -2424,14 +2424,14 @@ ThrowCompletionOr<void> BindingPattern::for_each_bound_name(ThrowCompletionOrVoi
{ {
for (auto const& entry : entries) { for (auto const& entry : entries) {
auto const& alias = entry.alias; auto const& alias = entry.alias;
if (alias.has<NonnullRefPtr<Identifier>>()) { if (alias.has<NonnullRefPtr<Identifier const>>()) {
TRY(callback(alias.get<NonnullRefPtr<Identifier>>()->string())); TRY(callback(alias.get<NonnullRefPtr<Identifier const>>()->string()));
} else if (alias.has<NonnullRefPtr<BindingPattern>>()) { } else if (alias.has<NonnullRefPtr<BindingPattern const>>()) {
TRY(alias.get<NonnullRefPtr<BindingPattern>>()->for_each_bound_name(forward<decltype(callback)>(callback))); TRY(alias.get<NonnullRefPtr<BindingPattern const>>()->for_each_bound_name(forward<decltype(callback)>(callback)));
} else { } else {
auto const& name = entry.name; auto const& name = entry.name;
if (name.has<NonnullRefPtr<Identifier>>()) if (name.has<NonnullRefPtr<Identifier const>>())
TRY(callback(name.get<NonnullRefPtr<Identifier>>()->string())); TRY(callback(name.get<NonnullRefPtr<Identifier const>>()->string()));
} }
} }
return {}; return {};
@ -2449,10 +2449,10 @@ void BindingPattern::dump(int indent) const
if (kind == Kind::Object) { if (kind == Kind::Object) {
print_indent(indent + 2); print_indent(indent + 2);
outln("(Identifier)"); outln("(Identifier)");
if (entry.name.has<NonnullRefPtr<Identifier>>()) { if (entry.name.has<NonnullRefPtr<Identifier const>>()) {
entry.name.get<NonnullRefPtr<Identifier>>()->dump(indent + 3); entry.name.get<NonnullRefPtr<Identifier const>>()->dump(indent + 3);
} else { } else {
entry.name.get<NonnullRefPtr<Expression>>()->dump(indent + 3); entry.name.get<NonnullRefPtr<Expression const>>()->dump(indent + 3);
} }
} else if (entry.is_elision()) { } else if (entry.is_elision()) {
print_indent(indent + 2); print_indent(indent + 2);
@ -2462,12 +2462,12 @@ void BindingPattern::dump(int indent) const
print_indent(indent + 2); print_indent(indent + 2);
outln("(Pattern{})", entry.is_rest ? " rest=true" : ""); outln("(Pattern{})", entry.is_rest ? " rest=true" : "");
if (entry.alias.has<NonnullRefPtr<Identifier>>()) { if (entry.alias.has<NonnullRefPtr<Identifier const>>()) {
entry.alias.get<NonnullRefPtr<Identifier>>()->dump(indent + 3); entry.alias.get<NonnullRefPtr<Identifier const>>()->dump(indent + 3);
} else if (entry.alias.has<NonnullRefPtr<BindingPattern>>()) { } else if (entry.alias.has<NonnullRefPtr<BindingPattern const>>()) {
entry.alias.get<NonnullRefPtr<BindingPattern>>()->dump(indent + 3); entry.alias.get<NonnullRefPtr<BindingPattern const>>()->dump(indent + 3);
} else if (entry.alias.has<NonnullRefPtr<MemberExpression>>()) { } else if (entry.alias.has<NonnullRefPtr<MemberExpression const>>()) {
entry.alias.get<NonnullRefPtr<MemberExpression>>()->dump(indent + 3); entry.alias.get<NonnullRefPtr<MemberExpression const>>()->dump(indent + 3);
} else { } else {
print_indent(indent + 3); print_indent(indent + 3);
outln("<empty>"); outln("<empty>");
@ -2718,7 +2718,7 @@ Completion AssignmentExpression::execute(Interpreter& interpreter) const
// AssignmentExpression : LeftHandSideExpression = AssignmentExpression // AssignmentExpression : LeftHandSideExpression = AssignmentExpression
return m_lhs.visit( return m_lhs.visit(
// 1. If LeftHandSideExpression is neither an ObjectLiteral nor an ArrayLiteral, then // 1. If LeftHandSideExpression is neither an ObjectLiteral nor an ArrayLiteral, then
[&](NonnullRefPtr<Expression> const& lhs) -> ThrowCompletionOr<Value> { [&](NonnullRefPtr<Expression const> const& lhs) -> ThrowCompletionOr<Value> {
// a. Let lref be the result of evaluating LeftHandSideExpression. // a. Let lref be the result of evaluating LeftHandSideExpression.
// b. ReturnIfAbrupt(lref). // b. ReturnIfAbrupt(lref).
auto reference = TRY(lhs->to_reference(interpreter)); auto reference = TRY(lhs->to_reference(interpreter));
@ -2745,7 +2745,7 @@ Completion AssignmentExpression::execute(Interpreter& interpreter) const
return rhs_result; return rhs_result;
}, },
// 2. Let assignmentPattern be the AssignmentPattern that is covered by LeftHandSideExpression. // 2. Let assignmentPattern be the AssignmentPattern that is covered by LeftHandSideExpression.
[&](NonnullRefPtr<BindingPattern> const& pattern) -> ThrowCompletionOr<Value> { [&](NonnullRefPtr<BindingPattern const> const& pattern) -> ThrowCompletionOr<Value> {
// 3. Let rref be the result of evaluating AssignmentExpression. // 3. Let rref be the result of evaluating AssignmentExpression.
// 4. Let rval be ? GetValue(rref). // 4. Let rval be ? GetValue(rref).
auto rhs_result = TRY(m_rhs->execute(interpreter)).release_value(); auto rhs_result = TRY(m_rhs->execute(interpreter)).release_value();
@ -2757,10 +2757,10 @@ Completion AssignmentExpression::execute(Interpreter& interpreter) const
return rhs_result; return rhs_result;
}); });
} }
VERIFY(m_lhs.has<NonnullRefPtr<Expression>>()); VERIFY(m_lhs.has<NonnullRefPtr<Expression const>>());
// 1. Let lref be the result of evaluating LeftHandSideExpression. // 1. Let lref be the result of evaluating LeftHandSideExpression.
auto& lhs_expression = *m_lhs.get<NonnullRefPtr<Expression>>(); auto& lhs_expression = *m_lhs.get<NonnullRefPtr<Expression const>>();
auto reference = TRY(lhs_expression.to_reference(interpreter)); auto reference = TRY(lhs_expression.to_reference(interpreter));
// 2. Let lval be ? GetValue(lref). // 2. Let lval be ? GetValue(lref).
@ -3029,7 +3029,7 @@ Completion VariableDeclaration::execute(Interpreter& interpreter) const
for (auto& declarator : m_declarations) { for (auto& declarator : m_declarations) {
if (auto* init = declarator.init()) { if (auto* init = declarator.init()) {
TRY(declarator.target().visit( TRY(declarator.target().visit(
[&](NonnullRefPtr<Identifier> const& id) -> ThrowCompletionOr<void> { [&](NonnullRefPtr<Identifier const> const& id) -> ThrowCompletionOr<void> {
auto reference = TRY(id->to_reference(interpreter)); auto reference = TRY(id->to_reference(interpreter));
auto initializer_result = TRY(interpreter.vm().named_evaluation_if_anonymous_function(*init, id->string())); auto initializer_result = TRY(interpreter.vm().named_evaluation_if_anonymous_function(*init, id->string()));
VERIFY(!initializer_result.is_empty()); VERIFY(!initializer_result.is_empty());
@ -3039,7 +3039,7 @@ Completion VariableDeclaration::execute(Interpreter& interpreter) const
else else
return reference.initialize_referenced_binding(vm, initializer_result); return reference.initialize_referenced_binding(vm, initializer_result);
}, },
[&](NonnullRefPtr<BindingPattern> const& pattern) -> ThrowCompletionOr<void> { [&](NonnullRefPtr<BindingPattern const> const& pattern) -> ThrowCompletionOr<void> {
auto initializer_result = TRY(init->execute(interpreter)).release_value(); auto initializer_result = TRY(init->execute(interpreter)).release_value();
Environment* environment = m_declaration_kind == DeclarationKind::Var ? nullptr : interpreter.lexical_environment(); Environment* environment = m_declaration_kind == DeclarationKind::Var ? nullptr : interpreter.lexical_environment();
@ -3047,8 +3047,8 @@ Completion VariableDeclaration::execute(Interpreter& interpreter) const
return vm.binding_initialization(pattern, initializer_result, environment); return vm.binding_initialization(pattern, initializer_result, environment);
})); }));
} else if (m_declaration_kind != DeclarationKind::Var) { } else if (m_declaration_kind != DeclarationKind::Var) {
VERIFY(declarator.target().has<NonnullRefPtr<Identifier>>()); VERIFY(declarator.target().has<NonnullRefPtr<Identifier const>>());
auto& identifier = declarator.target().get<NonnullRefPtr<Identifier>>(); auto& identifier = declarator.target().get<NonnullRefPtr<Identifier const>>();
auto reference = TRY(identifier->to_reference(interpreter)); auto reference = TRY(identifier->to_reference(interpreter));
TRY(reference.initialize_referenced_binding(vm, js_undefined())); TRY(reference.initialize_referenced_binding(vm, js_undefined()));
} }
@ -3068,10 +3068,10 @@ ThrowCompletionOr<void> VariableDeclaration::for_each_bound_name(ThrowCompletion
{ {
for (auto const& entry : declarations()) { for (auto const& entry : declarations()) {
TRY(entry.target().visit( TRY(entry.target().visit(
[&](NonnullRefPtr<Identifier> const& id) { [&](NonnullRefPtr<Identifier const> const& id) {
return callback(id->string()); return callback(id->string());
}, },
[&](NonnullRefPtr<BindingPattern> const& binding) { [&](NonnullRefPtr<BindingPattern const> const& binding) {
return binding->for_each_bound_name([&](auto const& name) { return binding->for_each_bound_name([&](auto const& name) {
return callback(name); return callback(name);
}); });
@ -3112,10 +3112,10 @@ Completion UsingDeclaration::execute(Interpreter& interpreter) const
auto& vm = interpreter.vm(); auto& vm = interpreter.vm();
for (auto& declarator : m_declarations) { for (auto& declarator : m_declarations) {
VERIFY(declarator.target().has<NonnullRefPtr<Identifier>>()); VERIFY(declarator.target().has<NonnullRefPtr<Identifier const>>());
VERIFY(declarator.init()); VERIFY(declarator.init());
auto& id = declarator.target().get<NonnullRefPtr<Identifier>>(); auto& id = declarator.target().get<NonnullRefPtr<Identifier const>>();
// 2. ReturnIfAbrupt(next). // 2. ReturnIfAbrupt(next).
auto reference = TRY(id->to_reference(interpreter)); auto reference = TRY(id->to_reference(interpreter));
@ -3131,8 +3131,8 @@ Completion UsingDeclaration::execute(Interpreter& interpreter) const
ThrowCompletionOr<void> UsingDeclaration::for_each_bound_name(ThrowCompletionOrVoidCallback<DeprecatedFlyString const&>&& callback) const ThrowCompletionOr<void> UsingDeclaration::for_each_bound_name(ThrowCompletionOrVoidCallback<DeprecatedFlyString const&>&& callback) const
{ {
for (auto const& entry : m_declarations) { for (auto const& entry : m_declarations) {
VERIFY(entry.target().has<NonnullRefPtr<Identifier>>()); VERIFY(entry.target().has<NonnullRefPtr<Identifier const>>());
TRY(callback(entry.target().get<NonnullRefPtr<Identifier>>()->string())); TRY(callback(entry.target().get<NonnullRefPtr<Identifier const>>()->string()));
} }
return {}; return {};
@ -3349,24 +3349,24 @@ ThrowCompletionOr<OptionalChain::ReferenceAndValue> OptionalChain::to_reference_
return ReferenceAndValue { {}, js_undefined() }; return ReferenceAndValue { {}, js_undefined() };
auto expression = reference.visit( auto expression = reference.visit(
[&](Call const& call) -> NonnullRefPtr<Expression> { [&](Call const& call) -> NonnullRefPtr<Expression const> {
return CallExpression::create(source_range(), return CallExpression::create(source_range(),
create_ast_node<SyntheticReferenceExpression>(source_range(), base_reference, base), create_ast_node<SyntheticReferenceExpression>(source_range(), base_reference, base),
call.arguments); call.arguments);
}, },
[&](ComputedReference const& ref) -> NonnullRefPtr<Expression> { [&](ComputedReference const& ref) -> NonnullRefPtr<Expression const> {
return create_ast_node<MemberExpression>(source_range(), return create_ast_node<MemberExpression>(source_range(),
create_ast_node<SyntheticReferenceExpression>(source_range(), base_reference, base), create_ast_node<SyntheticReferenceExpression>(source_range(), base_reference, base),
ref.expression, ref.expression,
true); true);
}, },
[&](MemberReference const& ref) -> NonnullRefPtr<Expression> { [&](MemberReference const& ref) -> NonnullRefPtr<Expression const> {
return create_ast_node<MemberExpression>(source_range(), return create_ast_node<MemberExpression>(source_range(),
create_ast_node<SyntheticReferenceExpression>(source_range(), base_reference, base), create_ast_node<SyntheticReferenceExpression>(source_range(), base_reference, base),
ref.identifier, ref.identifier,
false); false);
}, },
[&](PrivateMemberReference const& ref) -> NonnullRefPtr<Expression> { [&](PrivateMemberReference const& ref) -> NonnullRefPtr<Expression const> {
return create_ast_node<MemberExpression>(source_range(), return create_ast_node<MemberExpression>(source_range(),
create_ast_node<SyntheticReferenceExpression>(source_range(), base_reference, base), create_ast_node<SyntheticReferenceExpression>(source_range(), base_reference, base),
ref.private_identifier, ref.private_identifier,
@ -3945,7 +3945,7 @@ void CatchClause::dump(int indent) const
else else
outln("CatchClause ({})", parameter); outln("CatchClause ({})", parameter);
}, },
[&](NonnullRefPtr<BindingPattern> const& pattern) { [&](NonnullRefPtr<BindingPattern const> const& pattern) {
outln("CatchClause"); outln("CatchClause");
print_indent(indent); print_indent(indent);
outln("(Parameter)"); outln("(Parameter)");
@ -3981,7 +3981,7 @@ Completion TryStatement::execute(Interpreter& interpreter) const
// a. Perform ! catchEnv.CreateMutableBinding(argName, false). // a. Perform ! catchEnv.CreateMutableBinding(argName, false).
MUST(catch_environment->create_mutable_binding(vm, parameter, false)); MUST(catch_environment->create_mutable_binding(vm, parameter, false));
}, },
[&](NonnullRefPtr<BindingPattern> const& pattern) { [&](NonnullRefPtr<BindingPattern const> const& pattern) {
// 3. For each element argName of the BoundNames of CatchParameter, do // 3. For each element argName of the BoundNames of CatchParameter, do
pattern->for_each_bound_name([&](auto& name) { pattern->for_each_bound_name([&](auto& name) {
// a. Perform ! catchEnv.CreateMutableBinding(argName, false). // a. Perform ! catchEnv.CreateMutableBinding(argName, false).
@ -3997,7 +3997,7 @@ Completion TryStatement::execute(Interpreter& interpreter) const
[&](DeprecatedFlyString const& parameter) { [&](DeprecatedFlyString const& parameter) {
return catch_environment->initialize_binding(vm, parameter, thrown_value, Environment::InitializeBindingHint::Normal); return catch_environment->initialize_binding(vm, parameter, thrown_value, Environment::InitializeBindingHint::Normal);
}, },
[&](NonnullRefPtr<BindingPattern> const& pattern) { [&](NonnullRefPtr<BindingPattern const> const& pattern) {
return vm.binding_initialization(pattern, thrown_value, catch_environment); return vm.binding_initialization(pattern, thrown_value, catch_environment);
}); });
@ -4119,9 +4119,9 @@ Completion SwitchStatement::execute_impl(Interpreter& interpreter) const
return js_undefined(); return js_undefined();
} }
NonnullRefPtrVector<SwitchCase> case_clauses_1; NonnullRefPtrVector<SwitchCase const> case_clauses_1;
NonnullRefPtrVector<SwitchCase> case_clauses_2; NonnullRefPtrVector<SwitchCase const> case_clauses_2;
RefPtr<SwitchCase> default_clause; RefPtr<SwitchCase const> default_clause;
for (auto const& switch_case : m_cases) { for (auto const& switch_case : m_cases) {
if (!switch_case.test()) if (!switch_case.test())
default_clause = switch_case; default_clause = switch_case;
@ -4524,17 +4524,17 @@ ThrowCompletionOr<void> ScopeNode::for_each_function_hoistable_with_annexB_exten
return {}; return {};
} }
void ScopeNode::add_lexical_declaration(NonnullRefPtr<Declaration> declaration) void ScopeNode::add_lexical_declaration(NonnullRefPtr<Declaration const> declaration)
{ {
m_lexical_declarations.append(move(declaration)); m_lexical_declarations.append(move(declaration));
} }
void ScopeNode::add_var_scoped_declaration(NonnullRefPtr<Declaration> declaration) void ScopeNode::add_var_scoped_declaration(NonnullRefPtr<Declaration const> declaration)
{ {
m_var_declarations.append(move(declaration)); m_var_declarations.append(move(declaration));
} }
void ScopeNode::add_hoisted_function(NonnullRefPtr<FunctionDeclaration> declaration) void ScopeNode::add_hoisted_function(NonnullRefPtr<FunctionDeclaration const> declaration)
{ {
m_functions_hoistable_with_annexB_extension.append(move(declaration)); m_functions_hoistable_with_annexB_extension.append(move(declaration));
} }
@ -4967,12 +4967,12 @@ DeprecatedString SourceRange::filename() const
return code->filename().to_deprecated_string(); return code->filename().to_deprecated_string();
} }
NonnullRefPtr<CallExpression> CallExpression::create(SourceRange source_range, NonnullRefPtr<Expression> callee, ReadonlySpan<Argument> arguments) NonnullRefPtr<CallExpression> CallExpression::create(SourceRange source_range, NonnullRefPtr<Expression const> callee, ReadonlySpan<Argument> arguments)
{ {
return ASTNodeWithTailArray::create<CallExpression>(arguments.size(), move(source_range), move(callee), arguments); return ASTNodeWithTailArray::create<CallExpression>(arguments.size(), move(source_range), move(callee), arguments);
} }
NonnullRefPtr<NewExpression> NewExpression::create(SourceRange source_range, NonnullRefPtr<Expression> callee, ReadonlySpan<Argument> arguments) NonnullRefPtr<NewExpression> NewExpression::create(SourceRange source_range, NonnullRefPtr<Expression const> callee, ReadonlySpan<Argument> arguments)
{ {
return ASTNodeWithTailArray::create<NewExpression>(arguments.size(), move(source_range), move(callee), arguments); return ASTNodeWithTailArray::create<NewExpression>(arguments.size(), move(source_range), move(callee), arguments);
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2020-2021, Andreas Kling <kling@serenityos.org> * Copyright (c) 2020-2023, Andreas Kling <kling@serenityos.org>
* Copyright (c) 2020-2022, Linus Groh <linusg@serenityos.org> * Copyright (c) 2020-2022, Linus Groh <linusg@serenityos.org>
* Copyright (c) 2021-2022, David Tuin <davidot@serenityos.org> * Copyright (c) 2021-2022, David Tuin <davidot@serenityos.org>
* *
@ -97,7 +97,7 @@ private:
// NOTE: These members are carefully ordered so that `m_start_offset` is packed with the padding after RefCounted::m_ref_count. // NOTE: These members are carefully ordered so that `m_start_offset` is packed with the padding after RefCounted::m_ref_count.
// This creates a 4-byte padding hole after `m_end_offset` which is used to pack subclasses better. // This creates a 4-byte padding hole after `m_end_offset` which is used to pack subclasses better.
u32 m_start_offset { 0 }; u32 m_start_offset { 0 };
RefPtr<SourceCode> m_source_code; RefPtr<SourceCode const> m_source_code;
u32 m_end_offset { 0 }; u32 m_end_offset { 0 };
}; };
@ -152,7 +152,7 @@ public:
// 14.13 Labelled Statements, https://tc39.es/ecma262/#sec-labelled-statements // 14.13 Labelled Statements, https://tc39.es/ecma262/#sec-labelled-statements
class LabelledStatement : public Statement { class LabelledStatement : public Statement {
public: public:
LabelledStatement(SourceRange source_range, DeprecatedFlyString label, NonnullRefPtr<Statement> labelled_item) LabelledStatement(SourceRange source_range, DeprecatedFlyString label, NonnullRefPtr<Statement const> labelled_item)
: Statement(source_range) : Statement(source_range)
, m_label(move(label)) , m_label(move(label))
, m_labelled_item(move(labelled_item)) , m_labelled_item(move(labelled_item))
@ -166,14 +166,13 @@ public:
DeprecatedFlyString const& label() const { return m_label; } DeprecatedFlyString const& label() const { return m_label; }
DeprecatedFlyString& label() { return m_label; } DeprecatedFlyString& label() { return m_label; }
NonnullRefPtr<Statement> const& labelled_item() const { return m_labelled_item; } NonnullRefPtr<Statement const> const& labelled_item() const { return m_labelled_item; }
NonnullRefPtr<Statement>& labelled_item() { return m_labelled_item; }
private: private:
virtual bool is_labelled_statement() const final { return true; } virtual bool is_labelled_statement() const final { return true; }
DeprecatedFlyString m_label; DeprecatedFlyString m_label;
NonnullRefPtr<Statement> m_labelled_item; NonnullRefPtr<Statement const> m_labelled_item;
}; };
class LabelableStatement : public Statement { class LabelableStatement : public Statement {
@ -219,7 +218,7 @@ public:
class ExpressionStatement final : public Statement { class ExpressionStatement final : public Statement {
public: public:
ExpressionStatement(SourceRange source_range, NonnullRefPtr<Expression> expression) ExpressionStatement(SourceRange source_range, NonnullRefPtr<Expression const> expression)
: Statement(source_range) : Statement(source_range)
, m_expression(move(expression)) , m_expression(move(expression))
{ {
@ -234,7 +233,7 @@ public:
private: private:
virtual bool is_expression_statement() const override { return true; } virtual bool is_expression_statement() const override { return true; }
NonnullRefPtr<Expression> m_expression; NonnullRefPtr<Expression const> m_expression;
}; };
template<typename Func, typename... Args> template<typename Func, typename... Args>
@ -275,7 +274,7 @@ public:
m_children.append(move(child)); m_children.append(move(child));
return static_cast<T&>(m_children.last()); return static_cast<T&>(m_children.last());
} }
void append(NonnullRefPtr<Statement> child) void append(NonnullRefPtr<Statement const> child)
{ {
m_children.append(move(child)); m_children.append(move(child));
} }
@ -288,15 +287,15 @@ public:
m_functions_hoistable_with_annexB_extension.shrink_to_fit(); m_functions_hoistable_with_annexB_extension.shrink_to_fit();
} }
NonnullRefPtrVector<Statement> const& children() const { return m_children; } NonnullRefPtrVector<Statement const> const& children() const { return m_children; }
virtual void dump(int indent) const override; virtual void dump(int indent) const override;
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override; virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override;
Completion evaluate_statements(Interpreter&) const; Completion evaluate_statements(Interpreter&) const;
void add_var_scoped_declaration(NonnullRefPtr<Declaration> variables); void add_var_scoped_declaration(NonnullRefPtr<Declaration const> variables);
void add_lexical_declaration(NonnullRefPtr<Declaration> variables); void add_lexical_declaration(NonnullRefPtr<Declaration const> variables);
void add_hoisted_function(NonnullRefPtr<FunctionDeclaration> declaration); void add_hoisted_function(NonnullRefPtr<FunctionDeclaration const> declaration);
[[nodiscard]] bool has_lexical_declarations() const { return !m_lexical_declarations.is_empty(); } [[nodiscard]] bool has_lexical_declarations() const { return !m_lexical_declarations.is_empty(); }
[[nodiscard]] bool has_var_declarations() const { return !m_var_declarations.is_empty(); } [[nodiscard]] bool has_var_declarations() const { return !m_var_declarations.is_empty(); }
@ -325,11 +324,11 @@ protected:
private: private:
virtual bool is_scope_node() const final { return true; } virtual bool is_scope_node() const final { return true; }
NonnullRefPtrVector<Statement> m_children; NonnullRefPtrVector<Statement const> m_children;
NonnullRefPtrVector<Declaration> m_lexical_declarations; NonnullRefPtrVector<Declaration const> m_lexical_declarations;
NonnullRefPtrVector<Declaration> m_var_declarations; NonnullRefPtrVector<Declaration const> m_var_declarations;
NonnullRefPtrVector<FunctionDeclaration> m_functions_hoistable_with_annexB_extension; NonnullRefPtrVector<FunctionDeclaration const> m_functions_hoistable_with_annexB_extension;
}; };
// ImportEntry Record, https://tc39.es/ecma262/#table-importentry-record-fields // ImportEntry Record, https://tc39.es/ecma262/#table-importentry-record-fields
@ -375,7 +374,6 @@ public:
bool has_bound_name(DeprecatedFlyString const& name) const; bool has_bound_name(DeprecatedFlyString const& name) const;
Vector<ImportEntry> const& entries() const { return m_entries; } Vector<ImportEntry> const& entries() const { return m_entries; }
ModuleRequest const& module_request() const { return m_module_request; } ModuleRequest const& module_request() const { return m_module_request; }
ModuleRequest& module_request() { return m_module_request; }
private: private:
ModuleRequest m_module_request; ModuleRequest m_module_request;
@ -453,7 +451,7 @@ class ExportStatement final : public Statement {
public: public:
static DeprecatedFlyString local_name_for_default; static DeprecatedFlyString local_name_for_default;
ExportStatement(SourceRange source_range, RefPtr<ASTNode> statement, Vector<ExportEntry> entries, bool is_default_export, ModuleRequest module_request) ExportStatement(SourceRange source_range, RefPtr<ASTNode const> statement, Vector<ExportEntry> entries, bool is_default_export, ModuleRequest module_request)
: Statement(source_range) : Statement(source_range)
, m_statement(move(statement)) , m_statement(move(statement))
, m_entries(move(entries)) , m_entries(move(entries))
@ -483,14 +481,14 @@ public:
return *m_statement; return *m_statement;
} }
ModuleRequest& module_request() ModuleRequest const& module_request() const
{ {
VERIFY(!m_module_request.module_specifier.is_null()); VERIFY(!m_module_request.module_specifier.is_null());
return m_module_request; return m_module_request;
} }
private: private:
RefPtr<ASTNode> m_statement; RefPtr<ASTNode const> m_statement;
Vector<ExportEntry> m_entries; Vector<ExportEntry> m_entries;
bool m_is_default_export { false }; bool m_is_default_export { false };
ModuleRequest m_module_request; ModuleRequest m_module_request;
@ -516,23 +514,23 @@ public:
Type type() const { return m_type; } Type type() const { return m_type; }
void append_import(NonnullRefPtr<ImportStatement> import_statement) void append_import(NonnullRefPtr<ImportStatement const> import_statement)
{ {
m_imports.append(import_statement); m_imports.append(import_statement);
append(import_statement); append(import_statement);
} }
void append_export(NonnullRefPtr<ExportStatement> export_statement) void append_export(NonnullRefPtr<ExportStatement const> export_statement)
{ {
m_exports.append(export_statement); m_exports.append(export_statement);
append(export_statement); append(export_statement);
} }
NonnullRefPtrVector<ImportStatement> const& imports() const { return m_imports; } NonnullRefPtrVector<ImportStatement const> const& imports() const { return m_imports; }
NonnullRefPtrVector<ExportStatement> const& exports() const { return m_exports; } NonnullRefPtrVector<ExportStatement const> const& exports() const { return m_exports; }
NonnullRefPtrVector<ImportStatement>& imports() { return m_imports; } NonnullRefPtrVector<ImportStatement const>& imports() { return m_imports; }
NonnullRefPtrVector<ExportStatement>& exports() { return m_exports; } NonnullRefPtrVector<ExportStatement const>& exports() { return m_exports; }
bool has_top_level_await() const { return m_has_top_level_await; } bool has_top_level_await() const { return m_has_top_level_await; }
void set_has_top_level_await() { m_has_top_level_await = true; } void set_has_top_level_await() { m_has_top_level_await = true; }
@ -545,8 +543,8 @@ private:
bool m_is_strict_mode { false }; bool m_is_strict_mode { false };
Type m_type { Type::Script }; Type m_type { Type::Script };
NonnullRefPtrVector<ImportStatement> m_imports; NonnullRefPtrVector<ImportStatement const> m_imports;
NonnullRefPtrVector<ExportStatement> m_exports; NonnullRefPtrVector<ExportStatement const> m_exports;
bool m_has_top_level_await { false }; bool m_has_top_level_await { false };
}; };
@ -618,9 +616,9 @@ struct BindingPattern : RefCounted<BindingPattern> {
// This covers both BindingProperty and BindingElement, hence the more generic name // This covers both BindingProperty and BindingElement, hence the more generic name
struct BindingEntry { struct BindingEntry {
// If this entry represents a BindingElement, then name will be Empty // If this entry represents a BindingElement, then name will be Empty
Variant<NonnullRefPtr<Identifier>, NonnullRefPtr<Expression>, Empty> name {}; Variant<NonnullRefPtr<Identifier const>, NonnullRefPtr<Expression const>, Empty> name {};
Variant<NonnullRefPtr<Identifier>, NonnullRefPtr<BindingPattern>, NonnullRefPtr<MemberExpression>, Empty> alias {}; Variant<NonnullRefPtr<Identifier const>, NonnullRefPtr<BindingPattern const>, NonnullRefPtr<MemberExpression const>, Empty> alias {};
RefPtr<Expression> initializer {}; RefPtr<Expression const> initializer {};
bool is_rest { false }; bool is_rest { false };
bool is_elision() const { return name.has<Empty>() && alias.has<Empty>(); } bool is_elision() const { return name.has<Empty>() && alias.has<Empty>(); }
@ -642,8 +640,8 @@ struct BindingPattern : RefCounted<BindingPattern> {
}; };
struct FunctionParameter { struct FunctionParameter {
Variant<DeprecatedFlyString, NonnullRefPtr<BindingPattern>> binding; Variant<DeprecatedFlyString, NonnullRefPtr<BindingPattern const>> binding;
RefPtr<Expression> default_value; RefPtr<Expression const> default_value;
bool is_rest { false }; bool is_rest { false };
}; };
@ -661,7 +659,7 @@ public:
FunctionKind kind() const { return m_kind; } FunctionKind kind() const { return m_kind; }
protected: protected:
FunctionNode(DeprecatedFlyString name, DeprecatedString source_text, NonnullRefPtr<Statement> body, Vector<FunctionParameter> parameters, i32 function_length, FunctionKind kind, bool is_strict_mode, bool might_need_arguments_object, bool contains_direct_call_to_eval, bool is_arrow_function) FunctionNode(DeprecatedFlyString name, DeprecatedString source_text, NonnullRefPtr<Statement const> body, Vector<FunctionParameter> parameters, i32 function_length, FunctionKind kind, bool is_strict_mode, bool might_need_arguments_object, bool contains_direct_call_to_eval, bool is_arrow_function)
: m_name(move(name)) : m_name(move(name))
, m_source_text(move(source_text)) , m_source_text(move(source_text))
, m_body(move(body)) , m_body(move(body))
@ -682,7 +680,7 @@ protected:
private: private:
DeprecatedFlyString m_name; DeprecatedFlyString m_name;
DeprecatedString m_source_text; DeprecatedString m_source_text;
NonnullRefPtr<Statement> m_body; NonnullRefPtr<Statement const> m_body;
Vector<FunctionParameter> const m_parameters; Vector<FunctionParameter> const m_parameters;
const i32 m_function_length; const i32 m_function_length;
FunctionKind m_kind; FunctionKind m_kind;
@ -698,7 +696,7 @@ class FunctionDeclaration final
public: public:
static bool must_have_name() { return true; } static bool must_have_name() { return true; }
FunctionDeclaration(SourceRange source_range, DeprecatedFlyString const& name, DeprecatedString source_text, NonnullRefPtr<Statement> body, Vector<FunctionParameter> parameters, i32 function_length, FunctionKind kind, bool is_strict_mode, bool might_need_arguments_object, bool contains_direct_call_to_eval) FunctionDeclaration(SourceRange source_range, DeprecatedFlyString const& name, DeprecatedString source_text, NonnullRefPtr<Statement const> body, Vector<FunctionParameter> parameters, i32 function_length, FunctionKind kind, bool is_strict_mode, bool might_need_arguments_object, bool contains_direct_call_to_eval)
: Declaration(source_range) : Declaration(source_range)
, FunctionNode(name, move(source_text), move(body), move(parameters), function_length, kind, is_strict_mode, might_need_arguments_object, contains_direct_call_to_eval, false) , FunctionNode(name, move(source_text), move(body), move(parameters), function_length, kind, is_strict_mode, might_need_arguments_object, contains_direct_call_to_eval, false)
{ {
@ -724,7 +722,7 @@ class FunctionExpression final
public: public:
static bool must_have_name() { return false; } static bool must_have_name() { return false; }
FunctionExpression(SourceRange source_range, DeprecatedFlyString const& name, DeprecatedString source_text, NonnullRefPtr<Statement> body, Vector<FunctionParameter> parameters, i32 function_length, FunctionKind kind, bool is_strict_mode, bool might_need_arguments_object, bool contains_direct_call_to_eval, bool is_arrow_function = false) FunctionExpression(SourceRange source_range, DeprecatedFlyString const& name, DeprecatedString source_text, NonnullRefPtr<Statement const> body, Vector<FunctionParameter> parameters, i32 function_length, FunctionKind kind, bool is_strict_mode, bool might_need_arguments_object, bool contains_direct_call_to_eval, bool is_arrow_function = false)
: Expression(source_range) : Expression(source_range)
, FunctionNode(name, move(source_text), move(body), move(parameters), function_length, kind, is_strict_mode, might_need_arguments_object, contains_direct_call_to_eval, is_arrow_function) , FunctionNode(name, move(source_text), move(body), move(parameters), function_length, kind, is_strict_mode, might_need_arguments_object, contains_direct_call_to_eval, is_arrow_function)
{ {
@ -755,7 +753,7 @@ public:
class YieldExpression final : public Expression { class YieldExpression final : public Expression {
public: public:
explicit YieldExpression(SourceRange source_range, RefPtr<Expression> argument, bool is_yield_from) explicit YieldExpression(SourceRange source_range, RefPtr<Expression const> argument, bool is_yield_from)
: Expression(source_range) : Expression(source_range)
, m_argument(move(argument)) , m_argument(move(argument))
, m_is_yield_from(is_yield_from) , m_is_yield_from(is_yield_from)
@ -770,13 +768,13 @@ public:
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override; virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override;
private: private:
RefPtr<Expression> m_argument; RefPtr<Expression const> m_argument;
bool m_is_yield_from { false }; bool m_is_yield_from { false };
}; };
class AwaitExpression final : public Expression { class AwaitExpression final : public Expression {
public: public:
explicit AwaitExpression(SourceRange source_range, NonnullRefPtr<Expression> argument) explicit AwaitExpression(SourceRange source_range, NonnullRefPtr<Expression const> argument)
: Expression(source_range) : Expression(source_range)
, m_argument(move(argument)) , m_argument(move(argument))
{ {
@ -787,12 +785,12 @@ public:
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override; virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override;
private: private:
NonnullRefPtr<Expression> m_argument; NonnullRefPtr<Expression const> m_argument;
}; };
class ReturnStatement final : public Statement { class ReturnStatement final : public Statement {
public: public:
explicit ReturnStatement(SourceRange source_range, RefPtr<Expression> argument) explicit ReturnStatement(SourceRange source_range, RefPtr<Expression const> argument)
: Statement(source_range) : Statement(source_range)
, m_argument(move(argument)) , m_argument(move(argument))
{ {
@ -805,12 +803,12 @@ public:
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override; virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override;
private: private:
RefPtr<Expression> m_argument; RefPtr<Expression const> m_argument;
}; };
class IfStatement final : public Statement { class IfStatement final : public Statement {
public: public:
IfStatement(SourceRange source_range, NonnullRefPtr<Expression> predicate, NonnullRefPtr<Statement> consequent, RefPtr<Statement> alternate) IfStatement(SourceRange source_range, NonnullRefPtr<Expression const> predicate, NonnullRefPtr<Statement const> consequent, RefPtr<Statement const> alternate)
: Statement(source_range) : Statement(source_range)
, m_predicate(move(predicate)) , m_predicate(move(predicate))
, m_consequent(move(consequent)) , m_consequent(move(consequent))
@ -827,14 +825,14 @@ public:
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override; virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override;
private: private:
NonnullRefPtr<Expression> m_predicate; NonnullRefPtr<Expression const> m_predicate;
NonnullRefPtr<Statement> m_consequent; NonnullRefPtr<Statement const> m_consequent;
RefPtr<Statement> m_alternate; RefPtr<Statement const> m_alternate;
}; };
class WhileStatement final : public IterationStatement { class WhileStatement final : public IterationStatement {
public: public:
WhileStatement(SourceRange source_range, NonnullRefPtr<Expression> test, NonnullRefPtr<Statement> body) WhileStatement(SourceRange source_range, NonnullRefPtr<Expression const> test, NonnullRefPtr<Statement const> body)
: IterationStatement(source_range) : IterationStatement(source_range)
, m_test(move(test)) , m_test(move(test))
, m_body(move(body)) , m_body(move(body))
@ -851,13 +849,13 @@ public:
virtual Bytecode::CodeGenerationErrorOr<void> generate_labelled_evaluation(Bytecode::Generator&, Vector<DeprecatedFlyString> const&) const override; virtual Bytecode::CodeGenerationErrorOr<void> generate_labelled_evaluation(Bytecode::Generator&, Vector<DeprecatedFlyString> const&) const override;
private: private:
NonnullRefPtr<Expression> m_test; NonnullRefPtr<Expression const> m_test;
NonnullRefPtr<Statement> m_body; NonnullRefPtr<Statement const> m_body;
}; };
class DoWhileStatement final : public IterationStatement { class DoWhileStatement final : public IterationStatement {
public: public:
DoWhileStatement(SourceRange source_range, NonnullRefPtr<Expression> test, NonnullRefPtr<Statement> body) DoWhileStatement(SourceRange source_range, NonnullRefPtr<Expression const> test, NonnullRefPtr<Statement const> body)
: IterationStatement(source_range) : IterationStatement(source_range)
, m_test(move(test)) , m_test(move(test))
, m_body(move(body)) , m_body(move(body))
@ -874,13 +872,13 @@ public:
virtual Bytecode::CodeGenerationErrorOr<void> generate_labelled_evaluation(Bytecode::Generator&, Vector<DeprecatedFlyString> const&) const override; virtual Bytecode::CodeGenerationErrorOr<void> generate_labelled_evaluation(Bytecode::Generator&, Vector<DeprecatedFlyString> const&) const override;
private: private:
NonnullRefPtr<Expression> m_test; NonnullRefPtr<Expression const> m_test;
NonnullRefPtr<Statement> m_body; NonnullRefPtr<Statement const> m_body;
}; };
class WithStatement final : public Statement { class WithStatement final : public Statement {
public: public:
WithStatement(SourceRange source_range, NonnullRefPtr<Expression> object, NonnullRefPtr<Statement> body) WithStatement(SourceRange source_range, NonnullRefPtr<Expression const> object, NonnullRefPtr<Statement const> body)
: Statement(source_range) : Statement(source_range)
, m_object(move(object)) , m_object(move(object))
, m_body(move(body)) , m_body(move(body))
@ -895,13 +893,13 @@ public:
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override; virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override;
private: private:
NonnullRefPtr<Expression> m_object; NonnullRefPtr<Expression const> m_object;
NonnullRefPtr<Statement> m_body; NonnullRefPtr<Statement const> m_body;
}; };
class ForStatement final : public IterationStatement { class ForStatement final : public IterationStatement {
public: public:
ForStatement(SourceRange source_range, RefPtr<ASTNode> init, RefPtr<Expression> test, RefPtr<Expression> update, NonnullRefPtr<Statement> body) ForStatement(SourceRange source_range, RefPtr<ASTNode const> init, RefPtr<Expression const> test, RefPtr<Expression const> update, NonnullRefPtr<Statement const> body)
: IterationStatement(source_range) : IterationStatement(source_range)
, m_init(move(init)) , m_init(move(init))
, m_test(move(test)) , m_test(move(test))
@ -924,15 +922,15 @@ public:
private: private:
Completion for_body_evaluation(Interpreter&, Vector<DeprecatedFlyString> const&, size_t per_iteration_bindings_size) const; Completion for_body_evaluation(Interpreter&, Vector<DeprecatedFlyString> const&, size_t per_iteration_bindings_size) const;
RefPtr<ASTNode> m_init; RefPtr<ASTNode const> m_init;
RefPtr<Expression> m_test; RefPtr<Expression const> m_test;
RefPtr<Expression> m_update; RefPtr<Expression const> m_update;
NonnullRefPtr<Statement> m_body; NonnullRefPtr<Statement const> m_body;
}; };
class ForInStatement final : public IterationStatement { class ForInStatement final : public IterationStatement {
public: public:
ForInStatement(SourceRange source_range, Variant<NonnullRefPtr<ASTNode>, NonnullRefPtr<BindingPattern>> lhs, NonnullRefPtr<Expression> rhs, NonnullRefPtr<Statement> body) ForInStatement(SourceRange source_range, Variant<NonnullRefPtr<ASTNode const>, NonnullRefPtr<BindingPattern const>> lhs, NonnullRefPtr<Expression const> rhs, NonnullRefPtr<Statement const> body)
: IterationStatement(source_range) : IterationStatement(source_range)
, m_lhs(move(lhs)) , m_lhs(move(lhs))
, m_rhs(move(rhs)) , m_rhs(move(rhs))
@ -951,14 +949,14 @@ public:
virtual void dump(int indent) const override; virtual void dump(int indent) const override;
private: private:
Variant<NonnullRefPtr<ASTNode>, NonnullRefPtr<BindingPattern>> m_lhs; Variant<NonnullRefPtr<ASTNode const>, NonnullRefPtr<BindingPattern const>> m_lhs;
NonnullRefPtr<Expression> m_rhs; NonnullRefPtr<Expression const> m_rhs;
NonnullRefPtr<Statement> m_body; NonnullRefPtr<Statement const> m_body;
}; };
class ForOfStatement final : public IterationStatement { class ForOfStatement final : public IterationStatement {
public: public:
ForOfStatement(SourceRange source_range, Variant<NonnullRefPtr<ASTNode>, NonnullRefPtr<BindingPattern>> lhs, NonnullRefPtr<Expression> rhs, NonnullRefPtr<Statement> body) ForOfStatement(SourceRange source_range, Variant<NonnullRefPtr<ASTNode const>, NonnullRefPtr<BindingPattern const>> lhs, NonnullRefPtr<Expression const> rhs, NonnullRefPtr<Statement const> body)
: IterationStatement(source_range) : IterationStatement(source_range)
, m_lhs(move(lhs)) , m_lhs(move(lhs))
, m_rhs(move(rhs)) , m_rhs(move(rhs))
@ -977,14 +975,14 @@ public:
virtual void dump(int indent) const override; virtual void dump(int indent) const override;
private: private:
Variant<NonnullRefPtr<ASTNode>, NonnullRefPtr<BindingPattern>> m_lhs; Variant<NonnullRefPtr<ASTNode const>, NonnullRefPtr<BindingPattern const>> m_lhs;
NonnullRefPtr<Expression> m_rhs; NonnullRefPtr<Expression const> m_rhs;
NonnullRefPtr<Statement> m_body; NonnullRefPtr<Statement const> m_body;
}; };
class ForAwaitOfStatement final : public IterationStatement { class ForAwaitOfStatement final : public IterationStatement {
public: public:
ForAwaitOfStatement(SourceRange source_range, Variant<NonnullRefPtr<ASTNode>, NonnullRefPtr<BindingPattern>> lhs, NonnullRefPtr<Expression> rhs, NonnullRefPtr<Statement> body) ForAwaitOfStatement(SourceRange source_range, Variant<NonnullRefPtr<ASTNode const>, NonnullRefPtr<BindingPattern const>> lhs, NonnullRefPtr<Expression const> rhs, NonnullRefPtr<Statement const> body)
: IterationStatement(source_range) : IterationStatement(source_range)
, m_lhs(move(lhs)) , m_lhs(move(lhs))
, m_rhs(move(rhs)) , m_rhs(move(rhs))
@ -997,9 +995,9 @@ public:
virtual void dump(int indent) const override; virtual void dump(int indent) const override;
private: private:
Variant<NonnullRefPtr<ASTNode>, NonnullRefPtr<BindingPattern>> m_lhs; Variant<NonnullRefPtr<ASTNode const>, NonnullRefPtr<BindingPattern const>> m_lhs;
NonnullRefPtr<Expression> m_rhs; NonnullRefPtr<Expression const> m_rhs;
NonnullRefPtr<Statement> m_body; NonnullRefPtr<Statement const> m_body;
}; };
enum class BinaryOp { enum class BinaryOp {
@ -1029,7 +1027,7 @@ enum class BinaryOp {
class BinaryExpression final : public Expression { class BinaryExpression final : public Expression {
public: public:
BinaryExpression(SourceRange source_range, BinaryOp op, NonnullRefPtr<Expression> lhs, NonnullRefPtr<Expression> rhs) BinaryExpression(SourceRange source_range, BinaryOp op, NonnullRefPtr<Expression const> lhs, NonnullRefPtr<Expression const> rhs)
: Expression(source_range) : Expression(source_range)
, m_op(op) , m_op(op)
, m_lhs(move(lhs)) , m_lhs(move(lhs))
@ -1043,8 +1041,8 @@ public:
private: private:
BinaryOp m_op; BinaryOp m_op;
NonnullRefPtr<Expression> m_lhs; NonnullRefPtr<Expression const> m_lhs;
NonnullRefPtr<Expression> m_rhs; NonnullRefPtr<Expression const> m_rhs;
}; };
enum class LogicalOp { enum class LogicalOp {
@ -1055,7 +1053,7 @@ enum class LogicalOp {
class LogicalExpression final : public Expression { class LogicalExpression final : public Expression {
public: public:
LogicalExpression(SourceRange source_range, LogicalOp op, NonnullRefPtr<Expression> lhs, NonnullRefPtr<Expression> rhs) LogicalExpression(SourceRange source_range, LogicalOp op, NonnullRefPtr<Expression const> lhs, NonnullRefPtr<Expression const> rhs)
: Expression(source_range) : Expression(source_range)
, m_op(op) , m_op(op)
, m_lhs(move(lhs)) , m_lhs(move(lhs))
@ -1069,8 +1067,8 @@ public:
private: private:
LogicalOp m_op; LogicalOp m_op;
NonnullRefPtr<Expression> m_lhs; NonnullRefPtr<Expression const> m_lhs;
NonnullRefPtr<Expression> m_rhs; NonnullRefPtr<Expression const> m_rhs;
}; };
enum class UnaryOp { enum class UnaryOp {
@ -1085,7 +1083,7 @@ enum class UnaryOp {
class UnaryExpression final : public Expression { class UnaryExpression final : public Expression {
public: public:
UnaryExpression(SourceRange source_range, UnaryOp op, NonnullRefPtr<Expression> lhs) UnaryExpression(SourceRange source_range, UnaryOp op, NonnullRefPtr<Expression const> lhs)
: Expression(source_range) : Expression(source_range)
, m_op(op) , m_op(op)
, m_lhs(move(lhs)) , m_lhs(move(lhs))
@ -1098,12 +1096,12 @@ public:
private: private:
UnaryOp m_op; UnaryOp m_op;
NonnullRefPtr<Expression> m_lhs; NonnullRefPtr<Expression const> m_lhs;
}; };
class SequenceExpression final : public Expression { class SequenceExpression final : public Expression {
public: public:
SequenceExpression(SourceRange source_range, NonnullRefPtrVector<Expression> expressions) SequenceExpression(SourceRange source_range, NonnullRefPtrVector<Expression const> expressions)
: Expression(source_range) : Expression(source_range)
, m_expressions(move(expressions)) , m_expressions(move(expressions))
{ {
@ -1115,7 +1113,7 @@ public:
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override; virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override;
private: private:
NonnullRefPtrVector<Expression> m_expressions; NonnullRefPtrVector<Expression const> m_expressions;
}; };
class Literal : public Expression { class Literal : public Expression {
@ -1314,7 +1312,7 @@ public:
Setter, Setter,
}; };
ClassMethod(SourceRange source_range, NonnullRefPtr<Expression> key, NonnullRefPtr<FunctionExpression> function, Kind kind, bool is_static) ClassMethod(SourceRange source_range, NonnullRefPtr<Expression const> key, NonnullRefPtr<FunctionExpression const> function, Kind kind, bool is_static)
: ClassElement(source_range, is_static) : ClassElement(source_range, is_static)
, m_key(move(key)) , m_key(move(key))
, m_function(move(function)) , m_function(move(function))
@ -1332,14 +1330,14 @@ public:
private: private:
virtual bool is_class_method() const override { return true; } virtual bool is_class_method() const override { return true; }
NonnullRefPtr<Expression> m_key; NonnullRefPtr<Expression const> m_key;
NonnullRefPtr<FunctionExpression> m_function; NonnullRefPtr<FunctionExpression const> m_function;
Kind m_kind; Kind m_kind;
}; };
class ClassField final : public ClassElement { class ClassField final : public ClassElement {
public: public:
ClassField(SourceRange source_range, NonnullRefPtr<Expression> key, RefPtr<Expression> init, bool contains_direct_call_to_eval, bool is_static) ClassField(SourceRange source_range, NonnullRefPtr<Expression const> key, RefPtr<Expression const> init, bool contains_direct_call_to_eval, bool is_static)
: ClassElement(source_range, is_static) : ClassElement(source_range, is_static)
, m_key(move(key)) , m_key(move(key))
, m_initializer(move(init)) , m_initializer(move(init))
@ -1348,8 +1346,8 @@ public:
} }
Expression const& key() const { return *m_key; } Expression const& key() const { return *m_key; }
RefPtr<Expression> const& initializer() const { return m_initializer; } RefPtr<Expression const> const& initializer() const { return m_initializer; }
RefPtr<Expression>& initializer() { return m_initializer; } RefPtr<Expression const>& initializer() { return m_initializer; }
virtual ElementKind class_element_kind() const override { return ElementKind::Field; } virtual ElementKind class_element_kind() const override { return ElementKind::Field; }
@ -1358,8 +1356,8 @@ public:
virtual Optional<DeprecatedFlyString> private_bound_identifier() const override; virtual Optional<DeprecatedFlyString> private_bound_identifier() const override;
private: private:
NonnullRefPtr<Expression> m_key; NonnullRefPtr<Expression const> m_key;
RefPtr<Expression> m_initializer; RefPtr<Expression const> m_initializer;
bool m_contains_direct_call_to_eval { false }; bool m_contains_direct_call_to_eval { false };
}; };
@ -1397,7 +1395,7 @@ public:
class ClassExpression final : public Expression { class ClassExpression final : public Expression {
public: public:
ClassExpression(SourceRange source_range, DeprecatedString name, DeprecatedString source_text, RefPtr<FunctionExpression> constructor, RefPtr<Expression> super_class, NonnullRefPtrVector<ClassElement> elements) ClassExpression(SourceRange source_range, DeprecatedString name, DeprecatedString source_text, RefPtr<FunctionExpression const> constructor, RefPtr<Expression const> super_class, NonnullRefPtrVector<ClassElement const> elements)
: Expression(source_range) : Expression(source_range)
, m_name(move(name)) , m_name(move(name))
, m_source_text(move(source_text)) , m_source_text(move(source_text))
@ -1409,7 +1407,7 @@ public:
StringView name() const { return m_name; } StringView name() const { return m_name; }
DeprecatedString const& source_text() const { return m_source_text; } DeprecatedString const& source_text() const { return m_source_text; }
RefPtr<FunctionExpression> constructor() const { return m_constructor; } RefPtr<FunctionExpression const> constructor() const { return m_constructor; }
virtual Completion execute(Interpreter&) const override; virtual Completion execute(Interpreter&) const override;
virtual void dump(int indent) const override; virtual void dump(int indent) const override;
@ -1424,14 +1422,14 @@ private:
DeprecatedString m_name; DeprecatedString m_name;
DeprecatedString m_source_text; DeprecatedString m_source_text;
RefPtr<FunctionExpression> m_constructor; RefPtr<FunctionExpression const> m_constructor;
RefPtr<Expression> m_super_class; RefPtr<Expression const> m_super_class;
NonnullRefPtrVector<ClassElement> m_elements; NonnullRefPtrVector<ClassElement const> m_elements;
}; };
class ClassDeclaration final : public Declaration { class ClassDeclaration final : public Declaration {
public: public:
ClassDeclaration(SourceRange source_range, NonnullRefPtr<ClassExpression> class_expression) ClassDeclaration(SourceRange source_range, NonnullRefPtr<ClassExpression const> class_expression)
: Declaration(source_range) : Declaration(source_range)
, m_class_expression(move(class_expression)) , m_class_expression(move(class_expression))
{ {
@ -1452,12 +1450,12 @@ private:
friend ExportStatement; friend ExportStatement;
NonnullRefPtr<ClassExpression> m_class_expression; NonnullRefPtr<ClassExpression const> m_class_expression;
}; };
class SpreadExpression final : public Expression { class SpreadExpression final : public Expression {
public: public:
explicit SpreadExpression(SourceRange source_range, NonnullRefPtr<Expression> target) explicit SpreadExpression(SourceRange source_range, NonnullRefPtr<Expression const> target)
: Expression(source_range) : Expression(source_range)
, m_target(move(target)) , m_target(move(target))
{ {
@ -1468,7 +1466,7 @@ public:
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override; virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override;
private: private:
NonnullRefPtr<Expression> m_target; NonnullRefPtr<Expression const> m_target;
}; };
class ThisExpression final : public Expression { class ThisExpression final : public Expression {
@ -1483,7 +1481,7 @@ public:
}; };
struct CallExpressionArgument { struct CallExpressionArgument {
NonnullRefPtr<Expression> value; NonnullRefPtr<Expression const> value;
bool is_spread; bool is_spread;
}; };
@ -1493,7 +1491,7 @@ class CallExpression : public ASTNodeWithTailArray<CallExpression, Expression, C
public: public:
using Argument = CallExpressionArgument; using Argument = CallExpressionArgument;
static NonnullRefPtr<CallExpression> create(SourceRange, NonnullRefPtr<Expression> callee, ReadonlySpan<Argument> arguments); static NonnullRefPtr<CallExpression> create(SourceRange, NonnullRefPtr<Expression const> callee, ReadonlySpan<Argument> arguments);
virtual Completion execute(Interpreter&) const override; virtual Completion execute(Interpreter&) const override;
virtual void dump(int indent) const override; virtual void dump(int indent) const override;
@ -1504,7 +1502,7 @@ public:
ReadonlySpan<Argument> arguments() const { return tail_span(); } ReadonlySpan<Argument> arguments() const { return tail_span(); }
protected: protected:
CallExpression(SourceRange source_range, NonnullRefPtr<Expression> callee, ReadonlySpan<Argument> arguments) CallExpression(SourceRange source_range, NonnullRefPtr<Expression const> callee, ReadonlySpan<Argument> arguments)
: ASTNodeWithTailArray(move(source_range), arguments) : ASTNodeWithTailArray(move(source_range), arguments)
, m_callee(move(callee)) , m_callee(move(callee))
{ {
@ -1523,21 +1521,21 @@ protected:
Completion throw_type_error_for_callee(Interpreter&, Value callee_value, StringView call_type) const; Completion throw_type_error_for_callee(Interpreter&, Value callee_value, StringView call_type) const;
Optional<DeprecatedString> expression_string() const; Optional<DeprecatedString> expression_string() const;
NonnullRefPtr<Expression> m_callee; NonnullRefPtr<Expression const> m_callee;
}; };
class NewExpression final : public CallExpression { class NewExpression final : public CallExpression {
friend class ASTNodeWithTailArray; friend class ASTNodeWithTailArray;
public: public:
static NonnullRefPtr<NewExpression> create(SourceRange, NonnullRefPtr<Expression> callee, ReadonlySpan<Argument> arguments); static NonnullRefPtr<NewExpression> create(SourceRange, NonnullRefPtr<Expression const> callee, ReadonlySpan<Argument> arguments);
virtual Completion execute(Interpreter&) const override; virtual Completion execute(Interpreter&) const override;
virtual bool is_new_expression() const override { return true; } virtual bool is_new_expression() const override { return true; }
private: private:
NewExpression(SourceRange source_range, NonnullRefPtr<Expression> callee, ReadonlySpan<Argument> arguments) NewExpression(SourceRange source_range, NonnullRefPtr<Expression const> callee, ReadonlySpan<Argument> arguments)
: CallExpression(move(source_range), move(callee), arguments) : CallExpression(move(source_range), move(callee), arguments)
{ {
} }
@ -1599,7 +1597,7 @@ enum class AssignmentOp {
class AssignmentExpression final : public Expression { class AssignmentExpression final : public Expression {
public: public:
AssignmentExpression(SourceRange source_range, AssignmentOp op, NonnullRefPtr<Expression> lhs, NonnullRefPtr<Expression> rhs) AssignmentExpression(SourceRange source_range, AssignmentOp op, NonnullRefPtr<Expression const> lhs, NonnullRefPtr<Expression const> rhs)
: Expression(source_range) : Expression(source_range)
, m_op(op) , m_op(op)
, m_lhs(move(lhs)) , m_lhs(move(lhs))
@ -1607,7 +1605,7 @@ public:
{ {
} }
AssignmentExpression(SourceRange source_range, AssignmentOp op, NonnullRefPtr<BindingPattern> lhs, NonnullRefPtr<Expression> rhs) AssignmentExpression(SourceRange source_range, AssignmentOp op, NonnullRefPtr<BindingPattern const> lhs, NonnullRefPtr<Expression const> rhs)
: Expression(source_range) : Expression(source_range)
, m_op(op) , m_op(op)
, m_lhs(move(lhs)) , m_lhs(move(lhs))
@ -1621,8 +1619,8 @@ public:
private: private:
AssignmentOp m_op; AssignmentOp m_op;
Variant<NonnullRefPtr<Expression>, NonnullRefPtr<BindingPattern>> m_lhs; Variant<NonnullRefPtr<Expression const>, NonnullRefPtr<BindingPattern const>> m_lhs;
NonnullRefPtr<Expression> m_rhs; NonnullRefPtr<Expression const> m_rhs;
}; };
enum class UpdateOp { enum class UpdateOp {
@ -1632,7 +1630,7 @@ enum class UpdateOp {
class UpdateExpression final : public Expression { class UpdateExpression final : public Expression {
public: public:
UpdateExpression(SourceRange source_range, UpdateOp op, NonnullRefPtr<Expression> argument, bool prefixed = false) UpdateExpression(SourceRange source_range, UpdateOp op, NonnullRefPtr<Expression const> argument, bool prefixed = false)
: Expression(source_range) : Expression(source_range)
, m_op(op) , m_op(op)
, m_argument(move(argument)) , m_argument(move(argument))
@ -1648,7 +1646,7 @@ private:
virtual bool is_update_expression() const override { return true; } virtual bool is_update_expression() const override { return true; }
UpdateOp m_op; UpdateOp m_op;
NonnullRefPtr<Expression> m_argument; NonnullRefPtr<Expression const> m_argument;
bool m_prefixed; bool m_prefixed;
}; };
@ -1660,20 +1658,20 @@ enum class DeclarationKind {
class VariableDeclarator final : public ASTNode { class VariableDeclarator final : public ASTNode {
public: public:
VariableDeclarator(SourceRange source_range, NonnullRefPtr<Identifier> id) VariableDeclarator(SourceRange source_range, NonnullRefPtr<Identifier const> id)
: ASTNode(source_range) : ASTNode(source_range)
, m_target(move(id)) , m_target(move(id))
{ {
} }
VariableDeclarator(SourceRange source_range, NonnullRefPtr<Identifier> target, RefPtr<Expression> init) VariableDeclarator(SourceRange source_range, NonnullRefPtr<Identifier const> target, RefPtr<Expression const> init)
: ASTNode(source_range) : ASTNode(source_range)
, m_target(move(target)) , m_target(move(target))
, m_init(move(init)) , m_init(move(init))
{ {
} }
VariableDeclarator(SourceRange source_range, Variant<NonnullRefPtr<Identifier>, NonnullRefPtr<BindingPattern>> target, RefPtr<Expression> init) VariableDeclarator(SourceRange source_range, Variant<NonnullRefPtr<Identifier const>, NonnullRefPtr<BindingPattern const>> target, RefPtr<Expression const> init)
: ASTNode(source_range) : ASTNode(source_range)
, m_target(move(target)) , m_target(move(target))
, m_init(move(init)) , m_init(move(init))
@ -1687,13 +1685,13 @@ public:
virtual void dump(int indent) const override; virtual void dump(int indent) const override;
private: private:
Variant<NonnullRefPtr<Identifier>, NonnullRefPtr<BindingPattern>> m_target; Variant<NonnullRefPtr<Identifier const>, NonnullRefPtr<BindingPattern const>> m_target;
RefPtr<Expression> m_init; RefPtr<Expression const> m_init;
}; };
class VariableDeclaration final : public Declaration { class VariableDeclaration final : public Declaration {
public: public:
VariableDeclaration(SourceRange source_range, DeclarationKind declaration_kind, NonnullRefPtrVector<VariableDeclarator> declarations) VariableDeclaration(SourceRange source_range, DeclarationKind declaration_kind, NonnullRefPtrVector<VariableDeclarator const> declarations)
: Declaration(source_range) : Declaration(source_range)
, m_declaration_kind(declaration_kind) , m_declaration_kind(declaration_kind)
, m_declarations(move(declarations)) , m_declarations(move(declarations))
@ -1706,7 +1704,7 @@ public:
virtual void dump(int indent) const override; virtual void dump(int indent) const override;
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override; virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override;
NonnullRefPtrVector<VariableDeclarator> const& declarations() const { return m_declarations; } NonnullRefPtrVector<VariableDeclarator const> const& declarations() const { return m_declarations; }
virtual ThrowCompletionOr<void> for_each_bound_name(ThrowCompletionOrVoidCallback<DeprecatedFlyString const&>&& callback) const override; virtual ThrowCompletionOr<void> for_each_bound_name(ThrowCompletionOrVoidCallback<DeprecatedFlyString const&>&& callback) const override;
@ -1718,12 +1716,12 @@ private:
virtual bool is_variable_declaration() const override { return true; } virtual bool is_variable_declaration() const override { return true; }
DeclarationKind m_declaration_kind; DeclarationKind m_declaration_kind;
NonnullRefPtrVector<VariableDeclarator> m_declarations; NonnullRefPtrVector<VariableDeclarator const> m_declarations;
}; };
class UsingDeclaration final : public Declaration { class UsingDeclaration final : public Declaration {
public: public:
UsingDeclaration(SourceRange source_range, NonnullRefPtrVector<VariableDeclarator> declarations) UsingDeclaration(SourceRange source_range, NonnullRefPtrVector<VariableDeclarator const> declarations)
: Declaration(move(source_range)) : Declaration(move(source_range))
, m_declarations(move(declarations)) , m_declarations(move(declarations))
{ {
@ -1738,10 +1736,10 @@ public:
virtual bool is_lexical_declaration() const override { return true; } virtual bool is_lexical_declaration() const override { return true; }
NonnullRefPtrVector<VariableDeclarator> const& declarations() const { return m_declarations; } NonnullRefPtrVector<VariableDeclarator const> const& declarations() const { return m_declarations; }
private: private:
NonnullRefPtrVector<VariableDeclarator> m_declarations; NonnullRefPtrVector<VariableDeclarator const> m_declarations;
}; };
class ObjectProperty final : public ASTNode { class ObjectProperty final : public ASTNode {
@ -1754,7 +1752,7 @@ public:
ProtoSetter, ProtoSetter,
}; };
ObjectProperty(SourceRange source_range, NonnullRefPtr<Expression> key, RefPtr<Expression> value, Type property_type, bool is_method) ObjectProperty(SourceRange source_range, NonnullRefPtr<Expression const> key, RefPtr<Expression const> value, Type property_type, bool is_method)
: ASTNode(source_range) : ASTNode(source_range)
, m_property_type(property_type) , m_property_type(property_type)
, m_is_method(is_method) , m_is_method(is_method)
@ -1779,8 +1777,8 @@ public:
private: private:
Type m_property_type; Type m_property_type;
bool m_is_method { false }; bool m_is_method { false };
NonnullRefPtr<Expression> m_key; NonnullRefPtr<Expression const> m_key;
RefPtr<Expression> m_value; RefPtr<Expression const> m_value;
}; };
class ObjectExpression final : public Expression { class ObjectExpression final : public Expression {
@ -1803,13 +1801,13 @@ private:
class ArrayExpression final : public Expression { class ArrayExpression final : public Expression {
public: public:
ArrayExpression(SourceRange source_range, Vector<RefPtr<Expression>> elements) ArrayExpression(SourceRange source_range, Vector<RefPtr<Expression const>> elements)
: Expression(source_range) : Expression(source_range)
, m_elements(move(elements)) , m_elements(move(elements))
{ {
} }
Vector<RefPtr<Expression>> const& elements() const { return m_elements; } Vector<RefPtr<Expression const>> const& elements() const { return m_elements; }
virtual Completion execute(Interpreter&) const override; virtual Completion execute(Interpreter&) const override;
virtual void dump(int indent) const override; virtual void dump(int indent) const override;
@ -1818,18 +1816,18 @@ public:
private: private:
virtual bool is_array_expression() const override { return true; } virtual bool is_array_expression() const override { return true; }
Vector<RefPtr<Expression>> m_elements; Vector<RefPtr<Expression const>> m_elements;
}; };
class TemplateLiteral final : public Expression { class TemplateLiteral final : public Expression {
public: public:
TemplateLiteral(SourceRange source_range, NonnullRefPtrVector<Expression> expressions) TemplateLiteral(SourceRange source_range, NonnullRefPtrVector<Expression const> expressions)
: Expression(source_range) : Expression(source_range)
, m_expressions(move(expressions)) , m_expressions(move(expressions))
{ {
} }
TemplateLiteral(SourceRange source_range, NonnullRefPtrVector<Expression> expressions, NonnullRefPtrVector<Expression> raw_strings) TemplateLiteral(SourceRange source_range, NonnullRefPtrVector<Expression const> expressions, NonnullRefPtrVector<Expression const> raw_strings)
: Expression(source_range) : Expression(source_range)
, m_expressions(move(expressions)) , m_expressions(move(expressions))
, m_raw_strings(move(raw_strings)) , m_raw_strings(move(raw_strings))
@ -1840,17 +1838,17 @@ public:
virtual void dump(int indent) const override; virtual void dump(int indent) const override;
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override; virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override;
NonnullRefPtrVector<Expression> const& expressions() const { return m_expressions; } NonnullRefPtrVector<Expression const> const& expressions() const { return m_expressions; }
NonnullRefPtrVector<Expression> const& raw_strings() const { return m_raw_strings; } NonnullRefPtrVector<Expression const> const& raw_strings() const { return m_raw_strings; }
private: private:
NonnullRefPtrVector<Expression> const m_expressions; NonnullRefPtrVector<Expression const> const m_expressions;
NonnullRefPtrVector<Expression> const m_raw_strings; NonnullRefPtrVector<Expression const> const m_raw_strings;
}; };
class TaggedTemplateLiteral final : public Expression { class TaggedTemplateLiteral final : public Expression {
public: public:
TaggedTemplateLiteral(SourceRange source_range, NonnullRefPtr<Expression> tag, NonnullRefPtr<TemplateLiteral> template_literal) TaggedTemplateLiteral(SourceRange source_range, NonnullRefPtr<Expression const> tag, NonnullRefPtr<TemplateLiteral const> template_literal)
: Expression(source_range) : Expression(source_range)
, m_tag(move(tag)) , m_tag(move(tag))
, m_template_literal(move(template_literal)) , m_template_literal(move(template_literal))
@ -1864,14 +1862,14 @@ public:
ThrowCompletionOr<Value> get_template_object(Interpreter&) const; ThrowCompletionOr<Value> get_template_object(Interpreter&) const;
private: private:
NonnullRefPtr<Expression> const m_tag; NonnullRefPtr<Expression const> const m_tag;
NonnullRefPtr<TemplateLiteral> const m_template_literal; NonnullRefPtr<TemplateLiteral const> const m_template_literal;
mutable HashMap<Realm*, Handle<Array>> m_cached_values; mutable HashMap<Realm*, Handle<Array>> m_cached_values;
}; };
class MemberExpression final : public Expression { class MemberExpression final : public Expression {
public: public:
MemberExpression(SourceRange source_range, NonnullRefPtr<Expression> object, NonnullRefPtr<Expression> property, bool computed = false) MemberExpression(SourceRange source_range, NonnullRefPtr<Expression const> object, NonnullRefPtr<Expression const> property, bool computed = false)
: Expression(source_range) : Expression(source_range)
, m_computed(computed) , m_computed(computed)
, m_object(move(object)) , m_object(move(object))
@ -1896,8 +1894,8 @@ private:
virtual bool is_member_expression() const override { return true; } virtual bool is_member_expression() const override { return true; }
bool m_computed { false }; bool m_computed { false };
NonnullRefPtr<Expression> m_object; NonnullRefPtr<Expression const> m_object;
NonnullRefPtr<Expression> m_property; NonnullRefPtr<Expression const> m_property;
}; };
class OptionalChain final : public Expression { class OptionalChain final : public Expression {
@ -1912,21 +1910,21 @@ public:
Mode mode; Mode mode;
}; };
struct ComputedReference { struct ComputedReference {
NonnullRefPtr<Expression> expression; NonnullRefPtr<Expression const> expression;
Mode mode; Mode mode;
}; };
struct MemberReference { struct MemberReference {
NonnullRefPtr<Identifier> identifier; NonnullRefPtr<Identifier const> identifier;
Mode mode; Mode mode;
}; };
struct PrivateMemberReference { struct PrivateMemberReference {
NonnullRefPtr<PrivateIdentifier> private_identifier; NonnullRefPtr<PrivateIdentifier const> private_identifier;
Mode mode; Mode mode;
}; };
using Reference = Variant<Call, ComputedReference, MemberReference, PrivateMemberReference>; using Reference = Variant<Call, ComputedReference, MemberReference, PrivateMemberReference>;
OptionalChain(SourceRange source_range, NonnullRefPtr<Expression> base, Vector<Reference> references) OptionalChain(SourceRange source_range, NonnullRefPtr<Expression const> base, Vector<Reference> references)
: Expression(source_range) : Expression(source_range)
, m_base(move(base)) , m_base(move(base))
, m_references(move(references)) , m_references(move(references))
@ -1944,7 +1942,7 @@ private:
}; };
ThrowCompletionOr<ReferenceAndValue> to_reference_and_value(Interpreter&) const; ThrowCompletionOr<ReferenceAndValue> to_reference_and_value(Interpreter&) const;
NonnullRefPtr<Expression> m_base; NonnullRefPtr<Expression const> m_base;
Vector<Reference> m_references; Vector<Reference> m_references;
}; };
@ -1971,7 +1969,7 @@ private:
class ImportCall final : public Expression { class ImportCall final : public Expression {
public: public:
ImportCall(SourceRange source_range, NonnullRefPtr<Expression> specifier, RefPtr<Expression> options) ImportCall(SourceRange source_range, NonnullRefPtr<Expression const> specifier, RefPtr<Expression const> options)
: Expression(source_range) : Expression(source_range)
, m_specifier(move(specifier)) , m_specifier(move(specifier))
, m_options(move(options)) , m_options(move(options))
@ -1984,13 +1982,13 @@ public:
private: private:
virtual bool is_import_call() const override { return true; } virtual bool is_import_call() const override { return true; }
NonnullRefPtr<Expression> m_specifier; NonnullRefPtr<Expression const> m_specifier;
RefPtr<Expression> m_options; RefPtr<Expression const> m_options;
}; };
class ConditionalExpression final : public Expression { class ConditionalExpression final : public Expression {
public: public:
ConditionalExpression(SourceRange source_range, NonnullRefPtr<Expression> test, NonnullRefPtr<Expression> consequent, NonnullRefPtr<Expression> alternate) ConditionalExpression(SourceRange source_range, NonnullRefPtr<Expression const> test, NonnullRefPtr<Expression const> consequent, NonnullRefPtr<Expression const> alternate)
: Expression(source_range) : Expression(source_range)
, m_test(move(test)) , m_test(move(test))
, m_consequent(move(consequent)) , m_consequent(move(consequent))
@ -2003,21 +2001,21 @@ public:
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override; virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override;
private: private:
NonnullRefPtr<Expression> m_test; NonnullRefPtr<Expression const> m_test;
NonnullRefPtr<Expression> m_consequent; NonnullRefPtr<Expression const> m_consequent;
NonnullRefPtr<Expression> m_alternate; NonnullRefPtr<Expression const> m_alternate;
}; };
class CatchClause final : public ASTNode { class CatchClause final : public ASTNode {
public: public:
CatchClause(SourceRange source_range, DeprecatedFlyString parameter, NonnullRefPtr<BlockStatement> body) CatchClause(SourceRange source_range, DeprecatedFlyString parameter, NonnullRefPtr<BlockStatement const> body)
: ASTNode(source_range) : ASTNode(source_range)
, m_parameter(move(parameter)) , m_parameter(move(parameter))
, m_body(move(body)) , m_body(move(body))
{ {
} }
CatchClause(SourceRange source_range, NonnullRefPtr<BindingPattern> parameter, NonnullRefPtr<BlockStatement> body) CatchClause(SourceRange source_range, NonnullRefPtr<BindingPattern const> parameter, NonnullRefPtr<BlockStatement const> body)
: ASTNode(source_range) : ASTNode(source_range)
, m_parameter(move(parameter)) , m_parameter(move(parameter))
, m_body(move(body)) , m_body(move(body))
@ -2031,13 +2029,13 @@ public:
virtual Completion execute(Interpreter&) const override; virtual Completion execute(Interpreter&) const override;
private: private:
Variant<DeprecatedFlyString, NonnullRefPtr<BindingPattern>> m_parameter; Variant<DeprecatedFlyString, NonnullRefPtr<BindingPattern const>> m_parameter;
NonnullRefPtr<BlockStatement> m_body; NonnullRefPtr<BlockStatement const> m_body;
}; };
class TryStatement final : public Statement { class TryStatement final : public Statement {
public: public:
TryStatement(SourceRange source_range, NonnullRefPtr<BlockStatement> block, RefPtr<CatchClause> handler, RefPtr<BlockStatement> finalizer) TryStatement(SourceRange source_range, NonnullRefPtr<BlockStatement const> block, RefPtr<CatchClause const> handler, RefPtr<BlockStatement const> finalizer)
: Statement(source_range) : Statement(source_range)
, m_block(move(block)) , m_block(move(block))
, m_handler(move(handler)) , m_handler(move(handler))
@ -2054,14 +2052,14 @@ public:
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override; virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override;
private: private:
NonnullRefPtr<BlockStatement> m_block; NonnullRefPtr<BlockStatement const> m_block;
RefPtr<CatchClause> m_handler; RefPtr<CatchClause const> m_handler;
RefPtr<BlockStatement> m_finalizer; RefPtr<BlockStatement const> m_finalizer;
}; };
class ThrowStatement final : public Statement { class ThrowStatement final : public Statement {
public: public:
explicit ThrowStatement(SourceRange source_range, NonnullRefPtr<Expression> argument) explicit ThrowStatement(SourceRange source_range, NonnullRefPtr<Expression const> argument)
: Statement(source_range) : Statement(source_range)
, m_argument(move(argument)) , m_argument(move(argument))
{ {
@ -2074,12 +2072,12 @@ public:
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override; virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override;
private: private:
NonnullRefPtr<Expression> m_argument; NonnullRefPtr<Expression const> m_argument;
}; };
class SwitchCase final : public ScopeNode { class SwitchCase final : public ScopeNode {
public: public:
SwitchCase(SourceRange source_range, RefPtr<Expression> test) SwitchCase(SourceRange source_range, RefPtr<Expression const> test)
: ScopeNode(source_range) : ScopeNode(source_range)
, m_test(move(test)) , m_test(move(test))
{ {
@ -2091,12 +2089,12 @@ public:
virtual Completion execute(Interpreter&) const override; virtual Completion execute(Interpreter&) const override;
private: private:
RefPtr<Expression> m_test; RefPtr<Expression const> m_test;
}; };
class SwitchStatement final : public ScopeNode { class SwitchStatement final : public ScopeNode {
public: public:
SwitchStatement(SourceRange source_range, NonnullRefPtr<Expression> discriminant) SwitchStatement(SourceRange source_range, NonnullRefPtr<Expression const> discriminant)
: ScopeNode(source_range) : ScopeNode(source_range)
, m_discriminant(move(discriminant)) , m_discriminant(move(discriminant))
{ {
@ -2108,11 +2106,11 @@ public:
virtual Bytecode::CodeGenerationErrorOr<void> generate_labelled_evaluation(Bytecode::Generator&, Vector<DeprecatedFlyString> const&) const; virtual Bytecode::CodeGenerationErrorOr<void> generate_labelled_evaluation(Bytecode::Generator&, Vector<DeprecatedFlyString> const&) const;
Completion execute_impl(Interpreter&) const; Completion execute_impl(Interpreter&) const;
void add_case(NonnullRefPtr<SwitchCase> switch_case) { m_cases.append(move(switch_case)); } void add_case(NonnullRefPtr<SwitchCase const> switch_case) { m_cases.append(move(switch_case)); }
private: private:
NonnullRefPtr<Expression> m_discriminant; NonnullRefPtr<Expression const> m_discriminant;
NonnullRefPtrVector<SwitchCase> m_cases; NonnullRefPtrVector<SwitchCase const> m_cases;
}; };
class BreakStatement final : public Statement { class BreakStatement final : public Statement {

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2021, Andreas Kling <kling@serenityos.org> * Copyright (c) 2021-2023, Andreas Kling <kling@serenityos.org>
* Copyright (c) 2021, Linus Groh <linusg@serenityos.org> * Copyright (c) 2021, Linus Groh <linusg@serenityos.org>
* Copyright (c) 2021, Gunnar Beutner <gbeutner@serenityos.org> * Copyright (c) 2021, Gunnar Beutner <gbeutner@serenityos.org>
* Copyright (c) 2021, Marcin Gasperowicz <xnooga@gmail.com> * Copyright (c) 2021, Marcin Gasperowicz <xnooga@gmail.com>
@ -603,7 +603,7 @@ Bytecode::CodeGenerationErrorOr<void> AssignmentExpression::generate_bytecode(By
// AssignmentExpression : LeftHandSideExpression = AssignmentExpression // AssignmentExpression : LeftHandSideExpression = AssignmentExpression
return m_lhs.visit( return m_lhs.visit(
// 1. If LeftHandSideExpression is neither an ObjectLiteral nor an ArrayLiteral, then // 1. If LeftHandSideExpression is neither an ObjectLiteral nor an ArrayLiteral, then
[&](NonnullRefPtr<Expression> const& lhs) -> Bytecode::CodeGenerationErrorOr<void> { [&](NonnullRefPtr<Expression const> const& lhs) -> Bytecode::CodeGenerationErrorOr<void> {
// a. Let lref be the result of evaluating LeftHandSideExpression. // a. Let lref be the result of evaluating LeftHandSideExpression.
// b. ReturnIfAbrupt(lref). // b. ReturnIfAbrupt(lref).
Optional<Bytecode::Register> base_object_register; Optional<Bytecode::Register> base_object_register;
@ -675,7 +675,7 @@ Bytecode::CodeGenerationErrorOr<void> AssignmentExpression::generate_bytecode(By
return {}; return {};
}, },
// 2. Let assignmentPattern be the AssignmentPattern that is covered by LeftHandSideExpression. // 2. Let assignmentPattern be the AssignmentPattern that is covered by LeftHandSideExpression.
[&](NonnullRefPtr<BindingPattern> const& pattern) -> Bytecode::CodeGenerationErrorOr<void> { [&](NonnullRefPtr<BindingPattern const> const& pattern) -> Bytecode::CodeGenerationErrorOr<void> {
// 3. Let rref be the result of evaluating AssignmentExpression. // 3. Let rref be the result of evaluating AssignmentExpression.
// 4. Let rval be ? GetValue(rref). // 4. Let rval be ? GetValue(rref).
TRY(m_rhs->generate_bytecode(generator)); TRY(m_rhs->generate_bytecode(generator));
@ -691,8 +691,8 @@ Bytecode::CodeGenerationErrorOr<void> AssignmentExpression::generate_bytecode(By
}); });
} }
VERIFY(m_lhs.has<NonnullRefPtr<Expression>>()); VERIFY(m_lhs.has<NonnullRefPtr<Expression const>>());
auto& lhs = m_lhs.get<NonnullRefPtr<Expression>>(); auto& lhs = m_lhs.get<NonnullRefPtr<Expression const>>();
TRY(generator.emit_load_from_reference(lhs)); TRY(generator.emit_load_from_reference(lhs));
@ -1219,11 +1219,11 @@ static Bytecode::CodeGenerationErrorOr<void> generate_object_binding_pattern_byt
for (auto& [name, alias, initializer, is_rest] : pattern.entries) { for (auto& [name, alias, initializer, is_rest] : pattern.entries) {
if (is_rest) { if (is_rest) {
VERIFY(name.has<NonnullRefPtr<Identifier>>()); VERIFY(name.has<NonnullRefPtr<Identifier const>>());
VERIFY(alias.has<Empty>()); VERIFY(alias.has<Empty>());
VERIFY(!initializer); VERIFY(!initializer);
auto identifier = name.get<NonnullRefPtr<Identifier>>()->string(); auto identifier = name.get<NonnullRefPtr<Identifier const>>()->string();
auto interned_identifier = generator.intern_identifier(identifier); auto interned_identifier = generator.intern_identifier(identifier);
generator.emit_with_extra_register_slots<Bytecode::Op::CopyObjectExcludingProperties>(excluded_property_names.size(), value_reg, excluded_property_names); generator.emit_with_extra_register_slots<Bytecode::Op::CopyObjectExcludingProperties>(excluded_property_names.size(), value_reg, excluded_property_names);
@ -1234,8 +1234,8 @@ static Bytecode::CodeGenerationErrorOr<void> generate_object_binding_pattern_byt
Bytecode::StringTableIndex name_index; Bytecode::StringTableIndex name_index;
if (name.has<NonnullRefPtr<Identifier>>()) { if (name.has<NonnullRefPtr<Identifier const>>()) {
auto identifier = name.get<NonnullRefPtr<Identifier>>()->string(); auto identifier = name.get<NonnullRefPtr<Identifier const>>()->string();
name_index = generator.intern_string(identifier); name_index = generator.intern_string(identifier);
if (has_rest) { if (has_rest) {
@ -1248,7 +1248,7 @@ static Bytecode::CodeGenerationErrorOr<void> generate_object_binding_pattern_byt
generator.emit<Bytecode::Op::Load>(value_reg); generator.emit<Bytecode::Op::Load>(value_reg);
generator.emit<Bytecode::Op::GetById>(generator.intern_identifier(identifier)); generator.emit<Bytecode::Op::GetById>(generator.intern_identifier(identifier));
} else { } else {
auto expression = name.get<NonnullRefPtr<Expression>>(); auto expression = name.get<NonnullRefPtr<Expression const>>();
TRY(expression->generate_bytecode(generator)); TRY(expression->generate_bytecode(generator));
if (has_rest) { if (has_rest) {
@ -1277,24 +1277,24 @@ static Bytecode::CodeGenerationErrorOr<void> generate_object_binding_pattern_byt
generator.switch_to_basic_block(if_not_undefined_block); generator.switch_to_basic_block(if_not_undefined_block);
} }
if (alias.has<NonnullRefPtr<BindingPattern>>()) { if (alias.has<NonnullRefPtr<BindingPattern const>>()) {
auto& binding_pattern = *alias.get<NonnullRefPtr<BindingPattern>>(); auto& binding_pattern = *alias.get<NonnullRefPtr<BindingPattern const>>();
auto nested_value_reg = generator.allocate_register(); auto nested_value_reg = generator.allocate_register();
generator.emit<Bytecode::Op::Store>(nested_value_reg); generator.emit<Bytecode::Op::Store>(nested_value_reg);
TRY(generate_binding_pattern_bytecode(generator, binding_pattern, initialization_mode, nested_value_reg)); TRY(generate_binding_pattern_bytecode(generator, binding_pattern, initialization_mode, nested_value_reg));
} else if (alias.has<Empty>()) { } else if (alias.has<Empty>()) {
if (name.has<NonnullRefPtr<Expression>>()) { if (name.has<NonnullRefPtr<Expression const>>()) {
// This needs some sort of SetVariableByValue opcode, as it's a runtime binding // This needs some sort of SetVariableByValue opcode, as it's a runtime binding
return Bytecode::CodeGenerationError { return Bytecode::CodeGenerationError {
name.get<NonnullRefPtr<Expression>>().ptr(), name.get<NonnullRefPtr<Expression const>>().ptr(),
"Unimplemented name/alias pair: Empty/Expression"sv, "Unimplemented name/alias pair: Empty/Expression"sv,
}; };
} }
auto& identifier = name.get<NonnullRefPtr<Identifier>>()->string(); auto& identifier = name.get<NonnullRefPtr<Identifier const>>()->string();
generator.emit<Bytecode::Op::SetVariable>(generator.intern_identifier(identifier), initialization_mode); generator.emit<Bytecode::Op::SetVariable>(generator.intern_identifier(identifier), initialization_mode);
} else { } else {
auto& identifier = alias.get<NonnullRefPtr<Identifier>>()->string(); auto& identifier = alias.get<NonnullRefPtr<Identifier const>>()->string();
generator.emit<Bytecode::Op::SetVariable>(generator.intern_identifier(identifier), initialization_mode); generator.emit<Bytecode::Op::SetVariable>(generator.intern_identifier(identifier), initialization_mode);
} }
} }
@ -1340,18 +1340,18 @@ static Bytecode::CodeGenerationErrorOr<void> generate_array_binding_pattern_byte
// This element is an elision // This element is an elision
return {}; return {};
}, },
[&](NonnullRefPtr<Identifier> const& identifier) -> Bytecode::CodeGenerationErrorOr<void> { [&](NonnullRefPtr<Identifier const> const& identifier) -> Bytecode::CodeGenerationErrorOr<void> {
auto interned_index = generator.intern_identifier(identifier->string()); auto interned_index = generator.intern_identifier(identifier->string());
generator.emit<Bytecode::Op::SetVariable>(interned_index, initialization_mode); generator.emit<Bytecode::Op::SetVariable>(interned_index, initialization_mode);
return {}; return {};
}, },
[&](NonnullRefPtr<BindingPattern> const& pattern) -> Bytecode::CodeGenerationErrorOr<void> { [&](NonnullRefPtr<BindingPattern const> const& pattern) -> Bytecode::CodeGenerationErrorOr<void> {
// Store the accumulator value in a permanent register // Store the accumulator value in a permanent register
auto target_reg = generator.allocate_register(); auto target_reg = generator.allocate_register();
generator.emit<Bytecode::Op::Store>(target_reg); generator.emit<Bytecode::Op::Store>(target_reg);
return generate_binding_pattern_bytecode(generator, pattern, initialization_mode, target_reg); return generate_binding_pattern_bytecode(generator, pattern, initialization_mode, target_reg);
}, },
[&](NonnullRefPtr<MemberExpression> const& expr) -> Bytecode::CodeGenerationErrorOr<void> { [&](NonnullRefPtr<MemberExpression const> const& expr) -> Bytecode::CodeGenerationErrorOr<void> {
return generator.emit_store_to_reference(*expr); return generator.emit_store_to_reference(*expr);
}); });
}; };
@ -1487,11 +1487,11 @@ static Bytecode::CodeGenerationErrorOr<void> assign_accumulator_to_variable_decl
auto environment_mode = declaration.is_lexical_declaration() ? Bytecode::Op::EnvironmentMode::Lexical : Bytecode::Op::EnvironmentMode::Var; auto environment_mode = declaration.is_lexical_declaration() ? Bytecode::Op::EnvironmentMode::Lexical : Bytecode::Op::EnvironmentMode::Var;
return declarator.target().visit( return declarator.target().visit(
[&](NonnullRefPtr<Identifier> const& id) -> Bytecode::CodeGenerationErrorOr<void> { [&](NonnullRefPtr<Identifier const> const& id) -> Bytecode::CodeGenerationErrorOr<void> {
generator.emit<Bytecode::Op::SetVariable>(generator.intern_identifier(id->string()), initialization_mode, environment_mode); generator.emit<Bytecode::Op::SetVariable>(generator.intern_identifier(id->string()), initialization_mode, environment_mode);
return {}; return {};
}, },
[&](NonnullRefPtr<BindingPattern> const& pattern) -> Bytecode::CodeGenerationErrorOr<void> { [&](NonnullRefPtr<BindingPattern const> const& pattern) -> Bytecode::CodeGenerationErrorOr<void> {
auto value_register = generator.allocate_register(); auto value_register = generator.allocate_register();
generator.emit<Bytecode::Op::Store>(value_register); generator.emit<Bytecode::Op::Store>(value_register);
return generate_binding_pattern_bytecode(generator, pattern, initialization_mode, value_register); return generate_binding_pattern_bytecode(generator, pattern, initialization_mode, value_register);
@ -2224,7 +2224,7 @@ Bytecode::CodeGenerationErrorOr<void> TryStatement::generate_bytecode(Bytecode::
} }
return {}; return {};
}, },
[&](NonnullRefPtr<BindingPattern> const&) -> Bytecode::CodeGenerationErrorOr<void> { [&](NonnullRefPtr<BindingPattern const> const&) -> Bytecode::CodeGenerationErrorOr<void> {
// FIXME: Implement this path when the above DeclarativeEnvironment issue is dealt with. // FIXME: Implement this path when the above DeclarativeEnvironment issue is dealt with.
return Bytecode::CodeGenerationError { return Bytecode::CodeGenerationError {
this, this,
@ -2422,12 +2422,12 @@ struct ForInOfHeadEvaluationResult {
bool is_destructuring { false }; bool is_destructuring { false };
LHSKind lhs_kind { LHSKind::Assignment }; LHSKind lhs_kind { LHSKind::Assignment };
}; };
static Bytecode::CodeGenerationErrorOr<ForInOfHeadEvaluationResult> for_in_of_head_evaluation(Bytecode::Generator& generator, IterationKind iteration_kind, Variant<NonnullRefPtr<ASTNode>, NonnullRefPtr<BindingPattern>> const& lhs, NonnullRefPtr<ASTNode> const& rhs) static Bytecode::CodeGenerationErrorOr<ForInOfHeadEvaluationResult> for_in_of_head_evaluation(Bytecode::Generator& generator, IterationKind iteration_kind, Variant<NonnullRefPtr<ASTNode const>, NonnullRefPtr<BindingPattern const>> const& lhs, NonnullRefPtr<ASTNode const> const& rhs)
{ {
ForInOfHeadEvaluationResult result {}; ForInOfHeadEvaluationResult result {};
bool entered_lexical_scope = false; bool entered_lexical_scope = false;
if (auto* ast_ptr = lhs.get_pointer<NonnullRefPtr<ASTNode>>(); ast_ptr && is<VariableDeclaration>(**ast_ptr)) { if (auto* ast_ptr = lhs.get_pointer<NonnullRefPtr<ASTNode const>>(); ast_ptr && is<VariableDeclaration>(**ast_ptr)) {
// Runtime Semantics: ForInOfLoopEvaluation, for any of: // Runtime Semantics: ForInOfLoopEvaluation, for any of:
// ForInOfStatement : for ( var ForBinding in Expression ) Statement // ForInOfStatement : for ( var ForBinding in Expression ) Statement
// ForInOfStatement : for ( ForDeclaration in Expression ) Statement // ForInOfStatement : for ( ForDeclaration in Expression ) Statement
@ -2435,7 +2435,7 @@ static Bytecode::CodeGenerationErrorOr<ForInOfHeadEvaluationResult> for_in_of_he
// ForInOfStatement : for ( ForDeclaration of AssignmentExpression ) Statement // ForInOfStatement : for ( ForDeclaration of AssignmentExpression ) Statement
auto& variable_declaration = static_cast<VariableDeclaration const&>(**ast_ptr); auto& variable_declaration = static_cast<VariableDeclaration const&>(**ast_ptr);
result.is_destructuring = variable_declaration.declarations().first().target().has<NonnullRefPtr<BindingPattern>>(); result.is_destructuring = variable_declaration.declarations().first().target().has<NonnullRefPtr<BindingPattern const>>();
result.lhs_kind = variable_declaration.is_lexical_declaration() ? LHSKind::LexicalBinding : LHSKind::VarBinding; result.lhs_kind = variable_declaration.is_lexical_declaration() ? LHSKind::LexicalBinding : LHSKind::VarBinding;
// 1. Let oldEnv be the running execution context's LexicalEnvironment. // 1. Let oldEnv be the running execution context's LexicalEnvironment.
@ -2516,7 +2516,7 @@ static Bytecode::CodeGenerationErrorOr<ForInOfHeadEvaluationResult> for_in_of_he
} }
// 14.7.5.7 ForIn/OfBodyEvaluation ( lhs, stmt, iteratorRecord, iterationKind, lhsKind, labelSet [ , iteratorKind ] ), https://tc39.es/ecma262/#sec-runtime-semantics-forin-div-ofbodyevaluation-lhs-stmt-iterator-lhskind-labelset // 14.7.5.7 ForIn/OfBodyEvaluation ( lhs, stmt, iteratorRecord, iterationKind, lhsKind, labelSet [ , iteratorKind ] ), https://tc39.es/ecma262/#sec-runtime-semantics-forin-div-ofbodyevaluation-lhs-stmt-iterator-lhskind-labelset
static Bytecode::CodeGenerationErrorOr<void> for_in_of_body_evaluation(Bytecode::Generator& generator, ASTNode const& node, Variant<NonnullRefPtr<ASTNode>, NonnullRefPtr<BindingPattern>> const& lhs, ASTNode const& body, ForInOfHeadEvaluationResult const& head_result, Vector<DeprecatedFlyString> const& label_set, Bytecode::BasicBlock& loop_end, Bytecode::BasicBlock& loop_update) static Bytecode::CodeGenerationErrorOr<void> for_in_of_body_evaluation(Bytecode::Generator& generator, ASTNode const& node, Variant<NonnullRefPtr<ASTNode const>, NonnullRefPtr<BindingPattern const>> const& lhs, ASTNode const& body, ForInOfHeadEvaluationResult const& head_result, Vector<DeprecatedFlyString> const& label_set, Bytecode::BasicBlock& loop_end, Bytecode::BasicBlock& loop_update)
{ {
auto iterator_register = generator.allocate_register(); auto iterator_register = generator.allocate_register();
generator.emit<Bytecode::Op::Store>(iterator_register); generator.emit<Bytecode::Op::Store>(iterator_register);
@ -2579,14 +2579,14 @@ static Bytecode::CodeGenerationErrorOr<void> for_in_of_body_evaluation(Bytecode:
// 1. Let lhsRef be the result of evaluating lhs. (It may be evaluated repeatedly.) // 1. Let lhsRef be the result of evaluating lhs. (It may be evaluated repeatedly.)
// NOTE: We're skipping all the completion stuff that the spec does, as the unwinding mechanism will take case of doing that. // NOTE: We're skipping all the completion stuff that the spec does, as the unwinding mechanism will take case of doing that.
if (head_result.lhs_kind == LHSKind::VarBinding) { if (head_result.lhs_kind == LHSKind::VarBinding) {
auto& declaration = static_cast<VariableDeclaration const&>(*lhs.get<NonnullRefPtr<ASTNode>>()); auto& declaration = static_cast<VariableDeclaration const&>(*lhs.get<NonnullRefPtr<ASTNode const>>());
VERIFY(declaration.declarations().size() == 1); VERIFY(declaration.declarations().size() == 1);
TRY(assign_accumulator_to_variable_declarator(generator, declaration.declarations().first(), declaration)); TRY(assign_accumulator_to_variable_declarator(generator, declaration.declarations().first(), declaration));
} else { } else {
if (auto ptr = lhs.get_pointer<NonnullRefPtr<ASTNode>>()) { if (auto ptr = lhs.get_pointer<NonnullRefPtr<ASTNode const>>()) {
TRY(generator.emit_store_to_reference(**ptr)); TRY(generator.emit_store_to_reference(**ptr));
} else { } else {
auto& binding_pattern = lhs.get<NonnullRefPtr<BindingPattern>>(); auto& binding_pattern = lhs.get<NonnullRefPtr<BindingPattern const>>();
auto value_register = generator.allocate_register(); auto value_register = generator.allocate_register();
generator.emit<Bytecode::Op::Store>(value_register); generator.emit<Bytecode::Op::Store>(value_register);
TRY(generate_binding_pattern_bytecode(generator, *binding_pattern, Bytecode::Op::SetVariable::InitializationMode::Set, value_register)); TRY(generate_binding_pattern_bytecode(generator, *binding_pattern, Bytecode::Op::SetVariable::InitializationMode::Set, value_register));
@ -2607,7 +2607,7 @@ static Bytecode::CodeGenerationErrorOr<void> for_in_of_body_evaluation(Bytecode:
// 14.7.5.4 Runtime Semantics: ForDeclarationBindingInstantiation, https://tc39.es/ecma262/#sec-runtime-semantics-fordeclarationbindinginstantiation // 14.7.5.4 Runtime Semantics: ForDeclarationBindingInstantiation, https://tc39.es/ecma262/#sec-runtime-semantics-fordeclarationbindinginstantiation
// 1. Assert: environment is a declarative Environment Record. // 1. Assert: environment is a declarative Environment Record.
// NOTE: We just made it. // NOTE: We just made it.
auto& variable_declaration = static_cast<VariableDeclaration const&>(*lhs.get<NonnullRefPtr<ASTNode>>()); auto& variable_declaration = static_cast<VariableDeclaration const&>(*lhs.get<NonnullRefPtr<ASTNode const>>());
// 2. For each element name of the BoundNames of ForBinding, do // 2. For each element name of the BoundNames of ForBinding, do
variable_declaration.for_each_bound_name([&](auto const& name) { variable_declaration.for_each_bound_name([&](auto const& name) {
auto identifier = generator.intern_identifier(name); auto identifier = generator.intern_identifier(name);
@ -2630,7 +2630,7 @@ static Bytecode::CodeGenerationErrorOr<void> for_in_of_body_evaluation(Bytecode:
if (!destructuring) { if (!destructuring) {
// 1. Assert: lhs binds a single name. // 1. Assert: lhs binds a single name.
// 2. Let lhsName be the sole element of BoundNames of lhs. // 2. Let lhsName be the sole element of BoundNames of lhs.
auto lhs_name = variable_declaration.declarations().first().target().get<NonnullRefPtr<Identifier>>()->string(); auto lhs_name = variable_declaration.declarations().first().target().get<NonnullRefPtr<Identifier const>>()->string();
// 3. Let lhsRef be ! ResolveBinding(lhsName). // 3. Let lhsRef be ! ResolveBinding(lhsName).
// NOTE: We're skipping all the completion stuff that the spec does, as the unwinding mechanism will take case of doing that. // NOTE: We're skipping all the completion stuff that the spec does, as the unwinding mechanism will take case of doing that.
auto identifier = generator.intern_identifier(lhs_name); auto identifier = generator.intern_identifier(lhs_name);
@ -2660,9 +2660,9 @@ static Bytecode::CodeGenerationErrorOr<void> for_in_of_body_evaluation(Bytecode:
// 2. Assert: lhs is a ForDeclaration. // 2. Assert: lhs is a ForDeclaration.
// 3. Let status be Completion(ForDeclarationBindingInitialization of lhs with arguments nextValue and iterationEnv). // 3. Let status be Completion(ForDeclarationBindingInitialization of lhs with arguments nextValue and iterationEnv).
if (head_result.lhs_kind == LHSKind::VarBinding || head_result.lhs_kind == LHSKind::LexicalBinding) { if (head_result.lhs_kind == LHSKind::VarBinding || head_result.lhs_kind == LHSKind::LexicalBinding) {
auto& declaration = static_cast<VariableDeclaration const&>(*lhs.get<NonnullRefPtr<ASTNode>>()); auto& declaration = static_cast<VariableDeclaration const&>(*lhs.get<NonnullRefPtr<ASTNode const>>());
VERIFY(declaration.declarations().size() == 1); VERIFY(declaration.declarations().size() == 1);
auto& binding_pattern = declaration.declarations().first().target().get<NonnullRefPtr<BindingPattern>>(); auto& binding_pattern = declaration.declarations().first().target().get<NonnullRefPtr<BindingPattern const>>();
auto value_register = generator.allocate_register(); auto value_register = generator.allocate_register();
generator.emit<Bytecode::Op::Store>(value_register); generator.emit<Bytecode::Op::Store>(value_register);

View file

@ -4,6 +4,7 @@
* Copyright (c) 2021-2022, David Tuin <davidot@serenityos.org> * Copyright (c) 2021-2022, David Tuin <davidot@serenityos.org>
* Copyright (c) 2021, Ali Mohammad Pur <mpfard@serenityos.org> * Copyright (c) 2021, Ali Mohammad Pur <mpfard@serenityos.org>
* Copyright (c) 2021, Idan Horowitz <idan.horowitz@serenityos.org> * Copyright (c) 2021, Idan Horowitz <idan.horowitz@serenityos.org>
* Copyright (c) 2023, Andreas Kling <kling@serenityos.org>
* *
* SPDX-License-Identifier: BSD-2-Clause * SPDX-License-Identifier: BSD-2-Clause
*/ */
@ -68,7 +69,7 @@ public:
[&](DeprecatedFlyString const& name) { [&](DeprecatedFlyString const& name) {
scope_pusher.m_forbidden_lexical_names.set(name); scope_pusher.m_forbidden_lexical_names.set(name);
}, },
[&](NonnullRefPtr<BindingPattern> const& binding_pattern) { [&](NonnullRefPtr<BindingPattern const> const& binding_pattern) {
binding_pattern->for_each_bound_name([&](auto const& name) { binding_pattern->for_each_bound_name([&](auto const& name) {
scope_pusher.m_forbidden_lexical_names.set(name); scope_pusher.m_forbidden_lexical_names.set(name);
}); });
@ -87,7 +88,7 @@ public:
return ScopePusher(parser, &node, ScopeLevel::NotTopLevel); return ScopePusher(parser, &node, ScopeLevel::NotTopLevel);
} }
static ScopePusher for_loop_scope(Parser& parser, RefPtr<ASTNode> const& init) static ScopePusher for_loop_scope(Parser& parser, RefPtr<ASTNode const> const& init)
{ {
ScopePusher scope_pusher(parser, nullptr, ScopeLevel::NotTopLevel); ScopePusher scope_pusher(parser, nullptr, ScopeLevel::NotTopLevel);
if (init && is<VariableDeclaration>(*init)) { if (init && is<VariableDeclaration>(*init)) {
@ -102,7 +103,7 @@ public:
return scope_pusher; return scope_pusher;
} }
static ScopePusher catch_scope(Parser& parser, RefPtr<BindingPattern> const& pattern, DeprecatedFlyString const& parameter) static ScopePusher catch_scope(Parser& parser, RefPtr<BindingPattern const> const& pattern, DeprecatedFlyString const& parameter)
{ {
ScopePusher scope_pusher(parser, nullptr, ScopeLevel::NotTopLevel); ScopePusher scope_pusher(parser, nullptr, ScopeLevel::NotTopLevel);
if (pattern) { if (pattern) {
@ -125,7 +126,7 @@ public:
return ScopePusher(parser, nullptr, ScopeLevel::NotTopLevel); return ScopePusher(parser, nullptr, ScopeLevel::NotTopLevel);
} }
void add_declaration(NonnullRefPtr<Declaration> declaration) void add_declaration(NonnullRefPtr<Declaration const> declaration)
{ {
if (declaration->is_lexical_declaration()) { if (declaration->is_lexical_declaration()) {
declaration->for_each_bound_name([&](auto const& name) { declaration->for_each_bound_name([&](auto const& name) {
@ -184,7 +185,7 @@ public:
m_function_names.set(function_name); m_function_names.set(function_name);
if (!m_lexical_names.contains(function_name)) if (!m_lexical_names.contains(function_name))
m_functions_to_hoist.append(static_ptr_cast<FunctionDeclaration>(declaration)); m_functions_to_hoist.append(static_ptr_cast<FunctionDeclaration const>(declaration));
m_node->add_lexical_declaration(move(declaration)); m_node->add_lexical_declaration(move(declaration));
} }
@ -227,10 +228,10 @@ public:
if (m_lexical_names.contains(function_declaration.name()) || m_forbidden_var_names.contains(function_declaration.name())) if (m_lexical_names.contains(function_declaration.name()) || m_forbidden_var_names.contains(function_declaration.name()))
continue; continue;
if (is_top_level()) { if (is_top_level()) {
m_node->add_hoisted_function(move(m_functions_to_hoist[i])); m_node->add_hoisted_function(move(m_functions_to_hoist.ptr_at(i)));
} else { } else {
if (!m_parent_scope->m_lexical_names.contains(function_declaration.name()) && !m_parent_scope->m_function_names.contains(function_declaration.name())) if (!m_parent_scope->m_lexical_names.contains(function_declaration.name()) && !m_parent_scope->m_function_names.contains(function_declaration.name()))
m_parent_scope->m_functions_to_hoist.append(move(m_functions_to_hoist[i])); m_parent_scope->m_functions_to_hoist.append(move(m_functions_to_hoist.ptr_at(i)));
} }
} }
@ -259,7 +260,7 @@ public:
} }
private: private:
void throw_identifier_declared(DeprecatedFlyString const& name, NonnullRefPtr<Declaration> const& declaration) void throw_identifier_declared(DeprecatedFlyString const& name, NonnullRefPtr<Declaration const> const& declaration)
{ {
m_parser.syntax_error(DeprecatedString::formatted("Identifier '{}' already declared", name), declaration->source_range().start); m_parser.syntax_error(DeprecatedString::formatted("Identifier '{}' already declared", name), declaration->source_range().start);
} }
@ -277,7 +278,7 @@ private:
HashTable<DeprecatedFlyString> m_forbidden_lexical_names; HashTable<DeprecatedFlyString> m_forbidden_lexical_names;
HashTable<DeprecatedFlyString> m_forbidden_var_names; HashTable<DeprecatedFlyString> m_forbidden_var_names;
NonnullRefPtrVector<FunctionDeclaration> m_functions_to_hoist; NonnullRefPtrVector<FunctionDeclaration const> m_functions_to_hoist;
Optional<Vector<FunctionParameter>> m_function_parameters; Optional<Vector<FunctionParameter>> m_function_parameters;
@ -589,7 +590,7 @@ void Parser::parse_module(Program& program)
} }
} }
NonnullRefPtr<Declaration> Parser::parse_declaration() NonnullRefPtr<Declaration const> Parser::parse_declaration()
{ {
auto rule_start = push_start(); auto rule_start = push_start();
if (m_state.current_token.type() == TokenType::Async && next_token().type() == TokenType::Function) if (m_state.current_token.type() == TokenType::Async && next_token().type() == TokenType::Function)
@ -617,7 +618,7 @@ NonnullRefPtr<Declaration> Parser::parse_declaration()
} }
} }
NonnullRefPtr<Statement> Parser::parse_statement(AllowLabelledFunction allow_labelled_function) NonnullRefPtr<Statement const> Parser::parse_statement(AllowLabelledFunction allow_labelled_function)
{ {
auto rule_start = push_start(); auto rule_start = push_start();
auto type = m_state.current_token.type(); auto type = m_state.current_token.type();
@ -724,7 +725,7 @@ static bool is_simple_parameter_list(Vector<FunctionParameter> const& parameters
}); });
} }
RefPtr<FunctionExpression> Parser::try_parse_arrow_function_expression(bool expect_parens, bool is_async) RefPtr<FunctionExpression const> Parser::try_parse_arrow_function_expression(bool expect_parens, bool is_async)
{ {
if (is_async) if (is_async)
VERIFY(match(TokenType::Async)); VERIFY(match(TokenType::Async));
@ -815,7 +816,7 @@ RefPtr<FunctionExpression> Parser::try_parse_arrow_function_expression(bool expe
bool contains_direct_call_to_eval = false; bool contains_direct_call_to_eval = false;
auto function_body_result = [&]() -> RefPtr<FunctionBody> { auto function_body_result = [&]() -> RefPtr<FunctionBody const> {
TemporaryChange change(m_state.in_arrow_function_context, true); TemporaryChange change(m_state.in_arrow_function_context, true);
TemporaryChange async_context_change(m_state.await_expression_is_valid, is_async); TemporaryChange async_context_change(m_state.await_expression_is_valid, is_async);
TemporaryChange in_class_static_init_block_change(m_state.in_class_static_init_block, false); TemporaryChange in_class_static_init_block_change(m_state.in_class_static_init_block, false);
@ -837,9 +838,9 @@ RefPtr<FunctionExpression> Parser::try_parse_arrow_function_expression(bool expe
auto return_block = create_ast_node<FunctionBody>({ m_source_code, rule_start.position(), position() }); auto return_block = create_ast_node<FunctionBody>({ m_source_code, rule_start.position(), position() });
ScopePusher function_scope = ScopePusher::function_scope(*this, return_block, parameters); ScopePusher function_scope = ScopePusher::function_scope(*this, return_block, parameters);
auto return_expression = parse_expression(2); auto return_expression = parse_expression(2);
return_block->append<ReturnStatement>({ m_source_code, rule_start.position(), position() }, move(return_expression)); return_block->append<ReturnStatement const>({ m_source_code, rule_start.position(), position() }, move(return_expression));
if (m_state.strict_mode) if (m_state.strict_mode)
return_block->set_strict_mode(); const_cast<FunctionBody&>(*return_block).set_strict_mode();
contains_direct_call_to_eval = function_scope.contains_direct_call_to_eval(); contains_direct_call_to_eval = function_scope.contains_direct_call_to_eval();
return return_block; return return_block;
} }
@ -873,7 +874,7 @@ RefPtr<FunctionExpression> Parser::try_parse_arrow_function_expression(bool expe
/* might_need_arguments_object */ false, contains_direct_call_to_eval, /* is_arrow_function */ true); /* might_need_arguments_object */ false, contains_direct_call_to_eval, /* is_arrow_function */ true);
} }
RefPtr<LabelledStatement> Parser::try_parse_labelled_statement(AllowLabelledFunction allow_function) RefPtr<LabelledStatement const> Parser::try_parse_labelled_statement(AllowLabelledFunction allow_function)
{ {
{ {
// NOTE: This is a fast path where we try to fail early to avoid the expensive save_state+load_state. // NOTE: This is a fast path where we try to fail early to avoid the expensive save_state+load_state.
@ -924,7 +925,7 @@ RefPtr<LabelledStatement> Parser::try_parse_labelled_statement(AllowLabelledFunc
if (m_state.labels_in_scope.contains(identifier)) if (m_state.labels_in_scope.contains(identifier))
syntax_error(DeprecatedString::formatted("Label '{}' has already been declared", identifier)); syntax_error(DeprecatedString::formatted("Label '{}' has already been declared", identifier));
RefPtr<Statement> labelled_item; RefPtr<Statement const> labelled_item;
auto is_iteration_statement = false; auto is_iteration_statement = false;
@ -945,7 +946,7 @@ RefPtr<LabelledStatement> Parser::try_parse_labelled_statement(AllowLabelledFunc
// Extract the innermost statement from a potentially nested chain of LabelledStatements. // Extract the innermost statement from a potentially nested chain of LabelledStatements.
auto statement = labelled_item; auto statement = labelled_item;
while (is<LabelledStatement>(*statement)) while (is<LabelledStatement>(*statement))
statement = static_cast<LabelledStatement&>(*statement).labelled_item(); statement = static_cast<LabelledStatement const&>(*statement).labelled_item();
if (is<IterationStatement>(*statement)) if (is<IterationStatement>(*statement))
is_iteration_statement = true; is_iteration_statement = true;
} }
@ -960,7 +961,7 @@ RefPtr<LabelledStatement> Parser::try_parse_labelled_statement(AllowLabelledFunc
return create_ast_node<LabelledStatement>({ m_source_code, rule_start.position(), position() }, identifier, labelled_item.release_nonnull()); return create_ast_node<LabelledStatement>({ m_source_code, rule_start.position(), position() }, identifier, labelled_item.release_nonnull());
} }
RefPtr<MetaProperty> Parser::try_parse_new_target_expression() RefPtr<MetaProperty const> Parser::try_parse_new_target_expression()
{ {
// Optimization which skips the save/load state. // Optimization which skips the save/load state.
if (next_token().type() != TokenType::Period) if (next_token().type() != TokenType::Period)
@ -985,7 +986,7 @@ RefPtr<MetaProperty> Parser::try_parse_new_target_expression()
return create_ast_node<MetaProperty>({ m_source_code, rule_start.position(), position() }, MetaProperty::Type::NewTarget); return create_ast_node<MetaProperty>({ m_source_code, rule_start.position(), position() }, MetaProperty::Type::NewTarget);
} }
RefPtr<MetaProperty> Parser::try_parse_import_meta_expression() RefPtr<MetaProperty const> Parser::try_parse_import_meta_expression()
{ {
// Optimization which skips the save/load state. // Optimization which skips the save/load state.
if (next_token().type() != TokenType::Period) if (next_token().type() != TokenType::Period)
@ -1010,7 +1011,7 @@ RefPtr<MetaProperty> Parser::try_parse_import_meta_expression()
return create_ast_node<MetaProperty>({ m_source_code, rule_start.position(), position() }, MetaProperty::Type::ImportMeta); return create_ast_node<MetaProperty>({ m_source_code, rule_start.position(), position() }, MetaProperty::Type::ImportMeta);
} }
NonnullRefPtr<ImportCall> Parser::parse_import_call() NonnullRefPtr<ImportCall const> Parser::parse_import_call()
{ {
auto rule_start = push_start(); auto rule_start = push_start();
@ -1024,7 +1025,7 @@ NonnullRefPtr<ImportCall> Parser::parse_import_call()
consume(TokenType::ParenOpen); consume(TokenType::ParenOpen);
auto argument = parse_expression(2); auto argument = parse_expression(2);
RefPtr<Expression> options; RefPtr<Expression const> options;
if (match(TokenType::Comma)) { if (match(TokenType::Comma)) {
consume(TokenType::Comma); consume(TokenType::Comma);
@ -1042,13 +1043,13 @@ NonnullRefPtr<ImportCall> Parser::parse_import_call()
return create_ast_node<ImportCall>({ m_source_code, rule_start.position(), position() }, move(argument), move(options)); return create_ast_node<ImportCall>({ m_source_code, rule_start.position(), position() }, move(argument), move(options));
} }
NonnullRefPtr<ClassDeclaration> Parser::parse_class_declaration() NonnullRefPtr<ClassDeclaration const> Parser::parse_class_declaration()
{ {
auto rule_start = push_start(); auto rule_start = push_start();
return create_ast_node<ClassDeclaration>({ m_source_code, rule_start.position(), position() }, parse_class_expression(true)); return create_ast_node<ClassDeclaration>({ m_source_code, rule_start.position(), position() }, parse_class_expression(true));
} }
NonnullRefPtr<ClassExpression> Parser::parse_class_expression(bool expect_class_name) NonnullRefPtr<ClassExpression const> Parser::parse_class_expression(bool expect_class_name)
{ {
auto rule_start = push_start(); auto rule_start = push_start();
// Classes are always in strict mode. // Classes are always in strict mode.
@ -1056,9 +1057,9 @@ NonnullRefPtr<ClassExpression> Parser::parse_class_expression(bool expect_class_
consume(TokenType::Class); consume(TokenType::Class);
NonnullRefPtrVector<ClassElement> elements; NonnullRefPtrVector<ClassElement const> elements;
RefPtr<Expression> super_class; RefPtr<Expression const> super_class;
RefPtr<FunctionExpression> constructor; RefPtr<FunctionExpression const> constructor;
HashTable<DeprecatedFlyString> found_private_names; HashTable<DeprecatedFlyString> found_private_names;
DeprecatedFlyString class_name = expect_class_name || match_identifier() || match(TokenType::Yield) || match(TokenType::Await) DeprecatedFlyString class_name = expect_class_name || match_identifier() || match(TokenType::Yield) || match(TokenType::Await)
@ -1102,7 +1103,7 @@ NonnullRefPtr<ClassExpression> Parser::parse_class_expression(bool expect_class_
}; };
while (!done() && !match(TokenType::CurlyClose)) { while (!done() && !match(TokenType::CurlyClose)) {
RefPtr<Expression> property_key; RefPtr<Expression const> property_key;
bool is_static = false; bool is_static = false;
bool is_constructor = false; bool is_constructor = false;
bool is_generator = false; bool is_generator = false;
@ -1313,7 +1314,7 @@ NonnullRefPtr<ClassExpression> Parser::parse_class_expression(bool expect_class_
if (name == "constructor"sv) if (name == "constructor"sv)
syntax_error("Class cannot have field named 'constructor'"); syntax_error("Class cannot have field named 'constructor'");
RefPtr<Expression> initializer; RefPtr<Expression const> initializer;
bool contains_direct_call_to_eval = false; bool contains_direct_call_to_eval = false;
if (match(TokenType::Equals)) { if (match(TokenType::Equals)) {
@ -1389,7 +1390,7 @@ Parser::PrimaryExpressionParseResult Parser::parse_primary_expression()
if (match_unary_prefixed_expression()) if (match_unary_prefixed_expression())
return { parse_unary_prefixed_expression() }; return { parse_unary_prefixed_expression() };
auto try_arrow_function_parse_or_fail = [this](Position const& position, bool expect_paren, bool is_async = false) -> RefPtr<FunctionExpression> { auto try_arrow_function_parse_or_fail = [this](Position const& position, bool expect_paren, bool is_async = false) -> RefPtr<FunctionExpression const> {
if (try_parse_arrow_function_expression_failed_at_position(position)) if (try_parse_arrow_function_expression_failed_at_position(position))
return nullptr; return nullptr;
auto arrow_function = try_parse_arrow_function_expression(expect_paren, is_async); auto arrow_function = try_parse_arrow_function_expression(expect_paren, is_async);
@ -1411,7 +1412,7 @@ Parser::PrimaryExpressionParseResult Parser::parse_primary_expression()
auto expression = parse_expression(0); auto expression = parse_expression(0);
consume(TokenType::ParenClose); consume(TokenType::ParenClose);
if (is<FunctionExpression>(*expression)) { if (is<FunctionExpression>(*expression)) {
auto& function = static_cast<FunctionExpression&>(*expression); auto& function = static_cast<FunctionExpression const&>(*expression);
if (function.kind() == FunctionKind::Generator && function.name() == "yield"sv) if (function.kind() == FunctionKind::Generator && function.name() == "yield"sv)
syntax_error("function is not allowed to be called 'yield' in this context", function.source_range().start); syntax_error("function is not allowed to be called 'yield' in this context", function.source_range().start);
if (function.kind() == FunctionKind::Async && function.name() == "await"sv) if (function.kind() == FunctionKind::Async && function.name() == "await"sv)
@ -1534,7 +1535,7 @@ Parser::PrimaryExpressionParseResult Parser::parse_primary_expression()
return { create_ast_node<ErrorExpression>({ m_source_code, rule_start.position(), position() }) }; return { create_ast_node<ErrorExpression>({ m_source_code, rule_start.position(), position() }) };
} }
NonnullRefPtr<RegExpLiteral> Parser::parse_regexp_literal() NonnullRefPtr<RegExpLiteral const> Parser::parse_regexp_literal()
{ {
auto rule_start = push_start(); auto rule_start = push_start();
auto pattern = consume().value(); auto pattern = consume().value();
@ -1577,7 +1578,7 @@ static bool is_simple_assignment_target(Expression const& expression, bool allow
return is<Identifier>(expression) || is<MemberExpression>(expression) || (allow_web_reality_call_expression && is<CallExpression>(expression)); return is<Identifier>(expression) || is<MemberExpression>(expression) || (allow_web_reality_call_expression && is<CallExpression>(expression));
} }
NonnullRefPtr<Expression> Parser::parse_unary_prefixed_expression() NonnullRefPtr<Expression const> Parser::parse_unary_prefixed_expression()
{ {
auto rule_start = push_start(); auto rule_start = push_start();
auto precedence = g_operator_precedence.get(m_state.current_token.type()); auto precedence = g_operator_precedence.get(m_state.current_token.type());
@ -1591,7 +1592,7 @@ NonnullRefPtr<Expression> Parser::parse_unary_prefixed_expression()
syntax_error(DeprecatedString::formatted("Right-hand side of prefix increment operator must be identifier or member expression, got {}", rhs->class_name()), rhs_start); syntax_error(DeprecatedString::formatted("Right-hand side of prefix increment operator must be identifier or member expression, got {}", rhs->class_name()), rhs_start);
if (m_state.strict_mode && is<Identifier>(*rhs)) { if (m_state.strict_mode && is<Identifier>(*rhs)) {
auto& identifier = static_cast<Identifier&>(*rhs); auto& identifier = static_cast<Identifier const&>(*rhs);
auto& name = identifier.string(); auto& name = identifier.string();
check_identifier_name_for_assignment_validity(name); check_identifier_name_for_assignment_validity(name);
} }
@ -1606,7 +1607,7 @@ NonnullRefPtr<Expression> Parser::parse_unary_prefixed_expression()
syntax_error(DeprecatedString::formatted("Right-hand side of prefix decrement operator must be identifier or member expression, got {}", rhs->class_name()), rhs_start); syntax_error(DeprecatedString::formatted("Right-hand side of prefix decrement operator must be identifier or member expression, got {}", rhs->class_name()), rhs_start);
if (m_state.strict_mode && is<Identifier>(*rhs)) { if (m_state.strict_mode && is<Identifier>(*rhs)) {
auto& identifier = static_cast<Identifier&>(*rhs); auto& identifier = static_cast<Identifier const&>(*rhs);
auto& name = identifier.string(); auto& name = identifier.string();
check_identifier_name_for_assignment_validity(name); check_identifier_name_for_assignment_validity(name);
} }
@ -1655,7 +1656,7 @@ NonnullRefPtr<Expression> Parser::parse_unary_prefixed_expression()
} }
} }
NonnullRefPtr<Expression> Parser::parse_property_key() NonnullRefPtr<Expression const> Parser::parse_property_key()
{ {
auto rule_start = push_start(); auto rule_start = push_start();
if (match(TokenType::StringLiteral)) { if (match(TokenType::StringLiteral)) {
@ -1676,7 +1677,7 @@ NonnullRefPtr<Expression> Parser::parse_property_key()
} }
} }
NonnullRefPtr<ObjectExpression> Parser::parse_object_expression() NonnullRefPtr<ObjectExpression const> Parser::parse_object_expression()
{ {
auto rule_start = push_start(); auto rule_start = push_start();
consume(TokenType::CurlyOpen); consume(TokenType::CurlyOpen);
@ -1697,8 +1698,8 @@ NonnullRefPtr<ObjectExpression> Parser::parse_object_expression()
while (!done() && !match(TokenType::CurlyClose)) { while (!done() && !match(TokenType::CurlyClose)) {
property_type = ObjectProperty::Type::KeyValue; property_type = ObjectProperty::Type::KeyValue;
RefPtr<Expression> property_key; RefPtr<Expression const> property_key;
RefPtr<Expression> property_value; RefPtr<Expression const> property_value;
FunctionKind function_kind { FunctionKind::Normal }; FunctionKind function_kind { FunctionKind::Normal };
if (match(TokenType::TripleDot)) { if (match(TokenType::TripleDot)) {
@ -1829,14 +1830,14 @@ NonnullRefPtr<ObjectExpression> Parser::parse_object_expression()
move(properties)); move(properties));
} }
NonnullRefPtr<ArrayExpression> Parser::parse_array_expression() NonnullRefPtr<ArrayExpression const> Parser::parse_array_expression()
{ {
auto rule_start = push_start(); auto rule_start = push_start();
consume(TokenType::BracketOpen); consume(TokenType::BracketOpen);
Vector<RefPtr<Expression>> elements; Vector<RefPtr<Expression const>> elements;
while (match_expression() || match(TokenType::TripleDot) || match(TokenType::Comma)) { while (match_expression() || match(TokenType::TripleDot) || match(TokenType::Comma)) {
RefPtr<Expression> expression; RefPtr<Expression const> expression;
if (match(TokenType::TripleDot)) { if (match(TokenType::TripleDot)) {
consume(TokenType::TripleDot); consume(TokenType::TripleDot);
@ -1857,7 +1858,7 @@ NonnullRefPtr<ArrayExpression> Parser::parse_array_expression()
return create_ast_node<ArrayExpression>({ m_source_code, rule_start.position(), position() }, move(elements)); return create_ast_node<ArrayExpression>({ m_source_code, rule_start.position(), position() }, move(elements));
} }
NonnullRefPtr<StringLiteral> Parser::parse_string_literal(Token const& token, StringLiteralType string_literal_type, bool* contains_invalid_escape) NonnullRefPtr<StringLiteral const> Parser::parse_string_literal(Token const& token, StringLiteralType string_literal_type, bool* contains_invalid_escape)
{ {
auto rule_start = push_start(); auto rule_start = push_start();
auto status = Token::StringValueStatus::Ok; auto status = Token::StringValueStatus::Ok;
@ -1894,13 +1895,13 @@ NonnullRefPtr<StringLiteral> Parser::parse_string_literal(Token const& token, St
return create_ast_node<StringLiteral>({ m_source_code, rule_start.position(), position() }, string); return create_ast_node<StringLiteral>({ m_source_code, rule_start.position(), position() }, string);
} }
NonnullRefPtr<TemplateLiteral> Parser::parse_template_literal(bool is_tagged) NonnullRefPtr<TemplateLiteral const> Parser::parse_template_literal(bool is_tagged)
{ {
auto rule_start = push_start(); auto rule_start = push_start();
consume(TokenType::TemplateLiteralStart); consume(TokenType::TemplateLiteralStart);
NonnullRefPtrVector<Expression> expressions; NonnullRefPtrVector<Expression const> expressions;
NonnullRefPtrVector<Expression> raw_strings; NonnullRefPtrVector<Expression const> raw_strings;
auto append_empty_string = [this, &rule_start, &expressions, &raw_strings, is_tagged]() { auto append_empty_string = [this, &rule_start, &expressions, &raw_strings, is_tagged]() {
auto string_literal = create_ast_node<StringLiteral>({ m_source_code, rule_start.position(), position() }, ""); auto string_literal = create_ast_node<StringLiteral>({ m_source_code, rule_start.position(), position() }, "");
@ -1959,7 +1960,7 @@ NonnullRefPtr<TemplateLiteral> Parser::parse_template_literal(bool is_tagged)
return create_ast_node<TemplateLiteral>({ m_source_code, rule_start.position(), position() }, expressions); return create_ast_node<TemplateLiteral>({ m_source_code, rule_start.position(), position() }, expressions);
} }
NonnullRefPtr<Expression> Parser::parse_expression(int min_precedence, Associativity associativity, ForbiddenTokens forbidden) NonnullRefPtr<Expression const> Parser::parse_expression(int min_precedence, Associativity associativity, ForbiddenTokens forbidden)
{ {
auto rule_start = push_start(); auto rule_start = push_start();
auto [expression, should_continue_parsing] = parse_primary_expression(); auto [expression, should_continue_parsing] = parse_primary_expression();
@ -1970,7 +1971,7 @@ NonnullRefPtr<Expression> Parser::parse_expression(int min_precedence, Associati
} }
}; };
if (is<Identifier>(*expression) && m_state.current_scope_pusher) { if (is<Identifier>(*expression) && m_state.current_scope_pusher) {
auto identifier_instance = static_ptr_cast<Identifier>(expression); auto identifier_instance = static_ptr_cast<Identifier const>(expression);
auto function_scope = m_state.current_scope_pusher->last_function_scope(); auto function_scope = m_state.current_scope_pusher->last_function_scope();
auto function_parent_scope = function_scope ? function_scope->parent_scope() : nullptr; auto function_parent_scope = function_scope ? function_scope->parent_scope() : nullptr;
bool has_not_been_declared_as_variable = true; bool has_not_been_declared_as_variable = true;
@ -2017,7 +2018,7 @@ NonnullRefPtr<Expression> Parser::parse_expression(int min_precedence, Associati
check_for_invalid_object_property(expression); check_for_invalid_object_property(expression);
if (is<CallExpression>(*expression) && m_state.current_scope_pusher) { if (is<CallExpression>(*expression) && m_state.current_scope_pusher) {
auto& callee = static_ptr_cast<CallExpression>(expression)->callee(); auto& callee = static_ptr_cast<CallExpression const>(expression)->callee();
if (is<Identifier>(callee)) { if (is<Identifier>(callee)) {
auto& identifier_instance = static_cast<Identifier const&>(callee); auto& identifier_instance = static_cast<Identifier const&>(callee);
if (identifier_instance.string() == "eval"sv) { if (identifier_instance.string() == "eval"sv) {
@ -2035,7 +2036,7 @@ NonnullRefPtr<Expression> Parser::parse_expression(int min_precedence, Associati
} }
if (match(TokenType::Comma) && min_precedence <= 1) { if (match(TokenType::Comma) && min_precedence <= 1) {
NonnullRefPtrVector<Expression> expressions; NonnullRefPtrVector<Expression const> expressions;
expressions.append(expression); expressions.append(expression);
while (match(TokenType::Comma)) { while (match(TokenType::Comma)) {
consume(); consume();
@ -2047,7 +2048,7 @@ NonnullRefPtr<Expression> Parser::parse_expression(int min_precedence, Associati
return expression; return expression;
} }
Parser::ExpressionResult Parser::parse_secondary_expression(NonnullRefPtr<Expression> lhs, int min_precedence, Associativity associativity, ForbiddenTokens forbidden) Parser::ExpressionResult Parser::parse_secondary_expression(NonnullRefPtr<Expression const> lhs, int min_precedence, Associativity associativity, ForbiddenTokens forbidden)
{ {
auto rule_start = push_start(); auto rule_start = push_start();
switch (m_state.current_token.type()) { switch (m_state.current_token.type()) {
@ -2170,7 +2171,7 @@ Parser::ExpressionResult Parser::parse_secondary_expression(NonnullRefPtr<Expres
syntax_error(DeprecatedString::formatted("Left-hand side of postfix increment operator must be identifier or member expression, got {}", lhs->class_name())); syntax_error(DeprecatedString::formatted("Left-hand side of postfix increment operator must be identifier or member expression, got {}", lhs->class_name()));
if (m_state.strict_mode && is<Identifier>(*lhs)) { if (m_state.strict_mode && is<Identifier>(*lhs)) {
auto& identifier = static_cast<Identifier&>(*lhs); auto& identifier = static_cast<Identifier const&>(*lhs);
auto& name = identifier.string(); auto& name = identifier.string();
check_identifier_name_for_assignment_validity(name); check_identifier_name_for_assignment_validity(name);
} }
@ -2182,7 +2183,7 @@ Parser::ExpressionResult Parser::parse_secondary_expression(NonnullRefPtr<Expres
syntax_error(DeprecatedString::formatted("Left-hand side of postfix increment operator must be identifier or member expression, got {}", lhs->class_name())); syntax_error(DeprecatedString::formatted("Left-hand side of postfix increment operator must be identifier or member expression, got {}", lhs->class_name()));
if (m_state.strict_mode && is<Identifier>(*lhs)) { if (m_state.strict_mode && is<Identifier>(*lhs)) {
auto& identifier = static_cast<Identifier&>(*lhs); auto& identifier = static_cast<Identifier const&>(*lhs);
auto& name = identifier.string(); auto& name = identifier.string();
check_identifier_name_for_assignment_validity(name); check_identifier_name_for_assignment_validity(name);
} }
@ -2238,7 +2239,7 @@ bool Parser::is_private_identifier_valid() const
return true; return true;
} }
RefPtr<BindingPattern> Parser::synthesize_binding_pattern(Expression const& expression) RefPtr<BindingPattern const> Parser::synthesize_binding_pattern(Expression const& expression)
{ {
VERIFY(is<ArrayExpression>(expression) || is<ObjectExpression>(expression)); VERIFY(is<ArrayExpression>(expression) || is<ObjectExpression>(expression));
// Clear any syntax error that has occurred in the range that 'expression' spans. // Clear any syntax error that has occurred in the range that 'expression' spans.
@ -2276,7 +2277,7 @@ RefPtr<BindingPattern> Parser::synthesize_binding_pattern(Expression const& expr
return result; return result;
} }
NonnullRefPtr<AssignmentExpression> Parser::parse_assignment_expression(AssignmentOp assignment_op, NonnullRefPtr<Expression> lhs, int min_precedence, Associativity associativity, ForbiddenTokens forbidden) NonnullRefPtr<AssignmentExpression const> Parser::parse_assignment_expression(AssignmentOp assignment_op, NonnullRefPtr<Expression const> lhs, int min_precedence, Associativity associativity, ForbiddenTokens forbidden)
{ {
auto rule_start = push_start(); auto rule_start = push_start();
VERIFY(match(TokenType::Equals) VERIFY(match(TokenType::Equals)
@ -2327,7 +2328,7 @@ NonnullRefPtr<AssignmentExpression> Parser::parse_assignment_expression(Assignme
return create_ast_node<AssignmentExpression>({ m_source_code, rule_start.position(), position() }, assignment_op, move(lhs), move(rhs)); return create_ast_node<AssignmentExpression>({ m_source_code, rule_start.position(), position() }, assignment_op, move(lhs), move(rhs));
} }
NonnullRefPtr<Identifier> Parser::parse_identifier() NonnullRefPtr<Identifier const> Parser::parse_identifier()
{ {
auto identifier_start = position(); auto identifier_start = position();
auto token = consume_identifier(); auto token = consume_identifier();
@ -2359,7 +2360,7 @@ Vector<CallExpression::Argument> Parser::parse_arguments()
return arguments; return arguments;
} }
NonnullRefPtr<Expression> Parser::parse_call_expression(NonnullRefPtr<Expression> lhs) NonnullRefPtr<Expression const> Parser::parse_call_expression(NonnullRefPtr<Expression const> lhs)
{ {
auto rule_start = push_start(); auto rule_start = push_start();
if (!m_state.allow_super_constructor_call && is<SuperExpression>(*lhs)) if (!m_state.allow_super_constructor_call && is<SuperExpression>(*lhs))
@ -2373,7 +2374,7 @@ NonnullRefPtr<Expression> Parser::parse_call_expression(NonnullRefPtr<Expression
return CallExpression::create({ m_source_code, rule_start.position(), position() }, move(lhs), arguments.span()); return CallExpression::create({ m_source_code, rule_start.position(), position() }, move(lhs), arguments.span());
} }
NonnullRefPtr<NewExpression> Parser::parse_new_expression() NonnullRefPtr<NewExpression const> Parser::parse_new_expression()
{ {
auto rule_start = push_start(); auto rule_start = push_start();
consume(TokenType::New); consume(TokenType::New);
@ -2403,7 +2404,7 @@ NonnullRefPtr<NewExpression> Parser::parse_new_expression()
return NewExpression::create({ m_source_code, rule_start.position(), position() }, move(callee), move(arguments)); return NewExpression::create({ m_source_code, rule_start.position(), position() }, move(callee), move(arguments));
} }
NonnullRefPtr<YieldExpression> Parser::parse_yield_expression() NonnullRefPtr<YieldExpression const> Parser::parse_yield_expression()
{ {
auto rule_start = push_start(); auto rule_start = push_start();
@ -2411,7 +2412,7 @@ NonnullRefPtr<YieldExpression> Parser::parse_yield_expression()
syntax_error("'Yield' expression is not allowed in formal parameters of generator function"); syntax_error("'Yield' expression is not allowed in formal parameters of generator function");
consume(TokenType::Yield); consume(TokenType::Yield);
RefPtr<Expression> argument; RefPtr<Expression const> argument;
bool yield_from = false; bool yield_from = false;
if (!m_state.current_token.trivia_contains_line_terminator()) { if (!m_state.current_token.trivia_contains_line_terminator()) {
@ -2427,7 +2428,7 @@ NonnullRefPtr<YieldExpression> Parser::parse_yield_expression()
return create_ast_node<YieldExpression>({ m_source_code, rule_start.position(), position() }, move(argument), yield_from); return create_ast_node<YieldExpression>({ m_source_code, rule_start.position(), position() }, move(argument), yield_from);
} }
NonnullRefPtr<AwaitExpression> Parser::parse_await_expression() NonnullRefPtr<AwaitExpression const> Parser::parse_await_expression()
{ {
auto rule_start = push_start(); auto rule_start = push_start();
@ -2445,7 +2446,7 @@ NonnullRefPtr<AwaitExpression> Parser::parse_await_expression()
return create_ast_node<AwaitExpression>({ m_source_code, rule_start.position(), position() }, move(argument)); return create_ast_node<AwaitExpression>({ m_source_code, rule_start.position(), position() }, move(argument));
} }
NonnullRefPtr<ReturnStatement> Parser::parse_return_statement() NonnullRefPtr<ReturnStatement const> Parser::parse_return_statement()
{ {
auto rule_start = push_start(); auto rule_start = push_start();
if (!m_state.in_function_context && !m_state.in_arrow_function_context) if (!m_state.in_function_context && !m_state.in_arrow_function_context)
@ -2486,7 +2487,7 @@ void Parser::parse_statement_list(ScopeNode& output_node, AllowLabelledFunction
} }
// FunctionBody, https://tc39.es/ecma262/#prod-FunctionBody // FunctionBody, https://tc39.es/ecma262/#prod-FunctionBody
NonnullRefPtr<FunctionBody> Parser::parse_function_body(Vector<FunctionParameter> const& parameters, FunctionKind function_kind, bool& contains_direct_call_to_eval) NonnullRefPtr<FunctionBody const> Parser::parse_function_body(Vector<FunctionParameter> const& parameters, FunctionKind function_kind, bool& contains_direct_call_to_eval)
{ {
auto rule_start = push_start(); auto rule_start = push_start();
auto function_body = create_ast_node<FunctionBody>({ m_source_code, rule_start.position(), position() }); auto function_body = create_ast_node<FunctionBody>({ m_source_code, rule_start.position(), position() });
@ -2530,7 +2531,7 @@ NonnullRefPtr<FunctionBody> Parser::parse_function_body(Vector<FunctionParameter
parameter_names.append(parameter_name); parameter_names.append(parameter_name);
}, },
[&](NonnullRefPtr<BindingPattern> const& binding) { [&](NonnullRefPtr<BindingPattern const> const& binding) {
binding->for_each_bound_name([&](auto& bound_name) { binding->for_each_bound_name([&](auto& bound_name) {
if (function_kind == FunctionKind::Generator && bound_name == "yield"sv) if (function_kind == FunctionKind::Generator && bound_name == "yield"sv)
syntax_error("Parameter name 'yield' not allowed in this context"); syntax_error("Parameter name 'yield' not allowed in this context");
@ -2555,7 +2556,7 @@ NonnullRefPtr<FunctionBody> Parser::parse_function_body(Vector<FunctionParameter
return function_body; return function_body;
} }
NonnullRefPtr<BlockStatement> Parser::parse_block_statement() NonnullRefPtr<BlockStatement const> Parser::parse_block_statement()
{ {
auto rule_start = push_start(); auto rule_start = push_start();
auto block = create_ast_node<BlockStatement>({ m_source_code, rule_start.position(), position() }); auto block = create_ast_node<BlockStatement>({ m_source_code, rule_start.position(), position() });
@ -2669,7 +2670,7 @@ Vector<FunctionParameter> Parser::parse_formal_parameters(int& function_length,
Vector<FunctionParameter> parameters; Vector<FunctionParameter> parameters;
auto consume_identifier_or_binding_pattern = [&]() -> Variant<DeprecatedFlyString, NonnullRefPtr<BindingPattern>> { auto consume_identifier_or_binding_pattern = [&]() -> Variant<DeprecatedFlyString, NonnullRefPtr<BindingPattern const>> {
if (auto pattern = parse_binding_pattern(AllowDuplicates::No, AllowMemberExpressions::No)) if (auto pattern = parse_binding_pattern(AllowDuplicates::No, AllowMemberExpressions::No))
return pattern.release_nonnull(); return pattern.release_nonnull();
@ -2683,7 +2684,7 @@ Vector<FunctionParameter> Parser::parse_formal_parameters(int& function_length,
[&](DeprecatedFlyString const& name) { [&](DeprecatedFlyString const& name) {
return name == parameter_name; return name == parameter_name;
}, },
[&](NonnullRefPtr<BindingPattern> const& bindings) { [&](NonnullRefPtr<BindingPattern const> const& bindings) {
bool found_duplicate = false; bool found_duplicate = false;
bindings->for_each_bound_name([&](auto& bound_name) { bindings->for_each_bound_name([&](auto& bound_name) {
if (bound_name == parameter_name) if (bound_name == parameter_name)
@ -2724,7 +2725,7 @@ Vector<FunctionParameter> Parser::parse_formal_parameters(int& function_length,
is_rest = true; is_rest = true;
} }
auto parameter = consume_identifier_or_binding_pattern(); auto parameter = consume_identifier_or_binding_pattern();
RefPtr<Expression> default_value; RefPtr<Expression const> default_value;
if (match(TokenType::Equals)) { if (match(TokenType::Equals)) {
consume(); consume();
@ -2737,7 +2738,7 @@ Vector<FunctionParameter> Parser::parse_formal_parameters(int& function_length,
default_value = parse_expression(2); default_value = parse_expression(2);
bool is_generator = parse_options & FunctionNodeParseOptions::IsGeneratorFunction; bool is_generator = parse_options & FunctionNodeParseOptions::IsGeneratorFunction;
if ((is_generator || m_state.strict_mode) && default_value && default_value->fast_is<Identifier>() && static_cast<Identifier&>(*default_value).string() == "yield"sv) if ((is_generator || m_state.strict_mode) && default_value && default_value->fast_is<Identifier>() && static_cast<Identifier const&>(*default_value).string() == "yield"sv)
syntax_error("Generator function parameter initializer cannot contain a reference to an identifier named \"yield\""); syntax_error("Generator function parameter initializer cannot contain a reference to an identifier named \"yield\"");
} }
parameters.append({ move(parameter), default_value, is_rest }); parameters.append({ move(parameter), default_value, is_rest });
@ -2758,7 +2759,7 @@ Vector<FunctionParameter> Parser::parse_formal_parameters(int& function_length,
static AK::Array<DeprecatedFlyString, 36> s_reserved_words = { "break", "case", "catch", "class", "const", "continue", "debugger", "default", "delete", "do", "else", "enum", "export", "extends", "false", "finally", "for", "function", "if", "import", "in", "instanceof", "new", "null", "return", "super", "switch", "this", "throw", "true", "try", "typeof", "var", "void", "while", "with" }; static AK::Array<DeprecatedFlyString, 36> s_reserved_words = { "break", "case", "catch", "class", "const", "continue", "debugger", "default", "delete", "do", "else", "enum", "export", "extends", "false", "finally", "for", "function", "if", "import", "in", "instanceof", "new", "null", "return", "super", "switch", "this", "throw", "true", "try", "typeof", "var", "void", "while", "with" };
RefPtr<BindingPattern> Parser::parse_binding_pattern(Parser::AllowDuplicates allow_duplicates, Parser::AllowMemberExpressions allow_member_expressions) RefPtr<BindingPattern const> Parser::parse_binding_pattern(Parser::AllowDuplicates allow_duplicates, Parser::AllowMemberExpressions allow_member_expressions)
{ {
auto rule_start = push_start(); auto rule_start = push_start();
@ -2794,7 +2795,7 @@ RefPtr<BindingPattern> Parser::parse_binding_pattern(Parser::AllowDuplicates all
decltype(BindingPattern::BindingEntry::name) name = Empty {}; decltype(BindingPattern::BindingEntry::name) name = Empty {};
decltype(BindingPattern::BindingEntry::alias) alias = Empty {}; decltype(BindingPattern::BindingEntry::alias) alias = Empty {};
RefPtr<Expression> initializer = {}; RefPtr<Expression const> initializer = {};
if (is_object) { if (is_object) {
bool needs_alias = false; bool needs_alias = false;
@ -2802,9 +2803,9 @@ RefPtr<BindingPattern> Parser::parse_binding_pattern(Parser::AllowDuplicates all
auto expression_position = position(); auto expression_position = position();
auto expression = parse_expression(2, Associativity::Right, { TokenType::Equals }); auto expression = parse_expression(2, Associativity::Right, { TokenType::Equals });
if (is<MemberExpression>(*expression)) if (is<MemberExpression>(*expression))
alias = static_ptr_cast<MemberExpression>(expression); alias = static_ptr_cast<MemberExpression const>(expression);
else if (is<Identifier>(*expression)) else if (is<Identifier>(*expression))
name = static_ptr_cast<Identifier>(expression); name = static_ptr_cast<Identifier const>(expression);
else else
syntax_error("Invalid destructuring assignment target", expression_position); syntax_error("Invalid destructuring assignment target", expression_position);
} else if (match_identifier_name() || match(TokenType::StringLiteral) || match(TokenType::NumericLiteral) || match(TokenType::BigIntLiteral)) { } else if (match_identifier_name() || match(TokenType::StringLiteral) || match(TokenType::NumericLiteral) || match(TokenType::BigIntLiteral)) {
@ -2815,17 +2816,17 @@ RefPtr<BindingPattern> Parser::parse_binding_pattern(Parser::AllowDuplicates all
auto token = consume(TokenType::StringLiteral); auto token = consume(TokenType::StringLiteral);
auto string_literal = parse_string_literal(token); auto string_literal = parse_string_literal(token);
name = create_ast_node<Identifier>( name = create_ast_node<Identifier const>(
{ m_source_code, rule_start.position(), position() }, { m_source_code, rule_start.position(), position() },
string_literal->value()); string_literal->value());
} else if (match(TokenType::BigIntLiteral)) { } else if (match(TokenType::BigIntLiteral)) {
auto string_value = consume().DeprecatedFlyString_value(); auto string_value = consume().DeprecatedFlyString_value();
VERIFY(string_value.ends_with("n"sv)); VERIFY(string_value.ends_with("n"sv));
name = create_ast_node<Identifier>( name = create_ast_node<Identifier const>(
{ m_source_code, rule_start.position(), position() }, { m_source_code, rule_start.position(), position() },
DeprecatedFlyString(string_value.view().substring_view(0, string_value.length() - 1))); DeprecatedFlyString(string_value.view().substring_view(0, string_value.length() - 1)));
} else { } else {
name = create_ast_node<Identifier>( name = create_ast_node<Identifier const>(
{ m_source_code, rule_start.position(), position() }, { m_source_code, rule_start.position(), position() },
consume().DeprecatedFlyString_value()); consume().DeprecatedFlyString_value());
} }
@ -2851,9 +2852,9 @@ RefPtr<BindingPattern> Parser::parse_binding_pattern(Parser::AllowDuplicates all
else else
syntax_error("Invalid destructuring assignment target", expression_position); syntax_error("Invalid destructuring assignment target", expression_position);
} else if (is<MemberExpression>(*expression)) { } else if (is<MemberExpression>(*expression)) {
alias = static_ptr_cast<MemberExpression>(expression); alias = static_ptr_cast<MemberExpression const>(expression);
} else if (is<Identifier>(*expression)) { } else if (is<Identifier>(*expression)) {
alias = static_ptr_cast<Identifier>(expression); alias = static_ptr_cast<Identifier const>(expression);
} else { } else {
syntax_error("Invalid destructuring assignment target", expression_position); syntax_error("Invalid destructuring assignment target", expression_position);
} }
@ -2863,7 +2864,7 @@ RefPtr<BindingPattern> Parser::parse_binding_pattern(Parser::AllowDuplicates all
return {}; return {};
alias = binding_pattern.release_nonnull(); alias = binding_pattern.release_nonnull();
} else if (match_identifier_name()) { } else if (match_identifier_name()) {
alias = create_ast_node<Identifier>( alias = create_ast_node<Identifier const>(
{ m_source_code, rule_start.position(), position() }, { m_source_code, rule_start.position(), position() },
consume().DeprecatedFlyString_value()); consume().DeprecatedFlyString_value());
@ -2886,9 +2887,9 @@ RefPtr<BindingPattern> Parser::parse_binding_pattern(Parser::AllowDuplicates all
else else
syntax_error("Invalid destructuring assignment target", expression_position); syntax_error("Invalid destructuring assignment target", expression_position);
} else if (is<MemberExpression>(*expression)) { } else if (is<MemberExpression>(*expression)) {
alias = static_ptr_cast<MemberExpression>(expression); alias = static_ptr_cast<MemberExpression const>(expression);
} else if (is<Identifier>(*expression)) { } else if (is<Identifier>(*expression)) {
alias = static_ptr_cast<Identifier>(expression); alias = static_ptr_cast<Identifier const>(expression);
} else { } else {
syntax_error("Invalid destructuring assignment target", expression_position); syntax_error("Invalid destructuring assignment target", expression_position);
} }
@ -2902,7 +2903,7 @@ RefPtr<BindingPattern> Parser::parse_binding_pattern(Parser::AllowDuplicates all
} else if (match_identifier_name()) { } else if (match_identifier_name()) {
// BindingElement must always have an Empty name field // BindingElement must always have an Empty name field
auto identifier_name = consume_identifier().DeprecatedFlyString_value(); auto identifier_name = consume_identifier().DeprecatedFlyString_value();
alias = create_ast_node<Identifier>( alias = create_ast_node<Identifier const>(
{ m_source_code, rule_start.position(), position() }, { m_source_code, rule_start.position(), position() },
identifier_name); identifier_name);
} else { } else {
@ -2962,7 +2963,7 @@ RefPtr<BindingPattern> Parser::parse_binding_pattern(Parser::AllowDuplicates all
return pattern; return pattern;
} }
RefPtr<Identifier> Parser::parse_lexical_binding() RefPtr<Identifier const> Parser::parse_lexical_binding()
{ {
auto binding_start = push_start(); auto binding_start = push_start();
@ -2992,7 +2993,7 @@ RefPtr<Identifier> Parser::parse_lexical_binding()
return {}; return {};
} }
NonnullRefPtr<VariableDeclaration> Parser::parse_variable_declaration(IsForLoopVariableDeclaration is_for_loop_variable_declaration) NonnullRefPtr<VariableDeclaration const> Parser::parse_variable_declaration(IsForLoopVariableDeclaration is_for_loop_variable_declaration)
{ {
auto rule_start = push_start(); auto rule_start = push_start();
DeclarationKind declaration_kind; DeclarationKind declaration_kind;
@ -3012,9 +3013,9 @@ NonnullRefPtr<VariableDeclaration> Parser::parse_variable_declaration(IsForLoopV
} }
consume(); consume();
NonnullRefPtrVector<VariableDeclarator> declarations; NonnullRefPtrVector<VariableDeclarator const> declarations;
for (;;) { for (;;) {
Variant<NonnullRefPtr<Identifier>, NonnullRefPtr<BindingPattern>, Empty> target {}; Variant<NonnullRefPtr<Identifier const>, NonnullRefPtr<BindingPattern const>, Empty> target {};
if (auto pattern = parse_binding_pattern(declaration_kind != DeclarationKind::Var ? AllowDuplicates::No : AllowDuplicates::Yes, AllowMemberExpressions::No)) { if (auto pattern = parse_binding_pattern(declaration_kind != DeclarationKind::Var ? AllowDuplicates::No : AllowDuplicates::Yes, AllowMemberExpressions::No)) {
if ((declaration_kind == DeclarationKind::Let || declaration_kind == DeclarationKind::Const)) { if ((declaration_kind == DeclarationKind::Let || declaration_kind == DeclarationKind::Const)) {
pattern->for_each_bound_name([this](auto& name) { pattern->for_each_bound_name([this](auto& name) {
@ -3041,7 +3042,7 @@ NonnullRefPtr<VariableDeclaration> Parser::parse_variable_declaration(IsForLoopV
break; break;
} }
RefPtr<Expression> init; RefPtr<Expression const> init;
if (match(TokenType::Equals)) { if (match(TokenType::Equals)) {
consume(); consume();
// In a for loop 'in' can be ambiguous so we do not allow it // In a for loop 'in' can be ambiguous so we do not allow it
@ -3052,13 +3053,13 @@ NonnullRefPtr<VariableDeclaration> Parser::parse_variable_declaration(IsForLoopV
init = parse_expression(2); init = parse_expression(2);
} else if (is_for_loop_variable_declaration == IsForLoopVariableDeclaration::No && declaration_kind == DeclarationKind::Const) { } else if (is_for_loop_variable_declaration == IsForLoopVariableDeclaration::No && declaration_kind == DeclarationKind::Const) {
syntax_error("Missing initializer in 'const' variable declaration"); syntax_error("Missing initializer in 'const' variable declaration");
} else if (is_for_loop_variable_declaration == IsForLoopVariableDeclaration::No && target.has<NonnullRefPtr<BindingPattern>>()) { } else if (is_for_loop_variable_declaration == IsForLoopVariableDeclaration::No && target.has<NonnullRefPtr<BindingPattern const>>()) {
syntax_error("Missing initializer in destructuring assignment"); syntax_error("Missing initializer in destructuring assignment");
} }
declarations.append(create_ast_node<VariableDeclarator>( declarations.append(create_ast_node<VariableDeclarator>(
{ m_source_code, rule_start.position(), position() }, { m_source_code, rule_start.position(), position() },
move(target).downcast<NonnullRefPtr<Identifier>, NonnullRefPtr<BindingPattern>>(), move(target).downcast<NonnullRefPtr<Identifier const>, NonnullRefPtr<BindingPattern const>>(),
move(init))); move(init)));
if (match(TokenType::Comma)) { if (match(TokenType::Comma)) {
@ -3076,14 +3077,14 @@ NonnullRefPtr<VariableDeclaration> Parser::parse_variable_declaration(IsForLoopV
return declaration; return declaration;
} }
NonnullRefPtr<UsingDeclaration> Parser::parse_using_declaration(IsForLoopVariableDeclaration is_for_loop_variable_declaration) NonnullRefPtr<UsingDeclaration const> Parser::parse_using_declaration(IsForLoopVariableDeclaration is_for_loop_variable_declaration)
{ {
// using [no LineTerminator here] BindingList[?In, ?Yield, ?Await, +Using] ; // using [no LineTerminator here] BindingList[?In, ?Yield, ?Await, +Using] ;
auto rule_start = push_start(); auto rule_start = push_start();
VERIFY(m_state.current_token.original_value() == "using"sv); VERIFY(m_state.current_token.original_value() == "using"sv);
consume(TokenType::Identifier); consume(TokenType::Identifier);
VERIFY(!m_state.current_token.trivia_contains_line_terminator()); VERIFY(!m_state.current_token.trivia_contains_line_terminator());
NonnullRefPtrVector<VariableDeclarator> declarations; NonnullRefPtrVector<VariableDeclarator const> declarations;
for (;;) { for (;;) {
auto lexical_binding = parse_lexical_binding(); auto lexical_binding = parse_lexical_binding();
@ -3096,7 +3097,7 @@ NonnullRefPtr<UsingDeclaration> Parser::parse_using_declaration(IsForLoopVariabl
if (lexical_binding->string() == "let"sv) if (lexical_binding->string() == "let"sv)
syntax_error("Lexical binding may not be called 'let'"); syntax_error("Lexical binding may not be called 'let'");
RefPtr<Expression> initializer; RefPtr<Expression const> initializer;
if (match(TokenType::Equals)) { if (match(TokenType::Equals)) {
consume(); consume();
@ -3125,7 +3126,7 @@ NonnullRefPtr<UsingDeclaration> Parser::parse_using_declaration(IsForLoopVariabl
return create_ast_node<UsingDeclaration>({ m_source_code, rule_start.position(), position() }, move(declarations)); return create_ast_node<UsingDeclaration>({ m_source_code, rule_start.position(), position() }, move(declarations));
} }
NonnullRefPtr<ThrowStatement> Parser::parse_throw_statement() NonnullRefPtr<ThrowStatement const> Parser::parse_throw_statement()
{ {
auto rule_start = push_start(); auto rule_start = push_start();
consume(TokenType::Throw); consume(TokenType::Throw);
@ -3141,7 +3142,7 @@ NonnullRefPtr<ThrowStatement> Parser::parse_throw_statement()
return create_ast_node<ThrowStatement>({ m_source_code, rule_start.position(), position() }, move(expression)); return create_ast_node<ThrowStatement>({ m_source_code, rule_start.position(), position() }, move(expression));
} }
NonnullRefPtr<BreakStatement> Parser::parse_break_statement() NonnullRefPtr<BreakStatement const> Parser::parse_break_statement()
{ {
auto rule_start = push_start(); auto rule_start = push_start();
consume(TokenType::Break); consume(TokenType::Break);
@ -3165,7 +3166,7 @@ NonnullRefPtr<BreakStatement> Parser::parse_break_statement()
return create_ast_node<BreakStatement>({ m_source_code, rule_start.position(), position() }, target_label); return create_ast_node<BreakStatement>({ m_source_code, rule_start.position(), position() }, target_label);
} }
NonnullRefPtr<ContinueStatement> Parser::parse_continue_statement() NonnullRefPtr<ContinueStatement const> Parser::parse_continue_statement()
{ {
auto rule_start = push_start(); auto rule_start = push_start();
if (!m_state.in_continue_context) if (!m_state.in_continue_context)
@ -3191,7 +3192,7 @@ NonnullRefPtr<ContinueStatement> Parser::parse_continue_statement()
return create_ast_node<ContinueStatement>({ m_source_code, rule_start.position(), position() }, target_label); return create_ast_node<ContinueStatement>({ m_source_code, rule_start.position(), position() }, target_label);
} }
NonnullRefPtr<ConditionalExpression> Parser::parse_conditional_expression(NonnullRefPtr<Expression> test, ForbiddenTokens forbidden) NonnullRefPtr<ConditionalExpression const> Parser::parse_conditional_expression(NonnullRefPtr<Expression const> test, ForbiddenTokens forbidden)
{ {
auto rule_start = push_start(); auto rule_start = push_start();
consume(TokenType::QuestionMark); consume(TokenType::QuestionMark);
@ -3201,7 +3202,7 @@ NonnullRefPtr<ConditionalExpression> Parser::parse_conditional_expression(Nonnul
return create_ast_node<ConditionalExpression>({ m_source_code, rule_start.position(), position() }, move(test), move(consequent), move(alternate)); return create_ast_node<ConditionalExpression>({ m_source_code, rule_start.position(), position() }, move(test), move(consequent), move(alternate));
} }
NonnullRefPtr<OptionalChain> Parser::parse_optional_chain(NonnullRefPtr<Expression> base) NonnullRefPtr<OptionalChain const> Parser::parse_optional_chain(NonnullRefPtr<Expression const> base)
{ {
auto rule_start = push_start(); auto rule_start = push_start();
Vector<OptionalChain::Reference> chain; Vector<OptionalChain::Reference> chain;
@ -3296,18 +3297,18 @@ NonnullRefPtr<OptionalChain> Parser::parse_optional_chain(NonnullRefPtr<Expressi
move(chain)); move(chain));
} }
NonnullRefPtr<TryStatement> Parser::parse_try_statement() NonnullRefPtr<TryStatement const> Parser::parse_try_statement()
{ {
auto rule_start = push_start(); auto rule_start = push_start();
consume(TokenType::Try); consume(TokenType::Try);
auto block = parse_block_statement(); auto block = parse_block_statement();
RefPtr<CatchClause> handler; RefPtr<CatchClause const> handler;
if (match(TokenType::Catch)) if (match(TokenType::Catch))
handler = parse_catch_clause(); handler = parse_catch_clause();
RefPtr<BlockStatement> finalizer; RefPtr<BlockStatement const> finalizer;
if (match(TokenType::Finally)) { if (match(TokenType::Finally)) {
consume(); consume();
finalizer = parse_block_statement(); finalizer = parse_block_statement();
@ -3319,12 +3320,12 @@ NonnullRefPtr<TryStatement> Parser::parse_try_statement()
return create_ast_node<TryStatement>({ m_source_code, rule_start.position(), position() }, move(block), move(handler), move(finalizer)); return create_ast_node<TryStatement>({ m_source_code, rule_start.position(), position() }, move(block), move(handler), move(finalizer));
} }
NonnullRefPtr<DoWhileStatement> Parser::parse_do_while_statement() NonnullRefPtr<DoWhileStatement const> Parser::parse_do_while_statement()
{ {
auto rule_start = push_start(); auto rule_start = push_start();
consume(TokenType::Do); consume(TokenType::Do);
auto body = [&]() -> NonnullRefPtr<Statement> { auto body = [&]() -> NonnullRefPtr<Statement const> {
TemporaryChange break_change(m_state.in_break_context, true); TemporaryChange break_change(m_state.in_break_context, true);
TemporaryChange continue_change(m_state.in_continue_context, true); TemporaryChange continue_change(m_state.in_continue_context, true);
return parse_statement(); return parse_statement();
@ -3344,7 +3345,7 @@ NonnullRefPtr<DoWhileStatement> Parser::parse_do_while_statement()
return create_ast_node<DoWhileStatement>({ m_source_code, rule_start.position(), position() }, move(test), move(body)); return create_ast_node<DoWhileStatement>({ m_source_code, rule_start.position(), position() }, move(test), move(body));
} }
NonnullRefPtr<WhileStatement> Parser::parse_while_statement() NonnullRefPtr<WhileStatement const> Parser::parse_while_statement()
{ {
auto rule_start = push_start(); auto rule_start = push_start();
consume(TokenType::While); consume(TokenType::While);
@ -3361,7 +3362,7 @@ NonnullRefPtr<WhileStatement> Parser::parse_while_statement()
return create_ast_node<WhileStatement>({ m_source_code, rule_start.position(), position() }, move(test), move(body)); return create_ast_node<WhileStatement>({ m_source_code, rule_start.position(), position() }, move(test), move(body));
} }
NonnullRefPtr<SwitchStatement> Parser::parse_switch_statement() NonnullRefPtr<SwitchStatement const> Parser::parse_switch_statement()
{ {
auto rule_start = push_start(); auto rule_start = push_start();
consume(TokenType::Switch); consume(TokenType::Switch);
@ -3393,7 +3394,7 @@ NonnullRefPtr<SwitchStatement> Parser::parse_switch_statement()
return switch_statement; return switch_statement;
} }
NonnullRefPtr<WithStatement> Parser::parse_with_statement() NonnullRefPtr<WithStatement const> Parser::parse_with_statement()
{ {
auto rule_start = push_start(); auto rule_start = push_start();
consume(TokenType::With); consume(TokenType::With);
@ -3407,10 +3408,10 @@ NonnullRefPtr<WithStatement> Parser::parse_with_statement()
return create_ast_node<WithStatement>({ m_source_code, rule_start.position(), position() }, move(object), move(body)); return create_ast_node<WithStatement>({ m_source_code, rule_start.position(), position() }, move(object), move(body));
} }
NonnullRefPtr<SwitchCase> Parser::parse_switch_case() NonnullRefPtr<SwitchCase const> Parser::parse_switch_case()
{ {
auto rule_start = push_start(); auto rule_start = push_start();
RefPtr<Expression> test; RefPtr<Expression const> test;
if (consume().type() == TokenType::Case) { if (consume().type() == TokenType::Case) {
test = parse_expression(0); test = parse_expression(0);
@ -3426,13 +3427,13 @@ NonnullRefPtr<SwitchCase> Parser::parse_switch_case()
return switch_case; return switch_case;
} }
NonnullRefPtr<CatchClause> Parser::parse_catch_clause() NonnullRefPtr<CatchClause const> Parser::parse_catch_clause()
{ {
auto rule_start = push_start(); auto rule_start = push_start();
consume(TokenType::Catch); consume(TokenType::Catch);
DeprecatedFlyString parameter; DeprecatedFlyString parameter;
RefPtr<BindingPattern> pattern_parameter; RefPtr<BindingPattern const> pattern_parameter;
auto should_expect_parameter = false; auto should_expect_parameter = false;
if (match(TokenType::ParenOpen)) { if (match(TokenType::ParenOpen)) {
should_expect_parameter = true; should_expect_parameter = true;
@ -3486,7 +3487,7 @@ NonnullRefPtr<CatchClause> Parser::parse_catch_clause()
move(body)); move(body));
} }
NonnullRefPtr<IfStatement> Parser::parse_if_statement() NonnullRefPtr<IfStatement const> Parser::parse_if_statement()
{ {
auto rule_start = push_start(); auto rule_start = push_start();
auto parse_function_declaration_as_block_statement = [&] { auto parse_function_declaration_as_block_statement = [&] {
@ -3519,13 +3520,13 @@ NonnullRefPtr<IfStatement> Parser::parse_if_statement()
auto predicate = parse_expression(0); auto predicate = parse_expression(0);
consume(TokenType::ParenClose); consume(TokenType::ParenClose);
RefPtr<Statement> consequent; RefPtr<Statement const> consequent;
if (!m_state.strict_mode && match(TokenType::Function)) if (!m_state.strict_mode && match(TokenType::Function))
consequent = parse_function_declaration_as_block_statement(); consequent = parse_function_declaration_as_block_statement();
else else
consequent = parse_statement(); consequent = parse_statement();
RefPtr<Statement> alternate; RefPtr<Statement const> alternate;
if (match(TokenType::Else)) { if (match(TokenType::Else)) {
consume(); consume();
if (!m_state.strict_mode && match(TokenType::Function)) if (!m_state.strict_mode && match(TokenType::Function))
@ -3536,7 +3537,7 @@ NonnullRefPtr<IfStatement> Parser::parse_if_statement()
return create_ast_node<IfStatement>({ m_source_code, rule_start.position(), position() }, move(predicate), move(*consequent), move(alternate)); return create_ast_node<IfStatement>({ m_source_code, rule_start.position(), position() }, move(predicate), move(*consequent), move(alternate));
} }
NonnullRefPtr<Statement> Parser::parse_for_statement() NonnullRefPtr<Statement const> Parser::parse_for_statement()
{ {
auto rule_start = push_start(); auto rule_start = push_start();
auto is_await_loop = IsForAwaitLoop::No; auto is_await_loop = IsForAwaitLoop::No;
@ -3571,7 +3572,7 @@ NonnullRefPtr<Statement> Parser::parse_for_statement()
Optional<ScopePusher> scope_pusher; Optional<ScopePusher> scope_pusher;
RefPtr<ASTNode> init; RefPtr<ASTNode const> init;
if (!match(TokenType::Semicolon)) { if (!match(TokenType::Semicolon)) {
auto match_for_using_declaration = [&] { auto match_for_using_declaration = [&] {
@ -3650,13 +3651,13 @@ NonnullRefPtr<Statement> Parser::parse_for_statement()
} }
consume(TokenType::Semicolon); consume(TokenType::Semicolon);
RefPtr<Expression> test; RefPtr<Expression const> test;
if (!match(TokenType::Semicolon)) if (!match(TokenType::Semicolon))
test = parse_expression(0); test = parse_expression(0);
consume(TokenType::Semicolon); consume(TokenType::Semicolon);
RefPtr<Expression> update; RefPtr<Expression const> update;
if (!match(TokenType::ParenClose)) if (!match(TokenType::ParenClose))
update = parse_expression(0); update = parse_expression(0);
@ -3670,21 +3671,21 @@ NonnullRefPtr<Statement> Parser::parse_for_statement()
return create_ast_node<ForStatement>({ m_source_code, rule_start.position(), position() }, move(init), move(test), move(update), move(body)); return create_ast_node<ForStatement>({ m_source_code, rule_start.position(), position() }, move(init), move(test), move(update), move(body));
} }
NonnullRefPtr<Statement> Parser::parse_for_in_of_statement(NonnullRefPtr<ASTNode> lhs, IsForAwaitLoop is_for_await_loop) NonnullRefPtr<Statement const> Parser::parse_for_in_of_statement(NonnullRefPtr<ASTNode const> lhs, IsForAwaitLoop is_for_await_loop)
{ {
Variant<NonnullRefPtr<ASTNode>, NonnullRefPtr<BindingPattern>> for_declaration = lhs; Variant<NonnullRefPtr<ASTNode const>, NonnullRefPtr<BindingPattern const>> for_declaration = lhs;
auto rule_start = push_start(); auto rule_start = push_start();
auto has_annexB_for_in_init_extension = false; auto has_annexB_for_in_init_extension = false;
if (is<VariableDeclaration>(*lhs)) { if (is<VariableDeclaration>(*lhs)) {
auto& declaration = static_cast<VariableDeclaration&>(*lhs); auto& declaration = static_cast<VariableDeclaration const&>(*lhs);
// Syntax errors for wrong amounts of declaration should have already been hit. // Syntax errors for wrong amounts of declaration should have already been hit.
if (!declaration.declarations().is_empty()) { if (!declaration.declarations().is_empty()) {
// AnnexB extension B.3.5 Initializers in ForIn Statement Heads, https://tc39.es/ecma262/#sec-initializers-in-forin-statement-heads // AnnexB extension B.3.5 Initializers in ForIn Statement Heads, https://tc39.es/ecma262/#sec-initializers-in-forin-statement-heads
auto& variable = declaration.declarations().first(); auto& variable = declaration.declarations().first();
if (variable.init()) { if (variable.init()) {
if (m_state.strict_mode || declaration.declaration_kind() != DeclarationKind::Var || !variable.target().has<NonnullRefPtr<Identifier>>()) if (m_state.strict_mode || declaration.declaration_kind() != DeclarationKind::Var || !variable.target().has<NonnullRefPtr<Identifier const>>())
syntax_error("Variable initializer not allowed in for..in/of"); syntax_error("Variable initializer not allowed in for..in/of");
else else
has_annexB_for_in_init_extension = true; has_annexB_for_in_init_extension = true;
@ -3729,7 +3730,7 @@ NonnullRefPtr<Statement> Parser::parse_for_in_of_statement(NonnullRefPtr<ASTNode
return create_ast_node<ForOfStatement>({ m_source_code, rule_start.position(), position() }, move(for_declaration), move(rhs), move(body)); return create_ast_node<ForOfStatement>({ m_source_code, rule_start.position(), position() }, move(for_declaration), move(rhs), move(body));
} }
NonnullRefPtr<DebuggerStatement> Parser::parse_debugger_statement() NonnullRefPtr<DebuggerStatement const> Parser::parse_debugger_statement()
{ {
auto rule_start = push_start(); auto rule_start = push_start();
consume(TokenType::Debugger); consume(TokenType::Debugger);
@ -4280,7 +4281,7 @@ ModuleRequest Parser::parse_module_request()
static DeprecatedFlyString default_string_value = "default"; static DeprecatedFlyString default_string_value = "default";
NonnullRefPtr<ImportStatement> Parser::parse_import_statement(Program& program) NonnullRefPtr<ImportStatement const> Parser::parse_import_statement(Program& program)
{ {
// We use the extended syntax which adds: // We use the extended syntax which adds:
// ImportDeclaration: // ImportDeclaration:
@ -4440,7 +4441,7 @@ NonnullRefPtr<ImportStatement> Parser::parse_import_statement(Program& program)
return create_ast_node<ImportStatement>({ m_source_code, rule_start.position(), position() }, move(module_request), move(entries)); return create_ast_node<ImportStatement>({ m_source_code, rule_start.position(), position() }, move(module_request), move(entries));
} }
NonnullRefPtr<ExportStatement> Parser::parse_export_statement(Program& program) NonnullRefPtr<ExportStatement const> Parser::parse_export_statement(Program& program)
{ {
// We use the extended syntax which adds: // We use the extended syntax which adds:
// ExportDeclaration: // ExportDeclaration:
@ -4472,7 +4473,7 @@ NonnullRefPtr<ExportStatement> Parser::parse_export_statement(Program& program)
Vector<EntryAndLocation> entries_with_location; Vector<EntryAndLocation> entries_with_location;
RefPtr<ASTNode> expression = {}; RefPtr<ASTNode const> expression = {};
bool is_default = false; bool is_default = false;
ModuleRequest from_specifier; ModuleRequest from_specifier;
@ -4575,7 +4576,7 @@ NonnullRefPtr<ExportStatement> Parser::parse_export_statement(Program& program)
consume_or_insert_semicolon(); consume_or_insert_semicolon();
if (is<ClassExpression>(*expression)) { if (is<ClassExpression>(*expression)) {
auto const& class_expression = static_cast<ClassExpression&>(*expression); auto const& class_expression = static_cast<ClassExpression const&>(*expression);
if (class_expression.has_name()) if (class_expression.has_name())
local_name = class_expression.name(); local_name = class_expression.name();
} }
@ -4634,21 +4635,21 @@ NonnullRefPtr<ExportStatement> Parser::parse_export_statement(Program& program)
auto declaration = parse_declaration(); auto declaration = parse_declaration();
m_state.current_scope_pusher->add_declaration(declaration); m_state.current_scope_pusher->add_declaration(declaration);
if (is<FunctionDeclaration>(*declaration)) { if (is<FunctionDeclaration>(*declaration)) {
auto& func = static_cast<FunctionDeclaration&>(*declaration); auto& func = static_cast<FunctionDeclaration const&>(*declaration);
entries_with_location.append({ ExportEntry::named_export(func.name(), func.name()), func.source_range().start }); entries_with_location.append({ ExportEntry::named_export(func.name(), func.name()), func.source_range().start });
} else if (is<ClassDeclaration>(*declaration)) { } else if (is<ClassDeclaration>(*declaration)) {
auto& class_declaration = static_cast<ClassDeclaration&>(*declaration); auto& class_declaration = static_cast<ClassDeclaration const&>(*declaration);
entries_with_location.append({ ExportEntry::named_export(class_declaration.name(), class_declaration.name()), class_declaration.source_range().start }); entries_with_location.append({ ExportEntry::named_export(class_declaration.name(), class_declaration.name()), class_declaration.source_range().start });
} else { } else {
VERIFY(is<VariableDeclaration>(*declaration)); VERIFY(is<VariableDeclaration>(*declaration));
auto& variables = static_cast<VariableDeclaration&>(*declaration); auto& variables = static_cast<VariableDeclaration const&>(*declaration);
VERIFY(variables.is_lexical_declaration()); VERIFY(variables.is_lexical_declaration());
for (auto& decl : variables.declarations()) { for (auto& decl : variables.declarations()) {
decl.target().visit( decl.target().visit(
[&](NonnullRefPtr<Identifier> const& identifier) { [&](NonnullRefPtr<Identifier const> const& identifier) {
entries_with_location.append({ ExportEntry::named_export(identifier->string(), identifier->string()), identifier->source_range().start }); entries_with_location.append({ ExportEntry::named_export(identifier->string(), identifier->string()), identifier->source_range().start });
}, },
[&](NonnullRefPtr<BindingPattern> const& binding) { [&](NonnullRefPtr<BindingPattern const> const& binding) {
binding->for_each_bound_name([&](auto& name) { binding->for_each_bound_name([&](auto& name) {
entries_with_location.append({ ExportEntry::named_export(name, name), decl_position }); entries_with_location.append({ ExportEntry::named_export(name, name), decl_position });
}); });
@ -4662,10 +4663,10 @@ NonnullRefPtr<ExportStatement> Parser::parse_export_statement(Program& program)
m_state.current_scope_pusher->add_declaration(variable_declaration); m_state.current_scope_pusher->add_declaration(variable_declaration);
for (auto& decl : variable_declaration->declarations()) { for (auto& decl : variable_declaration->declarations()) {
decl.target().visit( decl.target().visit(
[&](NonnullRefPtr<Identifier> const& identifier) { [&](NonnullRefPtr<Identifier const> const& identifier) {
entries_with_location.append({ ExportEntry::named_export(identifier->string(), identifier->string()), identifier->source_range().start }); entries_with_location.append({ ExportEntry::named_export(identifier->string(), identifier->string()), identifier->source_range().start });
}, },
[&](NonnullRefPtr<BindingPattern> const& binding) { [&](NonnullRefPtr<BindingPattern const> const& binding) {
binding->for_each_bound_name([&](auto& name) { binding->for_each_bound_name([&](auto& name) {
entries_with_location.append({ ExportEntry::named_export(name, name), variable_position }); entries_with_location.append({ ExportEntry::named_export(name, name), variable_position });
}); });

View file

@ -1,6 +1,7 @@
/* /*
* Copyright (c) 2020, Stephan Unverwerth <s.unverwerth@serenityos.org> * Copyright (c) 2020, Stephan Unverwerth <s.unverwerth@serenityos.org>
* Copyright (c) 2021-2022, David Tuin <davidot@serenityos.org> * Copyright (c) 2021-2022, David Tuin <davidot@serenityos.org>
* Copyright (c) 2023, Andreas Kling <kling@serenityos.org>
* *
* SPDX-License-Identifier: BSD-2-Clause * SPDX-License-Identifier: BSD-2-Clause
*/ */
@ -70,34 +71,34 @@ public:
No No
}; };
RefPtr<BindingPattern> parse_binding_pattern(AllowDuplicates is_var_declaration = AllowDuplicates::No, AllowMemberExpressions allow_member_expressions = AllowMemberExpressions::No); RefPtr<BindingPattern const> parse_binding_pattern(AllowDuplicates is_var_declaration = AllowDuplicates::No, AllowMemberExpressions allow_member_expressions = AllowMemberExpressions::No);
struct PrimaryExpressionParseResult { struct PrimaryExpressionParseResult {
NonnullRefPtr<Expression> result; NonnullRefPtr<Expression const> result;
bool should_continue_parsing_as_expression { true }; bool should_continue_parsing_as_expression { true };
}; };
NonnullRefPtr<Declaration> parse_declaration(); NonnullRefPtr<Declaration const> parse_declaration();
enum class AllowLabelledFunction { enum class AllowLabelledFunction {
No, No,
Yes Yes
}; };
NonnullRefPtr<Statement> parse_statement(AllowLabelledFunction allow_labelled_function = AllowLabelledFunction::No); NonnullRefPtr<Statement const> parse_statement(AllowLabelledFunction allow_labelled_function = AllowLabelledFunction::No);
NonnullRefPtr<BlockStatement> parse_block_statement(); NonnullRefPtr<BlockStatement const> parse_block_statement();
NonnullRefPtr<FunctionBody> parse_function_body(Vector<FunctionParameter> const& parameters, FunctionKind function_kind, bool& contains_direct_call_to_eval); NonnullRefPtr<FunctionBody const> parse_function_body(Vector<FunctionParameter> const& parameters, FunctionKind function_kind, bool& contains_direct_call_to_eval);
NonnullRefPtr<ReturnStatement> parse_return_statement(); NonnullRefPtr<ReturnStatement const> parse_return_statement();
enum class IsForLoopVariableDeclaration { enum class IsForLoopVariableDeclaration {
No, No,
Yes Yes
}; };
NonnullRefPtr<VariableDeclaration> parse_variable_declaration(IsForLoopVariableDeclaration is_for_loop_variable_declaration = IsForLoopVariableDeclaration::No); NonnullRefPtr<VariableDeclaration const> parse_variable_declaration(IsForLoopVariableDeclaration is_for_loop_variable_declaration = IsForLoopVariableDeclaration::No);
RefPtr<Identifier> parse_lexical_binding(); RefPtr<Identifier const> parse_lexical_binding();
NonnullRefPtr<UsingDeclaration> parse_using_declaration(IsForLoopVariableDeclaration is_for_loop_variable_declaration = IsForLoopVariableDeclaration::No); NonnullRefPtr<UsingDeclaration const> parse_using_declaration(IsForLoopVariableDeclaration is_for_loop_variable_declaration = IsForLoopVariableDeclaration::No);
NonnullRefPtr<Statement> parse_for_statement(); NonnullRefPtr<Statement const> parse_for_statement();
enum class IsForAwaitLoop { enum class IsForAwaitLoop {
No, No,
@ -122,36 +123,43 @@ public:
struct ExpressionResult { struct ExpressionResult {
template<typename T> template<typename T>
ExpressionResult(NonnullRefPtr<T> expression, ForbiddenTokens forbidden = {}) ExpressionResult(NonnullRefPtr<T const> expression, ForbiddenTokens forbidden = {})
: expression(expression) : expression(move(expression))
, forbidden(forbidden) , forbidden(forbidden)
{ {
} }
NonnullRefPtr<Expression> expression;
template<typename T>
ExpressionResult(NonnullRefPtr<T> expression, ForbiddenTokens forbidden = {})
: expression(move(expression))
, forbidden(forbidden)
{
}
NonnullRefPtr<Expression const> expression;
ForbiddenTokens forbidden; ForbiddenTokens forbidden;
}; };
NonnullRefPtr<Statement> parse_for_in_of_statement(NonnullRefPtr<ASTNode> lhs, IsForAwaitLoop is_await); NonnullRefPtr<Statement const> parse_for_in_of_statement(NonnullRefPtr<ASTNode const> lhs, IsForAwaitLoop is_await);
NonnullRefPtr<IfStatement> parse_if_statement(); NonnullRefPtr<IfStatement const> parse_if_statement();
NonnullRefPtr<ThrowStatement> parse_throw_statement(); NonnullRefPtr<ThrowStatement const> parse_throw_statement();
NonnullRefPtr<TryStatement> parse_try_statement(); NonnullRefPtr<TryStatement const> parse_try_statement();
NonnullRefPtr<CatchClause> parse_catch_clause(); NonnullRefPtr<CatchClause const> parse_catch_clause();
NonnullRefPtr<SwitchStatement> parse_switch_statement(); NonnullRefPtr<SwitchStatement const> parse_switch_statement();
NonnullRefPtr<SwitchCase> parse_switch_case(); NonnullRefPtr<SwitchCase const> parse_switch_case();
NonnullRefPtr<BreakStatement> parse_break_statement(); NonnullRefPtr<BreakStatement const> parse_break_statement();
NonnullRefPtr<ContinueStatement> parse_continue_statement(); NonnullRefPtr<ContinueStatement const> parse_continue_statement();
NonnullRefPtr<DoWhileStatement> parse_do_while_statement(); NonnullRefPtr<DoWhileStatement const> parse_do_while_statement();
NonnullRefPtr<WhileStatement> parse_while_statement(); NonnullRefPtr<WhileStatement const> parse_while_statement();
NonnullRefPtr<WithStatement> parse_with_statement(); NonnullRefPtr<WithStatement const> parse_with_statement();
NonnullRefPtr<DebuggerStatement> parse_debugger_statement(); NonnullRefPtr<DebuggerStatement const> parse_debugger_statement();
NonnullRefPtr<ConditionalExpression> parse_conditional_expression(NonnullRefPtr<Expression> test, ForbiddenTokens); NonnullRefPtr<ConditionalExpression const> parse_conditional_expression(NonnullRefPtr<Expression const> test, ForbiddenTokens);
NonnullRefPtr<OptionalChain> parse_optional_chain(NonnullRefPtr<Expression> base); NonnullRefPtr<OptionalChain const> parse_optional_chain(NonnullRefPtr<Expression const> base);
NonnullRefPtr<Expression> parse_expression(int min_precedence, Associativity associate = Associativity::Right, ForbiddenTokens forbidden = {}); NonnullRefPtr<Expression const> parse_expression(int min_precedence, Associativity associate = Associativity::Right, ForbiddenTokens forbidden = {});
PrimaryExpressionParseResult parse_primary_expression(); PrimaryExpressionParseResult parse_primary_expression();
NonnullRefPtr<Expression> parse_unary_prefixed_expression(); NonnullRefPtr<Expression const> parse_unary_prefixed_expression();
NonnullRefPtr<RegExpLiteral> parse_regexp_literal(); NonnullRefPtr<RegExpLiteral const> parse_regexp_literal();
NonnullRefPtr<ObjectExpression> parse_object_expression(); NonnullRefPtr<ObjectExpression const> parse_object_expression();
NonnullRefPtr<ArrayExpression> parse_array_expression(); NonnullRefPtr<ArrayExpression const> parse_array_expression();
enum class StringLiteralType { enum class StringLiteralType {
Normal, Normal,
@ -159,26 +167,26 @@ public:
TaggedTemplate TaggedTemplate
}; };
NonnullRefPtr<StringLiteral> parse_string_literal(Token const& token, StringLiteralType string_literal_type = StringLiteralType::Normal, bool* contains_invalid_escape = nullptr); NonnullRefPtr<StringLiteral const> parse_string_literal(Token const& token, StringLiteralType string_literal_type = StringLiteralType::Normal, bool* contains_invalid_escape = nullptr);
NonnullRefPtr<TemplateLiteral> parse_template_literal(bool is_tagged); NonnullRefPtr<TemplateLiteral const> parse_template_literal(bool is_tagged);
ExpressionResult parse_secondary_expression(NonnullRefPtr<Expression>, int min_precedence, Associativity associate = Associativity::Right, ForbiddenTokens forbidden = {}); ExpressionResult parse_secondary_expression(NonnullRefPtr<Expression const>, int min_precedence, Associativity associate = Associativity::Right, ForbiddenTokens forbidden = {});
NonnullRefPtr<Expression> parse_call_expression(NonnullRefPtr<Expression>); NonnullRefPtr<Expression const> parse_call_expression(NonnullRefPtr<Expression const>);
NonnullRefPtr<NewExpression> parse_new_expression(); NonnullRefPtr<NewExpression const> parse_new_expression();
NonnullRefPtr<ClassDeclaration> parse_class_declaration(); NonnullRefPtr<ClassDeclaration const> parse_class_declaration();
NonnullRefPtr<ClassExpression> parse_class_expression(bool expect_class_name); NonnullRefPtr<ClassExpression const> parse_class_expression(bool expect_class_name);
NonnullRefPtr<YieldExpression> parse_yield_expression(); NonnullRefPtr<YieldExpression const> parse_yield_expression();
NonnullRefPtr<AwaitExpression> parse_await_expression(); NonnullRefPtr<AwaitExpression const> parse_await_expression();
NonnullRefPtr<Expression> parse_property_key(); NonnullRefPtr<Expression const> parse_property_key();
NonnullRefPtr<AssignmentExpression> parse_assignment_expression(AssignmentOp, NonnullRefPtr<Expression> lhs, int min_precedence, Associativity, ForbiddenTokens forbidden = {}); NonnullRefPtr<AssignmentExpression const> parse_assignment_expression(AssignmentOp, NonnullRefPtr<Expression const> lhs, int min_precedence, Associativity, ForbiddenTokens forbidden = {});
NonnullRefPtr<Identifier> parse_identifier(); NonnullRefPtr<Identifier const> parse_identifier();
NonnullRefPtr<ImportStatement> parse_import_statement(Program& program); NonnullRefPtr<ImportStatement const> parse_import_statement(Program& program);
NonnullRefPtr<ExportStatement> parse_export_statement(Program& program); NonnullRefPtr<ExportStatement const> parse_export_statement(Program& program);
RefPtr<FunctionExpression> try_parse_arrow_function_expression(bool expect_parens, bool is_async = false); RefPtr<FunctionExpression const> try_parse_arrow_function_expression(bool expect_parens, bool is_async = false);
RefPtr<LabelledStatement> try_parse_labelled_statement(AllowLabelledFunction allow_function); RefPtr<LabelledStatement const> try_parse_labelled_statement(AllowLabelledFunction allow_function);
RefPtr<MetaProperty> try_parse_new_target_expression(); RefPtr<MetaProperty const> try_parse_new_target_expression();
RefPtr<MetaProperty> try_parse_import_meta_expression(); RefPtr<MetaProperty const> try_parse_import_meta_expression();
NonnullRefPtr<ImportCall> parse_import_call(); NonnullRefPtr<ImportCall const> parse_import_call();
Vector<CallExpression::Argument> parse_arguments(); Vector<CallExpression::Argument> parse_arguments();
@ -246,7 +254,7 @@ private:
void discard_saved_state(); void discard_saved_state();
Position position() const; Position position() const;
RefPtr<BindingPattern> synthesize_binding_pattern(Expression const& expression); RefPtr<BindingPattern const> synthesize_binding_pattern(Expression const& expression);
Token next_token(size_t steps = 1) const; Token next_token(size_t steps = 1) const;
@ -333,7 +341,7 @@ private:
} }
}; };
NonnullRefPtr<SourceCode> m_source_code; NonnullRefPtr<SourceCode const> m_source_code;
Vector<Position> m_rule_starts; Vector<Position> m_rule_starts;
ParserState m_state; ParserState m_state;
DeprecatedFlyString m_filename; DeprecatedFlyString m_filename;

View file

@ -1,6 +1,7 @@
/* /*
* Copyright (c) 2020, Stephan Unverwerth <s.unverwerth@serenityos.org> * Copyright (c) 2020, Stephan Unverwerth <s.unverwerth@serenityos.org>
* Copyright (c) 2020-2022, Linus Groh <linusg@serenityos.org> * Copyright (c) 2020-2022, Linus Groh <linusg@serenityos.org>
* Copyright (c) 2023, Andreas Kling <kling@serenityos.org>
* *
* SPDX-License-Identifier: BSD-2-Clause * SPDX-License-Identifier: BSD-2-Clause
*/ */
@ -350,7 +351,7 @@ ThrowCompletionOr<void> ECMAScriptFunctionObject::function_declaration_instantia
if (parameter_names.set(name) != AK::HashSetResult::InsertedNewEntry) if (parameter_names.set(name) != AK::HashSetResult::InsertedNewEntry)
has_duplicates = true; has_duplicates = true;
}, },
[&](NonnullRefPtr<BindingPattern> const& pattern) { [&](NonnullRefPtr<BindingPattern const> const& pattern) {
if (pattern->contains_expression()) if (pattern->contains_expression())
has_parameter_expressions = true; has_parameter_expressions = true;
@ -472,7 +473,8 @@ ThrowCompletionOr<void> ECMAScriptFunctionObject::function_declaration_instantia
return reference.put_value(vm, argument_value); return reference.put_value(vm, argument_value);
else else
return reference.initialize_referenced_binding(vm, argument_value); return reference.initialize_referenced_binding(vm, argument_value);
} else if (IsSame<NonnullRefPtr<BindingPattern> const&, decltype(param)>) { }
if constexpr (IsSame<NonnullRefPtr<BindingPattern const> const&, decltype(param)>) {
// Here the difference from hasDuplicates is important // Here the difference from hasDuplicates is important
return vm.binding_initialization(param, argument_value, used_environment); return vm.binding_initialization(param, argument_value, used_environment);
} }
@ -728,7 +730,7 @@ void ECMAScriptFunctionObject::async_function_start(PromiseCapability const& pro
} }
// 27.7.5.2 AsyncBlockStart ( promiseCapability, asyncBody, asyncContext ), https://tc39.es/ecma262/#sec-asyncblockstart // 27.7.5.2 AsyncBlockStart ( promiseCapability, asyncBody, asyncContext ), https://tc39.es/ecma262/#sec-asyncblockstart
void async_block_start(VM& vm, NonnullRefPtr<Statement> const& async_body, PromiseCapability const& promise_capability, ExecutionContext& async_context) void async_block_start(VM& vm, NonnullRefPtr<Statement const> const& async_body, PromiseCapability const& promise_capability, ExecutionContext& async_context)
{ {
auto& realm = *vm.current_realm(); auto& realm = *vm.current_realm();

View file

@ -1,6 +1,7 @@
/* /*
* Copyright (c) 2020-2021, Andreas Kling <kling@serenityos.org> * Copyright (c) 2020-2021, Andreas Kling <kling@serenityos.org>
* Copyright (c) 2020-2022, Linus Groh <linusg@serenityos.org> * Copyright (c) 2020-2022, Linus Groh <linusg@serenityos.org>
* Copyright (c) 2023, Andreas Kling <kling@serenityos.org>
* *
* SPDX-License-Identifier: BSD-2-Clause * SPDX-License-Identifier: BSD-2-Clause
*/ */
@ -14,7 +15,7 @@
namespace JS { namespace JS {
void async_block_start(VM&, NonnullRefPtr<Statement> const& parse_node, PromiseCapability const&, ExecutionContext&); void async_block_start(VM&, NonnullRefPtr<Statement const> const& parse_node, PromiseCapability const&, ExecutionContext&);
// 10.2 ECMAScript Function Objects, https://tc39.es/ecma262/#sec-ecmascript-function-objects // 10.2 ECMAScript Function Objects, https://tc39.es/ecma262/#sec-ecmascript-function-objects
class ECMAScriptFunctionObject final : public FunctionObject { class ECMAScriptFunctionObject final : public FunctionObject {
@ -114,7 +115,7 @@ private:
Environment* m_environment { nullptr }; // [[Environment]] Environment* m_environment { nullptr }; // [[Environment]]
PrivateEnvironment* m_private_environment { nullptr }; // [[PrivateEnvironment]] PrivateEnvironment* m_private_environment { nullptr }; // [[PrivateEnvironment]]
Vector<FunctionParameter> const m_formal_parameters; // [[FormalParameters]] Vector<FunctionParameter> const m_formal_parameters; // [[FormalParameters]]
NonnullRefPtr<Statement> m_ecmascript_code; // [[ECMAScriptCode]] NonnullRefPtr<Statement const> m_ecmascript_code; // [[ECMAScriptCode]]
Realm* m_realm { nullptr }; // [[Realm]] Realm* m_realm { nullptr }; // [[Realm]]
ScriptOrModule m_script_or_module; // [[ScriptOrModule]] ScriptOrModule m_script_or_module; // [[ScriptOrModule]]
Object* m_home_object { nullptr }; // [[HomeObject]] Object* m_home_object { nullptr }; // [[HomeObject]]

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2020-2021, Andreas Kling <kling@serenityos.org> * Copyright (c) 2020-2023, Andreas Kling <kling@serenityos.org>
* Copyright (c) 2020-2023, Linus Groh <linusg@serenityos.org> * Copyright (c) 2020-2023, Linus Groh <linusg@serenityos.org>
* Copyright (c) 2021-2022, David Tuin <davidot@serenityos.org> * Copyright (c) 2021-2022, David Tuin <davidot@serenityos.org>
* *
@ -275,7 +275,7 @@ ThrowCompletionOr<Value> VM::named_evaluation_if_anonymous_function(ASTNode cons
} }
// 13.15.5.2 Runtime Semantics: DestructuringAssignmentEvaluation, https://tc39.es/ecma262/#sec-runtime-semantics-destructuringassignmentevaluation // 13.15.5.2 Runtime Semantics: DestructuringAssignmentEvaluation, https://tc39.es/ecma262/#sec-runtime-semantics-destructuringassignmentevaluation
ThrowCompletionOr<void> VM::destructuring_assignment_evaluation(NonnullRefPtr<BindingPattern> const& target, Value value) ThrowCompletionOr<void> VM::destructuring_assignment_evaluation(NonnullRefPtr<BindingPattern const> const& target, Value value)
{ {
// Note: DestructuringAssignmentEvaluation is just like BindingInitialization without an environment // Note: DestructuringAssignmentEvaluation is just like BindingInitialization without an environment
// And it allows member expressions. We thus trust the parser to disallow member expressions // And it allows member expressions. We thus trust the parser to disallow member expressions
@ -292,7 +292,7 @@ ThrowCompletionOr<void> VM::binding_initialization(DeprecatedFlyString const& ta
} }
// 8.5.2 Runtime Semantics: BindingInitialization, https://tc39.es/ecma262/#sec-runtime-semantics-bindinginitialization // 8.5.2 Runtime Semantics: BindingInitialization, https://tc39.es/ecma262/#sec-runtime-semantics-bindinginitialization
ThrowCompletionOr<void> VM::binding_initialization(NonnullRefPtr<BindingPattern> const& target, Value value, Environment* environment) ThrowCompletionOr<void> VM::binding_initialization(NonnullRefPtr<BindingPattern const> const& target, Value value, Environment* environment)
{ {
auto& vm = *this; auto& vm = *this;
@ -348,9 +348,9 @@ ThrowCompletionOr<void> VM::property_binding_initialization(BindingPattern const
if (property.is_rest) { if (property.is_rest) {
Reference assignment_target; Reference assignment_target;
if (auto identifier_ptr = property.name.get_pointer<NonnullRefPtr<Identifier>>()) { if (auto identifier_ptr = property.name.get_pointer<NonnullRefPtr<Identifier const>>()) {
assignment_target = TRY(resolve_binding((*identifier_ptr)->string(), environment)); assignment_target = TRY(resolve_binding((*identifier_ptr)->string(), environment));
} else if (auto member_ptr = property.alias.get_pointer<NonnullRefPtr<MemberExpression>>()) { } else if (auto member_ptr = property.alias.get_pointer<NonnullRefPtr<MemberExpression const>>()) {
assignment_target = TRY((*member_ptr)->to_reference(interpreter())); assignment_target = TRY((*member_ptr)->to_reference(interpreter()));
} else { } else {
VERIFY_NOT_REACHED(); VERIFY_NOT_REACHED();
@ -368,19 +368,19 @@ ThrowCompletionOr<void> VM::property_binding_initialization(BindingPattern const
auto name = TRY(property.name.visit( auto name = TRY(property.name.visit(
[&](Empty) -> ThrowCompletionOr<PropertyKey> { VERIFY_NOT_REACHED(); }, [&](Empty) -> ThrowCompletionOr<PropertyKey> { VERIFY_NOT_REACHED(); },
[&](NonnullRefPtr<Identifier> const& identifier) -> ThrowCompletionOr<PropertyKey> { [&](NonnullRefPtr<Identifier const> const& identifier) -> ThrowCompletionOr<PropertyKey> {
return identifier->string(); return identifier->string();
}, },
[&](NonnullRefPtr<Expression> const& expression) -> ThrowCompletionOr<PropertyKey> { [&](NonnullRefPtr<Expression const> const& expression) -> ThrowCompletionOr<PropertyKey> {
auto result = TRY(expression->execute(interpreter())).release_value(); auto result = TRY(expression->execute(interpreter())).release_value();
return result.to_property_key(vm); return result.to_property_key(vm);
})); }));
seen_names.set(name); seen_names.set(name);
if (property.name.has<NonnullRefPtr<Identifier>>() && property.alias.has<Empty>()) { if (property.name.has<NonnullRefPtr<Identifier const>>() && property.alias.has<Empty>()) {
// FIXME: this branch and not taking this have a lot in common we might want to unify it more (like it was before). // FIXME: this branch and not taking this have a lot in common we might want to unify it more (like it was before).
auto& identifier = *property.name.get<NonnullRefPtr<Identifier>>(); auto& identifier = *property.name.get<NonnullRefPtr<Identifier const>>();
auto reference = TRY(resolve_binding(identifier.string(), environment)); auto reference = TRY(resolve_binding(identifier.string(), environment));
auto value_to_assign = TRY(object->get(name)); auto value_to_assign = TRY(object->get(name));
@ -397,23 +397,23 @@ ThrowCompletionOr<void> VM::property_binding_initialization(BindingPattern const
auto reference_to_assign_to = TRY(property.alias.visit( auto reference_to_assign_to = TRY(property.alias.visit(
[&](Empty) -> ThrowCompletionOr<Optional<Reference>> { return Optional<Reference> {}; }, [&](Empty) -> ThrowCompletionOr<Optional<Reference>> { return Optional<Reference> {}; },
[&](NonnullRefPtr<Identifier> const& identifier) -> ThrowCompletionOr<Optional<Reference>> { [&](NonnullRefPtr<Identifier const> const& identifier) -> ThrowCompletionOr<Optional<Reference>> {
return TRY(resolve_binding(identifier->string(), environment)); return TRY(resolve_binding(identifier->string(), environment));
}, },
[&](NonnullRefPtr<BindingPattern> const&) -> ThrowCompletionOr<Optional<Reference>> { return Optional<Reference> {}; }, [&](NonnullRefPtr<BindingPattern const> const&) -> ThrowCompletionOr<Optional<Reference>> { return Optional<Reference> {}; },
[&](NonnullRefPtr<MemberExpression> const& member_expression) -> ThrowCompletionOr<Optional<Reference>> { [&](NonnullRefPtr<MemberExpression const> const& member_expression) -> ThrowCompletionOr<Optional<Reference>> {
return TRY(member_expression->to_reference(interpreter())); return TRY(member_expression->to_reference(interpreter()));
})); }));
auto value_to_assign = TRY(object->get(name)); auto value_to_assign = TRY(object->get(name));
if (property.initializer && value_to_assign.is_undefined()) { if (property.initializer && value_to_assign.is_undefined()) {
if (auto* identifier_ptr = property.alias.get_pointer<NonnullRefPtr<Identifier>>()) if (auto* identifier_ptr = property.alias.get_pointer<NonnullRefPtr<Identifier const>>())
value_to_assign = TRY(named_evaluation_if_anonymous_function(*property.initializer, (*identifier_ptr)->string())); value_to_assign = TRY(named_evaluation_if_anonymous_function(*property.initializer, (*identifier_ptr)->string()));
else else
value_to_assign = TRY(property.initializer->execute(interpreter())).release_value(); value_to_assign = TRY(property.initializer->execute(interpreter())).release_value();
} }
if (auto* binding_ptr = property.alias.get_pointer<NonnullRefPtr<BindingPattern>>()) { if (auto* binding_ptr = property.alias.get_pointer<NonnullRefPtr<BindingPattern const>>()) {
TRY(binding_initialization(*binding_ptr, value_to_assign, environment)); TRY(binding_initialization(*binding_ptr, value_to_assign, environment));
} else { } else {
VERIFY(reference_to_assign_to.has_value()); VERIFY(reference_to_assign_to.has_value());
@ -441,11 +441,11 @@ ThrowCompletionOr<void> VM::iterator_binding_initialization(BindingPattern const
auto assignment_target = TRY(entry.alias.visit( auto assignment_target = TRY(entry.alias.visit(
[&](Empty) -> ThrowCompletionOr<Optional<Reference>> { return Optional<Reference> {}; }, [&](Empty) -> ThrowCompletionOr<Optional<Reference>> { return Optional<Reference> {}; },
[&](NonnullRefPtr<Identifier> const& identifier) -> ThrowCompletionOr<Optional<Reference>> { [&](NonnullRefPtr<Identifier const> const& identifier) -> ThrowCompletionOr<Optional<Reference>> {
return TRY(resolve_binding(identifier->string(), environment)); return TRY(resolve_binding(identifier->string(), environment));
}, },
[&](NonnullRefPtr<BindingPattern> const&) -> ThrowCompletionOr<Optional<Reference>> { return Optional<Reference> {}; }, [&](NonnullRefPtr<BindingPattern const> const&) -> ThrowCompletionOr<Optional<Reference>> { return Optional<Reference> {}; },
[&](NonnullRefPtr<MemberExpression> const& member_expression) -> ThrowCompletionOr<Optional<Reference>> { [&](NonnullRefPtr<MemberExpression const> const& member_expression) -> ThrowCompletionOr<Optional<Reference>> {
return TRY(member_expression->to_reference(interpreter())); return TRY(member_expression->to_reference(interpreter()));
})); }));
@ -544,13 +544,13 @@ ThrowCompletionOr<void> VM::iterator_binding_initialization(BindingPattern const
if (value.is_undefined() && entry.initializer) { if (value.is_undefined() && entry.initializer) {
VERIFY(!entry.is_rest); VERIFY(!entry.is_rest);
if (auto* identifier_ptr = entry.alias.get_pointer<NonnullRefPtr<Identifier>>()) if (auto* identifier_ptr = entry.alias.get_pointer<NonnullRefPtr<Identifier const>>())
value = TRY(named_evaluation_if_anonymous_function(*entry.initializer, (*identifier_ptr)->string())); value = TRY(named_evaluation_if_anonymous_function(*entry.initializer, (*identifier_ptr)->string()));
else else
value = TRY(entry.initializer->execute(interpreter())).release_value(); value = TRY(entry.initializer->execute(interpreter())).release_value();
} }
if (auto* binding_ptr = entry.alias.get_pointer<NonnullRefPtr<BindingPattern>>()) { if (auto* binding_ptr = entry.alias.get_pointer<NonnullRefPtr<BindingPattern const>>()) {
TRY(binding_initialization(*binding_ptr, value, environment)); TRY(binding_initialization(*binding_ptr, value, environment));
} else if (!entry.alias.has<Empty>()) { } else if (!entry.alias.has<Empty>()) {
VERIFY(assignment_target.has_value()); VERIFY(assignment_target.has_value());

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2020, Andreas Kling <kling@serenityos.org> * Copyright (c) 2020-2023, Andreas Kling <kling@serenityos.org>
* Copyright (c) 2020-2023, Linus Groh <linusg@serenityos.org> * Copyright (c) 2020-2023, Linus Groh <linusg@serenityos.org>
* Copyright (c) 2021-2022, David Tuin <davidot@serenityos.org> * Copyright (c) 2021-2022, David Tuin <davidot@serenityos.org>
* *
@ -235,9 +235,9 @@ public:
CustomData* custom_data() { return m_custom_data; } CustomData* custom_data() { return m_custom_data; }
ThrowCompletionOr<void> destructuring_assignment_evaluation(NonnullRefPtr<BindingPattern> const& target, Value value); ThrowCompletionOr<void> destructuring_assignment_evaluation(NonnullRefPtr<BindingPattern const> const& target, Value value);
ThrowCompletionOr<void> binding_initialization(DeprecatedFlyString const& target, Value value, Environment* environment); ThrowCompletionOr<void> binding_initialization(DeprecatedFlyString const& target, Value value, Environment* environment);
ThrowCompletionOr<void> binding_initialization(NonnullRefPtr<BindingPattern> const& target, Value value, Environment* environment); ThrowCompletionOr<void> binding_initialization(NonnullRefPtr<BindingPattern const> const& target, Value value, Environment* environment);
ThrowCompletionOr<Value> named_evaluation_if_anonymous_function(ASTNode const& expression, DeprecatedFlyString const& name); ThrowCompletionOr<Value> named_evaluation_if_anonymous_function(ASTNode const& expression, DeprecatedFlyString const& name);

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2022, Andreas Kling <kling@serenityos.org> * Copyright (c) 2022-2023, Andreas Kling <kling@serenityos.org>
* *
* SPDX-License-Identifier: BSD-2-Clause * SPDX-License-Identifier: BSD-2-Clause
*/ */
@ -12,7 +12,7 @@
namespace JS { namespace JS {
NonnullRefPtr<SourceCode> SourceCode::create(String filename, String code) NonnullRefPtr<SourceCode const> SourceCode::create(String filename, String code)
{ {
return adopt_ref(*new SourceCode(move(filename), move(code))); return adopt_ref(*new SourceCode(move(filename), move(code)));
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2022, Andreas Kling <kling@serenityos.org> * Copyright (c) 2022-2023, Andreas Kling <kling@serenityos.org>
* *
* SPDX-License-Identifier: BSD-2-Clause * SPDX-License-Identifier: BSD-2-Clause
*/ */
@ -14,7 +14,7 @@ namespace JS {
class SourceCode : public RefCounted<SourceCode> { class SourceCode : public RefCounted<SourceCode> {
public: public:
static NonnullRefPtr<SourceCode> create(String filename, String code); static NonnullRefPtr<SourceCode const> create(String filename, String code);
String const& filename() const; String const& filename() const;
String const& code() const; String const& code() const;

View file

@ -1,5 +1,6 @@
/* /*
* Copyright (c) 2020, the SerenityOS developers. * Copyright (c) 2020, the SerenityOS developers.
* Copyright (c) 2023, Andreas Kling <kling@serenityos.org>
* *
* SPDX-License-Identifier: BSD-2-Clause * SPDX-License-Identifier: BSD-2-Clause
*/ */
@ -21,7 +22,7 @@ struct Position {
struct SourceRange { struct SourceRange {
[[nodiscard]] bool contains(Position const& position) const { return position.offset <= end.offset && position.offset >= start.offset; } [[nodiscard]] bool contains(Position const& position) const { return position.offset <= end.offset && position.offset >= start.offset; }
NonnullRefPtr<SourceCode> code; NonnullRefPtr<SourceCode const> code;
Position start; Position start;
Position end; Position end;

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2021, Andreas Kling <kling@serenityos.org> * Copyright (c) 2021-2023, Andreas Kling <kling@serenityos.org>
* Copyright (c) 2022, David Tuin <davidot@serenityos.org> * Copyright (c) 2022, David Tuin <davidot@serenityos.org>
* *
* SPDX-License-Identifier: BSD-2-Clause * SPDX-License-Identifier: BSD-2-Clause
@ -49,7 +49,7 @@ static Vector<ModuleRequest> module_requests(Program& program, Vector<Deprecated
// Note: The List is source text occurrence ordered! // Note: The List is source text occurrence ordered!
struct RequestedModuleAndSourceIndex { struct RequestedModuleAndSourceIndex {
u32 source_offset { 0 }; u32 source_offset { 0 };
ModuleRequest* module_request { nullptr }; ModuleRequest const* module_request { nullptr };
}; };
Vector<RequestedModuleAndSourceIndex> requested_modules_with_indices; Vector<RequestedModuleAndSourceIndex> requested_modules_with_indices;
@ -89,7 +89,7 @@ static Vector<ModuleRequest> module_requests(Program& program, Vector<Deprecated
// 2. Let assertions be AssertClauseToAssertions of AssertClause. // 2. Let assertions be AssertClauseToAssertions of AssertClause.
auto assertions = assert_clause_to_assertions(module.module_request->assertions, supported_import_assertions); auto assertions = assert_clause_to_assertions(module.module_request->assertions, supported_import_assertions);
// Note: We have to modify the assertions in place because else it might keep non supported ones // Note: We have to modify the assertions in place because else it might keep non supported ones
module.module_request->assertions = move(assertions); const_cast<ModuleRequest*>(module.module_request)->assertions = move(assertions);
// 3. Return a ModuleRequest Record { [[Specifer]]: specifier, [[Assertions]]: assertions }. // 3. Return a ModuleRequest Record { [[Specifer]]: specifier, [[Assertions]]: assertions }.
requested_modules_in_source_order.empend(module.module_request->module_specifier, module.module_request->assertions); requested_modules_in_source_order.empend(module.module_request->module_specifier, module.module_request->assertions);
@ -102,7 +102,7 @@ static Vector<ModuleRequest> module_requests(Program& program, Vector<Deprecated
SourceTextModule::SourceTextModule(Realm& realm, StringView filename, Script::HostDefined* host_defined, bool has_top_level_await, NonnullRefPtr<Program> body, Vector<ModuleRequest> requested_modules, SourceTextModule::SourceTextModule(Realm& realm, StringView filename, Script::HostDefined* host_defined, bool has_top_level_await, NonnullRefPtr<Program> body, Vector<ModuleRequest> requested_modules,
Vector<ImportEntry> import_entries, Vector<ExportEntry> local_export_entries, Vector<ImportEntry> import_entries, Vector<ExportEntry> local_export_entries,
Vector<ExportEntry> indirect_export_entries, Vector<ExportEntry> star_export_entries, Vector<ExportEntry> indirect_export_entries, Vector<ExportEntry> star_export_entries,
RefPtr<ExportStatement> default_export) RefPtr<ExportStatement const> default_export)
: CyclicModule(realm, filename, has_top_level_await, move(requested_modules), host_defined) : CyclicModule(realm, filename, has_top_level_await, move(requested_modules), host_defined)
, m_ecmascript_code(move(body)) , m_ecmascript_code(move(body))
, m_execution_context(realm.heap()) , m_execution_context(realm.heap())
@ -157,7 +157,7 @@ Result<NonnullGCPtr<SourceTextModule>, Vector<ParserError>> SourceTextModule::pa
Vector<ExportEntry> star_export_entries; Vector<ExportEntry> star_export_entries;
// Note: Not in the spec but makes it easier to find the default. // Note: Not in the spec but makes it easier to find the default.
RefPtr<ExportStatement> default_export; RefPtr<ExportStatement const> default_export;
// 9. Let exportEntries be ExportEntries of body. // 9. Let exportEntries be ExportEntries of body.
// 10. For each ExportEntry Record ee of exportEntries, do // 10. For each ExportEntry Record ee of exportEntries, do

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2021, Andreas Kling <kling@serenityos.org> * Copyright (c) 2021-2023, Andreas Kling <kling@serenityos.org>
* Copyright (c) 2022, David Tuin <davidot@serenityos.org> * Copyright (c) 2022, David Tuin <davidot@serenityos.org>
* *
* SPDX-License-Identifier: BSD-2-Clause * SPDX-License-Identifier: BSD-2-Clause
@ -36,7 +36,7 @@ private:
SourceTextModule(Realm&, StringView filename, Script::HostDefined* host_defined, bool has_top_level_await, NonnullRefPtr<Program> body, Vector<ModuleRequest> requested_modules, SourceTextModule(Realm&, StringView filename, Script::HostDefined* host_defined, bool has_top_level_await, NonnullRefPtr<Program> body, Vector<ModuleRequest> requested_modules,
Vector<ImportEntry> import_entries, Vector<ExportEntry> local_export_entries, Vector<ImportEntry> import_entries, Vector<ExportEntry> local_export_entries,
Vector<ExportEntry> indirect_export_entries, Vector<ExportEntry> star_export_entries, Vector<ExportEntry> indirect_export_entries, Vector<ExportEntry> star_export_entries,
RefPtr<ExportStatement> default_export); RefPtr<ExportStatement const> default_export);
virtual void visit_edges(Cell::Visitor&) override; virtual void visit_edges(Cell::Visitor&) override;
@ -48,7 +48,7 @@ private:
Vector<ExportEntry> m_indirect_export_entries; // [[IndirectExportEntries]] Vector<ExportEntry> m_indirect_export_entries; // [[IndirectExportEntries]]
Vector<ExportEntry> m_star_export_entries; // [[StarExportEntries]] Vector<ExportEntry> m_star_export_entries; // [[StarExportEntries]]
RefPtr<ExportStatement> m_default_export; // Note: Not from the spec RefPtr<ExportStatement const> m_default_export; // Note: Not from the spec
}; };
} }