summaryrefslogtreecommitdiff
path: root/vala/valamethod.vala
diff options
context:
space:
mode:
authorRico Tzschichholz <ricotz@ubuntu.com>2018-11-29 18:44:28 +0100
committerRico Tzschichholz <ricotz@ubuntu.com>2018-12-20 00:51:37 +0100
commit3da2f97f02d6dcc359765080bf2f894a0519806d (patch)
tree4dfa1770e4fa84f8ae2f7659b19f841cb5d43d0a /vala/valamethod.vala
parent7c8f91b6c919a58e5043ccf54c96da7b4f92972b (diff)
downloadvala-3da2f97f02d6dcc359765080bf2f894a0519806d.tar.gz
vala: Search in all interfaces for an implementation match and don't bail early
The first imcompatible method match doesn't mean there is no match for another interface. This might mean an implementation is missing which will be covered by the semantic check of the parent class. Fixes https://gitlab.gnome.org/GNOME/vala/issues/548
Diffstat (limited to 'vala/valamethod.vala')
-rw-r--r--vala/valamethod.vala29
1 files changed, 21 insertions, 8 deletions
diff --git a/vala/valamethod.vala b/vala/valamethod.vala
index 294f7b397..bd203ab36 100644
--- a/vala/valamethod.vala
+++ b/vala/valamethod.vala
@@ -631,6 +631,11 @@ public class Vala.Method : Subroutine, Callable {
}
private void find_base_interface_method (Class cl) {
+ Method? base_match = null;
+
+ string? invalid_error = null;
+ Method? invalid_base_match = null;
+
foreach (DataType type in cl.get_base_types ()) {
if (type.data_type is Interface) {
if (base_interface_type != null && base_interface_type.data_type != type.data_type) {
@@ -661,20 +666,28 @@ public class Vala.Method : Subroutine, Callable {
string invalid_match = null;
if (!compatible (base_method, out invalid_match)) {
- error = true;
- var base_method_type = new MethodType (base_method);
- Report.error (source_reference, "overriding method `%s' is incompatible with base method `%s': %s.".printf (get_full_name (), base_method_type.to_prototype_string (), invalid_match));
- return;
+ invalid_error = invalid_match;
+ invalid_base_match = base_method;
+ } else {
+ base_match = base_method;
+ break;
}
-
- _base_interface_method = base_method;
- copy_attribute_double (base_method, "CCode", "instance_pos");
- return;
}
}
}
}
+ if (base_match != null) {
+ _base_interface_method = base_match;
+ copy_attribute_double (base_match, "CCode", "instance_pos");
+ return;
+ } else if (invalid_base_match != null) {
+ error = true;
+ var base_method_type = new MethodType (invalid_base_match);
+ Report.error (source_reference, "overriding method `%s' is incompatible with base method `%s': %s.".printf (get_full_name (), base_method_type.to_prototype_string (), invalid_error));
+ return;
+ }
+
if (base_interface_type != null) {
Report.error (source_reference, "`%s': no suitable interface method found to implement".printf (get_full_name ()));
}