summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRico Tzschichholz <ricotz@ubuntu.com>2019-11-14 12:32:15 +0100
committerRico Tzschichholz <ricotz@ubuntu.com>2019-11-14 13:23:19 +0100
commit9c7a7891b024e66df377fc2b5d60abfbfbdd9edd (patch)
tree0e3d4e2afe05c49e8ffc482c14f537663884366a
parent07ff8734d0712921787681d20e59cc1531cdf7af (diff)
downloadvala-9c7a7891b024e66df377fc2b5d60abfbfbdd9edd.tar.gz
codegen: Fix support of dynamic DBus methods
-rw-r--r--codegen/valaccodemethodcallmodule.vala7
-rw-r--r--codegen/valagdbusclientmodule.vala6
-rw-r--r--tests/Makefile.am1
-rw-r--r--tests/dbus/dynamic-method.test63
-rw-r--r--vala/valamemberaccess.vala1
5 files changed, 74 insertions, 4 deletions
diff --git a/codegen/valaccodemethodcallmodule.vala b/codegen/valaccodemethodcallmodule.vala
index c5b36f86a..2413bc99a 100644
--- a/codegen/valaccodemethodcallmodule.vala
+++ b/codegen/valaccodemethodcallmodule.vala
@@ -296,6 +296,7 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
csizeof.add_argument (new CCodeIdentifier (get_ccode_name (array_type.element_type)));
in_arg_map.set (get_param_pos (0.1), csizeof);
} else if (m is DynamicMethod) {
+ emit_context.push_symbol (m);
m.clear_parameters ();
int param_nr = 1;
foreach (Expression arg in expr.get_argument_list ()) {
@@ -320,6 +321,7 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
param.accept (this);
}
generate_dynamic_method_wrapper ((DynamicMethod) m);
+ emit_context.pop_symbol ();
} else if (m is CreationMethod && context.profile == Profile.GOBJECT && m.parent_symbol is Class) {
ccode.add_assignment (get_this_cexpression (), new CCodeCastExpression (ccall, get_ccode_name (current_class) + "*"));
@@ -904,6 +906,11 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
ccode.add_expression (destroy_value (unary.inner.target_value));
}
+ // infer type of out-parameter from argument
+ if (ma.symbol_reference is DynamicMethod && unary.target_value.value_type == null) {
+ unary.target_value.value_type = unary.inner.value_type.copy ();
+ }
+
// assign new value
store_value (unary.inner.target_value, transform_value (unary.target_value, unary.inner.value_type, arg), expr.source_reference);
diff --git a/codegen/valagdbusclientmodule.vala b/codegen/valagdbusclientmodule.vala
index 3e79a3f3e..12a7693d2 100644
--- a/codegen/valagdbusclientmodule.vala
+++ b/codegen/valagdbusclientmodule.vala
@@ -43,8 +43,6 @@ public class Vala.GDBusClientModule : GDBusModule {
}
public override void generate_dynamic_method_wrapper (DynamicMethod method) {
- var dynamic_method = (DynamicMethod) method;
-
var func = new CCodeFunction (get_ccode_name (method));
func.modifiers = CCodeModifiers.STATIC;
@@ -54,10 +52,10 @@ public class Vala.GDBusClientModule : GDBusModule {
push_function (func);
- if (dynamic_method.dynamic_type.type_symbol == dbus_proxy_type) {
+ if (method.dynamic_type.type_symbol == dbus_proxy_type) {
generate_marshalling (method, CallType.SYNC, null, method.name, -1);
} else {
- Report.error (method.source_reference, "dynamic methods are not supported for `%s'".printf (dynamic_method.dynamic_type.to_string ()));
+ Report.error (method.source_reference, "dynamic methods are not supported for `%s'".printf (method.dynamic_type.to_string ()));
}
pop_function ();
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 3d0cef528..2bbd134b9 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -521,6 +521,7 @@ TESTS = \
dbus/errors.test \
dbus/async.test \
dbus/async-errors.test \
+ dbus/dynamic-method.test \
dbus/enum-string-marshalling.vala \
dbus/signals.test \
dbus/filedescriptor.test \
diff --git a/tests/dbus/dynamic-method.test b/tests/dbus/dynamic-method.test
new file mode 100644
index 000000000..fd3bc8a99
--- /dev/null
+++ b/tests/dbus/dynamic-method.test
@@ -0,0 +1,63 @@
+Packages: gio-2.0
+D-Bus
+
+Program: client
+
+async void run () {
+ try {
+ var bus = yield Bus.@get (BusType.SESSION);
+ dynamic DBusProxy test = yield new DBusProxy (bus, DBusProxyFlags.NONE, null, bus.get_unique_name (), "/org/example/test", "org.example.Test");
+ string s;
+ int i = test.do_foo (42, out s);
+ assert (i == 23);
+ assert (s == "foo");
+ } catch {
+ }
+
+ main_loop.quit ();
+}
+
+MainLoop main_loop;
+
+void main () {
+ main_loop = new MainLoop ();
+ run.begin ();
+ main_loop.run ();
+}
+
+Program: server
+
+[DBus (name = "org.example.Test")]
+class Test : Object {
+ public int do_foo (int i, out string s) throws Error {
+ assert (i == 42);
+ s = "foo";
+ return 23;
+ }
+}
+
+MainLoop main_loop;
+
+void client_exit (Pid pid, int status) {
+ // client finished, terminate server
+ assert (status == 0);
+ main_loop.quit ();
+}
+
+void main () {
+ var conn = Bus.get_sync (BusType.SESSION);
+ conn.register_object ("/org/example/test", new Test ());
+
+ // try to register service in session bus
+ var request_result = conn.call_sync ("org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus", "RequestName",
+ new Variant ("(su)", "org.example.Test", 0x4), null, 0, -1);
+ assert ((uint) request_result.get_child_value (0) == 1);
+
+ // server ready, spawn client
+ Pid client_pid;
+ Process.spawn_async (null, { "dbus_dynamic_method_client" }, null, SpawnFlags.DO_NOT_REAP_CHILD, null, out client_pid);
+ ChildWatch.add (client_pid, client_exit);
+
+ main_loop = new MainLoop ();
+ main_loop.run ();
+}
diff --git a/vala/valamemberaccess.vala b/vala/valamemberaccess.vala
index b6b67bfcd..946bd2b0a 100644
--- a/vala/valamemberaccess.vala
+++ b/vala/valamemberaccess.vala
@@ -408,6 +408,7 @@ public class Vala.MemberAccess : Expression {
m.add_error_type (err);
m.access = SymbolAccessibility.PUBLIC;
m.add_parameter (new Parameter.with_ellipsis ());
+ m.this_parameter = new Parameter ("this", dynamic_object_type.copy ());
dynamic_object_type.type_symbol.scope.add (null, m);
symbol_reference = m;
}