mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 02:37:36 +00:00
LibJS: Add parsing and evaluation of private fields and methods
This commit is contained in:
parent
c7a6572789
commit
16cc82460f
9 changed files with 368 additions and 69 deletions
|
@ -276,8 +276,8 @@ void ECMAScriptFunctionObject::visit_edges(Visitor& visitor)
|
|||
visitor.visit(m_home_object);
|
||||
|
||||
for (auto& field : m_fields) {
|
||||
if (field.name.is_symbol())
|
||||
visitor.visit(field.name.as_symbol());
|
||||
if (auto* property_name_ptr = field.name.get_pointer<PropertyName>(); property_name_ptr && property_name_ptr->is_symbol())
|
||||
visitor.visit(property_name_ptr->as_symbol());
|
||||
|
||||
visitor.visit(field.initializer);
|
||||
}
|
||||
|
@ -729,17 +729,9 @@ void ECMAScriptFunctionObject::set_name(const FlyString& name)
|
|||
VERIFY(success);
|
||||
}
|
||||
|
||||
// 7.3.31 DefineField ( receiver, fieldRecord ), https://tc39.es/ecma262/#sec-definefield
|
||||
void ECMAScriptFunctionObject::InstanceField::define_field(VM& vm, Object& receiver) const
|
||||
void ECMAScriptFunctionObject::add_field(ClassElement::ClassElementName property_key, ECMAScriptFunctionObject* initializer)
|
||||
{
|
||||
Value init_value = js_undefined();
|
||||
if (initializer) {
|
||||
auto init_value_or_error = vm.call(*initializer, receiver.value_of());
|
||||
if (init_value_or_error.is_error())
|
||||
return;
|
||||
init_value = init_value_or_error.release_value();
|
||||
}
|
||||
(void)receiver.create_data_property_or_throw(name, init_value);
|
||||
m_fields.empend(property_key, initializer);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -59,14 +59,15 @@ public:
|
|||
void set_home_object(Object* home_object) { m_home_object = home_object; }
|
||||
|
||||
struct InstanceField {
|
||||
PropertyName name;
|
||||
Variant<PropertyName, PrivateName> name;
|
||||
ECMAScriptFunctionObject* initializer { nullptr };
|
||||
|
||||
void define_field(VM& vm, Object& receiver) const;
|
||||
};
|
||||
|
||||
Vector<InstanceField> const& fields() const { return m_fields; }
|
||||
void add_field(PropertyName property_key, ECMAScriptFunctionObject* initializer) { m_fields.empend(property_key, initializer); }
|
||||
void add_field(Variant<PropertyName, PrivateName> property_key, ECMAScriptFunctionObject* initializer);
|
||||
|
||||
Vector<PrivateElement> const& private_methods() const { return m_private_methods; }
|
||||
void add_private_method(PrivateElement method) { m_private_methods.append(move(method)); };
|
||||
|
||||
// This is for IsSimpleParameterList (static semantics)
|
||||
bool has_simple_parameter_list() const { return m_has_simple_parameter_list; }
|
||||
|
@ -97,6 +98,7 @@ private:
|
|||
bool m_strict { false }; // [[Strict]]
|
||||
Object* m_home_object { nullptr }; // [[HomeObject]]
|
||||
Vector<InstanceField> m_fields; // [[Fields]]
|
||||
Vector<PrivateElement> m_private_methods; // [[PrivateMethods]]
|
||||
bool m_is_class_constructor { false }; // [[IsClassConstructor]]
|
||||
|
||||
FlyString m_name;
|
||||
|
|
|
@ -34,8 +34,9 @@ PrivateName PrivateEnvironment::resolve_private_identifier(FlyString const& iden
|
|||
|
||||
void PrivateEnvironment::add_private_name(Badge<ClassExpression>, FlyString description)
|
||||
{
|
||||
// FIXME: there is a exception for getter setter pairs.
|
||||
VERIFY(find_private_name(description).is_end());
|
||||
if (!find_private_name(description).is_end())
|
||||
return;
|
||||
|
||||
m_private_names.empend(m_unique_id, move(description));
|
||||
}
|
||||
|
||||
|
|
|
@ -478,11 +478,11 @@ Reference VM::resolve_binding(FlyString const& name, Environment* environment)
|
|||
// 7.3.32 InitializeInstanceElements ( O, constructor ), https://tc39.es/ecma262/#sec-initializeinstanceelements
|
||||
ThrowCompletionOr<void> VM::initialize_instance_elements(Object& object, ECMAScriptFunctionObject& constructor)
|
||||
{
|
||||
for (auto& field : constructor.fields()) {
|
||||
field.define_field(*this, object);
|
||||
if (auto* exception = this->exception())
|
||||
return JS::throw_completion(exception->value());
|
||||
}
|
||||
for (auto& method : constructor.private_methods())
|
||||
TRY(object.private_method_or_accessor_add(method));
|
||||
|
||||
for (auto& field : constructor.fields())
|
||||
TRY(object.define_field(field.name, field.initializer));
|
||||
return {};
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue