WrapperGenerator: Add support for IDL mixin interfaces

This commit is contained in:
Ali Mohammad Pur 2022-02-17 03:15:57 +03:30 committed by Andreas Kling
parent e9c76d339b
commit c38163494a
Notes: sideshowbarker 2024-07-17 23:02:37 +09:00
3 changed files with 68 additions and 1 deletions

View file

@ -681,6 +681,25 @@ void Parser::parse_dictionary(Interface& interface)
consume_whitespace();
}
void Parser::parse_interface_mixin(Interface& interface)
{
auto mixin_interface = make<Interface>();
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())
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));
}
void Parser::parse_non_interface_entities(bool allow_interface, Interface& interface)
{
while (!lexer.is_eof()) {
@ -688,8 +707,22 @@ 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("interface mixin")) {
parse_interface_mixin(interface);
} else if ((allow_interface && !lexer.next_is("interface")) || !allow_interface) {
report_parsing_error("expected 'enum' or 'dictionary'", filename, input, lexer.tell());
auto current_offset = lexer.tell();
auto name = lexer.consume_until([](auto ch) { return is_ascii_space(ch); });
consume_whitespace();
if (lexer.consume_specific("includes")) {
consume_whitespace();
auto mixin_name = lexer.consume_until([](auto ch) { return is_ascii_space(ch) || ch == ';'; });
interface.included_mixins.ensure(name).set(mixin_name);
consume_whitespace();
assert_specific(';');
consume_whitespace();
} else {
report_parsing_error("expected 'enum' or 'dictionary'", filename, input, current_offset);
}
} else {
break;
}
@ -740,7 +773,36 @@ NonnullOwnPtr<Interface> Parser::parse()
enumeration_copy.is_original_definition = false;
interface->enumerations.set(enumeration.key, move(enumeration_copy));
}
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());
interface->mixins.set(mixin.key, move(mixin.value));
}
}
// Resolve mixins
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())
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());
if (mixin->has_stringifier) {
interface->stringifier_attribute = mixin->stringifier_attribute;
interface->has_stringifier = true;
}
}
}
interface->imported_modules = move(imports);
return interface;

View file

@ -38,6 +38,7 @@ private:
void parse_interface(Interface&);
void parse_non_interface_entities(bool allow_interface, Interface&);
void parse_enumeration(Interface&);
void parse_interface_mixin(Interface&);
void parse_dictionary(Interface&);
void parse_constructor(Interface&);
void parse_getter(HashMap<String, String>& extended_attributes, Interface&);

View file

@ -271,6 +271,8 @@ struct Interface {
String name;
String parent_name;
bool is_mixin { false };
HashMap<String, String> extended_attributes;
Vector<Attribute> attributes;
@ -295,6 +297,7 @@ struct Interface {
HashMap<String, Dictionary> dictionaries;
HashMap<String, Enumeration> enumerations;
HashMap<String, NonnullOwnPtr<Interface>> mixins;
// Added for convenience after parsing
String wrapper_class;
@ -303,6 +306,7 @@ struct Interface {
String constructor_class;
String prototype_class;
String prototype_base_class;
HashMap<String, HashTable<String>> included_mixins;
String module_own_path;
HashTable<String> imported_paths;