mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 02:47:34 +00:00
LibWeb: Support interfaces with the [Global] extended attribute
These are treated differently as the interface members are placed on the object itself, not its prototype. As the object itself still needs to be hand-written code, and we can no longer fully hide the gnarly generated code in the prototype object, these now generate a 'mixin' class that is added to the actual object through inheritance. https://webidl.spec.whatwg.org/#Global
This commit is contained in:
parent
de83f5422d
commit
3316d247bf
5 changed files with 639 additions and 443 deletions
|
@ -76,7 +76,7 @@ endfunction()
|
||||||
function (generate_js_bindings target)
|
function (generate_js_bindings target)
|
||||||
set(LIBWEB_INPUT_FOLDER "${CMAKE_CURRENT_SOURCE_DIR}")
|
set(LIBWEB_INPUT_FOLDER "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||||
function(libweb_js_bindings class)
|
function(libweb_js_bindings class)
|
||||||
cmake_parse_arguments(PARSE_ARGV 1 LIBWEB_BINDINGS "ITERABLE" "" "")
|
cmake_parse_arguments(PARSE_ARGV 1 LIBWEB_BINDINGS "ITERABLE;GLOBAL" "" "")
|
||||||
get_filename_component(basename "${class}" NAME)
|
get_filename_component(basename "${class}" NAME)
|
||||||
set(BINDINGS_SOURCES
|
set(BINDINGS_SOURCES
|
||||||
"Bindings/${basename}Constructor.h"
|
"Bindings/${basename}Constructor.h"
|
||||||
|
@ -102,6 +102,19 @@ function (generate_js_bindings target)
|
||||||
iterator-prototype-implementation
|
iterator-prototype-implementation
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# FIXME: Instead of requiring a manual declaration of global object bindings, we should ask BindingsGenerator if it's global
|
||||||
|
if(LIBWEB_BINDINGS_GLOBAL)
|
||||||
|
list(APPEND BINDINGS_SOURCES
|
||||||
|
"Bindings/${basename}GlobalMixin.h"
|
||||||
|
"Bindings/${basename}GlobalMixin.cpp"
|
||||||
|
)
|
||||||
|
list(APPEND BINDINGS_TYPES
|
||||||
|
global-mixin-header
|
||||||
|
global-mixin-implementation
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
target_sources(${target} PRIVATE ${BINDINGS_SOURCES})
|
target_sources(${target} PRIVATE ${BINDINGS_SOURCES})
|
||||||
# FIXME: cmake_minimum_required(3.17) for ZIP_LISTS
|
# FIXME: cmake_minimum_required(3.17) for ZIP_LISTS
|
||||||
list(LENGTH BINDINGS_SOURCES num_bindings)
|
list(LENGTH BINDINGS_SOURCES num_bindings)
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2020-2021, Andreas Kling <kling@serenityos.org>
|
* Copyright (c) 2020-2021, Andreas Kling <kling@serenityos.org>
|
||||||
* Copyright (c) 2021-2022, Linus Groh <linusg@serenityos.org>
|
* Copyright (c) 2021-2023, Linus Groh <linusg@serenityos.org>
|
||||||
* Copyright (c) 2021, Luke Wilde <lukew@serenityos.org>
|
* Copyright (c) 2021, Luke Wilde <lukew@serenityos.org>
|
||||||
* Copyright (c) 2022, Ali Mohammad Pur <mpfard@serenityos.org>
|
* Copyright (c) 2022, Ali Mohammad Pur <mpfard@serenityos.org>
|
||||||
*
|
*
|
||||||
|
@ -24,6 +24,8 @@ void generate_prototype_header(IDL::Interface const&, StringBuilder&);
|
||||||
void generate_prototype_implementation(IDL::Interface const&, StringBuilder&);
|
void generate_prototype_implementation(IDL::Interface const&, StringBuilder&);
|
||||||
void generate_iterator_prototype_header(IDL::Interface const&, StringBuilder&);
|
void generate_iterator_prototype_header(IDL::Interface const&, StringBuilder&);
|
||||||
void generate_iterator_prototype_implementation(IDL::Interface const&, StringBuilder&);
|
void generate_iterator_prototype_implementation(IDL::Interface const&, StringBuilder&);
|
||||||
|
void generate_global_mixin_header(IDL::Interface const&, StringBuilder&);
|
||||||
|
void generate_global_mixin_implementation(IDL::Interface const&, StringBuilder&);
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorOr<int> serenity_main(Main::Arguments arguments)
|
ErrorOr<int> serenity_main(Main::Arguments arguments)
|
||||||
|
@ -40,12 +42,16 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
||||||
bool prototype_implementation_mode = false;
|
bool prototype_implementation_mode = false;
|
||||||
bool iterator_prototype_header_mode = false;
|
bool iterator_prototype_header_mode = false;
|
||||||
bool iterator_prototype_implementation_mode = false;
|
bool iterator_prototype_implementation_mode = false;
|
||||||
|
bool global_mixin_header_mode = false;
|
||||||
|
bool global_mixin_implementation_mode = false;
|
||||||
args_parser.add_option(constructor_header_mode, "Generate the constructor .h file", "constructor-header", 'C');
|
args_parser.add_option(constructor_header_mode, "Generate the constructor .h file", "constructor-header", 'C');
|
||||||
args_parser.add_option(constructor_implementation_mode, "Generate the constructor .cpp file", "constructor-implementation", 'O');
|
args_parser.add_option(constructor_implementation_mode, "Generate the constructor .cpp file", "constructor-implementation", 'O');
|
||||||
args_parser.add_option(prototype_header_mode, "Generate the prototype .h file", "prototype-header", 'P');
|
args_parser.add_option(prototype_header_mode, "Generate the prototype .h file", "prototype-header", 'P');
|
||||||
args_parser.add_option(prototype_implementation_mode, "Generate the prototype .cpp file", "prototype-implementation", 'R');
|
args_parser.add_option(prototype_implementation_mode, "Generate the prototype .cpp file", "prototype-implementation", 'R');
|
||||||
args_parser.add_option(iterator_prototype_header_mode, "Generate the iterator prototype .h file", "iterator-prototype-header", 0);
|
args_parser.add_option(iterator_prototype_header_mode, "Generate the iterator prototype .h file", "iterator-prototype-header", 0);
|
||||||
args_parser.add_option(iterator_prototype_implementation_mode, "Generate the iterator prototype .cpp file", "iterator-prototype-implementation", 0);
|
args_parser.add_option(iterator_prototype_implementation_mode, "Generate the iterator prototype .cpp file", "iterator-prototype-implementation", 0);
|
||||||
|
args_parser.add_option(global_mixin_header_mode, "Generate the global object mixin .h file", "global-mixin-header", 0);
|
||||||
|
args_parser.add_option(global_mixin_implementation_mode, "Generate the global object mixin .cpp file", "global-mixin-implementation", 0);
|
||||||
args_parser.add_option(Core::ArgsParser::Option {
|
args_parser.add_option(Core::ArgsParser::Option {
|
||||||
.argument_mode = Core::ArgsParser::OptionArgumentMode::Required,
|
.argument_mode = Core::ArgsParser::OptionArgumentMode::Required,
|
||||||
.help_string = "Add a header search path passed to the compiler",
|
.help_string = "Add a header search path passed to the compiler",
|
||||||
|
@ -148,6 +154,12 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
||||||
if (iterator_prototype_implementation_mode)
|
if (iterator_prototype_implementation_mode)
|
||||||
IDL::generate_iterator_prototype_implementation(interface, output_builder);
|
IDL::generate_iterator_prototype_implementation(interface, output_builder);
|
||||||
|
|
||||||
|
if (global_mixin_header_mode)
|
||||||
|
IDL::generate_global_mixin_header(interface, output_builder);
|
||||||
|
|
||||||
|
if (global_mixin_implementation_mode)
|
||||||
|
IDL::generate_global_mixin_implementation(interface, output_builder);
|
||||||
|
|
||||||
TRY(output_file->write(output_builder.string_view().bytes()));
|
TRY(output_file->write(output_builder.string_view().bytes()));
|
||||||
|
|
||||||
if (!depfile_path.is_null()) {
|
if (!depfile_path.is_null()) {
|
||||||
|
|
|
@ -595,6 +595,7 @@ void Parser::parse_interface(Interface& interface)
|
||||||
interface.constructor_class = DeprecatedString::formatted("{}Constructor", interface.name);
|
interface.constructor_class = DeprecatedString::formatted("{}Constructor", interface.name);
|
||||||
interface.prototype_class = DeprecatedString::formatted("{}Prototype", 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);
|
interface.prototype_base_class = DeprecatedString::formatted("{}Prototype", interface.parent_name.is_empty() ? "Object" : interface.parent_name);
|
||||||
|
interface.global_mixin_class = DeprecatedString::formatted("{}GlobalMixin", interface.name);
|
||||||
consume_whitespace();
|
consume_whitespace();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -291,6 +291,7 @@ public:
|
||||||
DeprecatedString constructor_class;
|
DeprecatedString constructor_class;
|
||||||
DeprecatedString prototype_class;
|
DeprecatedString prototype_class;
|
||||||
DeprecatedString prototype_base_class;
|
DeprecatedString prototype_base_class;
|
||||||
|
DeprecatedString global_mixin_class;
|
||||||
HashMap<DeprecatedString, HashTable<DeprecatedString>> included_mixins;
|
HashMap<DeprecatedString, HashTable<DeprecatedString>> included_mixins;
|
||||||
|
|
||||||
DeprecatedString module_own_path;
|
DeprecatedString module_own_path;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue