Commit f371f443 authored by Jürg Billeter's avatar Jürg Billeter Committed by Jürg Billeter
Browse files

add experimental D-Bus client support

2007-08-06  Juerg Billeter  <j@bitron.ch>

	* vala/Makefile.am, vala/parser.y, vala/valaarray.vala,
	  vala/valabindingprovider.vala, vala/valaclass.vala,
	  vala/valaenum.vala, vala/valainterface.vala,
	  vala/valamemorymanager.vala, vala/valamethod.vala,
	  vala/valasemanticanalyzer.vala, vala/valasymbol.vala,
	  vala/valasymbolresolver.vala, vala/valavariabledeclarator.vala,
	  gobject/Makefile.am, gobject/valacodegenerator.vala,
	  gobject/valacodegeneratorassignment.vala,
	  gobject/valacodegeneratorclass.vala,
	  gobject/valacodegeneratorinterface.vala,
	  gobject/valacodegeneratorinvocationexpression.vala,
	  gobject/valacodegeneratormethod.vala,
	  gobject/valadbusbindingprovider.vala, gobject/valadbusmethod.vala,
	  gobject/valadbussignal.vala, compiler/valacompiler.vala,
	  vapi/dbus-glib-1.vala, vapi/hal.vala: add experimental D-Bus client
	  support

