mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-08-27 20:58:16 +00:00
IDLGenerators: Support generating dictionary to value converter helpers
This is useful when returning dictionaries as a Promise.
This commit is contained in:
parent
d6c2893663
commit
dc1b7b1925
Notes:
github-actions[bot]
2025-08-08 17:12:32 +00:00
Author: https://github.com/IdanHo
Commit: dc1b7b1925
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/5766
Reviewed-by: https://github.com/trflynn89 ✅
4 changed files with 45 additions and 9 deletions
|
@ -919,7 +919,7 @@ void Parser::parse_typedef(Interface& interface)
|
|||
consume_whitespace();
|
||||
}
|
||||
|
||||
void Parser::parse_dictionary(Interface& interface)
|
||||
void Parser::parse_dictionary(HashMap<ByteString, ByteString> extended_attributes, Interface& interface)
|
||||
{
|
||||
bool partial = false;
|
||||
if (lexer.next_is("partial")) {
|
||||
|
@ -932,6 +932,7 @@ void Parser::parse_dictionary(Interface& interface)
|
|||
consume_whitespace();
|
||||
|
||||
Dictionary dictionary {};
|
||||
dictionary.extended_attributes = move(extended_attributes);
|
||||
|
||||
auto name = parse_identifier_ending_with_space();
|
||||
consume_whitespace();
|
||||
|
@ -953,10 +954,10 @@ void Parser::parse_dictionary(Interface& interface)
|
|||
}
|
||||
|
||||
bool required = false;
|
||||
HashMap<ByteString, ByteString> extended_attributes;
|
||||
HashMap<ByteString, ByteString> member_extended_attributes;
|
||||
|
||||
if (lexer.consume_specific('['))
|
||||
extended_attributes = parse_extended_attributes();
|
||||
member_extended_attributes = parse_extended_attributes();
|
||||
|
||||
if (lexer.consume_specific("required"sv)) {
|
||||
required = true;
|
||||
|
@ -964,7 +965,7 @@ void Parser::parse_dictionary(Interface& interface)
|
|||
}
|
||||
|
||||
if (lexer.consume_specific('['))
|
||||
extended_attributes.update(parse_extended_attributes());
|
||||
member_extended_attributes.update(parse_extended_attributes());
|
||||
|
||||
auto type = parse_type();
|
||||
consume_whitespace();
|
||||
|
@ -987,7 +988,7 @@ void Parser::parse_dictionary(Interface& interface)
|
|||
required,
|
||||
move(type),
|
||||
move(name),
|
||||
move(extended_attributes),
|
||||
move(member_extended_attributes),
|
||||
Optional<ByteString>(move(default_value)),
|
||||
};
|
||||
dictionary.members.append(move(member));
|
||||
|
@ -1061,7 +1062,7 @@ void Parser::parse_non_interface_entities(bool allow_interface, Interface& inter
|
|||
if (lexer.consume_specific('['))
|
||||
extended_attributes = parse_extended_attributes();
|
||||
if (lexer.next_is("dictionary") || lexer.next_is("partial dictionary")) {
|
||||
parse_dictionary(interface);
|
||||
parse_dictionary(extended_attributes, interface);
|
||||
} else if (lexer.next_is("enum")) {
|
||||
parse_enumeration(extended_attributes, interface);
|
||||
} else if (lexer.next_is("typedef")) {
|
||||
|
@ -1205,7 +1206,11 @@ Interface& Parser::parse()
|
|||
interface.extend_with_partial_interface(*partial_interface);
|
||||
}
|
||||
|
||||
interface.dictionaries.update(import.dictionaries);
|
||||
for (auto& dictionary : import.dictionaries) {
|
||||
auto dictionary_copy = dictionary.value;
|
||||
dictionary_copy.is_original_definition = false;
|
||||
interface.dictionaries.set(dictionary.key, move(dictionary_copy));
|
||||
}
|
||||
|
||||
for (auto& partial_dictionary : import.partial_dictionaries) {
|
||||
auto& it = interface.partial_dictionaries.ensure(partial_dictionary.key);
|
||||
|
|
|
@ -51,7 +51,7 @@ private:
|
|||
void parse_enumeration(HashMap<ByteString, ByteString>, Interface&);
|
||||
void parse_typedef(Interface&);
|
||||
void parse_interface_mixin(Interface&);
|
||||
void parse_dictionary(Interface&);
|
||||
void parse_dictionary(HashMap<ByteString, ByteString> extended_attributes, Interface&);
|
||||
void parse_callback_function(HashMap<ByteString, ByteString>& extended_attributes, Interface&);
|
||||
void parse_constructor(HashMap<ByteString, ByteString>& extended_attributes, Interface&);
|
||||
void parse_getter(HashMap<ByteString, ByteString>& extended_attributes, Interface&);
|
||||
|
|
|
@ -208,6 +208,8 @@ struct DictionaryMember {
|
|||
struct Dictionary {
|
||||
ByteString parent_name;
|
||||
Vector<DictionaryMember> members;
|
||||
HashMap<ByteString, ByteString> extended_attributes;
|
||||
bool is_original_definition { true };
|
||||
};
|
||||
|
||||
struct Typedef {
|
||||
|
@ -336,7 +338,7 @@ public:
|
|||
|
||||
bool will_generate_code() const
|
||||
{
|
||||
return !name.is_empty() || any_of(enumerations, [](auto& entry) { return entry.value.is_original_definition; });
|
||||
return !name.is_empty() || any_of(dictionaries, [](auto& entry) { return entry.value.is_original_definition; }) || any_of(enumerations, [](auto& entry) { return entry.value.is_original_definition; });
|
||||
}
|
||||
|
||||
void extend_with_partial_interface(Interface const&);
|
||||
|
|
|
@ -2953,6 +2953,33 @@ static ByteString get_best_value_for_underlying_enum_type(size_t size)
|
|||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
static void generate_dictionaries(SourceGenerator& generator, IDL::Interface const& interface)
|
||||
{
|
||||
for (auto const& it : interface.dictionaries) {
|
||||
if (!it.value.is_original_definition)
|
||||
continue;
|
||||
if (!it.value.extended_attributes.contains("GenerateToValue"sv))
|
||||
continue;
|
||||
auto dictionary_generator = generator.fork();
|
||||
dictionary_generator.set("dictionary.name", make_input_acceptable_cpp(it.key));
|
||||
dictionary_generator.set("dictionary.name:snakecase", make_input_acceptable_cpp(it.key.to_snakecase()));
|
||||
dictionary_generator.append(R"~~~(
|
||||
JS::Value @dictionary.name:snakecase@_to_value(JS::Realm&, @dictionary.name@ const&);
|
||||
JS::Value @dictionary.name:snakecase@_to_value(JS::Realm& realm, @dictionary.name@ const& dictionary)
|
||||
{
|
||||
auto& vm = realm.vm();
|
||||
@dictionary.name@ copy = dictionary;
|
||||
)~~~");
|
||||
// FIXME: Support generating wrap statements for lvalues and get rid of the copy above
|
||||
auto dictionary_type = adopt_ref(*new Type(it.key, false));
|
||||
generate_wrap_statement(dictionary_generator, "copy", dictionary_type, interface, "return"sv);
|
||||
|
||||
dictionary_generator.append(R"~~~(
|
||||
}
|
||||
)~~~");
|
||||
}
|
||||
}
|
||||
|
||||
static void generate_enumerations(HashMap<ByteString, Enumeration> const& enumerations, StringBuilder& builder)
|
||||
{
|
||||
SourceGenerator generator { builder };
|
||||
|
@ -4748,6 +4775,8 @@ JS_DEFINE_NATIVE_FUNCTION(@class_name@::clear)
|
|||
)~~~");
|
||||
}
|
||||
}
|
||||
|
||||
generate_dictionaries(generator, interface);
|
||||
}
|
||||
|
||||
void generate_namespace_header(IDL::Interface const& interface, StringBuilder& builder)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue