From: Simon Werbeck Date: Wed, 26 Nov 2014 12:00:29 +0000 (+0100) Subject: Make lambdas work in chain-ups again X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e90b726020c10b76be10bab78b79c419c18540fc;p=thirdparty%2Fvala.git 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 --- 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); + } + } } }