vala r2003 - in trunk: . vala



Author: juergbi
Date: Fri Nov  7 11:10:31 2008
New Revision: 2003
URL: http://svn.gnome.org/viewvc/vala?rev=2003&view=rev

Log:
2008-11-07  JÃrg Billeter  <j bitron ch>

	* vala/valablock.vala:
	* vala/valacatchclause.vala:
	* vala/valadeclarationstatement.vala:
	* vala/valadeletestatement.vala:
	* vala/valadostatement.vala:
	* vala/valaexpressionstatement.vala:
	* vala/valaforstatement.vala:
	* vala/valaifstatement.vala:
	* vala/valainitializerlist.vala:
	* vala/valalocalvariable.vala:
	* vala/valalockstatement.vala:
	* vala/valasemanticanalyzer.vala:
	* vala/valaswitchsection.vala:
	* vala/valatrystatement.vala:
	* vala/valawhilestatement.vala:

	Move statement checking to code nodes


Modified:
   trunk/ChangeLog
   trunk/vala/valablock.vala
   trunk/vala/valacatchclause.vala
   trunk/vala/valadeclarationstatement.vala
   trunk/vala/valadeletestatement.vala
   trunk/vala/valadostatement.vala
   trunk/vala/valaexpressionstatement.vala
   trunk/vala/valaforstatement.vala
   trunk/vala/valaifstatement.vala
   trunk/vala/valainitializerlist.vala
   trunk/vala/valalocalvariable.vala
   trunk/vala/valalockstatement.vala
   trunk/vala/valasemanticanalyzer.vala
   trunk/vala/valaswitchsection.vala
   trunk/vala/valatrystatement.vala
   trunk/vala/valawhilestatement.vala

Modified: trunk/vala/valablock.vala
==============================================================================
--- trunk/vala/valablock.vala	(original)
+++ trunk/vala/valablock.vala	Fri Nov  7 11:10:31 2008
@@ -90,4 +90,29 @@
 			stmt.accept (visitor);
 		}
 	}
+
+	public override bool check (SemanticAnalyzer analyzer) {
+		if (checked) {
+			return !error;
+		}
+
+		checked = true;
+
+		owner = analyzer.current_symbol.scope;
+		analyzer.current_symbol = this;
+
+		accept_children (analyzer);
+
+		foreach (LocalVariable local in get_local_variables ()) {
+			local.active = false;
+		}
+
+		foreach (Statement stmt in get_statements()) {
+			add_error_types (stmt.get_error_types ());
+		}
+
+		analyzer.current_symbol = analyzer.current_symbol.parent_symbol;
+
+		return !error;
+	}
 }

Modified: trunk/vala/valacatchclause.vala
==============================================================================
--- trunk/vala/valacatchclause.vala	(original)
+++ trunk/vala/valacatchclause.vala	Fri Nov  7 11:10:31 2008
@@ -1,4 +1,4 @@
-/* valacatchclause.vala
+/* valacatchvala
  *
  * Copyright (C) 2007-2008  JÃrg Billeter
  *
@@ -62,7 +62,7 @@
 	private DataType _data_type;
 
 	/**
-	 * Creates a new catch clause.
+	 * Creates a new catch 
 	 *
 	 * @param type_reference   error type
 	 * @param variable_name    error variable name
@@ -94,4 +94,27 @@
 			error_type = new_type;
 		}
 	}
+
+	public override bool check (SemanticAnalyzer analyzer) {
+		if (checked) {
+			return !error;
+		}
+
+		checked = true;
+
+		if (error_type != null) {
+			analyzer.current_source_file.add_type_dependency (error_type, SourceFileDependencyType.SOURCE);
+
+			error_variable = new LocalVariable (error_type.copy (), variable_name);
+
+			body.scope.add (variable_name, error_variable);
+			body.add_local_variable (error_variable);
+		} else {
+			error_type = new ErrorType (null, null, source_reference);
+		}
+
+		accept_children (analyzer);
+
+		return !error;
+	}
 }

Modified: trunk/vala/valadeclarationstatement.vala
==============================================================================
--- trunk/vala/valadeclarationstatement.vala	(original)
+++ trunk/vala/valadeclarationstatement.vala	Fri Nov  7 11:10:31 2008
@@ -48,4 +48,25 @@
 	
 		visitor.visit_declaration_statement (this);
 	}
+
+	public override bool check (SemanticAnalyzer analyzer) {
+		if (checked) {
+			return !error;
+		}
+
+		checked = true;
+
+		var local = declaration as LocalVariable;
+		if (local != null && local.initializer != null) {
+			foreach (DataType error_type in local.initializer.get_error_types ()) {
+				// ensure we can trace back which expression may throw errors of this type
+				var initializer_error_type = error_type.copy ();
+				initializer_error_type.source_reference = local.initializer.source_reference;
+
+				add_error_type (initializer_error_type);
+			}
+		}
+
+		return !error;
+	}
 }

Modified: trunk/vala/valadeletestatement.vala
==============================================================================
--- trunk/vala/valadeletestatement.vala	(original)
+++ trunk/vala/valadeletestatement.vala	Fri Nov  7 11:10:31 2008
@@ -43,4 +43,26 @@
 	public override void accept_children (CodeVisitor visitor) {
 		expression.accept (visitor);
 	}
+
+	public override bool check (SemanticAnalyzer analyzer) {
+		if (checked) {
+			return !error;
+		}
+
+		checked = true;
+
+		accept_children (analyzer);
+
+		if (expression.error) {
+			// if there was an error in the inner expression, skip this check
+			return false;
+		}
+
+		if (!(expression.value_type is PointerType)) {
+			error = true;
+			Report.error (source_reference, "delete operator not supported for `%s'".printf (expression.value_type.to_string ()));
+		}
+
+		return !error;
+	}
 }

Modified: trunk/vala/valadostatement.vala
==============================================================================
--- trunk/vala/valadostatement.vala	(original)
+++ trunk/vala/valadostatement.vala	Fri Nov  7 11:10:31 2008
@@ -86,4 +86,31 @@
 			condition = new_node;
 		}
 	}
+
+	public override bool check (SemanticAnalyzer analyzer) {
+		if (checked) {
+			return !error;
+		}
+
+		checked = true;
+
+		accept_children (analyzer);
+
+		if (condition.error) {
+			/* if there was an error in the condition, skip this check */
+			error = true;
+			return false;
+		}
+
+		if (!condition.value_type.compatible (analyzer.bool_type)) {
+			error = true;
+			Report.error (condition.source_reference, "Condition must be boolean");
+			return false;
+		}
+
+		add_error_types (condition.get_error_types ());
+		add_error_types (body.get_error_types ());
+
+		return !error;
+	}
 }

Modified: trunk/vala/valaexpressionstatement.vala
==============================================================================
--- trunk/vala/valaexpressionstatement.vala	(original)
+++ trunk/vala/valaexpressionstatement.vala	Fri Nov  7 11:10:31 2008
@@ -1,6 +1,6 @@
 /* valaexpressionstatement.vala
  *
- * Copyright (C) 2006-2007  JÃrg Billeter
+ * Copyright (C) 2006-2008  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
@@ -85,4 +85,22 @@
 
 		return null;
 	}
+
+	public override bool check (SemanticAnalyzer analyzer) {
+		if (checked) {
+			return !error;
+		}
+
+		checked = true;
+
+		if (expression.error) {
+			// ignore inner error
+			error = true;
+			return false;
+		}
+
+		add_error_types (expression.get_error_types ());
+
+		return !error;
+	}
 }

Modified: trunk/vala/valaforstatement.vala
==============================================================================
--- trunk/vala/valaforstatement.vala	(original)
+++ trunk/vala/valaforstatement.vala	Fri Nov  7 11:10:31 2008
@@ -156,4 +156,40 @@
 			}
 		}
 	}
+
+	public override bool check (SemanticAnalyzer analyzer) {
+		if (checked) {
+			return !error;
+		}
+
+		checked = true;
+
+		accept_children (analyzer);
+
+		if (condition != null && condition.error) {
+			/* if there was an error in the condition, skip this check */
+			error = true;
+			return false;
+		}
+
+		if (condition != null && !condition.value_type.compatible (analyzer.bool_type)) {
+			error = true;
+			Report.error (condition.source_reference, "Condition must be boolean");
+			return false;
+		}
+
+		if (condition != null) {
+			add_error_types (condition.get_error_types ());
+		}
+
+		add_error_types (body.get_error_types ());
+		foreach (Expression exp in get_initializer ()) {
+			add_error_types (exp.get_error_types ());
+		}
+		foreach (Expression exp in get_iterator ()) {
+			add_error_types (exp.get_error_types ());
+		}
+
+		return !error;
+	}
 }

Modified: trunk/vala/valaifstatement.vala
==============================================================================
--- trunk/vala/valaifstatement.vala	(original)
+++ trunk/vala/valaifstatement.vala	Fri Nov  7 11:10:31 2008
@@ -86,4 +86,35 @@
 			condition = new_node;
 		}
 	}
+
+	public override bool check (SemanticAnalyzer analyzer) {
+		if (checked) {
+			return !error;
+		}
+
+		checked = true;
+
+		accept_children (analyzer);
+
+		if (condition.error) {
+			/* if there was an error in the condition, skip this check */
+			error = true;
+			return false;
+		}
+
+		if (!condition.value_type.compatible (analyzer.bool_type)) {
+			error = true;
+			Report.error (condition.source_reference, "Condition must be boolean");
+			return false;
+		}
+
+		add_error_types (condition.get_error_types ());
+		add_error_types (true_statement.get_error_types ());
+
+		if (false_statement != null) {
+			add_error_types (false_statement.get_error_types ());
+		}
+
+		return !error;
+	}
 }

Modified: trunk/vala/valainitializerlist.vala
==============================================================================
--- trunk/vala/valainitializerlist.vala	(original)
+++ trunk/vala/valainitializerlist.vala	Fri Nov  7 11:10:31 2008
@@ -1,4 +1,4 @@
-/* valainitializerlist.vala
+/* valainitializervala
  *
  * Copyright (C) 2006-2008  JÃrg Billeter, Raffaele Sandrini
  *
@@ -31,7 +31,7 @@
 	private Gee.List<Expression> initializers = new ArrayList<Expression> ();
 	
 	/**
-	 * Appends the specified expression to this initializer list.
+	 * Appends the specified expression to this initializer 
 	 *
 	 * @param expr an expression
 	 */
@@ -41,7 +41,7 @@
 	}
 	
 	/**
-	 * Returns a copy of the expression list.
+	 * Returns a copy of the expression 
 	 *
 	 * @return expression list
 	 */
@@ -50,14 +50,14 @@
 	}
 
 	/**
-	 * Returns the initializer count in this initializer list.
+	 * Returns the initializer count in this initializer 
 	 */
 	public int size {
 		get { return initializers.size; }
 	}
 
 	/**
-	 * Creates a new initializer list.
+	 * Creates a new initializer 
 	 *
 	 * @param source_reference reference to source code
 	 * @return                 newly created initializer list
@@ -92,4 +92,80 @@
 			}
 		}
 	}
+
+	public override bool check (SemanticAnalyzer analyzer) {
+		if (checked) {
+			return !error;
+		}
+
+		checked = true;
+
+		if (target_type == null) {
+			error = true;
+			Report.error (source_reference, "initializer list used for unknown type");
+			return false;
+		} else if (target_type is ArrayType) {
+			/* initializer is used as array initializer */
+			var array_type = (ArrayType) target_type;
+
+			foreach (Expression e in get_initializers ()) {
+				e.target_type = array_type.element_type.copy ();
+			}
+		} else if (target_type.data_type is Struct) {
+			/* initializer is used as struct initializer */
+			var st = (Struct) target_type.data_type;
+
+			var field_it = st.get_fields ().iterator ();
+			foreach (Expression e in get_initializers ()) {
+				Field field = null;
+				while (field == null) {
+					if (!field_it.next ()) {
+						error = true;
+						Report.error (e.source_reference, "too many expressions in initializer list for `%s'".printf (target_type.to_string ()));
+						return false;
+					}
+					field = field_it.get ();
+					if (field.binding != MemberBinding.INSTANCE) {
+						// we only initialize instance fields
+						field = null;
+					}
+				}
+
+				e.target_type = field.field_type.copy ();
+				if (!target_type.value_owned) {
+					e.target_type.value_owned = false;
+				}
+			}
+		} else {
+			error = true;
+			Report.error (source_reference, "initializer list used for `%s', which is neither array nor struct".printf (target_type.to_string ()));
+			return false;
+		}
+
+		accept_children (analyzer);
+
+		bool error = false;
+		foreach (Expression e in get_initializers ()) {
+			if (e.value_type == null) {
+				error = true;
+				continue;
+			}
+
+			var unary = e as UnaryExpression;
+			if (unary != null && (unary.operator == UnaryOperator.REF || unary.operator == UnaryOperator.OUT)) {
+				// TODO check type for ref and out expressions
+			} else if (!e.value_type.compatible (e.target_type)) {
+				error = true;
+				e.error = true;
+				Report.error (e.source_reference, "Expected initializer of type `%s' but got `%s'".printf (e.target_type.to_string (), e.value_type.to_string ()));
+			}
+		}
+
+		if (!error) {
+			/* everything seems to be correct */
+			value_type = target_type;
+		}
+
+		return !error;
+	}
 }

