summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRico Tzschichholz <ricotz@ubuntu.com>2019-08-24 23:36:40 +0200
committerRico Tzschichholz <ricotz@ubuntu.com>2019-09-05 17:58:04 +0200
commit9b92b3d1f875fcc1c504481354baf52cdc660f91 (patch)
tree42dd3a0670b37c380b5edb6f5e48aa652843a03b
parent3c5d2b6056aa9c29501315a100bd0662037a019f (diff)
downloadvala-wip/issue/839.tar.gz
WIP vala: Allow to access function pointers of .begin and .end methodswip/issue/839
-rw-r--r--codegen/valaccodeattribute.vala12
-rw-r--r--codegen/valaccodememberaccessmodule.vala3
-rw-r--r--tests/Makefile.am1
-rw-r--r--tests/asynchronous/begin-end-as-delegates.vala62
-rw-r--r--vala/valamethod.vala31
-rw-r--r--vala/valamethodtype.vala4
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 ();
}