]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
GAsync: Fix .begin and add support for .end
authorJürg Billeter <j@bitron.ch>
Sun, 13 Sep 2009 14:30:52 +0000 (16:30 +0200)
committerJürg Billeter <j@bitron.ch>
Sun, 13 Sep 2009 15:27:29 +0000 (17:27 +0200)
Based on patch by Didier 'Ptitjes.

codegen/valaccodemethodcallmodule.vala
vala/valamethod.vala
vala/valamethodcall.vala
vala/valamethodtype.vala

index ddda66e8c7f2312662ad546ef2db5b43f9e57af7..bef722ca3432917f1c2d4b41a614008b3a49eb15 100644 (file)
@@ -67,32 +67,35 @@ internal class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
                        deleg = ((DelegateType) itype).delegate_symbol;
                }
 
-               HashMap<int,CCodeExpression> in_arg_map, out_arg_map;
+               var in_arg_map = new HashMap<int,CCodeExpression> (direct_hash, direct_equal);
+               var out_arg_map = in_arg_map;
 
                if (m != null && m.coroutine) {
                        // async call
 
-                       in_arg_map = new HashMap<int,CCodeExpression> (direct_hash, direct_equal);
-                       out_arg_map = new HashMap<int,CCodeExpression> (direct_hash, direct_equal);
-
                        async_call = new CCodeFunctionCall (new CCodeIdentifier (m.get_cname ()));
 
                        if (ma.member_name == "begin" && ma.inner.symbol_reference == ma.symbol_reference) {
                                // no finish call
                                ccall = async_call;
+                               params = m.get_async_begin_parameters ();
+                       } else if (ma.member_name == "end" && ma.inner.symbol_reference == ma.symbol_reference) {
+                               // no async call
+                               ccall = new CCodeFunctionCall (new CCodeIdentifier (m.get_finish_cname ()));
+                               params = m.get_async_end_parameters ();
                        } else if (!expr.is_yield_expression) {
                                Report.warning (expr.source_reference, "Calling async methods requires use of `yield' or `begin'");
 
                                ccall = async_call;
+                               params = m.get_async_begin_parameters ();
                        } else {
                                ccall = new CCodeFunctionCall (new CCodeIdentifier (m.get_finish_cname ()));
 
+                               // output arguments used separately
+                               out_arg_map = new HashMap<int,CCodeExpression> (direct_hash, direct_equal);
                                // pass GAsyncResult stored in closure to finish function
                                out_arg_map.set (get_param_pos (0.1), new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "res"));
                        }
-               } else {
-                       in_arg_map = new HashMap<int,CCodeExpression> (direct_hash, direct_equal);
-                       out_arg_map = in_arg_map;
                }
 
                if (m is CreationMethod) {
@@ -520,16 +523,10 @@ internal class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
                }
 
                if (m != null && m.coroutine) {
-                       if ((current_method != null && current_method.coroutine)
-                           || (ma.member_name == "begin" && ma.inner.symbol_reference == ma.symbol_reference)) {
+                       if (expr.is_yield_expression) {
                                // asynchronous call
-                               if (ma.member_name == "begin" && ma.inner.symbol_reference == ma.symbol_reference) {
-                                       in_arg_map.set (get_param_pos (-1), new CCodeConstant ("NULL"));
-                                       in_arg_map.set (get_param_pos (-0.9), new CCodeConstant ("NULL"));
-                               } else {
-                                       in_arg_map.set (get_param_pos (-1), new CCodeIdentifier (current_method.get_cname () + "_ready"));
-                                       in_arg_map.set (get_param_pos (-0.9), new CCodeIdentifier ("data"));
-                               }
+                               in_arg_map.set (get_param_pos (-1), new CCodeIdentifier (current_method.get_cname () + "_ready"));
+                               in_arg_map.set (get_param_pos (-0.9), new CCodeIdentifier ("data"));
                        }
                }
 
index f534c11f3ec09bf6932fd2e692e5f64b6bc3ccbf..2ef15283c7db1df3c0a35e1d295b444047061641 100644 (file)
@@ -961,6 +961,54 @@ public class Vala.Method : Member {
                }
                return callback_method;
        }
