LibJS: Make FunctionNode::Parameter be a standalone FunctionParameter

This will allow us to forward declare it and avoid including AST.h in a
number of places.
This commit is contained in:
Andreas Kling 2022-11-23 13:12:36 +01:00 committed by Linus Groh
parent 2a531efc5d
commit 835d7aac96
Notes: sideshowbarker 2024-07-17 04:12:05 +09:00
8 changed files with 35 additions and 34 deletions

View File

@ -607,18 +607,18 @@ struct BindingPattern : RefCounted<BindingPattern> {
Kind kind { Kind::Object };
};
struct FunctionParameter {
Variant<FlyString, NonnullRefPtr<BindingPattern>> binding;
RefPtr<Expression> default_value;
bool is_rest { false };
};
class FunctionNode {
public:
struct Parameter {
Variant<FlyString, NonnullRefPtr<BindingPattern>> binding;
RefPtr<Expression> default_value;
bool is_rest { false };
};
FlyString const& name() const { return m_name; }
String const& source_text() const { return m_source_text; }
Statement const& body() const { return *m_body; }
Vector<Parameter> const& parameters() const { return m_parameters; };
Vector<FunctionParameter> const& parameters() const { return m_parameters; };
i32 function_length() const { return m_function_length; }
bool is_strict_mode() const { return m_is_strict_mode; }
bool might_need_arguments_object() const { return m_might_need_arguments_object; }
@ -627,7 +627,7 @@ public:
FunctionKind kind() const { return m_kind; }
protected:
FunctionNode(FlyString name, String source_text, NonnullRefPtr<Statement> body, Vector<Parameter> 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(FlyString name, String 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)
: m_name(move(name))
, m_source_text(move(source_text))
, m_body(move(body))
@ -649,7 +649,7 @@ private:
FlyString m_name;
String m_source_text;
NonnullRefPtr<Statement> m_body;
Vector<Parameter> const m_parameters;
Vector<FunctionParameter> const m_parameters;
const i32 m_function_length;
FunctionKind m_kind;
bool m_is_strict_mode { false };
@ -664,7 +664,7 @@ class FunctionDeclaration final
public:
static bool must_have_name() { return true; }
FunctionDeclaration(SourceRange source_range, FlyString const& name, String source_text, NonnullRefPtr<Statement> body, Vector<Parameter> 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, FlyString const& name, String 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)
: 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)
{
@ -690,7 +690,7 @@ class FunctionExpression final
public:
static bool must_have_name() { return false; }
FunctionExpression(SourceRange source_range, FlyString const& name, String source_text, NonnullRefPtr<Statement> body, Vector<Parameter> 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, FlyString const& name, String 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)
: 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)
{

View File

@ -169,6 +169,7 @@ class Expression;
class ForStatement;
class FunctionEnvironment;
class FunctionNode;
struct FunctionParameter;
class GlobalEnvironment;
class GlobalObject;
class HandleImpl;

View File

@ -59,7 +59,7 @@ private:
}
public:
static ScopePusher function_scope(Parser& parser, FunctionBody& function_body, Vector<FunctionDeclaration::Parameter> const& parameters)
static ScopePusher function_scope(Parser& parser, FunctionBody& function_body, Vector<FunctionParameter> const& parameters)
{
ScopePusher scope_pusher(parser, &function_body, ScopeLevel::FunctionTopLevel);
scope_pusher.m_function_parameters = parameters;
@ -200,7 +200,7 @@ public:
return nullptr;
}
Vector<FunctionDeclaration::Parameter> const& function_parameters() const
Vector<FunctionParameter> const& function_parameters() const
{
return *m_function_parameters;
}
@ -274,7 +274,7 @@ private:
HashTable<FlyString> m_forbidden_var_names;
NonnullRefPtrVector<FunctionDeclaration> m_functions_to_hoist;
Optional<Vector<FunctionDeclaration::Parameter>> m_function_parameters;
Optional<Vector<FunctionParameter>> m_function_parameters;
bool m_contains_access_to_arguments_object { false };
bool m_contains_direct_call_to_eval { false };
@ -704,9 +704,9 @@ static bool is_strict_reserved_word(StringView str)
});
}
static bool is_simple_parameter_list(Vector<FunctionNode::Parameter> const& parameters)
static bool is_simple_parameter_list(Vector<FunctionParameter> const& parameters)
{
return all_of(parameters, [](FunctionNode::Parameter const& parameter) {
return all_of(parameters, [](FunctionParameter const& parameter) {
return !parameter.is_rest && parameter.default_value.is_null() && parameter.binding.has<FlyString>();
});
}
@ -756,7 +756,7 @@ RefPtr<FunctionExpression> Parser::try_parse_arrow_function_expression(bool expe
}
}
Vector<FunctionNode::Parameter> parameters;
Vector<FunctionParameter> parameters;
i32 function_length = -1;
if (expect_parens) {
// We have parens around the function parameters and can re-use the same parsing
@ -1343,12 +1343,12 @@ NonnullRefPtr<ClassExpression> Parser::parse_class_expression(bool expect_class_
constructor = create_ast_node<FunctionExpression>(
{ m_source_code, rule_start.position(), position() }, class_name, "",
move(constructor_body), Vector { FunctionNode::Parameter { move(argument_name), nullptr, true } }, 0, FunctionKind::Normal,
move(constructor_body), Vector { FunctionParameter { move(argument_name), nullptr, true } }, 0, FunctionKind::Normal,
/* is_strict_mode */ true, /* might_need_arguments_object */ false, /* contains_direct_call_to_eval */ false);
} else {
constructor = create_ast_node<FunctionExpression>(
{ m_source_code, rule_start.position(), position() }, class_name, "",
move(constructor_body), Vector<FunctionNode::Parameter> {}, 0, FunctionKind::Normal,
move(constructor_body), Vector<FunctionParameter> {}, 0, FunctionKind::Normal,
/* is_strict_mode */ true, /* might_need_arguments_object */ false, /* contains_direct_call_to_eval */ false);
}
}
@ -2458,7 +2458,7 @@ void Parser::parse_statement_list(ScopeNode& output_node, AllowLabelledFunction
}
// FunctionBody, https://tc39.es/ecma262/#prod-FunctionBody
NonnullRefPtr<FunctionBody> Parser::parse_function_body(Vector<FunctionDeclaration::Parameter> const& parameters, FunctionKind function_kind, bool& contains_direct_call_to_eval)
NonnullRefPtr<FunctionBody> 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() });
@ -2632,14 +2632,14 @@ NonnullRefPtr<FunctionNodeType> Parser::parse_function_node(u16 parse_options, O
contains_direct_call_to_eval);
}
Vector<FunctionNode::Parameter> Parser::parse_formal_parameters(int& function_length, u16 parse_options)
Vector<FunctionParameter> Parser::parse_formal_parameters(int& function_length, u16 parse_options)
{
auto rule_start = push_start();
bool has_default_parameter = false;
bool has_rest_parameter = false;
TemporaryChange formal_parameter_context_change { m_state.in_formal_parameter_context, true };
Vector<FunctionNode::Parameter> parameters;
Vector<FunctionParameter> parameters;
auto consume_identifier_or_binding_pattern = [&]() -> Variant<FlyString, NonnullRefPtr<BindingPattern>> {
if (auto pattern = parse_binding_pattern(AllowDuplicates::No, AllowMemberExpressions::No))

View File

@ -58,7 +58,7 @@ public:
template<typename FunctionNodeType>
NonnullRefPtr<FunctionNodeType> parse_function_node(u16 parse_options = FunctionNodeParseOptions::CheckForFunctionAndName, Optional<Position> const& function_start = {});
Vector<FunctionNode::Parameter> parse_formal_parameters(int& function_length, u16 parse_options = 0);
Vector<FunctionParameter> parse_formal_parameters(int& function_length, u16 parse_options = 0);
enum class AllowDuplicates {
Yes,
@ -86,7 +86,7 @@ public:
NonnullRefPtr<Statement> parse_statement(AllowLabelledFunction allow_labelled_function = AllowLabelledFunction::No);
NonnullRefPtr<BlockStatement> parse_block_statement();
NonnullRefPtr<FunctionBody> parse_function_body(Vector<FunctionDeclaration::Parameter> const& parameters, FunctionKind function_kind, bool& contains_direct_call_to_eval);
NonnullRefPtr<FunctionBody> parse_function_body(Vector<FunctionParameter> const& parameters, FunctionKind function_kind, bool& contains_direct_call_to_eval);
NonnullRefPtr<ReturnStatement> parse_return_statement();
NonnullRefPtr<VariableDeclaration> parse_variable_declaration(bool for_loop_variable_declaration = false);
NonnullRefPtr<Statement> parse_for_statement();

View File

@ -1065,7 +1065,7 @@ Object* create_unmapped_arguments_object(VM& vm, Span<Value> arguments)
}
// 10.4.4.7 CreateMappedArgumentsObject ( func, formals, argumentsList, env ), https://tc39.es/ecma262/#sec-createmappedargumentsobject
Object* create_mapped_arguments_object(VM& vm, FunctionObject& function, Vector<FunctionNode::Parameter> const& formals, Span<Value> arguments, Environment& environment)
Object* create_mapped_arguments_object(VM& vm, FunctionObject& function, Vector<FunctionParameter> const& formals, Span<Value> arguments, Environment& environment)
{
auto& realm = *vm.current_realm();

View File

@ -40,7 +40,7 @@ bool is_compatible_property_descriptor(bool extensible, PropertyDescriptor const
bool validate_and_apply_property_descriptor(Object*, PropertyKey const&, bool extensible, PropertyDescriptor const&, Optional<PropertyDescriptor> const& current);
ThrowCompletionOr<Object*> get_prototype_from_constructor(VM&, FunctionObject const& constructor, Object* (Intrinsics::*intrinsic_default_prototype)());
Object* create_unmapped_arguments_object(VM&, Span<Value> arguments);
Object* create_mapped_arguments_object(VM&, FunctionObject&, Vector<FunctionNode::Parameter> const&, Span<Value> arguments, Environment&);
Object* create_mapped_arguments_object(VM&, FunctionObject&, Vector<FunctionParameter> const&, Span<Value> arguments, Environment&);
enum class CanonicalIndexMode {
DetectNumericRoundtrip,

View File

@ -28,7 +28,7 @@
namespace JS {
ECMAScriptFunctionObject* ECMAScriptFunctionObject::create(Realm& realm, FlyString name, String source_text, Statement const& ecmascript_code, Vector<FunctionNode::Parameter> parameters, i32 m_function_length, Environment* parent_environment, PrivateEnvironment* private_environment, FunctionKind kind, bool is_strict, bool might_need_arguments_object, bool contains_direct_call_to_eval, bool is_arrow_function, Variant<PropertyKey, PrivateName, Empty> class_field_initializer_name)
ECMAScriptFunctionObject* ECMAScriptFunctionObject::create(Realm& realm, FlyString name, String source_text, Statement const& ecmascript_code, Vector<FunctionParameter> parameters, i32 m_function_length, Environment* parent_environment, PrivateEnvironment* private_environment, FunctionKind kind, bool is_strict, bool might_need_arguments_object, bool contains_direct_call_to_eval, bool is_arrow_function, Variant<PropertyKey, PrivateName, Empty> class_field_initializer_name)
{
Object* prototype = nullptr;
switch (kind) {
@ -48,12 +48,12 @@ ECMAScriptFunctionObject* ECMAScriptFunctionObject::create(Realm& realm, FlyStri
return realm.heap().allocate<ECMAScriptFunctionObject>(realm, move(name), move(source_text), ecmascript_code, move(parameters), m_function_length, parent_environment, private_environment, *prototype, kind, is_strict, might_need_arguments_object, contains_direct_call_to_eval, is_arrow_function, move(class_field_initializer_name));
}
ECMAScriptFunctionObject* ECMAScriptFunctionObject::create(Realm& realm, FlyString name, Object& prototype, String source_text, Statement const& ecmascript_code, Vector<FunctionNode::Parameter> parameters, i32 m_function_length, Environment* parent_environment, PrivateEnvironment* private_environment, FunctionKind kind, bool is_strict, bool might_need_arguments_object, bool contains_direct_call_to_eval, bool is_arrow_function, Variant<PropertyKey, PrivateName, Empty> class_field_initializer_name)
ECMAScriptFunctionObject* ECMAScriptFunctionObject::create(Realm& realm, FlyString name, Object& prototype, String source_text, Statement const& ecmascript_code, Vector<FunctionParameter> parameters, i32 m_function_length, Environment* parent_environment, PrivateEnvironment* private_environment, FunctionKind kind, bool is_strict, bool might_need_arguments_object, bool contains_direct_call_to_eval, bool is_arrow_function, Variant<PropertyKey, PrivateName, Empty> class_field_initializer_name)
{
return realm.heap().allocate<ECMAScriptFunctionObject>(realm, move(name), move(source_text), ecmascript_code, move(parameters), m_function_length, parent_environment, private_environment, prototype, kind, is_strict, might_need_arguments_object, contains_direct_call_to_eval, is_arrow_function, move(class_field_initializer_name));
}
ECMAScriptFunctionObject::ECMAScriptFunctionObject(FlyString name, String source_text, Statement const& ecmascript_code, Vector<FunctionNode::Parameter> formal_parameters, i32 function_length, Environment* parent_environment, PrivateEnvironment* private_environment, Object& prototype, FunctionKind kind, bool strict, bool might_need_arguments_object, bool contains_direct_call_to_eval, bool is_arrow_function, Variant<PropertyKey, PrivateName, Empty> class_field_initializer_name)
ECMAScriptFunctionObject::ECMAScriptFunctionObject(FlyString name, String source_text, Statement const& ecmascript_code, Vector<FunctionParameter> formal_parameters, i32 function_length, Environment* parent_environment, PrivateEnvironment* private_environment, Object& prototype, FunctionKind kind, bool strict, bool might_need_arguments_object, bool contains_direct_call_to_eval, bool is_arrow_function, Variant<PropertyKey, PrivateName, Empty> class_field_initializer_name)
: FunctionObject(prototype)
, m_name(move(name))
, m_function_length(function_length)

View File

@ -32,8 +32,8 @@ public:
Global,
};
static ECMAScriptFunctionObject* create(Realm&, FlyString name, String source_text, Statement const& ecmascript_code, Vector<FunctionNode::Parameter> parameters, i32 m_function_length, Environment* parent_environment, PrivateEnvironment* private_environment, FunctionKind, bool is_strict, bool might_need_arguments_object = true, bool contains_direct_call_to_eval = true, bool is_arrow_function = false, Variant<PropertyKey, PrivateName, Empty> class_field_initializer_name = {});
static ECMAScriptFunctionObject* create(Realm&, FlyString name, Object& prototype, String source_text, Statement const& ecmascript_code, Vector<FunctionNode::Parameter> parameters, i32 m_function_length, Environment* parent_environment, PrivateEnvironment* private_environment, FunctionKind, bool is_strict, bool might_need_arguments_object = true, bool contains_direct_call_to_eval = true, bool is_arrow_function = false, Variant<PropertyKey, PrivateName, Empty> class_field_initializer_name = {});
static ECMAScriptFunctionObject* create(Realm&, FlyString name, String source_text, Statement const& ecmascript_code, Vector<FunctionParameter> parameters, i32 m_function_length, Environment* parent_environment, PrivateEnvironment* private_environment, FunctionKind, bool is_strict, bool might_need_arguments_object = true, bool contains_direct_call_to_eval = true, bool is_arrow_function = false, Variant<PropertyKey, PrivateName, Empty> class_field_initializer_name = {});
static ECMAScriptFunctionObject* create(Realm&, FlyString name, Object& prototype, String source_text, Statement const& ecmascript_code, Vector<FunctionParameter> parameters, i32 m_function_length, Environment* parent_environment, PrivateEnvironment* private_environment, FunctionKind, bool is_strict, bool might_need_arguments_object = true, bool contains_direct_call_to_eval = true, bool is_arrow_function = false, Variant<PropertyKey, PrivateName, Empty> class_field_initializer_name = {});
virtual void initialize(Realm&) override;
virtual ~ECMAScriptFunctionObject() override = default;
@ -44,7 +44,7 @@ public:
void make_method(Object& home_object);
Statement const& ecmascript_code() const { return m_ecmascript_code; }
Vector<FunctionNode::Parameter> const& formal_parameters() const { return m_formal_parameters; };
Vector<FunctionParameter> const& formal_parameters() const { return m_formal_parameters; };
virtual FlyString const& name() const override { return m_name; };
void set_name(FlyString const& name);
@ -93,7 +93,7 @@ protected:
virtual Completion ordinary_call_evaluate_body();
private:
ECMAScriptFunctionObject(FlyString name, String source_text, Statement const& ecmascript_code, Vector<FunctionNode::Parameter> parameters, i32 m_function_length, Environment* parent_environment, PrivateEnvironment* private_environment, Object& prototype, FunctionKind, bool is_strict, bool might_need_arguments_object, bool contains_direct_call_to_eval, bool is_arrow_function, Variant<PropertyKey, PrivateName, Empty> class_field_initializer_name);
ECMAScriptFunctionObject(FlyString name, String source_text, Statement const& ecmascript_code, Vector<FunctionParameter> parameters, i32 m_function_length, Environment* parent_environment, PrivateEnvironment* private_environment, Object& prototype, FunctionKind, bool is_strict, bool might_need_arguments_object, bool contains_direct_call_to_eval, bool is_arrow_function, Variant<PropertyKey, PrivateName, Empty> class_field_initializer_name);
virtual bool is_ecmascript_function_object() const override { return true; }
virtual void visit_edges(Visitor&) override;
@ -113,7 +113,7 @@ private:
// Internal Slots of ECMAScript Function Objects, https://tc39.es/ecma262/#table-internal-slots-of-ecmascript-function-objects
Environment* m_environment { nullptr }; // [[Environment]]
PrivateEnvironment* m_private_environment { nullptr }; // [[PrivateEnvironment]]
Vector<FunctionNode::Parameter> const m_formal_parameters; // [[FormalParameters]]
Vector<FunctionParameter> const m_formal_parameters; // [[FormalParameters]]
NonnullRefPtr<Statement> m_ecmascript_code; // [[ECMAScriptCode]]
Realm* m_realm { nullptr }; // [[Realm]]
ScriptOrModule m_script_or_module; // [[ScriptOrModule]]