[vala] Perform flow analysis on lambda expressions



commit da67841f1fed0b391965e6c1b2179855396ab06b
Author: Marc-André Lureau <marcandre lureau gmail com>
Date:   Sun Jan 24 18:41:44 2010 +0100

    Perform flow analysis on lambda expressions
    
    Fixes bug 606478.

 vala/valaflowanalyzer.vala     |   26 +++++++++++++++++++++++++-
 vala/valalambdaexpression.vala |   17 ++++++-----------
 vala/valamethod.vala           |    8 ++++++++
 3 files changed, 39 insertions(+), 12 deletions(-)
---
diff --git a/vala/valaflowanalyzer.vala b/vala/valaflowanalyzer.vala
index 878936d..43baefd 100644
--- a/vala/valaflowanalyzer.vala
+++ b/vala/valaflowanalyzer.vala
@@ -135,6 +135,25 @@ public class Vala.FlowAnalyzer : CodeVisitor {
 		}
 	}
 
+	public override void visit_lambda_expression (LambdaExpression le) {
+		var old_current_block = current_block;
+		var old_unreachable_reported = unreachable_reported;
+		var old_jump_stack = jump_stack;
+		current_block = null;
+		unreachable_reported = false;
+		jump_stack = new ArrayList<JumpTarget> ();
+
+		le.accept_children (this);
+
+		current_block = old_current_block;
+		unreachable_reported = old_unreachable_reported;
+		jump_stack = old_jump_stack;
+	}
+
+	public override void visit_method_call (MethodCall mc) {
+		mc.accept_children (this);
+	}
+
 	public override void visit_method (Method m) {
 		if (m.is_internal_symbol () && !m.used && !m.entry_point
 		    && !m.overrides && (m.base_interface_method == null || m.base_interface_method == m)
@@ -151,6 +170,7 @@ public class Vala.FlowAnalyzer : CodeVisitor {
 
 		current_block = new BasicBlock ();
 		m.entry_block.connect (current_block);
+		current_block.add_node (m);
 
 		jump_stack.add (new JumpTarget.return_target (m.exit_block));
 
@@ -162,7 +182,7 @@ public class Vala.FlowAnalyzer : CodeVisitor {
 			// end of method body reachable
 
 			if (!(m.return_type is VoidType)) {
-				Report.error (m.source_reference, "missing return statement at end of method body");
+				Report.error (m.source_reference, "missing return statement at end of method or lambda body");
 				m.error = true;
 			}
 
@@ -508,6 +528,8 @@ public class Vala.FlowAnalyzer : CodeVisitor {
 	}
 
 	public override void visit_expression_statement (ExpressionStatement stmt) {
+		stmt.accept_children (this);
+
 		if (unreachable (stmt)) {
 			return;
 		}
@@ -759,6 +781,8 @@ public class Vala.FlowAnalyzer : CodeVisitor {
 	}
 
 	public override void visit_return_statement (ReturnStatement stmt) {
+		stmt.accept_children (this);
+
 		if (unreachable (stmt)) {
 			return;
 		}
diff --git a/vala/valalambdaexpression.vala b/vala/valalambdaexpression.vala
index 0f0bb29..facaed9 100644
--- a/vala/valalambdaexpression.vala
+++ b/vala/valalambdaexpression.vala
@@ -1,6 +1,6 @@
 /* valalambdaexpression.vala
  *
- * Copyright (C) 2006-2009  Jürg Billeter
+ * Copyright (C) 2006-2010  Jürg Billeter
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -133,7 +133,10 @@ public class Vala.LambdaExpression : Expression {
 		}
 
 		var cb = (Delegate) ((DelegateType) target_type).delegate_symbol;
-		method = new Method (get_lambda_name (analyzer), cb.return_type);
+		method = new Method (get_lambda_name (analyzer), cb.return_type, source_reference);
+		// track usage for flow analyzer
+		method.used = true;
+
 		if (!cb.has_target || !analyzer.is_in_instance_method ()) {
 			method.binding = MemberBinding.STATIC;
 		} else {
@@ -211,15 +214,7 @@ public class Vala.LambdaExpression : Expression {
 		/* lambda expressions should be usable like MemberAccess of a method */
 		symbol_reference = method;
 
-		if (method == null) {
-			if (expression_body != null) {
-				expression_body.check (analyzer);
-			} else if (statement_body != null) {
-				statement_body.check (analyzer);
-			}
-		} else {
-			method.check (analyzer);
-		}
+		method.check (analyzer);
 
 		value_type = new MethodType (method);
 		value_type.value_owned = target_type.value_owned;
diff --git a/vala/valamethod.vala b/vala/valamethod.vala
index 6089189..4040d37 100644
--- a/vala/valamethod.vala
+++ b/vala/valamethod.vala
@@ -1066,6 +1066,14 @@ public class Vala.Method : Member {
 			}
 		}
 	}
+
+	public override void get_defined_variables (Collection<LocalVariable> collection) {
+		// capturing variables is only supported if they are initialized
+		// therefore assume that captured variables are initialized
+		if (closure) {
+			get_captured_variables (collection);
+		}
+	}
 }
 
 // vim:sw=8 noet



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