[vala/staging] vala: Multiple lamdba arguments in method call should all use closure scope
- From: Rico Tzschichholz <ricotz src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vala/staging] vala: Multiple lamdba arguments in method call should all use closure scope
- Date: Tue, 15 Jan 2019 15:54:18 +0000 (UTC)
commit 92ba4e178723b1aa6404da556c79b08abe5eaf05
Author: Rico Tzschichholz <ricotz ubuntu com>
Date: Tue Jan 15 10:44:12 2019 +0100
vala: Multiple lamdba arguments in method call should all use closure scope
This does not enable proper support for delegates sharing a data argument,
but allows this special case.
See https://gitlab.gnome.org/GNOME/vala/issues/59
tests/Makefile.am | 1 +
tests/delegates/lambda-shared-closure.vala | 108 +++++++++++++++++++++++++++++
vala/valamethodcall.vala | 14 ++++
3 files changed, 123 insertions(+)
---
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 9ad4e4061..4bcd92671 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -238,6 +238,7 @@ TESTS = \
delegates/fields.vala \
delegates/fields-no-target.vala \
delegates/instance-method-to-no-target.test \
+ delegates/lambda-shared-closure.vala \
delegates/reference_transfer.vala \
delegates/wrapper.vala \
delegates/bug519949.test \
diff --git a/tests/delegates/lambda-shared-closure.vala b/tests/delegates/lambda-shared-closure.vala
new file mode 100644
index 000000000..028eca31a
--- /dev/null
+++ b/tests/delegates/lambda-shared-closure.vala
@@ -0,0 +1,108 @@
+public delegate void FooFunc ();
+
+public class Foo : Object {
+ int global = 42;
+
+ void call (FooFunc a, FooFunc b) {
+ a ();
+ b ();
+ }
+
+ void call_owned (owned FooFunc a, owned FooFunc b) {
+ a ();
+ b ();
+ }
+
+ void call_shared ([CCode (delegate_target_cname = "user_data", delegate_target_pos = 2.9)] FooFunc a,
[CCode (delegate_target_cname = "user_data", delegate_target_pos = 2.9)] FooFunc b) {
+ a ();
+ b ();
+ }
+
+ void call_shared_owned ([CCode (delegate_target_cname = "user_data", delegate_target_pos = 2.9)]
owned FooFunc a, [CCode (delegate_target_cname = "user_data", delegate_target_pos = 2.9)] owned FooFunc b) {
+ a ();
+ b ();
+ }
+
+ public void run_1 () {
+ int local = 23;
+
+ assert (this.ref_count == 2);
+
+ call (
+ () => {
+ assert (global == 42);
+ assert (this.ref_count == 2);
+ },
+ () => {
+ assert (local == 23);
+ assert (this.ref_count == 2);
+ }
+ );
+
+ assert (this.ref_count == 2);
+ }
+
+ public void run_2 () {
+ int local = 23;
+
+ assert (this.ref_count == 2);
+
+ call_owned (
+ () => {
+ assert (global == 42);
+ },
+ () => {
+ assert (local == 23);
+ }
+ );
+
+ assert (this.ref_count == 2);
+ }
+
+ public void run_3 () {
+ int local = 23;
+
+ assert (this.ref_count == 2);
+
+ call_shared (
+ () => {
+ assert (global == 42);
+ },
+ () => {
+ assert (local == 23);
+ }
+ );
+
+ assert (this.ref_count == 2);
+ }
+
+ public void run_4 () {
+ int local = 23;
+
+ assert (this.ref_count == 2);
+
+ call_shared_owned (
+ () => {
+ assert (global == 42);
+ },
+ () => {
+ assert (local == 23);
+ }
+ );
+
+ assert (this.ref_count == 2);
+ }
+}
+
+void main () {
+ var foo = new Foo ();
+ assert (foo.ref_count == 1);
+ foo.run_1 ();
+ assert (foo.ref_count == 1);
+ foo.run_2 ();
+ assert (foo.ref_count == 1);
+ foo.run_3 ();
+ assert (foo.ref_count == 1);
+ foo.run_4 ();
+ assert (foo.ref_count == 1);
+}
diff --git a/vala/valamethodcall.vala b/vala/valamethodcall.vala
index 3b5917668..e9cfc1c9d 100644
--- a/vala/valamethodcall.vala
+++ b/vala/valamethodcall.vala
@@ -476,8 +476,22 @@ public class Vala.MethodCall : Expression {
}
}
+ bool force_lambda_method_closure = false;
foreach (Expression arg in get_argument_list ()) {
arg.check (context);
+
+ if (arg is LambdaExpression && ((LambdaExpression) arg).method.closure) {
+ force_lambda_method_closure = true;
+ }
+ }
+ // force all lambda arguments using the same closure scope
+ // TODO https://gitlab.gnome.org/GNOME/vala/issues/59
+ if (force_lambda_method_closure) {
+ foreach (Expression arg in get_argument_list ()) {
+ if (arg is LambdaExpression) {
+ ((LambdaExpression) arg).method.closure = true;
+ }
+ }
}
if (ret_type is VoidType) {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]