]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
don't require developer to explicitly write static in namespace field
authorJürg Billeter <j@bitron.ch>
Thu, 27 Jul 2006 07:51:42 +0000 (07:51 +0000)
committerJürg Billeter <juergbi@src.gnome.org>
Thu, 27 Jul 2006 07:51:42 +0000 (07:51 +0000)
2006-07-27  Jürg Billeter  <j@bitron.ch>

* vala/parser.y: don't require developer to explicitly write static in
  namespace field declarations, support type parameters in interfaces
  and callbacks
* vala/valasymbolresolver.vala: support interfaces and callbacks
* vala/valasemanticanalyzer.vala: use is_subtype_of method, support
  callbacks in fields
* vala/valamemorymanager.vala: support callbacks in fields
* vala/valacodegenerator.vala: support callbacks in fields
* vala/valacallback.vala: support type parameters
* vala/valaclass.vala: add is_subtype_of method
* vala/valadatatype.vala: add is_subtype_of method
* vala/valainterface.vala: add is_subtype_of method

svn path=/trunk/; revision=84

vala/ChangeLog
vala/vala/parser.y
vala/vala/valacallback.vala
vala/vala/valaclass.vala
vala/vala/valacodegenerator.vala
vala/vala/valadatatype.vala
vala/vala/valainterface.vala
vala/vala/valamemorymanager.vala
vala/vala/valasemanticanalyzer.vala
vala/vala/valasymbolresolver.vala

index 0b176e58b3a14e61aa467f427f31ec843b343093..35865463e6cf634d7f6cffc82d400279c30b1c81 100644 (file)
@@ -1,3 +1,18 @@
+2006-07-27  Jürg Billeter  <j@bitron.ch>
+
+       * vala/parser.y: don't require developer to explicitly write static in
+         namespace field declarations, support type parameters in interfaces
+         and callbacks
+       * vala/valasymbolresolver.vala: support interfaces and callbacks
+       * vala/valasemanticanalyzer.vala: use is_subtype_of method, support
+         callbacks in fields
+       * vala/valamemorymanager.vala: support callbacks in fields
+       * vala/valacodegenerator.vala: support callbacks in fields
+       * vala/valacallback.vala: support type parameters
+       * vala/valaclass.vala: add is_subtype_of method
+       * vala/valadatatype.vala: add is_subtype_of method
+       * vala/valainterface.vala: add is_subtype_of method
+
 2006-07-26  Jürg Billeter  <j@bitron.ch>
 
        * vala/scanner.l: support casting arrays
