mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-04-22 12:35:14 +00:00
LibIDL+LibWeb: Begin supporting the LegacyNamespace extended attribute
This is used by WebAssembly IDL files. For now, we mostly use this for error messages and cache keys (to ensure compatibility with existing code as WebAssembly is ported to IDL).
This commit is contained in:
parent
1ff75618c0
commit
af119d92cb
Notes:
sideshowbarker
2024-07-16 23:05:02 +09:00
Author: https://github.com/trflynn89 Commit: https://github.com/SerenityOS/serenity/commit/af119d92cb Pull-request: https://github.com/SerenityOS/serenity/pull/17878 Reviewed-by: https://github.com/alimpfard ✅
4 changed files with 16 additions and 8 deletions
|
@ -2279,6 +2279,7 @@ static void generate_prototype_or_global_mixin_definitions(IDL::Interface const&
|
|||
auto is_global_interface = interface.extended_attributes.contains("Global");
|
||||
auto class_name = is_global_interface ? interface.global_mixin_class : interface.prototype_class;
|
||||
generator.set("name", interface.name);
|
||||
generator.set("namespaced_name", interface.namespaced_name);
|
||||
generator.set("class_name", class_name);
|
||||
generator.set("fully_qualified_name", interface.fully_qualified_name);
|
||||
|
||||
|
@ -2421,7 +2422,7 @@ JS::ThrowCompletionOr<void> @class_name@::initialize(JS::Realm& realm)
|
|||
}
|
||||
|
||||
generator.append(R"~~~(
|
||||
define_direct_property(*vm.well_known_symbol_to_string_tag(), MUST_OR_THROW_OOM(JS::PrimitiveString::create(vm, "@name@"sv)), JS::Attribute::Configurable);
|
||||
define_direct_property(*vm.well_known_symbol_to_string_tag(), MUST_OR_THROW_OOM(JS::PrimitiveString::create(vm, "@namespaced_name@"sv)), JS::Attribute::Configurable);
|
||||
)~~~");
|
||||
|
||||
if (!is_global_interface) {
|
||||
|
@ -2460,7 +2461,7 @@ static JS::ThrowCompletionOr<@fully_qualified_name@*> impl_from(JS::VM& vm)
|
|||
|
||||
generator.append(R"~~~(
|
||||
if (!is<@fully_qualified_name@>(this_object))
|
||||
return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "@name@");
|
||||
return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "@namespaced_name@");
|
||||
return static_cast<@fully_qualified_name@*>(this_object);
|
||||
}
|
||||
)~~~");
|
||||
|
@ -2560,7 +2561,7 @@ JS_DEFINE_NATIVE_FUNCTION(@class_name@::@attribute.setter_callback@)
|
|||
{
|
||||
auto this_value = vm.this_value();
|
||||
if (!this_value.is_object() || !is<@fully_qualified_name@>(this_value.as_object()))
|
||||
return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "@name@");
|
||||
return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "@namespaced_name@");
|
||||
TRY(this_value.as_object().internal_define_own_property("@attribute.name@", JS::PropertyDescriptor { .value = vm.argument(0), .writable = true }));
|
||||
return JS::js_undefined();
|
||||
}
|
||||
|
@ -2877,6 +2878,7 @@ void generate_constructor_implementation(IDL::Interface const& interface, String
|
|||
SourceGenerator generator { builder };
|
||||
|
||||
generator.set("name", interface.name);
|
||||
generator.set("namespaced_name", interface.namespaced_name);
|
||||
generator.set("prototype_class", interface.prototype_class);
|
||||
generator.set("constructor_class", interface.constructor_class);
|
||||
generator.set("fully_qualified_name", interface.fully_qualified_name);
|
||||
|
@ -2973,7 +2975,7 @@ namespace Web::Bindings {
|
|||
|
||||
JS::ThrowCompletionOr<JS::Value> @constructor_class@::call()
|
||||
{
|
||||
return vm().throw_completion<JS::TypeError>(JS::ErrorType::ConstructorWithoutNew, "@name@");
|
||||
return vm().throw_completion<JS::TypeError>(JS::ErrorType::ConstructorWithoutNew, "@namespaced_name@");
|
||||
}
|
||||
|
||||
JS::ThrowCompletionOr<JS::NonnullGCPtr<JS::Object>> @constructor_class@::construct(FunctionObject&)
|
||||
|
@ -2984,7 +2986,7 @@ JS::ThrowCompletionOr<JS::NonnullGCPtr<JS::Object>> @constructor_class@::constru
|
|||
// No constructor
|
||||
generator.set("constructor.length", "0");
|
||||
generator.append(R"~~~(
|
||||
return vm().throw_completion<JS::TypeError>(JS::ErrorType::NotAConstructor, "@name@");
|
||||
return vm().throw_completion<JS::TypeError>(JS::ErrorType::NotAConstructor, "@namespaced_name@");
|
||||
)~~~");
|
||||
} else if (interface.constructors.size() == 1) {
|
||||
// Single constructor
|
||||
|
@ -3029,7 +3031,7 @@ JS::ThrowCompletionOr<void> @constructor_class@::initialize(JS::Realm& realm)
|
|||
[[maybe_unused]] u8 default_attributes = JS::Attribute::Enumerable;
|
||||
|
||||
MUST_OR_THROW_OOM(Base::initialize(realm));
|
||||
define_direct_property(vm.names.prototype, &ensure_web_prototype<@prototype_class@>(realm, "@name@"), 0);
|
||||
define_direct_property(vm.names.prototype, &ensure_web_prototype<@prototype_class@>(realm, "@namespaced_name@"), 0);
|
||||
define_direct_property(vm.names.length, JS::Value(@constructor.length@), JS::Attribute::Configurable);
|
||||
|
||||
)~~~");
|
||||
|
|
|
@ -225,7 +225,7 @@ void Intrinsics::create_web_prototype_and_constructor<@prototype_class@>(JS::Rea
|
|||
if (interface.is_namespace)
|
||||
add_namespace(gen, interface.name, interface.namespace_class);
|
||||
else
|
||||
add_interface(gen, interface.name, interface.prototype_class, interface.constructor_class, lookup_legacy_constructor(interface));
|
||||
add_interface(gen, interface.namespaced_name, interface.prototype_class, interface.constructor_class, lookup_legacy_constructor(interface));
|
||||
}
|
||||
|
||||
// FIXME: Special case WebAssembly. We should convert WASM to use IDL.
|
||||
|
@ -346,7 +346,7 @@ void add_@global_object_snake_name@_exposed_interfaces(JS::Object& global)
|
|||
if (interface.is_namespace)
|
||||
add_namespace(gen, interface.name, interface.namespace_class);
|
||||
else
|
||||
add_interface(gen, interface.name, interface.prototype_class, lookup_legacy_constructor(interface));
|
||||
add_interface(gen, interface.namespaced_name, interface.prototype_class, lookup_legacy_constructor(interface));
|
||||
}
|
||||
|
||||
generator.append(R"~~~(
|
||||
|
|
|
@ -592,6 +592,11 @@ void Parser::parse_interface(Interface& interface)
|
|||
parse_function(extended_attributes, interface);
|
||||
}
|
||||
|
||||
if (auto legacy_namespace = interface.extended_attributes.get("LegacyNamespace"sv); legacy_namespace.has_value())
|
||||
interface.namespaced_name = DeprecatedString::formatted("{}.{}", *legacy_namespace, interface.name);
|
||||
else
|
||||
interface.namespaced_name = interface.name;
|
||||
|
||||
interface.constructor_class = DeprecatedString::formatted("{}Constructor", interface.name);
|
||||
interface.prototype_class = DeprecatedString::formatted("{}Prototype", interface.name);
|
||||
interface.prototype_base_class = DeprecatedString::formatted("{}Prototype", interface.parent_name.is_empty() ? "Object" : interface.parent_name);
|
||||
|
|
|
@ -255,6 +255,7 @@ public:
|
|||
|
||||
DeprecatedString name;
|
||||
DeprecatedString parent_name;
|
||||
DeprecatedString namespaced_name;
|
||||
|
||||
bool is_namespace { false };
|
||||
bool is_mixin { false };
|
||||
|
|
Loading…
Add table
Reference in a new issue