mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-04-20 19:45:12 +00:00
WrapperGenerator: Add support for IDL mixin interfaces
This commit is contained in:
parent
e9c76d339b
commit
c38163494a
Notes:
sideshowbarker
2024-07-17 23:02:37 +09:00
Author: https://github.com/alimpfard Commit: https://github.com/SerenityOS/serenity/commit/c38163494a Pull-request: https://github.com/SerenityOS/serenity/pull/12590
3 changed files with 68 additions and 1 deletions
|
@ -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;
|
||||
|
|
|
@ -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&);
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue