]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
codegen: Fix support of dynamic DBus methods
authorRico Tzschichholz <ricotz@ubuntu.com>
Thu, 14 Nov 2019 11:32:15 +0000 (12:32 +0100)
committerRico Tzschichholz <ricotz@ubuntu.com>
Mon, 18 Nov 2019 08:33:31 +0000 (09:33 +0100)
codegen/valaccodemethodcallmodule.vala
codegen/valagdbusclientmodule.vala
tests/Makefile.am
tests/dbus/dynamic-method.test [new file with mode: 0644]
vala/valamemberaccess.vala

index 60bc43097d47720eed040d98750c5e04ff3339a3..7de71aad3d67befe9dd31684ce44101ff5154451 100644 (file)
@@ -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) + "*"));
 
@@ -873,6 +875,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);
 
index 5303975eab178d23d41ec403a40eb597c3cff098..433e69fc1df01667bdf0beba9180566e6a69224b 100644 (file)
@@ -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 ();
index 4b424f87cc303bbecbbea1ffcea9b89ed30befeb..f3bd8e2c2a9d93730f481cb7e549bd761a7ca9c6 100644 (file)
@@ -503,6 +503,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 (file)
index 0000000..fd3bc8a
--- /dev/null
@@ -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 ();
+}
index a1b0fe84cda16bf12e5ff0067d15fcb2e4dd251c..7cb968dfef78c83479846a65f29c628fefe6be21 100644 (file)
@@ -398,6 +398,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;
                                        }