1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 06:37:43 +00:00

LibIDL: Emit an error when two decls of the same function are present

Duplicates can show up when copy-pasting IDL snippets into existing IDL
files, and the resulting error is extremely useless and misleading.
This commit makes it so the parser catches these cases, and emits a more
helpful error like "Overload set 'instantiate' contains multiple
identical declarations".
This commit is contained in:
Ali Mohammad Pur 2024-02-16 04:57:03 +03:30 committed by Andreas Kling
parent bc301b6f40
commit 971e466521
3 changed files with 30 additions and 2 deletions

View file

@ -372,6 +372,7 @@ Vector<Parameter> Parser::parse_parameters()
Function Parser::parse_function(HashMap<ByteString, ByteString>& extended_attributes, Interface& interface, IsSpecialOperation is_special_operation)
{
auto position = lexer.current_position();
bool static_ = false;
if (lexer.consume_specific("static"sv)) {
static_ = true;
@ -388,7 +389,7 @@ Function Parser::parse_function(HashMap<ByteString, ByteString>& extended_attrib
consume_whitespace();
assert_specific(';');
Function function { move(return_type), name, move(parameters), move(extended_attributes), {}, false };
Function function { move(return_type), name, move(parameters), move(extended_attributes), position, {}, false };
// "Defining a special operation with an identifier is equivalent to separating the special operation out into its own declaration without an identifier."
if (is_special_operation == IsSpecialOperation::No || (is_special_operation == IsSpecialOperation::Yes && !name.is_empty())) {
@ -1112,6 +1113,32 @@ Interface& Parser::parse()
}
// FIXME: Add support for overloading constructors
// Check overload sets for repeated instances of the same function
// as these will produce very cryptic errors if left alone.
for (auto& overload_set : interface.overload_sets) {
auto& functions = overload_set.value;
for (size_t i = 0; i < functions.size(); ++i) {
for (size_t j = i + 1; j < functions.size(); ++j) {
if (functions[i].parameters.size() != functions[j].parameters.size())
continue;
auto same = true;
for (size_t k = 0; k < functions[i].parameters.size(); ++k) {
if (functions[i].parameters[k].type->is_distinguishable_from(interface, functions[j].parameters[k].type)) {
same = false;
break;
}
}
if (same) {
report_parsing_error(
ByteString::formatted("Overload set '{}' contains multiple identical declarations", overload_set.key),
filename,
input,
functions[j].source_position.offset);
}
}
}
}
if (interface.will_generate_code())
interface.required_imported_paths.set(this_module);
interface.imported_modules = move(imports);