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
Notes: sideshowbarker 2024-07-17 20:19:08 +09:00
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 {
auto program_node = program.visit(
[](auto& visitor) -> NonnullRefPtr<JS::Program> {
[](auto& visitor) -> NonnullRefPtr<JS::Program const> {
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) 2021-2022, David Tuin <davidot@serenityos.org>
*
@ -914,21 +914,21 @@ Completion ForStatement::for_body_evaluation(JS::Interpreter& interpreter, Vecto
}
struct ForInOfHeadState {
explicit ForInOfHeadState(Variant<NonnullRefPtr<ASTNode>, NonnullRefPtr<BindingPattern>> lhs)
explicit ForInOfHeadState(Variant<NonnullRefPtr<ASTNode const>, NonnullRefPtr<BindingPattern const>> lhs)
{
lhs.visit(
[&](NonnullRefPtr<ASTNode>& ast_node) {
[&](NonnullRefPtr<ASTNode const>& ast_node) {
expression_lhs = ast_node.ptr();
},
[&](NonnullRefPtr<BindingPattern>& pattern) {
[&](NonnullRefPtr<BindingPattern const>& pattern) {
pattern_lhs = pattern.ptr();
destructuring = true;
lhs_kind = Assignment;
});
}
ASTNode* expression_lhs = nullptr;
BindingPattern* pattern_lhs = nullptr;
ASTNode const* expression_lhs = nullptr;
BindingPattern const* pattern_lhs = nullptr;
enum LhsKind {
Assignment,
VarBinding,
@ -956,12 +956,12 @@ struct ForInOfHeadState {
VERIFY(expression_lhs);
if (is<VariableDeclaration>(*expression_lhs)) {
auto& declaration = static_cast<VariableDeclaration const&>(*expression_lhs);
VERIFY(declaration.declarations().first().target().has<NonnullRefPtr<Identifier>>());
lhs_reference = TRY(declaration.declarations().first().target().get<NonnullRefPtr<Identifier>>()->to_reference(interpreter));
VERIFY(declaration.declarations().first().target().has<NonnullRefPtr<Identifier const>>());
lhs_reference = TRY(declaration.declarations().first().target().get<NonnullRefPtr<Identifier const>>()->to_reference(interpreter));
} else if (is<UsingDeclaration>(*expression_lhs)) {
auto& declaration = static_cast<UsingDeclaration const&>(*expression_lhs);
VERIFY(declaration.declarations().first().target().has<NonnullRefPtr<Identifier>>());
lhs_reference = TRY(declaration.declarations().first().target().get<NonnullRefPtr<Identifier>>()->to_reference(interpreter));
VERIFY(declaration.declarations().first().target().has<NonnullRefPtr<Identifier const>>());
lhs_reference = TRY(declaration.declarations().first().target().get<NonnullRefPtr<Identifier const>>()->to_reference(interpreter));
} else {
VERIFY(is<Identifier>(*expression_lhs) || is<MemberExpression>(*expression_lhs) || is<CallExpression>(*expression_lhs));
auto& expression = static_cast<Expression const&>(*expression_lhs);
@ -1028,7 +1028,7 @@ struct ForInOfHeadState {
}
VERIFY(expression_lhs && is<VariableDeclaration>(*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);
// 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
// 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.
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();
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:
// ForInOfStatement : for ( var ForBinding 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())) {
auto& variable_declaration = static_cast<VariableDeclaration const&>(*(*ast_ptr));
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) {
state.lhs_kind = ForInOfHeadState::VarBinding;
auto& variable = variable_declaration.declarations().first();
// B.3.5 Initializers in ForIn Statement Heads, https://tc39.es/ecma262/#sec-initializers-in-forin-statement-heads
if (variable.init()) {
VERIFY(variable.target().has<NonnullRefPtr<Identifier>>());
auto& binding_id = variable.target().get<NonnullRefPtr<Identifier>>()->string();
VERIFY(variable.target().has<NonnullRefPtr<Identifier const>>());
auto& binding_id = variable.target().get<NonnullRefPtr<Identifier const>>()->string();
auto reference = TRY(interpreter.vm().resolve_binding(binding_id));
auto result = TRY(interpreter.vm().named_evaluation_if_anonymous_function(*variable.init(), binding_id));
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
class ClassFieldInitializerStatement : public Statement {
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)
, m_expression(move(expression))
, m_class_field_identifier_name(move(field_name))
@ -1775,7 +1775,7 @@ public:
}
private:
NonnullRefPtr<Expression> m_expression;
NonnullRefPtr<Expression const> m_expression;
DeprecatedFlyString m_class_field_identifier_name; // [[ClassFieldIdentifierName]]
};
@ -2414,7 +2414,7 @@ bool BindingPattern::contains_expression() const
for (auto& entry : entries) {
if (entry.initializer)
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 false;
@ -2424,14 +2424,14 @@ ThrowCompletionOr<void> BindingPattern::for_each_bound_name(ThrowCompletionOrVoi
{
for (auto const& entry : entries) {
auto const& alias = entry.alias;
if (alias.has<NonnullRefPtr<Identifier>>()) {
TRY(callback(alias.get<NonnullRefPtr<Identifier>>()->string()));
} else if (alias.has<NonnullRefPtr<BindingPattern>>()) {
TRY(alias.get<NonnullRefPtr<BindingPattern>>()->for_each_bound_name(forward<decltype(callback)>(callback)));
if (alias.has<NonnullRefPtr<Identifier const>>()) {
TRY(callback(alias.get<NonnullRefPtr<Identifier const>>()->string()));
} else if (alias.has<NonnullRefPtr<BindingPattern const>>()) {
TRY(alias.get<NonnullRefPtr<BindingPattern const>>()->for_each_bound_name(forward<decltype(callback)>(callback)));
} else {
auto const& name = entry.name;
if (name.has<NonnullRefPtr<Identifier>>())
TRY(callback(name.get<NonnullRefPtr<Identifier>>()->string()));
if (name.has<NonnullRefPtr<Identifier const>>())
TRY(callback(name.get<NonnullRefPtr<Identifier const>>()->string()));
}
}
return {};
@ -2449,10 +2449,10 @@ void BindingPattern::dump(int indent) const
if (kind == Kind::Object) {
print_indent(indent + 2);
outln("(Identifier)");
if (entry.name.has<NonnullRefPtr<Identifier>>()) {
entry.name.get<NonnullRefPtr<Identifier>>()->dump(indent + 3);
if (entry.name.has<NonnullRefPtr<Identifier const>>()) {
entry.name.get<NonnullRefPtr<Identifier const>>()->dump(indent + 3);
} else {
entry.name.get<NonnullRefPtr<Expression>>()->dump(indent + 3);
entry.name.get<NonnullRefPtr<Expression const>>()->dump(indent + 3);
}
} else if (entry.is_elision()) {
print_indent(indent + 2);
@ -2462,12 +2462,12 @@ void BindingPattern::dump(int indent) const
print_indent(indent + 2);
outln("(Pattern{})", entry.is_rest ? " rest=true" : "");
if (entry.alias.has<NonnullRefPtr<Identifier>>()) {
entry.alias.get<NonnullRefPtr<Identifier>>()->dump(indent + 3);
} else if (entry.alias.has<NonnullRefPtr<BindingPattern>>()) {
entry.alias.get<NonnullRefPtr<BindingPattern>>()->dump(indent + 3);
} else if (entry.alias.has<NonnullRefPtr<MemberExpression>>()) {
entry.alias.get<NonnullRefPtr<MemberExpression>>()->dump(indent + 3);
if (entry.alias.has<NonnullRefPtr<Identifier const>>()) {
entry.alias.get<NonnullRefPtr<Identifier const>>()->dump(indent + 3);
} else if (entry.alias.has<NonnullRefPtr<BindingPattern const>>()) {
entry.alias.get<NonnullRefPtr<BindingPattern const>>()->dump(indent + 3);
} else if (entry.alias.has<NonnullRefPtr<MemberExpression const>>()) {
entry.alias.get<NonnullRefPtr<MemberExpression const>>()->dump(indent + 3);
} else {
print_indent(indent + 3);
outln("<empty>");
@ -2718,7 +2718,7 @@ Completion AssignmentExpression::execute(Interpreter& interpreter) const
// AssignmentExpression : LeftHandSideExpression = AssignmentExpression
return m_lhs.visit(
// 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.
// b. ReturnIfAbrupt(lref).
auto reference = TRY(lhs->to_reference(interpreter));
@ -2745,7 +2745,7 @@ Completion AssignmentExpression::execute(Interpreter& interpreter) const
return rhs_result;
},
// 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.
// 4. Let rval be ? GetValue(rref).
auto rhs_result = TRY(m_rhs->execute(interpreter)).release_value();
@ -2757,10 +2757,10 @@ Completion AssignmentExpression::execute(Interpreter& interpreter) const
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.
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));
// 2. Let lval be ? GetValue(lref).
@ -3029,7 +3029,7 @@ Completion VariableDeclaration::execute(Interpreter& interpreter) const
for (auto& declarator : m_declarations) {
if (auto* init = declarator.init()) {
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 initializer_result = TRY(interpreter.vm().named_evaluation_if_anonymous_function(*init, id->string()));
VERIFY(!initializer_result.is_empty());
@ -3039,7 +3039,7 @@ Completion VariableDeclaration::execute(Interpreter& interpreter) const
else
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();
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);
}));
} else if (m_declaration_kind != DeclarationKind::Var) {
VERIFY(declarator.target().has<NonnullRefPtr<Identifier>>());
auto& identifier = declarator.target().get<NonnullRefPtr<Identifier>>();
VERIFY(declarator.target().has<NonnullRefPtr<Identifier const>>());
auto& identifier = declarator.target().get<NonnullRefPtr<Identifier const>>();
auto reference = TRY(identifier->to_reference(interpreter));
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()) {
TRY(entry.target().visit(
[&](NonnullRefPtr<Identifier> const& id) {
[&](NonnullRefPtr<Identifier const> const& id) {
return callback(id->string());
},
[&](NonnullRefPtr<BindingPattern> const& binding) {
[&](NonnullRefPtr<BindingPattern const> const& binding) {
return binding->for_each_bound_name([&](auto const& name) {
return callback(name);
});
@ -3112,10 +3112,10 @@ Completion UsingDeclaration::execute(Interpreter& interpreter) const
auto& vm = interpreter.vm();
for (auto& declarator : m_declarations) {
VERIFY(declarator.target().has<NonnullRefPtr<Identifier>>());
VERIFY(declarator.target().has<NonnullRefPtr<Identifier const>>());
VERIFY(declarator.init());
auto& id = declarator.target().get<NonnullRefPtr<Identifier>>();
auto& id = declarator.target().get<NonnullRefPtr<Identifier const>>();
// 2. ReturnIfAbrupt(next).
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
{
for (auto const& entry : m_declarations) {
VERIFY(entry.target().has<NonnullRefPtr<Identifier>>());
TRY(callback(entry.target().get<NonnullRefPtr<Identifier>>()->string()));
VERIFY(entry.target().has<NonnullRefPtr<Identifier const>>());
TRY(callback(entry.target().get<NonnullRefPtr<Identifier const>>()->string()));
}
return {};
@ -3349,24 +3349,24 @@ ThrowCompletionOr<OptionalChain::ReferenceAndValue> OptionalChain::to_reference_
return ReferenceAndValue { {}, js_undefined() };
auto expression = reference.visit(
[&](Call const& call) -> NonnullRefPtr<Expression> {
[&](Call const& call) -> NonnullRefPtr<Expression const> {
return CallExpression::create(source_range(),
create_ast_node<SyntheticReferenceExpression>(source_range(), base_reference, base),
call.arguments);
},
[&](ComputedReference const& ref) -> NonnullRefPtr<Expression> {
[&](ComputedReference const& ref) -> NonnullRefPtr<Expression const> {
return create_ast_node<MemberExpression>(source_range(),
create_ast_node<SyntheticReferenceExpression>(source_range(), base_reference, base),
ref.expression,
true);
},
[&](MemberReference const& ref) -> NonnullRefPtr<Expression> {
[&](MemberReference const& ref) -> NonnullRefPtr<Expression const> {
return create_ast_node<MemberExpression>(source_range(),
create_ast_node<SyntheticReferenceExpression>(source_range(), base_reference, base),
ref.identifier,
false);
},
[&](PrivateMemberReference const& ref) -> NonnullRefPtr<Expression> {
[&](PrivateMemberReference const& ref) -> NonnullRefPtr<Expression const> {
return create_ast_node<MemberExpression>(source_range(),
create_ast_node<SyntheticReferenceExpression>(source_range(), base_reference, base),
ref.private_identifier,
@ -3945,7 +3945,7 @@ void CatchClause::dump(int indent) const
else
outln("CatchClause ({})", parameter);
},
[&](NonnullRefPtr<BindingPattern> const& pattern) {
[&](NonnullRefPtr<BindingPattern const> const& pattern) {
outln("CatchClause");
print_indent(indent);
outln("(Parameter)");
@ -3981,7 +3981,7 @@ Completion TryStatement::execute(Interpreter& interpreter) const
// a. Perform ! catchEnv.CreateMutableBinding(argName, 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
pattern->for_each_bound_name([&](auto& name) {
// a. Perform ! catchEnv.CreateMutableBinding(argName, false).
@ -3997,7 +3997,7 @@ Completion TryStatement::execute(Interpreter& interpreter) const
[&](DeprecatedFlyString const& parameter) {
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);
});
@ -4119,9 +4119,9 @@ Completion SwitchStatement::execute_impl(Interpreter& interpreter) const
return js_undefined();
}
NonnullRefPtrVector<SwitchCase> case_clauses_1;
NonnullRefPtrVector<SwitchCase> case_clauses_2;
RefPtr<SwitchCase> default_clause;
NonnullRefPtrVector<SwitchCase const> case_clauses_1;
NonnullRefPtrVector<SwitchCase const> case_clauses_2;
RefPtr<SwitchCase const> default_clause;
for (auto const& switch_case : m_cases) {
if (!switch_case.test())
default_clause = switch_case;
@ -4524,17 +4524,17 @@ ThrowCompletionOr<void> ScopeNode::for_each_function_hoistable_with_annexB_exten
return {};
}
void ScopeNode::add_lexical_declaration(NonnullRefPtr<Declaration> declaration)
void ScopeNode::add_lexical_declaration(NonnullRefPtr<Declaration const> 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));
}
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));
}
@ -4967,12 +4967,12 @@ DeprecatedString SourceRange::filename() const
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);
}
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);
}

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) 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.
// This creates a 4-byte padding hole after `m_end_offset` which is used to pack subclasses better.
u32 m_start_offset { 0 };
RefPtr<SourceCode> m_source_code;
RefPtr<SourceCode const> m_source_code;
u32 m_end_offset { 0 };
};
@ -152,7 +152,7 @@ public:
// 14.13 Labelled Statements, https://tc39.es/ecma262/#sec-labelled-statements
class LabelledStatement : public Statement {
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)
, m_label(move(label))
, m_labelled_item(move(labelled_item))
@ -166,14 +166,13 @@ public:
DeprecatedFlyString const& label() const { return m_label; }
DeprecatedFlyString& label() { return m_label; }
NonnullRefPtr<Statement> const& labelled_item() const { return m_labelled_item; }
NonnullRefPtr<Statement>& labelled_item() { return m_labelled_item; }
NonnullRefPtr<Statement const> const& labelled_item() const { return m_labelled_item; }
private:
virtual bool is_labelled_statement() const final { return true; }
DeprecatedFlyString m_label;
NonnullRefPtr<Statement> m_labelled_item;
NonnullRefPtr<Statement const> m_labelled_item;
};
class LabelableStatement : public Statement {
@ -219,7 +218,7 @@ public:
class ExpressionStatement final : public Statement {
public:
ExpressionStatement(SourceRange source_range, NonnullRefPtr<Expression> expression)
ExpressionStatement(SourceRange source_range, NonnullRefPtr<Expression const> expression)
: Statement(source_range)
, m_expression(move(expression))
{
@ -234,7 +233,7 @@ public:
private:
virtual bool is_expression_statement() const override { return true; }
NonnullRefPtr<Expression> m_expression;
NonnullRefPtr<Expression const> m_expression;
};
template<typename Func, typename... Args>
@ -275,7 +274,7 @@ public:
m_children.append(move(child));
return static_cast<T&>(m_children.last());
}
void append(NonnullRefPtr<Statement> child)
void append(NonnullRefPtr<Statement const> child)
{
m_children.append(move(child));
}
@ -288,15 +287,15 @@ public:
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 Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override;
Completion evaluate_statements(Interpreter&) const;
void add_var_scoped_declaration(NonnullRefPtr<Declaration> variables);
void add_lexical_declaration(NonnullRefPtr<Declaration> variables);
void add_hoisted_function(NonnullRefPtr<FunctionDeclaration> declaration);
void add_var_scoped_declaration(NonnullRefPtr<Declaration const> variables);
void add_lexical_declaration(NonnullRefPtr<Declaration const> variables);
void add_hoisted_function(NonnullRefPtr<FunctionDeclaration const> declaration);
[[nodiscard]] bool has_lexical_declarations() const { return !m_lexical_declarations.is_empty(); }
[[nodiscard]] bool has_var_declarations() const { return !m_var_declarations.is_empty(); }
@ -325,11 +324,11 @@ protected:
private:
virtual bool is_scope_node() const final { return true; }
NonnullRefPtrVector<Statement> m_children;
NonnullRefPtrVector<Declaration> m_lexical_declarations;
NonnullRefPtrVector<Declaration> m_var_declarations;
NonnullRefPtrVector<Statement const> m_children;
NonnullRefPtrVector<Declaration const> m_lexical_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
@ -375,7 +374,6 @@ public:
bool has_bound_name(DeprecatedFlyString const& name) const;
Vector<ImportEntry> const& entries() const { return m_entries; }
ModuleRequest const& module_request() const { return m_module_request; }
ModuleRequest& module_request() { return m_module_request; }
private:
ModuleRequest m_module_request;
@ -453,7 +451,7 @@ class ExportStatement final : public Statement {
public:
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)
, m_statement(move(statement))
, m_entries(move(entries))
@ -483,14 +481,14 @@ public:
return *m_statement;
}
ModuleRequest& module_request()
ModuleRequest const& module_request() const
{
VERIFY(!m_module_request.module_specifier.is_null());
return m_module_request;
}
private:
RefPtr<ASTNode> m_statement;
RefPtr<ASTNode const> m_statement;
Vector<ExportEntry> m_entries;
bool m_is_default_export { false };
ModuleRequest m_module_request;
@ -516,23 +514,23 @@ public:
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);
append(import_statement);
}
void append_export(NonnullRefPtr<ExportStatement> export_statement)
void append_export(NonnullRefPtr<ExportStatement const> export_statement)
{
m_exports.append(export_statement);
append(export_statement);
}
NonnullRefPtrVector<ImportStatement> const& imports() const { return m_imports; }
NonnullRefPtrVector<ExportStatement> const& exports() const { return m_exports; }
NonnullRefPtrVector<ImportStatement const> const& imports() const { return m_imports; }
NonnullRefPtrVector<ExportStatement const> const& exports() const { return m_exports; }
NonnullRefPtrVector<ImportStatement>& imports() { return m_imports; }
NonnullRefPtrVector<ExportStatement>& exports() { return m_exports; }
NonnullRefPtrVector<ImportStatement const>& imports() { return m_imports; }
NonnullRefPtrVector<ExportStatement const>& exports() { return m_exports; }
bool has_top_level_await() const { return m_has_top_level_await; }
void set_has_top_level_await() { m_has_top_level_await = true; }
@ -545,8 +543,8 @@ private:
bool m_is_strict_mode { false };
Type m_type { Type::Script };
NonnullRefPtrVector<ImportStatement> m_imports;
NonnullRefPtrVector<ExportStatement> m_exports;
NonnullRefPtrVector<ImportStatement const> m_imports;
NonnullRefPtrVector<ExportStatement const> m_exports;
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
struct BindingEntry {
// If this entry represents a BindingElement, then name will be Empty
Variant<NonnullRefPtr<Identifier>, NonnullRefPtr<Expression>, Empty> name {};
Variant<NonnullRefPtr<Identifier>, NonnullRefPtr<BindingPattern>, NonnullRefPtr<MemberExpression>, Empty> alias {};
RefPtr<Expression> initializer {};
Variant<NonnullRefPtr<Identifier const>, NonnullRefPtr<Expression const>, Empty> name {};
Variant<NonnullRefPtr<Identifier const>, NonnullRefPtr<BindingPattern const>, NonnullRefPtr<MemberExpression const>, Empty> alias {};
RefPtr<Expression const> initializer {};
bool is_rest { false };
bool is_elision() const { return name.has<Empty>() && alias.has<Empty>(); }
@ -642,8 +640,8 @@ struct BindingPattern : RefCounted<BindingPattern> {
};
struct FunctionParameter {
Variant<DeprecatedFlyString, NonnullRefPtr<BindingPattern>> binding;
RefPtr<Expression> default_value;
Variant<DeprecatedFlyString, NonnullRefPtr<BindingPattern const>> binding;
RefPtr<Expression const> default_value;
bool is_rest { false };
};
@ -661,7 +659,7 @@ public:
FunctionKind kind() const { return m_kind; }
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_source_text(move(source_text))
, m_body(move(body))
@ -682,7 +680,7 @@ protected:
private:
DeprecatedFlyString m_name;
DeprecatedString m_source_text;
NonnullRefPtr<Statement> m_body;
NonnullRefPtr<Statement const> m_body;
Vector<FunctionParameter> const m_parameters;
const i32 m_function_length;
FunctionKind m_kind;
@ -698,7 +696,7 @@ class FunctionDeclaration final
public:
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)
, 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:
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)
, 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 {
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)
, m_argument(move(argument))
, m_is_yield_from(is_yield_from)
@ -770,13 +768,13 @@ public:
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override;
private:
RefPtr<Expression> m_argument;
RefPtr<Expression const> m_argument;
bool m_is_yield_from { false };
};
class AwaitExpression final : public Expression {
public:
explicit AwaitExpression(SourceRange source_range, NonnullRefPtr<Expression> argument)
explicit AwaitExpression(SourceRange source_range, NonnullRefPtr<Expression const> argument)
: Expression(source_range)
, m_argument(move(argument))
{
@ -787,12 +785,12 @@ public:
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override;
private:
NonnullRefPtr<Expression> m_argument;
NonnullRefPtr<Expression const> m_argument;
};
class ReturnStatement final : public Statement {
public:
explicit ReturnStatement(SourceRange source_range, RefPtr<Expression> argument)
explicit ReturnStatement(SourceRange source_range, RefPtr<Expression const> argument)
: Statement(source_range)
, m_argument(move(argument))
{
@ -805,12 +803,12 @@ public:
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override;
private:
RefPtr<Expression> m_argument;
RefPtr<Expression const> m_argument;
};
class IfStatement final : public Statement {
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)
, m_predicate(move(predicate))
, m_consequent(move(consequent))
@ -827,14 +825,14 @@ public:
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override;
private:
NonnullRefPtr<Expression> m_predicate;
NonnullRefPtr<Statement> m_consequent;
RefPtr<Statement> m_alternate;
NonnullRefPtr<Expression const> m_predicate;
NonnullRefPtr<Statement const> m_consequent;
RefPtr<Statement const> m_alternate;
};
class WhileStatement final : public IterationStatement {
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)
, m_test(move(test))
, m_body(move(body))
@ -851,13 +849,13 @@ public:
virtual Bytecode::CodeGenerationErrorOr<void> generate_labelled_evaluation(Bytecode::Generator&, Vector<DeprecatedFlyString> const&) const override;
private:
NonnullRefPtr<Expression> m_test;
NonnullRefPtr<Statement> m_body;
NonnullRefPtr<Expression const> m_test;
NonnullRefPtr<Statement const> m_body;
};
class DoWhileStatement final : public IterationStatement {
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)
, m_test(move(test))
, m_body(move(body))
@ -874,13 +872,13 @@ public:
virtual Bytecode::CodeGenerationErrorOr<void> generate_labelled_evaluation(Bytecode::Generator&, Vector<DeprecatedFlyString> const&) const override;
private:
NonnullRefPtr<Expression> m_test;
NonnullRefPtr<Statement> m_body;
NonnullRefPtr<Expression const> m_test;
NonnullRefPtr<Statement const> m_body;
};
class WithStatement final : public Statement {
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)
, m_object(move(object))
, m_body(move(body))
@ -895,13 +893,13 @@ public:
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override;
private:
NonnullRefPtr<Expression> m_object;
NonnullRefPtr<Statement> m_body;
NonnullRefPtr<Expression const> m_object;
NonnullRefPtr<Statement const> m_body;
};
class ForStatement final : public IterationStatement {
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)
, m_init(move(init))
, m_test(move(test))
@ -924,15 +922,15 @@ public:
private:
Completion for_body_evaluation(Interpreter&, Vector<DeprecatedFlyString> const&, size_t per_iteration_bindings_size) const;
RefPtr<ASTNode> m_init;
RefPtr<Expression> m_test;
RefPtr<Expression> m_update;
NonnullRefPtr<Statement> m_body;
RefPtr<ASTNode const> m_init;
RefPtr<Expression const> m_test;
RefPtr<Expression const> m_update;
NonnullRefPtr<Statement const> m_body;
};
class ForInStatement final : public IterationStatement {
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)
, m_lhs(move(lhs))
, m_rhs(move(rhs))
@ -951,14 +949,14 @@ public:
virtual void dump(int indent) const override;
private:
Variant<NonnullRefPtr<ASTNode>, NonnullRefPtr<BindingPattern>> m_lhs;
NonnullRefPtr<Expression> m_rhs;
NonnullRefPtr<Statement> m_body;
Variant<NonnullRefPtr<ASTNode const>, NonnullRefPtr<BindingPattern const>> m_lhs;
NonnullRefPtr<Expression const> m_rhs;
NonnullRefPtr<Statement const> m_body;
};
class ForOfStatement final : public IterationStatement {
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)
, m_lhs(move(lhs))
, m_rhs(move(rhs))
@ -977,14 +975,14 @@ public:
virtual void dump(int indent) const override;
private:
Variant<NonnullRefPtr<ASTNode>, NonnullRefPtr<BindingPattern>> m_lhs;
NonnullRefPtr<Expression> m_rhs;
NonnullRefPtr<Statement> m_body;
Variant<NonnullRefPtr<ASTNode const>, NonnullRefPtr<BindingPattern const>> m_lhs;
NonnullRefPtr<Expression const> m_rhs;
NonnullRefPtr<Statement const> m_body;
};
class ForAwaitOfStatement final : public IterationStatement {
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)
, m_lhs(move(lhs))
, m_rhs(move(rhs))
@ -997,9 +995,9 @@ public:
virtual void dump(int indent) const override;
private:
Variant<NonnullRefPtr<ASTNode>, NonnullRefPtr<BindingPattern>> m_lhs;
NonnullRefPtr<Expression> m_rhs;
NonnullRefPtr<Statement> m_body;
Variant<NonnullRefPtr<ASTNode const>, NonnullRefPtr<BindingPattern const>> m_lhs;
NonnullRefPtr<Expression const> m_rhs;
NonnullRefPtr<Statement const> m_body;
};
enum class BinaryOp {
@ -1029,7 +1027,7 @@ enum class BinaryOp {
class BinaryExpression final : public Expression {
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)
, m_op(op)
, m_lhs(move(lhs))
@ -1043,8 +1041,8 @@ public:
private:
BinaryOp m_op;
NonnullRefPtr<Expression> m_lhs;
NonnullRefPtr<Expression> m_rhs;
NonnullRefPtr<Expression const> m_lhs;
NonnullRefPtr<Expression const> m_rhs;
};
enum class LogicalOp {
@ -1055,7 +1053,7 @@ enum class LogicalOp {
class LogicalExpression final : public Expression {
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)
, m_op(op)
, m_lhs(move(lhs))
@ -1069,8 +1067,8 @@ public:
private:
LogicalOp m_op;
NonnullRefPtr<Expression> m_lhs;
NonnullRefPtr<Expression> m_rhs;
NonnullRefPtr<Expression const> m_lhs;
NonnullRefPtr<Expression const> m_rhs;
};
enum class UnaryOp {
@ -1085,7 +1083,7 @@ enum class UnaryOp {
class UnaryExpression final : public Expression {
public:
UnaryExpression(SourceRange source_range, UnaryOp op, NonnullRefPtr<Expression> lhs)
UnaryExpression(SourceRange source_range, UnaryOp op, NonnullRefPtr<Expression const> lhs)
: Expression(source_range)
, m_op(op)
, m_lhs(move(lhs))
@ -1098,12 +1096,12 @@ public:
private:
UnaryOp m_op;
NonnullRefPtr<Expression> m_lhs;
NonnullRefPtr<Expression const> m_lhs;
};
class SequenceExpression final : public Expression {
public:
SequenceExpression(SourceRange source_range, NonnullRefPtrVector<Expression> expressions)
SequenceExpression(SourceRange source_range, NonnullRefPtrVector<Expression const> expressions)
: Expression(source_range)
, m_expressions(move(expressions))
{
@ -1115,7 +1113,7 @@ public:
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override;
private:
NonnullRefPtrVector<Expression> m_expressions;
NonnullRefPtrVector<Expression const> m_expressions;
};
class Literal : public Expression {
@ -1314,7 +1312,7 @@ public:
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)
, m_key(move(key))
, m_function(move(function))
@ -1332,14 +1330,14 @@ public:
private:
virtual bool is_class_method() const override { return true; }
NonnullRefPtr<Expression> m_key;
NonnullRefPtr<FunctionExpression> m_function;
NonnullRefPtr<Expression const> m_key;
NonnullRefPtr<FunctionExpression const> m_function;
Kind m_kind;
};
class ClassField final : public ClassElement {
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)
, m_key(move(key))
, m_initializer(move(init))
@ -1348,8 +1346,8 @@ public:
}
Expression const& key() const { return *m_key; }
RefPtr<Expression> const& initializer() const { return m_initializer; }
RefPtr<Expression>& initializer() { return m_initializer; }
RefPtr<Expression const> const& initializer() const { return m_initializer; }
RefPtr<Expression const>& initializer() { return m_initializer; }
virtual ElementKind class_element_kind() const override { return ElementKind::Field; }
@ -1358,8 +1356,8 @@ public:
virtual Optional<DeprecatedFlyString> private_bound_identifier() const override;
private:
NonnullRefPtr<Expression> m_key;
RefPtr<Expression> m_initializer;
NonnullRefPtr<Expression const> m_key;
RefPtr<Expression const> m_initializer;
bool m_contains_direct_call_to_eval { false };
};
@ -1397,7 +1395,7 @@ public:
class ClassExpression final : public Expression {
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)
, m_name(move(name))
, m_source_text(move(source_text))
@ -1409,7 +1407,7 @@ public:
StringView name() const { return m_name; }
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 void dump(int indent) const override;
@ -1424,14 +1422,14 @@ private:
DeprecatedString m_name;
DeprecatedString m_source_text;
RefPtr<FunctionExpression> m_constructor;
RefPtr<Expression> m_super_class;
NonnullRefPtrVector<ClassElement> m_elements;
RefPtr<FunctionExpression const> m_constructor;
RefPtr<Expression const> m_super_class;
NonnullRefPtrVector<ClassElement const> m_elements;
};
class ClassDeclaration final : public Declaration {
public:
ClassDeclaration(SourceRange source_range, NonnullRefPtr<ClassExpression> class_expression)
ClassDeclaration(SourceRange source_range, NonnullRefPtr<ClassExpression const> class_expression)
: Declaration(source_range)
, m_class_expression(move(class_expression))
{
@ -1452,12 +1450,12 @@ private:
friend ExportStatement;
NonnullRefPtr<ClassExpression> m_class_expression;
NonnullRefPtr<ClassExpression const> m_class_expression;
};
class SpreadExpression final : public Expression {
public:
explicit SpreadExpression(SourceRange source_range, NonnullRefPtr<Expression> target)
explicit SpreadExpression(SourceRange source_range, NonnullRefPtr<Expression const> target)
: Expression(source_range)
, m_target(move(target))
{
@ -1468,7 +1466,7 @@ public:
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override;
private:
NonnullRefPtr<Expression> m_target;
NonnullRefPtr<Expression const> m_target;
};
class ThisExpression final : public Expression {
@ -1483,7 +1481,7 @@ public:
};
struct CallExpressionArgument {
NonnullRefPtr<Expression> value;
NonnullRefPtr<Expression const> value;
bool is_spread;
};
@ -1493,7 +1491,7 @@ class CallExpression : public ASTNodeWithTailArray<CallExpression, Expression, C
public:
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 void dump(int indent) const override;
@ -1504,7 +1502,7 @@ public:
ReadonlySpan<Argument> arguments() const { return tail_span(); }
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)
, m_callee(move(callee))
{
@ -1523,21 +1521,21 @@ protected:
Completion throw_type_error_for_callee(Interpreter&, Value callee_value, StringView call_type) const;
Optional<DeprecatedString> expression_string() const;
NonnullRefPtr<Expression> m_callee;
NonnullRefPtr<Expression const> m_callee;
};
class NewExpression final : public CallExpression {
friend class ASTNodeWithTailArray;
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 bool is_new_expression() const override { return true; }
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)
{
}
@ -1599,7 +1597,7 @@ enum class AssignmentOp {
class AssignmentExpression final : public Expression {
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)
, m_op(op)
, 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)
, m_op(op)
, m_lhs(move(lhs))
@ -1621,8 +1619,8 @@ public:
private:
AssignmentOp m_op;
Variant<NonnullRefPtr<Expression>, NonnullRefPtr<BindingPattern>> m_lhs;
NonnullRefPtr<Expression> m_rhs;
Variant<NonnullRefPtr<Expression const>, NonnullRefPtr<BindingPattern const>> m_lhs;
NonnullRefPtr<Expression const> m_rhs;
};
enum class UpdateOp {
@ -1632,7 +1630,7 @@ enum class UpdateOp {
class UpdateExpression final : public Expression {
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)
, m_op(op)
, m_argument(move(argument))
@ -1648,7 +1646,7 @@ private:
virtual bool is_update_expression() const override { return true; }
UpdateOp m_op;
NonnullRefPtr<Expression> m_argument;
NonnullRefPtr<Expression const> m_argument;
bool m_prefixed;
};
@ -1660,20 +1658,20 @@ enum class DeclarationKind {
class VariableDeclarator final : public ASTNode {
public:
VariableDeclarator(SourceRange source_range, NonnullRefPtr<Identifier> id)
VariableDeclarator(SourceRange source_range, NonnullRefPtr<Identifier const> id)
: ASTNode(source_range)
, 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)
, m_target(move(target))
, 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)
, m_target(move(target))
, m_init(move(init))
@ -1687,13 +1685,13 @@ public:
virtual void dump(int indent) const override;
private:
Variant<NonnullRefPtr<Identifier>, NonnullRefPtr<BindingPattern>> m_target;
RefPtr<Expression> m_init;
Variant<NonnullRefPtr<Identifier const>, NonnullRefPtr<BindingPattern const>> m_target;
RefPtr<Expression const> m_init;
};
class VariableDeclaration final : public Declaration {
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)
, m_declaration_kind(declaration_kind)
, m_declarations(move(declarations))
@ -1706,7 +1704,7 @@ public:
virtual void dump(int indent) 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;
@ -1718,12 +1716,12 @@ private:
virtual bool is_variable_declaration() const override { return true; }
DeclarationKind m_declaration_kind;
NonnullRefPtrVector<VariableDeclarator> m_declarations;
NonnullRefPtrVector<VariableDeclarator const> m_declarations;
};
class UsingDeclaration final : public Declaration {
public:
UsingDeclaration(SourceRange source_range, NonnullRefPtrVector<VariableDeclarator> declarations)
UsingDeclaration(SourceRange source_range, NonnullRefPtrVector<VariableDeclarator const> declarations)
: Declaration(move(source_range))
, m_declarations(move(declarations))
{
@ -1738,10 +1736,10 @@ public:
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:
NonnullRefPtrVector<VariableDeclarator> m_declarations;
NonnullRefPtrVector<VariableDeclarator const> m_declarations;
};
class ObjectProperty final : public ASTNode {
@ -1754,7 +1752,7 @@ public:
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)
, m_property_type(property_type)
, m_is_method(is_method)
@ -1779,8 +1777,8 @@ public:
private:
Type m_property_type;
bool m_is_method { false };
NonnullRefPtr<Expression> m_key;
RefPtr<Expression> m_value;
NonnullRefPtr<Expression const> m_key;
RefPtr<Expression const> m_value;
};
class ObjectExpression final : public Expression {
@ -1803,13 +1801,13 @@ private:
class ArrayExpression final : public Expression {
public:
ArrayExpression(SourceRange source_range, Vector<RefPtr<Expression>> elements)
ArrayExpression(SourceRange source_range, Vector<RefPtr<Expression const>> elements)
: Expression(source_range)
, 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 void dump(int indent) const override;
@ -1818,18 +1816,18 @@ public:
private:
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 {
public:
TemplateLiteral(SourceRange source_range, NonnullRefPtrVector<Expression> expressions)
TemplateLiteral(SourceRange source_range, NonnullRefPtrVector<Expression const> expressions)
: Expression(source_range)
, 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)
, m_expressions(move(expressions))
, m_raw_strings(move(raw_strings))
@ -1840,17 +1838,17 @@ public:
virtual void dump(int indent) const override;
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override;
NonnullRefPtrVector<Expression> const& expressions() const { return m_expressions; }
NonnullRefPtrVector<Expression> const& raw_strings() const { return m_raw_strings; }
NonnullRefPtrVector<Expression const> const& expressions() const { return m_expressions; }
NonnullRefPtrVector<Expression const> const& raw_strings() const { return m_raw_strings; }
private:
NonnullRefPtrVector<Expression> const m_expressions;
NonnullRefPtrVector<Expression> const m_raw_strings;
NonnullRefPtrVector<Expression const> const m_expressions;
NonnullRefPtrVector<Expression const> const m_raw_strings;
};
class TaggedTemplateLiteral final : public Expression {
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)
, m_tag(move(tag))
, m_template_literal(move(template_literal))
@ -1864,14 +1862,14 @@ public:
ThrowCompletionOr<Value> get_template_object(Interpreter&) const;
private:
NonnullRefPtr<Expression> const m_tag;
NonnullRefPtr<TemplateLiteral> const m_template_literal;
NonnullRefPtr<Expression const> const m_tag;
NonnullRefPtr<TemplateLiteral const> const m_template_literal;
mutable HashMap<Realm*, Handle<Array>> m_cached_values;
};
class MemberExpression final : public Expression {
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)
, m_computed(computed)
, m_object(move(object))
@ -1896,8 +1894,8 @@ private:
virtual bool is_member_expression() const override { return true; }
bool m_computed { false };
NonnullRefPtr<Expression> m_object;
NonnullRefPtr<Expression> m_property;
NonnullRefPtr<Expression const> m_object;
NonnullRefPtr<Expression const> m_property;
};
class OptionalChain final : public Expression {
@ -1912,21 +1910,21 @@ public:
Mode mode;
};
struct ComputedReference {
NonnullRefPtr<Expression> expression;
NonnullRefPtr<Expression const> expression;
Mode mode;
};
struct MemberReference {
NonnullRefPtr<Identifier> identifier;
NonnullRefPtr<Identifier const> identifier;
Mode mode;
};
struct PrivateMemberReference {
NonnullRefPtr<PrivateIdentifier> private_identifier;
NonnullRefPtr<PrivateIdentifier const> private_identifier;
Mode mode;
};
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)
, m_base(move(base))
, m_references(move(references))
@ -1944,7 +1942,7 @@ private:
};
ThrowCompletionOr<ReferenceAndValue> to_reference_and_value(Interpreter&) const;
NonnullRefPtr<Expression> m_base;
NonnullRefPtr<Expression const> m_base;
Vector<Reference> m_references;
};
@ -1971,7 +1969,7 @@ private:
class ImportCall final : public Expression {
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)
, m_specifier(move(specifier))
, m_options(move(options))
@ -1984,13 +1982,13 @@ public:
private:
virtual bool is_import_call() const override { return true; }
NonnullRefPtr<Expression> m_specifier;
RefPtr<Expression> m_options;
NonnullRefPtr<Expression const> m_specifier;
RefPtr<Expression const> m_options;
};
class ConditionalExpression final : public Expression {
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)
, m_test(move(test))
, m_consequent(move(consequent))
@ -2003,21 +2001,21 @@ public:
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override;
private:
NonnullRefPtr<Expression> m_test;
NonnullRefPtr<Expression> m_consequent;
NonnullRefPtr<Expression> m_alternate;
NonnullRefPtr<Expression const> m_test;
NonnullRefPtr<Expression const> m_consequent;
NonnullRefPtr<Expression const> m_alternate;
};
class CatchClause final : public ASTNode {
public:
CatchClause(SourceRange source_range, DeprecatedFlyString parameter, NonnullRefPtr<BlockStatement> body)
CatchClause(SourceRange source_range, DeprecatedFlyString parameter, NonnullRefPtr<BlockStatement const> body)
: ASTNode(source_range)
, m_parameter(move(parameter))
, 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)
, m_parameter(move(parameter))
, m_body(move(body))
@ -2031,13 +2029,13 @@ public:
virtual Completion execute(Interpreter&) const override;
private:
Variant<DeprecatedFlyString, NonnullRefPtr<BindingPattern>> m_parameter;
NonnullRefPtr<BlockStatement> m_body;
Variant<DeprecatedFlyString, NonnullRefPtr<BindingPattern const>> m_parameter;
NonnullRefPtr<BlockStatement const> m_body;
};
class TryStatement final : public Statement {
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)
, m_block(move(block))
, m_handler(move(handler))
@ -2054,14 +2052,14 @@ public:
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override;
private:
NonnullRefPtr<BlockStatement> m_block;
RefPtr<CatchClause> m_handler;
RefPtr<BlockStatement> m_finalizer;
NonnullRefPtr<BlockStatement const> m_block;
RefPtr<CatchClause const> m_handler;
RefPtr<BlockStatement const> m_finalizer;
};
class ThrowStatement final : public Statement {
public:
explicit ThrowStatement(SourceRange source_range, NonnullRefPtr<Expression> argument)
explicit ThrowStatement(SourceRange source_range, NonnullRefPtr<Expression const> argument)
: Statement(source_range)
, m_argument(move(argument))
{
@ -2074,12 +2072,12 @@ public:
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override;
private:
NonnullRefPtr<Expression> m_argument;
NonnullRefPtr<Expression const> m_argument;
};
class SwitchCase final : public ScopeNode {
public:
SwitchCase(SourceRange source_range, RefPtr<Expression> test)
SwitchCase(SourceRange source_range, RefPtr<Expression const> test)
: ScopeNode(source_range)
, m_test(move(test))
{
@ -2091,12 +2089,12 @@ public:
virtual Completion execute(Interpreter&) const override;
private:
RefPtr<Expression> m_test;
RefPtr<Expression const> m_test;
};
class SwitchStatement final : public ScopeNode {
public:
SwitchStatement(SourceRange source_range, NonnullRefPtr<Expression> discriminant)
SwitchStatement(SourceRange source_range, NonnullRefPtr<Expression const> discriminant)
: ScopeNode(source_range)
, m_discriminant(move(discriminant))
{
@ -2108,11 +2106,11 @@ public:
virtual Bytecode::CodeGenerationErrorOr<void> generate_labelled_evaluation(Bytecode::Generator&, Vector<DeprecatedFlyString> const&) 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:
NonnullRefPtr<Expression> m_discriminant;
NonnullRefPtrVector<SwitchCase> m_cases;
NonnullRefPtr<Expression const> m_discriminant;
NonnullRefPtrVector<SwitchCase const> m_cases;
};
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, Gunnar Beutner <gbeutner@serenityos.org>
* Copyright (c) 2021, Marcin Gasperowicz <xnooga@gmail.com>
@ -603,7 +603,7 @@ Bytecode::CodeGenerationErrorOr<void> AssignmentExpression::generate_bytecode(By
// AssignmentExpression : LeftHandSideExpression = AssignmentExpression
return m_lhs.visit(
// 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.
// b. ReturnIfAbrupt(lref).
Optional<Bytecode::Register> base_object_register;
@ -675,7 +675,7 @@ Bytecode::CodeGenerationErrorOr<void> AssignmentExpression::generate_bytecode(By
return {};
},
// 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.
// 4. Let rval be ? GetValue(rref).
TRY(m_rhs->generate_bytecode(generator));
@ -691,8 +691,8 @@ Bytecode::CodeGenerationErrorOr<void> AssignmentExpression::generate_bytecode(By
});
}
VERIFY(m_lhs.has<NonnullRefPtr<Expression>>());
auto& lhs = m_lhs.get<NonnullRefPtr<Expression>>();
VERIFY(m_lhs.has<NonnullRefPtr<Expression const>>());
auto& lhs = m_lhs.get<NonnullRefPtr<Expression const>>();
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) {
if (is_rest) {
VERIFY(name.has<NonnullRefPtr<Identifier>>());
VERIFY(name.has<NonnullRefPtr<Identifier const>>());
VERIFY(alias.has<Empty>());
VERIFY(!initializer);
auto identifier = name.get<NonnullRefPtr<Identifier>>()->string();
auto identifier = name.get<NonnullRefPtr<Identifier const>>()->string();
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);
@ -1234,8 +1234,8 @@ static Bytecode::CodeGenerationErrorOr<void> generate_object_binding_pattern_byt
Bytecode::StringTableIndex name_index;
if (name.has<NonnullRefPtr<Identifier>>()) {
auto identifier = name.get<NonnullRefPtr<Identifier>>()->string();
if (name.has<NonnullRefPtr<Identifier const>>()) {
auto identifier = name.get<NonnullRefPtr<Identifier const>>()->string();
name_index = generator.intern_string(identifier);
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::GetById>(generator.intern_identifier(identifier));
} else {
auto expression = name.get<NonnullRefPtr<Expression>>();
auto expression = name.get<NonnullRefPtr<Expression const>>();
TRY(expression->generate_bytecode(generator));
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);
}
if (alias.has<NonnullRefPtr<BindingPattern>>()) {
auto& binding_pattern = *alias.get<NonnullRefPtr<BindingPattern>>();
if (alias.has<NonnullRefPtr<BindingPattern const>>()) {
auto& binding_pattern = *alias.get<NonnullRefPtr<BindingPattern const>>();
auto nested_value_reg = generator.allocate_register();
generator.emit<Bytecode::Op::Store>(nested_value_reg);
TRY(generate_binding_pattern_bytecode(generator, binding_pattern, initialization_mode, nested_value_reg));
} 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
return Bytecode::CodeGenerationError {
name.get<NonnullRefPtr<Expression>>().ptr(),
name.get<NonnullRefPtr<Expression const>>().ptr(),
"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);
} 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);
}
}
@ -1340,18 +1340,18 @@ static Bytecode::CodeGenerationErrorOr<void> generate_array_binding_pattern_byte
// This element is an elision
return {};
},
[&](NonnullRefPtr<Identifier> const& identifier) -> Bytecode::CodeGenerationErrorOr<void> {
[&](NonnullRefPtr<Identifier const> const& identifier) -> Bytecode::CodeGenerationErrorOr<void> {
auto interned_index = generator.intern_identifier(identifier->string());
generator.emit<Bytecode::Op::SetVariable>(interned_index, initialization_mode);
return {};
},
[&](NonnullRefPtr<BindingPattern> const& pattern) -> Bytecode::CodeGenerationErrorOr<void> {
[&](NonnullRefPtr<BindingPattern const> const& pattern) -> Bytecode::CodeGenerationErrorOr<void> {
// Store the accumulator value in a permanent register
auto target_reg = generator.allocate_register();
generator.emit<Bytecode::Op::Store>(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);
});
};
@ -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;
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);
return {};
},
[&](NonnullRefPtr<BindingPattern> const& pattern) -> Bytecode::CodeGenerationErrorOr<void> {
[&](NonnullRefPtr<BindingPattern const> const& pattern) -> Bytecode::CodeGenerationErrorOr<void> {
auto value_register = generator.allocate_register();
generator.emit<Bytecode::Op::Store>(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 {};
},
[&](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.
return Bytecode::CodeGenerationError {
this,
@ -2422,12 +2422,12 @@ struct ForInOfHeadEvaluationResult {
bool is_destructuring { false };
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 {};
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:
// ForInOfStatement : for ( var ForBinding 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
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;
// 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
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();
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.)
// 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) {
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);
TRY(assign_accumulator_to_variable_declarator(generator, declaration.declarations().first(), declaration));
} 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));
} else {
auto& binding_pattern = lhs.get<NonnullRefPtr<BindingPattern>>();
auto& binding_pattern = lhs.get<NonnullRefPtr<BindingPattern const>>();
auto value_register = generator.allocate_register();
generator.emit<Bytecode::Op::Store>(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
// 1. Assert: environment is a declarative Environment Record.
// 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
variable_declaration.for_each_bound_name([&](auto const& name) {
auto identifier = generator.intern_identifier(name);
@ -2630,7 +2630,7 @@ static Bytecode::CodeGenerationErrorOr<void> for_in_of_body_evaluation(Bytecode:
if (!destructuring) {
// 1. Assert: lhs binds a single name.
// 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).
// 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);
@ -2660,9 +2660,9 @@ static Bytecode::CodeGenerationErrorOr<void> for_in_of_body_evaluation(Bytecode:
// 2. Assert: lhs is a ForDeclaration.
// 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) {
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);
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();
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, Ali Mohammad Pur <mpfard@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
*/
@ -68,7 +69,7 @@ public:
[&](DeprecatedFlyString const& 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) {
scope_pusher.m_forbidden_lexical_names.set(name);
});
@ -87,7 +88,7 @@ public:
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);
if (init && is<VariableDeclaration>(*init)) {
@ -102,7 +103,7 @@ public:
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);
if (pattern) {
@ -125,7 +126,7 @@ public:
return ScopePusher(parser, nullptr, ScopeLevel::NotTopLevel);
}
void add_declaration(NonnullRefPtr<Declaration> declaration)
void add_declaration(NonnullRefPtr<Declaration const> declaration)
{
if (declaration->is_lexical_declaration()) {
declaration->for_each_bound_name([&](auto const& name) {
@ -184,7 +185,7 @@ public:
m_function_names.set(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));
}
@ -227,10 +228,10 @@ public:
if (m_lexical_names.contains(function_declaration.name()) || m_forbidden_var_names.contains(function_declaration.name()))
continue;
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 {
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:
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);
}
@ -277,7 +278,7 @@ private:
HashTable<DeprecatedFlyString> m_forbidden_lexical_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;
@ -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();
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 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)
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;
auto function_body_result = [&]() -> RefPtr<FunctionBody> {
auto function_body_result = [&]() -> RefPtr<FunctionBody const> {
TemporaryChange change(m_state.in_arrow_function_context, true);
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);
@ -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() });
ScopePusher function_scope = ScopePusher::function_scope(*this, return_block, parameters);
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)
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();
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);
}
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.
@ -924,7 +925,7 @@ RefPtr<LabelledStatement> Parser::try_parse_labelled_statement(AllowLabelledFunc
if (m_state.labels_in_scope.contains(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;
@ -945,7 +946,7 @@ RefPtr<LabelledStatement> Parser::try_parse_labelled_statement(AllowLabelledFunc
// Extract the innermost statement from a potentially nested chain of LabelledStatements.
auto statement = labelled_item;
while (is<LabelledStatement>(*statement))
statement = static_cast<LabelledStatement&>(*statement).labelled_item();
statement = static_cast<LabelledStatement const&>(*statement).labelled_item();
if (is<IterationStatement>(*statement))
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());
}
RefPtr<MetaProperty> Parser::try_parse_new_target_expression()
RefPtr<MetaProperty const> Parser::try_parse_new_target_expression()
{
// Optimization which skips the save/load state.
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);
}
RefPtr<MetaProperty> Parser::try_parse_import_meta_expression()
RefPtr<MetaProperty const> Parser::try_parse_import_meta_expression()
{
// Optimization which skips the save/load state.
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);
}
NonnullRefPtr<ImportCall> Parser::parse_import_call()
NonnullRefPtr<ImportCall const> Parser::parse_import_call()
{
auto rule_start = push_start();
@ -1024,7 +1025,7 @@ NonnullRefPtr<ImportCall> Parser::parse_import_call()
consume(TokenType::ParenOpen);
auto argument = parse_expression(2);
RefPtr<Expression> options;
RefPtr<Expression const> options;
if (match(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));
}
NonnullRefPtr<ClassDeclaration> Parser::parse_class_declaration()
NonnullRefPtr<ClassDeclaration const> Parser::parse_class_declaration()
{
auto rule_start = push_start();
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();
// Classes are always in strict mode.
@ -1056,9 +1057,9 @@ NonnullRefPtr<ClassExpression> Parser::parse_class_expression(bool expect_class_
consume(TokenType::Class);
NonnullRefPtrVector<ClassElement> elements;
RefPtr<Expression> super_class;
RefPtr<FunctionExpression> constructor;
NonnullRefPtrVector<ClassElement const> elements;
RefPtr<Expression const> super_class;
RefPtr<FunctionExpression const> constructor;
HashTable<DeprecatedFlyString> found_private_names;
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)) {
RefPtr<Expression> property_key;
RefPtr<Expression const> property_key;
bool is_static = false;
bool is_constructor = false;
bool is_generator = false;
@ -1313,7 +1314,7 @@ NonnullRefPtr<ClassExpression> Parser::parse_class_expression(bool expect_class_
if (name == "constructor"sv)
syntax_error("Class cannot have field named 'constructor'");
RefPtr<Expression> initializer;
RefPtr<Expression const> initializer;
bool contains_direct_call_to_eval = false;
if (match(TokenType::Equals)) {
@ -1389,7 +1390,7 @@ Parser::PrimaryExpressionParseResult Parser::parse_primary_expression()
if (match_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))
return nullptr;
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);
consume(TokenType::ParenClose);
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)
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)
@ -1534,7 +1535,7 @@ Parser::PrimaryExpressionParseResult Parser::parse_primary_expression()
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 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));
}
NonnullRefPtr<Expression> Parser::parse_unary_prefixed_expression()
NonnullRefPtr<Expression const> Parser::parse_unary_prefixed_expression()
{
auto rule_start = push_start();
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);
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();
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);
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();
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();
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();
consume(TokenType::CurlyOpen);
@ -1697,8 +1698,8 @@ NonnullRefPtr<ObjectExpression> Parser::parse_object_expression()
while (!done() && !match(TokenType::CurlyClose)) {
property_type = ObjectProperty::Type::KeyValue;
RefPtr<Expression> property_key;
RefPtr<Expression> property_value;
RefPtr<Expression const> property_key;
RefPtr<Expression const> property_value;
FunctionKind function_kind { FunctionKind::Normal };
if (match(TokenType::TripleDot)) {
@ -1829,14 +1830,14 @@ NonnullRefPtr<ObjectExpression> Parser::parse_object_expression()
move(properties));
}
NonnullRefPtr<ArrayExpression> Parser::parse_array_expression()
NonnullRefPtr<ArrayExpression const> Parser::parse_array_expression()
{
auto rule_start = push_start();
consume(TokenType::BracketOpen);
Vector<RefPtr<Expression>> elements;
Vector<RefPtr<Expression const>> elements;
while (match_expression() || match(TokenType::TripleDot) || match(TokenType::Comma)) {
RefPtr<Expression> expression;
RefPtr<Expression const> expression;
if (match(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));
}
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 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);
}
NonnullRefPtr<TemplateLiteral> Parser::parse_template_literal(bool is_tagged)
NonnullRefPtr<TemplateLiteral const> Parser::parse_template_literal(bool is_tagged)
{
auto rule_start = push_start();
consume(TokenType::TemplateLiteralStart);
NonnullRefPtrVector<Expression> expressions;
NonnullRefPtrVector<Expression> raw_strings;
NonnullRefPtrVector<Expression const> expressions;
NonnullRefPtrVector<Expression const> raw_strings;
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() }, "");
@ -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);
}
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 [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) {
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_parent_scope = function_scope ? function_scope->parent_scope() : nullptr;
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);
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)) {
auto& identifier_instance = static_cast<Identifier const&>(callee);
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) {
NonnullRefPtrVector<Expression> expressions;
NonnullRefPtrVector<Expression const> expressions;
expressions.append(expression);
while (match(TokenType::Comma)) {
consume();
@ -2047,7 +2048,7 @@ NonnullRefPtr<Expression> Parser::parse_expression(int min_precedence, Associati
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();
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()));
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();
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()));
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();
check_identifier_name_for_assignment_validity(name);
}
@ -2238,7 +2239,7 @@ bool Parser::is_private_identifier_valid() const
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));
// 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;
}
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();
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));
}
NonnullRefPtr<Identifier> Parser::parse_identifier()
NonnullRefPtr<Identifier const> Parser::parse_identifier()
{
auto identifier_start = position();
auto token = consume_identifier();
@ -2359,7 +2360,7 @@ Vector<CallExpression::Argument> Parser::parse_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();
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());
}
NonnullRefPtr<NewExpression> Parser::parse_new_expression()
NonnullRefPtr<NewExpression const> Parser::parse_new_expression()
{
auto rule_start = push_start();
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));
}
NonnullRefPtr<YieldExpression> Parser::parse_yield_expression()
NonnullRefPtr<YieldExpression const> Parser::parse_yield_expression()
{
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");
consume(TokenType::Yield);
RefPtr<Expression> argument;
RefPtr<Expression const> argument;
bool yield_from = false;
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);
}
NonnullRefPtr<AwaitExpression> Parser::parse_await_expression()
NonnullRefPtr<AwaitExpression const> Parser::parse_await_expression()
{
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));
}
NonnullRefPtr<ReturnStatement> Parser::parse_return_statement()
NonnullRefPtr<ReturnStatement const> Parser::parse_return_statement()
{
auto rule_start = push_start();
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
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 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);
},
[&](NonnullRefPtr<BindingPattern> const& binding) {
[&](NonnullRefPtr<BindingPattern const> const& binding) {
binding->for_each_bound_name([&](auto& bound_name) {
if (function_kind == FunctionKind::Generator && bound_name == "yield"sv)
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;
}
NonnullRefPtr<BlockStatement> Parser::parse_block_statement()
NonnullRefPtr<BlockStatement const> Parser::parse_block_statement()
{
auto rule_start = push_start();
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;
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))
return pattern.release_nonnull();
@ -2683,7 +2684,7 @@ Vector<FunctionParameter> Parser::parse_formal_parameters(int& function_length,
[&](DeprecatedFlyString const& name) {
return name == parameter_name;
},
[&](NonnullRefPtr<BindingPattern> const& bindings) {
[&](NonnullRefPtr<BindingPattern const> const& bindings) {
bool found_duplicate = false;
bindings->for_each_bound_name([&](auto& bound_name) {
if (bound_name == parameter_name)
@ -2724,7 +2725,7 @@ Vector<FunctionParameter> Parser::parse_formal_parameters(int& function_length,
is_rest = true;
}
auto parameter = consume_identifier_or_binding_pattern();
RefPtr<Expression> default_value;
RefPtr<Expression const> default_value;
if (match(TokenType::Equals)) {
consume();
@ -2737,7 +2738,7 @@ Vector<FunctionParameter> Parser::parse_formal_parameters(int& function_length,
default_value = parse_expression(2);
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\"");
}
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" };
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();
@ -2794,7 +2795,7 @@ RefPtr<BindingPattern> Parser::parse_binding_pattern(Parser::AllowDuplicates all
decltype(BindingPattern::BindingEntry::name) name = Empty {};
decltype(BindingPattern::BindingEntry::alias) alias = Empty {};
RefPtr<Expression> initializer = {};
RefPtr<Expression const> initializer = {};
if (is_object) {
bool needs_alias = false;
@ -2802,9 +2803,9 @@ RefPtr<BindingPattern> Parser::parse_binding_pattern(Parser::AllowDuplicates all
auto expression_position = position();
auto expression = parse_expression(2, Associativity::Right, { TokenType::Equals });
if (is<MemberExpression>(*expression))
alias = static_ptr_cast<MemberExpression>(expression);
alias = static_ptr_cast<MemberExpression const>(expression);
else if (is<Identifier>(*expression))
name = static_ptr_cast<Identifier>(expression);
name = static_ptr_cast<Identifier const>(expression);
else
syntax_error("Invalid destructuring assignment target", expression_position);
} 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 string_literal = parse_string_literal(token);
name = create_ast_node<Identifier>(
name = create_ast_node<Identifier const>(
{ m_source_code, rule_start.position(), position() },
string_literal->value());
} else if (match(TokenType::BigIntLiteral)) {
auto string_value = consume().DeprecatedFlyString_value();
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() },
DeprecatedFlyString(string_value.view().substring_view(0, string_value.length() - 1)));
} else {
name = create_ast_node<Identifier>(
name = create_ast_node<Identifier const>(
{ m_source_code, rule_start.position(), position() },
consume().DeprecatedFlyString_value());
}
@ -2851,9 +2852,9 @@ RefPtr<BindingPattern> Parser::parse_binding_pattern(Parser::AllowDuplicates all
else
syntax_error("Invalid destructuring assignment target", expression_position);
} else if (is<MemberExpression>(*expression)) {
alias = static_ptr_cast<MemberExpression>(expression);
alias = static_ptr_cast<MemberExpression const>(expression);
} else if (is<Identifier>(*expression)) {
alias = static_ptr_cast<Identifier>(expression);
alias = static_ptr_cast<Identifier const>(expression);
} else {
syntax_error("Invalid destructuring assignment target", expression_position);
}
@ -2863,7 +2864,7 @@ RefPtr<BindingPattern> Parser::parse_binding_pattern(Parser::AllowDuplicates all
return {};
alias = binding_pattern.release_nonnull();
} else if (match_identifier_name()) {
alias = create_ast_node<Identifier>(
alias = create_ast_node<Identifier const>(
{ m_source_code, rule_start.position(), position() },
consume().DeprecatedFlyString_value());
@ -2886,9 +2887,9 @@ RefPtr<BindingPattern> Parser::parse_binding_pattern(Parser::AllowDuplicates all
else
syntax_error("Invalid destructuring assignment target", expression_position);
} else if (is<MemberExpression>(*expression)) {
alias = static_ptr_cast<MemberExpression>(expression);
alias = static_ptr_cast<MemberExpression const>(expression);
} else if (is<Identifier>(*expression)) {
alias = static_ptr_cast<Identifier>(expression);
alias = static_ptr_cast<Identifier const>(expression);
} else {
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()) {
// BindingElement must always have an Empty name field
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() },
identifier_name);
} else {
@ -2962,7 +2963,7 @@ RefPtr<BindingPattern> Parser::parse_binding_pattern(Parser::AllowDuplicates all
return pattern;
}
RefPtr<Identifier> Parser::parse_lexical_binding()
RefPtr<Identifier const> Parser::parse_lexical_binding()
{
auto binding_start = push_start();
@ -2992,7 +2993,7 @@ RefPtr<Identifier> Parser::parse_lexical_binding()
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();
DeclarationKind declaration_kind;
@ -3012,9 +3013,9 @@ NonnullRefPtr<VariableDeclaration> Parser::parse_variable_declaration(IsForLoopV
}
consume();
NonnullRefPtrVector<VariableDeclarator> declarations;
NonnullRefPtrVector<VariableDeclarator const> declarations;
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 ((declaration_kind == DeclarationKind::Let || declaration_kind == DeclarationKind::Const)) {
pattern->for_each_bound_name([this](auto& name) {
@ -3041,7 +3042,7 @@ NonnullRefPtr<VariableDeclaration> Parser::parse_variable_declaration(IsForLoopV
break;
}
RefPtr<Expression> init;
RefPtr<Expression const> init;
if (match(TokenType::Equals)) {
consume();
// 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);
} else if (is_for_loop_variable_declaration == IsForLoopVariableDeclaration::No && declaration_kind == DeclarationKind::Const) {
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");
}
declarations.append(create_ast_node<VariableDeclarator>(
{ 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)));
if (match(TokenType::Comma)) {
@ -3076,14 +3077,14 @@ NonnullRefPtr<VariableDeclaration> Parser::parse_variable_declaration(IsForLoopV
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] ;
auto rule_start = push_start();
VERIFY(m_state.current_token.original_value() == "using"sv);
consume(TokenType::Identifier);
VERIFY(!m_state.current_token.trivia_contains_line_terminator());
NonnullRefPtrVector<VariableDeclarator> declarations;
NonnullRefPtrVector<VariableDeclarator const> declarations;
for (;;) {
auto lexical_binding = parse_lexical_binding();
@ -3096,7 +3097,7 @@ NonnullRefPtr<UsingDeclaration> Parser::parse_using_declaration(IsForLoopVariabl
if (lexical_binding->string() == "let"sv)
syntax_error("Lexical binding may not be called 'let'");
RefPtr<Expression> initializer;
RefPtr<Expression const> initializer;
if (match(TokenType::Equals)) {
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));
}
NonnullRefPtr<ThrowStatement> Parser::parse_throw_statement()
NonnullRefPtr<ThrowStatement const> Parser::parse_throw_statement()
{
auto rule_start = push_start();
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));
}
NonnullRefPtr<BreakStatement> Parser::parse_break_statement()
NonnullRefPtr<BreakStatement const> Parser::parse_break_statement()
{
auto rule_start = push_start();
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);
}
NonnullRefPtr<ContinueStatement> Parser::parse_continue_statement()
NonnullRefPtr<ContinueStatement const> Parser::parse_continue_statement()
{
auto rule_start = push_start();
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);
}
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();
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));
}
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();
Vector<OptionalChain::Reference> chain;
@ -3296,18 +3297,18 @@ NonnullRefPtr<OptionalChain> Parser::parse_optional_chain(NonnullRefPtr<Expressi
move(chain));
}
NonnullRefPtr<TryStatement> Parser::parse_try_statement()
NonnullRefPtr<TryStatement const> Parser::parse_try_statement()
{
auto rule_start = push_start();
consume(TokenType::Try);
auto block = parse_block_statement();
RefPtr<CatchClause> handler;
RefPtr<CatchClause const> handler;
if (match(TokenType::Catch))
handler = parse_catch_clause();
RefPtr<BlockStatement> finalizer;
RefPtr<BlockStatement const> finalizer;
if (match(TokenType::Finally)) {
consume();
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));
}
NonnullRefPtr<DoWhileStatement> Parser::parse_do_while_statement()
NonnullRefPtr<DoWhileStatement const> Parser::parse_do_while_statement()
{
auto rule_start = push_start();
consume(TokenType::Do);
auto body = [&]() -> NonnullRefPtr<Statement> {
auto body = [&]() -> NonnullRefPtr<Statement const> {
TemporaryChange break_change(m_state.in_break_context, true);
TemporaryChange continue_change(m_state.in_continue_context, true);
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));
}
NonnullRefPtr<WhileStatement> Parser::parse_while_statement()
NonnullRefPtr<WhileStatement const> Parser::parse_while_statement()
{
auto rule_start = push_start();
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));
}
NonnullRefPtr<SwitchStatement> Parser::parse_switch_statement()
NonnullRefPtr<SwitchStatement const> Parser::parse_switch_statement()
{
auto rule_start = push_start();
consume(TokenType::Switch);
@ -3393,7 +3394,7 @@ NonnullRefPtr<SwitchStatement> Parser::parse_switch_statement()
return switch_statement;
}
NonnullRefPtr<WithStatement> Parser::parse_with_statement()
NonnullRefPtr<WithStatement const> Parser::parse_with_statement()
{
auto rule_start = push_start();
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));
}
NonnullRefPtr<SwitchCase> Parser::parse_switch_case()
NonnullRefPtr<SwitchCase const> Parser::parse_switch_case()
{
auto rule_start = push_start();
RefPtr<Expression> test;
RefPtr<Expression const> test;
if (consume().type() == TokenType::Case) {
test = parse_expression(0);
@ -3426,13 +3427,13 @@ NonnullRefPtr<SwitchCase> Parser::parse_switch_case()
return switch_case;
}
NonnullRefPtr<CatchClause> Parser::parse_catch_clause()
NonnullRefPtr<CatchClause const> Parser::parse_catch_clause()
{
auto rule_start = push_start();
consume(TokenType::Catch);
DeprecatedFlyString parameter;
RefPtr<BindingPattern> pattern_parameter;
RefPtr<BindingPattern const> pattern_parameter;
auto should_expect_parameter = false;
if (match(TokenType::ParenOpen)) {
should_expect_parameter = true;
@ -3486,7 +3487,7 @@ NonnullRefPtr<CatchClause> Parser::parse_catch_clause()
move(body));
}
NonnullRefPtr<IfStatement> Parser::parse_if_statement()
NonnullRefPtr<IfStatement const> Parser::parse_if_statement()
{
auto rule_start = push_start();
auto parse_function_declaration_as_block_statement = [&] {
@ -3519,13 +3520,13 @@ NonnullRefPtr<IfStatement> Parser::parse_if_statement()
auto predicate = parse_expression(0);
consume(TokenType::ParenClose);
RefPtr<Statement> consequent;
RefPtr<Statement const> consequent;
if (!m_state.strict_mode && match(TokenType::Function))
consequent = parse_function_declaration_as_block_statement();
else
consequent = parse_statement();
RefPtr<Statement> alternate;
RefPtr<Statement const> alternate;
if (match(TokenType::Else)) {
consume();
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));
}
NonnullRefPtr<Statement> Parser::parse_for_statement()
NonnullRefPtr<Statement const> Parser::parse_for_statement()
{
auto rule_start = push_start();
auto is_await_loop = IsForAwaitLoop::No;
@ -3571,7 +3572,7 @@ NonnullRefPtr<Statement> Parser::parse_for_statement()
Optional<ScopePusher> scope_pusher;
RefPtr<ASTNode> init;
RefPtr<ASTNode const> init;
if (!match(TokenType::Semicolon)) {
auto match_for_using_declaration = [&] {
@ -3650,13 +3651,13 @@ NonnullRefPtr<Statement> Parser::parse_for_statement()
}
consume(TokenType::Semicolon);
RefPtr<Expression> test;
RefPtr<Expression const> test;
if (!match(TokenType::Semicolon))
test = parse_expression(0);
consume(TokenType::Semicolon);
RefPtr<Expression> update;
RefPtr<Expression const> update;
if (!match(TokenType::ParenClose))
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));
}
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 has_annexB_for_in_init_extension = false;
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.
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
auto& variable = declaration.declarations().first();
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");
else
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));
}
NonnullRefPtr<DebuggerStatement> Parser::parse_debugger_statement()
NonnullRefPtr<DebuggerStatement const> Parser::parse_debugger_statement()
{
auto rule_start = push_start();
consume(TokenType::Debugger);
@ -4280,7 +4281,7 @@ ModuleRequest Parser::parse_module_request()
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:
// 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));
}
NonnullRefPtr<ExportStatement> Parser::parse_export_statement(Program& program)
NonnullRefPtr<ExportStatement const> Parser::parse_export_statement(Program& program)
{
// We use the extended syntax which adds:
// ExportDeclaration:
@ -4472,7 +4473,7 @@ NonnullRefPtr<ExportStatement> Parser::parse_export_statement(Program& program)
Vector<EntryAndLocation> entries_with_location;
RefPtr<ASTNode> expression = {};
RefPtr<ASTNode const> expression = {};
bool is_default = false;
ModuleRequest from_specifier;
@ -4575,7 +4576,7 @@ NonnullRefPtr<ExportStatement> Parser::parse_export_statement(Program& program)
consume_or_insert_semicolon();
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())
local_name = class_expression.name();
}
@ -4634,21 +4635,21 @@ NonnullRefPtr<ExportStatement> Parser::parse_export_statement(Program& program)
auto declaration = parse_declaration();
m_state.current_scope_pusher->add_declaration(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 });
} 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 });
} else {
VERIFY(is<VariableDeclaration>(*declaration));
auto& variables = static_cast<VariableDeclaration&>(*declaration);
auto& variables = static_cast<VariableDeclaration const&>(*declaration);
VERIFY(variables.is_lexical_declaration());
for (auto& decl : variables.declarations()) {
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 });
},
[&](NonnullRefPtr<BindingPattern> const& binding) {
[&](NonnullRefPtr<BindingPattern const> const& binding) {
binding->for_each_bound_name([&](auto& name) {
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);
for (auto& decl : variable_declaration->declarations()) {
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 });
},
[&](NonnullRefPtr<BindingPattern> const& binding) {
[&](NonnullRefPtr<BindingPattern const> const& binding) {
binding->for_each_bound_name([&](auto& name) {
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) 2021-2022, David Tuin <davidot@serenityos.org>
* Copyright (c) 2023, Andreas Kling <kling@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
@ -70,34 +71,34 @@ public:
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 {
NonnullRefPtr<Expression> result;
NonnullRefPtr<Expression const> result;
bool should_continue_parsing_as_expression { true };
};
NonnullRefPtr<Declaration> parse_declaration();
NonnullRefPtr<Declaration const> parse_declaration();
enum class AllowLabelledFunction {
No,
Yes
};
NonnullRefPtr<Statement> parse_statement(AllowLabelledFunction allow_labelled_function = AllowLabelledFunction::No);
NonnullRefPtr<BlockStatement> parse_block_statement();
NonnullRefPtr<FunctionBody> parse_function_body(Vector<FunctionParameter> const& parameters, FunctionKind function_kind, bool& contains_direct_call_to_eval);
NonnullRefPtr<ReturnStatement> parse_return_statement();
NonnullRefPtr<Statement const> parse_statement(AllowLabelledFunction allow_labelled_function = AllowLabelledFunction::No);
NonnullRefPtr<BlockStatement const> parse_block_statement();
NonnullRefPtr<FunctionBody const> parse_function_body(Vector<FunctionParameter> const& parameters, FunctionKind function_kind, bool& contains_direct_call_to_eval);
NonnullRefPtr<ReturnStatement const> parse_return_statement();
enum class IsForLoopVariableDeclaration {
No,
Yes
};
NonnullRefPtr<VariableDeclaration> parse_variable_declaration(IsForLoopVariableDeclaration is_for_loop_variable_declaration = IsForLoopVariableDeclaration::No);
RefPtr<Identifier> parse_lexical_binding();
NonnullRefPtr<UsingDeclaration> parse_using_declaration(IsForLoopVariableDeclaration is_for_loop_variable_declaration = IsForLoopVariableDeclaration::No);
NonnullRefPtr<Statement> parse_for_statement();
NonnullRefPtr<VariableDeclaration const> parse_variable_declaration(IsForLoopVariableDeclaration is_for_loop_variable_declaration = IsForLoopVariableDeclaration::No);
RefPtr<Identifier const> parse_lexical_binding();
NonnullRefPtr<UsingDeclaration const> parse_using_declaration(IsForLoopVariableDeclaration is_for_loop_variable_declaration = IsForLoopVariableDeclaration::No);
NonnullRefPtr<Statement const> parse_for_statement();
enum class IsForAwaitLoop {
No,
@ -122,36 +123,43 @@ public:
struct ExpressionResult {
template<typename T>
ExpressionResult(NonnullRefPtr<T> expression, ForbiddenTokens forbidden = {})
: expression(expression)
ExpressionResult(NonnullRefPtr<T const> expression, ForbiddenTokens forbidden = {})
: expression(move(expression))
, 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;
};
NonnullRefPtr<Statement> parse_for_in_of_statement(NonnullRefPtr<ASTNode> lhs, IsForAwaitLoop is_await);
NonnullRefPtr<IfStatement> parse_if_statement();
NonnullRefPtr<ThrowStatement> parse_throw_statement();
NonnullRefPtr<TryStatement> parse_try_statement();
NonnullRefPtr<CatchClause> parse_catch_clause();
NonnullRefPtr<SwitchStatement> parse_switch_statement();
NonnullRefPtr<SwitchCase> parse_switch_case();
NonnullRefPtr<BreakStatement> parse_break_statement();
NonnullRefPtr<ContinueStatement> parse_continue_statement();
NonnullRefPtr<DoWhileStatement> parse_do_while_statement();
NonnullRefPtr<WhileStatement> parse_while_statement();
NonnullRefPtr<WithStatement> parse_with_statement();
NonnullRefPtr<DebuggerStatement> parse_debugger_statement();
NonnullRefPtr<ConditionalExpression> parse_conditional_expression(NonnullRefPtr<Expression> test, ForbiddenTokens);
NonnullRefPtr<OptionalChain> parse_optional_chain(NonnullRefPtr<Expression> base);
NonnullRefPtr<Expression> parse_expression(int min_precedence, Associativity associate = Associativity::Right, ForbiddenTokens forbidden = {});
NonnullRefPtr<Statement const> parse_for_in_of_statement(NonnullRefPtr<ASTNode const> lhs, IsForAwaitLoop is_await);
NonnullRefPtr<IfStatement const> parse_if_statement();
NonnullRefPtr<ThrowStatement const> parse_throw_statement();
NonnullRefPtr<TryStatement const> parse_try_statement();
NonnullRefPtr<CatchClause const> parse_catch_clause();
NonnullRefPtr<SwitchStatement const> parse_switch_statement();
NonnullRefPtr<SwitchCase const> parse_switch_case();
NonnullRefPtr<BreakStatement const> parse_break_statement();
NonnullRefPtr<ContinueStatement const> parse_continue_statement();
NonnullRefPtr<DoWhileStatement const> parse_do_while_statement();
NonnullRefPtr<WhileStatement const> parse_while_statement();
NonnullRefPtr<WithStatement const> parse_with_statement();
NonnullRefPtr<DebuggerStatement const> parse_debugger_statement();
NonnullRefPtr<ConditionalExpression const> parse_conditional_expression(NonnullRefPtr<Expression const> test, ForbiddenTokens);
NonnullRefPtr<OptionalChain const> parse_optional_chain(NonnullRefPtr<Expression const> base);
NonnullRefPtr<Expression const> parse_expression(int min_precedence, Associativity associate = Associativity::Right, ForbiddenTokens forbidden = {});
PrimaryExpressionParseResult parse_primary_expression();
NonnullRefPtr<Expression> parse_unary_prefixed_expression();
NonnullRefPtr<RegExpLiteral> parse_regexp_literal();
NonnullRefPtr<ObjectExpression> parse_object_expression();
NonnullRefPtr<ArrayExpression> parse_array_expression();
NonnullRefPtr<Expression const> parse_unary_prefixed_expression();
NonnullRefPtr<RegExpLiteral const> parse_regexp_literal();
NonnullRefPtr<ObjectExpression const> parse_object_expression();
NonnullRefPtr<ArrayExpression const> parse_array_expression();
enum class StringLiteralType {
Normal,
@ -159,26 +167,26 @@ public:
TaggedTemplate
};
NonnullRefPtr<StringLiteral> 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);
ExpressionResult parse_secondary_expression(NonnullRefPtr<Expression>, int min_precedence, Associativity associate = Associativity::Right, ForbiddenTokens forbidden = {});
NonnullRefPtr<Expression> parse_call_expression(NonnullRefPtr<Expression>);
NonnullRefPtr<NewExpression> parse_new_expression();
NonnullRefPtr<ClassDeclaration> parse_class_declaration();
NonnullRefPtr<ClassExpression> parse_class_expression(bool expect_class_name);
NonnullRefPtr<YieldExpression> parse_yield_expression();
NonnullRefPtr<AwaitExpression> parse_await_expression();
NonnullRefPtr<Expression> parse_property_key();
NonnullRefPtr<AssignmentExpression> parse_assignment_expression(AssignmentOp, NonnullRefPtr<Expression> lhs, int min_precedence, Associativity, ForbiddenTokens forbidden = {});
NonnullRefPtr<Identifier> parse_identifier();
NonnullRefPtr<ImportStatement> parse_import_statement(Program& program);
NonnullRefPtr<ExportStatement> parse_export_statement(Program& program);
NonnullRefPtr<StringLiteral const> parse_string_literal(Token const& token, StringLiteralType string_literal_type = StringLiteralType::Normal, bool* contains_invalid_escape = nullptr);
NonnullRefPtr<TemplateLiteral const> parse_template_literal(bool is_tagged);
ExpressionResult parse_secondary_expression(NonnullRefPtr<Expression const>, int min_precedence, Associativity associate = Associativity::Right, ForbiddenTokens forbidden = {});
NonnullRefPtr<Expression const> parse_call_expression(NonnullRefPtr<Expression const>);
NonnullRefPtr<NewExpression const> parse_new_expression();
NonnullRefPtr<ClassDeclaration const> parse_class_declaration();
NonnullRefPtr<ClassExpression const> parse_class_expression(bool expect_class_name);
NonnullRefPtr<YieldExpression const> parse_yield_expression();
NonnullRefPtr<AwaitExpression const> parse_await_expression();
NonnullRefPtr<Expression const> parse_property_key();
NonnullRefPtr<AssignmentExpression const> parse_assignment_expression(AssignmentOp, NonnullRefPtr<Expression const> lhs, int min_precedence, Associativity, ForbiddenTokens forbidden = {});
NonnullRefPtr<Identifier const> parse_identifier();
NonnullRefPtr<ImportStatement const> parse_import_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<LabelledStatement> try_parse_labelled_statement(AllowLabelledFunction allow_function);
RefPtr<MetaProperty> try_parse_new_target_expression();
RefPtr<MetaProperty> try_parse_import_meta_expression();
NonnullRefPtr<ImportCall> parse_import_call();
RefPtr<FunctionExpression const> try_parse_arrow_function_expression(bool expect_parens, bool is_async = false);
RefPtr<LabelledStatement const> try_parse_labelled_statement(AllowLabelledFunction allow_function);
RefPtr<MetaProperty const> try_parse_new_target_expression();
RefPtr<MetaProperty const> try_parse_import_meta_expression();
NonnullRefPtr<ImportCall const> parse_import_call();
Vector<CallExpression::Argument> parse_arguments();
@ -246,7 +254,7 @@ private:
void discard_saved_state();
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;
@ -333,7 +341,7 @@ private:
}
};
NonnullRefPtr<SourceCode> m_source_code;
NonnullRefPtr<SourceCode const> m_source_code;
Vector<Position> m_rule_starts;
ParserState m_state;
DeprecatedFlyString m_filename;

View file

@ -1,6 +1,7 @@
/*
* Copyright (c) 2020, Stephan Unverwerth <s.unverwerth@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
*/
@ -350,7 +351,7 @@ ThrowCompletionOr<void> ECMAScriptFunctionObject::function_declaration_instantia
if (parameter_names.set(name) != AK::HashSetResult::InsertedNewEntry)
has_duplicates = true;
},
[&](NonnullRefPtr<BindingPattern> const& pattern) {
[&](NonnullRefPtr<BindingPattern const> const& pattern) {
if (pattern->contains_expression())
has_parameter_expressions = true;
@ -472,7 +473,8 @@ ThrowCompletionOr<void> ECMAScriptFunctionObject::function_declaration_instantia
return reference.put_value(vm, argument_value);
else
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
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
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();

View file

@ -1,6 +1,7 @@
/*
* Copyright (c) 2020-2021, Andreas Kling <kling@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
*/
@ -14,7 +15,7 @@
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
class ECMAScriptFunctionObject final : public FunctionObject {
@ -114,7 +115,7 @@ private:
Environment* m_environment { nullptr }; // [[Environment]]
PrivateEnvironment* m_private_environment { nullptr }; // [[PrivateEnvironment]]
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]]
ScriptOrModule m_script_or_module; // [[ScriptOrModule]]
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) 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
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
// 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
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;
@ -348,9 +348,9 @@ ThrowCompletionOr<void> VM::property_binding_initialization(BindingPattern const
if (property.is_rest) {
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));
} 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()));
} else {
VERIFY_NOT_REACHED();
@ -368,19 +368,19 @@ ThrowCompletionOr<void> VM::property_binding_initialization(BindingPattern const
auto name = TRY(property.name.visit(
[&](Empty) -> ThrowCompletionOr<PropertyKey> { VERIFY_NOT_REACHED(); },
[&](NonnullRefPtr<Identifier> const& identifier) -> ThrowCompletionOr<PropertyKey> {
[&](NonnullRefPtr<Identifier const> const& identifier) -> ThrowCompletionOr<PropertyKey> {
return identifier->string();
},
[&](NonnullRefPtr<Expression> const& expression) -> ThrowCompletionOr<PropertyKey> {
[&](NonnullRefPtr<Expression const> const& expression) -> ThrowCompletionOr<PropertyKey> {
auto result = TRY(expression->execute(interpreter())).release_value();
return result.to_property_key(vm);
}));
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).
auto& identifier = *property.name.get<NonnullRefPtr<Identifier>>();
auto& identifier = *property.name.get<NonnullRefPtr<Identifier const>>();
auto reference = TRY(resolve_binding(identifier.string(), environment));
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(
[&](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));
},
[&](NonnullRefPtr<BindingPattern> const&) -> ThrowCompletionOr<Optional<Reference>> { return Optional<Reference> {}; },
[&](NonnullRefPtr<MemberExpression> const& member_expression) -> ThrowCompletionOr<Optional<Reference>> {
[&](NonnullRefPtr<BindingPattern const> const&) -> ThrowCompletionOr<Optional<Reference>> { return Optional<Reference> {}; },
[&](NonnullRefPtr<MemberExpression const> const& member_expression) -> ThrowCompletionOr<Optional<Reference>> {
return TRY(member_expression->to_reference(interpreter()));
}));
auto value_to_assign = TRY(object->get(name));
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()));
else
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));
} else {
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(
[&](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));
},
[&](NonnullRefPtr<BindingPattern> const&) -> ThrowCompletionOr<Optional<Reference>> { return Optional<Reference> {}; },
[&](NonnullRefPtr<MemberExpression> const& member_expression) -> ThrowCompletionOr<Optional<Reference>> {
[&](NonnullRefPtr<BindingPattern const> const&) -> ThrowCompletionOr<Optional<Reference>> { return Optional<Reference> {}; },
[&](NonnullRefPtr<MemberExpression const> const& member_expression) -> ThrowCompletionOr<Optional<Reference>> {
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) {
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()));
else
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));
} else if (!entry.alias.has<Empty>()) {
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) 2021-2022, David Tuin <davidot@serenityos.org>
*
@ -235,9 +235,9 @@ public:
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(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);

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
*/
@ -12,7 +12,7 @@
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)));
}

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
*/
@ -14,7 +14,7 @@ namespace JS {
class SourceCode : public RefCounted<SourceCode> {
public:
static NonnullRefPtr<SourceCode> create(String filename, String code);
static NonnullRefPtr<SourceCode const> create(String filename, String code);
String const& filename() const;
String const& code() const;

View file

@ -1,5 +1,6 @@
/*
* Copyright (c) 2020, the SerenityOS developers.
* Copyright (c) 2023, Andreas Kling <kling@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
@ -21,7 +22,7 @@ struct Position {
struct SourceRange {
[[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 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>
*
* 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!
struct RequestedModuleAndSourceIndex {
u32 source_offset { 0 };
ModuleRequest* module_request { nullptr };
ModuleRequest const* module_request { nullptr };
};
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.
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
module.module_request->assertions = move(assertions);
const_cast<ModuleRequest*>(module.module_request)->assertions = move(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);
@ -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,
Vector<ImportEntry> import_entries, Vector<ExportEntry> local_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)
, m_ecmascript_code(move(body))
, m_execution_context(realm.heap())
@ -157,7 +157,7 @@ Result<NonnullGCPtr<SourceTextModule>, Vector<ParserError>> SourceTextModule::pa
Vector<ExportEntry> star_export_entries;
// 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.
// 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>
*
* 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,
Vector<ImportEntry> import_entries, Vector<ExportEntry> local_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;
@ -48,7 +48,7 @@ private:
Vector<ExportEntry> m_indirect_export_entries; // [[IndirectExportEntries]]
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
};
}