index 7c7e52b1f3b66832869b302a3caa90ddb970fb82..4962e7e356473ecf53efc157464f3c95b07a08a6 100644 (file)
@@ -1511,6 +1511,10 @@ namespace_member_declaration
          {
                /* skip declarations with errors */
                if ($1 != NULL) {
+                       /* field must be static, don't require developer
+                        * to explicitly state it */
+                       vala_field_set_instance ($1, FALSE);
+                       
                        vala_namespace_add_field (current_namespace, $1);
                        g_object_unref ($1);
                }
@@ -1560,13 +1564,19 @@ class_declaration
                if (($4 & VALA_MODIFIER_ABSTRACT) == VALA_MODIFIER_ABSTRACT) {
                        vala_class_set_is_abstract (current_class, TRUE);
                }
-               for (l = $8; l != NULL; l = l->next) {
-                       vala_class_add_type_parameter (current_class, l->data);
-                       g_object_unref (l->data);
+               if ($8 != NULL) {
+                       for (l = $8; l != NULL; l = l->next) {
+                               vala_class_add_type_parameter (current_class, l->data);
+                               g_object_unref (l->data);
+                       }
+                       g_list_free ($8);
                }
-               for (l = $9; l != NULL; l = l->next) {
-                       vala_class_add_base_type (current_class, l->data);
-                       g_object_unref (l->data);
+               if ($9 != NULL) {
+                       for (l = $9; l != NULL; l = l->next) {
+                               vala_class_add_base_type (current_class, l->data);
+                               g_object_unref (l->data);
+                       }
+                       g_list_free ($9);
                }
          }
          class_body
@@ -2207,7 +2217,7 @@ struct_member_declaration
        ;
 
 interface_declaration
-       : comment opt_attributes opt_access_modifier INTERFACE IDENTIFIER opt_name_specifier
+       : comment opt_attributes opt_access_modifier INTERFACE IDENTIFIER opt_name_specifier opt_type_parameter_list
          {
                char *name = $5;
          
@@ -2228,6 +2238,15 @@ interface_declaration
                current_interface = vala_interface_new (name, src);
                g_free (name);
                g_object_unref (src);
+
+               if ($7 != NULL) {
+                       GList *l;
+                       for (l = $7; l != NULL; l = l->next) {
+                               vala_interface_add_type_parameter (current_interface, l->data);
+                               g_object_unref (l->data);
+                       }
+                       g_list_free ($7);
+               }
          }
          interface_body
          {
@@ -2390,7 +2409,7 @@ flags_member_declaration
        ;
 
 callback_declaration
-       : comment opt_attributes opt_access_modifier CALLBACK type IDENTIFIER opt_name_specifier OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS SEMICOLON
+       : comment opt_attributes opt_access_modifier CALLBACK type IDENTIFIER opt_name_specifier opt_type_parameter_list OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS SEMICOLON
          {
                GList *l;
                char *name = $6;
@@ -2410,22 +2429,28 @@ callback_declaration
                
                ValaSourceReference *src = src_com(@6, $1);
                $$ = vala_callback_new (name, $5, src);
+               g_free (name);
+               g_object_unref ($5);
                g_object_unref (src);
                if ($3 != 0) {
                        VALA_DATA_TYPE($$)->access = $3;
                }
                VALA_CODE_NODE($$)->attributes = $2;
                
-               for (l = $9; l != NULL; l = l->next) {
-                       vala_callback_add_parameter ($$, l->data);
-                       g_object_unref (l->data);
+               if ($8 != NULL) {
+                       for (l = $8; l != NULL; l = l->next) {
+                               vala_callback_add_type_parameter ($$, l->data);
+                               g_object_unref (l->data);
+                       }
+                       g_list_free ($8);
                }
-               if ($9 != NULL) {
-                       g_list_free ($9);
+               if ($10 != NULL) {
+                       for (l = $10; l != NULL; l = l->next) {
+                               vala_callback_add_parameter ($$, l->data);
+                               g_object_unref (l->data);
+                       }
+                       g_list_free ($10);
                }
-
-               g_object_unref ($5);
-               g_free (name);
          }
        ;
 
index 4934ae7220722a92949750f535ee8ea8dfff4885..968f553eaadc85ca142c99583f5073cb16264bb6 100644 (file)
@@ -38,6 +38,8 @@ public class Vala.Callback : DataType {
         */
        public bool instance { get; set; }
        
+       private List<TypeParameter> type_parameters;
+
        private List<FormalParameter> parameters;
        private string cname;
        
@@ -52,6 +54,16 @@ public class Vala.Callback : DataType {
        public static ref Callback new (string! name, TypeReference return_type, SourceReference source) {
                return (new Callback (name = name, return_type = return_type, source_reference = source));
        }
+
+       /**
+        * Appends the specified parameter to the list of type parameters.
+        *
+        * @param p a type parameter
+        */
+       public void add_type_parameter (TypeParameter! p) {
+               type_parameters.append (p);
+               p.type = this;
+       }
        
        /**
         * Appends paramater to this callback function.
@@ -109,6 +121,10 @@ public class Vala.Callback : DataType {
        
        public override void accept (CodeVisitor! visitor) {
                visitor.visit_begin_callback (this);
+
+               foreach (TypeParameter p in type_parameters) {
+                       p.accept (visitor);
+               }
                
                return_type.accept (visitor);
                
index dd0f4d394018190f1b358d517914d0e898f1e2b5..7461143df523c857f3798e45eae9456a89058b9d 100644 (file)
@@ -52,15 +52,15 @@ public class Vala.Class : DataType {
        
        private bool _has_private_fields;
        
-       List<string> type_parameters;
+       private List<TypeParameter> type_parameters;
 
        private List<TypeReference> base_types;
 
-       List<Constant> constants;
-       List<Field> fields;
-       List<Method> methods;
-       List<Property> properties;
-       List<Signal> signals;
+       private List<Constant> constants;
+       private List<Field> fields;
+       private List<Method> methods;
+       private List<Property> properties;
+       private List<Signal> signals;
        
        /**
         * Specifies the instance constructor.
@@ -346,4 +346,15 @@ public class Vala.Class : DataType {
        public override string get_unref_function () {
                return "g_object_unref";
        }
+       
+       public override bool is_subtype_of (DataType! t) {
+               foreach (TypeReference base_type in base_types) {
+                       if (base_type.data_type == t ||
+                           base_type.data_type.is_subtype_of (t)) {
+                               return true;
+                       }
+               }
+               
+               return false;
+       }
 }
index 18ab8e944249e27effeed4427ce31140c1ae79c6..440fb1f6130371327700d0415a642d59690a0ff4 100644 (file)
@@ -1776,10 +1776,14 @@ public class Vala.CodeGenerator : CodeVisitor {
                        var param = (FormalParameter) expr.call.symbol_reference.node;
                        var cb = (Callback) param.type_reference.data_type;
                        params = cb.get_parameters ();
+               } else if (expr.call.symbol_reference.node is Field) {
+                       var f = (Field) expr.call.symbol_reference.node;
+                       var cb = (Callback) f.type_reference.data_type;
+                       params = cb.get_parameters ();
                } else if (expr.call.symbol_reference.node is Method) {
                        m = (Method) expr.call.symbol_reference.node;
                        params = m.get_parameters ();
-               } else {
+               } else if (expr.call.symbol_reference.node is Signal) {
                        var sig = (Signal) expr.call.symbol_reference.node;
                        params = sig.get_parameters ();
                        
index 316fec5a1a9644dea92d9e9b02f5f45b8c8f65fd..85fe194670918b9b60076e6d37e1ab045918c761 100644 (file)
@@ -46,6 +46,9 @@ public abstract class Vala.DataType : CodeNode {
         */
        public weak Namespace @namespace;
 
+       private List<string> cheader_filenames;
+       private Array array_type;
+
        /**
         * Returns the name of this data type as it is used in C code.
         *
@@ -192,11 +195,10 @@ public abstract class Vala.DataType : CodeNode {
                cheader_filenames.append (filename);
        }
 
-       private List<string> cheader_filenames;
-       
-       private Array array_type;
        /**
-        * Retrieves for a given DataType its corresponding Array.
+        * Returns the array type for elements of this data type.
+        *
+        * @return array type for this data type
         */
        public Array! get_array () {
                if (array_type == null) {
@@ -213,4 +215,15 @@ public abstract class Vala.DataType : CodeNode {
                
                return array_type;
        }       
+
+       /**
+        * Checks whether this data type is a subtype of the specified data
+        * type.
+        *
+        * @param t a data type
+        * @return  true if t is a supertype of this data type, false otherwise
+        */
+       public virtual bool is_subtype_of (DataType! t) {
+               return false;
+       }
 }
index 0efedf4e55ba9f7ab0abb97bef3c87131119150c..3283455c0e18a516da757ab1167b89750093b0af 100644 (file)
@@ -26,12 +26,13 @@ using GLib;
  * Represents a class declaration in the source code.
  */
 public class Vala.Interface : DataType {
-       List<string> type_parameters;
+       private List<TypeParameter> type_parameters;
+       
        private List<TypeReference> base_types;
 
-       List<Method> methods;
-       List<Property> properties;
-       List<Signal> signals;
+       private List<Method> methods;
+       private List<Property> properties;
+       private List<Signal> signals;
        
        /**
         * Creates a new interface.
@@ -199,4 +200,15 @@ public class Vala.Interface : DataType {
        public override string get_unref_function () {
                return "g_object_unref";
        }
+
+       public override bool is_subtype_of (DataType! t) {
+               foreach (TypeReference base_type in base_types) {
+                       if (base_type.data_type == t ||
+                           base_type.data_type.is_subtype_of (t)) {
+                               return true;
+                       }
+               }
+               
+               return false;
+       }
 }
index 62cbe519a08bade61b6022a0d46b340c396081b7..69d35fc25f9f24a89e5045b77ea44db78d6d1bb3 100644 (file)
@@ -131,10 +131,14 @@ public class Vala.MemoryManager : CodeVisitor {
                        var param = (FormalParameter) msym.node;
                        var cb = (Callback) param.type_reference.data_type;
                        params = cb.get_parameters ();
+               } else if (msym.node is Field) {
+                       var f = (Field) msym.node;
+                       var cb = (Callback) f.type_reference.data_type;
+                       params = cb.get_parameters ();
                } else if (msym.node is Method) {
                        var m = (Method) msym.node;
                        params = m.get_parameters ();
-               } else {
+               } else if (msym.node is Signal) {
                        var sig = (Signal) msym.node;
                        params = sig.get_parameters ();
                }
index 1fecb5ff17faf891cc15f415ff336a7d551e7154..ce1b1b71474d890ecfb77609bd819d967dace779 100644 (file)
@@ -381,12 +381,14 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
                }
                
                if (stmt.return_expression == null && current_return_type.data_type != null) {
-                       Report.error (stmt.source_reference, "Return with value in void function");
+                       Report.error (stmt.source_reference, "Return without value in non-void function");
                        return;
                }
                
-               if (stmt.return_expression != null && current_return_type.data_type == null) {
-                       Report.error (stmt.source_reference, "Return without value in non-void function");
+               if (stmt.return_expression != null &&
+                   current_return_type.data_type == null &&
+                   current_return_type.type_parameter == null) {
+                       Report.error (stmt.source_reference, "Return with value in void function");
                        return;
                }
                
@@ -655,21 +657,7 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
                        return true;
                }
                
-               /* non-class types must match exactly */
-               if (!(expression_type.data_type is Class)) {
-                       return false;
-               }
-               
-               var cl = (Class) expression_type.data_type;
-               
-               var base_class = cl.base_class;
-               for (; base_class != null; base_class = base_class.base_class) {
-                       if (base_class == expected_type.data_type) {
-                               return true;
-                       }
-               }
-               
-               return false;
+               return expression_type.data_type.is_subtype_of (expected_type.data_type);
        }
 
        public override void visit_begin_invocation_expression (InvocationExpression! expr) {
@@ -703,6 +691,16 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
                                Report.error (expr.source_reference, "invocation not supported in this context");
                                return;
                        }
+               } else if (msym.node is Field) {
+                       var f = (Field) msym.node;
+                       if (f.type_reference.data_type is Callback) {
+                               var cb = (Callback) f.type_reference.data_type;
+                               params = cb.get_parameters ();
+                       } else {
+                               expr.error = true;
+                               Report.error (expr.source_reference, "invocation not supported in this context");
+                               return;
+                       }
                } else if (msym.node is Method) {
                        var m = (Method) msym.node;
                        params = m.get_parameters ();
@@ -753,6 +751,11 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
                        var cb = (Callback) param.type_reference.data_type;
                        ret_type = cb.return_type;
                        params = cb.get_parameters ();
+               } else if (msym.node is Field) {
+                       var f = (Field) msym.node;
+                       var cb = (Callback) f.type_reference.data_type;
+                       ret_type = cb.return_type;
+                       params = cb.get_parameters ();
                } else if (msym.node is Method) {
                        var m = (Method) msym.node;
                        ret_type = m.return_type;
index 1dd22cc05417ee6c152701ac286bc60d9590bf4d..a622a3eca679bb3b961087dac455371162ebc139 100644 (file)
@@ -93,6 +93,22 @@ public class Vala.SymbolResolver : CodeVisitor {
                current_scope = current_scope.parent_symbol;
        }
 
+       public override void visit_begin_interface (Interface! iface) {
+               current_scope = iface.symbol;
+       }
+
+       public override void visit_end_interface (Interface! iface) {
+               current_scope = current_scope.parent_symbol;
+       }
+
+       public override void visit_begin_callback (Callback! cb) {
+               current_scope = cb.symbol;
+       }
+
+       public override void visit_end_callback (Callback! cb) {
+               current_scope = current_scope.parent_symbol;
+       }
+
        public override void visit_formal_parameter (FormalParameter! p) {
                if (!p.ellipsis && p.type_reference.is_ref) {
                        if ((p.type_reference.data_type != null &&