[vala/wip/issue548: 3/5] codegen: Do a proper check before connecting inherited implementations



commit c452e32cec8fe4bb2edb87d0cfe17a977d9e0828
Author: Rico Tzschichholz <ricotz ubuntu com>
Date:   Fri Nov 30 21:26:15 2018 +0100

    codegen: Do a proper check before connecting inherited implementations
    
    This caused double vfunc assignments if an implementation is provided while
    a method with the same name is available in prerequisite class.
    
    See https://bugzilla.gnome.org/show_bug.cgi?id=536863
    and https://bugzilla.gnome.org/show_bug.cgi?id=652098
    
    Fixes https://gitlab.gnome.org/GNOME/vala/issues/548

 codegen/valagtypemodule.vala          |  8 +++++++-
 tests/Makefile.am                     |  1 +
 tests/objects/classes-interfaces.vala | 27 +++++++++++++++++++++++++++
 3 files changed, 35 insertions(+), 1 deletion(-)
---
diff --git a/codegen/valagtypemodule.vala b/codegen/valagtypemodule.vala
index bb971c1c4..dda5e6fef 100644
--- a/codegen/valagtypemodule.vala
+++ b/codegen/valagtypemodule.vala
@@ -1477,7 +1477,13 @@ public class Vala.GTypeModule : GErrorModule {
                                Method cl_method = null;
                                var base_class = cl;
                                while (base_class != null && cl_method == null) {
-                                       cl_method = base_class.scope.lookup (m.name) as Method;
+                                       foreach (var impl in base_class.get_methods ()) {
+                                               if (impl.name == m.name && impl.base_interface_method == null 
&& impl.base_interface_type == null
+                                                   && impl.compatible_no_error (m)) {
+                                                       cl_method = impl;
+                                                       break;
+                                               }
+                                       }
                                        base_class = base_class.base_class;
                                }
                                if (base_class != null && cl_method.parent_symbol != cl) {
diff --git a/tests/Makefile.am b/tests/Makefile.am
index f62e5f2c3..a806956cc 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -254,6 +254,7 @@ TESTS = \
        objects/chainup.vala \
        objects/class_only.vala \
        objects/classes.vala \
+       objects/classes-interfaces.vala \
        objects/compact-class.vala \
        objects/compact-class-destructor.vala \
        objects/constructor-variadic.test \
diff --git a/tests/objects/classes-interfaces.vala b/tests/objects/classes-interfaces.vala
new file mode 100644
index 000000000..9f2474653
--- /dev/null
+++ b/tests/objects/classes-interfaces.vala
@@ -0,0 +1,27 @@
+class Base : Object {
+       public void foo () {
+       }
+}
+
+interface IFoo : Base {
+       public abstract string foo ();
+}
+
+interface IBar : Base {
+       public abstract int foo ();
+}
+
+class Manam : Base, IFoo, IBar {
+       public int IBar.foo () {
+               return 23;
+       }
+       public string IFoo.foo () {
+               return "foo";
+       }
+}
+
+void main () {
+       var manam = new Manam ();
+       assert (((IFoo) manam).foo () == "foo");
+       assert (((IBar) manam).foo () == 23);
+}


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]