From e90b726020c10b76be10bab78b79c419c18540fc Mon Sep 17 00:00:00 2001 From: Simon Werbeck Date: Wed, 26 Nov 2014 13:00:29 +0100 Subject: [PATCH] Make lambdas work in chain-ups again Lambdas can confuse the flow analyser when chaining up. The reason is that lambdas take their instance parameter directly from the enclosing method without copying it. Since flow analysis in the lambdas method body is separate from the creation method it was defined in, 'this' is seen as uninitialized. https://bugzilla.gnome.org/show_bug.cgi?id=567269 --- vala/valalambdaexpression.vala | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/vala/valalambdaexpression.vala b/vala/valalambdaexpression.vala index a3ee20a2f..6d0264e2c 100644 --- a/vala/valalambdaexpression.vala +++ b/vala/valalambdaexpression.vala @@ -48,6 +48,8 @@ public class Vala.LambdaExpression : Expression { private List parameters = new ArrayList (); + private bool in_creation_method; + /** * Creates a new lambda expression. * @@ -141,23 +143,27 @@ public class Vala.LambdaExpression : Expression { method.binding = MemberBinding.STATIC; } else { var sym = context.analyzer.current_symbol; - while (method.this_parameter == null) { + Parameter this_parameter = null; + while (this_parameter == null) { if (sym is Property) { var prop = (Property) sym; - method.this_parameter = prop.this_parameter; + this_parameter = prop.this_parameter; } else if (sym is Constructor) { var c = (Constructor) sym; - method.this_parameter = c.this_parameter; + this_parameter = c.this_parameter; } else if (sym is Destructor) { var d = (Destructor) sym; - method.this_parameter = d.this_parameter; + this_parameter = d.this_parameter; } else if (sym is Method) { var m = (Method) sym; - method.this_parameter = m.this_parameter; + this_parameter = m.this_parameter; + in_creation_method = sym is CreationMethod; } sym = sym.parent_symbol; } + method.this_parameter = new Parameter ("this", this_parameter.variable_type.copy ()); + method.scope.add ("this", method.this_parameter); } method.owner = context.analyzer.current_symbol.scope; @@ -250,5 +256,16 @@ public class Vala.LambdaExpression : Expression { if (method.closure) { method.get_captured_variables ((Collection) collection); } + if (in_creation_method) { + Symbol sym = (Block) parent_statement.parent_node; + do { + sym = sym.parent_symbol; + } while (sym is Block); + var m = (CreationMethod) sym; + + if (m.chain_up) { + collection.add (m.this_parameter); + } + } } } -- 2.47.2