[vala/0.40] codegen: Fix support of dynamic DBus methods



commit 3b44a7628ffe7e2af3c985005c07d4e2b92f6483
Author: Rico Tzschichholz <ricotz ubuntu com>
Date:   Thu Nov 14 12:32:15 2019 +0100

    codegen: Fix support of dynamic DBus methods

 codegen/valaccodemethodcallmodule.vala |  7 ++++
 codegen/valagdbusclientmodule.vala     |  6 ++--
 tests/Makefile.am                      |  1 +
 tests/dbus/dynamic-method.test         | 63 ++++++++++++++++++++++++++++++++++
 vala/valamemberaccess.vala             |  1 +
 5 files changed, 74 insertions(+), 4 deletions(-)
---
diff --git a/codegen/valaccodemethodcallmodule.vala b/codegen/valaccodemethodcallmodule.vala
index 115ec891f..fa2bd5947 100644
--- a/codegen/valaccodemethodcallmodule.vala
+++ b/codegen/valaccodemethodcallmodule.vala
@@ -291,6 +291,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 ()) {
@@ -315,6 +316,7 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
                                param.accept (this);
                        }
                        generate_dynamic_method_wrapper ((DynamicMethod) m);
+                       emit_context.pop_symbol ();
                } else if (m is CreationMethod && m.parent_symbol is Class) {
                        ccode.add_assignment (get_this_cexpression (), new CCodeCastExpression (ccall, 
get_ccode_name (current_class) + "*"));
 
@@ -881,6 +883,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 4e4668d2e..32b8cfb9c 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.data_type == dbus_proxy_type) {
+               if (method.dynamic_type.data_type == 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 23f387949..935aac999 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -456,6 +456,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 91c8303b8..9b9988400 100644
--- a/vala/valamemberaccess.vala
+++ b/vala/valamemberaccess.vala
@@ -392,6 +392,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;
                                        }


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