]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
codegen: Use builder API in GVariant and GDBus modules
authorJürg Billeter <j@bitron.ch>
Sun, 10 Oct 2010 16:20:45 +0000 (18:20 +0200)
committerJürg Billeter <j@bitron.ch>
Sun, 10 Oct 2010 16:20:45 +0000 (18:20 +0200)
codegen/valaccodebasemodule.vala
codegen/valagdbusclientmodule.vala
codegen/valagdbusservermodule.vala
codegen/valagvariantmodule.vala

index baf58a6775e749846a959af3993dc9b44ed9a121..564af4abacbf2748eb0fb0d734d6e1d3b26543f2 100644 (file)
@@ -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;
index f3b385e03fa8fce704047c38aa0313f4190fbe87..dd35c09f5759c09d0cc2c48588533682276eabcd 100644 (file)
@@ -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;
index abe9ed1f3363127d6f58fc6ffef3465716a1c8c0..bf5fe2c1f2a1d065d69c65029ec83d50dbca6885 100644 (file)
@@ -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;
index 859c47491d5fc89536f8fa495205d06a12ed86da..a8a3e9eda1a01fdb14e4ed736676d772cb196b30 100644 (file)
@@ -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);
                }
        }
 }