LibJS+LibWeb: Add JS::Object::inherits(class_name)
To allow implementing the DOM class hierarchy in JS bindings, this patch adds an inherits() function that can be used to ask an Object if it inherits from a specific C++ class (by name). The necessary overrides are baked into each Object subclass by the new JS_OBJECT macro, which works similarly to C_OBJECT in LibCore. Thanks to @Dexesttp for suggesting this approach. :^)
This commit is contained in:
parent
1914f52371
commit
af51dc105a
Notes:
sideshowbarker
2024-07-19 05:29:32 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/af51dc105a1
57 changed files with 122 additions and 106 deletions
|
@ -31,6 +31,8 @@
|
|||
namespace JS {
|
||||
|
||||
class Array final : public Object {
|
||||
JS_OBJECT(Array, Object);
|
||||
|
||||
public:
|
||||
static Array* create(GlobalObject&);
|
||||
|
||||
|
@ -40,7 +42,6 @@ public:
|
|||
static Array* typed_this(Interpreter&, GlobalObject&);
|
||||
|
||||
private:
|
||||
virtual const char* class_name() const override { return "Array"; }
|
||||
virtual bool is_array() const override { return true; }
|
||||
|
||||
JS_DECLARE_NATIVE_GETTER(length_getter);
|
||||
|
|
|
@ -31,6 +31,8 @@
|
|||
namespace JS {
|
||||
|
||||
class ArrayConstructor final : public NativeFunction {
|
||||
JS_OBJECT(ArrayConstructor, NativeFunction);
|
||||
|
||||
public:
|
||||
explicit ArrayConstructor(GlobalObject&);
|
||||
virtual void initialize(Interpreter&, GlobalObject&) override;
|
||||
|
@ -41,7 +43,6 @@ public:
|
|||
|
||||
private:
|
||||
virtual bool has_constructor() const override { return true; }
|
||||
virtual const char* class_name() const override { return "ArrayConstructor"; }
|
||||
|
||||
JS_DECLARE_NATIVE_FUNCTION(is_array);
|
||||
JS_DECLARE_NATIVE_FUNCTION(of);
|
||||
|
|
|
@ -32,14 +32,14 @@
|
|||
namespace JS {
|
||||
|
||||
class ArrayPrototype final : public Object {
|
||||
JS_OBJECT(ArrayPrototype, Object);
|
||||
|
||||
public:
|
||||
ArrayPrototype(GlobalObject&);
|
||||
virtual void initialize(Interpreter&, GlobalObject&) override;
|
||||
virtual ~ArrayPrototype() override;
|
||||
|
||||
private:
|
||||
virtual const char* class_name() const override { return "ArrayPrototype"; }
|
||||
|
||||
JS_DECLARE_NATIVE_FUNCTION(filter);
|
||||
JS_DECLARE_NATIVE_FUNCTION(for_each);
|
||||
JS_DECLARE_NATIVE_FUNCTION(map);
|
||||
|
|
|
@ -31,6 +31,8 @@
|
|||
namespace JS {
|
||||
|
||||
class BigIntConstructor final : public NativeFunction {
|
||||
JS_OBJECT(BigIntConstructor, NativeFunction);
|
||||
|
||||
public:
|
||||
explicit BigIntConstructor(GlobalObject&);
|
||||
virtual void initialize(Interpreter&, GlobalObject&) override;
|
||||
|
@ -41,7 +43,6 @@ public:
|
|||
|
||||
private:
|
||||
virtual bool has_constructor() const override { return true; }
|
||||
virtual const char* class_name() const override { return "BigIntConstructor"; }
|
||||
|
||||
JS_DECLARE_NATIVE_FUNCTION(as_int_n);
|
||||
JS_DECLARE_NATIVE_FUNCTION(as_uint_n);
|
||||
|
|
|
@ -32,6 +32,8 @@
|
|||
namespace JS {
|
||||
|
||||
class BigIntObject final : public Object {
|
||||
JS_OBJECT(BigIntObject, Object);
|
||||
|
||||
public:
|
||||
static BigIntObject* create(GlobalObject&, BigInt&);
|
||||
|
||||
|
@ -46,7 +48,6 @@ public:
|
|||
|
||||
private:
|
||||
virtual void visit_children(Visitor&) override;
|
||||
virtual const char* class_name() const override { return "BigIntObject"; }
|
||||
virtual bool is_bigint_object() const override { return true; }
|
||||
|
||||
BigInt& m_bigint;
|
||||
|
|
|
@ -31,14 +31,14 @@
|
|||
namespace JS {
|
||||
|
||||
class BigIntPrototype final : public Object {
|
||||
JS_OBJECT(BigIntPrototype, Object);
|
||||
|
||||
public:
|
||||
explicit BigIntPrototype(GlobalObject&);
|
||||
virtual void initialize(Interpreter&, GlobalObject&) override;
|
||||
virtual ~BigIntPrototype() override;
|
||||
|
||||
private:
|
||||
virtual const char* class_name() const override { return "BigIntPrototype"; }
|
||||
|
||||
JS_DECLARE_NATIVE_FUNCTION(to_string);
|
||||
JS_DECLARE_NATIVE_FUNCTION(to_locale_string);
|
||||
JS_DECLARE_NATIVE_FUNCTION(value_of);
|
||||
|
|
|
@ -31,6 +31,8 @@
|
|||
namespace JS {
|
||||
|
||||
class BooleanConstructor final : public NativeFunction {
|
||||
JS_OBJECT(BooleanConstructor, NativeFunction);
|
||||
|
||||
public:
|
||||
explicit BooleanConstructor(GlobalObject&);
|
||||
virtual void initialize(Interpreter&, GlobalObject&) override;
|
||||
|
@ -41,7 +43,6 @@ public:
|
|||
|
||||
private:
|
||||
virtual bool has_constructor() const override { return true; }
|
||||
virtual const char* class_name() const override { return "BooleanConstructor"; }
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -30,6 +30,8 @@
|
|||
|
||||
namespace JS {
|
||||
class BooleanObject : public Object {
|
||||
JS_OBJECT(BooleanObject, Object);
|
||||
|
||||
public:
|
||||
static BooleanObject* create(GlobalObject&, bool);
|
||||
|
||||
|
@ -42,7 +44,6 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
virtual const char* class_name() const override { return "BooleanObject"; }
|
||||
virtual bool is_boolean_object() const override { return true; }
|
||||
bool m_value { false };
|
||||
};
|
||||
|
|
|
@ -31,14 +31,14 @@
|
|||
namespace JS {
|
||||
|
||||
class BooleanPrototype final : public BooleanObject {
|
||||
JS_OBJECT(BooleanPrototype, BooleanObject);
|
||||
|
||||
public:
|
||||
explicit BooleanPrototype(GlobalObject&);
|
||||
virtual void initialize(Interpreter&, GlobalObject&) override;
|
||||
virtual ~BooleanPrototype() override;
|
||||
|
||||
private:
|
||||
virtual const char* class_name() const override { return "BooleanPrototype"; }
|
||||
|
||||
JS_DECLARE_NATIVE_FUNCTION(to_string);
|
||||
JS_DECLARE_NATIVE_FUNCTION(value_of);
|
||||
};
|
||||
|
|
|
@ -31,6 +31,8 @@
|
|||
namespace JS {
|
||||
|
||||
class BoundFunction final : public Function {
|
||||
JS_OBJECT(BoundFunction, Function);
|
||||
|
||||
public:
|
||||
BoundFunction(GlobalObject&, Function& target_function, Value bound_this, Vector<Value> arguments, i32 length, Object* constructor_prototype);
|
||||
virtual void initialize(Interpreter&, GlobalObject&) override;
|
||||
|
@ -56,7 +58,6 @@ public:
|
|||
|
||||
private:
|
||||
virtual bool is_bound_function() const override { return true; }
|
||||
virtual const char* class_name() const override { return "BoundFunction"; }
|
||||
|
||||
Function* m_target_function = nullptr;
|
||||
Object* m_constructor_prototype = nullptr;
|
||||
|
|
|
@ -31,14 +31,14 @@
|
|||
namespace JS {
|
||||
|
||||
class ConsoleObject final : public Object {
|
||||
JS_OBJECT(ConsoleObject, Object);
|
||||
|
||||
public:
|
||||
explicit ConsoleObject(GlobalObject&);
|
||||
virtual void initialize(Interpreter&, GlobalObject&) override;
|
||||
virtual ~ConsoleObject() override;
|
||||
|
||||
private:
|
||||
virtual const char* class_name() const override { return "ConsoleObject"; }
|
||||
|
||||
JS_DECLARE_NATIVE_FUNCTION(log);
|
||||
JS_DECLARE_NATIVE_FUNCTION(debug);
|
||||
JS_DECLARE_NATIVE_FUNCTION(info);
|
||||
|
|
|
@ -32,6 +32,8 @@
|
|||
namespace JS {
|
||||
|
||||
class Date final : public Object {
|
||||
JS_OBJECT(Date, Object);
|
||||
|
||||
public:
|
||||
static Date* create(GlobalObject&, Core::DateTime, u16 milliseconds);
|
||||
|
||||
|
@ -57,7 +59,6 @@ public:
|
|||
|
||||
private:
|
||||
virtual bool is_date() const final { return true; }
|
||||
virtual const char* class_name() const override { return "Date"; }
|
||||
|
||||
Core::DateTime m_datetime;
|
||||
u16 m_milliseconds;
|
||||
|
|
|
@ -31,6 +31,8 @@
|
|||
namespace JS {
|
||||
|
||||
class DateConstructor final : public NativeFunction {
|
||||
JS_OBJECT(DateConstructor, NativeFunction);
|
||||
|
||||
public:
|
||||
explicit DateConstructor(GlobalObject&);
|
||||
virtual void initialize(Interpreter&, GlobalObject&) override;
|
||||
|
@ -41,7 +43,6 @@ public:
|
|||
|
||||
private:
|
||||
virtual bool has_constructor() const override { return true; }
|
||||
virtual const char* class_name() const override { return "DateConstructor"; }
|
||||
|
||||
JS_DECLARE_NATIVE_FUNCTION(now);
|
||||
};
|
||||
|
|
|
@ -31,14 +31,13 @@
|
|||
namespace JS {
|
||||
|
||||
class DatePrototype final : public Object {
|
||||
JS_OBJECT(DatePrototype, Object);
|
||||
public:
|
||||
explicit DatePrototype(GlobalObject&);
|
||||
virtual void initialize(Interpreter&, GlobalObject&) override;
|
||||
virtual ~DatePrototype() override;
|
||||
|
||||
private:
|
||||
virtual const char* class_name() const override { return "DatePrototype"; }
|
||||
|
||||
JS_DECLARE_NATIVE_FUNCTION(get_date);
|
||||
JS_DECLARE_NATIVE_FUNCTION(get_day);
|
||||
JS_DECLARE_NATIVE_FUNCTION(get_full_year);
|
||||
|
|
|
@ -57,7 +57,6 @@ Error::~Error()
|
|||
{ \
|
||||
} \
|
||||
ClassName::~ClassName() { } \
|
||||
const char* ClassName::class_name() const { return #ClassName; }
|
||||
|
||||
JS_ENUMERATE_ERROR_SUBCLASSES
|
||||
#undef __JS_ENUMERATE
|
||||
|
|
|
@ -32,6 +32,8 @@
|
|||
namespace JS {
|
||||
|
||||
class Error : public Object {
|
||||
JS_OBJECT(Error, Object);
|
||||
|
||||
public:
|
||||
static Error* create(GlobalObject&, const FlyString& name, const String& message);
|
||||
|
||||
|
@ -45,7 +47,6 @@ public:
|
|||
|
||||
private:
|
||||
virtual bool is_error() const final { return true; }
|
||||
virtual const char* class_name() const override { return "Error"; }
|
||||
|
||||
FlyString m_name;
|
||||
String m_message;
|
||||
|
@ -53,14 +54,13 @@ private:
|
|||
|
||||
#define DECLARE_ERROR_SUBCLASS(ClassName, snake_name, PrototypeName, ConstructorName) \
|
||||
class ClassName final : public Error { \
|
||||
JS_OBJECT(ClassName, Error); \
|
||||
\
|
||||
public: \
|
||||
static ClassName* create(GlobalObject&, const String& message); \
|
||||
\
|
||||
ClassName(const String& message, Object& prototype); \
|
||||
virtual ~ClassName() override; \
|
||||
\
|
||||
private: \
|
||||
virtual const char* class_name() const override; \
|
||||
};
|
||||
|
||||
#define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName) \
|
||||
|
|
|
@ -32,6 +32,8 @@
|
|||
namespace JS {
|
||||
|
||||
class ErrorConstructor final : public NativeFunction {
|
||||
JS_OBJECT(ErrorConstructor, NativeFunction);
|
||||
|
||||
public:
|
||||
explicit ErrorConstructor(GlobalObject&);
|
||||
virtual void initialize(Interpreter&, GlobalObject&) override;
|
||||
|
@ -42,11 +44,12 @@ public:
|
|||
|
||||
private:
|
||||
virtual bool has_constructor() const override { return true; }
|
||||
virtual const char* class_name() const override { return "ErrorConstructor"; }
|
||||
};
|
||||
|
||||
#define DECLARE_ERROR_SUBCLASS_CONSTRUCTOR(ClassName, snake_name, PrototypeName, ConstructorName) \
|
||||
class ConstructorName final : public NativeFunction { \
|
||||
JS_OBJECT(ConstructorName, NativeFunction); \
|
||||
\
|
||||
public: \
|
||||
explicit ConstructorName(GlobalObject&); \
|
||||
virtual void initialize(Interpreter&, GlobalObject&) override; \
|
||||
|
@ -56,7 +59,6 @@ private:
|
|||
\
|
||||
private: \
|
||||
virtual bool has_constructor() const override { return true; } \
|
||||
virtual const char* class_name() const override { return #ClassName "Constructor"; } \
|
||||
};
|
||||
|
||||
#define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName) \
|
||||
|
|
|
@ -126,8 +126,7 @@ JS_DEFINE_NATIVE_FUNCTION(ErrorPrototype::to_string)
|
|||
: Object(global_object.error_prototype()) \
|
||||
{ \
|
||||
} \
|
||||
PrototypeName::~PrototypeName() { } \
|
||||
const char* PrototypeName::class_name() const { return #PrototypeName; }
|
||||
PrototypeName::~PrototypeName() { }
|
||||
|
||||
JS_ENUMERATE_ERROR_SUBCLASSES
|
||||
#undef __JS_ENUMERATE
|
||||
|
|
|
@ -31,14 +31,14 @@
|
|||
namespace JS {
|
||||
|
||||
class ErrorPrototype final : public Object {
|
||||
JS_OBJECT(ErrorPrototype, Object);
|
||||
|
||||
public:
|
||||
explicit ErrorPrototype(GlobalObject&);
|
||||
virtual void initialize(Interpreter&, GlobalObject&) override;
|
||||
virtual ~ErrorPrototype() override;
|
||||
|
||||
private:
|
||||
virtual const char* class_name() const override { return "ErrorPrototype"; }
|
||||
|
||||
JS_DECLARE_NATIVE_FUNCTION(to_string);
|
||||
|
||||
JS_DECLARE_NATIVE_GETTER(name_getter);
|
||||
|
@ -49,13 +49,12 @@ private:
|
|||
|
||||
#define DECLARE_ERROR_SUBCLASS_PROTOTYPE(ClassName, snake_name, PrototypeName, ConstructorName) \
|
||||
class PrototypeName final : public Object { \
|
||||
JS_OBJECT(PrototypeName, Object); \
|
||||
\
|
||||
public: \
|
||||
explicit PrototypeName(GlobalObject&); \
|
||||
virtual void initialize(Interpreter&, GlobalObject&) override { } \
|
||||
virtual ~PrototypeName() override; \
|
||||
\
|
||||
private: \
|
||||
virtual const char* class_name() const override; \
|
||||
};
|
||||
|
||||
#define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName) \
|
||||
|
|
|
@ -32,6 +32,8 @@
|
|||
namespace JS {
|
||||
|
||||
class Function : public Object {
|
||||
JS_OBJECT(Function, Object);
|
||||
|
||||
public:
|
||||
virtual ~Function();
|
||||
virtual void initialize(Interpreter&, GlobalObject&) override { }
|
||||
|
@ -60,7 +62,6 @@ public:
|
|||
protected:
|
||||
explicit Function(Object& prototype);
|
||||
Function(Object& prototype, Value bound_this, Vector<Value> bound_arguments);
|
||||
virtual const char* class_name() const override { return "Function"; }
|
||||
|
||||
private:
|
||||
virtual bool is_function() const final { return true; }
|
||||
|
|
|
@ -31,6 +31,8 @@
|
|||
namespace JS {
|
||||
|
||||
class FunctionConstructor final : public NativeFunction {
|
||||
JS_OBJECT(FunctionConstructor, NativeFunction);
|
||||
|
||||
public:
|
||||
explicit FunctionConstructor(GlobalObject&);
|
||||
virtual void initialize(Interpreter&, GlobalObject&) override;
|
||||
|
@ -41,7 +43,6 @@ public:
|
|||
|
||||
private:
|
||||
virtual bool has_constructor() const override { return true; }
|
||||
virtual const char* class_name() const override { return "FunctionConstructor"; }
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -31,14 +31,14 @@
|
|||
namespace JS {
|
||||
|
||||
class FunctionPrototype final : public Object {
|
||||
JS_OBJECT(FunctionPrototype, Object);
|
||||
|
||||
public:
|
||||
explicit FunctionPrototype(GlobalObject&);
|
||||
virtual void initialize(Interpreter&, GlobalObject&) override;
|
||||
virtual ~FunctionPrototype() override;
|
||||
|
||||
private:
|
||||
virtual const char* class_name() const override { return "FunctionPrototype"; }
|
||||
|
||||
JS_DECLARE_NATIVE_FUNCTION(apply);
|
||||
JS_DECLARE_NATIVE_FUNCTION(bind);
|
||||
JS_DECLARE_NATIVE_FUNCTION(call);
|
||||
|
|
|
@ -32,6 +32,8 @@
|
|||
namespace JS {
|
||||
|
||||
class GlobalObject : public Object {
|
||||
JS_OBJECT(GlobalObject, Object);
|
||||
|
||||
public:
|
||||
explicit GlobalObject();
|
||||
virtual void initialize();
|
||||
|
@ -53,8 +55,6 @@ protected:
|
|||
void add_constructor(const FlyString& property_name, ConstructorType*&, Object& prototype);
|
||||
|
||||
private:
|
||||
virtual const char* class_name() const override { return "GlobalObject"; }
|
||||
|
||||
JS_DECLARE_NATIVE_FUNCTION(gc);
|
||||
JS_DECLARE_NATIVE_FUNCTION(is_nan);
|
||||
JS_DECLARE_NATIVE_FUNCTION(is_finite);
|
||||
|
|
|
@ -31,6 +31,8 @@
|
|||
namespace JS {
|
||||
|
||||
class JSONObject final : public Object {
|
||||
JS_OBJECT(JSONObject, Object);
|
||||
|
||||
public:
|
||||
explicit JSONObject(GlobalObject&);
|
||||
virtual void initialize(Interpreter&, GlobalObject&) override;
|
||||
|
@ -45,8 +47,6 @@ private:
|
|||
Optional<Vector<String>> property_list;
|
||||
};
|
||||
|
||||
virtual const char* class_name() const override { return "JSONObject"; }
|
||||
|
||||
// Stringify helpers
|
||||
static String serialize_json_property(Interpreter&, StringifyState&, const PropertyName& key, Object* holder);
|
||||
static String serialize_json_object(Interpreter&, StringifyState&, Object&);
|
||||
|
|
|
@ -31,14 +31,14 @@
|
|||
namespace JS {
|
||||
|
||||
class MathObject final : public Object {
|
||||
JS_OBJECT(MathObject, Object);
|
||||
|
||||
public:
|
||||
explicit MathObject(GlobalObject&);
|
||||
virtual void initialize(Interpreter&, GlobalObject&) override;
|
||||
virtual ~MathObject() override;
|
||||
|
||||
private:
|
||||
virtual const char* class_name() const override { return "MathObject"; }
|
||||
|
||||
JS_DECLARE_NATIVE_FUNCTION(abs);
|
||||
JS_DECLARE_NATIVE_FUNCTION(random);
|
||||
JS_DECLARE_NATIVE_FUNCTION(sqrt);
|
||||
|
|
|
@ -32,6 +32,8 @@
|
|||
namespace JS {
|
||||
|
||||
class NativeFunction : public Function {
|
||||
JS_OBJECT(NativeFunction, Function);
|
||||
|
||||
public:
|
||||
static NativeFunction* create(Interpreter&, GlobalObject&, const FlyString& name, AK::Function<Value(Interpreter&, GlobalObject&)>);
|
||||
|
||||
|
@ -51,7 +53,6 @@ protected:
|
|||
|
||||
private:
|
||||
virtual bool is_native_function() const override { return true; }
|
||||
virtual const char* class_name() const override { return "NativeFunction"; }
|
||||
virtual LexicalEnvironment* create_environment() override final { return nullptr; }
|
||||
|
||||
FlyString m_name;
|
||||
|
|
|
@ -32,6 +32,8 @@
|
|||
namespace JS {
|
||||
|
||||
class NativeProperty final : public Object {
|
||||
JS_OBJECT(NativeProperty, Object);
|
||||
|
||||
public:
|
||||
NativeProperty(AK::Function<Value(Interpreter&, GlobalObject&)> getter, AK::Function<void(Interpreter&, GlobalObject&, Value)> setter);
|
||||
virtual ~NativeProperty() override;
|
||||
|
@ -41,7 +43,6 @@ public:
|
|||
|
||||
private:
|
||||
virtual bool is_native_property() const override { return true; }
|
||||
virtual const char* class_name() const override { return "NativeProperty"; }
|
||||
|
||||
AK::Function<Value(Interpreter&, GlobalObject&)> m_getter;
|
||||
AK::Function<void(Interpreter&, GlobalObject&, Value)> m_setter;
|
||||
|
|
|
@ -31,6 +31,8 @@
|
|||
namespace JS {
|
||||
|
||||
class NumberConstructor final : public NativeFunction {
|
||||
JS_OBJECT(NumberConstructor, NativeFunction);
|
||||
|
||||
public:
|
||||
explicit NumberConstructor(GlobalObject&);
|
||||
virtual void initialize(Interpreter&, GlobalObject&) override;
|
||||
|
@ -41,7 +43,6 @@ public:
|
|||
|
||||
private:
|
||||
virtual bool has_constructor() const override { return true; }
|
||||
virtual const char* class_name() const override { return "NumberConstructor"; }
|
||||
|
||||
JS_DECLARE_NATIVE_FUNCTION(is_finite);
|
||||
JS_DECLARE_NATIVE_FUNCTION(is_integer);
|
||||
|
|
|
@ -31,6 +31,8 @@
|
|||
namespace JS {
|
||||
|
||||
class NumberObject : public Object {
|
||||
JS_OBJECT(NumberObject, Object);
|
||||
|
||||
public:
|
||||
static NumberObject* create(GlobalObject&, double);
|
||||
|
||||
|
@ -41,8 +43,6 @@ public:
|
|||
virtual Value value_of() const override { return Value(m_value); }
|
||||
|
||||
private:
|
||||
virtual const char* class_name() const override { return "NumberObject"; }
|
||||
|
||||
double m_value { 0 };
|
||||
};
|
||||
|
||||
|
|
|
@ -31,12 +31,11 @@
|
|||
namespace JS {
|
||||
|
||||
class NumberPrototype final : public NumberObject {
|
||||
JS_OBJECT(NumberPrototype, NumberObject);
|
||||
|
||||
public:
|
||||
explicit NumberPrototype(GlobalObject&);
|
||||
virtual ~NumberPrototype() override;
|
||||
|
||||
private:
|
||||
virtual const char* class_name() const override { return "NumberPrototype"; }
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -39,6 +39,12 @@
|
|||
|
||||
namespace JS {
|
||||
|
||||
#define JS_OBJECT(class_, base_class) \
|
||||
public: \
|
||||
using Base = base_class; \
|
||||
virtual const char* class_name() const override { return #class_; } \
|
||||
virtual bool inherits(const StringView& class_name) const override { return class_name == #class_ || Base::inherits(class_name); }
|
||||
|
||||
struct PropertyDescriptor {
|
||||
PropertyAttributes attributes;
|
||||
Value value;
|
||||
|
@ -60,6 +66,8 @@ public:
|
|||
virtual void initialize(Interpreter&, GlobalObject&) override;
|
||||
virtual ~Object();
|
||||
|
||||
virtual bool inherits(const StringView& class_name) const { return class_name == this->class_name(); }
|
||||
|
||||
enum class GetOwnPropertyMode {
|
||||
Key,
|
||||
Value,
|
||||
|
@ -111,8 +119,6 @@ public:
|
|||
virtual bool is_symbol_object() const { return false; }
|
||||
virtual bool is_bigint_object() const { return false; }
|
||||
|
||||
virtual bool is_web_wrapper() const { return false; }
|
||||
|
||||
virtual const char* class_name() const override { return "Object"; }
|
||||
virtual void visit_children(Cell::Visitor&) override;
|
||||
|
||||
|
|
|
@ -31,6 +31,8 @@
|
|||
namespace JS {
|
||||
|
||||
class ObjectConstructor final : public NativeFunction {
|
||||
JS_OBJECT(ObjectConstructor, NativeFunction);
|
||||
|
||||
public:
|
||||
explicit ObjectConstructor(GlobalObject&);
|
||||
virtual void initialize(Interpreter&, GlobalObject&) override;
|
||||
|
@ -41,7 +43,6 @@ public:
|
|||
|
||||
private:
|
||||
virtual bool has_constructor() const override { return true; }
|
||||
virtual const char* class_name() const override { return "ObjectConstructor"; }
|
||||
|
||||
JS_DECLARE_NATIVE_FUNCTION(define_property_);
|
||||
JS_DECLARE_NATIVE_FUNCTION(is);
|
||||
|
|
|
@ -31,6 +31,8 @@
|
|||
namespace JS {
|
||||
|
||||
class ObjectPrototype final : public Object {
|
||||
JS_OBJECT(ObjectPrototype, Object);
|
||||
|
||||
public:
|
||||
explicit ObjectPrototype(GlobalObject&);
|
||||
virtual void initialize(Interpreter&, GlobalObject&) override;
|
||||
|
@ -40,8 +42,6 @@ public:
|
|||
JS_DECLARE_NATIVE_FUNCTION(to_string);
|
||||
|
||||
private:
|
||||
virtual const char* class_name() const override { return "ObjectPrototype"; }
|
||||
|
||||
JS_DECLARE_NATIVE_FUNCTION(has_own_property);
|
||||
JS_DECLARE_NATIVE_FUNCTION(to_locale_string);
|
||||
JS_DECLARE_NATIVE_FUNCTION(value_of);
|
||||
|
|
|
@ -31,6 +31,8 @@
|
|||
namespace JS {
|
||||
|
||||
class ProxyConstructor final : public NativeFunction {
|
||||
JS_OBJECT(ProxyConstructor, NativeFunction);
|
||||
|
||||
public:
|
||||
explicit ProxyConstructor(GlobalObject&);
|
||||
virtual void initialize(Interpreter&, GlobalObject&) override;
|
||||
|
@ -41,7 +43,6 @@ public:
|
|||
|
||||
private:
|
||||
virtual bool has_constructor() const override { return true; }
|
||||
virtual const char* class_name() const override { return "ProxyConstructor"; }
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -31,6 +31,8 @@
|
|||
namespace JS {
|
||||
|
||||
class ProxyObject : public Object {
|
||||
JS_OBJECT(ProxyObject, Object);
|
||||
|
||||
public:
|
||||
static ProxyObject* create(GlobalObject&, Object& target, Object& handler);
|
||||
|
||||
|
@ -56,7 +58,6 @@ public:
|
|||
|
||||
private:
|
||||
virtual void visit_children(Visitor&) override;
|
||||
virtual const char* class_name() const override { return "ProxyObject"; }
|
||||
virtual bool is_proxy_object() const override { return true; }
|
||||
virtual bool is_array() const override { return m_target.is_array(); };
|
||||
|
||||
|
|
|
@ -31,12 +31,11 @@
|
|||
namespace JS {
|
||||
|
||||
class ProxyPrototype final : public Object {
|
||||
JS_OBJECT(ProxyPrototype, Object);
|
||||
|
||||
public:
|
||||
explicit ProxyPrototype(GlobalObject&);
|
||||
virtual ~ProxyPrototype() override;
|
||||
|
||||
private:
|
||||
virtual const char* class_name() const override { return "ProxyPrototype"; }
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -31,14 +31,14 @@
|
|||
namespace JS {
|
||||
|
||||
class ReflectObject final : public Object {
|
||||
JS_OBJECT(ReflectObject, Object);
|
||||
|
||||
public:
|
||||
explicit ReflectObject(GlobalObject&);
|
||||
virtual void initialize(Interpreter&, GlobalObject&) override;
|
||||
virtual ~ReflectObject() override;
|
||||
|
||||
private:
|
||||
virtual const char* class_name() const override { return "ReflectObject"; }
|
||||
|
||||
JS_DECLARE_NATIVE_FUNCTION(apply);
|
||||
JS_DECLARE_NATIVE_FUNCTION(construct);
|
||||
JS_DECLARE_NATIVE_FUNCTION(define_property);
|
||||
|
|
|
@ -31,6 +31,8 @@
|
|||
namespace JS {
|
||||
|
||||
class RegExpConstructor final : public NativeFunction {
|
||||
JS_OBJECT(RegExpConstructor, NativeFunction);
|
||||
|
||||
public:
|
||||
explicit RegExpConstructor(GlobalObject&);
|
||||
virtual void initialize(Interpreter&, GlobalObject&) override;
|
||||
|
@ -41,7 +43,6 @@ public:
|
|||
|
||||
private:
|
||||
virtual bool has_constructor() const override { return true; }
|
||||
virtual const char* class_name() const override { return "RegExpConstructor"; }
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -32,6 +32,8 @@
|
|||
namespace JS {
|
||||
|
||||
class RegExpObject : public Object {
|
||||
JS_OBJECT(RegExpObject, Object);
|
||||
|
||||
public:
|
||||
static RegExpObject* create(GlobalObject&, String content, String flags);
|
||||
|
||||
|
@ -44,7 +46,6 @@ public:
|
|||
Value to_string() const override;
|
||||
|
||||
private:
|
||||
virtual const char* class_name() const override { return "RegExpObject"; }
|
||||
virtual bool is_regexp_object() const override { return true; }
|
||||
|
||||
String m_content;
|
||||
|
|
|
@ -31,12 +31,11 @@
|
|||
namespace JS {
|
||||
|
||||
class RegExpPrototype final : public RegExpObject {
|
||||
JS_OBJECT(RegExpPrototype, RegExpObject);
|
||||
|
||||
public:
|
||||
explicit RegExpPrototype(GlobalObject&);
|
||||
virtual ~RegExpPrototype() override;
|
||||
|
||||
private:
|
||||
virtual const char* class_name() const override { return "RegExpPrototype"; }
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -32,6 +32,8 @@
|
|||
namespace JS {
|
||||
|
||||
class ScriptFunction final : public Function {
|
||||
JS_OBJECT(ScriptFunction, Function);
|
||||
|
||||
public:
|
||||
static ScriptFunction* create(GlobalObject&, const FlyString& name, const Statement& body, Vector<FunctionNode::Parameter> parameters, i32 m_function_length, LexicalEnvironment* parent_environment, bool is_arrow_function = false);
|
||||
|
||||
|
@ -50,7 +52,6 @@ public:
|
|||
|
||||
private:
|
||||
virtual bool is_script_function() const override { return true; }
|
||||
virtual const char* class_name() const override { return "ScriptFunction"; }
|
||||
virtual LexicalEnvironment* create_environment() override;
|
||||
virtual void visit_children(Visitor&) override;
|
||||
|
||||
|
|
|
@ -31,6 +31,8 @@
|
|||
namespace JS {
|
||||
|
||||
class StringConstructor final : public NativeFunction {
|
||||
JS_OBJECT(StringConstructor, NativeFunction);
|
||||
|
||||
public:
|
||||
explicit StringConstructor(GlobalObject&);
|
||||
virtual void initialize(Interpreter&, GlobalObject&) override;
|
||||
|
@ -41,7 +43,6 @@ public:
|
|||
|
||||
private:
|
||||
virtual bool has_constructor() const override { return true; }
|
||||
virtual const char* class_name() const override { return "StringConstructor"; }
|
||||
|
||||
JS_DECLARE_NATIVE_FUNCTION(raw);
|
||||
JS_DECLARE_NATIVE_FUNCTION(from_char_code);
|
||||
|
|
|
@ -31,6 +31,8 @@
|
|||
namespace JS {
|
||||
|
||||
class StringObject : public Object {
|
||||
JS_OBJECT(StringObject, Object);
|
||||
|
||||
public:
|
||||
static StringObject* create(GlobalObject&, PrimitiveString&);
|
||||
|
||||
|
@ -45,7 +47,6 @@ public:
|
|||
|
||||
private:
|
||||
virtual void visit_children(Visitor&) override;
|
||||
virtual const char* class_name() const override { return "StringObject"; }
|
||||
virtual bool is_string_object() const override { return true; }
|
||||
|
||||
PrimitiveString& m_string;
|
||||
|
|
|
@ -31,14 +31,14 @@
|
|||
namespace JS {
|
||||
|
||||
class StringPrototype final : public StringObject {
|
||||
JS_OBJECT(StringPrototype, StringObject);
|
||||
|
||||
public:
|
||||
explicit StringPrototype(GlobalObject&);
|
||||
virtual void initialize(Interpreter&, GlobalObject&) override;
|
||||
virtual ~StringPrototype() override;
|
||||
|
||||
private:
|
||||
virtual const char* class_name() const override { return "StringPrototype"; }
|
||||
|
||||
JS_DECLARE_NATIVE_FUNCTION(char_at);
|
||||
JS_DECLARE_NATIVE_FUNCTION(repeat);
|
||||
JS_DECLARE_NATIVE_FUNCTION(starts_with);
|
||||
|
|
|
@ -31,6 +31,8 @@
|
|||
namespace JS {
|
||||
|
||||
class SymbolConstructor final : public NativeFunction {
|
||||
JS_OBJECT(SymbolConstructor, NativeFunction);
|
||||
|
||||
public:
|
||||
explicit SymbolConstructor(GlobalObject&);
|
||||
virtual void initialize(Interpreter&, GlobalObject&) override;
|
||||
|
@ -41,7 +43,6 @@ public:
|
|||
|
||||
private:
|
||||
virtual bool has_constructor() const override { return true; }
|
||||
virtual const char* class_name() const override { return "SymbolConstructor"; }
|
||||
|
||||
JS_DECLARE_NATIVE_FUNCTION(for_);
|
||||
JS_DECLARE_NATIVE_FUNCTION(key_for);
|
||||
|
|
|
@ -32,6 +32,8 @@
|
|||
namespace JS {
|
||||
|
||||
class SymbolObject : public Object {
|
||||
JS_OBJECT(SymbolObject, Object);
|
||||
|
||||
public:
|
||||
static SymbolObject* create(GlobalObject&, Symbol&);
|
||||
|
||||
|
@ -70,7 +72,6 @@ public:
|
|||
|
||||
private:
|
||||
virtual void visit_children(Visitor&) override;
|
||||
virtual const char* class_name() const override { return "SymbolObject"; }
|
||||
virtual bool is_symbol_object() const override { return true; }
|
||||
|
||||
Symbol& m_symbol;
|
||||
|
|
|
@ -31,14 +31,14 @@
|
|||
namespace JS {
|
||||
|
||||
class SymbolPrototype final : public Object {
|
||||
JS_OBJECT(SymbolPrototype, Object);
|
||||
|
||||
public:
|
||||
explicit SymbolPrototype(GlobalObject&);
|
||||
virtual void initialize(Interpreter&, GlobalObject&) override;
|
||||
virtual ~SymbolPrototype() override;
|
||||
|
||||
private:
|
||||
virtual const char* class_name() const override { return "SymbolPrototype"; }
|
||||
|
||||
JS_DECLARE_NATIVE_GETTER(description_getter);
|
||||
|
||||
JS_DECLARE_NATIVE_FUNCTION(to_string);
|
||||
|
|
|
@ -31,6 +31,8 @@
|
|||
namespace JS {
|
||||
|
||||
class Uint8ClampedArray final : public Object {
|
||||
JS_OBJECT(Uint8ClampedArray, Object);
|
||||
|
||||
public:
|
||||
static Uint8ClampedArray* create(GlobalObject&, u32 length);
|
||||
|
||||
|
@ -46,8 +48,6 @@ public:
|
|||
const u8* data() const { return m_data; }
|
||||
|
||||
private:
|
||||
virtual const char* class_name() const override { return "Uint8ClampedArray"; }
|
||||
|
||||
JS_DECLARE_NATIVE_GETTER(length_getter);
|
||||
|
||||
u8* m_data { nullptr };
|
||||
|
|
|
@ -32,6 +32,7 @@ namespace Web {
|
|||
namespace Bindings {
|
||||
|
||||
class CanvasRenderingContext2DWrapper final : public Wrapper {
|
||||
JS_OBJECT(CanvasRenderingContext2DWrapper, Wrapper);
|
||||
public:
|
||||
CanvasRenderingContext2DWrapper(JS::GlobalObject&, CanvasRenderingContext2D&);
|
||||
virtual void initialize(JS::Interpreter&, JS::GlobalObject&) override;
|
||||
|
@ -41,8 +42,6 @@ public:
|
|||
const CanvasRenderingContext2D& impl() const { return m_impl; }
|
||||
|
||||
private:
|
||||
virtual const char* class_name() const override { return "CanvasRenderingContext2DWrapper"; }
|
||||
|
||||
JS_DECLARE_NATIVE_FUNCTION(fill_rect);
|
||||
JS_DECLARE_NATIVE_FUNCTION(stroke_rect);
|
||||
JS_DECLARE_NATIVE_FUNCTION(draw_image);
|
||||
|
|
|
@ -32,6 +32,8 @@ namespace Web {
|
|||
namespace Bindings {
|
||||
|
||||
class EventListenerWrapper final : public Wrapper {
|
||||
JS_OBJECT(EventListenerWrapper, Wrapper);
|
||||
|
||||
public:
|
||||
EventListenerWrapper(JS::GlobalObject&, EventListener&);
|
||||
virtual ~EventListenerWrapper() override;
|
||||
|
@ -40,8 +42,6 @@ public:
|
|||
const EventListener& impl() const { return *m_impl; }
|
||||
|
||||
private:
|
||||
virtual const char* class_name() const override { return "EventListenerWrapper"; }
|
||||
|
||||
NonnullRefPtr<EventListener> m_impl;
|
||||
};
|
||||
|
||||
|
|
|
@ -32,6 +32,8 @@ namespace Web {
|
|||
namespace Bindings {
|
||||
|
||||
class EventWrapper : public Wrapper {
|
||||
JS_OBJECT(EventWrapper, Wrapper);
|
||||
|
||||
public:
|
||||
EventWrapper(JS::GlobalObject&, Event&);
|
||||
virtual ~EventWrapper() override;
|
||||
|
@ -40,8 +42,6 @@ public:
|
|||
const Event& event() const { return m_event; }
|
||||
|
||||
private:
|
||||
virtual const char* class_name() const override { return "EventWrapper"; }
|
||||
|
||||
NonnullRefPtr<Event> m_event;
|
||||
};
|
||||
|
||||
|
|
|
@ -32,6 +32,8 @@ namespace Web {
|
|||
namespace Bindings {
|
||||
|
||||
class ImageDataWrapper : public Wrapper {
|
||||
JS_OBJECT(ImageDataWrapper, Wrapper);
|
||||
|
||||
public:
|
||||
ImageDataWrapper(JS::GlobalObject&, ImageData&);
|
||||
virtual void initialize(JS::Interpreter&, JS::GlobalObject&) override;
|
||||
|
@ -41,8 +43,6 @@ public:
|
|||
const ImageData& impl() const { return m_impl; }
|
||||
|
||||
private:
|
||||
virtual const char* class_name() const override { return "ImageDataWrapper"; }
|
||||
|
||||
JS_DECLARE_NATIVE_GETTER(width_getter);
|
||||
JS_DECLARE_NATIVE_GETTER(height_getter);
|
||||
JS_DECLARE_NATIVE_GETTER(data_getter);
|
||||
|
|
|
@ -33,14 +33,14 @@ namespace Web {
|
|||
namespace Bindings {
|
||||
|
||||
class LocationObject final : public JS::Object {
|
||||
JS_OBJECT(LocationObject, JS::Object);
|
||||
|
||||
public:
|
||||
explicit LocationObject(JS::GlobalObject&);
|
||||
virtual void initialize(JS::Interpreter&, JS::GlobalObject&) override;
|
||||
virtual ~LocationObject() override;
|
||||
|
||||
private:
|
||||
virtual const char* class_name() const override { return "LocationObject"; }
|
||||
|
||||
JS_DECLARE_NATIVE_FUNCTION(reload);
|
||||
|
||||
JS_DECLARE_NATIVE_GETTER(href_getter);
|
||||
|
|
|
@ -33,14 +33,14 @@ namespace Web {
|
|||
namespace Bindings {
|
||||
|
||||
class NavigatorObject final : public JS::Object {
|
||||
JS_OBJECT(NavigatorObject, JS::Object);
|
||||
|
||||
public:
|
||||
NavigatorObject(JS::GlobalObject&);
|
||||
virtual void initialize(JS::Interpreter&, JS::GlobalObject&) override;
|
||||
virtual ~NavigatorObject() override;
|
||||
|
||||
private:
|
||||
virtual const char* class_name() const override { return "NavigatorObject"; }
|
||||
|
||||
JS_DECLARE_NATIVE_GETTER(user_agent_getter);
|
||||
};
|
||||
|
||||
|
|
|
@ -37,20 +37,14 @@ namespace Bindings {
|
|||
class Wrapper
|
||||
: public JS::Object
|
||||
, public Weakable<Wrapper> {
|
||||
public:
|
||||
virtual bool is_event_target_wrapper() const { return false; }
|
||||
virtual bool is_node_wrapper() const { return false; }
|
||||
virtual bool is_document_wrapper() const { return false; }
|
||||
virtual bool is_element_wrapper() const { return false; }
|
||||
virtual bool is_htmlelement_wrapper() const { return false; }
|
||||
JS_OBJECT(Wrapper, JS::Object);
|
||||
|
||||
public:
|
||||
protected:
|
||||
explicit Wrapper(Object& prototype)
|
||||
: Object(&prototype)
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool is_web_wrapper() const final { return true; }
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -32,14 +32,14 @@ namespace Web {
|
|||
namespace Bindings {
|
||||
|
||||
class XMLHttpRequestPrototype final : public JS::Object {
|
||||
JS_OBJECT(XMLHttpRequestPrototype, JS::Object);
|
||||
|
||||
public:
|
||||
explicit XMLHttpRequestPrototype(JS::GlobalObject&);
|
||||
virtual void initialize(JS::Interpreter&, JS::GlobalObject&) override;
|
||||
virtual ~XMLHttpRequestPrototype() override;
|
||||
|
||||
private:
|
||||
virtual const char* class_name() const override { return "XMLHttpRequestPrototype"; }
|
||||
|
||||
JS_DECLARE_NATIVE_FUNCTION(open);
|
||||
JS_DECLARE_NATIVE_FUNCTION(send);
|
||||
|
||||
|
|
|
@ -315,6 +315,7 @@ static void generate_header(const IDL::Interface& interface)
|
|||
out() << "namespace Bindings {";
|
||||
|
||||
out() << "class " << wrapper_class << " : public " << wrapper_base_class << " {";
|
||||
out() << " JS_OBJECT(" << wrapper_class << ", " << wrapper_base_class << ");";
|
||||
out() << "public:";
|
||||
out() << " " << wrapper_class << "(JS::GlobalObject&, " << interface.name << "&);";
|
||||
out() << " virtual void initialize(JS::Interpreter&, JS::GlobalObject&) override;";
|
||||
|
@ -332,7 +333,6 @@ static void generate_header(const IDL::Interface& interface)
|
|||
out() << " virtual bool " << is_foo_wrapper_name << "() const final { return true; }";
|
||||
|
||||
out() << "private:";
|
||||
out() << " virtual const char* class_name() const override { return \"" << interface.name << "\"; }";
|
||||
|
||||
for (auto& function : interface.functions) {
|
||||
out() << " JS_DECLARE_NATIVE_FUNCTION(" << snake_name(function.name) << ");";
|
||||
|
@ -412,8 +412,7 @@ void generate_implementation(const IDL::Interface& interface)
|
|||
out() << " auto* this_object = interpreter.this_value(global_object).to_object(interpreter, global_object);";
|
||||
out() << " if (!this_object)";
|
||||
out() << " return {};";
|
||||
auto is_foo_wrapper_name = snake_name(String::format("Is%s", wrapper_class.characters()));
|
||||
out() << " if (!this_object->is_web_wrapper() || !static_cast<Wrapper*>(this_object)->" << is_foo_wrapper_name << "()) {";
|
||||
out() << " if (!this_object->inherits(\"" << wrapper_class << "\")) {";
|
||||
out() << " interpreter.throw_exception<JS::TypeError>(JS::ErrorType::NotA, \"" << interface.name << "\");";
|
||||
out() << " return nullptr;";
|
||||
out() << " }";
|
||||
|
@ -441,8 +440,7 @@ void generate_implementation(const IDL::Interface& interface)
|
|||
out() << " auto " << cpp_name << "_object = " << js_name << js_suffix << ".to_object(interpreter, global_object);";
|
||||
out() << " if (interpreter.exception())";
|
||||
generate_return();
|
||||
auto is_foo_wrapper_name = snake_name(String::format("Is%sWrapper", parameter.type.name.characters()));
|
||||
out() << " if (!" << cpp_name << "_object->is_web_wrapper() || !static_cast<Wrapper*>(" << cpp_name << "_object)->" << is_foo_wrapper_name << "()) {";
|
||||
out() << " if (!" << cpp_name << "_object->inherits(\"" << parameter.type.name << "Wrapper\")) {";
|
||||
out() << " interpreter.throw_exception<JS::TypeError>(JS::ErrorType::NotA, \"" << parameter.type.name << "\");";
|
||||
generate_return();
|
||||
out() << " }";
|
||||
|
|
Loading…
Add table
Reference in a new issue