svn path=/trunk/; revision=419
parent fa628f64
2007-08-06 Jürg Billeter <j@bitron.ch>
* vala/Makefile.am, vala/parser.y, vala/valaarray.vala,
vala/valabindingprovider.vala, vala/valaclass.vala,
vala/valaenum.vala, vala/valainterface.vala,
vala/valamemorymanager.vala, vala/valamethod.vala,
vala/valasemanticanalyzer.vala, vala/valasymbol.vala,
vala/valasymbolresolver.vala, vala/valavariabledeclarator.vala,
gobject/Makefile.am, gobject/valacodegenerator.vala,
gobject/valacodegeneratorassignment.vala,
gobject/valacodegeneratorclass.vala,
gobject/valacodegeneratorinterface.vala,
gobject/valacodegeneratorinvocationexpression.vala,
gobject/valacodegeneratormethod.vala,
gobject/valadbusbindingprovider.vala, gobject/valadbusmethod.vala,
gobject/valadbussignal.vala, compiler/valacompiler.vala,
vapi/dbus-glib-1.vala, vapi/hal.vala: add experimental D-Bus client
support
2007-08-06 Jürg Billeter <j@bitron.ch> 2007-08-06 Jürg Billeter <j@bitron.ch>
* gobject/valacodegenerator.vala, * gobject/valacodegenerator.vala,
......
...@@ -217,8 +217,12 @@ class Vala.Compiler { ...@@ -217,8 +217,12 @@ class Vala.Compiler {
if (Report.get_errors () > 0) { if (Report.get_errors () > 0) {
return quit (); return quit ();
} }
var dbus_binding_provider = new DBusBindingProvider ();
dbus_binding_provider.context = context;
var analyzer = new SemanticAnalyzer (!disable_memory_management); var analyzer = new SemanticAnalyzer (!disable_memory_management);
analyzer.add_binding_provider (dbus_binding_provider);
analyzer.analyze (context); analyzer.analyze (context);
if (Report.get_errors () > 0) { if (Report.get_errors () > 0) {
......
...@@ -48,6 +48,15 @@ libvala_la_SOURCES = \ ...@@ -48,6 +48,15 @@ libvala_la_SOURCES = \
valacodegeneratorstruct.c \ valacodegeneratorstruct.c \
valacodegeneratorstruct.h \ valacodegeneratorstruct.h \
valacodegeneratorstruct.vala \ valacodegeneratorstruct.vala \
valadbusbindingprovider.c \
valadbusbindingprovider.h \
valadbusbindingprovider.vala \
valadbusmethod.c \
valadbusmethod.h \
valadbusmethod.vala \
valadbussignal.c \
valadbussignal.h \
valadbussignal.vala \
valainterfaceregisterfunction.c \ valainterfaceregisterfunction.c \
valainterfaceregisterfunction.h \ valainterfaceregisterfunction.h \
valainterfaceregisterfunction.vala \ valainterfaceregisterfunction.vala \
...@@ -71,6 +80,9 @@ gobjectinclude_HEADERS = \ ...@@ -71,6 +80,9 @@ gobjectinclude_HEADERS = \
valacodegeneratorsignal.h \ valacodegeneratorsignal.h \
valacodegeneratorsourcefile.h \ valacodegeneratorsourcefile.h \
valacodegeneratorstruct.h \ valacodegeneratorstruct.h \
valadbusbindingprovider.h \
valadbusmethod.h \
valadbussignal.h \
valainterfaceregisterfunction.h \ valainterfaceregisterfunction.h \
valatyperegisterfunction.h \ valatyperegisterfunction.h \
$(NULL) $(NULL)
......
...@@ -99,12 +99,14 @@ public class Vala.CodeGenerator : CodeVisitor { ...@@ -99,12 +99,14 @@ public class Vala.CodeGenerator : CodeVisitor {
DataType glist_type; DataType glist_type;
DataType gslist_type; DataType gslist_type;
DataType gstring_type; DataType gstring_type;
DataType garray_type;
TypeReference mutex_type; TypeReference mutex_type;
DataType type_module_type; DataType type_module_type;
DataType iterable_type; DataType iterable_type;
DataType iterator_type; DataType iterator_type;
DataType list_type; DataType list_type;
DataType map_type; DataType map_type;
DataType connection_type;
Method substring_method; Method substring_method;
...@@ -246,6 +248,7 @@ public class Vala.CodeGenerator : CodeVisitor { ...@@ -246,6 +248,7 @@ public class Vala.CodeGenerator : CodeVisitor {
glist_type = (DataType) glib_ns.scope.lookup ("List"); glist_type = (DataType) glib_ns.scope.lookup ("List");
gslist_type = (DataType) glib_ns.scope.lookup ("SList"); gslist_type = (DataType) glib_ns.scope.lookup ("SList");
gstring_type = (DataType) glib_ns.scope.lookup ("String"); gstring_type = (DataType) glib_ns.scope.lookup ("String");
garray_type = (DataType) glib_ns.scope.lookup ("Array");
mutex_type = new TypeReference (); mutex_type = new TypeReference ();
mutex_type.data_type = (DataType) glib_ns.scope.lookup ("Mutex"); mutex_type.data_type = (DataType) glib_ns.scope.lookup ("Mutex");
...@@ -270,6 +273,11 @@ public class Vala.CodeGenerator : CodeVisitor { ...@@ -270,6 +273,11 @@ public class Vala.CodeGenerator : CodeVisitor {
list_type = (DataType) gee_ns.scope.lookup ("List"); list_type = (DataType) gee_ns.scope.lookup ("List");
map_type = (DataType) gee_ns.scope.lookup ("Map"); map_type = (DataType) gee_ns.scope.lookup ("Map");
} }
var dbus_ns = root_symbol.scope.lookup ("DBus");
if (dbus_ns != null) {
connection_type = (DataType) dbus_ns.scope.lookup ("Connection");
}
/* we're only interested in non-pkg source files */ /* we're only interested in non-pkg source files */
var source_files = context.get_source_files (); var source_files = context.get_source_files ();
...@@ -807,6 +815,8 @@ public class Vala.CodeGenerator : CodeVisitor { ...@@ -807,6 +815,8 @@ public class Vala.CodeGenerator : CodeVisitor {
} }
public override void visit_variable_declarator (VariableDeclarator! decl) { public override void visit_variable_declarator (VariableDeclarator! decl) {
decl.accept_children (this);
if (decl.type_reference.data_type is Array) { if (decl.type_reference.data_type is Array) {
// create variables to store array dimensions // create variables to store array dimensions
var arr = (Array) decl.type_reference.data_type; var arr = (Array) decl.type_reference.data_type;
......
...@@ -125,12 +125,20 @@ public class Vala.CodeGenerator { ...@@ -125,12 +125,20 @@ public class Vala.CodeGenerator {
bool disconnect = false; bool disconnect = false;
if (a.operator == AssignmentOperator.ADD) { if (a.operator == AssignmentOperator.ADD) {
connect_func = "g_signal_connect_object"; if (sig is DBusSignal) {
if (!m.instance) { connect_func = "dbus_g_proxy_connect_signal";
connect_func = "g_signal_connect"; } else {
connect_func = "g_signal_connect_object";
if (!m.instance) {
connect_func = "g_signal_connect";
}
} }
} else if (a.operator == AssignmentOperator.SUB) { } else if (a.operator == AssignmentOperator.SUB) {
connect_func = "g_signal_handlers_disconnect_matched"; if (sig is DBusSignal) {
connect_func = "dbus_g_proxy_disconnect_signal";
} else {
connect_func = "g_signal_handlers_disconnect_matched";
}
disconnect = true; disconnect = true;
} else { } else {
a.error = true; a.error = true;
...@@ -146,7 +154,7 @@ public class Vala.CodeGenerator { ...@@ -146,7 +154,7 @@ public class Vala.CodeGenerator {
ccall.add_argument (new CCodeIdentifier ("self")); ccall.add_argument (new CCodeIdentifier ("self"));
} }
if (!disconnect) { if (!disconnect || sig is DBusSignal) {
ccall.add_argument (sig.get_canonical_cconstant ()); ccall.add_argument (sig.get_canonical_cconstant ());
} else { } else {
ccall.add_argument (new CCodeConstant ("G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA")); ccall.add_argument (new CCodeConstant ("G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA"));
...@@ -185,13 +193,74 @@ public class Vala.CodeGenerator { ...@@ -185,13 +193,74 @@ public class Vala.CodeGenerator {
ccall.add_argument (new CCodeIdentifier ("self")); ccall.add_argument (new CCodeIdentifier ("self"));
} }
if (!disconnect) { if (!disconnect) {
ccall.add_argument (new CCodeConstant ("0")); if (sig is DBusSignal) {
// free_data_func
ccall.add_argument (new CCodeConstant ("NULL"));
} else {
// connect_flags
ccall.add_argument (new CCodeConstant ("0"));
}
} }
} else { } else {
ccall.add_argument (new CCodeConstant ("NULL")); ccall.add_argument (new CCodeConstant ("NULL"));
} }
a.ccodenode = ccall; a.ccodenode = ccall;
if (sig is DBusSignal && !disconnect) {
bool first = true;
foreach (FormalParameter param in m.get_parameters ()) {
if (first) {
// skip sender parameter
first = false;
continue;
}
sig.add_parameter (param);
}
sig.accept (this);
// FIXME should only be done once per marshaller
var register_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_object_register_marshaller"));
register_call.add_argument (new CCodeIdentifier (get_signal_marshaller_function (sig)));
register_call.add_argument (new CCodeIdentifier ("G_TYPE_NONE"));
var add_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_proxy_add_signal"));
if (ma.inner != null) {
add_call.add_argument ((CCodeExpression) ma.inner.ccodenode);
} else {
add_call.add_argument (new CCodeIdentifier ("self"));
}
add_call.add_argument (sig.get_canonical_cconstant ());
first = true;
foreach (FormalParameter param in m.get_parameters ()) {
if (first) {
// skip sender parameter
first = false;
continue;
}
if (param.type_reference.data_type is Array && ((Array) param.type_reference.data_type).element_type != string_type.data_type) {
var array = (Array) param.type_reference.data_type;
var carray_type = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_type_get_collection"));
carray_type.add_argument (new CCodeConstant ("\"GArray\""));
carray_type.add_argument (new CCodeIdentifier (array.element_type.get_type_id ()));
register_call.add_argument (carray_type);
add_call.add_argument (carray_type);
} else {
register_call.add_argument (new CCodeIdentifier (param.type_reference.data_type.get_type_id ()));
add_call.add_argument (new CCodeIdentifier (param.type_reference.data_type.get_type_id ()));
}
}
register_call.add_argument (new CCodeIdentifier ("G_TYPE_INVALID"));
add_call.add_argument (new CCodeIdentifier ("G_TYPE_INVALID"));
var ccomma = new CCodeCommaExpression ();
ccomma.append_expression (register_call);
ccomma.append_expression (add_call);
ccomma.append_expression (ccall);
a.ccodenode = ccomma;
}
} else if (a.left is ElementAccess && !(((ElementAccess) a.left).container.static_type.data_type is Array)) { } else if (a.left is ElementAccess && !(((ElementAccess) a.left).container.static_type.data_type is Array)) {
// custom element access // custom element access
CCodeExpression rhs = (CCodeExpression) a.right.ccodenode; CCodeExpression rhs = (CCodeExpression) a.right.ccodenode;
......
...@@ -97,7 +97,7 @@ public class Vala.CodeGenerator { ...@@ -97,7 +97,7 @@ public class Vala.CodeGenerator {
def_frag.append (instance_struct); def_frag.append (instance_struct);
def_frag.append (type_struct); def_frag.append (type_struct);
/* only add the *Private struct if it is not empty, i.e. we actually have private data */ /* only add the *Private struct if it is not empty, i.e. we actually have private data */
if (cl.has_private_fields) { if (cl.has_private_fields || cl.get_type_parameters ().size > 0) {
source_type_member_declaration.append (instance_priv_struct); source_type_member_declaration.append (instance_priv_struct);
macro = "(G_TYPE_INSTANCE_GET_PRIVATE ((o), %s, %sPrivate))".printf (cl.get_upper_case_cname ("TYPE_"), cl.get_cname ()); macro = "(G_TYPE_INSTANCE_GET_PRIVATE ((o), %s, %sPrivate))".printf (cl.get_upper_case_cname ("TYPE_"), cl.get_cname ());
source_type_member_declaration.append (new CCodeMacroReplacement ("%s_GET_PRIVATE(o)".printf (cl.get_upper_case_cname (null)), macro)); source_type_member_declaration.append (new CCodeMacroReplacement ("%s_GET_PRIVATE(o)".printf (cl.get_upper_case_cname (null)), macro));
...@@ -107,10 +107,10 @@ public class Vala.CodeGenerator { ...@@ -107,10 +107,10 @@ public class Vala.CodeGenerator {
cl.accept_children (this); cl.accept_children (this);
if (!cl.is_static) { if (!cl.is_static) {
if (class_has_readable_properties (cl)) { if (class_has_readable_properties (cl) || cl.get_type_parameters ().size > 0) {
add_get_property_function (cl); add_get_property_function (cl);
} }
if (class_has_writable_properties (cl)) { if (class_has_writable_properties (cl) || cl.get_type_parameters ().size > 0) {
add_set_property_function (cl); add_set_property_function (cl);
} }
add_class_init_function (cl); add_class_init_function (cl);
...@@ -176,7 +176,7 @@ public class Vala.CodeGenerator { ...@@ -176,7 +176,7 @@ public class Vala.CodeGenerator {
init_block.add_statement (new CCodeExpressionStatement (parent_assignment)); init_block.add_statement (new CCodeExpressionStatement (parent_assignment));
/* add struct for private fields */ /* add struct for private fields */
if (cl.has_private_fields) { if (cl.has_private_fields || cl.get_type_parameters ().size > 0) {
ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_type_class_add_private")); ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_type_class_add_private"));
ccall.add_argument (new CCodeIdentifier ("klass")); ccall.add_argument (new CCodeIdentifier ("klass"));
ccall.add_argument (new CCodeConstant ("sizeof (%sPrivate)".printf (cl.get_cname ()))); ccall.add_argument (new CCodeConstant ("sizeof (%sPrivate)".printf (cl.get_cname ())));
...@@ -186,10 +186,10 @@ public class Vala.CodeGenerator { ...@@ -186,10 +186,10 @@ public class Vala.CodeGenerator {
/* set property handlers */ /* set property handlers */
ccall = new CCodeFunctionCall (new CCodeIdentifier ("G_OBJECT_CLASS")); ccall = new CCodeFunctionCall (new CCodeIdentifier ("G_OBJECT_CLASS"));
ccall.add_argument (new CCodeIdentifier ("klass")); ccall.add_argument (new CCodeIdentifier ("klass"));
if (class_has_readable_properties (cl)) { if (class_has_readable_properties (cl) || cl.get_type_parameters ().size > 0) {
init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (ccall, "get_property"), new CCodeIdentifier ("%s_get_property".printf (cl.get_lower_case_cname (null)))))); init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (ccall, "get_property"), new CCodeIdentifier ("%s_get_property".printf (cl.get_lower_case_cname (null))))));
} }
if (class_has_writable_properties (cl)) { if (class_has_writable_properties (cl) || cl.get_type_parameters ().size > 0) {
init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (ccall, "set_property"), new CCodeIdentifier ("%s_set_property".printf (cl.get_lower_case_cname (null)))))); init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (ccall, "set_property"), new CCodeIdentifier ("%s_set_property".printf (cl.get_lower_case_cname (null))))));
} }
...@@ -337,7 +337,7 @@ public class Vala.CodeGenerator { ...@@ -337,7 +337,7 @@ public class Vala.CodeGenerator {
var init_block = new CCodeBlock (); var init_block = new CCodeBlock ();
instance_init.block = init_block; instance_init.block = init_block;
if (cl.has_private_fields) { if (cl.has_private_fields || cl.get_type_parameters ().size > 0) {
var ccall = new CCodeFunctionCall (new CCodeIdentifier ("%s_GET_PRIVATE".printf (cl.get_upper_case_cname (null)))); var ccall = new CCodeFunctionCall (new CCodeIdentifier ("%s_GET_PRIVATE".printf (cl.get_upper_case_cname (null))));
ccall.add_argument (new CCodeIdentifier ("self")); ccall.add_argument (new CCodeIdentifier ("self"));
init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("self"), "priv"), ccall))); init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("self"), "priv"), ccall)));
......
...@@ -28,7 +28,7 @@ public class Vala.CodeGenerator { ...@@ -28,7 +28,7 @@ public class Vala.CodeGenerator {
current_symbol = iface; current_symbol = iface;
current_type_symbol = iface; current_type_symbol = iface;
if (!iface.is_static) { if (!iface.is_static && !iface.declaration_only) {
type_struct = new CCodeStruct ("_%s".printf (iface.get_type_cname ())); type_struct = new CCodeStruct ("_%s".printf (iface.get_type_cname ()));
header_type_declaration.append (new CCodeNewline ()); header_type_declaration.append (new CCodeNewline ());
...@@ -61,7 +61,7 @@ public class Vala.CodeGenerator { ...@@ -61,7 +61,7 @@ public class Vala.CodeGenerator {
iface.accept_children (this); iface.accept_children (this);
if (!iface.is_static) { if (!iface.is_static && !iface.declaration_only) {
add_interface_base_init_function (iface); add_interface_base_init_function (iface);
var type_fun = new InterfaceRegisterFunction (iface); var type_fun = new InterfaceRegisterFunction (iface);
......
...@@ -73,12 +73,12 @@ public class Vala.CodeGenerator { ...@@ -73,12 +73,12 @@ public class Vala.CodeGenerator {
if (ma.inner == null) { if (ma.inner == null) {
instance = new CCodeIdentifier ("self"); instance = new CCodeIdentifier ("self");
/* require casts for overriden and inherited methods */ /* require casts for overriden and inherited methods */
req_cast = m.overrides || m.base_interface_method != null || (m.parent_symbol != current_type_symbol); req_cast = m.overrides || m.base_interface_method != null || (m.parent_symbol != null && m.parent_symbol != current_type_symbol);
} else { } else {
instance = (CCodeExpression) ma.inner.ccodenode; instance = (CCodeExpression) ma.inner.ccodenode;
/* reqiure casts if the type of the used instance is /* reqiure casts if the type of the used instance is
* different than the type which declared the method */ * different than the type which declared the method */
req_cast = base_method.parent_symbol != ma.inner.static_type.data_type; req_cast = base_method.parent_symbol != null && base_method.parent_symbol != ma.inner.static_type.data_type;
} }
if (m.instance_by_reference && (ma.inner != null || m.parent_symbol != current_type_symbol)) { if (m.instance_by_reference && (ma.inner != null || m.parent_symbol != current_type_symbol)) {
...@@ -102,6 +102,103 @@ public class Vala.CodeGenerator { ...@@ -102,6 +102,103 @@ public class Vala.CodeGenerator {
var csizeof = new CCodeFunctionCall (new CCodeIdentifier ("sizeof")); var csizeof = new CCodeFunctionCall (new CCodeIdentifier ("sizeof"));
csizeof.add_argument (new CCodeIdentifier (array.get_cname ())); csizeof.add_argument (new CCodeIdentifier (array.get_cname ()));
ccall.add_argument (csizeof); ccall.add_argument (csizeof);
} else if (m is DBusMethod) {
bool found_out = false;
Expression callback = null;
foreach (Expression arg in expr.get_argument_list ()) {
if (arg.symbol_reference is Method) {
// callback
if (callback != null) {
Report.error (expr.source_reference, "only one reply callback may be specified in invocation of DBus method");
expr.error = true;
return;
} else if (found_out) {
Report.error (expr.source_reference, "out argument and reply callback conflict in invocation of DBus method");
expr.error = true;
return;
}
callback = arg;
} else if (arg is UnaryExpression && ((UnaryExpression) arg).operator == UnaryOperator.OUT) {
// out arg
if (callback != null) {
Report.error (expr.source_reference, "out argument and reply callback conflict in invocation of DBus method");
expr.error = true;
return;
}
found_out = true;
} else {
// in arg
if (callback != null || found_out) {
Report.error (expr.source_reference, "in argument must not follow out argument or reply callback in invocation of DBus method");
expr.error = true;
return;
}
}
}
ccall.add_argument (new CCodeConstant ("\"%s\"".printf (m.name)));
if (callback != null) {
var reply_method = (Method) callback.symbol_reference;
var cb_fun = new CCodeFunction ("_%s_cb".printf (reply_method.get_cname ()), "void");
cb_fun.modifiers = CCodeModifiers.STATIC;
cb_fun.add_parameter (new CCodeFormalParameter ("proxy", "DBusGProxy*"));
cb_fun.add_parameter (new CCodeFormalParameter ("call", "DBusGProxyCall*"));
cb_fun.add_parameter (new CCodeFormalParameter ("user_data", "void*"));
cb_fun.block = new CCodeBlock ();
var cerrdecl = new CCodeDeclaration ("GError*");
cerrdecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("error", new CCodeConstant ("NULL")));
cb_fun.block.add_statement (cerrdecl);
var cend_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_proxy_end_call"));
cend_call.add_argument (new CCodeIdentifier ("proxy"));
cend_call.add_argument (new CCodeIdentifier ("call"));
cend_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("error")));
var creply_call = new CCodeFunctionCall ((CCodeExpression) callback.ccodenode);
creply_call.add_argument (new CCodeIdentifier ("user_data"));
int param_count = reply_method.get_parameters ().size;
int i = 0;
foreach (FormalParameter param in reply_method.get_parameters ()) {
if ((++i) == param_count) {
// error parameter
break;
}
if (param.type_reference.data_type is Array && ((Array) param.type_reference.data_type).element_type != string_type.data_type) {
var array = (Array) param.type_reference.data_type;
var cdecl = new CCodeDeclaration ("GArray*");
cdecl.add_declarator (new CCodeVariableDeclarator (param.name));
cb_fun.block.add_statement (cdecl);
cend_call.add_argument (get_dbus_array_type (array));
cend_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (param.name)));
creply_call.add_argument (new CCodeMemberAccess.pointer (new CCodeIdentifier (param.name), "len"));
creply_call.add_argument (new CCodeMemberAccess.pointer (new CCodeIdentifier (param.name), "data"));
} else {
var cdecl = new CCodeDeclaration (param.type_reference.get_cname ());
cdecl.add_declarator (new CCodeVariableDeclarator (param.name));
cb_fun.block.add_statement (cdecl);
cend_call.add_argument (new CCodeIdentifier (param.type_reference.data_type.get_type_id ()));
cend_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (param.name)));
creply_call.add_argument (new CCodeIdentifier (param.name));
}
}
cend_call.add_argument (new CCodeIdentifier ("G_TYPE_INVALID"));
cb_fun.block.add_statement (new CCodeExpressionStatement (cend_call));
creply_call.add_argument (new CCodeIdentifier ("error"));
cb_fun.block.add_statement (new CCodeExpressionStatement (creply_call));
source_type_member_definition.append (cb_fun);
ccall.add_argument (new CCodeIdentifier (cb_fun.name));
ccall.add_argument (new CCodeConstant ("self"));
ccall.add_argument (new CCodeConstant ("NULL"));
} else if (found_out || m.return_type.data_type != null) {
ccall.call = new CCodeIdentifier ("dbus_g_proxy_call");
// method can fail
current_method_inner_error = true;
ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("inner_error")));
} else {
ccall.call = new CCodeIdentifier ("dbus_g_proxy_call_no_reply");
}
} }
bool ellipsis = false; bool ellipsis = false;
...@@ -109,9 +206,15 @@ public class Vala.CodeGenerator { ...@@ -109,9 +206,15 @@ public class Vala.CodeGenerator {
var i = 1; var i = 1;
Iterator<FormalParameter> params_it = params.iterator (); Iterator<FormalParameter> params_it = params.iterator ();
foreach (Expression arg in expr.get_argument_list ()) { foreach (Expression arg in expr.get_argument_list ()) {
/* explicitly use strong reference as ccall gets if (m is DBusMethod) {
* unrefed at end of inner block if (arg.symbol_reference is Method) {
*/ // callback parameter
break;
}
ccall.add_argument (new CCodeIdentifier (arg.static_type.data_type.get_type_id ()));
}
CCodeExpression cexpr = (CCodeExpression) arg.ccodenode; CCodeExpression cexpr = (CCodeExpression) arg.ccodenode;
if (params_it.next ()) { if (params_it.next ()) {
var param = params_it.get (); var param = params_it.get ();
...@@ -175,7 +278,7 @@ public class Vala.CodeGenerator { ...@@ -175,7 +278,7 @@ public class Vala.CodeGenerator {
} }
/* add length argument for methods returning arrays */ /* add length argument for methods returning arrays */
if (m != null && m.return_type.data_type is Array) { if (m != null && m.return_type.data_type is Array && !(m is DBusMethod)) {
var arr = (Array) m.return_type.data_type; var arr = (Array) m.return_type.data_type;
for (int dim = 1; dim <= arr.rank; dim++) { for (int dim = 1; dim <= arr.rank; dim++) {
if (!m.no_array_length) { if (!m.no_array_length) {
...@@ -193,7 +296,15 @@ public class Vala.CodeGenerator { ...@@ -193,7 +296,15 @@ public class Vala.CodeGenerator {
} }
} }
if (expr.can_fail) { if (connection_type != null && ma.inner != null && ma.inner.static_type != null && ma.inner.static_type.data_type == connection_type && m.name == "get_object") {
var dbus_iface = (Interface) m.return_type.data_type;
var dbus_attr = dbus_iface.get_attribute ("DBusInterface");
ccall.add_argument (new CCodeConstant ("\"%s\"".printf (dbus_attr.get_string ("name"))));
} else if (m is DBusMethod) {
ccall.add_argument (new CCodeIdentifier ("G_TYPE_INVALID"));
}
if (expr.can_fail && !(m is DBusMethod)) {
// method can fail // method can fail
current_method_inner_error = true; current_method_inner_error = true;
ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("inner_error"))); ccall.add_argument (new CCodeUnaryExpression