diff options
author | Rico Tzschichholz <ricotz@ubuntu.com> | 2019-08-24 23:36:40 +0200 |
---|---|---|
committer | Rico Tzschichholz <ricotz@ubuntu.com> | 2019-09-05 17:58:04 +0200 |
commit | 9b92b3d1f875fcc1c504481354baf52cdc660f91 (patch) | |
tree | 42dd3a0670b37c380b5edb6f5e48aa652843a03b | |
parent | 3c5d2b6056aa9c29501315a100bd0662037a019f (diff) | |
download | vala-wip/issue/839.tar.gz |
WIP vala: Allow to access function pointers of .begin and .end methodswip/issue/839
-rw-r--r-- | codegen/valaccodeattribute.vala | 12 | ||||
-rw-r--r-- | codegen/valaccodememberaccessmodule.vala | 3 | ||||
-rw-r--r-- | tests/Makefile.am | 1 | ||||
-rw-r--r-- | tests/asynchronous/begin-end-as-delegates.vala | 62 | ||||
-rw-r--r-- | vala/valamethod.vala | 31 | ||||
-rw-r--r-- | vala/valamethodtype.vala | 4 |
6 files changed, 108 insertions, 5 deletions
diff --git a/codegen/valaccodeattribute.vala b/codegen/valaccodeattribute.vala index 87d5142e8..73c8dbb27 100644 --- a/codegen/valaccodeattribute.vala +++ b/codegen/valaccodeattribute.vala @@ -717,6 +717,18 @@ public class Vala.CCodeAttribute : AttributeCache { unowned Method m = (Method) sym; if (m.is_async_callback) { return "%s_co".printf (get_ccode_real_name ((Method) m.parent_symbol)); + } else if (m.is_async_begin) { + if (m.parent_symbol is CreationMethod) { + return get_ccode_real_name ((Method) m.parent_symbol); + } else { + return get_ccode_name ((Method) m.parent_symbol); + } + } else if (m.is_async_end) { + if (m.parent_symbol is CreationMethod) { + return get_ccode_finish_real_name ((Method) m.parent_symbol); + } else { + return get_ccode_finish_name ((Method) m.parent_symbol); + } } if (m.signal_reference != null) { return "%s%s".printf (get_ccode_lower_case_prefix (m.parent_symbol), get_ccode_lower_case_name (m.signal_reference)); diff --git a/codegen/valaccodememberaccessmodule.vala b/codegen/valaccodememberaccessmodule.vala index 5ef5f4eb9..7c8770fc7 100644 --- a/codegen/valaccodememberaccessmodule.vala +++ b/codegen/valaccodememberaccessmodule.vala @@ -36,7 +36,8 @@ public abstract class Vala.CCodeMemberAccessModule : CCodeControlFlowModule { if (expr.symbol_reference is Method) { var m = (Method) expr.symbol_reference; - if (!(m is DynamicMethod || m is ArrayMoveMethod || m is ArrayResizeMethod || m is ArrayCopyMethod)) { + if (!(m is DynamicMethod || m is ArrayMoveMethod || m is ArrayResizeMethod || m is ArrayCopyMethod) + && !m.is_async_begin && !m.is_async_end) { generate_method_declaration (m, cfile); if (!m.external && m.external_package) { diff --git a/tests/Makefile.am b/tests/Makefile.am index 9e5190a5b..d3a8e9297 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -464,6 +464,7 @@ TESTS = \ asynchronous/bug792660.vala \ asynchronous/bug792942.vala \ asynchronous/bug793158.vala \ + asynchronous/begin-end-as-delegates.vala \ asynchronous/catch-error-scope.vala \ asynchronous/catch-in-finally.vala \ asynchronous/closures.vala \ diff --git a/tests/asynchronous/begin-end-as-delegates.vala b/tests/asynchronous/begin-end-as-delegates.vala new file mode 100644 index 000000000..e07e7c513 --- /dev/null +++ b/tests/asynchronous/begin-end-as-delegates.vala @@ -0,0 +1,62 @@ +[CCode (has_target = false)] +delegate void FooBegin (int i, AsyncReadyCallback cb); +[CCode (has_target = false)] +delegate int FooEnd (AsyncResult res, out string s); + +async int foo (int i, out string s) { + s = "foo"; + return i; +} + +delegate void BarBegin (int i, AsyncReadyCallback cb); +delegate int BarEnd (AsyncResult res, out string s); + +class Bar { + public async int bar (int i, out string s) { + s = "bar"; + return i; + } +} + +MainLoop loop; + +int count = 2; + +void main () { + loop = new MainLoop (); + + { + FooBegin begin = foo.begin; + FooEnd end = foo.end; + + begin (23, (o,a) => { + string s; + assert (end (a, out s) == 23); + assert (s == "foo"); + + count--; + if (count <= 0) + loop.quit (); + } + }); + } + + { + var bar = new Bar (); + BarBegin begin = bar.bar.begin; + BarEnd end = bar.bar.end; + + begin (42, (o,a) => { + string s; + assert (end (a, out s) == 42); + assert (s == "bar"); + + count--; + if (count <= 0) + loop.quit (); + } + }); + } + + loop.run (); +} diff --git a/vala/valamethod.vala b/vala/valamethod.vala index 60a1a3543..2a632677a 100644 --- a/vala/valamethod.vala +++ b/vala/valamethod.vala @@ -181,8 +181,12 @@ public class Vala.Method : Subroutine, Callable { public bool coroutine { get; set; } + public bool is_async_begin { get; set; } + public bool is_async_callback { get; set; } + public bool is_async_end { get; set; } + private List<Parameter> parameters = new ArrayList<Parameter> (); private List<Expression> preconditions; private List<Expression> postconditions; @@ -195,6 +199,7 @@ public class Vala.Method : Subroutine, Callable { private DataType _base_interface_type; private bool base_methods_valid; + Method? begin_method; Method? callback_method; Method? end_method; @@ -1094,14 +1099,36 @@ public class Vala.Method : Subroutine, Callable { return n; } + public Method get_begin_method () { + assert (this.coroutine); + + if (begin_method == null) { + begin_method = new Method ("begin", new VoidType (), source_reference); + begin_method.access = access; + begin_method.external = true; + begin_method.binding = ((this is CreationMethod) ? MemberBinding.STATIC : binding); + begin_method.owner = scope; + begin_method.is_async_begin = true; + foreach (var param in get_async_begin_parameters ()) { + begin_method.add_parameter (param.copy ()); + } + foreach (var param in get_type_parameters ()) { + begin_method.add_type_parameter (param); + } + } + return begin_method; + } + public Method get_end_method () { assert (this.coroutine); if (end_method == null) { - end_method = new Method ("end", return_type, source_reference); - end_method.access = SymbolAccessibility.PUBLIC; + end_method = new Method ("end", ((this is CreationMethod) ? SemanticAnalyzer.get_this_type (this) : return_type), source_reference); + end_method.access = access; end_method.external = true; + end_method.binding = ((this is CreationMethod) ? MemberBinding.STATIC : binding); end_method.owner = scope; + end_method.is_async_end = true; foreach (var param in get_async_end_parameters ()) { end_method.add_parameter (param.copy ()); } diff --git a/vala/valamethodtype.vala b/vala/valamethodtype.vala index a2effdec6..16c92fce2 100644 --- a/vala/valamethodtype.vala +++ b/vala/valamethodtype.vala @@ -64,9 +64,9 @@ public class Vala.MethodType : CallableType { public override Symbol? get_member (string member_name) { if (method_symbol.coroutine && member_name == "begin") { - return method_symbol; + return method_symbol.get_begin_method (); } else if (method_symbol.coroutine && member_name == "end") { - return method_symbol; + return method_symbol.get_end_method (); } else if (method_symbol.coroutine && member_name == "callback") { return method_symbol.get_callback_method (); } |