mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-08-22 02:09:24 +00: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)
|
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);
|
assert_string("dictionary"sv);
|
||||||
consume_whitespace();
|
consume_whitespace();
|
||||||
|
|
||||||
|
@ -896,7 +903,13 @@ void Parser::parse_dictionary(Interface& interface)
|
||||||
return one.name < two.name;
|
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();
|
consume_whitespace();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -952,7 +965,7 @@ void Parser::parse_non_interface_entities(bool allow_interface, Interface& inter
|
||||||
HashMap<ByteString, ByteString> extended_attributes;
|
HashMap<ByteString, ByteString> extended_attributes;
|
||||||
if (lexer.consume_specific('['))
|
if (lexer.consume_specific('['))
|
||||||
extended_attributes = parse_extended_attributes();
|
extended_attributes = parse_extended_attributes();
|
||||||
if (lexer.next_is("dictionary")) {
|
if (lexer.next_is("dictionary") || lexer.next_is("partial dictionary")) {
|
||||||
parse_dictionary(interface);
|
parse_dictionary(interface);
|
||||||
} else if (lexer.next_is("enum")) {
|
} else if (lexer.next_is("enum")) {
|
||||||
parse_enumeration(extended_attributes, interface);
|
parse_enumeration(extended_attributes, interface);
|
||||||
|
@ -1093,6 +1106,11 @@ Interface& Parser::parse()
|
||||||
for (auto& dictionary : import.dictionaries)
|
for (auto& dictionary : import.dictionaries)
|
||||||
interface.dictionaries.set(dictionary.key, dictionary.value);
|
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) {
|
for (auto& enumeration : import.enumerations) {
|
||||||
auto enumeration_copy = enumeration.value;
|
auto enumeration_copy = enumeration.value;
|
||||||
enumeration_copy.is_original_definition = false;
|
enumeration_copy.is_original_definition = false;
|
||||||
|
@ -1172,6 +1190,11 @@ Interface& Parser::parse()
|
||||||
for (auto& dictionary_member : dictionary.value.members)
|
for (auto& dictionary_member : dictionary.value.members)
|
||||||
resolve_typedef(interface, dictionary_member.type, &dictionary_member.extended_attributes);
|
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)
|
for (auto& callback_function : interface.callback_functions)
|
||||||
resolve_function_typedefs(interface, callback_function.value);
|
resolve_function_typedefs(interface, callback_function.value);
|
||||||
|
|
||||||
|
|
|
@ -297,6 +297,7 @@ public:
|
||||||
Optional<Function> named_property_deleter;
|
Optional<Function> named_property_deleter;
|
||||||
|
|
||||||
HashMap<ByteString, Dictionary> dictionaries;
|
HashMap<ByteString, Dictionary> dictionaries;
|
||||||
|
HashMap<ByteString, Vector<Dictionary>> partial_dictionaries;
|
||||||
HashMap<ByteString, Enumeration> enumerations;
|
HashMap<ByteString, Enumeration> enumerations;
|
||||||
HashMap<ByteString, Typedef> typedefs;
|
HashMap<ByteString, Typedef> typedefs;
|
||||||
HashMap<ByteString, Interface*> mixins;
|
HashMap<ByteString, Interface*> mixins;
|
||||||
|
|
|
@ -897,11 +897,23 @@ static void generate_to_cpp(SourceGenerator& generator, ParameterType& parameter
|
||||||
|
|
||||||
@parameter.type.name@ @cpp_name@ {};
|
@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.
|
// FIXME: This (i) is a hack to make sure we don't generate duplicate variable names.
|
||||||
static auto i = 0;
|
static auto i = 0;
|
||||||
while (true) {
|
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);
|
dictionary_generator.set("member_key", member.name);
|
||||||
auto member_js_name = make_input_acceptable_cpp(member.name.to_snakecase());
|
auto member_js_name = make_input_acceptable_cpp(member.name.to_snakecase());
|
||||||
auto member_value_name = ByteString::formatted("{}_value_{}", member_js_name, i);
|
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())
|
if (current_dictionary->parent_name.is_empty())
|
||||||
break;
|
break;
|
||||||
VERIFY(interface.dictionaries.contains(current_dictionary->parent_name));
|
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())) {
|
} else if (interface.callback_functions.contains(parameter.type->name())) {
|
||||||
// https://webidl.spec.whatwg.org/#es-callback-function
|
// https://webidl.spec.whatwg.org/#es-callback-function
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue