check interfaces before base class in symbol lookup
authorJuerg Billeter <j@bitron.ch>
Fri, 30 Nov 2007 11:59:29 +0000 (11:59 +0000)
committerJürg Billeter <juergbi@src.gnome.org>
Fri, 30 Nov 2007 11:59:29 +0000 (11:59 +0000)
2007-11-30  Juerg Billeter  <j@bitron.ch>

* vala/valasemanticanalyzer.vala: check interfaces before base class
  in symbol lookup

* tests/classes-methods.exp, tests/classes-methods.vala: test expected
  symbol lookup behavior

svn path=/trunk/; revision=741

ChangeLog
tests/classes-methods.exp
tests/classes-methods.vala
vala/valasemanticanalyzer.vala

index 03824bd..19ee83e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2007-11-30  Jürg Billeter  <j@bitron.ch>
+
+       * vala/valasemanticanalyzer.vala: check interfaces before base class
+         in symbol lookup
+
+       * tests/classes-methods.exp, tests/classes-methods.vala: test expected
+         symbol lookup behavior
+
 2007-11-29  Jürg Billeter  <j@bitron.ch>
 
        * vala/valamemberaccess.vala, gobject/Makefile.am,
index 8619eb6..6e621cb 100644 (file)
@@ -1,3 +1,4 @@
 Inheritance Test: 1 2 3
 Static Inheritance Test: 1 2 3
 Virtual Method Test: 1 2 3
+Interface Inheritance Test: 1 2 3
index b4c123f..3d1dc7c 100644 (file)
@@ -39,6 +39,31 @@ class Maman.SubBar : Bar {
        
                stdout.printf (" 3\n");
 
+               // test symbol resolving to check that methods of implemented
+               // interfaces take precedence of methods in base classes
+               stdout.printf ("Interface Inheritance Test: 1");
+
+               var foobar = new SubFooBar ();
+               foobar.do_action ();
+       
+               stdout.printf (" 3\n");
+
                return 0;
        }
 }
+
+interface Maman.Foo {
+       public void do_action () {
+               stdout.printf (" 2");
+       }
+}
+
+class Maman.FooBar : Object {
+       public void do_action () {
+               stdout.printf (" BAD");
+       }
+}
+
+class Maman.SubFooBar : FooBar, Foo {
+}
+
index d3429a8..87d3318 100644 (file)
@@ -1240,12 +1240,20 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
 
                if (sym is Class) {
                        var cl = (Class) sym;
+                       // first check interfaces without prerequisites
+                       // (prerequisites can be assumed to be met already)
                        foreach (TypeReference base_type in cl.get_base_types ()) {
-                               result = symbol_lookup_inherited (base_type.data_type, name);
-                               if (result != null) {
-                                       return result;
+                               if (base_type.data_type is Interface) {
+                                       result = base_type.data_type.scope.lookup (name);
+                                       if (result != null) {
+                                               return result;
+                                       }
                                }
                        }
+                       // then check base class recursively
+                       if (cl.base_class != null) {
+                               return symbol_lookup_inherited (cl.base_class, name);
+                       }
                } else if (sym is Struct) {
                        var st = (Struct) sym;
                        foreach (TypeReference base_type in st.get_base_types ()) {
@@ -1256,10 +1264,22 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
                        }
                } else if (sym is Interface) {
                        var iface = (Interface) sym;
+                       // first check interface prerequisites recursively
                        foreach (TypeReference prerequisite in iface.get_prerequisites ()) {
-                               result = symbol_lookup_inherited (prerequisite.data_type, name);
-                               if (result != null) {
-                                       return result;
+                               if (prerequisite.data_type is Interface) {
+                                       result = symbol_lookup_inherited (prerequisite.data_type, name);
+                                       if (result != null) {
+                                               return result;
+                                       }
+                               }
+                       }
+                       // then check class prerequisite recursively
+                       foreach (TypeReference prerequisite in iface.get_prerequisites ()) {
+                               if (prerequisite.data_type is Class) {
+                                       result = symbol_lookup_inherited (prerequisite.data_type, name);
+                                       if (result != null) {
+                                               return result;
+                                       }
                                }
                        }
                }