summaryrefslogtreecommitdiff
path: root/Meta/Lagom
diff options
context:
space:
mode:
Diffstat (limited to 'Meta/Lagom')
-rw-r--r--Meta/Lagom/Tools/CodeGenerators/LibWeb/WrapperGenerator/IDLParser.cpp164
-rw-r--r--Meta/Lagom/Tools/CodeGenerators/LibWeb/WrapperGenerator/IDLParser.h9
-rw-r--r--Meta/Lagom/Tools/CodeGenerators/LibWeb/WrapperGenerator/IDLTypes.h14
-rw-r--r--Meta/Lagom/Tools/CodeGenerators/LibWeb/WrapperGenerator/main.cpp34
4 files changed, 117 insertions, 104 deletions
diff --git a/Meta/Lagom/Tools/CodeGenerators/LibWeb/WrapperGenerator/IDLParser.cpp b/Meta/Lagom/Tools/CodeGenerators/LibWeb/WrapperGenerator/IDLParser.cpp
index f009e16c6f..8171319598 100644
--- a/Meta/Lagom/Tools/CodeGenerators/LibWeb/WrapperGenerator/IDLParser.cpp
+++ b/Meta/Lagom/Tools/CodeGenerators/LibWeb/WrapperGenerator/IDLParser.cpp
@@ -76,7 +76,8 @@ static String convert_enumeration_value_to_cpp_enum_member(String const& value,
namespace IDL {
-HashMap<String, NonnullRefPtr<Interface>> Parser::s_resolved_imports {};
+HashTable<NonnullOwnPtr<Interface>> Parser::s_interfaces {};
+HashMap<String, Interface*> Parser::s_resolved_imports {};
void Parser::assert_specific(char ch)
{
@@ -125,7 +126,7 @@ HashMap<String, String> Parser::parse_extended_attributes()
}
static HashTable<String> import_stack;
-Optional<NonnullRefPtr<Interface>> Parser::resolve_import(auto path)
+Optional<Interface&> Parser::resolve_import(auto path)
{
auto include_path = LexicalPath::join(import_base_path, path).string();
if (!Core::File::exists(include_path))
@@ -133,7 +134,7 @@ Optional<NonnullRefPtr<Interface>> Parser::resolve_import(auto path)
auto real_path = Core::File::real_path_for(include_path);
if (s_resolved_imports.contains(real_path))
- return s_resolved_imports.find(real_path)->value;
+ return *s_resolved_imports.find(real_path)->value;
if (import_stack.contains(real_path))
report_parsing_error(String::formatted("Circular import detected: {}", include_path), filename, input, lexer.tell());
@@ -144,10 +145,10 @@ Optional<NonnullRefPtr<Interface>> Parser::resolve_import(auto path)
report_parsing_error(String::formatted("Failed to open {}: {}", real_path, file_or_error.error()), filename, input, lexer.tell());
auto data = file_or_error.value()->read_all();
- auto result = Parser(real_path, data, import_base_path).parse();
+ auto& result = Parser(real_path, data, import_base_path).parse();
import_stack.remove(real_path);
- s_resolved_imports.set(real_path, result);
+ s_resolved_imports.set(real_path, &result);
return result;
}
@@ -709,21 +710,23 @@ void Parser::parse_dictionary(Interface& interface)
void Parser::parse_interface_mixin(Interface& interface)
{
- auto mixin_interface = make_ref_counted<Interface>();
- mixin_interface->module_own_path = interface.module_own_path;
- mixin_interface->is_mixin = true;
+ auto mixin_interface_ptr = make<Interface>();
+ auto& mixin_interface = *mixin_interface_ptr;
+ VERIFY(s_interfaces.set(move(mixin_interface_ptr)) == AK::HashSetResult::InsertedNewEntry);
+ mixin_interface.module_own_path = interface.module_own_path;
+ mixin_interface.is_mixin = true;
assert_string("interface");
consume_whitespace();
assert_string("mixin");
auto offset = lexer.tell();
- parse_interface(*mixin_interface);
- if (!mixin_interface->parent_name.is_empty())
+ parse_interface(mixin_interface);
+ if (!mixin_interface.parent_name.is_empty())
report_parsing_error("Mixin interfaces are not allowed to have inherited parents", filename, input, offset);
- auto name = mixin_interface->name;
- interface.mixins.set(move(name), move(mixin_interface));
+ auto name = mixin_interface.name;
+ interface.mixins.set(move(name), &mixin_interface);
}
void Parser::parse_callback_function(HashMap<String, String>& extended_attributes, Interface& interface)
@@ -817,15 +820,18 @@ void resolve_function_typedefs(Interface& interface, FunctionType& function)
resolve_parameters_typedefs(interface, function.parameters);
}
-NonnullRefPtr<Interface> Parser::parse()
+Interface& Parser::parse()
{
auto this_module = Core::File::real_path_for(filename);
- auto interface = make_ref_counted<Interface>();
- interface->module_own_path = this_module;
- s_resolved_imports.set(this_module, interface);
+ auto interface_ptr = make<Interface>();
+ auto& interface = *interface_ptr;
+ VERIFY(s_interfaces.set(move(interface_ptr)) == AK::HashSetResult::InsertedNewEntry);
+ interface.module_own_path = this_module;
+ s_resolved_imports.set(this_module, &interface);
- NonnullRefPtrVector<Interface> imports;
+ Vector<Interface&> imports;
+ HashTable<String> required_imported_paths;
while (lexer.consume_specific("#import")) {
consume_whitespace();
assert_specific('<');
@@ -833,121 +839,121 @@ NonnullRefPtr<Interface> Parser::parse()
lexer.ignore();
auto maybe_interface = resolve_import(path);
if (maybe_interface.has_value()) {
- for (auto& entry : maybe_interface.value()->required_imported_paths)
+ for (auto& entry : maybe_interface.value().required_imported_paths)
required_imported_paths.set(entry);
imports.append(maybe_interface.release_value());
}
consume_whitespace();
}
- interface->required_imported_paths = required_imported_paths;
+ interface.required_imported_paths = required_imported_paths;
- parse_non_interface_entities(true, *interface);
+ parse_non_interface_entities(true, interface);
if (lexer.consume_specific("interface"))
- parse_interface(*interface);
+ parse_interface(interface);
- parse_non_interface_entities(false, *interface);
+ parse_non_interface_entities(false, interface);
for (auto& import : imports) {
// FIXME: Instead of copying every imported entity into the current interface, query imports directly
for (auto& dictionary : import.dictionaries)
- interface->dictionaries.set(dictionary.key, dictionary.value);
+ interface.dictionaries.set(dictionary.key, dictionary.value);
for (auto& enumeration : import.enumerations) {
auto enumeration_copy = enumeration.value;
enumeration_copy.is_original_definition = false;
- interface->enumerations.set(enumeration.key, move(enumeration_copy));
+ interface.enumerations.set(enumeration.key, move(enumeration_copy));
}
for (auto& typedef_ : import.typedefs)
- interface->typedefs.set(typedef_.key, typedef_.value);
+ interface.typedefs.set(typedef_.key, typedef_.value);
for (auto& mixin : import.mixins) {
- if (auto it = interface->mixins.find(mixin.key); it != interface->mixins.end() && it->value.ptr() != mixin.value.ptr())
+ if (auto it = interface.mixins.find(mixin.key); it != interface.mixins.end() && it->value != mixin.value)
report_parsing_error(String::formatted("Mixin '{}' was already defined in {}", mixin.key, mixin.value->module_own_path), filename, input, lexer.tell());
- interface->mixins.set(mixin.key, mixin.value);
+ interface.mixins.set(mixin.key, mixin.value);
}
for (auto& callback_function : import.callback_functions)
- interface->callback_functions.set(callback_function.key, callback_function.value);
+ interface.callback_functions.set(callback_function.key, callback_function.value);
}
// Resolve mixins
- if (auto it = interface->included_mixins.find(interface->name); it != interface->included_mixins.end()) {
+ if (auto it = interface.included_mixins.find(interface.name); it != interface.included_mixins.end()) {
for (auto& entry : it->value) {
- auto mixin_it = interface->mixins.find(entry);
- if (mixin_it == interface->mixins.end())
+ auto mixin_it = interface.mixins.find(entry);
+ if (mixin_it == interface.mixins.end())
report_parsing_error(String::formatted("Mixin '{}' was never defined", entry), filename, input, lexer.tell());
auto& mixin = mixin_it->value;
- interface->attributes.extend(mixin->attributes);
- interface->constants.extend(mixin->constants);
- interface->functions.extend(mixin->functions);
- interface->static_functions.extend(mixin->static_functions);
- if (interface->has_stringifier && mixin->has_stringifier)
- report_parsing_error(String::formatted("Both interface '{}' and mixin '{}' have defined stringifier attributes", interface->name, mixin->name), filename, input, lexer.tell());
+ interface.attributes.extend(mixin->attributes);
+ interface.constants.extend(mixin->constants);
+ interface.functions.extend(mixin->functions);
+ interface.static_functions.extend(mixin->static_functions);
+ if (interface.has_stringifier && mixin->has_stringifier)
+ report_parsing_error(String::formatted("Both interface '{}' and mixin '{}' have defined stringifier attributes", interface.name, mixin->name), filename, input, lexer.tell());
if (mixin->has_stringifier) {
- interface->stringifier_attribute = mixin->stringifier_attribute;
- interface->has_stringifier = true;
+ interface.stringifier_attribute = mixin->stringifier_attribute;
+ interface.has_stringifier = true;
}
}
}
// Resolve typedefs
- for (auto& attribute : interface->attributes)
- resolve_typedef(*interface, attribute.type, &attribute.extended_attributes);
- for (auto& constant : interface->constants)
- resolve_typedef(*interface, constant.type);
- for (auto& constructor : interface->constructors)
- resolve_parameters_typedefs(*interface, constructor.parameters);
- for (auto& function : interface->functions)
- resolve_function_typedefs(*interface, function);
- for (auto& static_function : interface->static_functions)
- resolve_function_typedefs(*interface, static_function);
- if (interface->value_iterator_type.has_value())
- resolve_typedef(*interface, *interface->value_iterator_type);
- if (interface->pair_iterator_types.has_value()) {
- resolve_typedef(*interface, interface->pair_iterator_types->get<0>());
- resolve_typedef(*interface, interface->pair_iterator_types->get<1>());
+ for (auto& attribute : interface.attributes)
+ resolve_typedef(interface, attribute.type, &attribute.extended_attributes);
+ for (auto& constant : interface.constants)
+ resolve_typedef(interface, constant.type);
+ for (auto& constructor : interface.constructors)
+ resolve_parameters_typedefs(interface, constructor.parameters);
+ for (auto& function : interface.functions)
+ resolve_function_typedefs(interface, function);
+ for (auto& static_function : interface.static_functions)
+ resolve_function_typedefs(interface, static_function);
+ if (interface.value_iterator_type.has_value())
+ resolve_typedef(interface, *interface.value_iterator_type);
+ if (interface.pair_iterator_types.has_value()) {
+ resolve_typedef(interface, interface.pair_iterator_types->get<0>());
+ resolve_typedef(interface, interface.pair_iterator_types->get<1>());
}
- if (interface->named_property_getter.has_value())
- resolve_function_typedefs(*interface, *interface->named_property_getter);
- if (interface->named_property_setter.has_value())
- resolve_function_typedefs(*interface, *interface->named_property_setter);
- if (interface->indexed_property_getter.has_value())
- resolve_function_typedefs(*interface, *interface->indexed_property_getter);
- if (interface->indexed_property_setter.has_value())
- resolve_function_typedefs(*interface, *interface->indexed_property_setter);
- if (interface->named_property_deleter.has_value())
- resolve_function_typedefs(*interface, *interface->named_property_deleter);
- if (interface->named_property_getter.has_value())
- resolve_function_typedefs(*interface, *interface->named_property_getter);
- for (auto& dictionary : interface->dictionaries) {
+ if (interface.named_property_getter.has_value())
+ resolve_function_typedefs(interface, *interface.named_property_getter);
+ if (interface.named_property_setter.has_value())
+ resolve_function_typedefs(interface, *interface.named_property_setter);
+ if (interface.indexed_property_getter.has_value())
+ resolve_function_typedefs(interface, *interface.indexed_property_getter);
+ if (interface.indexed_property_setter.has_value())
+ resolve_function_typedefs(interface, *interface.indexed_property_setter);
+ if (interface.named_property_deleter.has_value())
+ resolve_function_typedefs(interface, *interface.named_property_deleter);
+ if (interface.named_property_getter.has_value())
+ resolve_function_typedefs(interface, *interface.named_property_getter);
+ for (auto& dictionary : interface.dictionaries) {
for (auto& dictionary_member : dictionary.value.members)
- resolve_typedef(*interface, dictionary_member.type, &dictionary_member.extended_attributes);
+ resolve_typedef(interface, dictionary_member.type, &dictionary_member.extended_attributes);
}
- for (auto& callback_function : interface->callback_functions)
- resolve_function_typedefs(*interface, callback_function.value);
+ for (auto& callback_function : interface.callback_functions)
+ resolve_function_typedefs(interface, callback_function.value);
// Create overload sets
- for (auto& function : interface->functions) {
- auto& overload_set = interface->overload_sets.ensure(function.name);
+ for (auto& function : interface.functions) {
+ auto& overload_set = interface.overload_sets.ensure(function.name);
function.overload_index = overload_set.size();
overload_set.append(function);
}
- for (auto& overload_set : interface->overload_sets) {
+ for (auto& overload_set : interface.overload_sets) {
if (overload_set.value.size() == 1)
continue;
for (auto& overloaded_function : overload_set.value)
overloaded_function.is_overloaded = true;
}
- for (auto& function : interface->static_functions) {
- auto& overload_set = interface->static_overload_sets.ensure(function.name);
+ for (auto& function : interface.static_functions) {
+ auto& overload_set = interface.static_overload_sets.ensure(function.name);
function.overload_index = overload_set.size();
overload_set.append(function);
}
- for (auto& overload_set : interface->static_overload_sets) {
+ for (auto& overload_set : interface.static_overload_sets) {
if (overload_set.value.size() == 1)
continue;
for (auto& overloaded_function : overload_set.value)
@@ -955,9 +961,9 @@ NonnullRefPtr<Interface> Parser::parse()
}
// FIXME: Add support for overloading constructors
- if (interface->will_generate_code())
- interface->required_imported_paths.set(this_module);
- interface->imported_modules = move(imports);
+ if (interface.will_generate_code())
+ interface.required_imported_paths.set(this_module);
+ interface.imported_modules = move(imports);
return interface;
}
diff --git a/Meta/Lagom/Tools/CodeGenerators/LibWeb/WrapperGenerator/IDLParser.h b/Meta/Lagom/Tools/CodeGenerators/LibWeb/WrapperGenerator/IDLParser.h
index de0cd00aaf..a735537f82 100644
--- a/Meta/Lagom/Tools/CodeGenerators/LibWeb/WrapperGenerator/IDLParser.h
+++ b/Meta/Lagom/Tools/CodeGenerators/LibWeb/WrapperGenerator/IDLParser.h
@@ -18,7 +18,7 @@ namespace IDL {
class Parser {
public:
Parser(String filename, StringView contents, String import_base_path);
- NonnullRefPtr<Interface> parse();
+ Interface& parse();
private:
// https://webidl.spec.whatwg.org/#dfn-special-operation
@@ -31,7 +31,7 @@ private:
void assert_specific(char ch);
void assert_string(StringView expected);
void consume_whitespace();
- Optional<NonnullRefPtr<Interface>> resolve_import(auto path);
+ Optional<Interface&> resolve_import(auto path);
HashMap<String, String> parse_extended_attributes();
void parse_attribute(HashMap<String, String>& extended_attributes, Interface&);
@@ -53,8 +53,9 @@ private:
NonnullRefPtr<Type> parse_type();
void parse_constant(Interface&);
- static HashMap<String, NonnullRefPtr<Interface>> s_resolved_imports;
- HashTable<String> required_imported_paths;
+ static HashTable<NonnullOwnPtr<Interface>> s_interfaces;
+ static HashMap<String, Interface*> s_resolved_imports;
+
String import_base_path;
String filename;
StringView input;
diff --git a/Meta/Lagom/Tools/CodeGenerators/LibWeb/WrapperGenerator/IDLTypes.h b/Meta/Lagom/Tools/CodeGenerators/LibWeb/WrapperGenerator/IDLTypes.h
index 6874d0190c..88de8e3374 100644
--- a/Meta/Lagom/Tools/CodeGenerators/LibWeb/WrapperGenerator/IDLTypes.h
+++ b/Meta/Lagom/Tools/CodeGenerators/LibWeb/WrapperGenerator/IDLTypes.h
@@ -141,7 +141,7 @@ struct CallbackFunction {
bool is_legacy_treat_non_object_as_null { false };
};
-struct Interface;
+class Interface;
struct ParameterizedType : public Type {
ParameterizedType() = default;
@@ -167,7 +167,13 @@ static inline size_t get_shortest_function_length(Vector<Function&> const& overl
return longest_length;
}
-struct Interface : public RefCounted<Interface> {
+class Interface {
+ AK_MAKE_NONCOPYABLE(Interface);
+ AK_MAKE_NONMOVABLE(Interface);
+
+public:
+ explicit Interface() = default;
+
String name;
String parent_name;
@@ -198,7 +204,7 @@ struct Interface : public RefCounted<Interface> {
HashMap<String, Dictionary> dictionaries;
HashMap<String, Enumeration> enumerations;
HashMap<String, Typedef> typedefs;
- HashMap<String, NonnullRefPtr<Interface>> mixins;
+ HashMap<String, Interface*> mixins;
HashMap<String, CallbackFunction> callback_functions;
// Added for convenience after parsing
@@ -212,7 +218,7 @@ struct Interface : public RefCounted<Interface> {
String module_own_path;
HashTable<String> required_imported_paths;
- NonnullRefPtrVector<Interface> imported_modules;
+ Vector<Interface&> imported_modules;
HashMap<String, Vector<Function&>> overload_sets;
HashMap<String, Vector<Function&>> static_overload_sets;
diff --git a/Meta/Lagom/Tools/CodeGenerators/LibWeb/WrapperGenerator/main.cpp b/Meta/Lagom/Tools/CodeGenerators/LibWeb/WrapperGenerator/main.cpp
index 5bec84bedf..8f501a9709 100644
--- a/Meta/Lagom/Tools/CodeGenerators/LibWeb/WrapperGenerator/main.cpp
+++ b/Meta/Lagom/Tools/CodeGenerators/LibWeb/WrapperGenerator/main.cpp
@@ -83,21 +83,21 @@ int main(int argc, char** argv)
if (import_base_path.is_null())
import_base_path = lexical_path.dirname();
- auto interface = IDL::Parser(path, data, import_base_path).parse();
+ auto& interface = IDL::Parser(path, data, import_base_path).parse();
if (namespace_.is_one_of("Crypto", "CSS", "DOM", "Encoding", "HTML", "UIEvents", "Geometry", "HighResolutionTime", "IntersectionObserver", "NavigationTiming", "RequestIdleCallback", "ResizeObserver", "SVG", "Selection", "URL", "WebSockets", "XHR")) {
StringBuilder builder;
builder.append(namespace_);
builder.append("::");
- builder.append(interface->name);
- interface->fully_qualified_name = builder.to_string();
+ builder.append(interface.name);
+ interface.fully_qualified_name = builder.to_string();
} else {
- interface->fully_qualified_name = interface->name;
+ interface.fully_qualified_name = interface.name;
}
if constexpr (WRAPPER_GENERATOR_DEBUG) {
dbgln("Attributes:");
- for (auto& attribute : interface->attributes) {
+ for (auto& attribute : interface.attributes) {
dbgln(" {}{}{} {}",
attribute.readonly ? "readonly " : "",
attribute.type->name,
@@ -106,7 +106,7 @@ int main(int argc, char** argv)
}
dbgln("Functions:");
- for (auto& function : interface->functions) {
+ for (auto& function : interface.functions) {
dbgln(" {}{} {}",
function.return_type->name,
function.return_type->nullable ? "?" : "",
@@ -120,7 +120,7 @@ int main(int argc, char** argv)
}
dbgln("Static Functions:");
- for (auto& function : interface->static_functions) {
+ for (auto& function : interface.static_functions) {
dbgln(" static {}{} {}",
function.return_type->name,
function.return_type->nullable ? "?" : "",
@@ -135,34 +135,34 @@ int main(int argc, char** argv)
}
if (header_mode)
- IDL::generate_header(*interface);
+ IDL::generate_header(interface);
if (implementation_mode)
- IDL::generate_implementation(*interface);
+ IDL::generate_implementation(interface);
if (constructor_header_mode)
- IDL::generate_constructor_header(*interface);
+ IDL::generate_constructor_header(interface);
if (constructor_implementation_mode)
- IDL::generate_constructor_implementation(*interface);
+ IDL::generate_constructor_implementation(interface);
if (prototype_header_mode)
- IDL::generate_prototype_header(*interface);
+ IDL::generate_prototype_header(interface);
if (prototype_implementation_mode)
- IDL::generate_prototype_implementation(*interface);
+ IDL::generate_prototype_implementation(interface);
if (iterator_header_mode)
- IDL::generate_iterator_header(*interface);
+ IDL::generate_iterator_header(interface);
if (iterator_implementation_mode)
- IDL::generate_iterator_implementation(*interface);
+ IDL::generate_iterator_implementation(interface);
if (iterator_prototype_header_mode)
- IDL::generate_iterator_prototype_header(*interface);
+ IDL::generate_iterator_prototype_header(interface);
if (iterator_prototype_implementation_mode)
- IDL::generate_iterator_prototype_implementation(*interface);
+ IDL::generate_iterator_prototype_implementation(interface);
return 0;
}