[vala] codegen: Use builder API in GVariant and GDBus modules



commit 34e72d0192c97e9bfafb4727db16dc024a74dd95
Author: Jürg Billeter <j bitron ch>
Date:   Sun Oct 10 18:20:45 2010 +0200

    codegen: Use builder API in GVariant and GDBus modules

 codegen/valaccodebasemodule.vala   |   28 +-
 codegen/valagdbusclientmodule.vala |  354 +++++++++---------------
 codegen/valagdbusservermodule.vala |  543 +++++++++++++++---------------------
 codegen/valagvariantmodule.vala    |  282 +++++++------------
 4 files changed, 481 insertions(+), 726 deletions(-)
---
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index baf58a6..564af4a 100644
--- a/codegen/valaccodebasemodule.vala
+++ b/codegen/valaccodebasemodule.vala
@@ -4372,26 +4372,24 @@ public class Vala.CCodeBaseModule : CodeGenerator {
 			}
 		}
 
-		var block = new CCodeBlock ();
-		var fragment = new CCodeFragment ();
-		var result = deserialize_expression (fragment, to, new CCodeIdentifier ("value"), new CCodeIdentifier ("*result"));
+		push_function (cfunc);
 
-		block.add_statement (fragment);
-		block.add_statement (new CCodeReturnStatement (result));
+		var result = deserialize_expression (to, new CCodeIdentifier ("value"), new CCodeIdentifier ("*result"));
+		ccode.add_return (result);
 
-		cfile.add_function_declaration (cfunc);
+		pop_function ();
 
-		cfunc.block = block;
+		cfile.add_function_declaration (cfunc);
 		cfile.add_function (cfunc);
 
 		return ccall;
 	}
 
-	public virtual CCodeExpression? deserialize_expression (CCodeFragment fragment, DataType type, CCodeExpression variant_expr, CCodeExpression? expr) {
+	public virtual CCodeExpression? deserialize_expression (DataType type, CCodeExpression variant_expr, CCodeExpression? expr) {
 		return null;
 	}
 
-	public virtual CCodeExpression? serialize_expression (CCodeFragment fragment, DataType type, CCodeExpression expr) {
+	public virtual CCodeExpression? serialize_expression (DataType type, CCodeExpression expr) {
 		return null;
 	}
 
@@ -5027,20 +5025,18 @@ public class Vala.CCodeBaseModule : CodeGenerator {
 				}
 			}
 
-			var block = new CCodeBlock ();
-			var fragment = new CCodeFragment ();
-			var result = serialize_expression (fragment, expression_type, new CCodeIdentifier ("value"));
+			push_function (cfunc);
+
+			var result = serialize_expression (expression_type, new CCodeIdentifier ("value"));
 
 			// sink floating reference
 			var sink = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_ref_sink"));
 			sink.add_argument (result);
+			ccode.add_return (sink);
 
-			block.add_statement (fragment);
-			block.add_statement (new CCodeReturnStatement (sink));
+			pop_function ();
 
 			cfile.add_function_declaration (cfunc);
-
-			cfunc.block = block;
 			cfile.add_function (cfunc);
 
 			return ccall;
diff --git a/codegen/valagdbusclientmodule.vala b/codegen/valagdbusclientmodule.vala
index f3b385e..dd35c09 100644
--- a/codegen/valagdbusclientmodule.vala
+++ b/codegen/valagdbusclientmodule.vala
@@ -52,27 +52,25 @@ public class Vala.GDBusClientModule : GDBusModule {
 
 		generate_cparameters (method, cfile, cparam_map, func);
 
-		var block = new CCodeBlock ();
+		push_function (func);
+
 		if (dynamic_method.dynamic_type.data_type == dbus_proxy_type) {
-			generate_dbus_method_wrapper (method, block);
+			generate_dbus_method_wrapper (method);
 		} else {
 			Report.error (method.source_reference, "dynamic methods are not supported for `%s'".printf (dynamic_method.dynamic_type.to_string ()));
 		}
 
-		// append to C source file
-		cfile.add_function_declaration (func);
+		pop_function ();
 
-		func.block = block;
+		cfile.add_function_declaration (func);
 		cfile.add_function (func);
 	}
 
-	void generate_dbus_method_wrapper (Method m, CCodeBlock block) {
-		var cdecl = new CCodeDeclaration ("GVariant");
-		cdecl.add_declarator (new CCodeVariableDeclarator ("*_arguments"));
-		cdecl.add_declarator (new CCodeVariableDeclarator ("*_reply"));
-		block.add_statement (cdecl);
+	void generate_dbus_method_wrapper (Method m) {
+		ccode.add_declaration ("GVariant", new CCodeVariableDeclarator ("*_arguments"));
+		ccode.add_declaration ("GVariant", new CCodeVariableDeclarator ("*_reply"));
 
-		generate_marshalling (m, CallType.SYNC, null, m.name, block);
+		generate_marshalling (m, CallType.SYNC, null, m.name);
 	}
 
 	void generate_proxy_interface_init (Interface main_iface, Interface iface) {
@@ -269,29 +267,19 @@ public class Vala.GDBusClientModule : GDBusModule {
 	string generate_dbus_signal_handler (Signal sig, ObjectTypeSymbol sym) {
 		string wrapper_name = "_dbus_handle_%s_%s".printf (sym.get_lower_case_cname (), sig.get_cname ());
 
-		// declaration
-
-		CCodeDeclaration cdecl;
-
 		var function = new CCodeFunction (wrapper_name);
 		function.modifiers = CCodeModifiers.STATIC;
 		function.add_parameter (new CCodeFormalParameter ("self", sym.get_cname () + "*"));
 		function.add_parameter (new CCodeFormalParameter ("parameters", "GVariant*"));
-		var block = new CCodeBlock ();
-
-		var prefragment = new CCodeFragment ();
-		var postfragment = new CCodeFragment ();
 
-		block.add_statement (prefragment);
+		push_function (function);
 
-		cdecl = new CCodeDeclaration ("GVariantIter");
-		cdecl.add_declarator (new CCodeVariableDeclarator ("_arguments_iter"));
-		block.add_statement (cdecl);
+		ccode.add_declaration ("GVariantIter", new CCodeVariableDeclarator ("_arguments_iter"));
 
 		var iter_init = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_iter_init"));
 		iter_init.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_arguments_iter")));
 		iter_init.add_argument (new CCodeIdentifier ("parameters"));
-		prefragment.append (new CCodeExpressionStatement (iter_init));
+		ccode.add_expression (iter_init);
 
 		var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_signal_emit_by_name"));
 		ccall.add_argument (new CCodeIdentifier ("self"));
@@ -301,9 +289,7 @@ public class Vala.GDBusClientModule : GDBusModule {
 			var owned_type = param.variable_type.copy ();
 			owned_type.value_owned = true;
 
-			cdecl = new CCodeDeclaration (owned_type.get_cname ());
-			cdecl.add_declarator (new CCodeVariableDeclarator.zero (param.name, default_value_for_type (param.variable_type, true)));
-			prefragment.append (cdecl);
+			ccode.add_declaration (owned_type.get_cname (), new CCodeVariableDeclarator.zero (param.name, default_value_for_type (param.variable_type, true)));
 
 			var st = param.variable_type.data_type as Struct;
 			if (st != null && !st.is_simple_type ()) {
@@ -318,32 +304,32 @@ public class Vala.GDBusClientModule : GDBusModule {
 				for (int dim = 1; dim <= array_type.rank; dim++) {
 					string length_cname = get_parameter_array_length_cname (param, dim);
 
-					cdecl = new CCodeDeclaration ("int");
-					cdecl.add_declarator (new CCodeVariableDeclarator (length_cname, new CCodeConstant ("0")));
-					prefragment.append (cdecl);
+					ccode.add_declaration ("int", new CCodeVariableDeclarator (length_cname, new CCodeConstant ("0")));
 					ccall.add_argument (new CCodeIdentifier (length_cname));
 				}
 			}
 
-			read_expression (prefragment, param.variable_type, new CCodeIdentifier ("_arguments_iter"), new CCodeIdentifier (param.name), param);
+			read_expression (param.variable_type, new CCodeIdentifier ("_arguments_iter"), new CCodeIdentifier (param.name), param);
+		}
+
+		ccode.add_expression (ccall);
+
+		foreach (FormalParameter param in sig.get_parameters ()) {
+			var owned_type = param.variable_type.copy ();
+			owned_type.value_owned = true;
 
 			if (requires_destroy (owned_type)) {
 				// keep local alive (symbol_reference is weak)
 				var local = new LocalVariable (owned_type, param.name);
 				var ma = new MemberAccess.simple (param.name);
 				ma.symbol_reference = local;
-				var stmt = new CCodeExpressionStatement (get_unref_expression (new CCodeIdentifier (param.name), owned_type, ma));
-				postfragment.append (stmt);
+				ccode.add_expression (get_unref_expression (new CCodeIdentifier (param.name), owned_type, ma));
 			}
 		}
 
-		block.add_statement (new CCodeExpressionStatement (ccall));
-
-		block.add_statement (postfragment);
+		pop_function ();
 
 		cfile.add_function_declaration (function);
-
-		function.block = block;
 		cfile.add_function (function);
 
 		return wrapper_name;
@@ -395,20 +381,14 @@ public class Vala.GDBusClientModule : GDBusModule {
 		cfile.add_function (cfunc);
 	}
 
-	void generate_marshalling (Method m, CallType call_type, string? iface_name, string? method_name, CCodeBlock block) {
-		CCodeDeclaration cdecl;
-
+	void generate_marshalling (Method m, CallType call_type, string? iface_name, string? method_name) {
 		if (call_type != CallType.FINISH) {
-			var prefragment = new CCodeFragment ();
-
-			cdecl = new CCodeDeclaration ("GVariantBuilder");
-			cdecl.add_declarator (new CCodeVariableDeclarator ("_arguments_builder"));
-			prefragment.append (cdecl);
+			ccode.add_declaration ("GVariantBuilder", new CCodeVariableDeclarator ("_arguments_builder"));
 
 			var builder_init = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_builder_init"));
 			builder_init.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_arguments_builder")));
 			builder_init.add_argument (new CCodeIdentifier ("G_VARIANT_TYPE_TUPLE"));
-			prefragment.append (new CCodeExpressionStatement (builder_init));
+			ccode.add_expression (builder_init);
 
 			foreach (FormalParameter param in m.get_parameters ()) {
 				if (param.direction == ParameterDirection.IN) {
@@ -416,15 +396,13 @@ public class Vala.GDBusClientModule : GDBusModule {
 					if (param.variable_type.is_real_struct_type ()) {
 						expr = new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, expr);
 					}
-					write_expression (prefragment, param.variable_type, new CCodeIdentifier ("_arguments_builder"), expr, param);
+					write_expression (param.variable_type, new CCodeIdentifier ("_arguments_builder"), expr, param);
 				}
 			}
 
 			var builder_end = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_builder_end"));
 			builder_end.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_arguments_builder")));
-			prefragment.append (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("_arguments"), builder_end)));
-
-			block.add_statement (prefragment);
+			ccode.add_expression (new CCodeAssignment (new CCodeIdentifier ("_arguments"), builder_end));
 		}
 
 		if (call_type == CallType.SYNC) {
@@ -436,20 +414,9 @@ public class Vala.GDBusClientModule : GDBusModule {
 			ccall.add_argument (get_dbus_timeout (m));
 			ccall.add_argument (new CCodeConstant ("NULL"));
 			ccall.add_argument (new CCodeConstant ("error"));
-			block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("_reply"), ccall)));
-
-			// return on error
-			var error_block = new CCodeBlock ();
-			if (m.return_type is VoidType || m.return_type.is_real_non_null_struct_type ()) {
-				error_block.add_statement (new CCodeReturnStatement ());
-			} else {
-				error_block.add_statement (new CCodeReturnStatement (default_value_for_type (m.return_type, false)));
-			}
-			block.add_statement (new CCodeIfStatement (new CCodeUnaryExpression (CCodeUnaryOperator.LOGICAL_NEGATION, new CCodeIdentifier ("_reply")), error_block));
+			ccode.add_expression (new CCodeAssignment (new CCodeIdentifier ("_reply"), ccall));
 		} else if (call_type == CallType.NO_REPLY) {
-			cdecl = new CCodeDeclaration ("GDBusMessage");
-			cdecl.add_declarator (new CCodeVariableDeclarator ("*_message"));
-			block.add_statement (cdecl);
+			ccode.add_declaration ("GDBusMessage", new CCodeVariableDeclarator ("*_message"));
 
 			var connection = new CCodeFunctionCall (new CCodeIdentifier ("g_dbus_proxy_get_connection"));
 			connection.add_argument (new CCodeIdentifier ("self"));
@@ -465,17 +432,17 @@ public class Vala.GDBusClientModule : GDBusModule {
 			ccall.add_argument (object_path);
 			ccall.add_argument (new CCodeConstant ("\"%s\"".printf (iface_name)));
 			ccall.add_argument (new CCodeConstant ("\"%s\"".printf (get_dbus_name_for_member (m))));
-			block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("_message"), ccall)));
+			ccode.add_expression (new CCodeAssignment (new CCodeIdentifier ("_message"), ccall));
 
 			var set_flags = new CCodeFunctionCall (new CCodeIdentifier ("g_dbus_message_set_flags"));
 			set_flags.add_argument (new CCodeIdentifier ("_message"));
 			set_flags.add_argument (new CCodeConstant ("G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED"));
-			block.add_statement (new CCodeExpressionStatement (set_flags));
+			ccode.add_expression (set_flags);
 
 			var set_body = new CCodeFunctionCall (new CCodeIdentifier ("g_dbus_message_set_body"));
 			set_body.add_argument (new CCodeIdentifier ("_message"));
 			set_body.add_argument (new CCodeIdentifier ("_arguments"));
-			block.add_statement (new CCodeExpressionStatement (set_body));
+			ccode.add_expression (set_body);
 
 			ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_dbus_connection_send_message"));
 			ccall.add_argument (connection);
@@ -483,11 +450,11 @@ public class Vala.GDBusClientModule : GDBusModule {
 			ccall.add_argument (new CCodeConstant ("0"));
 			ccall.add_argument (new CCodeConstant ("NULL"));
 			ccall.add_argument (new CCodeIdentifier ("error"));
-			block.add_statement (new CCodeExpressionStatement (ccall));
+			ccode.add_expression (ccall);
 
 			ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_object_unref"));
 			ccall.add_argument (new CCodeIdentifier ("_message"));
-			block.add_statement (new CCodeExpressionStatement (ccall));
+			ccode.add_expression (ccall);
 		} else if (call_type == CallType.ASYNC) {
 			var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_dbus_proxy_call"));
 			ccall.add_argument (new CCodeCastExpression (new CCodeIdentifier ("self"), "GDBusProxy *"));
@@ -498,63 +465,55 @@ public class Vala.GDBusClientModule : GDBusModule {
 			ccall.add_argument (new CCodeConstant ("NULL"));
 			ccall.add_argument (new CCodeIdentifier ("_callback_"));
 			ccall.add_argument (new CCodeIdentifier ("_user_data_"));
-			block.add_statement (new CCodeExpressionStatement (ccall));
+			ccode.add_expression (ccall);
 		} else if (call_type == CallType.FINISH) {
 			var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_dbus_proxy_call_finish"));
 			ccall.add_argument (new CCodeCastExpression (new CCodeIdentifier ("self"), "GDBusProxy *"));
 			ccall.add_argument (new CCodeIdentifier ("_res_"));
 			ccall.add_argument (new CCodeConstant ("error"));
-			block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("_reply"), ccall)));
+			ccode.add_expression (new CCodeAssignment (new CCodeIdentifier ("_reply"), ccall));
+		}
 
+		if (call_type == CallType.SYNC || call_type == CallType.FINISH) {
 			// return on error
-			var error_block = new CCodeBlock ();
+			ccode.open_if (new CCodeUnaryExpression (CCodeUnaryOperator.LOGICAL_NEGATION, new CCodeIdentifier ("_reply")));
 			if (m.return_type is VoidType || m.return_type.is_real_non_null_struct_type ()) {
-				error_block.add_statement (new CCodeReturnStatement ());
+				ccode.add_return ();
 			} else {
-				error_block.add_statement (new CCodeReturnStatement (default_value_for_type (m.return_type, false)));
+				ccode.add_return (default_value_for_type (m.return_type, false));
 			}
-			block.add_statement (new CCodeIfStatement (new CCodeUnaryExpression (CCodeUnaryOperator.LOGICAL_NEGATION, new CCodeIdentifier ("_reply")), error_block));
-		}
+			ccode.close ();
 
-		if (call_type == CallType.SYNC || call_type == CallType.FINISH) {
-			var postfragment = new CCodeFragment ();
-
-			cdecl = new CCodeDeclaration ("GVariantIter");
-			cdecl.add_declarator (new CCodeVariableDeclarator ("_reply_iter"));
-			postfragment.append (cdecl);
+			ccode.add_declaration ("GVariantIter", new CCodeVariableDeclarator ("_reply_iter"));
 
 			var iter_init = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_iter_init"));
 			iter_init.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_reply_iter")));
 			iter_init.add_argument (new CCodeIdentifier ("_reply"));
-			postfragment.append (new CCodeExpressionStatement (iter_init));
+			ccode.add_expression (iter_init);
 
 			foreach (FormalParameter param in m.get_parameters ()) {
 				if (param.direction == ParameterDirection.OUT) {
-					cdecl = new CCodeDeclaration (param.variable_type.get_cname ());
-					cdecl.add_declarator (new CCodeVariableDeclarator ("_" + param.name));
-					postfragment.append (cdecl);
+					ccode.add_declaration (param.variable_type.get_cname (), new CCodeVariableDeclarator ("_" + param.name));
 
 					var array_type = param.variable_type as ArrayType;
 
 					if (array_type != null) {
 						for (int dim = 1; dim <= array_type.rank; dim++) {
-							cdecl = new CCodeDeclaration ("int");
-							cdecl.add_declarator (new CCodeVariableDeclarator ("_%s_length%d".printf (param.name, dim), new CCodeConstant ("0")));
-							postfragment.append (cdecl);
+							ccode.add_declaration ("int", new CCodeVariableDeclarator ("_%s_length%d".printf (param.name, dim), new CCodeConstant ("0")));
 						}
 					}
 
 					var target = new CCodeIdentifier ("_" + param.name);
-					read_expression (postfragment, param.variable_type, new CCodeIdentifier ("_reply_iter"), target, param);
+					read_expression (param.variable_type, new CCodeIdentifier ("_reply_iter"), target, param);
 
 					// TODO check that parameter is not NULL (out parameters are optional)
 					// free value if parameter is NULL
-					postfragment.append (new CCodeExpressionStatement (new CCodeAssignment (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier (param.name)), target)));
+					ccode.add_expression (new CCodeAssignment (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier (param.name)), target));
 
 					if (array_type != null) {
 						for (int dim = 1; dim <= array_type.rank; dim++) {
 							// TODO check that parameter is not NULL (out parameters are optional)
-							postfragment.append (new CCodeExpressionStatement (new CCodeAssignment (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier ("%s_length%d".printf (param.name, dim))), new CCodeIdentifier ("_%s_length%d".printf (param.name, dim)))));
+							ccode.add_expression (new CCodeAssignment (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier ("%s_length%d".printf (param.name, dim))), new CCodeIdentifier ("_%s_length%d".printf (param.name, dim))));
 						}
 					}
 				}
@@ -563,41 +522,35 @@ public class Vala.GDBusClientModule : GDBusModule {
 			if (!(m.return_type is VoidType)) {
 				if (m.return_type.is_real_non_null_struct_type ()) {
 					var target = new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier ("result"));
-					read_expression (postfragment, m.return_type, new CCodeIdentifier ("_reply_iter"), target, m);
+					read_expression (m.return_type, new CCodeIdentifier ("_reply_iter"), target, m);
 				} else {
-					cdecl = new CCodeDeclaration (m.return_type.get_cname ());
-					cdecl.add_declarator (new CCodeVariableDeclarator ("_result"));
-					postfragment.append (cdecl);
+					ccode.add_declaration (m.return_type.get_cname (), new CCodeVariableDeclarator ("_result"));
 
 					var array_type = m.return_type as ArrayType;
 
 					if (array_type != null) {
 						for (int dim = 1; dim <= array_type.rank; dim++) {
-							cdecl = new CCodeDeclaration ("int");
-							cdecl.add_declarator (new CCodeVariableDeclarator ("_result_length%d".printf (dim), new CCodeConstant ("0")));
-							postfragment.append (cdecl);
+							ccode.add_declaration ("int", new CCodeVariableDeclarator ("_result_length%d".printf (dim), new CCodeConstant ("0")));
 						}
 					}
 
-					read_expression (postfragment, m.return_type, new CCodeIdentifier ("_reply_iter"), new CCodeIdentifier ("_result"), m);
+					read_expression (m.return_type, new CCodeIdentifier ("_reply_iter"), new CCodeIdentifier ("_result"), m);
 
 					if (array_type != null) {
 						for (int dim = 1; dim <= array_type.rank; dim++) {
 							// TODO check that parameter is not NULL (out parameters are optional)
-							postfragment.append (new CCodeExpressionStatement (new CCodeAssignment (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier ("result_length%d".printf (dim))), new CCodeIdentifier ("_result_length%d".printf (dim)))));
+							ccode.add_expression (new CCodeAssignment (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier ("result_length%d".printf (dim))), new CCodeIdentifier ("_result_length%d".printf (dim))));
 						}
 					}
 				}
 			}
 
-			block.add_statement (postfragment);
-
 			var unref_reply = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_unref"));
 			unref_reply.add_argument (new CCodeIdentifier ("_reply"));
-			block.add_statement (new CCodeExpressionStatement (unref_reply));
+			ccode.add_expression (unref_reply);
 
 			if (!(m.return_type is VoidType || m.return_type.is_real_non_null_struct_type ())) {
-				block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("_result")));
+				ccode.add_return (new CCodeIdentifier ("_result"));
 			}
 		}
 	}
@@ -609,8 +562,6 @@ public class Vala.GDBusClientModule : GDBusModule {
 
 		bool no_reply = is_dbus_no_reply (m);
 
-		CCodeDeclaration cdecl;
-
 		var function = new CCodeFunction (proxy_name);
 		function.modifiers = CCodeModifiers.STATIC;
 
@@ -618,19 +569,18 @@ public class Vala.GDBusClientModule : GDBusModule {
 
 		generate_cparameters (m, cfile, cparam_map, function);
 
-		var block = new CCodeBlock ();
+		push_function (function);
 
-		cdecl = new CCodeDeclaration ("GVariant");
-		cdecl.add_declarator (new CCodeVariableDeclarator ("*_arguments"));
+		ccode.add_declaration ("GVariant", new CCodeVariableDeclarator ("*_arguments"));
 		if (!no_reply) {
-			cdecl.add_declarator (new CCodeVariableDeclarator ("*_reply"));
+			ccode.add_declaration ("GVariant", new CCodeVariableDeclarator ("*_reply"));
 		}
-		block.add_statement (cdecl);
 
-		generate_marshalling (m, no_reply ? CallType.NO_REPLY : CallType.SYNC, dbus_iface_name, "%s.%s".printf (dbus_iface_name, get_dbus_name_for_member (m)), block);
+		generate_marshalling (m, no_reply ? CallType.NO_REPLY : CallType.SYNC, dbus_iface_name, "%s.%s".printf (dbus_iface_name, get_dbus_name_for_member (m)));
+
+		pop_function ();
 
 		cfile.add_function_declaration (function);
-		function.block = block;
 		cfile.add_function (function);
 
 		return proxy_name;
@@ -641,8 +591,6 @@ public class Vala.GDBusClientModule : GDBusModule {
 
 		string dbus_iface_name = get_dbus_name (iface);
 
-		CCodeDeclaration cdecl;
-
 		var function = new CCodeFunction (proxy_name, "void");
 		function.modifiers = CCodeModifiers.STATIC;
 
@@ -653,16 +601,15 @@ public class Vala.GDBusClientModule : GDBusModule {
 
 		generate_cparameters (m, cfile, cparam_map, function, null, null, null, 1);
 
-		var block = new CCodeBlock ();
+		push_function (function);
 
-		cdecl = new CCodeDeclaration ("GVariant");
-		cdecl.add_declarator (new CCodeVariableDeclarator ("*_arguments"));
-		block.add_statement (cdecl);
+		ccode.add_declaration ("GVariant", new CCodeVariableDeclarator ("*_arguments"));
 
-		generate_marshalling (m, CallType.ASYNC, dbus_iface_name, "%s.%s".printf (dbus_iface_name, get_dbus_name_for_member (m)), block);
+		generate_marshalling (m, CallType.ASYNC, dbus_iface_name, "%s.%s".printf (dbus_iface_name, get_dbus_name_for_member (m)));
+
+		pop_function ();
 
 		cfile.add_function_declaration (function);
-		function.block = block;
 		cfile.add_function (function);
 
 		return proxy_name;
@@ -671,8 +618,6 @@ public class Vala.GDBusClientModule : GDBusModule {
 	string generate_finish_dbus_proxy_method (Interface main_iface, Interface iface, Method m) {
 		string proxy_name = "%sproxy_%s_finish".printf (main_iface.get_lower_case_cprefix (), m.name);
 
-		CCodeDeclaration cdecl;
-
 		var function = new CCodeFunction (proxy_name);
 		function.modifiers = CCodeModifiers.STATIC;
 
@@ -682,16 +627,15 @@ public class Vala.GDBusClientModule : GDBusModule {
 
 		generate_cparameters (m, cfile, cparam_map, function, null, null, null, 2);
 
-		var block = new CCodeBlock ();
+		push_function (function);
 
-		cdecl = new CCodeDeclaration ("GVariant");
-		cdecl.add_declarator (new CCodeVariableDeclarator ("*_reply"));
-		block.add_statement (cdecl);
+		ccode.add_declaration ("GVariant", new CCodeVariableDeclarator ("*_reply"));
 
-		generate_marshalling (m, CallType.FINISH, null, null, block);
+		generate_marshalling (m, CallType.FINISH, null, null);
+
+		pop_function ();
 
 		cfile.add_function_declaration (function);
-		function.block = block;
 		cfile.add_function (function);
 
 		return proxy_name;
@@ -710,8 +654,6 @@ public class Vala.GDBusClientModule : GDBusModule {
 
 		var array_type = prop.get_accessor.value_type as ArrayType;
 
-		CCodeDeclaration cdecl;
-
 		var function = new CCodeFunction (proxy_name);
 		function.modifiers = CCodeModifiers.STATIC;
 
@@ -729,110 +671,95 @@ public class Vala.GDBusClientModule : GDBusModule {
 			function.return_type = prop.get_accessor.value_type.get_cname ();
 		}
 
-		var block = new CCodeBlock ();
-		var prefragment = new CCodeFragment ();
-		var postfragment = new CCodeFragment ();
-
-		cdecl = new CCodeDeclaration ("GVariant");
-		cdecl.add_declarator (new CCodeVariableDeclarator ("*_arguments"));
-		cdecl.add_declarator (new CCodeVariableDeclarator ("*_reply"));
-		cdecl.add_declarator (new CCodeVariableDeclarator ("*_inner_reply"));
-		block.add_statement (cdecl);
+		push_function (function);
 
-		block.add_statement (prefragment);
+		ccode.add_declaration ("GVariant", new CCodeVariableDeclarator ("*_arguments"));
+		ccode.add_declaration ("GVariant", new CCodeVariableDeclarator ("*_reply"));
+		ccode.add_declaration ("GVariant", new CCodeVariableDeclarator ("*_inner_reply"));
 
-		cdecl = new CCodeDeclaration ("GVariantBuilder");
-		cdecl.add_declarator (new CCodeVariableDeclarator ("_arguments_builder"));
-		prefragment.append (cdecl);
+		ccode.add_declaration ("GVariantBuilder", new CCodeVariableDeclarator ("_arguments_builder"));
 
 		var builder_init = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_builder_init"));
 		builder_init.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_arguments_builder")));
 		builder_init.add_argument (new CCodeIdentifier ("G_VARIANT_TYPE_TUPLE"));
-		prefragment.append (new CCodeExpressionStatement (builder_init));
+		ccode.add_expression (builder_init);
 
 		// interface name
-		write_expression (prefragment, string_type, new CCodeIdentifier ("_arguments_builder"), new CCodeConstant ("\"%s\"".printf (dbus_iface_name)), null);
+		write_expression (string_type, new CCodeIdentifier ("_arguments_builder"), new CCodeConstant ("\"%s\"".printf (dbus_iface_name)), null);
 		// property name
-		write_expression (prefragment, string_type, new CCodeIdentifier ("_arguments_builder"), new CCodeConstant ("\"%s\"".printf (get_dbus_name_for_member (prop))), null);
+		write_expression (string_type, new CCodeIdentifier ("_arguments_builder"), new CCodeConstant ("\"%s\"".printf (get_dbus_name_for_member (prop))), null);
 
 		var builder_end = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_builder_end"));
 		builder_end.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_arguments_builder")));
-		prefragment.append (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("_arguments"), builder_end)));
+		ccode.add_expression (new CCodeAssignment (new CCodeIdentifier ("_arguments"), builder_end));
+
+		var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_dbus_proxy_call_sync"));
+		ccall.add_argument (new CCodeCastExpression (new CCodeIdentifier ("self"), "GDBusProxy *"));
+		ccall.add_argument (new CCodeConstant ("\"org.freedesktop.DBus.Properties.Get\""));
+		ccall.add_argument (new CCodeIdentifier ("_arguments"));
+		ccall.add_argument (new CCodeConstant ("G_DBUS_CALL_FLAGS_NONE"));
+		ccall.add_argument (get_dbus_timeout (prop));
+		ccall.add_argument (new CCodeConstant ("NULL"));
+		ccall.add_argument (new CCodeConstant ("NULL"));
+
+		ccode.add_expression (new CCodeAssignment (new CCodeIdentifier ("_reply"), ccall));
+
+		// return on error
+		ccode.open_if (new CCodeUnaryExpression (CCodeUnaryOperator.LOGICAL_NEGATION, new CCodeIdentifier ("_reply")));
+		if (prop.property_type.is_real_non_null_struct_type ()) {
+			ccode.add_return ();
+		} else {
+			ccode.add_return (default_value_for_type (prop.property_type, false));
+		}
+		ccode.close ();
 
-		cdecl = new CCodeDeclaration ("GVariantIter");
-		cdecl.add_declarator (new CCodeVariableDeclarator ("_reply_iter"));
-		postfragment.append (cdecl);
+		ccode.add_declaration ("GVariantIter", new CCodeVariableDeclarator ("_reply_iter"));
 
 		var get_variant = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_get_child_value"));
 		get_variant.add_argument (new CCodeIdentifier ("_reply"));
 		get_variant.add_argument (new CCodeConstant ("0"));
-		postfragment.append (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("_inner_reply"), get_variant)));
+		ccode.add_expression (new CCodeAssignment (new CCodeIdentifier ("_inner_reply"), get_variant));
 
 		var iter_init = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_iter_init"));
 		iter_init.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_reply_iter")));
 		iter_init.add_argument (new CCodeIdentifier ("_inner_reply"));
-		postfragment.append (new CCodeExpressionStatement (iter_init));
+		ccode.add_expression (iter_init);
 
 		if (prop.property_type.is_real_non_null_struct_type ()) {
 			var target = new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier ("result"));
-			read_expression (postfragment, prop.get_accessor.value_type, new CCodeIdentifier ("_reply_iter"), target, prop);
+			read_expression (prop.get_accessor.value_type, new CCodeIdentifier ("_reply_iter"), target, prop);
 		} else {
-			cdecl = new CCodeDeclaration (prop.get_accessor.value_type.get_cname ());
-			cdecl.add_declarator (new CCodeVariableDeclarator ("_result"));
-			postfragment.append (cdecl);
+			ccode.add_declaration (prop.get_accessor.value_type.get_cname (), new CCodeVariableDeclarator ("_result"));
 
 			if (array_type != null) {
 				for (int dim = 1; dim <= array_type.rank; dim++) {
-					cdecl = new CCodeDeclaration ("int");
-					cdecl.add_declarator (new CCodeVariableDeclarator ("_result_length%d".printf (dim), new CCodeConstant ("0")));
-					postfragment.append (cdecl);
+					ccode.add_declaration ("int", new CCodeVariableDeclarator ("_result_length%d".printf (dim), new CCodeConstant ("0")));
 				}
 			}
 
-			read_expression (postfragment, prop.get_accessor.value_type, new CCodeIdentifier ("_reply_iter"), new CCodeIdentifier ("_result"), prop);
+			read_expression (prop.get_accessor.value_type, new CCodeIdentifier ("_reply_iter"), new CCodeIdentifier ("_result"), prop);
 
 			if (array_type != null) {
 				for (int dim = 1; dim <= array_type.rank; dim++) {
 					// TODO check that parameter is not NULL (out parameters are optional)
-					postfragment.append (new CCodeExpressionStatement (new CCodeAssignment (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier ("result_length%d".printf (dim))), new CCodeIdentifier ("_result_length%d".printf (dim)))));
+					ccode.add_expression (new CCodeAssignment (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier ("result_length%d".printf (dim))), new CCodeIdentifier ("_result_length%d".printf (dim))));
 				}
 			}
 		}
 
-		var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_dbus_proxy_call_sync"));
-		ccall.add_argument (new CCodeCastExpression (new CCodeIdentifier ("self"), "GDBusProxy *"));
-		ccall.add_argument (new CCodeConstant ("\"org.freedesktop.DBus.Properties.Get\""));
-		ccall.add_argument (new CCodeIdentifier ("_arguments"));
-		ccall.add_argument (new CCodeConstant ("G_DBUS_CALL_FLAGS_NONE"));
-		ccall.add_argument (get_dbus_timeout (prop));
-		ccall.add_argument (new CCodeConstant ("NULL"));
-		ccall.add_argument (new CCodeConstant ("NULL"));
-
-		block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("_reply"), ccall)));
-
-		// return on error
-		var error_block = new CCodeBlock ();
-		if (prop.property_type.is_real_non_null_struct_type ()) {
-			error_block.add_statement (new CCodeReturnStatement ());
-		} else {
-			error_block.add_statement (new CCodeReturnStatement (default_value_for_type (prop.property_type, false)));
-		}
-		block.add_statement (new CCodeIfStatement (new CCodeUnaryExpression (CCodeUnaryOperator.LOGICAL_NEGATION, new CCodeIdentifier ("_reply")), error_block));
-
-		block.add_statement (postfragment);
-
 		var unref_reply = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_unref"));
 		unref_reply.add_argument (new CCodeIdentifier ("_reply"));
-		block.add_statement (new CCodeExpressionStatement (unref_reply));
+		ccode.add_expression (unref_reply);
 
 		if (prop.property_type.is_real_non_null_struct_type ()) {
-			block.add_statement (new CCodeReturnStatement ());
+			ccode.add_return ();
 		} else {
-			block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("_result")));
+			ccode.add_return (new CCodeIdentifier ("_result"));
 		}
 
+		pop_function ();
+
 		cfile.add_function_declaration (function);
-		function.block = block;
 		cfile.add_function (function);
 
 		return proxy_name;
@@ -845,8 +772,6 @@ public class Vala.GDBusClientModule : GDBusModule {
 
 		var array_type = prop.set_accessor.value_type as ArrayType;
 
-		CCodeDeclaration cdecl;
-
 		var function = new CCodeFunction (proxy_name);
 		function.modifiers = CCodeModifiers.STATIC;
 
@@ -864,50 +789,42 @@ public class Vala.GDBusClientModule : GDBusModule {
 			}
 		}
 
-		var block = new CCodeBlock ();
-		var prefragment = new CCodeFragment ();
-		var postfragment = new CCodeFragment ();
-
-		cdecl = new CCodeDeclaration ("GVariant");
-		cdecl.add_declarator (new CCodeVariableDeclarator ("*_arguments"));
-		cdecl.add_declarator (new CCodeVariableDeclarator ("*_reply"));
-		block.add_statement (cdecl);
+		push_function (function);
 
-		block.add_statement (prefragment);
+		ccode.add_declaration ("GVariant", new CCodeVariableDeclarator ("*_arguments"));
+		ccode.add_declaration ("GVariant", new CCodeVariableDeclarator ("*_reply"));
 
-		cdecl = new CCodeDeclaration ("GVariantBuilder");
-		cdecl.add_declarator (new CCodeVariableDeclarator ("_arguments_builder"));
-		prefragment.append (cdecl);
+		ccode.add_declaration ("GVariantBuilder", new CCodeVariableDeclarator ("_arguments_builder"));
 
 		var builder_init = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_builder_init"));
 		builder_init.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_arguments_builder")));
 		builder_init.add_argument (new CCodeIdentifier ("G_VARIANT_TYPE_TUPLE"));
-		prefragment.append (new CCodeExpressionStatement (builder_init));
+		ccode.add_expression (builder_init);
 
 		// interface name
-		write_expression (prefragment, string_type, new CCodeIdentifier ("_arguments_builder"), new CCodeConstant ("\"%s\"".printf (dbus_iface_name)), null);
+		write_expression (string_type, new CCodeIdentifier ("_arguments_builder"), new CCodeConstant ("\"%s\"".printf (dbus_iface_name)), null);
 		// property name
-		write_expression (prefragment, string_type, new CCodeIdentifier ("_arguments_builder"), new CCodeConstant ("\"%s\"".printf (get_dbus_name_for_member (prop))), null);
+		write_expression (string_type, new CCodeIdentifier ("_arguments_builder"), new CCodeConstant ("\"%s\"".printf (get_dbus_name_for_member (prop))), null);
 
 		// property value (as variant)
 		var builder_open = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_builder_open"));
 		builder_open.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_arguments_builder")));
 		builder_open.add_argument (new CCodeIdentifier ("G_VARIANT_TYPE_VARIANT"));
-		prefragment.append (new CCodeExpressionStatement (builder_open));
+		ccode.add_expression (builder_open);
 
 		if (prop.property_type.is_real_non_null_struct_type ()) {
-			write_expression (prefragment, prop.set_accessor.value_type, new CCodeIdentifier ("_arguments_builder"), new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier ("value")), prop);
+			write_expression (prop.set_accessor.value_type, new CCodeIdentifier ("_arguments_builder"), new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier ("value")), prop);
 		} else {
-			write_expression (prefragment, prop.set_accessor.value_type, new CCodeIdentifier ("_arguments_builder"), new CCodeIdentifier ("value"), prop);
+			write_expression (prop.set_accessor.value_type, new CCodeIdentifier ("_arguments_builder"), new CCodeIdentifier ("value"), prop);
 		}
 
 		var builder_close = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_builder_close"));
 		builder_close.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_arguments_builder")));
-		prefragment.append (new CCodeExpressionStatement (builder_close));
+		ccode.add_expression (builder_close);
 
 		var builder_end = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_builder_end"));
 		builder_end.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_arguments_builder")));
-		prefragment.append (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("_arguments"), builder_end)));
+		ccode.add_expression (new CCodeAssignment (new CCodeIdentifier ("_arguments"), builder_end));
 
 		var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_dbus_proxy_call_sync"));
 		ccall.add_argument (new CCodeCastExpression (new CCodeIdentifier ("self"), "GDBusProxy *"));
@@ -918,21 +835,20 @@ public class Vala.GDBusClientModule : GDBusModule {
 		ccall.add_argument (new CCodeConstant ("NULL"));
 		ccall.add_argument (new CCodeConstant ("NULL"));
 
-		block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("_reply"), ccall)));
+		ccode.add_expression (new CCodeAssignment (new CCodeIdentifier ("_reply"), ccall));
 
 		// return on error
-		var error_block = new CCodeBlock ();
-		error_block.add_statement (new CCodeReturnStatement ());
-		block.add_statement (new CCodeIfStatement (new CCodeUnaryExpression (CCodeUnaryOperator.LOGICAL_NEGATION, new CCodeIdentifier ("_reply")), error_block));
-
-		block.add_statement (postfragment);
+		ccode.open_if (new CCodeUnaryExpression (CCodeUnaryOperator.LOGICAL_NEGATION, new CCodeIdentifier ("_reply")));
+		ccode.add_return ();
+		ccode.close ();
 
 		var unref_reply = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_unref"));
 		unref_reply.add_argument (new CCodeIdentifier ("_reply"));
-		block.add_statement (new CCodeExpressionStatement (unref_reply));
+		ccode.add_expression (unref_reply);
+
+		pop_function ();
 
 		cfile.add_function_declaration (function);
-		function.block = block;
 		cfile.add_function (function);
 
 		return proxy_name;
diff --git a/codegen/valagdbusservermodule.vala b/codegen/valagdbusservermodule.vala
index abe9ed1..bf5fe2c 100644
--- a/codegen/valagdbusservermodule.vala
+++ b/codegen/valagdbusservermodule.vala
@@ -45,317 +45,283 @@ public class Vala.GDBusServerModule : GDBusClientModule {
 		return "result";
 	}
 
-	string generate_dbus_wrapper (Method m, ObjectTypeSymbol sym) {
+	string generate_dbus_wrapper (Method m, ObjectTypeSymbol sym, bool ready = false) {
 		string wrapper_name = "_dbus_%s".printf (m.get_cname ());
 
-		// declaration
-
-		CCodeDeclaration cdecl;
+		if (ready) {
+			// async ready function
+			wrapper_name += "_ready";
+		}
 
 		var function = new CCodeFunction (wrapper_name);
 		function.modifiers = CCodeModifiers.STATIC;
-		function.add_parameter (new CCodeFormalParameter ("self", sym.get_cname () + "*"));
-		function.add_parameter (new CCodeFormalParameter ("parameters", "GVariant*"));
-		function.add_parameter (new CCodeFormalParameter ("invocation", "GDBusMethodInvocation*"));
-		var block = new CCodeBlock ();
 
-		CCodeFunction ready_function = null;
-		CCodeBlock ready_block = null;
-		if (m.coroutine) {
-			// GAsyncResult
-			cfile.add_include ("gio/gio.h");
-
-			ready_function = new CCodeFunction (wrapper_name + "_ready", "void");
-			ready_function.modifiers = CCodeModifiers.STATIC;
-			ready_function.add_parameter (new CCodeFormalParameter ("source_object", "GObject *"));
-			ready_function.add_parameter (new CCodeFormalParameter ("_res_", "GAsyncResult *"));
-			ready_function.add_parameter (new CCodeFormalParameter ("_user_data_", "gpointer *"));
-			ready_block = new CCodeBlock ();
-
-			cdecl = new CCodeDeclaration ("GDBusMethodInvocation *");
-			cdecl.add_declarator (new CCodeVariableDeclarator ("invocation", new CCodeIdentifier ("_user_data_")));
-			ready_block.add_statement (cdecl);
+		if (!ready) {
+			function.add_parameter (new CCodeFormalParameter ("self", sym.get_cname () + "*"));
+			function.add_parameter (new CCodeFormalParameter ("parameters", "GVariant*"));
+			function.add_parameter (new CCodeFormalParameter ("invocation", "GDBusMethodInvocation*"));
+		} else {
+			function.add_parameter (new CCodeFormalParameter ("source_object", "GObject *"));
+			function.add_parameter (new CCodeFormalParameter ("_res_", "GAsyncResult *"));
+			function.add_parameter (new CCodeFormalParameter ("_user_data_", "gpointer *"));
+		}
+
+		push_function (function);
+
+		if (ready) {
+			ccode.add_declaration ("GDBusMethodInvocation *", new CCodeVariableDeclarator ("invocation", new CCodeIdentifier ("_user_data_")));
 		}
 
 		bool no_reply = is_dbus_no_reply (m);
 
-		var in_prefragment = new CCodeFragment ();
-		var in_postfragment = new CCodeFragment ();
-		var out_prefragment = in_prefragment;
-		var out_postfragment = in_postfragment;
-		if (m.coroutine) {
-			out_prefragment = new CCodeFragment ();
-			out_postfragment = new CCodeFragment ();
+		if (!m.coroutine || ready) {
+			ccode.add_declaration ("GError*", new CCodeVariableDeclarator ("error", new CCodeConstant ("NULL")));
 		}
 
-		cdecl = new CCodeDeclaration ("GError*");
-		cdecl.add_declarator (new CCodeVariableDeclarator ("error", new CCodeConstant ("NULL")));
-		if (m.coroutine) {
-			ready_block.add_statement (cdecl);
-		} else {
-			block.add_statement (cdecl);
-		}
+		ccode.add_declaration ("GVariantIter", new CCodeVariableDeclarator ("_arguments_iter"));
 
-		block.add_statement (in_prefragment);
-		if (m.coroutine) {
-			ready_block.add_statement (out_prefragment);
+		if (!ready) {
+			var iter_init = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_iter_init"));
+			iter_init.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_arguments_iter")));
+			iter_init.add_argument (new CCodeIdentifier ("parameters"));
+			ccode.add_expression (iter_init);
 		}
 
-		if (!no_reply) {
-			cdecl = new CCodeDeclaration ("GVariant*");
-			cdecl.add_declarator (new CCodeVariableDeclarator ("_reply"));
-			out_postfragment.append (cdecl);
+		CCodeFunctionCall ccall;
+		if (!ready) {
+			ccall = new CCodeFunctionCall (new CCodeIdentifier (m.get_cname ()));
+			ccall.add_argument (new CCodeIdentifier ("self"));
+		} else {
+			ccall = new CCodeFunctionCall (new CCodeIdentifier (m.get_finish_cname ()));
+			ccall.add_argument (new CCodeCastExpression (new CCodeIdentifier ("source_object"), sym.get_cname () + "*"));
+			ccall.add_argument (new CCodeIdentifier ("_res_"));
 		}
 
-		cdecl = new CCodeDeclaration ("GVariantIter");
-		cdecl.add_declarator (new CCodeVariableDeclarator ("_arguments_iter"));
-		block.add_statement (cdecl);
+		if (!ready) {
+			foreach (FormalParameter param in m.get_parameters ()) {
+				if (param.direction != ParameterDirection.IN) {
+					continue;
+				}
 
-		var iter_init = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_iter_init"));
-		iter_init.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_arguments_iter")));
-		iter_init.add_argument (new CCodeIdentifier ("parameters"));
-		in_prefragment.append (new CCodeExpressionStatement (iter_init));
+				var owned_type = param.variable_type.copy ();
+				owned_type.value_owned = true;
 
-		if (!no_reply) {
-			cdecl = new CCodeDeclaration ("GVariantBuilder");
-			cdecl.add_declarator (new CCodeVariableDeclarator ("_reply_builder"));
-			out_postfragment.append (cdecl);
+				ccode.add_declaration (owned_type.get_cname (), new CCodeVariableDeclarator.zero (param.name, default_value_for_type (param.variable_type, true)));
 
-			var builder_init = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_builder_init"));
-			builder_init.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_reply_builder")));
-			builder_init.add_argument (new CCodeIdentifier ("G_VARIANT_TYPE_TUPLE"));
-			out_postfragment.append (new CCodeExpressionStatement (builder_init));
-		}
+				var array_type = param.variable_type as ArrayType;
+				if (array_type != null) {
+					for (int dim = 1; dim <= array_type.rank; dim++) {
+						string length_cname = get_parameter_array_length_cname (param, dim);
 
-		var ccall = new CCodeFunctionCall (new CCodeIdentifier (m.get_cname ()));
+						ccode.add_declaration ("int", new CCodeVariableDeclarator.zero (length_cname, new CCodeConstant ("0")));
+					}
+				}
 
-		CCodeFunctionCall finish_ccall = null;
-		if (m.coroutine) {
-			finish_ccall = new CCodeFunctionCall (new CCodeIdentifier (m.get_finish_cname ()));
-			finish_ccall.add_argument (new CCodeCastExpression (new CCodeIdentifier ("source_object"), sym.get_cname () + "*"));
-			finish_ccall.add_argument (new CCodeIdentifier ("_res_"));
+				read_expression (param.variable_type, new CCodeIdentifier ("_arguments_iter"), new CCodeIdentifier (param.name), param);
+			}
 		}
 
-		ccall.add_argument (new CCodeIdentifier ("self"));
-
 		foreach (FormalParameter param in m.get_parameters ()) {
-			var owned_type = param.variable_type.copy ();
-			owned_type.value_owned = true;
-
-			cdecl = new CCodeDeclaration (owned_type.get_cname ());
-			cdecl.add_declarator (new CCodeVariableDeclarator.zero (param.name, default_value_for_type (param.variable_type, true)));
-			if (param.direction == ParameterDirection.IN) {
-				in_prefragment.append (cdecl);
-			} else {
-				out_prefragment.append (cdecl);
-			}
-
-			if (!m.coroutine || param.direction == ParameterDirection.IN) {
+			if (param.direction == ParameterDirection.IN && !ready) {
 				var st = param.variable_type.data_type as Struct;
-				if (param.direction != ParameterDirection.IN
-				    || (st != null && !st.is_simple_type ())) {
+				if (st != null && !st.is_simple_type ()) {
 					ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (param.name)));
 				} else {
 					ccall.add_argument (new CCodeIdentifier (param.name));
 				}
-			} else {
-				finish_ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (param.name)));
+			} else if (param.direction == ParameterDirection.OUT && (!m.coroutine || ready)) {
+				ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (param.name)));
 			}
 
-			if (param.variable_type is ArrayType) {
-				var array_type = (ArrayType) param.variable_type;
-
+			var array_type = param.variable_type as ArrayType;
+			if (array_type != null) {
 				for (int dim = 1; dim <= array_type.rank; dim++) {
 					string length_cname = get_parameter_array_length_cname (param, dim);
 
-					cdecl = new CCodeDeclaration ("int");
-					cdecl.add_declarator (new CCodeVariableDeclarator (length_cname, new CCodeConstant ("0")));
-					if (!m.coroutine || param.direction == ParameterDirection.IN) {
-						if (param.direction != ParameterDirection.IN) {
-							out_prefragment.append (cdecl);
-							ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (length_cname)));
-						} else {
-							in_prefragment.append (cdecl);
-							ccall.add_argument (new CCodeIdentifier (length_cname));
-						}
-					} else {
-						out_prefragment.append (cdecl);
-						finish_ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (length_cname)));
+					if (param.direction == ParameterDirection.IN && !ready) {
+						ccall.add_argument (new CCodeIdentifier (length_cname));
+					} else if (param.direction == ParameterDirection.OUT && !no_reply && (!m.coroutine || ready)) {
+						ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (length_cname)));
 					}
 				}
 			}
+		}
 
-			if (param.direction == ParameterDirection.IN) {
-				read_expression (in_prefragment, param.variable_type, new CCodeIdentifier ("_arguments_iter"), new CCodeIdentifier (param.name), param);
-			} else {
-				write_expression (out_postfragment, param.variable_type, new CCodeIdentifier ("_reply_builder"), new CCodeIdentifier (param.name), param);
-			}
-
-			if (requires_destroy (owned_type)) {
-				// keep local alive (symbol_reference is weak)
-				var local = new LocalVariable (owned_type, param.name);
-				var ma = new MemberAccess.simple (param.name);
-				ma.symbol_reference = local;
-				var stmt = new CCodeExpressionStatement (get_unref_expression (new CCodeIdentifier (param.name), owned_type, ma));
-				if (param.direction == ParameterDirection.IN) {
-					in_postfragment.append (stmt);
+		if (!m.coroutine || ready) {
+			if (!(m.return_type is VoidType)) {
+				if (m.return_type.is_real_non_null_struct_type ()) {
+					ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("result")));
 				} else {
-					out_postfragment.append (stmt);
+					var array_type = m.return_type as ArrayType;
+					if (array_type != null) {
+						for (int dim = 1; dim <= array_type.rank; dim++) {
+							string length_cname = get_array_length_cname ("result", dim);
+
+							ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (length_cname)));
+						}
+					}
 				}
 			}
 		}
 
-		if (!(m.return_type is VoidType)) {
-			if (m.return_type.is_real_non_null_struct_type ()) {
-				cdecl = new CCodeDeclaration (m.return_type.get_cname ());
-				cdecl.add_declarator (new CCodeVariableDeclarator.zero ("result", default_value_for_type (m.return_type, true)));
-				out_prefragment.append (cdecl);
+		if (m.coroutine && !ready) {
+			ccall.add_argument (new CCodeCastExpression (new CCodeIdentifier (wrapper_name + "_ready"), "GAsyncReadyCallback"));
 
-				if (!m.coroutine) {
-					ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("result")));
-				} else {
-					finish_ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("result")));
-				}
+			var ref_call = new CCodeFunctionCall (new CCodeIdentifier ("g_object_ref"));
+			ref_call.add_argument (new CCodeIdentifier ("invocation"));
 
-				write_expression (out_postfragment, m.return_type, new CCodeIdentifier ("_reply_builder"), new CCodeIdentifier ("result"), m);
+			ccall.add_argument (ref_call);
+		}
 
-				if (requires_destroy (m.return_type)) {
-					// keep local alive (symbol_reference is weak)
-					// space before `result' is work around to not trigger
-					// variable renaming, we really mean C identifier `result' here
-					var local = new LocalVariable (m.return_type, " result");
-					var ma = new MemberAccess.simple ("result");
-					ma.symbol_reference = local;
-					out_postfragment.append (new CCodeExpressionStatement (get_unref_expression (new CCodeIdentifier ("result"), m.return_type, ma)));
-				}
+		if (!m.coroutine || ready) {
+			if (m.get_error_types ().size > 0) {
+				ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("error")));
+			}
+		}
 
-				block.add_statement (new CCodeExpressionStatement (ccall));
-				if (m.coroutine) {
-					ready_block.add_statement (new CCodeExpressionStatement (finish_ccall));
-				}
+		if (!no_reply && (!m.coroutine || ready)) {
+			if (m.return_type is VoidType || m.return_type.is_real_non_null_struct_type ()) {
+				ccode.add_expression (ccall);
 			} else {
-				cdecl = new CCodeDeclaration (m.return_type.get_cname ());
-				cdecl.add_declarator (new CCodeVariableDeclarator ("result"));
-				out_prefragment.append (cdecl);
-				if (!m.coroutine) {
-					block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("result"), ccall)));
-				} else {
-					block.add_statement (new CCodeExpressionStatement (ccall));
-					ready_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("result"), finish_ccall)));
+				ccode.add_expression (new CCodeAssignment (new CCodeIdentifier ("result"), ccall));
+			}
+
+			if (m.get_error_types ().size > 0) {
+				ccode.open_if (new CCodeIdentifier ("error"));
+
+				var return_error = new CCodeFunctionCall (new CCodeIdentifier ("g_dbus_method_invocation_return_gerror"));
+				return_error.add_argument (new CCodeIdentifier ("invocation"));
+				return_error.add_argument (new CCodeIdentifier ("error"));
+				ccode.add_expression (return_error);
+
+				ccode.add_return ();
+
+				ccode.close ();
+			}
+
+			ccode.add_declaration ("GVariant*", new CCodeVariableDeclarator ("_reply"));
+			ccode.add_declaration ("GVariantBuilder", new CCodeVariableDeclarator ("_reply_builder"));
+
+			var builder_init = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_builder_init"));
+			builder_init.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_reply_builder")));
+			builder_init.add_argument (new CCodeIdentifier ("G_VARIANT_TYPE_TUPLE"));
+			ccode.add_expression (builder_init);
+
+			foreach (FormalParameter param in m.get_parameters ()) {
+				if (param.direction != ParameterDirection.OUT) {
+					continue;
 				}
 
-				if (m.return_type is ArrayType) {
-					var array_type = (ArrayType) m.return_type;
+				var owned_type = param.variable_type.copy ();
+				owned_type.value_owned = true;
 
+				ccode.add_declaration (owned_type.get_cname (), new CCodeVariableDeclarator.zero (param.name, default_value_for_type (param.variable_type, true)));
+
+				var array_type = param.variable_type as ArrayType;
+				if (array_type != null) {
 					for (int dim = 1; dim <= array_type.rank; dim++) {
-						string length_cname = get_array_length_cname ("result", dim);
+						string length_cname = get_parameter_array_length_cname (param, dim);
 
-						cdecl = new CCodeDeclaration ("int");
-						cdecl.add_declarator (new CCodeVariableDeclarator (length_cname, new CCodeConstant ("0")));
-						out_prefragment.append (cdecl);
-						if (!m.coroutine) {
-							ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (length_cname)));
-						} else {
-							finish_ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (length_cname)));
-						}
+						ccode.add_declaration ("int", new CCodeVariableDeclarator.zero (length_cname, new CCodeConstant ("0")));
 					}
 				}
 
-				write_expression (out_postfragment, m.return_type, new CCodeIdentifier ("_reply_builder"), new CCodeIdentifier ("result"), m);
-
-				if (requires_destroy (m.return_type)) {
-					// keep local alive (symbol_reference is weak)
-					// space before `result' is work around to not trigger
-					// variable renaming, we really mean C identifier `result' here
-					var local = new LocalVariable (m.return_type, " result");
-					var ma = new MemberAccess.simple ("result");
-					ma.symbol_reference = local;
-					out_postfragment.append (new CCodeExpressionStatement (get_unref_expression (new CCodeIdentifier ("result"), m.return_type, ma)));
-				}
+				write_expression (param.variable_type, new CCodeIdentifier ("_reply_builder"), new CCodeIdentifier (param.name), param);
 			}
-		} else {
-			block.add_statement (new CCodeExpressionStatement (ccall));
-			if (m.coroutine) {
-				ready_block.add_statement (new CCodeExpressionStatement (finish_ccall));
-			}
-		}
 
-		if (!no_reply) {
-			var builder_end = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_builder_end"));
-			builder_end.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_reply_builder")));
-			out_postfragment.append (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("_reply"), builder_end)));
-		}
+			if (!(m.return_type is VoidType)) {
+				if (m.return_type.is_real_non_null_struct_type ()) {
+					ccode.add_declaration (m.return_type.get_cname (), new CCodeVariableDeclarator.zero ("result", default_value_for_type (m.return_type, true)));
+
+					write_expression (m.return_type, new CCodeIdentifier ("_reply_builder"), new CCodeIdentifier ("result"), m);
+
+					if (requires_destroy (m.return_type)) {
+						// keep local alive (symbol_reference is weak)
+						// space before `result' is work around to not trigger
+						// variable renaming, we really mean C identifier `result' here
+						var local = new LocalVariable (m.return_type, " result");
+						var ma = new MemberAccess.simple ("result");
+						ma.symbol_reference = local;
+						ccode.add_expression (get_unref_expression (new CCodeIdentifier ("result"), m.return_type, ma));
+					}
+				} else {
+					ccode.add_declaration (m.return_type.get_cname (), new CCodeVariableDeclarator ("result"));
 
-		if (m.coroutine) {
-			ccall.add_argument (new CCodeCastExpression (new CCodeIdentifier (wrapper_name + "_ready"), "GAsyncReadyCallback"));
+					var array_type = m.return_type as ArrayType;
+					if (array_type != null) {
+						for (int dim = 1; dim <= array_type.rank; dim++) {
+							string length_cname = get_array_length_cname ("result", dim);
 
-			var ref_call = new CCodeFunctionCall (new CCodeIdentifier ("g_object_ref"));
-			ref_call.add_argument (new CCodeIdentifier ("invocation"));
+							ccode.add_declaration ("int", new CCodeVariableDeclarator.zero (length_cname, new CCodeConstant ("0")));
+						}
+					}
 
-			ccall.add_argument (ref_call);
-		}
+					write_expression (m.return_type, new CCodeIdentifier ("_reply_builder"), new CCodeIdentifier ("result"), m);
 
-		if (m.get_error_types ().size > 0) {
-			if (m.coroutine) {
-				finish_ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("error")));
-			} else {
-				ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("error")));
+					if (requires_destroy (m.return_type)) {
+						// keep local alive (symbol_reference is weak)
+						// space before `result' is work around to not trigger
+						// variable renaming, we really mean C identifier `result' here
+						var local = new LocalVariable (m.return_type, " result");
+						var ma = new MemberAccess.simple ("result");
+						ma.symbol_reference = local;
+						ccode.add_expression (get_unref_expression (new CCodeIdentifier ("result"), m.return_type, ma));
+					}
+				}
 			}
 
-			var error_block = new CCodeBlock ();
-
-			var return_error = new CCodeFunctionCall (new CCodeIdentifier ("g_dbus_method_invocation_return_gerror"));
-			return_error.add_argument (new CCodeIdentifier ("invocation"));
-			return_error.add_argument (new CCodeIdentifier ("error"));
-			error_block.add_statement (new CCodeExpressionStatement (return_error));
+			var builder_end = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_builder_end"));
+			builder_end.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_reply_builder")));
+			ccode.add_expression (new CCodeAssignment (new CCodeIdentifier ("_reply"), builder_end));
+		} else {
+			ccode.add_expression (ccall);
+		}
 
-			error_block.add_statement (new CCodeReturnStatement ());
+		foreach (FormalParameter param in m.get_parameters ()) {
+			if ((param.direction == ParameterDirection.IN && !ready) ||
+			    (param.direction == ParameterDirection.OUT && !no_reply && (!m.coroutine || ready))) {
+				var owned_type = param.variable_type.copy ();
+				owned_type.value_owned = true;
 
-			if (m.coroutine) {
-				ready_block.add_statement (new CCodeIfStatement (new CCodeIdentifier ("error"), error_block));
-			} else {
-				block.add_statement (new CCodeIfStatement (new CCodeIdentifier ("error"), error_block));
+				if (requires_destroy (owned_type)) {
+					// keep local alive (symbol_reference is weak)
+					var local = new LocalVariable (owned_type, param.name);
+					var ma = new MemberAccess.simple (param.name);
+					ma.symbol_reference = local;
+					ccode.add_expression (get_unref_expression (new CCodeIdentifier (param.name), owned_type, ma));
+				}
 			}
 		}
 
-		block.add_statement (in_postfragment);
-
 		if (no_reply) {
 			var return_value = new CCodeFunctionCall (new CCodeIdentifier ("g_object_unref"));
 			return_value.add_argument (new CCodeIdentifier ("invocation"));
-			block.add_statement (new CCodeExpressionStatement (return_value));
-		} else if (!m.coroutine) {
+			ccode.add_expression (return_value);
+		} else if (!m.coroutine || ready) {
 			var return_value = new CCodeFunctionCall (new CCodeIdentifier ("g_dbus_method_invocation_return_value"));
 			return_value.add_argument (new CCodeIdentifier ("invocation"));
 			return_value.add_argument (new CCodeIdentifier ("_reply"));
-			block.add_statement (new CCodeExpressionStatement (return_value));
-		} else {
-			ready_block.add_statement (out_postfragment);
-
-			var return_value = new CCodeFunctionCall (new CCodeIdentifier ("g_dbus_method_invocation_return_value"));
-			return_value.add_argument (new CCodeIdentifier ("invocation"));
-			return_value.add_argument (new CCodeIdentifier ("_reply"));
-			ready_block.add_statement (new CCodeExpressionStatement (return_value));
+			ccode.add_expression (return_value);
 
-			var unref_call = new CCodeFunctionCall (new CCodeIdentifier ("g_object_unref"));
-			unref_call.add_argument (new CCodeIdentifier ("invocation"));
-			ready_block.add_statement (new CCodeExpressionStatement (unref_call));
+			if (ready) {
+				var unref_call = new CCodeFunctionCall (new CCodeIdentifier ("g_object_unref"));
+				unref_call.add_argument (new CCodeIdentifier ("invocation"));
+				ccode.add_expression (unref_call);
 
-			unref_call = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_unref"));
-			unref_call.add_argument (new CCodeIdentifier ("_reply"));
-			ready_block.add_statement (new CCodeExpressionStatement (unref_call));
+				unref_call = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_unref"));
+				unref_call.add_argument (new CCodeIdentifier ("_reply"));
+				ccode.add_expression (unref_call);
+			}
 		}
 
-		cfile.add_function_declaration (function);
+		pop_function ();
 
-		function.block = block;
+		cfile.add_function_declaration (function);
 		cfile.add_function (function);
 
-		if (m.coroutine) {
-			cfile.add_function_declaration (ready_function);
-
-			ready_function.block = ready_block;
-			cfile.add_function (ready_function);
+		if (m.coroutine && !ready) {
+			// generate ready function
+			generate_dbus_wrapper (m, sym, true);
 		}
 
 		return wrapper_name;
@@ -364,10 +330,6 @@ public class Vala.GDBusServerModule : GDBusClientModule {
 	string generate_dbus_signal_wrapper (Signal sig, ObjectTypeSymbol sym, string dbus_iface_name) {
 		string wrapper_name = "_dbus_%s_%s".printf (sym.get_lower_case_cname (), sig.get_cname ());
 
-		// declaration
-
-		CCodeDeclaration cdecl;
-
 		var function = new CCodeFunction (wrapper_name, "void");
 		function.modifiers = CCodeModifiers.STATIC;
 
@@ -388,43 +350,29 @@ public class Vala.GDBusServerModule : GDBusClientModule {
 
 		function.add_parameter (new CCodeFormalParameter ("_data", "gpointer*"));
 
-		var block = new CCodeBlock ();
-		var prefragment = new CCodeFragment ();
+		push_function (function);
 
-		cdecl = new CCodeDeclaration ("GDBusConnection *");
-		cdecl.add_declarator (new CCodeVariableDeclarator ("_connection", new CCodeElementAccess (new CCodeIdentifier ("_data"), new CCodeConstant ("1"))));
-		block.add_statement (cdecl);
-
-		cdecl = new CCodeDeclaration ("const gchar *");
-		cdecl.add_declarator (new CCodeVariableDeclarator ("_path", new CCodeElementAccess (new CCodeIdentifier ("_data"), new CCodeConstant ("2"))));
-		block.add_statement (cdecl);
-
-		cdecl = new CCodeDeclaration ("GVariant");
-		cdecl.add_declarator (new CCodeVariableDeclarator ("*_arguments"));
-		block.add_statement (cdecl);
-
-		cdecl = new CCodeDeclaration ("GVariantBuilder");
-		cdecl.add_declarator (new CCodeVariableDeclarator ("_arguments_builder"));
-		prefragment.append (cdecl);
+		ccode.add_declaration ("GDBusConnection *", new CCodeVariableDeclarator ("_connection", new CCodeElementAccess (new CCodeIdentifier ("_data"), new CCodeConstant ("1"))));
+		ccode.add_declaration ("const gchar *", new CCodeVariableDeclarator ("_path", new CCodeElementAccess (new CCodeIdentifier ("_data"), new CCodeConstant ("2"))));
+		ccode.add_declaration ("GVariant", new CCodeVariableDeclarator ("*_arguments"));
+		ccode.add_declaration ("GVariantBuilder", new CCodeVariableDeclarator ("_arguments_builder"));
 
 		var builder_init = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_builder_init"));
 		builder_init.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_arguments_builder")));
 		builder_init.add_argument (new CCodeIdentifier ("G_VARIANT_TYPE_TUPLE"));
-		prefragment.append (new CCodeExpressionStatement (builder_init));
+		ccode.add_expression (builder_init);
 
 		foreach (FormalParameter param in sig.get_parameters ()) {
 			CCodeExpression expr = new CCodeIdentifier (param.name);
 			if (param.variable_type.is_real_struct_type ()) {
 				expr = new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, expr);
 			}
-			write_expression (prefragment, param.variable_type, new CCodeIdentifier ("_arguments_builder"), expr, param);
+			write_expression (param.variable_type, new CCodeIdentifier ("_arguments_builder"), expr, param);
 		}
 
 		var builder_end = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_builder_end"));
 		builder_end.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_arguments_builder")));
-		prefragment.append (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("_arguments"), builder_end)));
-
-		block.add_statement (prefragment);
+		ccode.add_expression (new CCodeAssignment (new CCodeIdentifier ("_arguments"), builder_end));
 
 		var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_dbus_connection_emit_signal"));
 		ccall.add_argument (new CCodeIdentifier ("_connection"));
@@ -434,10 +382,11 @@ public class Vala.GDBusServerModule : GDBusClientModule {
 		ccall.add_argument (new CCodeConstant ("\"%s\"".printf (get_dbus_name_for_member (sig))));
 		ccall.add_argument (new CCodeIdentifier ("_arguments"));
 		ccall.add_argument (new CCodeConstant ("NULL"));
-		block.add_statement (new CCodeExpressionStatement (ccall));
+		ccode.add_expression (ccall);
+
+		pop_function ();
 
 		cfile.add_function_declaration (function);
-		function.block = block;
 		cfile.add_function (function);
 
 		return wrapper_name;
@@ -446,59 +395,39 @@ public class Vala.GDBusServerModule : GDBusClientModule {
 	string generate_dbus_property_get_wrapper (Property prop, ObjectTypeSymbol sym) {
 		string wrapper_name = "_dbus_%s".printf (prop.get_accessor.get_cname ());
 
-		// declaration
-
-		CCodeDeclaration cdecl;
-
 		var function = new CCodeFunction (wrapper_name, "GVariant*");
 		function.modifiers = CCodeModifiers.STATIC;
 		function.add_parameter (new CCodeFormalParameter ("self", sym.get_cname () + "*"));
-		var block = new CCodeBlock ();
-
-		var prefragment = new CCodeFragment ();
-		var postfragment = new CCodeFragment ();
 
-		block.add_statement (prefragment);
-
-		cdecl = new CCodeDeclaration ("GVariant*");
-		cdecl.add_declarator (new CCodeVariableDeclarator ("_reply"));
-		postfragment.append (cdecl);
+		push_function (function);
 
 		var ccall = new CCodeFunctionCall (new CCodeIdentifier (prop.get_accessor.get_cname ()));
 		ccall.add_argument (new CCodeIdentifier ("self"));
 
 		if (prop.property_type.is_real_non_null_struct_type ()) {
-			cdecl = new CCodeDeclaration (prop.property_type.get_cname ());
-			cdecl.add_declarator (new CCodeVariableDeclarator.zero ("result", default_value_for_type (prop.property_type, true)));
-			prefragment.append (cdecl);
-
+			ccode.add_declaration (prop.property_type.get_cname (), new CCodeVariableDeclarator.zero ("result", default_value_for_type (prop.property_type, true)));
 			ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("result")));
 
-			block.add_statement (new CCodeExpressionStatement (ccall));
+			ccode.add_expression (ccall);
 		} else {
-			cdecl = new CCodeDeclaration (prop.property_type.get_cname ());
-			cdecl.add_declarator (new CCodeVariableDeclarator ("result"));
-			prefragment.append (cdecl);
-
-			block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("result"), ccall)));
+			ccode.add_declaration (prop.property_type.get_cname (), new CCodeVariableDeclarator ("result"));
+			ccode.add_expression (new CCodeAssignment (new CCodeIdentifier ("result"), ccall));
 
 			var array_type = prop.property_type as ArrayType;
 			if (array_type != null) {
 				for (int dim = 1; dim <= array_type.rank; dim++) {
 					string length_cname = get_array_length_cname ("result", dim);
 
-					cdecl = new CCodeDeclaration ("int");
-					cdecl.add_declarator (new CCodeVariableDeclarator (length_cname));
-					postfragment.append (cdecl);
-
+					ccode.add_declaration ("int", new CCodeVariableDeclarator (length_cname));
 					ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (length_cname)));
 				}
 			}
 		}
 
-		var reply_expr = serialize_expression (postfragment, prop.property_type, new CCodeIdentifier ("result"));
+		var reply_expr = serialize_expression (prop.property_type, new CCodeIdentifier ("result"));
 
-		postfragment.append (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("_reply"), reply_expr)));
+		ccode.add_declaration ("GVariant*", new CCodeVariableDeclarator ("_reply"));
+		ccode.add_expression (new CCodeAssignment (new CCodeIdentifier ("_reply"), reply_expr));
 
 		if (requires_destroy (prop.property_type)) {
 			// keep local alive (symbol_reference is weak)
@@ -507,16 +436,14 @@ public class Vala.GDBusServerModule : GDBusClientModule {
 			var local = new LocalVariable (prop.property_type, " result");
 			var ma = new MemberAccess.simple ("result");
 			ma.symbol_reference = local;
-			postfragment.append (new CCodeExpressionStatement (get_unref_expression (new CCodeIdentifier ("result"), prop.property_type, ma)));
+			ccode.add_expression (get_unref_expression (new CCodeIdentifier ("result"), prop.property_type, ma));
 		}
 
-		block.add_statement (postfragment);
+		ccode.add_return (new CCodeIdentifier ("_reply"));
 
-		block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("_reply")));
+		pop_function ();
 
 		cfile.add_function_declaration (function);
-
-		function.block = block;
 		cfile.add_function (function);
 
 		return wrapper_name;
@@ -525,20 +452,12 @@ public class Vala.GDBusServerModule : GDBusClientModule {
 	string generate_dbus_property_set_wrapper (Property prop, ObjectTypeSymbol sym) {
 		string wrapper_name = "_dbus_%s".printf (prop.set_accessor.get_cname ());
 
-		// declaration
-
-		CCodeDeclaration cdecl;
-
 		var function = new CCodeFunction (wrapper_name);
 		function.modifiers = CCodeModifiers.STATIC;
 		function.add_parameter (new CCodeFormalParameter ("self", sym.get_cname () + "*"));
 		function.add_parameter (new CCodeFormalParameter ("_value", "GVariant*"));
-		var block = new CCodeBlock ();
-
-		var prefragment = new CCodeFragment ();
-		var postfragment = new CCodeFragment ();
 
-		block.add_statement (prefragment);
+		push_function (function);
 
 		var ccall = new CCodeFunctionCall (new CCodeIdentifier (prop.set_accessor.get_cname ()));
 		ccall.add_argument (new CCodeIdentifier ("self"));
@@ -546,9 +465,7 @@ public class Vala.GDBusServerModule : GDBusClientModule {
 		var owned_type = prop.property_type.copy ();
 		owned_type.value_owned = true;
 
-		cdecl = new CCodeDeclaration (owned_type.get_cname ());
-		cdecl.add_declarator (new CCodeVariableDeclarator.zero ("value", default_value_for_type (prop.property_type, true)));
-		prefragment.append (cdecl);
+		ccode.add_declaration (owned_type.get_cname (), new CCodeVariableDeclarator.zero ("value", default_value_for_type (prop.property_type, true)));
 
 		var st = prop.property_type.data_type as Struct;
 		if (st != null && !st.is_simple_type ()) {
@@ -559,35 +476,29 @@ public class Vala.GDBusServerModule : GDBusClientModule {
 			var array_type = prop.property_type as ArrayType;
 			if (array_type != null) {
 				for (int dim = 1; dim <= array_type.rank; dim++) {
-					cdecl = new CCodeDeclaration ("int");
-					cdecl.add_declarator (new CCodeVariableDeclarator (get_array_length_cname ("value", dim)));
-					prefragment.append (cdecl);
-
+					ccode.add_declaration ("int", new CCodeVariableDeclarator (get_array_length_cname ("value", dim)));
 					ccall.add_argument (new CCodeIdentifier (get_array_length_cname ("value", dim)));
 				}
 			}
 		}
 
 		var target = new CCodeIdentifier ("value");
-		var expr = deserialize_expression (prefragment, prop.property_type, new CCodeIdentifier ("_value"), target);
-		prefragment.append (new CCodeExpressionStatement (new CCodeAssignment (target, expr)));
+		var expr = deserialize_expression (prop.property_type, new CCodeIdentifier ("_value"), target);
+		ccode.add_expression (new CCodeAssignment (target, expr));
+
+		ccode.add_expression (ccall);
 
 		if (requires_destroy (owned_type)) {
 			// keep local alive (symbol_reference is weak)
 			var local = new LocalVariable (owned_type, "value");
 			var ma = new MemberAccess.simple ("value");
 			ma.symbol_reference = local;
-			var stmt = new CCodeExpressionStatement (get_unref_expression (new CCodeIdentifier ("value"), owned_type, ma));
-			postfragment.append (stmt);
+			ccode.add_expression (get_unref_expression (new CCodeIdentifier ("value"), owned_type, ma));
 		}
 
-		block.add_statement (new CCodeExpressionStatement (ccall));
-
-		block.add_statement (postfragment);
+		pop_function ();
 
 		cfile.add_function_declaration (function);
-
-		function.block = block;
 		cfile.add_function (function);
 
 		return wrapper_name;
diff --git a/codegen/valagvariantmodule.vala b/codegen/valagvariantmodule.vala
index 859c474..a8a3e9e 100644
--- a/codegen/valagvariantmodule.vala
+++ b/codegen/valagvariantmodule.vala
@@ -192,7 +192,7 @@ public class Vala.GVariantModule : GAsyncModule {
 		}
 	}
 
-	CCodeExpression? generate_enum_value_from_string (CCodeFragment fragment, EnumValueType type, CCodeExpression? expr) {
+	CCodeExpression? generate_enum_value_from_string (EnumValueType type, CCodeExpression? expr) {
 		var en = type.type_symbol as Enum;
 		var from_string_name = "%s_from_string".printf (en.get_lower_case_cname (null));
 
@@ -252,7 +252,7 @@ public class Vala.GVariantModule : GAsyncModule {
 		return from_string_func;
 	}
 
-	CCodeExpression deserialize_basic (CCodeFragment fragment, BasicTypeInfo basic_type, CCodeExpression variant_expr, bool transfer = false) {
+	CCodeExpression deserialize_basic (BasicTypeInfo basic_type, CCodeExpression variant_expr, bool transfer = false) {
 		var get_call = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_get_" + basic_type.type_name));
 		get_call.add_argument (variant_expr);
 
@@ -268,7 +268,7 @@ public class Vala.GVariantModule : GAsyncModule {
 		return get_call;
 	}
 
-	CCodeExpression deserialize_array (CCodeFragment fragment, ArrayType array_type, CCodeExpression variant_expr, CCodeExpression? expr) {
+	CCodeExpression deserialize_array (ArrayType array_type, CCodeExpression variant_expr, CCodeExpression? expr) {
 		string temp_name = "_tmp%d_".printf (next_temp_var_id++);
 
 		var new_call = new CCodeFunctionCall (new CCodeIdentifier ("g_new"));
@@ -276,113 +276,89 @@ public class Vala.GVariantModule : GAsyncModule {
 		// add one extra element for NULL-termination
 		new_call.add_argument (new CCodeConstant ("5"));
 
-		var cdecl = new CCodeDeclaration (array_type.get_cname ());
-		cdecl.add_declarator (new CCodeVariableDeclarator (temp_name, new_call));
-		fragment.append (cdecl);
+		ccode.add_declaration (array_type.get_cname (), new CCodeVariableDeclarator (temp_name, new_call));
+		ccode.add_declaration ("int", new CCodeVariableDeclarator (temp_name + "_length", new CCodeConstant ("0")));
+		ccode.add_declaration ("int", new CCodeVariableDeclarator (temp_name + "_size", new CCodeConstant ("4")));
 
-		cdecl = new CCodeDeclaration ("int");
-		cdecl.add_declarator (new CCodeVariableDeclarator (temp_name + "_length", new CCodeConstant ("0")));
-		fragment.append (cdecl);
-
-		cdecl = new CCodeDeclaration ("int");
-		cdecl.add_declarator (new CCodeVariableDeclarator (temp_name + "_size", new CCodeConstant ("4")));
-		fragment.append (cdecl);
-
-		deserialize_array_dim (fragment, array_type, 1, temp_name, variant_expr, expr);
+		deserialize_array_dim (array_type, 1, temp_name, variant_expr, expr);
 
 		if (array_type.element_type.is_reference_type_or_type_parameter ()) {
 			// NULL terminate array
 			var length = new CCodeIdentifier (temp_name + "_length");
 			var element_access = new CCodeElementAccess (new CCodeIdentifier (temp_name), length);
-			fragment.append (new CCodeExpressionStatement (new CCodeAssignment (element_access, new CCodeIdentifier ("NULL"))));
+			ccode.add_expression (new CCodeAssignment (element_access, new CCodeIdentifier ("NULL")));
 		}
 
 		return new CCodeIdentifier (temp_name);
 	}
 
-	void deserialize_array_dim (CCodeFragment fragment, ArrayType array_type, int dim, string temp_name, CCodeExpression variant_expr, CCodeExpression? expr) {
+	void deserialize_array_dim (ArrayType array_type, int dim, string temp_name, CCodeExpression variant_expr, CCodeExpression? expr) {
 		string subiter_name = "_tmp%d_".printf (next_temp_var_id++);
 		string element_name = "_tmp%d_".printf (next_temp_var_id++);
 
-		var cdecl = new CCodeDeclaration ("int");
-		cdecl.add_declarator (new CCodeVariableDeclarator ("%s_length%d".printf (temp_name, dim), new CCodeConstant ("0")));
-		fragment.append (cdecl);
-
-		cdecl = new CCodeDeclaration ("GVariantIter");
-		cdecl.add_declarator (new CCodeVariableDeclarator (subiter_name));
-		fragment.append (cdecl);
-
-		cdecl = new CCodeDeclaration ("GVariant*");
-		cdecl.add_declarator (new CCodeVariableDeclarator (element_name));
-		fragment.append (cdecl);
+		ccode.add_declaration ("int", new CCodeVariableDeclarator ("%s_length%d".printf (temp_name, dim), new CCodeConstant ("0")));
+		ccode.add_declaration ("GVariantIter", new CCodeVariableDeclarator (subiter_name));
+		ccode.add_declaration ("GVariant*", new CCodeVariableDeclarator (element_name));
 
 		var iter_call = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_iter_init"));
 		iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (subiter_name)));
 		iter_call.add_argument (variant_expr);
-		fragment.append (new CCodeExpressionStatement (iter_call));
+		ccode.add_expression (iter_call);
 
 		iter_call = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_iter_next_value"));
 		iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (subiter_name)));
 
-		var cforblock = new CCodeBlock ();
-		var cforfragment = new CCodeFragment ();
-		cforblock.add_statement (cforfragment);
-		var cfor = new CCodeForStatement (new CCodeAssignment (new CCodeIdentifier (element_name), iter_call), cforblock);
-		cfor.add_iterator (new CCodeUnaryExpression (CCodeUnaryOperator.POSTFIX_INCREMENT, new CCodeIdentifier ("%s_length%d".printf (temp_name, dim))));
+		var cforcond = new CCodeAssignment (new CCodeIdentifier (element_name), iter_call);
+		var cforiter = new CCodeUnaryExpression (CCodeUnaryOperator.POSTFIX_INCREMENT, new CCodeIdentifier ("%s_length%d".printf (temp_name, dim)));
+		ccode.open_for (null, cforcond, cforiter);
 
 		if (dim < array_type.rank) {
-			deserialize_array_dim (cforfragment, array_type, dim + 1, temp_name, new CCodeIdentifier (element_name), expr);
+			deserialize_array_dim (array_type, dim + 1, temp_name, new CCodeIdentifier (element_name), expr);
 		} else {
 			var size_check = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, new CCodeIdentifier (temp_name + "_size"), new CCodeIdentifier (temp_name + "_length"));
-			var renew_block = new CCodeBlock ();
+
+			ccode.open_if (size_check);
 
 			// tmp_size = (2 * tmp_size);
 			var new_size = new CCodeBinaryExpression (CCodeBinaryOperator.MUL, new CCodeConstant ("2"), new CCodeIdentifier (temp_name + "_size"));
-			renew_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier (temp_name + "_size"), new_size)));
+			ccode.add_expression (new CCodeAssignment (new CCodeIdentifier (temp_name + "_size"), new_size));
 
 			var renew_call = new CCodeFunctionCall (new CCodeIdentifier ("g_renew"));
 			renew_call.add_argument (new CCodeIdentifier (array_type.element_type.get_cname ()));
 			renew_call.add_argument (new CCodeIdentifier (temp_name));
 			// add one extra element for NULL-termination
 			renew_call.add_argument (new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, new CCodeIdentifier (temp_name + "_size"), new CCodeConstant ("1")));
-			var renew_stmt = new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier (temp_name), renew_call));
-			renew_block.add_statement (renew_stmt);
+			ccode.add_expression (new CCodeAssignment (new CCodeIdentifier (temp_name), renew_call));
 
-			var cif = new CCodeIfStatement (size_check, renew_block);
-			cforfragment.append (cif);
+			ccode.close ();
 
 			var element_access = new CCodeElementAccess (new CCodeIdentifier (temp_name), new CCodeUnaryExpression (CCodeUnaryOperator.POSTFIX_INCREMENT, new CCodeIdentifier (temp_name + "_length")));
-			var element_expr = deserialize_expression (cforfragment, array_type.element_type, new CCodeIdentifier (element_name), null);
-			cforfragment.append (new CCodeExpressionStatement (new CCodeAssignment (element_access, element_expr)));
+			var element_expr = deserialize_expression (array_type.element_type, new CCodeIdentifier (element_name), null);
+			ccode.add_expression (new CCodeAssignment (element_access, element_expr));
 		}
 
 		var unref = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_unref"));
 		unref.add_argument (new CCodeIdentifier (element_name));