+
+       public Gee.List<FormalParameter> get_async_begin_parameters () {
+               assert (this.coroutine);
+
+               var glib_ns = CodeContext.get ().root.scope.lookup ("GLib");
+
+               var params = new ArrayList<FormalParameter> ();
+               foreach (var param in parameters) {
+                       if (param.direction == ParameterDirection.IN) {
+                               params.add (param);
+                       }
+               }
+
+               var callback_type = new DelegateType ((Delegate) glib_ns.scope.lookup ("AsyncReadyCallback"));
+               callback_type.nullable = true;
+
+               var callback_param = new FormalParameter ("callback", callback_type);
+               callback_param.default_expression = new NullLiteral (source_reference);
+               callback_param.cparameter_position = -1;
+               callback_param.cdelegate_target_parameter_position = -0.9;
+
+               params.add (callback_param);
+
+               return params;
+       }
+
+       public Gee.List<FormalParameter> get_async_end_parameters () {
+               assert (this.coroutine);
+
+               var glib_ns = CodeContext.get ().root.scope.lookup ("GLib");
+
+               var params = new ArrayList<FormalParameter> ();
+               foreach (var param in parameters) {
+                       if (param.direction == ParameterDirection.OUT) {
+                               params.add (param);
+                       }
+               }
+
+               var result_type = new ObjectType ((ObjectTypeSymbol) glib_ns.scope.lookup ("AsyncResult"));
+
+               var result_param = new FormalParameter ("res", result_type);
+               result_param.default_expression = new NullLiteral (source_reference);
+               result_param.cparameter_position = 0.1;
+
+               params.add (result_param);
+
+               return params;
+       }
 }
 
 // vim:sw=8 noet
index 65ee4d6f2526601eb329976d40b7005ecf4d1e5e..ba2b6d94743845831215d0c9d97b1390ddb5a7e8 100644 (file)
@@ -198,10 +198,8 @@ public class Vala.MethodCall : Expression {
                        }
                }
 
-               Gee.List<FormalParameter> params;
-
                if (mtype != null && mtype.is_invokable ()) {
-                       params = mtype.get_parameters ();
+                       // call ok, expression is invokable
                } else if (call.symbol_reference is Class) {
                        error = true;
                        Report.error (source_reference, "use `new' operator to create new objects");
@@ -212,6 +210,25 @@ public class Vala.MethodCall : Expression {
                        return false;
                }
 
+               var ret_type = mtype.get_return_type ();
+               var params = mtype.get_parameters ();
+
+               if (mtype is MethodType) {
+                       var m = ((MethodType) mtype).method_symbol;
+                       if (m != null && m.coroutine && !is_yield_expression) {
+                               // begin or end call of async method
+                               var ma = (MemberAccess) call;
+                               if (ma.member_name != "end") {
+                                       // begin (possibly implicit)
+                                       params = m.get_async_begin_parameters ();
+                                       ret_type = new VoidType ();
+                               } else {
+                                       // end
+                                       params = m.get_async_end_parameters ();
+                               }
+                       }
+               }
+
                Expression last_arg = null;
 
                var args = get_argument_list ();
@@ -382,9 +399,6 @@ public class Vala.MethodCall : Expression {
                        arg.check (analyzer);
                }
 
-               DataType ret_type = mtype.get_return_type ();
-               params = mtype.get_parameters ();
-
                if (ret_type is VoidType) {
                        // void return type
                        if (!(parent_node is ExpressionStatement)
index 6167a2592c95422c70a19b7ab6617a2b1d57f843..a782371a59d5742e70de70e98550f5fddcb4969b 100644 (file)
@@ -70,6 +70,8 @@ public class Vala.MethodType : DataType {
        public override Symbol? get_member (string member_name) {
                if (method_symbol.coroutine && member_name == "begin") {
                        return method_symbol;
+               } else if (method_symbol.coroutine && member_name == "end") {
+                       return method_symbol;
                } else if (method_symbol.coroutine && member_name == "callback") {
                        return method_symbol.get_callback_method ();
                }