mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-06-09 09:34:57 +09:00
LibIDL+IDLGenerators: Support generation of IDL partial dictionaries
This commit is contained in:
parent
8cf16da6c2
commit
348db1c445
Notes:
github-actions[bot]
2025-02-05 20:20:03 +00:00
Author: https://github.com/devgianlu
Commit: 348db1c445
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/3117
Reviewed-by: https://github.com/ADKaster ✅
3 changed files with 42 additions and 5 deletions
|
@ -829,6 +829,13 @@ void Parser::parse_typedef(Interface& interface)
|
|||
|
||||
void Parser::parse_dictionary(Interface& interface)
|
||||
{
|
||||
bool partial = false;
|
||||
if (lexer.next_is("partial")) {
|
||||
assert_string("partial"sv);
|
||||
consume_whitespace();
|
||||
partial = true;
|
||||
}
|
||||
|
||||
assert_string("dictionary"sv);
|
||||
consume_whitespace();
|
||||
|
||||
|
@ -896,7 +903,13 @@ void Parser::parse_dictionary(Interface& interface)
|
|||
return one.name < two.name;
|
||||
});
|
||||
|
||||
interface.dictionaries.set(name, move(dictionary));
|
||||
if (partial) {
|
||||
auto& it = interface.partial_dictionaries.ensure(name);
|
||||
it.append(move(dictionary));
|
||||
} else {
|
||||
interface.dictionaries.set(name, move(dictionary));
|
||||
}
|
||||
|
||||
consume_whitespace();
|
||||
}
|
||||
|
||||
|
@ -952,7 +965,7 @@ void Parser::parse_non_interface_entities(bool allow_interface, Interface& inter
|
|||
HashMap<ByteString, ByteString> extended_attributes;
|
||||
if (lexer.consume_specific('['))
|
||||
extended_attributes = parse_extended_attributes();
|
||||
if (lexer.next_is("dictionary")) {
|
||||
if (lexer.next_is("dictionary") || lexer.next_is("partial dictionary")) {
|
||||
parse_dictionary(interface);
|
||||
} else if (lexer.next_is("enum")) {
|
||||
parse_enumeration(extended_attributes, interface);
|
||||
|
@ -1093,6 +1106,11 @@ Interface& Parser::parse()
|
|||
for (auto& dictionary : import.dictionaries)
|
||||
interface.dictionaries.set(dictionary.key, dictionary.value);
|
||||
|
||||
for (auto& partial_dictionary : import.partial_dictionaries) {
|
||||
auto& it = interface.partial_dictionaries.ensure(partial_dictionary.key);
|
||||
it.extend(partial_dictionary.value);
|
||||
}
|
||||
|
||||
for (auto& enumeration : import.enumerations) {
|
||||
auto enumeration_copy = enumeration.value;
|
||||
enumeration_copy.is_original_definition = false;
|
||||
|
@ -1172,6 +1190,11 @@ Interface& Parser::parse()
|
|||
for (auto& dictionary_member : dictionary.value.members)
|
||||
resolve_typedef(interface, dictionary_member.type, &dictionary_member.extended_attributes);
|
||||
}
|
||||
for (auto& dictionaries : interface.partial_dictionaries) {
|
||||
for (auto& dictionary : dictionaries.value)
|
||||
for (auto& dictionary_member : dictionary.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);
|
||||
|
||||
|
|
|
@ -297,6 +297,7 @@ public:
|
|||
Optional<Function> named_property_deleter;
|
||||
|
||||
HashMap<ByteString, Dictionary> dictionaries;
|
||||
HashMap<ByteString, Vector<Dictionary>> partial_dictionaries;
|
||||
HashMap<ByteString, Enumeration> enumerations;
|
||||
HashMap<ByteString, Typedef> typedefs;
|
||||
HashMap<ByteString, Interface*> mixins;
|
||||
|
|
|
@ -897,11 +897,23 @@ static void generate_to_cpp(SourceGenerator& generator, ParameterType& parameter
|
|||
|
||||
@parameter.type.name@ @cpp_name@ {};
|
||||
)~~~");
|
||||
auto* current_dictionary = &interface.dictionaries.find(parameter.type->name())->value;
|
||||
auto current_dictionary_name = parameter.type->name();
|
||||
auto* current_dictionary = &interface.dictionaries.find(current_dictionary_name)->value;
|
||||
// FIXME: This (i) is a hack to make sure we don't generate duplicate variable names.
|
||||
static auto i = 0;
|
||||
while (true) {
|
||||
for (auto& member : current_dictionary->members) {
|
||||
Vector<DictionaryMember> members;
|
||||
for (auto& member : current_dictionary->members)
|
||||
members.append(member);
|
||||
|
||||
if (interface.partial_dictionaries.contains(current_dictionary_name)) {
|
||||
auto& partial_dictionaries = interface.partial_dictionaries.find(current_dictionary_name)->value;
|
||||
for (auto& partial_dictionary : partial_dictionaries)
|
||||
for (auto& member : partial_dictionary.members)
|
||||
members.append(member);
|
||||
}
|
||||
|
||||
for (auto& member : members) {
|
||||
dictionary_generator.set("member_key", member.name);
|
||||
auto member_js_name = make_input_acceptable_cpp(member.name.to_snakecase());
|
||||
auto member_value_name = ByteString::formatted("{}_value_{}", member_js_name, i);
|
||||
|
@ -953,7 +965,8 @@ static void generate_to_cpp(SourceGenerator& generator, ParameterType& parameter
|
|||
if (current_dictionary->parent_name.is_empty())
|
||||
break;
|
||||
VERIFY(interface.dictionaries.contains(current_dictionary->parent_name));
|
||||
current_dictionary = &interface.dictionaries.find(current_dictionary->parent_name)->value;
|
||||
current_dictionary_name = current_dictionary->parent_name;
|
||||
current_dictionary = &interface.dictionaries.find(current_dictionary_name)->value;
|
||||
}
|
||||
} else if (interface.callback_functions.contains(parameter.type->name())) {
|
||||
// https://webidl.spec.whatwg.org/#es-callback-function
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue