mirror of
https://github.com/RGBCube/serenity
synced 2025-07-10 12:27:35 +00:00
LibWeb: Add support for IDL typedefs
This commit is contained in:
parent
f0cd28dedd
commit
c14cb65215
3 changed files with 98 additions and 0 deletions
|
@ -612,6 +612,25 @@ void Parser::parse_enumeration(Interface& interface)
|
|||
consume_whitespace();
|
||||
}
|
||||
|
||||
void Parser::parse_typedef(Interface& interface)
|
||||
{
|
||||
assert_string("typedef");
|
||||
consume_whitespace();
|
||||
|
||||
HashMap<String, String> extended_attributes;
|
||||
if (lexer.consume_specific('['))
|
||||
extended_attributes = parse_extended_attributes();
|
||||
|
||||
auto type = parse_type();
|
||||
consume_whitespace();
|
||||
|
||||
auto name = lexer.consume_until(';');
|
||||
assert_specific(';');
|
||||
|
||||
interface.typedefs.set(name, Typedef { move(extended_attributes), move(type) });
|
||||
consume_whitespace();
|
||||
}
|
||||
|
||||
void Parser::parse_dictionary(Interface& interface)
|
||||
{
|
||||
assert_string("dictionary");
|
||||
|
@ -710,6 +729,8 @@ 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("typedef")) {
|
||||
parse_typedef(interface);
|
||||
} else if (lexer.next_is("interface mixin")) {
|
||||
parse_interface_mixin(interface);
|
||||
} else if ((allow_interface && !lexer.next_is("interface")) || !allow_interface) {
|
||||
|
@ -732,6 +753,37 @@ void Parser::parse_non_interface_entities(bool allow_interface, Interface& inter
|
|||
}
|
||||
}
|
||||
|
||||
void resolve_typedef(Interface& interface, NonnullRefPtr<Type>& type, HashMap<String, String>* extended_attributes = {})
|
||||
{
|
||||
if (is<ParameterizedType>(*type)) {
|
||||
auto parameterized_type = static_ptr_cast<ParameterizedType>(type);
|
||||
auto& parameters = static_cast<Vector<NonnullRefPtr<Type>>&>(parameterized_type->parameters);
|
||||
for (auto& parameter : parameters)
|
||||
resolve_typedef(interface, parameter);
|
||||
return;
|
||||
}
|
||||
|
||||
auto it = interface.typedefs.find(type->name);
|
||||
if (it == interface.typedefs.end())
|
||||
return;
|
||||
type = it->value.type;
|
||||
if (!extended_attributes)
|
||||
return;
|
||||
for (auto& attribute : it->value.extended_attributes)
|
||||
extended_attributes->set(attribute.key, attribute.value);
|
||||
}
|
||||
void resolve_parameters_typedefs(Interface& interface, Vector<Parameter>& parameters)
|
||||
{
|
||||
for (auto& parameter : parameters)
|
||||
resolve_typedef(interface, parameter.type, ¶meter.extended_attributes);
|
||||
}
|
||||
template<typename FunctionType>
|
||||
void resolve_function_typedefs(Interface& interface, FunctionType& function)
|
||||
{
|
||||
resolve_typedef(interface, function.return_type);
|
||||
resolve_parameters_typedefs(interface, function.parameters);
|
||||
}
|
||||
|
||||
NonnullOwnPtr<Interface> Parser::parse()
|
||||
{
|
||||
auto this_module = Core::File::real_path_for(filename);
|
||||
|
@ -780,6 +832,9 @@ NonnullOwnPtr<Interface> Parser::parse()
|
|||
interface->enumerations.set(enumeration.key, move(enumeration_copy));
|
||||
}
|
||||
|
||||
for (auto& typedef_ : import.typedefs)
|
||||
interface->typedefs.set(typedef_.key, move(typedef_.value));
|
||||
|
||||
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());
|
||||
|
@ -809,6 +864,42 @@ NonnullOwnPtr<Interface> Parser::parse()
|
|||
}
|
||||
}
|
||||
|
||||
// Resolve typedefs
|
||||
for (auto& attribute : interface->attributes)
|
||||
resolve_typedef(*interface, attribute.type, &attribute.extended_attributes);
|
||||
for (auto& constant : interface->constants)
|
||||
resolve_typedef(*interface, constant.type);
|
||||
for (auto& constructor : interface->constructors)
|
||||
resolve_parameters_typedefs(*interface, constructor.parameters);
|
||||
for (auto& function : interface->functions)
|
||||
resolve_function_typedefs(*interface, function);
|
||||
for (auto& static_function : interface->static_functions)
|
||||
resolve_function_typedefs(*interface, static_function);
|
||||
if (interface->value_iterator_type.has_value())
|
||||
resolve_typedef(*interface, *interface->value_iterator_type);
|
||||
if (interface->pair_iterator_types.has_value()) {
|
||||
resolve_typedef(*interface, interface->pair_iterator_types->get<0>());
|
||||
resolve_typedef(*interface, interface->pair_iterator_types->get<1>());
|
||||
}
|
||||
if (interface->named_property_getter.has_value())
|
||||
resolve_function_typedefs(*interface, *interface->named_property_getter);
|
||||
if (interface->named_property_setter.has_value())
|
||||
resolve_function_typedefs(*interface, *interface->named_property_setter);
|
||||
if (interface->indexed_property_getter.has_value())
|
||||
resolve_function_typedefs(*interface, *interface->indexed_property_getter);
|
||||
if (interface->indexed_property_setter.has_value())
|
||||
resolve_function_typedefs(*interface, *interface->indexed_property_setter);
|
||||
if (interface->named_property_deleter.has_value())
|
||||
resolve_function_typedefs(*interface, *interface->named_property_deleter);
|
||||
if (interface->named_property_getter.has_value())
|
||||
resolve_function_typedefs(*interface, *interface->named_property_getter);
|
||||
for (auto& dictionary : interface->dictionaries) {
|
||||
for (auto& dictionary_member : dictionary.value.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);
|
||||
|
||||
// Create overload sets
|
||||
for (auto& function : interface->functions) {
|
||||
auto& overload_set = interface->overload_sets.ensure(function.name);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue