From: Jürg Billeter Date: Thu, 6 Nov 2008 19:24:23 +0000 (+0000) Subject: Move dynamic property generation to GObjectModule and DBusClientModule X-Git-Tag: VALA_0_5_2~122 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=965530de59d1f4d9d85e3e1ff8be5e406dfb58ee;p=thirdparty%2Fvala.git Move dynamic property generation to GObjectModule and DBusClientModule 2008-11-06 Jürg Billeter * gobject/Makefile.am: * gobject/valaccodedynamicpropertymodule.vala: * gobject/valaccodedynamicsignalmodule.vala: * gobject/valaccodegenerator.vala: * gobject/valadbusclientmodule.vala: * gobject/valagobjectmodule.vala: Move dynamic property generation to GObjectModule and DBusClientModule svn path=/trunk/; revision=1989 --- diff --git a/ChangeLog b/ChangeLog index 5e5c93171..b2e062eef 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2008-11-06 Jürg Billeter + + * gobject/Makefile.am: + * gobject/valaccodedynamicpropertymodule.vala: + * gobject/valaccodedynamicsignalmodule.vala: + * gobject/valaccodegenerator.vala: + * gobject/valadbusclientmodule.vala: + * gobject/valagobjectmodule.vala: + + Move dynamic property generation to GObjectModule and + DBusClientModule + 2008-11-06 Jürg Billeter * gobject/valaccodebasemodule.vala: diff --git a/gobject/Makefile.am b/gobject/Makefile.am index f7b57fd57..dbffebbaa 100644 --- a/gobject/Makefile.am +++ b/gobject/Makefile.am @@ -18,7 +18,6 @@ libvala_la_VALASOURCES = \ valaccodecompiler.vala \ valaccodecontrolflowmodule.vala \ valaccodedelegatemodule.vala \ - valaccodedynamicpropertymodule.vala \ valaccodedynamicsignalmodule.vala \ valaccodegenerator.vala \ valaccodeinvocationexpressionmodule.vala \ diff --git a/gobject/valaccodedynamicpropertymodule.vala b/gobject/valaccodedynamicpropertymodule.vala deleted file mode 100644 index cad5f3d27..000000000 --- a/gobject/valaccodedynamicpropertymodule.vala +++ /dev/null @@ -1,238 +0,0 @@ -/* valaccodedynamicpropertymodule.vala - * - * Copyright (C) 2008 Jürg Billeter - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Author: - * Jürg Billeter - */ - -using GLib; -using Gee; - -/** - * The link between a dynamic property and generated code. - */ -public class Vala.CCodeDynamicPropertyModule : CCodeDelegateModule { - int dynamic_property_id; - - public CCodeDynamicPropertyModule (CCodeGenerator codegen, CCodeModule? next) { - base (codegen, next); - } - - public override string get_dynamic_property_getter_cname (DynamicProperty node) { - string getter_cname = "_dynamic_get_%s%d".printf (node.name, dynamic_property_id++); - - var dynamic_property = (DynamicProperty) node; - - var func = new CCodeFunction (getter_cname, node.property_type.get_cname ()); - func.modifiers |= CCodeModifiers.STATIC | CCodeModifiers.INLINE; - - func.add_parameter (new CCodeFormalParameter ("obj", dynamic_property.dynamic_type.get_cname ())); - - var block = new CCodeBlock (); - if (dynamic_property.dynamic_type.data_type == dbus_object_type) { - generate_dbus_property_getter_wrapper (node, block); - } else if (dynamic_property.dynamic_type.data_type != null - && dynamic_property.dynamic_type.data_type.is_subtype_of (gobject_type)) { - generate_gobject_property_getter_wrapper (node, block); - } else { - Report.error (node.source_reference, "dynamic properties are not supported for `%s'".printf (dynamic_property.dynamic_type.to_string ())); - } - - // append to C source file - source_type_member_declaration.append (func.copy ()); - - func.block = block; - source_type_member_definition.append (func); - - return getter_cname; - } - - public override string get_dynamic_property_setter_cname (DynamicProperty node) { - string setter_cname = "_dynamic_set_%s%d".printf (node.name, dynamic_property_id++); - - var dynamic_property = (DynamicProperty) node; - - var func = new CCodeFunction (setter_cname, "void"); - func.modifiers |= CCodeModifiers.STATIC | CCodeModifiers.INLINE; - - func.add_parameter (new CCodeFormalParameter ("obj", dynamic_property.dynamic_type.get_cname ())); - func.add_parameter (new CCodeFormalParameter ("value", node.property_type.get_cname ())); - - var block = new CCodeBlock (); - if (dynamic_property.dynamic_type.data_type == dbus_object_type) { - generate_dbus_property_setter_wrapper (node, block); - } else if (dynamic_property.dynamic_type.data_type != null - && dynamic_property.dynamic_type.data_type.is_subtype_of (gobject_type)) { - generate_gobject_property_setter_wrapper (node, block); - } else { - Report.error (node.source_reference, "dynamic properties are not supported for `%s'".printf (dynamic_property.dynamic_type.to_string ())); - } - - // append to C source file - source_type_member_declaration.append (func.copy ()); - - func.block = block; - source_type_member_definition.append (func); - - return setter_cname; - } - - void generate_gobject_property_getter_wrapper (DynamicProperty node, CCodeBlock block) { - var cdecl = new CCodeDeclaration (node.property_type.get_cname ()); - cdecl.add_declarator (new CCodeVariableDeclarator ("result")); - block.add_statement (cdecl); - - var call = new CCodeFunctionCall (new CCodeIdentifier ("g_object_get")); - call.add_argument (new CCodeIdentifier ("obj")); - call.add_argument (node.get_canonical_cconstant ()); - call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("result"))); - call.add_argument (new CCodeConstant ("NULL")); - - block.add_statement (new CCodeExpressionStatement (call)); - - block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("result"))); - } - - void generate_gobject_property_setter_wrapper (DynamicProperty node, CCodeBlock block) { - var call = new CCodeFunctionCall (new CCodeIdentifier ("g_object_set")); - call.add_argument (new CCodeIdentifier ("obj")); - call.add_argument (node.get_canonical_cconstant ()); - call.add_argument (new CCodeIdentifier ("value")); - call.add_argument (new CCodeConstant ("NULL")); - - block.add_statement (new CCodeExpressionStatement (call)); - } - - void create_dbus_property_proxy (DynamicProperty node, CCodeBlock block) { - var prop_proxy_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_proxy_new_from_proxy")); - prop_proxy_call.add_argument (new CCodeIdentifier ("obj")); - prop_proxy_call.add_argument (new CCodeConstant ("DBUS_INTERFACE_PROPERTIES")); - prop_proxy_call.add_argument (new CCodeConstant ("NULL")); - - var prop_proxy_decl = new CCodeDeclaration ("DBusGProxy*"); - prop_proxy_decl.add_declarator (new CCodeVariableDeclarator.with_initializer ("property_proxy", prop_proxy_call)); - block.add_statement (prop_proxy_decl); - } - - void generate_dbus_property_getter_wrapper (DynamicProperty node, CCodeBlock block) { - create_dbus_property_proxy (node, block); - - // initialize GValue - var cvalinit = new CCodeInitializerList (); - cvalinit.append (new CCodeConstant ("0")); - - var cval_decl = new CCodeDeclaration ("GValue"); - cval_decl.add_declarator (new CCodeVariableDeclarator.with_initializer ("gvalue", cvalinit)); - block.add_statement (cval_decl); - - var val_ptr = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("gvalue")); - - // call Get method on property proxy - var cdecl = new CCodeDeclaration (node.property_type.get_cname ()); - cdecl.add_declarator (new CCodeVariableDeclarator ("result")); - block.add_statement (cdecl); - - var ccall = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_proxy_call")); - ccall.add_argument (new CCodeIdentifier ("property_proxy")); - ccall.add_argument (new CCodeConstant ("\"Get\"")); - ccall.add_argument (new CCodeConstant ("NULL")); - - ccall.add_argument (new CCodeIdentifier ("G_TYPE_STRING")); - var get_iface = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_proxy_get_interface")); - get_iface.add_argument (new CCodeIdentifier ("obj")); - ccall.add_argument (get_iface); - - ccall.add_argument (new CCodeIdentifier ("G_TYPE_STRING")); - ccall.add_argument (new CCodeConstant ("\"%s\"".printf (Symbol.lower_case_to_camel_case (node.name)))); - - ccall.add_argument (new CCodeIdentifier ("G_TYPE_INVALID")); - - ccall.add_argument (new CCodeIdentifier ("G_TYPE_VALUE")); - ccall.add_argument (val_ptr); - - ccall.add_argument (new CCodeIdentifier ("G_TYPE_INVALID")); - - block.add_statement (new CCodeExpressionStatement (ccall)); - - // unref property proxy - var prop_proxy_unref = new CCodeFunctionCall (new CCodeIdentifier ("g_object_unref")); - prop_proxy_unref.add_argument (new CCodeIdentifier ("property_proxy")); - block.add_statement (new CCodeExpressionStatement (prop_proxy_unref)); - - // assign value to result variable - var cget_call = new CCodeFunctionCall (new CCodeIdentifier (node.property_type.data_type.get_get_value_function ())); - cget_call.add_argument (val_ptr); - var assign = new CCodeAssignment (new CCodeIdentifier ("result"), cget_call); - block.add_statement (new CCodeExpressionStatement (assign)); - - // return result - block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("result"))); - } - - void generate_dbus_property_setter_wrapper (DynamicProperty node, CCodeBlock block) { - create_dbus_property_proxy (node, block); - - // initialize GValue - var cvalinit = new CCodeInitializerList (); - cvalinit.append (new CCodeConstant ("0")); - - var cval_decl = new CCodeDeclaration ("GValue"); - cval_decl.add_declarator (new CCodeVariableDeclarator.with_initializer ("gvalue", cvalinit)); - block.add_statement (cval_decl); - - var val_ptr = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("gvalue")); - - var cinit_call = new CCodeFunctionCall (new CCodeIdentifier ("g_value_init")); - cinit_call.add_argument (val_ptr); - cinit_call.add_argument (new CCodeIdentifier (node.property_type.data_type.get_type_id ())); - block.add_statement (new CCodeExpressionStatement (cinit_call)); - - var cset_call = new CCodeFunctionCall (new CCodeIdentifier (node.property_type.data_type.get_set_value_function ())); - cset_call.add_argument (val_ptr); - cset_call.add_argument (new CCodeIdentifier ("value")); - block.add_statement (new CCodeExpressionStatement (cset_call)); - - // call Set method on property proxy - var ccall = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_proxy_call")); - ccall.add_argument (new CCodeIdentifier ("property_proxy")); - ccall.add_argument (new CCodeConstant ("\"Set\"")); - ccall.add_argument (new CCodeConstant ("NULL")); - - ccall.add_argument (new CCodeIdentifier ("G_TYPE_STRING")); - var get_iface = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_proxy_get_interface")); - get_iface.add_argument (new CCodeIdentifier ("obj")); - ccall.add_argument (get_iface); - - ccall.add_argument (new CCodeIdentifier ("G_TYPE_STRING")); - ccall.add_argument (new CCodeConstant ("\"%s\"".printf (Symbol.lower_case_to_camel_case (node.name)))); - - ccall.add_argument (new CCodeIdentifier ("G_TYPE_VALUE")); - ccall.add_argument (val_ptr); - - ccall.add_argument (new CCodeIdentifier ("G_TYPE_INVALID")); - - ccall.add_argument (new CCodeIdentifier ("G_TYPE_INVALID")); - - block.add_statement (new CCodeExpressionStatement (ccall)); - - // unref property proxy - var prop_proxy_unref = new CCodeFunctionCall (new CCodeIdentifier ("g_object_unref")); - prop_proxy_unref.add_argument (new CCodeIdentifier ("property_proxy")); - block.add_statement (new CCodeExpressionStatement (prop_proxy_unref)); - } -} diff --git a/gobject/valaccodedynamicsignalmodule.vala b/gobject/valaccodedynamicsignalmodule.vala index d6647988c..077752ab3 100644 --- a/gobject/valaccodedynamicsignalmodule.vala +++ b/gobject/valaccodedynamicsignalmodule.vala @@ -26,7 +26,7 @@ using Gee; /** * The link between a dynamic signal and generated code. */ -public class Vala.CCodeDynamicSignalModule : CCodeDynamicPropertyModule { +public class Vala.CCodeDynamicSignalModule : CCodeDelegateModule { public CCodeDynamicSignalModule (CCodeGenerator codegen, CCodeModule? next) { base (codegen, next); } diff --git a/gobject/valaccodegenerator.vala b/gobject/valaccodegenerator.vala index 5c53bb787..aaa3f615c 100644 --- a/gobject/valaccodegenerator.vala +++ b/gobject/valaccodegenerator.vala @@ -41,7 +41,6 @@ public class Vala.CCodeGenerator : CodeGenerator { head = new CCodeInvocationExpressionModule (this, head); head = new CCodeArrayModule (this, head); head = new CCodeDelegateModule (this, head); - head = new CCodeDynamicPropertyModule (this, head); head = new CCodeDynamicSignalModule (this, head); head = new GErrorModule (this, head); head = new GTypeModule (this, head); diff --git a/gobject/valadbusclientmodule.vala b/gobject/valadbusclientmodule.vala index c4dc2564f..e49be5d4f 100644 --- a/gobject/valadbusclientmodule.vala +++ b/gobject/valadbusclientmodule.vala @@ -29,6 +29,8 @@ using Gee; * The link between a dynamic method and generated code. */ public class Vala.DBusClientModule : GAsyncModule { + int dynamic_property_id; + public DBusClientModule (CCodeGenerator codegen, CCodeModule? next) { base (codegen, next); } @@ -509,4 +511,171 @@ public class Vala.DBusClientModule : GAsyncModule { return true; } } + + public override string get_dynamic_property_getter_cname (DynamicProperty prop) { + if (prop.dynamic_type.data_type != dbus_object_type) { + return base.get_dynamic_property_getter_cname (prop); + } + + string getter_cname = "_dynamic_get_%s%d".printf (prop.name, dynamic_property_id++); + + var func = new CCodeFunction (getter_cname, prop.property_type.get_cname ()); + func.modifiers |= CCodeModifiers.STATIC | CCodeModifiers.INLINE; + + func.add_parameter (new CCodeFormalParameter ("obj", prop.dynamic_type.get_cname ())); + + var block = new CCodeBlock (); + generate_dbus_property_getter_wrapper (prop, block); + + // append to C source file + source_type_member_declaration.append (func.copy ()); + + func.block = block; + source_type_member_definition.append (func); + + return getter_cname; + } + + public override string get_dynamic_property_setter_cname (DynamicProperty prop) { + if (prop.dynamic_type.data_type != dbus_object_type) { + return base.get_dynamic_property_setter_cname (prop); + } + + string setter_cname = "_dynamic_set_%s%d".printf (prop.name, dynamic_property_id++); + + var func = new CCodeFunction (setter_cname, "void"); + func.modifiers |= CCodeModifiers.STATIC | CCodeModifiers.INLINE; + + func.add_parameter (new CCodeFormalParameter ("obj", prop.dynamic_type.get_cname ())); + func.add_parameter (new CCodeFormalParameter ("value", prop.property_type.get_cname ())); + + var block = new CCodeBlock (); + generate_dbus_property_setter_wrapper (prop, block); + + // append to C source file + source_type_member_declaration.append (func.copy ()); + + func.block = block; + source_type_member_definition.append (func); + + return setter_cname; + } + + void create_dbus_property_proxy (DynamicProperty node, CCodeBlock block) { + var prop_proxy_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_proxy_new_from_proxy")); + prop_proxy_call.add_argument (new CCodeIdentifier ("obj")); + prop_proxy_call.add_argument (new CCodeConstant ("DBUS_INTERFACE_PROPERTIES")); + prop_proxy_call.add_argument (new CCodeConstant ("NULL")); + + var prop_proxy_decl = new CCodeDeclaration ("DBusGProxy*"); + prop_proxy_decl.add_declarator (new CCodeVariableDeclarator.with_initializer ("property_proxy", prop_proxy_call)); + block.add_statement (prop_proxy_decl); + } + + void generate_dbus_property_getter_wrapper (DynamicProperty node, CCodeBlock block) { + create_dbus_property_proxy (node, block); + + // initialize GValue + var cvalinit = new CCodeInitializerList (); + cvalinit.append (new CCodeConstant ("0")); + + var cval_decl = new CCodeDeclaration ("GValue"); + cval_decl.add_declarator (new CCodeVariableDeclarator.with_initializer ("gvalue", cvalinit)); + block.add_statement (cval_decl); + + var val_ptr = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("gvalue")); + + // call Get method on property proxy + var cdecl = new CCodeDeclaration (node.property_type.get_cname ()); + cdecl.add_declarator (new CCodeVariableDeclarator ("result")); + block.add_statement (cdecl); + + var ccall = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_proxy_call")); + ccall.add_argument (new CCodeIdentifier ("property_proxy")); + ccall.add_argument (new CCodeConstant ("\"Get\"")); + ccall.add_argument (new CCodeConstant ("NULL")); + + ccall.add_argument (new CCodeIdentifier ("G_TYPE_STRING")); + var get_iface = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_proxy_get_interface")); + get_iface.add_argument (new CCodeIdentifier ("obj")); + ccall.add_argument (get_iface); + + ccall.add_argument (new CCodeIdentifier ("G_TYPE_STRING")); + ccall.add_argument (new CCodeConstant ("\"%s\"".printf (Symbol.lower_case_to_camel_case (node.name)))); + + ccall.add_argument (new CCodeIdentifier ("G_TYPE_INVALID")); + + ccall.add_argument (new CCodeIdentifier ("G_TYPE_VALUE")); + ccall.add_argument (val_ptr); + + ccall.add_argument (new CCodeIdentifier ("G_TYPE_INVALID")); + + block.add_statement (new CCodeExpressionStatement (ccall)); + + // unref property proxy + var prop_proxy_unref = new CCodeFunctionCall (new CCodeIdentifier ("g_object_unref")); + prop_proxy_unref.add_argument (new CCodeIdentifier ("property_proxy")); + block.add_statement (new CCodeExpressionStatement (prop_proxy_unref)); + + // assign value to result variable + var cget_call = new CCodeFunctionCall (new CCodeIdentifier (node.property_type.data_type.get_get_value_function ())); + cget_call.add_argument (val_ptr); + var assign = new CCodeAssignment (new CCodeIdentifier ("result"), cget_call); + block.add_statement (new CCodeExpressionStatement (assign)); + + // return result + block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("result"))); + } + + void generate_dbus_property_setter_wrapper (DynamicProperty node, CCodeBlock block) { + create_dbus_property_proxy (node, block); + + // initialize GValue + var cvalinit = new CCodeInitializerList (); + cvalinit.append (new CCodeConstant ("0")); + + var cval_decl = new CCodeDeclaration ("GValue"); + cval_decl.add_declarator (new CCodeVariableDeclarator.with_initializer ("gvalue", cvalinit)); + block.add_statement (cval_decl); + + var val_ptr = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("gvalue")); + + var cinit_call = new CCodeFunctionCall (new CCodeIdentifier ("g_value_init")); + cinit_call.add_argument (val_ptr); + cinit_call.add_argument (new CCodeIdentifier (node.property_type.data_type.get_type_id ())); + block.add_statement (new CCodeExpressionStatement (cinit_call)); + + var cset_call = new CCodeFunctionCall (new CCodeIdentifier (node.property_type.data_type.get_set_value_function ())); + cset_call.add_argument (val_ptr); + cset_call.add_argument (new CCodeIdentifier ("value")); + block.add_statement (new CCodeExpressionStatement (cset_call)); + + // call Set method on property proxy + var ccall = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_proxy_call")); + ccall.add_argument (new CCodeIdentifier ("property_proxy")); + ccall.add_argument (new CCodeConstant ("\"Set\"")); + ccall.add_argument (new CCodeConstant ("NULL")); + + ccall.add_argument (new CCodeIdentifier ("G_TYPE_STRING")); + var get_iface = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_proxy_get_interface")); + get_iface.add_argument (new CCodeIdentifier ("obj")); + ccall.add_argument (get_iface); + + ccall.add_argument (new CCodeIdentifier ("G_TYPE_STRING")); + ccall.add_argument (new CCodeConstant ("\"%s\"".printf (Symbol.lower_case_to_camel_case (node.name)))); + + ccall.add_argument (new CCodeIdentifier ("G_TYPE_VALUE")); + ccall.add_argument (val_ptr); + + ccall.add_argument (new CCodeIdentifier ("G_TYPE_INVALID")); + + ccall.add_argument (new CCodeIdentifier ("G_TYPE_INVALID")); + + block.add_statement (new CCodeExpressionStatement (ccall)); + + // unref property proxy + var prop_proxy_unref = new CCodeFunctionCall (new CCodeIdentifier ("g_object_unref")); + prop_proxy_unref.add_argument (new CCodeIdentifier ("property_proxy")); + block.add_statement (new CCodeExpressionStatement (prop_proxy_unref)); + } } diff --git a/gobject/valagobjectmodule.vala b/gobject/valagobjectmodule.vala index ae2d1eb78..3d9ac125b 100644 --- a/gobject/valagobjectmodule.vala +++ b/gobject/valagobjectmodule.vala @@ -24,6 +24,8 @@ using GLib; public class Vala.GObjectModule : GTypeModule { + int dynamic_property_id; + public GObjectModule (CCodeGenerator codegen, CCodeModule? next) { base (codegen, next); } @@ -1610,5 +1612,82 @@ public class Vala.GObjectModule : GTypeModule { Report.error (c.source_reference, "internal error: constructors must have instance, class, or static binding"); } } + + public override string get_dynamic_property_getter_cname (DynamicProperty prop) { + if (prop.dynamic_type.data_type == null + || !prop.dynamic_type.data_type.is_subtype_of (gobject_type)) { + return base.get_dynamic_property_getter_cname (prop); + } + + string getter_cname = "_dynamic_get_%s%d".printf (prop.name, dynamic_property_id++); + + var func = new CCodeFunction (getter_cname, prop.property_type.get_cname ()); + func.modifiers |= CCodeModifiers.STATIC | CCodeModifiers.INLINE; + + func.add_parameter (new CCodeFormalParameter ("obj", prop.dynamic_type.get_cname ())); + + var block = new CCodeBlock (); + generate_gobject_property_getter_wrapper (prop, block); + + // append to C source file + source_type_member_declaration.append (func.copy ()); + + func.block = block; + source_type_member_definition.append (func); + + return getter_cname; + } + + public override string get_dynamic_property_setter_cname (DynamicProperty prop) { + if (prop.dynamic_type.data_type == null + || !prop.dynamic_type.data_type.is_subtype_of (gobject_type)) { + return base.get_dynamic_property_setter_cname (prop); + } + + string setter_cname = "_dynamic_set_%s%d".printf (prop.name, dynamic_property_id++); + + var func = new CCodeFunction (setter_cname, "void"); + func.modifiers |= CCodeModifiers.STATIC | CCodeModifiers.INLINE; + + func.add_parameter (new CCodeFormalParameter ("obj", prop.dynamic_type.get_cname ())); + func.add_parameter (new CCodeFormalParameter ("value", prop.property_type.get_cname ())); + + var block = new CCodeBlock (); + generate_gobject_property_setter_wrapper (prop, block); + + // append to C source file + source_type_member_declaration.append (func.copy ()); + + func.block = block; + source_type_member_definition.append (func); + + return setter_cname; + } + + void generate_gobject_property_getter_wrapper (DynamicProperty node, CCodeBlock block) { + var cdecl = new CCodeDeclaration (node.property_type.get_cname ()); + cdecl.add_declarator (new CCodeVariableDeclarator ("result")); + block.add_statement (cdecl); + + var call = new CCodeFunctionCall (new CCodeIdentifier ("g_object_get")); + call.add_argument (new CCodeIdentifier ("obj")); + call.add_argument (node.get_canonical_cconstant ()); + call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("result"))); + call.add_argument (new CCodeConstant ("NULL")); + + block.add_statement (new CCodeExpressionStatement (call)); + + block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("result"))); + } + + void generate_gobject_property_setter_wrapper (DynamicProperty node, CCodeBlock block) { + var call = new CCodeFunctionCall (new CCodeIdentifier ("g_object_set")); + call.add_argument (new CCodeIdentifier ("obj")); + call.add_argument (node.get_canonical_cconstant ()); + call.add_argument (new CCodeIdentifier ("value")); + call.add_argument (new CCodeConstant ("NULL")); + + block.add_statement (new CCodeExpressionStatement (call)); + } }