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



commit 52aa5b46d7bce35da33e20bcdf0e78f0ee37e857
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 7c1f1cf03..69ad4561c 100644
--- a/codegen/valagtypemodule.vala
+++ b/codegen/valagtypemodule.vala
@@ -1476,7 +1476,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 (m, null)) {
+                                                       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 a269d528d..15cefa931 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -252,6 +252,7 @@ TESTS = \
        delegates/bug792077.vala \
        objects/chainup.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]