[vala/wip/bug567269: 5/7] Allow 'static' lambdas before chainup
- From: Rico Tzschichholz <ricotz src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vala/wip/bug567269: 5/7] Allow 'static' lambdas before chainup
- Date: Fri, 2 Dec 2016 12:43:08 +0000 (UTC)
commit cc7bb2bcf6acba6824456533ffa5d908e8f2b5d9
Author: Simon Werbeck <simon werbeck gmail com>
Date: Wed Nov 26 14:08:41 2014 +0100
Allow 'static' lambdas before chainup
If a lambda expression does not use its instance parameter, it is safe
to use before a chainup expression. To make this work, usage of 'this'
has to be tracked and the code generator needs to make use of this
information.
https://bugzilla.gnome.org/show_bug.cgi?id=567269
codegen/valaccodebasemodule.vala | 2 +-
vala/valalambdaexpression.vala | 13 ++++++++++++-
vala/valamemberaccess.vala | 22 ++++++++++++++++++++++
3 files changed, 35 insertions(+), 2 deletions(-)
---
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index 3e4da40..23a0300 100644
--- a/codegen/valaccodebasemodule.vala
+++ b/codegen/valaccodebasemodule.vala
@@ -5550,7 +5550,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
set_delegate_target_destroy_notify (lambda, new CCodeConstant ("NULL"));
}
set_delegate_target (lambda, delegate_target);
- } else if (get_this_type () != null) {
+ } else if (lambda.method.binding == MemberBinding.INSTANCE && get_this_type () != null) {
CCodeExpression delegate_target = get_result_cexpression ("self");
delegate_target = convert_to_generic_pointer (delegate_target, get_this_type ());
if (expr_owned || delegate_type.is_called_once) {
diff --git a/vala/valalambdaexpression.vala b/vala/valalambdaexpression.vala
index 6c2cf7a..c073e71 100644
--- a/vala/valalambdaexpression.vala
+++ b/vala/valalambdaexpression.vala
@@ -241,6 +241,17 @@ public class Vala.LambdaExpression : Expression {
method.check (context);
+ if (method.this_parameter != null) {
+ if (!method.this_parameter.used) {
+ method.scope.remove ("this");
+ method.this_parameter = null;
+ method.binding = MemberBinding.STATIC;
+ } else if (m != null && m.this_parameter != null) {
+ // track usage inside nested lambda expressions
+ m.this_parameter.used |= method.this_parameter.used;
+ }
+ }
+
value_type = new MethodType (method);
value_type.value_owned = target_type.value_owned;
@@ -258,7 +269,7 @@ public class Vala.LambdaExpression : Expression {
if (method.closure) {
method.get_captured_variables ((Collection<LocalVariable>) collection);
}
- if (in_creation_method) {
+ if (in_creation_method && method.this_parameter != null && method.this_parameter.used) {
Symbol sym = (Block)parent_statement.parent_node;
do {
sym = sym.parent_symbol;
diff --git a/vala/valamemberaccess.vala b/vala/valamemberaccess.vala
index 4a660a9..9447d1c 100644
--- a/vala/valamemberaccess.vala
+++ b/vala/valamemberaccess.vala
@@ -281,6 +281,7 @@ public class Vala.MemberAccess : Expression {
inner.value_type = this_parameter.variable_type.copy ();
inner.value_type.value_owned = false;
inner.symbol_reference = this_parameter;
+ inner.symbol_reference.used = true;
symbol_reference = inner.value_type.get_member (member_name);
}
@@ -497,6 +498,16 @@ public class Vala.MemberAccess : Expression {
local.captured = true;
block.captured = true;
}
+
+ // track usage of instance parameter for flow analysis.
+ // When accessing generic type information, instance access
+ // is needed to copy/destroy generic values.
+ if (local.variable_type.type_parameter != null &&
local.variable_type.type_parameter.parent_symbol is TypeSymbol) {
+ var m = context.analyzer.current_method_or_property_accessor as Method;
+ if (m != null && m.binding == MemberBinding.INSTANCE) {
+ m.this_parameter.used = true;
+ }
+ }
} else if (member is Parameter) {
var param = (Parameter) member;
var m = param.parent_symbol as Method;
@@ -537,6 +548,16 @@ public class Vala.MemberAccess : Expression {
acc.body.captured = true;
}
}
+
+ // track usage of instance parameter for flow analysis.
+ // When accessing generic type information, instance access
+ // is needed to copy/destroy generic values.
+ if (param.variable_type.type_parameter != null &&
param.variable_type.type_parameter.parent_symbol is TypeSymbol) {
+ m = context.analyzer.current_method_or_property_accessor as Method;
+ if (m != null && m.binding == MemberBinding.INSTANCE) {
+ m.this_parameter.used = true;
+ }
+ }
} else if (member is Field) {
var f = (Field) member;
access = f.access;
@@ -785,6 +806,7 @@ public class Vala.MemberAccess : Expression {
inner.value_type = this_parameter.variable_type.copy ();
inner.value_type.value_owned = false;
inner.symbol_reference = this_parameter;
+ inner.symbol_reference.used = true;
} else {
check_lvalue_access ();
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]