Modified: trunk/vala/valalocalvariable.vala
==============================================================================
--- trunk/vala/valalocalvariable.vala	(original)
+++ trunk/vala/valalocalvariable.vala	Fri Nov  7 11:10:31 2008
@@ -98,4 +98,96 @@
 			variable_type = new_type;
 		}
 	}
+
+	public override bool check (SemanticAnalyzer analyzer) {
+		if (checked) {
+			return !error;
+		}
+
+		checked = true;
+
+		if (initializer != null) {
+			initializer.target_type = variable_type;
+		}
+
+		accept_children (analyzer);
+
+		if (variable_type == null) {
+			/* var type */
+
+			if (initializer == null) {
+				error = true;
+				Report.error (source_reference, "var declaration not allowed without initializer");
+				return false;
+			}
+			if (initializer.value_type == null) {
+				error = true;
+				Report.error (source_reference, "var declaration not allowed with non-typed initializer");
+				return false;
+			}
+
+			variable_type = initializer.value_type.copy ();
+			variable_type.value_owned = true;
+			variable_type.floating_reference = false;
+
+			initializer.target_type = variable_type;
+		}
+
+		if (initializer != null) {
+			if (initializer.value_type == null) {
+				if (!(initializer is MemberAccess) && !(initializer is LambdaExpression)) {
+					error = true;
+					Report.error (source_reference, "expression type not allowed as initializer");
+					return false;
+				}
+
+				if (initializer.symbol_reference is Method &&
+				    variable_type is DelegateType) {
+					var m = (Method) initializer.symbol_reference;
+					var dt = (DelegateType) variable_type;
+					var cb = dt.delegate_symbol;
+
+					/* check whether method matches callback type */
+					if (!cb.matches_method (m)) {
+						error = true;
+						Report.error (source_reference, "declaration of method `%s' doesn't match declaration of callback `%s'".printf (m.get_full_name (), cb.get_full_name ()));
+						return false;
+					}
+
+					initializer.value_type = variable_type;
+				} else {
+					error = true;
+					Report.error (source_reference, "expression type not allowed as initializer");
+					return false;
+				}
+			}
+
+			if (!initializer.value_type.compatible (variable_type)) {
+				error = true;
+				Report.error (source_reference, "Assignment: Cannot convert from `%s' to `%s'".printf (initializer.value_type.to_string (), variable_type.to_string ()));
+				return false;
+			}
+
+			if (initializer.value_type.is_disposable ()) {
+				/* rhs transfers ownership of the expression */
+				if (!(variable_type is PointerType) && !variable_type.value_owned) {
+					/* lhs doesn't own the value */
+					error = true;
+					Report.error (source_reference, "Invalid assignment from owned expression to unowned variable");
+					return false;
+				}
+			}
+		}
+
+		analyzer.current_source_file.add_type_dependency (variable_type, SourceFileDependencyType.SOURCE);
+
+		analyzer.current_symbol.scope.add (name, this);
+
+		var block = (Block) analyzer.current_symbol;
+		block.add_local_variable (this);
+
+		active = true;
+
+		return !error;
+	}
 }

