Commit 92ba4e17 authored by Rico Tzschichholz's avatar Rico Tzschichholz

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 #59
parent 82ae929d
......@@ -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 \
......
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);
}
......@@ -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) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment