replace Invokable interface by DelegateType, MethodType, and SignalType
authorJuerg Billeter <j@bitron.ch>
Fri, 14 Dec 2007 19:41:38 +0000 (19:41 +0000)
committerJürg Billeter <juergbi@src.gnome.org>
Fri, 14 Dec 2007 19:41:38 +0000 (19:41 +0000)
2007-12-14  Juerg Billeter  <j@bitron.ch>

* vala/Makefile.am, vala/valadatatype.vala, vala/valadelegatetype.vala,
  vala/valafield.vala, vala/valaformalparameter.vala,
  vala/valainterfacewriter.vala, vala/valainvokable.vala,
  vala/valamemorymanager.vala, vala/valamethod.vala,
  vala/valamethodtype.vala, vala/valasemanticanalyzer.vala,
  vala/valasignal.vala, vala/valasignaltype.vala,
  vala/valasymbolresolver.vala, vala/valavariabledeclarator.vala,
  gobject/valaccodegenerator.vala,
  gobject/valaccodegeneratorinvocationexpression.vala: replace Invokable
  interface by DelegateType, MethodType, and SignalType classes

svn path=/trunk/; revision=768

17 files changed:
ChangeLog
gobject/valaccodegenerator.vala
gobject/valaccodegeneratorinvocationexpression.vala
vala/Makefile.am
vala/valadatatype.vala
vala/valadelegatetype.vala [new file with mode: 0644]
vala/valafield.vala
vala/valaformalparameter.vala
vala/valainterfacewriter.vala
vala/valamemorymanager.vala
vala/valamethod.vala
vala/valamethodtype.vala [moved from vala/valainvokable.vala with 58% similarity]
vala/valasemanticanalyzer.vala
vala/valasignal.vala
vala/valasignaltype.vala [new file with mode: 0644]
vala/valasymbolresolver.vala
vala/valavariabledeclarator.vala

index 0ab00a2..cefb2d4 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,18 @@
 2007-12-14  Jürg Billeter  <j@bitron.ch>
 
+       * vala/Makefile.am, vala/valadatatype.vala, vala/valadelegatetype.vala,
+         vala/valafield.vala, vala/valaformalparameter.vala,
+         vala/valainterfacewriter.vala, vala/valainvokable.vala,
+         vala/valamemorymanager.vala, vala/valamethod.vala,
+         vala/valamethodtype.vala, vala/valasemanticanalyzer.vala,
+         vala/valasignal.vala, vala/valasignaltype.vala,
+         vala/valasymbolresolver.vala, vala/valavariabledeclarator.vala,
+         gobject/valaccodegenerator.vala,
+         gobject/valaccodegeneratorinvocationexpression.vala: replace Invokable
+         interface by DelegateType, MethodType, and SignalType classes
+
+2007-12-14  Jürg Billeter  <j@bitron.ch>
+
        * gobject/valaccodegeneratorinvocationexpression.vala: fix exception
          handling with ellipsis parameters
 