Modified: trunk/vala/valalockstatement.vala
==============================================================================
--- trunk/vala/valalockstatement.vala	(original)
+++ trunk/vala/valalockstatement.vala	Fri Nov  7 11:10:31 2008
@@ -47,4 +47,31 @@
 		body.accept (visitor);
 		visitor.visit_lock_statement (this);
 	}
+
+	public override bool check (SemanticAnalyzer analyzer) {
+		if (checked) {
+			return !error;
+		}
+
+		checked = true;
+
+		/* resource must be a member access and denote a Lockable */
+		if (!(resource is MemberAccess && resource.symbol_reference is Lockable)) {
+		    	error = true;
+			resource.error = true;
+			Report.error (resource.source_reference, "Expression is either not a member access or does not denote a lockable member");
+			return false;
+		}
+
+		/* parent symbol must be the current class */
+		if (resource.symbol_reference.parent_symbol != analyzer.current_class) {
+		    	error = true;
+			resource.error = true;
+			Report.error (resource.source_reference, "Only members of the current class are lockable");
+		}
+
+		((Lockable) resource.symbol_reference).set_lock_used (true);
+
+		return !error;
+	}
 }

Modified: trunk/vala/valasemanticanalyzer.vala
==============================================================================
--- trunk/vala/valasemanticanalyzer.vala	(original)
+++ trunk/vala/valasemanticanalyzer.vala	Fri Nov  7 11:10:31 2008
@@ -229,308 +229,43 @@
 	}
 
 	public override void visit_block (Block b) {
-		b.owner = current_symbol.scope;
-		current_symbol = b;
-
-		b.accept_children (this);
-
-		foreach (LocalVariable local in b.get_local_variables ()) {
-			local.active = false;
-		}
-
-		foreach (Statement stmt in b.get_statements()) {
-			b.add_error_types (stmt.get_error_types ());
-		}
-
-		current_symbol = current_symbol.parent_symbol;
+		b.check (this);
 	}
 
 	public override void visit_declaration_statement (DeclarationStatement stmt) {
-		var local = stmt.declaration as LocalVariable;
-		if (local != null && local.initializer != null) {
-			foreach (DataType error_type in local.initializer.get_error_types ()) {
-				// ensure we can trace back which expression may throw errors of this type
-				var initializer_error_type = error_type.copy ();
-				initializer_error_type.source_reference = local.initializer.source_reference;
-
-				stmt.add_error_type (initializer_error_type);
-			}
-		}
+		stmt.check (this);
 	}
 
 	public override void visit_local_variable (LocalVariable local) {
-		if (local.initializer != null) {
-			local.initializer.target_type = local.variable_type;
-		}
-
-		local.accept_children (this);
-
-		if (local.variable_type == null) {
-			/* var type */
-
-			if (local.initializer == null) {
-				local.error = true;
-				Report.error (local.source_reference, "var declaration not allowed without initializer");
-				return;
-			}
-			if (local.initializer.value_type == null) {
-				local.error = true;
-				Report.error (local.source_reference, "var declaration not allowed with non-typed initializer");
-				return;
-			}
-
-			local.variable_type = local.initializer.value_type.copy ();
-			local.variable_type.value_owned = true;
-			local.variable_type.floating_reference = false;
-
-			local.initializer.target_type = local.variable_type;
-		}
-
-		if (local.initializer != null) {
-			if (local.initializer.value_type == null) {
-				if (!(local.initializer is MemberAccess) && !(local.initializer is LambdaExpression)) {
-					local.error = true;
-					Report.error (local.source_reference, "expression type not allowed as initializer");
-					return;
-				}
-
-				if (local.initializer.symbol_reference is Method &&
-				    local.variable_type is DelegateType) {
-					var m = (Method) local.initializer.symbol_reference;
-					var dt = (DelegateType) local.variable_type;
-					var cb = dt.delegate_symbol;
-
-					/* check whether method matches callback type */
-					if (!cb.matches_method (m)) {
-						local.error = true;
-						Report.error (local.source_reference, "declaration of method `%s' doesn't match declaration of callback `%s'".printf (m.get_full_name (), cb.get_full_name ()));
-						return;
-					}
-
-					local.initializer.value_type = local.variable_type;
-				} else {
-					local.error = true;
-					Report.error (local.source_reference, "expression type not allowed as initializer");
-					return;
-				}
-			}
-
-			if (!local.initializer.value_type.compatible (local.variable_type)) {
-				local.error = true;
-				Report.error (local.source_reference, "Assignment: Cannot convert from `%s' to `%s'".printf (local.initializer.value_type.to_string (), local.variable_type.to_string ()));
-				return;
-			}
-
-			if (local.initializer.value_type.is_disposable ()) {
-				/* rhs transfers ownership of the expression */
-				if (!(local.variable_type is PointerType) && !local.variable_type.value_owned) {
-					/* lhs doesn't own the value */
-					local.error = true;
-					Report.error (local.source_reference, "Invalid assignment from owned expression to unowned variable");
-					return;
-				}
-			}
-		}
-
-		current_source_file.add_type_dependency (local.variable_type, SourceFileDependencyType.SOURCE);
-
-		current_symbol.scope.add (local.name, local);
-
-		var block = (Block) current_symbol;
-		block.add_local_variable (local);
-
-		local.active = true;
+		local.check (this);
 	}
 
