diff --git a/Libraries/LibIDL/IDLParser.cpp b/Libraries/LibIDL/IDLParser.cpp index 4f76b867896..3d6ddb087d8 100644 --- a/Libraries/LibIDL/IDLParser.cpp +++ b/Libraries/LibIDL/IDLParser.cpp @@ -813,6 +813,17 @@ void Parser::parse_interface(Interface& interface) consume_whitespace(); } +void Parser::parse_partial_interface(Interface& parent) +{ + assert_string("partial"sv); + consume_whitespace(); + assert_string("interface"sv); + + auto partial_interface = make(); + parse_interface(*partial_interface); + parent.partial_interfaces.append(move(partial_interface)); +} + void Parser::parse_namespace(Interface& interface) { consume_whitespace(); @@ -1051,6 +1062,8 @@ void Parser::parse_non_interface_entities(bool allow_interface, Interface& inter parse_enumeration(extended_attributes, interface); } else if (lexer.next_is("typedef")) { parse_typedef(interface); + } else if (lexer.next_is("partial interface"sv)) { + parse_partial_interface(interface); } else if (lexer.next_is("interface mixin")) { parse_interface_mixin(interface); } else if (lexer.next_is("callback")) { @@ -1183,6 +1196,11 @@ Interface& Parser::parse() for (auto& import : imports) { // FIXME: Instead of copying every imported entity into the current interface, query imports directly + for (auto& partial_interface : import.partial_interfaces) { + if (partial_interface->name == interface.name) + interface.extend_with_partial_interface(*partial_interface); + } + for (auto& dictionary : import.dictionaries) interface.dictionaries.set(dictionary.key, dictionary.value); diff --git a/Libraries/LibIDL/IDLParser.h b/Libraries/LibIDL/IDLParser.h index 9537162726b..3b2a6e818e7 100644 --- a/Libraries/LibIDL/IDLParser.h +++ b/Libraries/LibIDL/IDLParser.h @@ -45,6 +45,7 @@ private: HashMap parse_extended_attributes(); void parse_attribute(HashMap& extended_attributes, Interface&, IsStatic is_static = IsStatic::No); void parse_interface(Interface&); + void parse_partial_interface(Interface& parent); void parse_namespace(Interface&); void parse_non_interface_entities(bool allow_interface, Interface&); void parse_enumeration(HashMap, Interface&); diff --git a/Libraries/LibIDL/Types.cpp b/Libraries/LibIDL/Types.cpp index c9c58b0e3c1..aaaf21e86de 100644 --- a/Libraries/LibIDL/Types.cpp +++ b/Libraries/LibIDL/Types.cpp @@ -305,4 +305,13 @@ void EffectiveOverloadSet::remove_all_other_entries() m_items = move(new_items); } +void Interface::extend_with_partial_interface(Interface const& partial) +{ + attributes.extend(partial.attributes); + static_attributes.extend(partial.static_attributes); + constants.extend(partial.constants); + functions.extend(partial.functions); + static_functions.extend(partial.static_functions); +} + } diff --git a/Libraries/LibIDL/Types.h b/Libraries/LibIDL/Types.h index 8249219cad6..b53a27122d4 100644 --- a/Libraries/LibIDL/Types.h +++ b/Libraries/LibIDL/Types.h @@ -318,6 +318,7 @@ public: HashMap> included_mixins; ByteString module_own_path; + Vector> partial_interfaces; Vector imported_modules; HashMap> overload_sets; @@ -337,6 +338,8 @@ public: { return !name.is_empty() || any_of(enumerations, [](auto& entry) { return entry.value.is_original_definition; }); } + + void extend_with_partial_interface(Interface const&); }; class UnionType : public Type {