diff --git a/Meta/Lagom/Tools/CodeGenerators/LibWeb/WrapperGenerator/IDLParser.cpp b/Meta/Lagom/Tools/CodeGenerators/LibWeb/WrapperGenerator/IDLParser.cpp index e2356d3bf7..9fff31645a 100644 --- a/Meta/Lagom/Tools/CodeGenerators/LibWeb/WrapperGenerator/IDLParser.cpp +++ b/Meta/Lagom/Tools/CodeGenerators/LibWeb/WrapperGenerator/IDLParser.cpp @@ -612,6 +612,25 @@ void Parser::parse_enumeration(Interface& interface) consume_whitespace(); } +void Parser::parse_typedef(Interface& interface) +{ + assert_string("typedef"); + consume_whitespace(); + + HashMap extended_attributes; + if (lexer.consume_specific('[')) + extended_attributes = parse_extended_attributes(); + + auto type = parse_type(); + consume_whitespace(); + + auto name = lexer.consume_until(';'); + assert_specific(';'); + + interface.typedefs.set(name, Typedef { move(extended_attributes), move(type) }); + consume_whitespace(); +} + void Parser::parse_dictionary(Interface& interface) { assert_string("dictionary"); @@ -710,6 +729,8 @@ void Parser::parse_non_interface_entities(bool allow_interface, Interface& inter parse_dictionary(interface); } else if (lexer.next_is("enum")) { parse_enumeration(interface); + } else if (lexer.next_is("typedef")) { + parse_typedef(interface); } else if (lexer.next_is("interface mixin")) { parse_interface_mixin(interface); } else if ((allow_interface && !lexer.next_is("interface")) || !allow_interface) { @@ -732,6 +753,37 @@ void Parser::parse_non_interface_entities(bool allow_interface, Interface& inter } } +void resolve_typedef(Interface& interface, NonnullRefPtr& type, HashMap* extended_attributes = {}) +{ + if (is(*type)) { + auto parameterized_type = static_ptr_cast(type); + auto& parameters = static_cast>&>(parameterized_type->parameters); + for (auto& parameter : parameters) + resolve_typedef(interface, parameter); + return; + } + + auto it = interface.typedefs.find(type->name); + if (it == interface.typedefs.end()) + return; + type = it->value.type; + if (!extended_attributes) + return; + for (auto& attribute : it->value.extended_attributes) + extended_attributes->set(attribute.key, attribute.value); +} +void resolve_parameters_typedefs(Interface& interface, Vector& parameters) +{ + for (auto& parameter : parameters) + resolve_typedef(interface, parameter.type, ¶meter.extended_attributes); +} +template +void resolve_function_typedefs(Interface& interface, FunctionType& function) +{ + resolve_typedef(interface, function.return_type); + resolve_parameters_typedefs(interface, function.parameters); +} + NonnullOwnPtr Parser::parse() { auto this_module = Core::File::real_path_for(filename); @@ -780,6 +832,9 @@ NonnullOwnPtr Parser::parse() interface->enumerations.set(enumeration.key, move(enumeration_copy)); } + for (auto& typedef_ : import.typedefs) + interface->typedefs.set(typedef_.key, move(typedef_.value)); + for (auto& mixin : import.mixins) { if (interface->mixins.contains(mixin.key)) report_parsing_error(String::formatted("Mixin '{}' was already defined in {}", mixin.key, mixin.value->module_own_path), filename, input, lexer.tell()); @@ -809,6 +864,42 @@ NonnullOwnPtr Parser::parse() } } + // 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>()); + } + 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); + } + 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); diff --git a/Meta/Lagom/Tools/CodeGenerators/LibWeb/WrapperGenerator/IDLParser.h b/Meta/Lagom/Tools/CodeGenerators/LibWeb/WrapperGenerator/IDLParser.h index 3f340dac85..4ce432772c 100644 --- a/Meta/Lagom/Tools/CodeGenerators/LibWeb/WrapperGenerator/IDLParser.h +++ b/Meta/Lagom/Tools/CodeGenerators/LibWeb/WrapperGenerator/IDLParser.h @@ -38,6 +38,7 @@ private: void parse_interface(Interface&); void parse_non_interface_entities(bool allow_interface, Interface&); void parse_enumeration(Interface&); + void parse_typedef(Interface&); void parse_interface_mixin(Interface&); void parse_dictionary(Interface&); void parse_constructor(Interface&); diff --git a/Meta/Lagom/Tools/CodeGenerators/LibWeb/WrapperGenerator/IDLTypes.h b/Meta/Lagom/Tools/CodeGenerators/LibWeb/WrapperGenerator/IDLTypes.h index 0c9e9044bf..39faff027f 100644 --- a/Meta/Lagom/Tools/CodeGenerators/LibWeb/WrapperGenerator/IDLTypes.h +++ b/Meta/Lagom/Tools/CodeGenerators/LibWeb/WrapperGenerator/IDLTypes.h @@ -121,6 +121,11 @@ struct Dictionary { Vector members; }; +struct Typedef { + HashMap extended_attributes; + NonnullRefPtr type; +}; + struct Enumeration { HashTable values; HashMap translated_cpp_names; @@ -184,6 +189,7 @@ struct Interface { HashMap dictionaries; HashMap enumerations; + HashMap typedefs; HashMap> mixins; // Added for convenience after parsing