-	/**
-	 * Visit operation called for initializer lists
-	 *
-	 * @param list an initializer list
-	 */
 	public override void visit_initializer_list (InitializerList list) {
-		if (list.target_type == null) {
-			list.error = true;
-			Report.error (list.source_reference, "initializer list used for unknown type");
-			return;
-		} else if (list.target_type is ArrayType) {
-			/* initializer is used as array initializer */
-			var array_type = (ArrayType) list.target_type;
-
-			foreach (Expression e in list.get_initializers ()) {
-				e.target_type = array_type.element_type.copy ();
-			}
-		} else if (list.target_type.data_type is Struct) {
-			/* initializer is used as struct initializer */
-			var st = (Struct) list.target_type.data_type;
-
-			var field_it = st.get_fields ().iterator ();
-			foreach (Expression e in list.get_initializers ()) {
-				Field field = null;
-				while (field == null) {
-					if (!field_it.next ()) {
-						list.error = true;
-						Report.error (e.source_reference, "too many expressions in initializer list for `%s'".printf (list.target_type.to_string ()));
-						return;
-					}
-					field = field_it.get ();
-					if (field.binding != MemberBinding.INSTANCE) {
-						// we only initialize instance fields
-						field = null;
-					}
-				}
-
-				e.target_type = field.field_type.copy ();
-				if (!list.target_type.value_owned) {
-					e.target_type.value_owned = false;
-				}
-			}
-		} else {
-			list.error = true;
-			Report.error (list.source_reference, "initializer list used for `%s', which is neither array nor struct".printf (list.target_type.to_string ()));
-			return;
-		}
-
-		list.accept_children (this);
-
-		bool error = false;
-		foreach (Expression e in list.get_initializers ()) {
-			if (e.value_type == null) {
-				error = true;
-				continue;
-			}
-
-			var unary = e as UnaryExpression;
-			if (unary != null && (unary.operator == UnaryOperator.REF || unary.operator == UnaryOperator.OUT)) {
-				// TODO check type for ref and out expressions
-			} else if (!e.value_type.compatible (e.target_type)) {
-				error = true;
-				e.error = true;
-				Report.error (e.source_reference, "Expected initializer of type `%s' but got `%s'".printf (e.target_type.to_string (), e.value_type.to_string ()));
-			}
-		}
-
-		if (!error) {
-			/* everything seems to be correct */
-			list.value_type = list.target_type;
-		}
+		list.check (this);
 	}
 
 	public override void visit_expression_statement (ExpressionStatement stmt) {
-		if (stmt.expression.error) {
-			// ignore inner error
-			stmt.error = true;
-			return;
-		}
-
-		stmt.add_error_types (stmt.expression.get_error_types ());
+		stmt.check (this);
 	}
 
 	public override void visit_if_statement (IfStatement stmt) {
-		stmt.accept_children (this);
-
-		if (stmt.condition.error) {
-			/* if there was an error in the condition, skip this check */
-			stmt.error = true;
-			return;
-		}
-
-		if (!stmt.condition.value_type.compatible (bool_type)) {
-			stmt.error = true;
-			Report.error (stmt.condition.source_reference, "Condition must be boolean");
-			return;
-		}
-
-		stmt.add_error_types (stmt.condition.get_error_types ());
-		stmt.add_error_types (stmt.true_statement.get_error_types ());
-
-		if (stmt.false_statement != null) {
-			stmt.add_error_types (stmt.false_statement.get_error_types ());
-		}
+		stmt.check (this);
 	}
 
 	public override void visit_switch_section (SwitchSection section) {
-		foreach (SwitchLabel label in section.get_labels ()) {
-			label.accept (this);
-		}
-
-		section.owner = current_symbol.scope;
-		current_symbol = section;
-
-		foreach (Statement st in section.get_statements ()) {
-			st.accept (this);
-		}
-
-		foreach (LocalVariable local in section.get_local_variables ()) {
-			local.active = false;
-		}
-
-		current_symbol = current_symbol.parent_symbol;
+		section.check (this);
 	}
 
 	public override void visit_while_statement (WhileStatement stmt) {
-		stmt.accept_children (this);
-
-		if (stmt.condition.error) {
-			/* if there was an error in the condition, skip this check */
-			stmt.error = true;
-			return;
-		}
-
-		if (!stmt.condition.value_type.compatible (bool_type)) {
-			stmt.error = true;
-			Report.error (stmt.condition.source_reference, "Condition must be boolean");
-			return;
-		}
-
-		stmt.add_error_types (stmt.condition.get_error_types ());
-		stmt.add_error_types (stmt.body.get_error_types ());
+		stmt.check (this);
 	}
 
 	public override void visit_do_statement (DoStatement stmt) {
-		stmt.accept_children (this);
-
-		if (stmt.condition.error) {
-			/* if there was an error in the condition, skip this check */
-			stmt.error = true;
-			return;
-		}
-
-		if (!stmt.condition.value_type.compatible (bool_type)) {
-			stmt.error = true;
-			Report.error (stmt.condition.source_reference, "Condition must be boolean");
-			return;
-		}
-
-		stmt.add_error_types (stmt.condition.get_error_types ());
-		stmt.add_error_types (stmt.body.get_error_types ());
+		stmt.check (this);
 	}
 
 	public override void visit_for_statement (ForStatement stmt) {
-		stmt.accept_children (this);
-
-		if (stmt.condition != null && stmt.condition.error) {
-			/* if there was an error in the condition, skip this check */
-			stmt.error = true;
-			return;
-		}
-
-		if (stmt.condition != null && !stmt.condition.value_type.compatible (bool_type)) {
-			stmt.error = true;
-			Report.error (stmt.condition.source_reference, "Condition must be boolean");
-			return;
-		}
-
-		if (stmt.condition != null) {
-			stmt.add_error_types (stmt.condition.get_error_types ());
-		}
-
-		stmt.add_error_types (stmt.body.get_error_types ());
-		foreach (Expression exp in stmt.get_initializer ()) {
-			stmt.add_error_types (exp.get_error_types ());
-		}
-		foreach (Expression exp in stmt.get_iterator ()) {
-			stmt.add_error_types (exp.get_error_types ());
-		}
+		stmt.check (this);
 	}
 
 	public override void visit_foreach_statement (ForeachStatement stmt) {
@@ -550,62 +285,21 @@
 	}
 
 	public override void visit_try_statement (TryStatement stmt) {
-		stmt.accept_children (this);
+		stmt.check (this);
 	}
 
 	public override void visit_catch_clause (CatchClause clause) {
-		if (clause.error_type != null) {
-			current_source_file.add_type_dependency (clause.error_type, SourceFileDependencyType.SOURCE);
-
-			clause.error_variable = new LocalVariable (clause.error_type.copy (), clause.variable_name);
-
-			clause.body.scope.add (clause.variable_name, clause.error_variable);
-			clause.body.add_local_variable (clause.error_variable);
-		} else {
-			clause.error_type = new ErrorType (null, null, clause.source_reference);
-		}
-
-		clause.accept_children (this);
+		clause.check (this);
 	}
 
 	public override void visit_lock_statement (LockStatement stmt) {
-		/* resource must be a member access and denote a Lockable */
-		if (!(stmt.resource is MemberAccess && stmt.resource.symbol_reference is Lockable)) {
-		    	stmt.error = true;
-			stmt.resource.error = true;
-			Report.error (stmt.resource.source_reference, "Expression is either not a member access or does not denote a lockable member");
-			return;
-		}
-
-		/* parent symbol must be the current class */
-		if (stmt.resource.symbol_reference.parent_symbol != current_class) {
-		    	stmt.error = true;
-			stmt.resource.error = true;
-			Report.error (stmt.resource.source_reference, "Only members of the current class are lockable");
-		}
-
-		((Lockable) stmt.resource.symbol_reference).set_lock_used (true);
+		stmt.check (this);
 	}
 
 	public override void visit_delete_statement (DeleteStatement stmt) {
-		stmt.accept_children (this);
-
-		if (stmt.expression.error) {
-			// if there was an error in the inner expression, skip this check
-			return;
-		}
-
-		if (!(stmt.expression.value_type is PointerType)) {
-			stmt.error = true;
-			Report.error (stmt.source_reference, "delete operator not supported for `%s'".printf (stmt.expression.value_type.to_string ()));
-		}
+		stmt.check (this);
 	}
 
