[vala] GAsync: Fix .begin and add support for .end



commit 09e57fab5aefb5d670fcd3704c6df7427066202c
Author: Jürg Billeter <j bitron ch>
Date:   Sun Sep 13 16:30:52 2009 +0200

    GAsync: Fix .begin and add support for .end
    
    Based on patch by Didier 'Ptitjes.

 codegen/valaccodemethodcallmodule.vala |   29 ++++++++----------
 vala/valamethod.vala                   |   48 ++++++++++++++++++++++++++++++++
 vala/valamethodcall.vala               |   26 +++++++++++++----
 vala/valamethodtype.vala               |    2 +
 4 files changed, 83 insertions(+), 22 deletions(-)
---
diff --git a/codegen/valaccodemethodcallmodule.vala b/codegen/valaccodemethodcallmodule.vala
index ddda66e..bef722c 100644
--- a/codegen/valaccodemethodcallmodule.vala
+++ b/codegen/valaccodemethodcallmodule.vala
@@ -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"));
 			}
 		}
 
diff --git a/vala/valamethod.vala b/vala/valamethod.vala
index f534c11..2ef1528 100644
--- a/vala/valamethod.vala
+++ b/vala/valamethod.vala
@@ -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
diff --git a/vala/valamethodcall.vala b/vala/valamethodcall.vala
index 65ee4d6..ba2b6d9 100644
--- a/vala/valamethodcall.vala
+++ b/vala/valamethodcall.vala
@@ -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)
diff --git a/vala/valamethodtype.vala b/vala/valamethodtype.vala
index 6167a25..a782371 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 ();
 		}



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]