-		cforfragment.append (new CCodeExpressionStatement (unref));
+		ccode.add_expression (unref);
 
-		fragment.append (cfor);
+		ccode.close ();
 
 		if (expr != null) {
-			fragment.append (new CCodeExpressionStatement (new CCodeAssignment (get_array_length (expr, dim), new CCodeIdentifier ("%s_length%d".printf (temp_name, dim)))));
+			ccode.add_expression (new CCodeAssignment (get_array_length (expr, dim), new CCodeIdentifier ("%s_length%d".printf (temp_name, dim))));
 		}
 	}
 
-	CCodeExpression? deserialize_struct (CCodeFragment fragment, Struct st, CCodeExpression variant_expr) {
+	CCodeExpression? deserialize_struct (Struct st, CCodeExpression variant_expr) {
 		string temp_name = "_tmp%d_".printf (next_temp_var_id++);
 		string subiter_name = "_tmp%d_".printf (next_temp_var_id++);
 
-		var cdecl = new CCodeDeclaration (st.get_cname ());
-		cdecl.add_declarator (new CCodeVariableDeclarator (temp_name));
-		fragment.append (cdecl);
-
-		cdecl = new CCodeDeclaration ("GVariantIter");
-		cdecl.add_declarator (new CCodeVariableDeclarator (subiter_name));
-		fragment.append (cdecl);
+		ccode.add_declaration (st.get_cname (), new CCodeVariableDeclarator (temp_name));
+		ccode.add_declaration ("GVariantIter", new CCodeVariableDeclarator (subiter_name));
 
 		var iter_call = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_iter_init"));
 		iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (subiter_name)));
 		iter_call.add_argument (variant_expr);
-		fragment.append (new CCodeExpressionStatement (iter_call));
+		ccode.add_expression (iter_call);
 
 		bool field_found = false;;
 
@@ -393,7 +369,7 @@ public class Vala.GVariantModule : GAsyncModule {
 
 			field_found = true;
 
-			read_expression (fragment, f.variable_type, new CCodeIdentifier (subiter_name), new CCodeMemberAccess (new CCodeIdentifier (temp_name), f.get_cname ()), f);
+			read_expression (f.variable_type, new CCodeIdentifier (subiter_name), new CCodeMemberAccess (new CCodeIdentifier (temp_name), f.get_cname ()), f);
 		}
 
 		if (!field_found) {
@@ -403,7 +379,7 @@ public class Vala.GVariantModule : GAsyncModule {
 		return new CCodeIdentifier (temp_name);
 	}
 
-	CCodeExpression deserialize_hash_table (CCodeFragment fragment, ObjectType type, CCodeExpression variant_expr) {
+	CCodeExpression deserialize_hash_table (ObjectType type, CCodeExpression variant_expr) {
 		string temp_name = "_tmp%d_".printf (next_temp_var_id++);
 		string subiter_name = "_tmp%d_".printf (next_temp_var_id++);
 		string key_name = "_tmp%d_".printf (next_temp_var_id++);
@@ -414,21 +390,10 @@ public class Vala.GVariantModule : GAsyncModule {
 		var key_type = type_args.get (0);
 		var value_type = type_args.get (1);
 
-		var cdecl = new CCodeDeclaration ("GHashTable*");
-		cdecl.add_declarator (new CCodeVariableDeclarator (temp_name));
-		fragment.append (cdecl);
-
-		cdecl = new CCodeDeclaration ("GVariantIter");
-		cdecl.add_declarator (new CCodeVariableDeclarator (subiter_name));
-		fragment.append (cdecl);
-
-		cdecl = new CCodeDeclaration ("GVariant*");
-		cdecl.add_declarator (new CCodeVariableDeclarator (key_name));
-		fragment.append (cdecl);
-
-		cdecl = new CCodeDeclaration ("GVariant*");
-		cdecl.add_declarator (new CCodeVariableDeclarator (value_name));
-		fragment.append (cdecl);
+		ccode.add_declaration ("GHashTable*", new CCodeVariableDeclarator (temp_name));
+		ccode.add_declaration ("GVariantIter", new CCodeVariableDeclarator (subiter_name));
+		ccode.add_declaration ("GVariant*", new CCodeVariableDeclarator (key_name));
+		ccode.add_declaration ("GVariant*", new CCodeVariableDeclarator (value_name));
 
 		var hash_table_new = new CCodeFunctionCall (new CCodeIdentifier ("g_hash_table_new_full"));
 		if (key_type.data_type == string_type.data_type) {
@@ -448,12 +413,12 @@ public class Vala.GVariantModule : GAsyncModule {
 		} else {
 			hash_table_new.add_argument (new CCodeIdentifier ("NULL"));
 		}
-		fragment.append (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier (temp_name), hash_table_new)));
+		ccode.add_expression (new CCodeAssignment (new CCodeIdentifier (temp_name), hash_table_new));
 
 		var iter_call = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_iter_init"));
 		iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (subiter_name)));
 		iter_call.add_argument (variant_expr);
-		fragment.append (new CCodeExpressionStatement (iter_call));
+		ccode.add_expression (iter_call);
 
 		iter_call = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_iter_loop"));
 		iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (subiter_name)));
@@ -461,39 +426,36 @@ public class Vala.GVariantModule : GAsyncModule {
 		iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (key_name)));
 		iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (value_name)));
 
-		var cwhileblock = new CCodeBlock ();
-		var cwhilefragment = new CCodeFragment ();
-		cwhileblock.add_statement (cwhilefragment);
-		var cwhile = new CCodeWhileStatement (iter_call, cwhileblock);
+		ccode.open_while (iter_call);
 
-		var key_expr = deserialize_expression (cwhilefragment, key_type, new CCodeIdentifier (key_name), null);
-		var value_expr = deserialize_expression (cwhilefragment, value_type, new CCodeIdentifier (value_name), null);
+		var key_expr = deserialize_expression (key_type, new CCodeIdentifier (key_name), null);
+		var value_expr = deserialize_expression (value_type, new CCodeIdentifier (value_name), null);
 
 		var hash_table_insert = new CCodeFunctionCall (new CCodeIdentifier ("g_hash_table_insert"));
 		hash_table_insert.add_argument (new CCodeIdentifier (temp_name));
 		hash_table_insert.add_argument (convert_to_generic_pointer (key_expr, key_type));
 		hash_table_insert.add_argument (convert_to_generic_pointer (value_expr, value_type));
-		cwhilefragment.append (new CCodeExpressionStatement (hash_table_insert));
+		ccode.add_expression (hash_table_insert);
 
-		fragment.append (cwhile);
+		ccode.close ();
 
 		return new CCodeIdentifier (temp_name);
 	}
 
