[vala/wip/bug567269: 1/5] Make lambdas work in chain-ups again



commit e90b726020c10b76be10bab78b79c419c18540fc
Author: Simon Werbeck <simon werbeck gmail com>
Date:   Wed Nov 26 13:00:29 2014 +0100

    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 files changed, 22 insertions(+), 5 deletions(-)
---
diff --git a/vala/valalambdaexpression.vala b/vala/valalambdaexpression.vala
index a3ee20a..6d0264e 100644
--- a/vala/valalambdaexpression.vala
+++ b/vala/valalambdaexpression.vala
@@ -48,6 +48,8 @@ public class Vala.LambdaExpression : Expression {
 
        private List<Parameter> parameters = new ArrayList<Parameter> ();
 
+       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<LocalVariable>) 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);
+                       }
+               }
        }
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]