From: Jürg Billeter Date: Sun, 13 Sep 2009 14:30:52 +0000 (+0200) Subject: GAsync: Fix .begin and add support for .end X-Git-Tag: 0.7.6~112 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=09e57fab5aefb5d670fcd3704c6df7427066202c;p=thirdparty%2Fvala.git GAsync: Fix .begin and add support for .end Based on patch by Didier 'Ptitjes. --- diff --git a/codegen/valaccodemethodcallmodule.vala b/codegen/valaccodemethodcallmodule.vala index ddda66e8c..bef722ca3 100644 --- a/codegen/valaccodemethodcallmodule.vala +++ b/codegen/valaccodemethodcallmodule.vala @@ -67,32 +67,35 @@ internal class Vala.CCodeMethodCallModule : CCodeAssignmentModule { deleg = ((DelegateType) itype).delegate_symbol; } - HashMap in_arg_map, out_arg_map; + var in_arg_map = new HashMap (direct_hash, direct_equal); + var out_arg_map = in_arg_map; if (m != null && m.coroutine) { // async call - in_arg_map = new HashMap (direct_hash, direct_equal); - out_arg_map = new HashMap (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 (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 (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")); } } diff --git a/vala/valamethod.vala b/vala/valamethod.vala index f534c11f3..2ef15283c 100644 --- a/vala/valamethod.vala +++ b/vala/valamethod.vala @@ -961,6 +961,54 @@ public class Vala.Method : Member { } return callback_method; } + + public Gee.List get_async_begin_parameters () { + assert (this.coroutine); + + var glib_ns = CodeContext.get ().root.scope.lookup ("GLib"); + + var params = new ArrayList (); + 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 get_async_end_parameters () { + assert (this.coroutine); + + var glib_ns = CodeContext.get ().root.scope.lookup ("GLib"); + + var params = new ArrayList (); + 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 diff --git a/vala/valamethodcall.vala b/vala/valamethodcall.vala index 65ee4d6f2..ba2b6d947 100644 --- a/vala/valamethodcall.vala +++ b/vala/valamethodcall.vala @@ -198,10 +198,8 @@ public class Vala.MethodCall : Expression { } } - Gee.List 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) diff --git a/vala/valamethodtype.vala b/vala/valamethodtype.vala index 6167a2592..a782371a5 100644 --- a/vala/valamethodtype.vala +++ b/vala/valamethodtype.vala @@ -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 (); }