-	/**
-	 * Visit operations called for array creation expresions.
-	 *
-	 * @param expr an array creation expression
-	 */
 	public override void visit_array_creation_expression (ArrayCreationExpression expr) {
 		expr.check (this);
 	}

Modified: trunk/vala/valaswitchsection.vala
==============================================================================
--- trunk/vala/valaswitchsection.vala	(original)
+++ trunk/vala/valaswitchsection.vala	Fri Nov  7 11:10:31 2008
@@ -80,4 +80,31 @@
 			st.accept (visitor);
 		}
 	}
+
+	public override bool check (SemanticAnalyzer analyzer) {
+		if (checked) {
+			return !error;
+		}
+
+		checked = true;
+
+		foreach (SwitchLabel label in get_labels ()) {
+			label.accept (analyzer);
+		}
+
+		owner = analyzer.current_symbol.scope;
+		analyzer.current_symbol = this;
+
+		foreach (Statement st in get_statements ()) {
+			st.accept (analyzer);
+		}
+
+		foreach (LocalVariable local in get_local_variables ()) {
+			local.active = false;
+		}
+
+		analyzer.current_symbol = analyzer.current_symbol.parent_symbol;
+
+		return !error;
+	}
 }

Modified: trunk/vala/valatrystatement.vala
==============================================================================
--- trunk/vala/valatrystatement.vala	(original)
+++ trunk/vala/valatrystatement.vala	Fri Nov  7 11:10:31 2008
@@ -86,4 +86,16 @@
 			finally_body.accept (visitor);
 		}
 	}
+
+	public override bool check (SemanticAnalyzer analyzer) {
+		if (checked) {
+			return !error;
+		}
+
+		checked = true;
+
+		accept_children (analyzer);
+
+		return !error;
+	}
 }

Modified: trunk/vala/valawhilestatement.vala
==============================================================================
--- trunk/vala/valawhilestatement.vala	(original)
+++ trunk/vala/valawhilestatement.vala	Fri Nov  7 11:10:31 2008
@@ -86,4 +86,31 @@
 			condition = new_node;
 		}
 	}
+
+	public override bool check (SemanticAnalyzer analyzer) {
+		if (checked) {
+			return !error;
+		}
+
+		checked = true;
+
+		accept_children (analyzer);
+
+		if (condition.error) {
+			/* if there was an error in the condition, skip this check */
+			error = true;
+			return false;
+		}
+
+		if (!condition.value_type.compatible (analyzer.bool_type)) {
+			error = true;
+			Report.error (condition.source_reference, "Condition must be boolean");
+			return false;
+		}
+
+		add_error_types (condition.get_error_types ());
+		add_error_types (body.get_error_types ());
+
+		return !error;
+	}
 }



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