]> 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>
Thu, 14 Nov 2019 12:23:19 +0000 (13:23 +0100)
codegen/valaccodemethodcallmodule.vala
codegen/valagdbusclientmodule.vala
tests/Makefile.am
tests/dbus/dynamic-method.test [new file with mode: 0644]
vala/valamemberaccess.vala

index c5b36f86a06b31d40e280c4584f293b436c72364..2413bc99a27705fa8b2f8a23886c6a874f90cc3d 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) + "*"));
 
@@ -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);
 
index 3e79a3f3e2b21d45bf6b45751d78b6a16353c001..12a7693d28c2b0847770ab9879e4511f701523b9 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.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 ();
index 3d0cef52828aef9fcf2512d1519a8b6df1e8e603..2bbd134b9b3d5eaaf7287415ff47027901c92717 100644 (file)
@@ -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 (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 b6b67bfcdb50279f203052580b6d57a90a1e3802..946bd2b0a892b53355ef3c863dfe189c80c02211 100644 (file)
@@ -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;
                                        }