index 18ea2e8..4f7a3b9 100644 (file)
@@ -1771,7 +1771,7 @@ public class Vala.CCodeGenerator : CodeGenerator {
 
                var local_vars = b.get_local_variables ();
                foreach (VariableDeclarator decl in local_vars) {
-                       if (decl.active && decl.type_reference.data_type.is_reference_type () && decl.type_reference.takes_ownership) {
+                       if (decl.active && decl.type_reference.data_type != null && decl.type_reference.data_type.is_reference_type () && decl.type_reference.takes_ownership) {
                                found = true;
                                var ma = new MemberAccess.simple (decl.name);
                                ma.symbol_reference = decl;
index c522cf0..13e4af3 100644 (file)
@@ -41,15 +41,13 @@ public class Vala.CCodeGenerator {
                
                var ma = (MemberAccess) expr.call;
                
-               if (expr.call.symbol_reference is Invokable) {
-                       var i = (Invokable) expr.call.symbol_reference;
-                       params = i.get_parameters ();
-                       
-                       if (i is Method) {
-                               m = (Method) i;
-                       } else if (i is Signal) {
-                               ccall = (CCodeFunctionCall) expr.call.ccodenode;
-                       }
+               var itype = expr.call.static_type;
+               params = itype.get_parameters ();
+               
+               if (itype is MethodType) {
+                       m = ((MethodType) itype).method_symbol;
+               } else if (itype is SignalType) {
+                       ccall = (CCodeFunctionCall) expr.call.ccodenode;
                }
                
                if (m is ArrayResizeMethod) {
index c7023a7..20ba18f 100644 (file)
@@ -46,6 +46,7 @@ libvalacore_la_VALASOURCES = \
        valacreationmethod.vala \
        valadatatype.vala \
        valadeclarationstatement.vala \
+       valadelegatetype.vala \
        valadestructor.vala \
        valadostatement.vala \
        valaelementaccess.vala \
@@ -65,7 +66,6 @@ libvalacore_la_VALASOURCES = \
        valainterface.vala \
        valainterfacewriter.vala \
        valainvocationexpression.vala \
-       valainvokable.vala \
        valalambdaexpression.vala \
        valaliteral.vala \
        valaliteralexpression.vala \
@@ -77,6 +77,7 @@ libvalacore_la_VALASOURCES = \
        valamemberinitializer.vala \
        valamemorymanager.vala \
        valamethod.vala \
+       valamethodtype.vala \
        valanamedargument.vala \
        valanamespace.vala \
        valanamespacereference.vala \
@@ -99,6 +100,7 @@ libvalacore_la_VALASOURCES = \
        valascope.vala \
        valasemanticanalyzer.vala \
        valasignal.vala \
+       valasignaltype.vala \
        valasizeofexpression.vala \
        valasourcefile.vala \
        valasourcefilecycle.vala \
index a4722c1..c19ba42 100644 (file)
@@ -121,7 +121,7 @@ public class Vala.DataType : CodeNode {
         *
         * @return the type string to be used in C code
         */
-       public string get_cname (bool var_type = false, bool const_type = false) {
+       public virtual string get_cname (bool var_type = false, bool const_type = false) {
                if (data_type == null && type_parameter == null) {
                        if (var_type) {
                                return "gpointer";
@@ -176,21 +176,44 @@ public class Vala.DataType : CodeNode {
                
                return "const %s%s".printf (t.get_cname (), ptr);
        }
-       
-       /**
-        * Returns a user-readable name of the type corresponding to this type
-        * reference.
-        *
-        * @return display name
-        */
-       public string! to_string () {
+
+       public override string! to_string () {
+               string s;
+
                if (data_type != null) {
-                       return data_type.get_full_name ();
+                       s = data_type.get_full_name ();
                } else if (type_parameter != null) {
-                       return type_parameter.name;
+                       s = type_parameter.name;
                } else {
-                       return "null";
+                       s = "null";
                }
+
+               var type_args = get_type_arguments ();
+               if (!(data_type is Array) && type_args.size > 0) {
+                       s += "<";
+                       bool first = true;
+                       foreach (DataType type_arg in type_args) {
+                               if (!first) {
+                                       s += ",";
+                               } else {
+                                       first = false;
+                               }
+                               if (!type_arg.takes_ownership) {
+                                       s += "weak ";
+                               }
+                               if (type_arg.data_type != null) {
+                                       s += type_arg.data_type.get_full_name ();
+                               } else {
+                                       s += type_arg.type_parameter.name;
+                               }
+                       }
+                       s += ">";
+               }
+               if (non_null) {
+                       s += "!";
+               }
+
+               return s;
        }
        
        /**
@@ -307,4 +330,31 @@ public class Vala.DataType : CodeNode {
                        }
                }
        }
+
+       /**
+        * Returns whether instances of this type are invokable.
+        *
+        * @return true if invokable, false otherwise
+        */
+       public virtual bool is_invokable () {
+               return false;
+       }
+
+       /**
+        * Returns the return type of this invokable.
+        *
+        * @return return type
+        */
+       public virtual DataType get_return_type () {
+               return null;
+       }
+
+       /**
+        * Returns copy of the list of invocation parameters.
+        *
+        * @return parameter list
+        */
+       public virtual Collection<FormalParameter> get_parameters () {
+               return null;
+       }
 }
diff --git a/vala/valadelegatetype.vala b/vala/valadelegatetype.vala
new file mode 100644 (file)
index 0000000..afe0019
--- /dev/null
@@ -0,0 +1,58 @@
+/* valadelegatetype.vala
+ *
+ * Copyright (C) 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
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
+ *
+ * Author:
+ *     Jürg Billeter <j@bitron.ch>
+ */
+
+using GLib;
+using Gee;
+
+/**
+ * The type of an instance of a delegate.
+ */
+public class Vala.DelegateType : DataType {
+       public Callback delegate_symbol { get; set; }
+
+       public DelegateType (construct Callback delegate_symbol) {
+       }
+
+       public override bool is_invokable () {
+               return true;
+       }
+
+       public override DataType get_return_type () {
+               return delegate_symbol.return_type;
+       }
+
+       public override Collection<FormalParameter> get_parameters () {
+               return delegate_symbol.get_parameters ();
+       }
+
+       public override string! to_string () {
+               return delegate_symbol.get_full_name ();
+       }
+
+       public override DataType! copy () {
+               return new DelegateType (delegate_symbol);
+       }
+
+       public override string get_cname (bool var_type = false, bool const_type = false) {
+               return delegate_symbol.get_cname (const_type);
+       }
+}
index 164e5b6..e411729 100644 (file)
@@ -26,7 +26,7 @@ using Gee;
 /**
  * Represents a type or namespace field.
  */
-public class Vala.Field : Member, Invokable, Lockable {
+public class Vala.Field : Member, Lockable {
        /**
         * The data type of this field.
         */
@@ -151,28 +151,6 @@ public class Vala.Field : Member, Invokable, Lockable {
                }
        }
 
-       public Collection<FormalParameter> get_parameters () {
-               if (!is_invokable ()) {
-                       return null;
-               }
-               
-               var cb = (Callback) type_reference.data_type;
-               return cb.get_parameters ();
-       }
-       
-       public DataType get_return_type () {
-               if (!is_invokable ()) {
-                       return null;
-               }
-               
-               var cb = (Callback) type_reference.data_type;
-               return cb.return_type;
-       }
-
-       public bool is_invokable () {
-               return (type_reference.data_type is Callback);
-       }
-       
        public bool get_lock_used () {
                return lock_used;
        }
index 7dc466b..b63bd5d 100644 (file)
@@ -27,7 +27,7 @@ using Gee;
 /**
  * Represents a formal parameter in method and callback signatures.
  */
-public class Vala.FormalParameter : Symbol, Invokable {
+public class Vala.FormalParameter : Symbol {
        /**
         * The parameter type.
         */
@@ -106,28 +106,6 @@ public class Vala.FormalParameter : Symbol, Invokable {
                }
        }
 
-       public Collection<FormalParameter> get_parameters () {
-               if (!is_invokable ()) {
-                       return null;
-               }
-               
-               var cb = (Callback) type_reference.data_type;
-               return cb.get_parameters ();
-       }
-       
-       public DataType get_return_type () {
-               if (!is_invokable ()) {
-                       return null;
-               }
-               
-               var cb = (Callback) type_reference.data_type;
-               return cb.return_type;
-       }
-
-       public bool is_invokable () {
-               return (type_reference.data_type is Callback);
-       }
-
        public override void replace_type (DataType! old_type, DataType! new_type) {
                if (type_reference == old_type) {
                        type_reference = new_type;
index 6fefe40..d4ce4fb 100644 (file)
@@ -660,36 +660,7 @@ public class Vala.InterfaceWriter : CodeVisitor {
        }
 
        private void write_type (DataType! type) {
-               if (type.data_type != null) {
-                       write_string (type.data_type.get_full_name ());
-               } else {
-                       write_string (type.type_parameter.name);
-               }
-               
-               var type_args = type.get_type_arguments ();
-               if (!(type.data_type is Array) && type_args.size > 0) {
-                       write_string ("<");
-                       bool first = true;
-                       foreach (DataType type_arg in type_args) {
-                               if (!first) {
-                                       write_string (",");
-                               } else {
-                                       first = false;
-                               }
-                               if (!type_arg.takes_ownership) {
-                                       write_string ("weak ");
-                               }
-                               if (type_arg.data_type != null) {
-                                       write_string (type_arg.data_type.get_full_name ());
-                               } else {
-                                       write_string (type_arg.type_parameter.name);
-                               }
-                       }
-                       write_string (">");
-               }
-               if (type.non_null) {
-                       write_string ("!");
-               }
+               write_string (type.to_string ());
        }
 
        private void write_string (string! s) {
index 2449c83..1435784 100644 (file)
@@ -205,8 +205,8 @@ public class Vala.MemoryManager : CodeVisitor {
        public override void visit_invocation_expression (InvocationExpression! expr) {
                expr.accept_children (this);
 
-               var msym = (Invokable) expr.call.symbol_reference;
-               Collection<FormalParameter> params = msym.get_parameters ();
+               var mtype = expr.call.static_type;
+               Collection<FormalParameter> params = mtype.get_parameters ();
 
                Iterator<FormalParameter> params_it = params.iterator ();
                foreach (Expression arg in expr.get_argument_list ()) {
@@ -220,7 +220,7 @@ public class Vala.MemoryManager : CodeVisitor {
                                        if (is_ref && param.type_reference.type_parameter != null) {
                                                if (expr.call is MemberAccess) {
                                                        var ma = (MemberAccess) expr.call;
-                                                       var param_type = SemanticAnalyzer.get_actual_type (ma.inner.static_type, msym, param.type_reference, expr);
+                                                       var param_type = SemanticAnalyzer.get_actual_type (ma.inner.static_type, ma.symbol_reference, param.type_reference, expr);
                                                        if (param_type != null) {
                                                                is_ref = param_type.takes_ownership;
                                                        }
@@ -244,11 +244,11 @@ public class Vala.MemoryManager : CodeVisitor {
        public override void visit_object_creation_expression (ObjectCreationExpression! expr) {
                expr.accept_children (this);
 
-               if (!(expr.symbol_reference is Invokable)) {
+               if (!(expr.symbol_reference is Method)) {
                        return;
                }
                
-               var msym = (Invokable) expr.symbol_reference;
+               var msym = (Method) expr.symbol_reference;
                Collection<FormalParameter> params = msym.get_parameters ();
 
                Iterator<FormalParameter> params_it = params.iterator ();
index 22cb69c..831cc55 100644 (file)
@@ -27,7 +27,7 @@ using Gee;
 /**
  * Represents a type or namespace method.
  */
-public class Vala.Method : Member, Invokable {
+public class Vala.Method : Member {
        public const string DEFAULT_SENTINEL = "NULL";
 
        /**
@@ -202,14 +202,6 @@ public class Vala.Method : Member, Invokable {
        public Collection<FormalParameter> get_parameters () {
                return new ReadOnlyCollection<FormalParameter> (parameters);
        }
-       
-       public DataType get_return_type () {
-               return return_type;
-       }
-
-       public bool is_invokable () {
-               return true;
-       }
 
        public override void accept (CodeVisitor! visitor) {
                visitor.visit_method (this);
similarity index 58%
rename from vala/valainvokable.vala
rename to vala/valamethodtype.vala
index eef37f0..f4b2cf5 100644 (file)
@@ -1,6 +1,6 @@
-/* valainvokable.vala
+/* valamethodtype.vala
  *
- * Copyright (C) 2006-2007  Jürg Billeter
+ * Copyright (C) 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
@@ -24,27 +24,23 @@ using GLib;
 using Gee;
 
 /**
- * Represents a possibly invokable code object.
+ * The type of a method referencea.
  */
-public interface Vala.Invokable : Symbol {
-       /**
-        * Returns whether this code object is invokable.
-        *
-        * @return true if invokable, false otherwise
-        */
-       public abstract bool is_invokable ();
-
-       /**
-        * Returns the return type of this invokable.
-        *
-        * @return return type
-        */
-       public abstract DataType get_return_type ();
-       
-       /**
-        * Returns copy of the list of invocation parameters.
-        *
-        * @return parameter list
-        */
-       public abstract Collection<FormalParameter> get_parameters ();
+public class Vala.MethodType : DataType {
+       public Method method_symbol { get; set; }
+
+       public MethodType (construct Method method_symbol) {
+       }
+
+       public override bool is_invokable () {
+               return true;
+       }
+
+       public override DataType get_return_type () {
+               return method_symbol.return_type;
+       }
+
+       public override Collection<FormalParameter> get_parameters () {
+               return method_symbol.get_parameters ();
+       }
 }
index bb8e715..91220b8 100644 (file)
@@ -1219,6 +1219,10 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
                        return decl.type_reference;
                } else if (sym is EnumValue) {
                        return new ValueType ((Typesymbol) sym.parent_symbol);
+               } else if (sym is Method) {
+                       return new MethodType ((Method) sym);
+               } else if (sym is Signal) {
+                       return new SignalType ((Signal) sym);
                }
                return null;
        }
@@ -1437,6 +1441,10 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
        }
 
        private bool is_type_compatible (DataType! expression_type, DataType! expected_type) {
+               if (expected_type is DelegateType && expression_type is DelegateType) {
+                       return ((DelegateType) expected_type).delegate_symbol == ((DelegateType) expression_type).delegate_symbol;
+               }
+
                /* only null is compatible to null */
                if (expected_type.data_type == null && expected_type.type_parameter == null) {
                        return (expression_type.data_type == null && expected_type.type_parameter == null);
@@ -1527,25 +1535,18 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
                        }
                }
 
-               var msym = expr.call.symbol_reference;
+               var mtype = expr.call.static_type;
 
-               if (msym == null) {
-                       /* if no symbol found, skip this check */
+               if (mtype == null) {
+                       /* if no type found, skip this check */
                        expr.error = true;
                        return;
                }
 
                Collection<FormalParameter> params;
 
-               if (msym is Invokable) {
-                       var m = (Invokable) msym;
-                       if (m.is_invokable ()) {
-                               params = m.get_parameters ();
-                       } else {
-                               expr.error = true;
-                               Report.error (expr.source_reference, "invocation not supported in this context");
-                               return;
-                       }
+               if (mtype.is_invokable ()) {
+                       params = mtype.get_parameters ();
                } else {
                        expr.error = true;
                        Report.error (expr.source_reference, "invocation not supported in this context");
@@ -1573,57 +1574,54 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
 
                DataType ret_type;
 
-               if (msym is Invokable) {
-                       var m = (Invokable) msym;
-                       ret_type = m.get_return_type ();
-                       params = m.get_parameters ();
+               ret_type = mtype.get_return_type ();
+               params = mtype.get_parameters ();
 
-                       if (ret_type.data_type == null && ret_type.type_parameter == null) {
-                               // void return type
-                               if (!(expr.parent_node is ExpressionStatement)) {
-                                       expr.error = true;
-                                       Report.error (expr.source_reference, "invocation of void method not allowed as expression");
-                                       return;
-                               }
+               if (ret_type.data_type == null && ret_type.type_parameter == null) {
+                       // void return type
+                       if (!(expr.parent_node is ExpressionStatement)) {
+                               expr.error = true;
+                               Report.error (expr.source_reference, "invocation of void method not allowed as expression");
+                               return;
                        }
+               }
 
-                       // resolve generic return values
-                       if (ret_type.type_parameter != null) {
-                               if (!(expr.call is MemberAccess)) {
-                                       Report.error (((CodeNode) m).source_reference, "internal error: unsupported generic return value");
-                                       expr.error = true;
-                                       return;
-                               }
-                               var ma = (MemberAccess) expr.call;
-                               if (ma.inner == null) {
-                                       // TODO resolve generic return values within the type hierarchy if possible
-                                       Report.error (expr.source_reference, "internal error: resolving generic return values within type hierarchy not supported yet");
-                                       expr.error = true;
+               // resolve generic return values
+               if (ret_type.type_parameter != null) {
+                       if (!(expr.call is MemberAccess)) {
+                               Report.error (expr.source_reference, "internal error: unsupported generic return value");
+                               expr.error = true;
+                               return;
+                       }
+                       var ma = (MemberAccess) expr.call;
+                       if (ma.inner == null) {
+                               // TODO resolve generic return values within the type hierarchy if possible
+                               Report.error (expr.source_reference, "internal error: resolving generic return values within type hierarchy not supported yet");
+                               expr.error = true;
+                               return;
+                       } else {
+                               ret_type = get_actual_type (ma.inner.static_type, ma.symbol_reference, ret_type, expr);
+                               if (ret_type == null) {
                                        return;
-                               } else {
-                                       ret_type = get_actual_type (ma.inner.static_type, msym, ret_type, expr);
-                                       if (ret_type == null) {
-                                               return;
-                                       }
                                }
                        }
                }
 
-               if (msym is Method) {
-                       var m = (Method) msym;
+               if (mtype is MethodType) {
+                       var m = ((MethodType) mtype).method_symbol;
                        expr.tree_can_fail = expr.can_fail = (m.get_error_domains ().size > 0);
                }
 
                expr.static_type = ret_type;
 
-               check_arguments (expr, msym, params, expr.get_argument_list ());
+               check_arguments (expr, mtype, params, expr.get_argument_list ());
        }
 
-       private bool check_arguments (Expression! expr, Symbol! msym, Collection<FormalParameter> params, Collection<Expression> args) {
+       private bool check_arguments (Expression! expr, DataType! mtype, Collection<FormalParameter> params, Collection<Expression> args) {
                Expression prev_arg = null;
                Iterator<Expression> arg_it = args.iterator ();
 
-               bool diag = (msym.get_attribute ("Diagnostics") != null);
+               bool diag = (mtype is MethodType && ((MethodType) mtype).method_symbol.get_attribute ("Diagnostics") != null);
 
                bool ellipsis = false;
                int i = 0;
@@ -1641,7 +1639,7 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
                        if (!arg_it.next ()) {
                                if (param.default_expression == null) {
                                        expr.error = true;
-                                       Report.error (expr.source_reference, "Too few arguments, method `%s' does not take %d arguments".printf (msym.get_full_name (), args.size));
+                                       Report.error (expr.source_reference, "Too few arguments, method `%s' does not take %d arguments".printf (mtype.to_string (), args.size));
                                        return false;
                                }
                        } else {
@@ -1652,7 +1650,7 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
                                        return false;
                                } else if (arg.static_type == null) {
                                        // disallow untyped arguments except for type inference of callbacks
-                                       if (!(param.type_reference.data_type is Callback) || !(arg.symbol_reference is Method)) {
+                                       if (!(param.type_reference is DelegateType) || !(arg.symbol_reference is Method)) {
                                                expr.error = true;
                                                Report.error (expr.source_reference, "Invalid type for argument %d".printf (i + 1));
                                                return false;
@@ -1689,7 +1687,7 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
                        }
                } else if (!ellipsis && arg_it.next ()) {
                        expr.error = true;
-                       Report.error (expr.source_reference, "Too many arguments, method `%s' does not take %d arguments".printf (msym.get_full_name (), args.size));
+                       Report.error (expr.source_reference, "Too many arguments, method `%s' does not take %d arguments".printf (mtype.to_string (), args.size));
                        return false;
                }
 
@@ -1996,7 +1994,7 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
 
                if (expr.symbol_reference is Method) {
                        var m = (Method) expr.symbol_reference;
-                       check_arguments (expr, m, m.get_parameters (), expr.get_argument_list ());
+                       check_arguments (expr, new MethodType (m), m.get_parameters (), expr.get_argument_list ());
 
                        expr.tree_can_fail = expr.can_fail = (m.get_error_domains ().size > 0);
                } else if (type is Enum) {
@@ -2564,7 +2562,7 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
        }
 
        public override void visit_lambda_expression (LambdaExpression! l) {
-               if (l.expected_type == null || !(l.expected_type.data_type is Callback)) {
+               if (!(l.expected_type is DelegateType)) {
                        l.error = true;
                        Report.error (l.source_reference, "lambda expression not allowed in this context");
                        return;
@@ -2578,7 +2576,7 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
                        in_instance_method = is_in_constructor ();
                }
 
-               var cb = (Callback) l.expected_type.data_type;
+               var cb = (Callback) ((DelegateType) l.expected_type).delegate_symbol;
                l.method = new Method (get_lambda_name (), cb.return_type);
                l.method.instance = cb.instance && in_instance_method;
                l.method.owner = current_symbol.scope;
@@ -2659,8 +2657,7 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
                        if (ma.symbol_reference is Signal) {
                                var sig = (Signal) ma.symbol_reference;
 
-                               a.right.expected_type = new DataType ();
-                               a.right.expected_type.data_type = sig.get_callback ();
+                               a.right.expected_type = new DelegateType (sig.get_callback ());
                        } else {
                                a.right.expected_type = ma.static_type;
                        }
index f8088e5..b0820c0 100644 (file)
@@ -26,7 +26,7 @@ using Gee;
 /**
  * Represents an object signal. Signals enable objects to provide notifications.
  */
-public class Vala.Signal : Member, Invokable, Lockable {
+public class Vala.Signal : Member, Lockable {
        /**
         * The return type of handlers of this signal.
         */
@@ -76,15 +76,7 @@ public class Vala.Signal : Member, Invokable, Lockable {
        public Collection<FormalParameter> get_parameters () {
                return new ReadOnlyCollection<FormalParameter> (parameters);
        }
-       
-       public DataType get_return_type () {
-               return return_type;
-       }
 
-       public bool is_invokable () {
-               return true;
-       }
-       
        /**
         * Returns generated callback to be used for signal handlers.
         *
diff --git a/vala/valasignaltype.vala b/vala/valasignaltype.vala
new file mode 100644 (file)
index 0000000..3992f2e
--- /dev/null
@@ -0,0 +1,46 @@
+/* valasignaltype.vala
+ *
+ * Copyright (C) 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
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
+ *
+ * Author:
+ *     Jürg Billeter <j@bitron.ch>
+ */
+
+using GLib;
+using Gee;
+
+/**
+ * The type of a signal referencea.
+ */
+public class Vala.SignalType : DataType {
+       public Signal signal_symbol { get; set; }
+
+       public SignalType (construct Signal signal_symbol) {
+       }
+
+       public override bool is_invokable () {
+               return true;
+       }
+
+       public override DataType get_return_type () {
+               return signal_symbol.return_type;
+       }
+
+       public override Collection<FormalParameter> get_parameters () {
+               return signal_symbol.get_parameters ();
+       }
+}
index 40b8c27..76269a8 100644 (file)
@@ -231,7 +231,11 @@ public class Vala.SymbolResolver : CodeVisitor {
                        if (sym is TypeParameter) {
                                type.type_parameter = (TypeParameter) sym;
                        } else if (sym is Typesymbol) {
-                               type.data_type = (Typesymbol) sym;
+                               if (sym is Callback) {
+                                       type = new DelegateType ((Callback) sym);
+                               } else {
+                                       type.data_type = (Typesymbol) sym;
+                               }
                        } else {
                                Report.error (type.source_reference, "`%s' is not a type".printf (sym.get_full_name ()));
                                return null;
@@ -250,7 +254,11 @@ public class Vala.SymbolResolver : CodeVisitor {
                                return null;
                        }
                        if (sym is Typesymbol) {
-                               type.data_type = (Typesymbol) sym;
+                               if (sym is Callback) {
+                                       type = new DelegateType ((Callback) sym);
+                               } else {
+                                       type.data_type = (Typesymbol) sym;
+                               }
                        } else {
                                Report.error (type.source_reference, "`%s' is not a type".printf (sym.get_full_name ()));
                                return null;
index bea885a..ca6d0c2 100644 (file)
@@ -26,7 +26,7 @@ using Gee;
 /**
  * Represents a variable declarator in the source code.
  */
-public class Vala.VariableDeclarator : Symbol, Invokable {
+public class Vala.VariableDeclarator : Symbol {
        /**
         * The optional initializer expression.
         */
@@ -83,28 +83,6 @@ public class Vala.VariableDeclarator : Symbol, Invokable {
                }
        }
 
-       public Collection<FormalParameter> get_parameters () {
-               if (!is_invokable ()) {
-                       return null;
-               }
-               
-               var cb = (Callback) type_reference.data_type;
-               return cb.get_parameters ();
-       }
-       
-       public DataType get_return_type () {
-               if (!is_invokable ()) {
-                       return null;
-               }
-               
-               var cb = (Callback) type_reference.data_type;
-               return cb.return_type;
-       }
-
-       public bool is_invokable () {
-               return (type_reference.data_type is Callback);
-       }
-
        public override void replace_expression (Expression! old_node, Expression! new_node) {
                if (initializer == old_node) {
                        initializer = new_node;