improve equality check add type parameter equality check add symbol
authorJürg Billeter <j@bitron.ch>
Thu, 1 Mar 2007 22:02:22 +0000 (22:02 +0000)
committerJürg Billeter <juergbi@src.gnome.org>
Thu, 1 Mar 2007 22:02:22 +0000 (22:02 +0000)
2007-03-01  Jürg Billeter  <j@bitron.ch>

* vala/valatypereference.vala: improve equality check
* vala/valatypeparameter.vala: add type parameter equality check
* vala/valasemanticanalyzer.vala: add symbol dependencies for
  interfaces, support overriding methods of interfaces with
  prerequisites

svn path=/trunk/; revision=209

vala/ChangeLog
vala/vala/valasemanticanalyzer.vala
vala/vala/valatypeparameter.vala
vala/vala/valatypereference.vala

index 9c3f7af..54efc93 100644 (file)
@@ -1,3 +1,11 @@
+2007-03-01  Jürg Billeter  <j@bitron.ch>
+
+       * vala/valatypereference.vala: improve equality check
+       * vala/valatypeparameter.vala: add type parameter equality check
+       * vala/valasemanticanalyzer.vala: add symbol dependencies for
+         interfaces, support overriding methods of interfaces with
+         prerequisites
+
 2007-02-28  Jürg Billeter  <j@bitron.ch>
 
        * configure.ac: Post-release version bump
index 707e0f6..3a7d1f5 100644 (file)
@@ -132,6 +132,18 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
                current_symbol = current_symbol.parent_symbol;
                current_struct = null;
        }
+
+       public override void visit_begin_interface (Interface! iface) {
+               current_symbol = iface.symbol;
+               
+               foreach (TypeReference base_type_reference in iface.get_base_types ()) {
+                       current_source_file.add_symbol_dependency (base_type_reference.data_type.symbol, SourceFileDependencyType.HEADER_FULL);
+               }
+       }
+
+       public override void visit_end_interface (Interface! iface) {
+               current_symbol = current_symbol.parent_symbol;
+       }
        
        public override void visit_constant (Constant! c) {
                if (!current_source_file.pkg) {
@@ -189,6 +201,42 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
                }
        }
 
+       private void find_base_method (Method! m, DataType! datatype) {
+               var sym = datatype.symbol.lookup (m.name);
+               if (sym != null && sym.node is Method) {
+                       var base_method = (Method) sym.node;
+                       if (base_method.is_abstract || base_method.is_virtual) {
+                               if (!m.equals (base_method)) {
+                                       m.error = true;
+                                       Report.error (m.source_reference, "Return type and/or parameters of overriding method `%s' do not match overridden method `%s'.".printf (m.symbol.get_full_name (), base_method.symbol.get_full_name ()));
+                                       return;
+                               }
+                               
+                               m.base_method = base_method;
+                               return;
+                       }
+               }
+
+               // FIXME report error if multiple possible base methods are found
+               if (datatype is Class) {
+                       var cl = (Class) datatype;
+                       foreach (TypeReference type in cl.get_base_types ()) {
+                               find_base_method (m, type.data_type);
+                               if (m.base_method != null) {
+                                       return;
+                               }
+                       }
+               } else {
+                       var iface = (Interface) datatype;
+                       foreach (TypeReference type in iface.get_base_types ()) {
+                               find_base_method (m, type.data_type);
+                               if (m.base_method != null) {
+                                       return;
+                               }
+                       }
+               }
+       }
+
        public override void visit_end_method (Method! m) {
                current_symbol = current_symbol.parent_symbol;
                current_return_type = null;
@@ -202,42 +250,7 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
                
                if (m.is_virtual || m.overrides) {
                        if (current_symbol.node is Class) {
-                               var cl = (Class) current_symbol.node;
-                               Class base_class;
-                               for (base_class = cl; base_class != null; base_class = base_class.base_class) {
-                                       var sym = base_class.symbol.lookup (m.name);
-                                       if (sym != null && sym.node is Method) {
-                                               var base_method = (Method) sym.node;
-                                               if (base_method.is_abstract || base_method.is_virtual) {
-                                                       if (!m.equals (base_method)) {
-                                                               m.error = true;
-                                                               Report.error (m.source_reference, "Return type and or parameters of overriding method `%s' do not match overridden method `%s'.".printf (m.symbol.get_full_name (), base_method.symbol.get_full_name ()));
-                                                               return;
-                                                       }
-                                                       
-                                                       m.base_method = base_method;
-                                                       break;
-                                               }
-                                       }
-                               }
-                               if (m.base_method == null) {
-                                       /* FIXME: also look at interfaces implemented
-                                        * by one of the base types
-                                        */
-                                       foreach (TypeReference type in cl.get_base_types ()) {
-                                               if (type.data_type is Interface) {
-                                                       var iface = (Interface) type.data_type;
-                                                       var sym = iface.symbol.lookup (m.name);
-                                                       if (sym != null && sym.node is Method) {
-                                                               var base_method = (Method) sym.node;
-                                                               if (base_method.is_abstract || base_method.is_virtual) {
-                                                                       m.base_method = base_method;
-                                                                       break;
-                                                               }
-                                                       }
-                                               }
-                                       }
-                               }
+                               find_base_method (m, (Class) current_symbol.node);
                                if (m.base_method == null) {
                                        Report.error (m.source_reference, "%s: no suitable method found to override".printf (m.symbol.get_full_name ()));
                                }
index 1bad1cf..83dc39e 100644 (file)
@@ -86,4 +86,19 @@ public class Vala.TypeParameter : CodeNode {
                
                return array_type;
        }
+
+       /**
+        * Checks two type parameters for equality.
+        *
+        * @param param2 a type parameter
+        * @return      true if this type parameter is equal to param2, false
+        *              otherwise
+        */
+       public bool equals (TypeParameter! param2) {
+               // FIXME check whether the corresponding data type of one of the
+               //       parameters is a base type of the corresponding data
+               //       type of the other parameter and check along the path
+               //       whether one parameter maps to the other
+               return true;
+       }
 }
index 6d2ff04..fba60fd 100644 (file)
@@ -307,8 +307,13 @@ public class Vala.TypeReference : CodeNode {
                if (type2.data_type != data_type) {
                        return false;
                }
-               if (type2.type_parameter != type_parameter) {
-                       return false;
+               if (type2.type_parameter != null || type_parameter != null) {
+                       if (type2.type_parameter == null || type_parameter == null) {
+                               return false;
+                       }
+                       if (!type2.type_parameter.equals (type_parameter)) {
+                               return false;
+                       }
                }
                if (type2.floating_reference != floating_reference) {
                        return false;