From: Rico Tzschichholz Date: Mon, 10 Dec 2018 15:07:46 +0000 (+0100) Subject: codegen: Handle non-default AsyncResult parameter position X-Git-Tag: 0.43.2~4 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=013bb64cc8ef97326db1a44affcf420b0bc941cf;p=thirdparty%2Fvala.git codegen: Handle non-default AsyncResult parameter position Unfortunately gdbus-codegen puts the AsyncResult parameter after possible out-parameters therefore there is an "async_result_pos" attribute required to handle this correctly. Vala supposely follows the common practice to put the AsyncResult before out-parameters by default. Fixes https://gitlab.gnome.org/GNOME/vala/issues/709 --- diff --git a/codegen/valaccode.vala b/codegen/valaccode.vala index d4d9abee5..2954b3e37 100644 --- a/codegen/valaccode.vala +++ b/codegen/valaccode.vala @@ -380,6 +380,11 @@ namespace Vala { return get_ccode_attribute(m).vfunc_name; } + public static double get_ccode_async_result_pos (Method m) { + assert (m.coroutine); + return m.get_attribute_double ("CCode", "async_result_pos", 0.1); + } + public static string get_ccode_finish_name (Method m) { return get_ccode_attribute(m).finish_name; } diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala index 9012567c4..6662e1c45 100644 --- a/codegen/valaccodebasemodule.vala +++ b/codegen/valaccodebasemodule.vala @@ -4835,7 +4835,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator { // output arguments used separately out_arg_map = new HashMap (direct_hash, direct_equal); // pass GAsyncResult stored in closure to finish function - out_arg_map.set (get_param_pos (0.1), new CCodeMemberAccess.pointer (new CCodeIdentifier ("_data_"), "_res_")); + out_arg_map.set (get_param_pos (get_ccode_async_result_pos (m)), new CCodeMemberAccess.pointer (new CCodeIdentifier ("_data_"), "_res_")); } if (cl != null && !cl.is_compact) { diff --git a/codegen/valaccodemethodcallmodule.vala b/codegen/valaccodemethodcallmodule.vala index 18505c247..90da65c88 100644 --- a/codegen/valaccodemethodcallmodule.vala +++ b/codegen/valaccodemethodcallmodule.vala @@ -129,7 +129,7 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule { // output arguments used separately out_arg_map = new HashMap (direct_hash, direct_equal); // pass GAsyncResult stored in closure to finish function - out_arg_map.set (get_param_pos (0.1), new CCodeMemberAccess.pointer (new CCodeIdentifier ("_data_"), "_res_")); + out_arg_map.set (get_param_pos (get_ccode_async_result_pos (m)), new CCodeMemberAccess.pointer (new CCodeIdentifier ("_data_"), "_res_")); } } diff --git a/codegen/valagasyncmodule.vala b/codegen/valagasyncmodule.vala index a3022532a..29c38fddd 100644 --- a/codegen/valagasyncmodule.vala +++ b/codegen/valagasyncmodule.vala @@ -586,7 +586,7 @@ public class Vala.GAsyncModule : GtkModule { var cparam_map = new HashMap (direct_hash, direct_equal); - cparam_map.set (get_param_pos (0.1), new CCodeParameter ("_res_", "GAsyncResult*")); + cparam_map.set (get_param_pos (get_ccode_async_result_pos (m)), new CCodeParameter ("_res_", "GAsyncResult*")); generate_cparameters (m, cfile, cparam_map, finishfunc, null, null, null, 2); @@ -832,9 +832,9 @@ public class Vala.GAsyncModule : GtkModule { carg_map.set (get_param_pos (-0.9), new CCodeIdentifier ("_user_data_")); } } else if (direction == 2) { - cparam_map.set (get_param_pos (0.1), new CCodeParameter ("_res_", "GAsyncResult*")); + cparam_map.set (get_param_pos (get_ccode_async_result_pos (m)), new CCodeParameter ("_res_", "GAsyncResult*")); if (carg_map != null) { - carg_map.set (get_param_pos (0.1), new CCodeIdentifier ("_res_")); + carg_map.set (get_param_pos (get_ccode_async_result_pos (m)), new CCodeIdentifier ("_res_")); } } } diff --git a/codegen/valagdbusclientmodule.vala b/codegen/valagdbusclientmodule.vala index 57051b2c4..398c17f45 100644 --- a/codegen/valagdbusclientmodule.vala +++ b/codegen/valagdbusclientmodule.vala @@ -936,7 +936,7 @@ public class Vala.GDBusClientModule : GDBusModule { var cparam_map = new HashMap (direct_hash, direct_equal); - cparam_map.set (get_param_pos (0.1), new CCodeParameter ("_res_", "GAsyncResult*")); + cparam_map.set (get_param_pos (get_ccode_async_result_pos (m)), new CCodeParameter ("_res_", "GAsyncResult*")); generate_cparameters (m, cfile, cparam_map, function, null, null, null, 2); diff --git a/tests/Makefile.am b/tests/Makefile.am index a4b93c1c5..380703da2 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -403,6 +403,7 @@ TESTS = \ asynchronous/bug793158.vala \ asynchronous/closures.vala \ asynchronous/generator.vala \ + asynchronous/result-pos.vala \ asynchronous/yield.vala \ generics/bug640330.test \ generics/bug640330.vala \ @@ -434,6 +435,7 @@ TESTS = \ gir/bug788775.test \ gir/bug792998.test \ gir/array-fixed-length.test \ + gir/async-result-pos.test \ gir/class.test \ gir/delegate-alias-without-target.test \ gir/delegate-closure-destroy-index-conflict.test \ diff --git a/tests/asynchronous/result-pos.vala b/tests/asynchronous/result-pos.vala new file mode 100644 index 000000000..3c86f75b5 --- /dev/null +++ b/tests/asynchronous/result-pos.vala @@ -0,0 +1,48 @@ +[CCode (async_result_pos = 2.1)] +async void foo (int in_i, out int out_i) { + out_i = in_i; +} + +[CCode (async_result_pos = 2.1)] +async void bar (int in_i, out int out_i) throws Error { + out_i = in_i; +} + +async void run () { + int i; + yield foo (323, out i); + assert (i == 323); + try { + yield bar (742, out i); + assert (i == 742); + } catch { + assert_not_reached (); + } + loop.quit (); +} + +MainLoop loop; + +void main () { + loop = new MainLoop (); + + foo.begin (23, (o,r) => { + int i; + foo.end (r, out i); + assert (i == 23); + }); + + bar.begin (42, (o,r) => { + try { + int i; + bar.end (r, out i); + assert (i == 42); + } catch { + assert_not_reached (); + } + }); + + run.begin (); + + loop.run (); +} diff --git a/tests/gir/async-result-pos.test b/tests/gir/async-result-pos.test new file mode 100644 index 000000000..2a17f53dc --- /dev/null +++ b/tests/gir/async-result-pos.test @@ -0,0 +1,56 @@ +GIR + +Input: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Output: + +[CCode (cheader_filename = "test.h", type_id = "test_foo_get_type ()")] +public class Foo : GLib.Object { + [CCode (has_construct_function = false)] + public Foo (); + [CCode (async_result_pos = 2.1)] + public async void method_async (string input, out string output) throws GLib.Error; +} diff --git a/vala/valagirparser.vala b/vala/valagirparser.vala index 4a22841f0..061eb17c5 100644 --- a/vala/valagirparser.vala +++ b/vala/valagirparser.vala @@ -3854,6 +3854,7 @@ public class Vala.GirParser : CodeVisitor { int i = 0, j=1; + int first_out = -1; int last = -1; foreach (ParameterInfo info in parameters) { if (s is Delegate && info.closure_idx == i) { @@ -3885,6 +3886,16 @@ public class Vala.GirParser : CodeVisitor { // hidden parameters at the end of the parameter list info.vala_idx = (j - 1) + (i - last) * 0.1F; } + if (first_out < 0 && info.param.direction == ParameterDirection.OUT) { + first_out = i; + } + if (s is Method && first_out >= 0 && info.param.variable_type != null) { + var type_name = info.param.variable_type.to_string (); + if (type_name == "GLib.AsyncResult" || type_name == "Gio.AsyncResult") { + var shift = ((Method) s).binding == MemberBinding.INSTANCE ? 1.1 : 0.1; + s.set_attribute_double ("CCode", "async_result_pos", i + shift); + } + } i++; } @@ -4124,6 +4135,8 @@ public class Vala.GirParser : CodeVisitor { } } + method.copy_attribute_double (finish_method, "CCode", "async_result_pos"); + foreach (var param in finish_method.get_parameters ()) { if (param.direction == ParameterDirection.OUT) { var async_param = param.copy (); diff --git a/vala/valamethod.vala b/vala/valamethod.vala index 7ec91729d..18f043f07 100644 --- a/vala/valamethod.vala +++ b/vala/valamethod.vala @@ -1061,6 +1061,7 @@ public class Vala.Method : Subroutine, Callable { foreach (var param in get_type_parameters ()) { end_method.add_type_parameter (param); } + end_method.copy_attribute_double (this, "CCode", "async_result_pos"); } return end_method; } @@ -1125,7 +1126,7 @@ public class Vala.Method : Subroutine, Callable { var result_type = new ObjectType ((ObjectTypeSymbol) glib_ns.scope.lookup ("AsyncResult")); var result_param = new Parameter ("_res_", result_type); - result_param.set_attribute_double ("CCode", "pos", 0.1); + result_param.set_attribute_double ("CCode", "pos", get_attribute_double ("CCode", "async_result_pos", 0.1)); params.add (result_param); foreach (var param in parameters) { diff --git a/vala/valausedattr.vala b/vala/valausedattr.vala index 28047daf3..97e9e9da9 100644 --- a/vala/valausedattr.vala +++ b/vala/valausedattr.vala @@ -40,7 +40,7 @@ public class Vala.UsedAttr : CodeVisitor { "array_length_type", "array_length", "array_length_cname", "array_length_cexpr", "array_null_terminated", "vfunc_name", "finish_vfunc_name", "finish_name", "free_function_address_of", "pos", "delegate_target", "delegate_target_cname", "array_length_pos", "delegate_target_pos", "destroy_notify_pos", "ctype", "has_new_function", "notify", "finish_instance", - "use_inplace", "feature_test_macro", "default_value_on_error", "", + "use_inplace", "feature_test_macro", "default_value_on_error", "async_result_pos", "", "Immutable", "", "SingleInstance", "",