-	public override CCodeExpression? deserialize_expression (CCodeFragment fragment, DataType type, CCodeExpression variant_expr, CCodeExpression? expr) {
+	public override CCodeExpression? deserialize_expression (DataType type, CCodeExpression variant_expr, CCodeExpression? expr) {
 		BasicTypeInfo basic_type;
 		CCodeExpression result = null;
 		if (is_string_marshalled_enum (type.data_type)) {
 			get_basic_type_info ("s", out basic_type);
-			result = deserialize_basic (fragment, basic_type, variant_expr, true);
-			result = generate_enum_value_from_string (fragment, type as EnumValueType, result);
+			result = deserialize_basic (basic_type, variant_expr, true);
+			result = generate_enum_value_from_string (type as EnumValueType, result);
 		} else if (get_basic_type_info (get_type_signature (type), out basic_type)) {
-			result = deserialize_basic (fragment, basic_type, variant_expr);
+			result = deserialize_basic (basic_type, variant_expr);
 		} else if (type is ArrayType) {
-			result = deserialize_array (fragment, (ArrayType) type, variant_expr, expr);
+			result = deserialize_array ((ArrayType) type, variant_expr, expr);
 		} else if (type.data_type is Struct) {
 			var st = (Struct) type.data_type;
-			result = deserialize_struct (fragment, st, variant_expr);
+			result = deserialize_struct (st, variant_expr);
 			if (result != null && type.nullable) {
 				var csizeof = new CCodeFunctionCall (new CCodeIdentifier ("sizeof"));
 				csizeof.add_argument (new CCodeIdentifier (st.get_cname ()));
@@ -508,7 +470,7 @@ public class Vala.GVariantModule : GAsyncModule {
 				variant_get.add_argument (variant_expr);
 				result = variant_get;
 			} else if (type.data_type.get_full_name () == "GLib.HashTable") {
-				result = deserialize_hash_table (fragment, (ObjectType) type, variant_expr);
+				result = deserialize_hash_table ((ObjectType) type, variant_expr);
 			}
 		}
 
@@ -519,35 +481,33 @@ public class Vala.GVariantModule : GAsyncModule {
 		return result;
 	}
 
-	public void read_expression (CCodeFragment fragment, DataType type, CCodeExpression iter_expr, CCodeExpression target_expr, Symbol? sym) {
+	public void read_expression (DataType type, CCodeExpression iter_expr, CCodeExpression target_expr, Symbol? sym) {
 		var iter_call = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_iter_next_value"));
 		iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, iter_expr));
 
 		if (sym != null && get_dbus_signature (sym) != null) {
 			// raw GVariant
-			fragment.append (new CCodeExpressionStatement (new CCodeAssignment (target_expr, iter_call)));
+			ccode.add_expression (new CCodeAssignment (target_expr, iter_call));
 			return;
 		}
 
 		string temp_name = "_tmp%d_".printf (next_temp_var_id++);
 
-		var cdecl = new CCodeDeclaration ("GVariant*");
-		cdecl.add_declarator (new CCodeVariableDeclarator (temp_name));
-		fragment.append (cdecl);
+		ccode.add_declaration ("GVariant*", new CCodeVariableDeclarator (temp_name));
 
 		var variant_expr = new CCodeIdentifier (temp_name);
 
-		fragment.append (new CCodeExpressionStatement (new CCodeAssignment (variant_expr, iter_call)));
+		ccode.add_expression (new CCodeAssignment (variant_expr, iter_call));
 
-		var result = deserialize_expression (fragment, type, variant_expr, target_expr);
-		fragment.append (new CCodeExpressionStatement (new CCodeAssignment (target_expr, result)));
+		var result = deserialize_expression (type, variant_expr, target_expr);
+		ccode.add_expression (new CCodeAssignment (target_expr, result));
 
 		var unref = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_unref"));
 		unref.add_argument (variant_expr);
-		fragment.append (new CCodeExpressionStatement (unref));
+		ccode.add_expression (unref);
 	}
 
-	CCodeExpression? generate_enum_value_to_string (CCodeFragment fragment, EnumValueType type, CCodeExpression? expr) {
+	CCodeExpression? generate_enum_value_to_string (EnumValueType type, CCodeExpression? expr) {
 		var en = type.type_symbol as Enum;
 		var to_string_name = "%s_to_string".printf (en.get_lower_case_cname (null));
 
@@ -593,84 +553,72 @@ public class Vala.GVariantModule : GAsyncModule {
 		return to_string_func;
 	}
 
-	CCodeExpression? serialize_basic (CCodeFragment fragment, BasicTypeInfo basic_type, CCodeExpression expr) {
+	CCodeExpression? serialize_basic (BasicTypeInfo basic_type, CCodeExpression expr) {
 		var new_call = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_new_" + basic_type.type_name));
 		new_call.add_argument (expr);
 		return new_call;
 	}
 
-	CCodeExpression? serialize_array (CCodeFragment fragment, ArrayType array_type, CCodeExpression array_expr) {
+	CCodeExpression? serialize_array (ArrayType array_type, CCodeExpression array_expr) {
 		string array_iter_name = "_tmp%d_".printf (next_temp_var_id++);
 
-		var cdecl = new CCodeDeclaration (array_type.get_cname ());
-		cdecl.add_declarator (new CCodeVariableDeclarator (array_iter_name));
-		fragment.append (cdecl);
+		ccode.add_declaration (array_type.get_cname (), new CCodeVariableDeclarator (array_iter_name));
+		ccode.add_expression (new CCodeAssignment (new CCodeIdentifier (array_iter_name), array_expr));
 
-		fragment.append (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier (array_iter_name), array_expr)));
-
-		return serialize_array_dim (fragment, array_type, 1, array_expr, new CCodeIdentifier (array_iter_name));
+		return serialize_array_dim (array_type, 1, array_expr, new CCodeIdentifier (array_iter_name));
 	}
 
-	CCodeExpression? serialize_array_dim (CCodeFragment fragment, ArrayType array_type, int dim, CCodeExpression array_expr, CCodeExpression array_iter_expr) {
+	CCodeExpression? serialize_array_dim (ArrayType array_type, int dim, CCodeExpression array_expr, CCodeExpression array_iter_expr) {
 		string builder_name = "_tmp%d_".printf (next_temp_var_id++);
 		string index_name = "_tmp%d_".printf (next_temp_var_id++);
 
-		var cdecl = new CCodeDeclaration ("GVariantBuilder");
-		cdecl.add_declarator (new CCodeVariableDeclarator (builder_name));
-		fragment.append (cdecl);
-
-		cdecl = new CCodeDeclaration ("int");
-		cdecl.add_declarator (new CCodeVariableDeclarator (index_name));
-		fragment.append (cdecl);
+		ccode.add_declaration ("GVariantBuilder", new CCodeVariableDeclarator (builder_name));
+		ccode.add_declaration ("int", new CCodeVariableDeclarator (index_name));
 
 		var builder_init = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_builder_init"));
 		builder_init.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (builder_name)));
 		builder_init.add_argument (new CCodeConstant ("\"%s\"".printf (get_type_signature (array_type))));
-		fragment.append (new CCodeExpressionStatement (builder_init));
+		ccode.add_expression (builder_init);
 
-		var cforblock = new CCodeBlock ();
-		var cforfragment = new CCodeFragment ();
-		cforblock.add_statement (cforfragment);
-		var cfor = new CCodeForStatement (new CCodeBinaryExpression (CCodeBinaryOperator.LESS_THAN, new CCodeIdentifier (index_name), get_array_length (array_expr, dim)), cforblock);
-		cfor.add_initializer (new CCodeAssignment (new CCodeIdentifier (index_name), new CCodeConstant ("0")));
-		cfor.add_iterator (new CCodeUnaryExpression (CCodeUnaryOperator.POSTFIX_INCREMENT, new CCodeIdentifier (index_name)));
+		var cforinit = new CCodeAssignment (new CCodeIdentifier (index_name), new CCodeConstant ("0"));
+		var cforcond = new CCodeBinaryExpression (CCodeBinaryOperator.LESS_THAN, new CCodeIdentifier (index_name), get_array_length (array_expr, dim));
+		var cforiter = new CCodeUnaryExpression (CCodeUnaryOperator.POSTFIX_INCREMENT, new CCodeIdentifier (index_name));
+		ccode.open_for (cforinit, cforcond, cforiter);
 
 		CCodeExpression element_variant;
 		if (dim < array_type.rank) {
-			element_variant = serialize_array_dim (cforfragment, array_type, dim + 1, array_expr, array_iter_expr);
+			element_variant = serialize_array_dim (array_type, dim + 1, array_expr, array_iter_expr);
 		} else {
 			var element_expr = new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, array_iter_expr);
-			element_variant = serialize_expression (cforfragment, array_type.element_type, element_expr);
+			element_variant = serialize_expression (array_type.element_type, element_expr);
 		}
 
 		var builder_add = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_builder_add_value"));
 		builder_add.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (builder_name)));
 		builder_add.add_argument (element_variant);
-		cforfragment.append (new CCodeExpressionStatement (builder_add));
+		ccode.add_expression (builder_add);
 
 		if (dim == array_type.rank) {
 			var array_iter_incr = new CCodeUnaryExpression (CCodeUnaryOperator.POSTFIX_INCREMENT, array_iter_expr);
-			cforfragment.append (new CCodeExpressionStatement (array_iter_incr));
+			ccode.add_expression (array_iter_incr);
 		}
 
-		fragment.append (cfor);
+		ccode.close ();
 
 		var builder_end = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_builder_end"));
 		builder_end.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (builder_name)));
 		return builder_end;
 	}
 
-	CCodeExpression? serialize_struct (CCodeFragment fragment, Struct st, CCodeExpression struct_expr) {
+	CCodeExpression? serialize_struct (Struct st, CCodeExpression struct_expr) {
 		string builder_name = "_tmp%d_".printf (next_temp_var_id++);
 
-		var cdecl = new CCodeDeclaration ("GVariantBuilder");
-		cdecl.add_declarator (new CCodeVariableDeclarator (builder_name));
-		fragment.append (cdecl);
+		ccode.add_declaration ("GVariantBuilder", new CCodeVariableDeclarator (builder_name));
 
 		var iter_call = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_builder_init"));
 		iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (builder_name)));
 		iter_call.add_argument (new CCodeIdentifier ("G_VARIANT_TYPE_TUPLE"));
-		fragment.append (new CCodeExpressionStatement (iter_call));
+		ccode.add_expression (iter_call);
 
 		bool field_found = false;;
 
@@ -681,7 +629,7 @@ public class Vala.GVariantModule : GAsyncModule {
 
 			field_found = true;
 
-			write_expression (fragment, f.variable_type, new CCodeIdentifier (builder_name), new CCodeMemberAccess (struct_expr, f.get_cname ()), f);
+			write_expression (f.variable_type, new CCodeIdentifier (builder_name), new CCodeMemberAccess (struct_expr, f.get_cname ()), f);
 		}
 
 		if (!field_found) {
@@ -693,7 +641,7 @@ public class Vala.GVariantModule : GAsyncModule {
 		return builder_end;
 	}
 
-	CCodeExpression serialize_hash_table (CCodeFragment fragment, ObjectType type, CCodeExpression hash_table_expr) {
+	CCodeExpression serialize_hash_table (ObjectType type, CCodeExpression hash_table_expr) {
 		string subiter_name = "_tmp%d_".printf (next_temp_var_id++);
 		string tableiter_name = "_tmp%d_".printf (next_temp_var_id++);
 		string key_name = "_tmp%d_".printf (next_temp_var_id++);
@@ -704,88 +652,72 @@ public class Vala.GVariantModule : GAsyncModule {
 		var key_type = type_args.get (0);
 		var value_type = type_args.get (1);
 
-		var cdecl = new CCodeDeclaration ("GVariantBuilder");
-		cdecl.add_declarator (new CCodeVariableDeclarator (subiter_name));
-		fragment.append (cdecl);
-
-		cdecl = new CCodeDeclaration ("GHashTableIter");
-		cdecl.add_declarator (new CCodeVariableDeclarator (tableiter_name));
-		fragment.append (cdecl);
-
-		cdecl = new CCodeDeclaration ("gpointer");
-		cdecl.add_declarator (new CCodeVariableDeclarator (key_name));
-		cdecl.add_declarator (new CCodeVariableDeclarator (value_name));
-		fragment.append (cdecl);
+		ccode.add_declaration ("GVariantBuilder", new CCodeVariableDeclarator (subiter_name));
+		ccode.add_declaration ("GHashTableIter", new CCodeVariableDeclarator (tableiter_name));
+		ccode.add_declaration ("gpointer", new CCodeVariableDeclarator (key_name));
+		ccode.add_declaration ("gpointer", new CCodeVariableDeclarator (value_name));
 
 		var iter_init_call = new CCodeFunctionCall (new CCodeIdentifier ("g_hash_table_iter_init"));
 		iter_init_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (tableiter_name)));
 		iter_init_call.add_argument (hash_table_expr);
-		fragment.append (new CCodeExpressionStatement (iter_init_call));
+		ccode.add_expression (iter_init_call);
 
 		var iter_call = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_builder_init"));
 		iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (subiter_name)));
 		iter_call.add_argument (new CCodeIdentifier ("G_VARIANT_TYPE_DICTIONARY"));
-		fragment.append (new CCodeExpressionStatement (iter_call));
+		ccode.add_expression (iter_call);
 
 		var iter_next_call = new CCodeFunctionCall (new CCodeIdentifier ("g_hash_table_iter_next"));
 		iter_next_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (tableiter_name)));
 		iter_next_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (key_name)));
 		iter_next_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (value_name)));
 
-		var cwhileblock = new CCodeBlock ();
-		var cwhilefragment = new CCodeFragment ();
-		cwhileblock.add_statement (cwhilefragment);
-		var cwhile = new CCodeWhileStatement (iter_next_call, cwhileblock);
-
-		cdecl = new CCodeDeclaration (key_type.get_cname ());
-		cdecl.add_declarator (new CCodeVariableDeclarator ("_key"));
-		cwhilefragment.append (cdecl);
+		ccode.open_while (iter_next_call);
 
-		cdecl = new CCodeDeclaration (value_type.get_cname ());
-		cdecl.add_declarator (new CCodeVariableDeclarator ("_value"));
-		cwhilefragment.append (cdecl);
+		ccode.add_declaration (key_type.get_cname (), new CCodeVariableDeclarator ("_key"));
+		ccode.add_declaration (value_type.get_cname (), new CCodeVariableDeclarator ("_value"));
 
-		cwhilefragment.append (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("_key"), convert_from_generic_pointer (new CCodeIdentifier (key_name), key_type))));
-		cwhilefragment.append (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("_value"), convert_from_generic_pointer (new CCodeIdentifier (value_name), value_type))));
+		ccode.add_expression (new CCodeAssignment (new CCodeIdentifier ("_key"), convert_from_generic_pointer (new CCodeIdentifier (key_name), key_type)));
+		ccode.add_expression (new CCodeAssignment (new CCodeIdentifier ("_value"), convert_from_generic_pointer (new CCodeIdentifier (value_name), value_type)));
 
 		iter_call = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_builder_add"));
 		iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (subiter_name)));
 		iter_call.add_argument (new CCodeConstant ("\"{?*}\""));
-		iter_call.add_argument (serialize_expression (cwhilefragment, key_type, new CCodeIdentifier ("_key")));
-		iter_call.add_argument (serialize_expression (cwhilefragment, value_type, new CCodeIdentifier ("_value")));
-		cwhilefragment.append (new CCodeExpressionStatement (iter_call));
+		iter_call.add_argument (serialize_expression (key_type, new CCodeIdentifier ("_key")));
+		iter_call.add_argument (serialize_expression (value_type, new CCodeIdentifier ("_value")));
+		ccode.add_expression (iter_call);
 
-		fragment.append (cwhile);
+		ccode.close ();
 
 		iter_call = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_builder_end"));
 		iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (subiter_name)));
 		return iter_call;
 	}
 
-	public override CCodeExpression? serialize_expression (CCodeFragment fragment, DataType type, CCodeExpression expr) {
+	public override CCodeExpression? serialize_expression (DataType type, CCodeExpression expr) {
 		BasicTypeInfo basic_type;
 		CCodeExpression result = null;
 		if (is_string_marshalled_enum (type.data_type)) {
 			get_basic_type_info ("s", out basic_type);
-			result = generate_enum_value_to_string (fragment, type as EnumValueType, expr);
-			result = serialize_basic (fragment, basic_type, result);
+			result = generate_enum_value_to_string (type as EnumValueType, expr);
+			result = serialize_basic (basic_type, result);
 		} else if (get_basic_type_info (get_type_signature (type), out basic_type)) {
-			result = serialize_basic (fragment, basic_type, expr);
+			result = serialize_basic (basic_type, expr);
 		} else if (type is ArrayType) {
-			result = serialize_array (fragment, (ArrayType) type, expr);
+			result = serialize_array ((ArrayType) type, expr);
 		} else if (type.data_type is Struct) {
 			var st_expr = expr;
 			if (type.nullable) {
 				st_expr = new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, st_expr);
 			}
-			result = serialize_struct (fragment, (Struct) type.data_type, st_expr);
+			result = serialize_struct ((Struct) type.data_type, st_expr);
 		} else if (type is ObjectType) {
 			if (type.data_type.get_full_name () == "GLib.Variant") {
 				var variant_new = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_new_variant"));
 				variant_new.add_argument (expr);
 				result = variant_new;
 			} else if (type.data_type.get_full_name () == "GLib.HashTable") {
-				result = serialize_hash_table (fragment, (ObjectType) type, expr);
+				result = serialize_hash_table ((ObjectType) type, expr);
 			}
 		}
 
@@ -796,17 +728,17 @@ public class Vala.GVariantModule : GAsyncModule {
 		return result;
 	}
 
-	public void write_expression (CCodeFragment fragment, DataType type, CCodeExpression builder_expr, CCodeExpression expr, Symbol? sym) {
+	public void write_expression (DataType type, CCodeExpression builder_expr, CCodeExpression expr, Symbol? sym) {
 		var variant_expr = expr;
 		if (sym == null || get_dbus_signature (sym) == null) {
 			// perform boxing
-			variant_expr = serialize_expression (fragment, type, expr);
+			variant_expr = serialize_expression (type, expr);
 		}
 		if (variant_expr != null) {
 			var builder_add = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_builder_add_value"));
 			builder_add.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, builder_expr));
 			builder_add.add_argument (variant_expr);
-			fragment.append (new CCodeExpressionStatement (builder_add));
+			ccode.add_expression (builder_add);
 		}
 	}
 }



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