check whether a class implements all abstract methods of base classes fix
authorJürg Billeter <j@bitron.ch>
Wed, 7 Mar 2007 21:20:05 +0000 (21:20 +0000)
committerJürg Billeter <juergbi@src.gnome.org>
Wed, 7 Mar 2007 21:20:05 +0000 (21:20 +0000)
2007-03-07  Jürg Billeter  <j@bitron.ch>

* vala/valasemanticanalyzer.vala: check whether a class implements all
  abstract methods of base classes
* vala/valacodenode.vala, vala/valadatatype.vala,
  vala/valaexpression.vala, vala/valaliteral.vala: fix build with added
  checks

svn path=/trunk/; revision=228

vala/ChangeLog
vala/vala/valacodenode.vala
vala/vala/valadatatype.vala
vala/vala/valaexpression.vala
vala/vala/valaliteral.vala
vala/vala/valasemanticanalyzer.vala

index 18d832f..6faa917 100644 (file)
@@ -1,5 +1,13 @@
 2007-03-07  Jürg Billeter  <j@bitron.ch>
 
+       * vala/valasemanticanalyzer.vala: check whether a class implements all
+         abstract methods of base classes
+       * vala/valacodenode.vala, vala/valadatatype.vala,
+         vala/valaexpression.vala, vala/valaliteral.vala: fix build with added
+         checks
+
+2007-03-07  Jürg Billeter  <j@bitron.ch>
+
        * vala/valaclass.vala: implement get_type_parameter_index
 
 2007-03-07  Raffaele Sandrini  <rasa@gmx.ch>
index 22a0309..92df6fc 100644 (file)
@@ -79,7 +79,8 @@ public abstract class Vala.CodeNode {
         *
         * @param visitor the visitor to be called while traversing
         */
-       public abstract void accept (CodeVisitor! visitor);
+       public virtual void accept (CodeVisitor! visitor) {
+       }
        
        public virtual void replace (CodeNode! old_node, CodeNode! new_node) {
        }
@@ -108,10 +109,10 @@ public abstract class Vala.CodeNode {
         *
         * @return a string representation
         */
-       public ref string to_string () {
+       public virtual ref string! to_string () {
                if (source_reference != null) {
                        return source_reference.to_string ();
                }
-               return null;
+               return "(unknown)";
        }
 }
index 15ce343..d9585c1 100644 (file)
@@ -173,7 +173,9 @@ public abstract class Vala.DataType : CodeNode {
         *              name or null
         * @return      the upper case name to be used in C code
         */
-       public abstract ref string get_upper_case_cname (string infix = null);
+       public virtual ref string get_upper_case_cname (string infix = null) {
+               return null;
+       }
        
        /**
         * Returns the C name of this data type in lower case. Words are
@@ -184,7 +186,9 @@ public abstract class Vala.DataType : CodeNode {
         *              name or null
         * @return      the lower case name to be used in C code
         */
-       public abstract ref string get_lower_case_cname (string infix = null);
+       public virtual ref string get_lower_case_cname (string infix = null) {
+               return null;
+       }
        
        /**
         * Returns the string to be prefixed to members of this data type in
@@ -192,7 +196,9 @@ public abstract class Vala.DataType : CodeNode {
         *
         * @return      the lower case prefix to be used in C code
         */
-       public abstract ref string get_lower_case_cprefix ();
+       public virtual ref string get_lower_case_cprefix () {
+               return null;
+       }
        
        /**
         * Returns a list of C header filenames users of this data type must
index b4a44b2..38a8a9f 100644 (file)
@@ -1,6 +1,6 @@
 /* valaexpression.vala
  *
- * Copyright (C) 2006  Jürg Billeter
+ * Copyright (C) 2006-2007  Jürg Billeter
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -73,6 +73,4 @@ public abstract class Vala.Expression : CodeNode {
         * The code generator sets and uses them for memory management.
         */
        public List<VariableDeclarator> temp_vars;
-       
-       public abstract ref string! to_string ();
 }
index aab9f21..01886bf 100644 (file)
@@ -1,6 +1,6 @@
 /* valaliteral.vala
  *
- * Copyright (C) 2006  Jürg Billeter
+ * Copyright (C) 2006-2007  Jürg Billeter
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -30,6 +30,4 @@ public abstract class Vala.Literal : CodeNode {
         * Specifies the type of this literal.
         */
        public TypeReference static_type { get; set; }
-       
-       public abstract ref string! to_string ();
 }
index 6af2738..344046a 100644 (file)
@@ -178,22 +178,44 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
                        Report.error (cl.source_reference, error_string);
                }
                
-               /* all virtual symbols defined in interfaces have to be at least defined (or implemented) also in this type */
+               /* all abstract symbols defined in base types have to be at least defined (or implemented) also in this type */
                foreach (TypeReference base_type in cl.get_base_types ()) {
                        if (base_type.data_type is Interface) {
-                               Interface iface = (Interface)base_type.data_type;
-                               
+                               Interface iface = (Interface) base_type.data_type;
+
                                /* We do not need to do expensive equality checking here since this is done
                                 * already. We only need to guarantee the symbols are present.
                                 */
-                               
+
                                /* check methods */
                                foreach (Method m in iface.get_methods ()) {
-                                       if (cl.symbol.lookup (m.name) == null && m.is_abstract) {
-                                               cl.error = true;
-                                               Report.error (cl.source_reference, "`%s' does not implement interface method `%s'".printf (cl.symbol.get_full_name (), m.symbol.get_full_name ()));
+                                       if (m.is_abstract) {
+                                               var sym = cl.symbol.lookup (m.name);
+                                               if (sym == null || !(sym.node is Method) || ((Method) sym.node).base_interface_method != m) {
+                                                       cl.error = true;
+                                                       Report.error (cl.source_reference, "`%s' does not implement interface method `%s'".printf (cl.symbol.get_full_name (), m.symbol.get_full_name ()));
+                                               }
+                                       }
+                               }
+                       }
+               }
+
+               /* all abstract symbols defined in base classes have to be implemented in non-abstract classes
+                * VAPI classes don't have to specify overridden methods
+                */
+               if (!cl.is_abstract && !cl.source_reference.file.pkg) {
+                       var base_class = cl.base_class;
+                       while (base_class != null && base_class.is_abstract) {
+                               foreach (Method m in base_class.get_methods ()) {
+                                       if (m.is_abstract) {
+                                               var sym = cl.symbol.lookup (m.name);
+                                               if (sym == null || !(sym.node is Method) || ((Method) sym.node).base_method != m) {
+                                                       cl.error = true;
+                                                       Report.error (cl.source_reference, "`%s' does not implement abstract method `%s'".printf (cl.symbol.get_full_name (), m.symbol.get_full_name ()));
+                                               }
                                        }
                                }
+                               base_class = base_class.base_class;
                        }
                }