vala r1420 - in trunk: . gobject vala vapigen



Author: juergbi
Date: Sun May 25 09:09:39 2008
New Revision: 1420
URL: http://svn.gnome.org/viewvc/vala?rev=1420&view=rev

Log:
2008-05-25  Juerg Billeter  <j bitron ch>

	* vala/valacodenode.vala:
	* vala/valacreationmethod.vala:
	* vala/valaexpression.vala:
	* vala/valagenieparser.vala:
	* vala/valainterfacewriter.vala:
	* vala/valamethod.vala:
	* vala/valanamespace.vala:
	* vala/valaparser.vala:
	* vala/valasemanticanalyzer.vala:
	* vala/valasourcefile.vala:
	* gobject/valaccodeclassbinding.vala:
	* gobject/valaccodegenerator.vala:
	* gobject/valaccodeinvocationexpressionbinding.vala:
	* gobject/valaccodemethodbinding.vala:
	* vapigen/valagidlparser.vala:
	* vapigen/valavapigen.vala:

	Track error types that expressions can throw,
	based on patch by Jared Moore, fixes bug 482999


Modified:
   trunk/ChangeLog
   trunk/gobject/valaccodeclassbinding.vala
   trunk/gobject/valaccodegenerator.vala
   trunk/gobject/valaccodeinvocationexpressionbinding.vala
   trunk/gobject/valaccodemethodbinding.vala
   trunk/vala/valacodenode.vala
   trunk/vala/valacreationmethod.vala
   trunk/vala/valaexpression.vala
   trunk/vala/valagenieparser.vala
   trunk/vala/valainterfacewriter.vala
   trunk/vala/valamethod.vala
   trunk/vala/valanamespace.vala
   trunk/vala/valaparser.vala
   trunk/vala/valasemanticanalyzer.vala
   trunk/vala/valasourcefile.vala
   trunk/vapigen/valagidlparser.vala
   trunk/vapigen/valavapigen.vala

Modified: trunk/gobject/valaccodeclassbinding.vala
==============================================================================
--- trunk/gobject/valaccodeclassbinding.vala	(original)
+++ trunk/gobject/valaccodeclassbinding.vala	Sun May 25 09:09:39 2008
@@ -949,7 +949,7 @@
 			ccall.add_argument (new CCodeIdentifier (param.name));
 		}
 
-		if (m.get_error_domains ().size > 0) {
+		if (m.get_error_types ().size > 0) {
 			ccall.add_argument (new CCodeIdentifier ("error"));
 		}
 

Modified: trunk/gobject/valaccodegenerator.vala
==============================================================================
--- trunk/gobject/valaccodegenerator.vala	(original)
+++ trunk/gobject/valaccodegenerator.vala	Sun May 25 09:09:39 2008
@@ -1206,7 +1206,7 @@
 		cdecl.add_declarator (cvar);
 		cfrag.append (cdecl);
 
-		if (local.initializer != null && local.initializer.can_fail) {
+		if (local.initializer != null && local.initializer.tree_can_fail) {
 			add_simple_check (local.initializer, cfrag);
 		}
 
@@ -1559,7 +1559,7 @@
 			var ccond = new CCodeBinaryExpression (CCodeBinaryOperator.INEQUALITY, new CCodeIdentifier ("inner_error"), new CCodeConstant ("NULL"));
 
 			cfrag.append (new CCodeIfStatement (ccond, cerror_block));
-		} else if (current_method != null && current_method.get_error_domains ().size > 0) {
+		} else if (current_method != null && current_method.get_error_types ().size > 0) {
 			// current method can fail, propagate error
 			// TODO ensure one of the error domains matches
 
@@ -1580,8 +1580,7 @@
 
 			cfrag.append (new CCodeIfStatement (ccond, cerror_block));
 		} else {
-			// TODO improve check and move to semantic analyzer
-			Report.warning (node.source_reference, "unhandled error");
+			// unhandled error
 
 			var cerror_block = new CCodeBlock ();
 			// print critical message
@@ -1597,7 +1596,7 @@
 	public override void visit_expression_statement (ExpressionStatement stmt) {
 		stmt.ccodenode = new CCodeExpressionStatement ((CCodeExpression) stmt.expression.ccodenode);
 
-		if (stmt.tree_can_fail && stmt.expression.can_fail) {
+		if (stmt.tree_can_fail && stmt.expression.tree_can_fail) {
 			// simple case, no node breakdown necessary
 
 			var cfrag = new CCodeFragment ();
@@ -1874,7 +1873,7 @@
 		ccoldecl.add_declarator (ccolvardecl);
 		cblock.add_statement (ccoldecl);
 		
-		if (stmt.tree_can_fail && stmt.collection.can_fail) {
+		if (stmt.tree_can_fail && stmt.collection.tree_can_fail) {
 			// exception handling
 			var cfrag = new CCodeFragment ();
 			add_simple_check (stmt.collection, cfrag);
@@ -3091,7 +3090,7 @@
 				creation_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, instance));
 			}
 
-			if (expr.can_fail) {
+			if (expr.tree_can_fail) {
 				// method can fail
 				current_method_inner_error = true;
 				creation_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("inner_error")));
@@ -3512,7 +3511,7 @@
 
 		}
 
-		if (m.get_error_domains ().size > 0) {
+		if (m.get_error_types ().size > 0) {
 			var cparam = new CCodeFormalParameter ("error", "GError**");
 			cparam_map.set (get_param_pos (-1), cparam);
 		}
@@ -3574,7 +3573,7 @@
 			i++;
 		}
 
-		if (m.get_error_domains ().size > 0) {
+		if (m.get_error_types ().size > 0) {
 			carg_map.set (get_param_pos (-1), new CCodeIdentifier ("error"));
 		}
 

Modified: trunk/gobject/valaccodeinvocationexpressionbinding.vala
==============================================================================
--- trunk/gobject/valaccodeinvocationexpressionbinding.vala	(original)
+++ trunk/gobject/valaccodeinvocationexpressionbinding.vala	Sun May 25 09:09:39 2008
@@ -345,7 +345,7 @@
 			}
 		}
 
-		if (expr.can_fail) {
+		if (expr.tree_can_fail) {
 			// method can fail
 			codegen.current_method_inner_error = true;
 			// add &inner_error before the ellipsis arguments

Modified: trunk/gobject/valaccodemethodbinding.vala
==============================================================================
--- trunk/gobject/valaccodemethodbinding.vala	(original)
+++ trunk/gobject/valaccodemethodbinding.vala	Sun May 25 09:09:39 2008
@@ -452,7 +452,7 @@
 				}
 			}
 
-			if (m.get_error_domains ().size > 0) {
+			if (m.get_error_types ().size > 0) {
 				var cparam = new CCodeFormalParameter ("error", "GError**");
 				cparam_map.set (codegen.get_param_pos (-1), cparam);
 				carg_map.set (codegen.get_param_pos (-1), new CCodeIdentifier (cparam.name));
@@ -635,7 +635,7 @@
 			}
 		}
 
-		if (m.get_error_domains ().size > 0) {
+		if (m.get_error_types ().size > 0) {
 			var cparam = new CCodeFormalParameter ("error", "GError**");
 			cparam_map.set (codegen.get_param_pos (-1), cparam);
 		}

Modified: trunk/vala/valacodenode.vala
==============================================================================
--- trunk/vala/valacodenode.vala	(original)
+++ trunk/vala/valacodenode.vala	Sun May 25 09:09:39 2008
@@ -21,6 +21,7 @@
  */
 
 using GLib;
+using Gee;
 
 /**
  * Represents a part of the parsed source code.
@@ -43,7 +44,7 @@
 	/**
 	 * Contains all attributes that have been specified for this code node.
 	 */
-	public List<Attribute> attributes;
+	public GLib.List<Attribute> attributes;
 	
 	/**
 	 * Generated CCodeNode that corresponds to this code node.
@@ -71,7 +72,38 @@
 	/**
 	 * Specifies that this node or a child node may throw an exception.
 	 */
-	public bool tree_can_fail { get; set; }
+	public bool tree_can_fail { 
+		get { return _error_types.size > 0; }
+	}
+
+	/**
+	 * Specifies the exceptions that can be thrown by this node or a child node
+	 */
+	public Gee.List<DataType> get_error_types () { 
+		return _error_types;
+	}
+
+	private Gee.List<DataType> _error_types = new ArrayList<DataType> ();
+
+	/**
+	 * Adds an error type to the exceptions that can be thrown by this node
+	 * or a child node 
+	 */
+	public void add_error_type (DataType error_type) {
+		_error_types.add (error_type);
+		error_type.parent_node = this;
+	}
+
+	/**
+	 * Adds a collection of error types to the exceptions that can be thrown by this node
+	 * or a child node 
+	 */
+	public void add_error_types (Gee.Collection<DataType> error_types) {
+		foreach (DataType error_type in error_types) {
+			_error_types.add (error_type);
+			error_type.parent_node = this;
+		}
+	}
 
 	/**
 	 * Visits this code node with the specified CodeVisitor.

Modified: trunk/vala/valacreationmethod.vala
==============================================================================
--- trunk/vala/valacreationmethod.vala	(original)
+++ trunk/vala/valacreationmethod.vala	Sun May 25 09:09:39 2008
@@ -60,8 +60,8 @@
 			param.accept (visitor);
 		}
 
-		foreach (DataType error_domain in get_error_domains ()) {
-			error_domain.accept (visitor);
+		foreach (DataType error_type in get_error_types ()) {
+			error_type.accept (visitor);
 		}
 
 		if (body != null) {

Modified: trunk/vala/valaexpression.vala
==============================================================================
--- trunk/vala/valaexpression.vala	(original)
+++ trunk/vala/valaexpression.vala	Sun May 25 09:09:39 2008
@@ -68,11 +68,6 @@
 	public bool ref_sink { get; set; }
 
 	/**
-	 * Specifies that this expression may throw an exception.
-	 */
-	public bool can_fail { get; set; }
-
-	/**
 	 * Specifies that this expression is used as lvalue, i.e. the
 	 * left hand side of an assignment.
 	 */

Modified: trunk/vala/valagenieparser.vala
==============================================================================
--- trunk/vala/valagenieparser.vala	(original)
+++ trunk/vala/valagenieparser.vala	Sun May 25 09:09:39 2008
@@ -2385,7 +2385,7 @@
 
 		if (accept (TokenType.RAISES)) {
 			do {
-				method.add_error_domain (parse_type ());
+				method.add_error_type (parse_type ());
 			} while (accept (TokenType.COMMA));
 		}
 
@@ -3031,7 +3031,7 @@
 		expect (TokenType.CLOSE_PARENS);
 		if (accept (TokenType.RAISES)) {
 			do {
-				method.add_error_domain (parse_type ());
+				method.add_error_type (parse_type ());
 			} while (accept (TokenType.COMMA));
 		}
 		method.access = SymbolAccessibility.PUBLIC;

Modified: trunk/vala/valainterfacewriter.vala
==============================================================================
--- trunk/vala/valainterfacewriter.vala	(original)
+++ trunk/vala/valainterfacewriter.vala	Sun May 25 09:09:39 2008
@@ -709,7 +709,7 @@
 		}
 		
 		write_params (m.get_parameters ());
-		write_error_domains (m.get_error_domains ());
+		write_error_domains (m.get_error_types ());
 
 		write_string (";");
 

Modified: trunk/vala/valamethod.vala
==============================================================================
--- trunk/vala/valamethod.vala	(original)
+++ trunk/vala/valamethod.vala	Sun May 25 09:09:39 2008
@@ -189,7 +189,6 @@
 	private string _vfunc_name;
 	private string _sentinel;
 	private bool _no_array_length;
-	private Gee.List<DataType> error_domains = new ArrayList<DataType> ();
 	private Gee.List<Expression> preconditions = new ArrayList<Expression> ();
 	private Gee.List<Expression> postconditions = new ArrayList<Expression> ();
 	private DataType _return_type;
@@ -263,8 +262,8 @@
 			param.accept (visitor);
 		}
 
-		foreach (DataType error_domain in error_domains) {
-			error_domain.accept (visitor);
+		foreach (DataType error_type in get_error_types ()) {
+			error_type.accept (visitor);
 		}
 
 		if (result_var != null) {
@@ -419,17 +418,17 @@
 		}
 
 		/* this method may throw more but not less errors than the base method */
-		foreach (DataType method_error_domain in error_domains) {
+		foreach (DataType method_error_type in get_error_types ()) {
 			bool match = false;
-			foreach (DataType base_method_error_domain in base_method.error_domains) {
-				if (method_error_domain.compatible (base_method_error_domain)) {
+			foreach (DataType base_method_error_type in base_method.get_error_types ()) {
+				if (method_error_type.compatible (base_method_error_type)) {
 					match = true;
 					break;
 				}
 			}
 
 			if (!match) {
-				invalid_match = "incompatible error domain `%s'".printf (method_error_domain.to_string ());
+				invalid_match = "incompatible error type `%s'".printf (method_error_type.to_string ());
 				return false;
 			}
 		}
@@ -438,25 +437,6 @@
 	}
 
 	/**
-	 * Adds an error domain to this method.
-	 *
-	 * @param error_domain an error domain
-	 */
-	public void add_error_domain (DataType error_domain) {
-		error_domains.add (error_domain);
-		error_domain.parent_node = this;
-	}
-
-	/**
-	 * Returns a copy of the list of error domains of this method.
-	 *
-	 * @return list of error domains
-	 */
-	public Collection<DataType> get_error_domains () {
-		return new ReadOnlyCollection<DataType> (error_domains);
-	}
-
-	/**
 	 * Adds a precondition to this method.
 	 *
 	 * @param precondition a boolean precondition expression
@@ -499,9 +479,10 @@
 			return_type = new_type;
 			return;
 		}
-		for (int i = 0; i < error_domains.size; i++) {
-			if (error_domains[i] == old_type) {
-				error_domains[i] = new_type;
+		var error_types = get_error_types ();
+		for (int i = 0; i < error_types.size; i++) {
+			if (error_types[i] == old_type) {
+				error_types[i] = new_type;
 				return;
 			}
 		}

Modified: trunk/vala/valanamespace.vala
==============================================================================
--- trunk/vala/valanamespace.vala	(original)
+++ trunk/vala/valanamespace.vala	Sun May 25 09:09:39 2008
@@ -87,7 +87,7 @@
 			foreach (Enum en in ns.get_enums ()) {
 				old_ns.add_enum (en);
 			}
-			foreach (ErrorDomain ed in ns.get_error_domains ()) {
+			foreach (ErrorDomain ed in ns.get_error_types ()) {
 				old_ns.add_error_domain (ed);
 			}
 			foreach (Constant c in ns.get_constants ()) {
@@ -237,7 +237,7 @@
 	 *
 	 * @return error domain list
 	 */
-	public Collection<ErrorDomain> get_error_domains () {
+	public Collection<ErrorDomain> get_error_types () {
 		return new ReadOnlyCollection<ErrorDomain> (error_domains);
 	}
 	

Modified: trunk/vala/valaparser.vala
==============================================================================
--- trunk/vala/valaparser.vala	(original)
+++ trunk/vala/valaparser.vala	Sun May 25 09:09:39 2008
@@ -2080,7 +2080,7 @@
 		expect (TokenType.CLOSE_PARENS);
 		if (accept (TokenType.THROWS)) {
 			do {
-				method.add_error_domain (parse_type ());
+				method.add_error_type (parse_type ());
 			} while (accept (TokenType.COMMA));
 		}
 		while (accept (TokenType.REQUIRES)) {
@@ -2616,7 +2616,7 @@
 		expect (TokenType.CLOSE_PARENS);
 		if (accept (TokenType.THROWS)) {
 			do {
-				method.add_error_domain (parse_type ());
+				method.add_error_type (parse_type ());
 			} while (accept (TokenType.COMMA));
 		}
 		method.access = access;

Modified: trunk/vala/valasemanticanalyzer.vala
==============================================================================
--- trunk/vala/valasemanticanalyzer.vala	(original)
+++ trunk/vala/valasemanticanalyzer.vala	Sun May 25 09:09:39 2008
@@ -469,6 +469,21 @@
 				return;
 			}
 		}
+
+		// check that all errors that can be thrown in the method body are declared
+		if (m.body != null) { 
+			foreach (DataType body_error_type in m.body.get_error_types ()) {
+				bool can_propagate_error = false;
+				foreach (DataType method_error_type in m.get_error_types ()) {
+					if (body_error_type.compatible (method_error_type)) {
+						can_propagate_error = true;
+					}
+				}
+				if (!can_propagate_error) {
+					Report.warning (body_error_type.source_reference, "unhandled error `%s'".printf (body_error_type.to_string()));
+				}
+			}
+		}
 	}
 
 	private void find_base_class_method (Method m, Class cl) {
@@ -788,9 +803,26 @@
 			local.active = false;
 		}
 
+		foreach (Statement stmt in b.get_statements()) {
+			b.add_error_types (stmt.get_error_types ());
+		}
+
 		current_symbol = current_symbol.parent_symbol;
 	}
 
+	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);
+			}
+		}
+	}
+
 	public override void visit_local_variable (LocalVariable local) {
 		if (local.initializer != null) {
 			local.initializer.expected_type = local.variable_type;
@@ -949,7 +981,7 @@
 			return;
 		}
 
-		stmt.tree_can_fail = stmt.expression.tree_can_fail;
+		stmt.add_error_types (stmt.expression.get_error_types ());
 	}
 
 	public override void visit_if_statement (IfStatement stmt) {
@@ -966,6 +998,13 @@
 			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 ());
+		}
 	}
 
 	public override void visit_switch_section (SwitchSection section) {
@@ -1001,6 +1040,9 @@
 			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 ());
 	}
 
 	public override void visit_do_statement (DoStatement stmt) {
@@ -1017,6 +1059,9 @@
 			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 ());
 	}
 
 	public override void visit_for_statement (ForStatement stmt) {
@@ -1033,6 +1078,18 @@
 			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 ());
+		}
 	}
 
 	public override void visit_foreach_statement (ForeachStatement stmt) {
@@ -1118,7 +1175,8 @@
 			}
 		}
 
-		stmt.tree_can_fail = stmt.collection.tree_can_fail || stmt.body.tree_can_fail;
+		stmt.add_error_types (stmt.collection.get_error_types ());
+		stmt.add_error_types (stmt.body.get_error_types ());
 	}
 
 	public override void visit_return_statement (ReturnStatement stmt) {
@@ -1172,6 +1230,10 @@
 		    && !current_return_type.nullable) {
 			Report.warning (stmt.source_reference, "`null' incompatible with return type `%s`".printf (current_return_type.to_string ()));
 		}
+
+		if (stmt.return_expression != null) {
+			stmt.add_error_types (stmt.return_expression.get_error_types ());
+		}
 	}
 
 	public override void visit_throw_statement (ThrowStatement stmt) {
@@ -1603,7 +1665,7 @@
 						}
 						var m = new DynamicMethod (expr.inner.value_type, expr.member_name, ret_type, expr.source_reference);
 						m.invocation = invoc;
-						m.add_error_domain (new ErrorType (null));
+						m.add_error_type (new ErrorType (null));
 						m.access = SymbolAccessibility.PUBLIC;
 						m.add_parameter (new FormalParameter.with_ellipsis ());
 						context.add_dynamic_member (m);
@@ -1863,7 +1925,13 @@
 
 		if (mtype is MethodType) {
 			var m = ((MethodType) mtype).method_symbol;
-			expr.tree_can_fail = expr.can_fail = (m.get_error_domains ().size > 0);
+			foreach (DataType error_type in m.get_error_types ()) {
+				// ensure we can trace back which expression may throw errors of this type
+				var call_error_type = error_type.copy ();
+				call_error_type.source_reference = expr.source_reference;
+
+				expr.add_error_type (call_error_type);
+			}
 		}
 
 		expr.value_type = ret_type;
@@ -2445,7 +2513,13 @@
 
 			check_arguments (expr, new MethodType (m), m.get_parameters (), args);
 
-			expr.tree_can_fail = expr.can_fail = (m.get_error_domains ().size > 0);
+			foreach (DataType error_type in m.get_error_types ()) {
+				// ensure we can trace back which expression may throw errors of this type
+				var call_error_type = error_type.copy ();
+				call_error_type.source_reference = expr.source_reference;
+
+				expr.add_error_type (call_error_type);
+			}
 		} else if (expr.type_reference is ErrorType) {
 			expr.accept_children (this);
 
@@ -3236,6 +3310,7 @@
 			a.value_type = null;
 		}
 
-		a.tree_can_fail = a.left.tree_can_fail || a.right.tree_can_fail;
+		a.add_error_types (a.left.get_error_types ());
+		a.add_error_types (a.right.get_error_types ());
 	}
 }

Modified: trunk/vala/valasourcefile.vala
==============================================================================
--- trunk/vala/valasourcefile.vala	(original)
+++ trunk/vala/valasourcefile.vala	Sun May 25 09:09:39 2008
@@ -406,7 +406,12 @@
 
 	public char* get_mapped_contents () {
 		if (mapped_file == null) {
-			mapped_file = new MappedFile (filename, false);
+			try {
+				mapped_file = new MappedFile (filename, false);
+			} catch (FileError e) {
+				Report.error (null, "Unable to map file `%s': %s".printf (filename, e.message));
+				return null;
+			}
 		}
 
 		return mapped_file.get_contents ();

Modified: trunk/vapigen/valagidlparser.vala
==============================================================================
--- trunk/vapigen/valagidlparser.vala	(original)
+++ trunk/vapigen/valagidlparser.vala	Sun May 25 09:09:39 2008
@@ -1334,7 +1334,7 @@
 			}
 
 			if (suppress_throws == false && param_is_exception (param)) {
-				m.add_error_domain (parse_type (param.type));
+				m.add_error_type (parse_type (param.type));
 				continue;
 			}
 

Modified: trunk/vapigen/valavapigen.vala
==============================================================================
--- trunk/vapigen/valavapigen.vala	(original)
+++ trunk/vapigen/valavapigen.vala	Sun May 25 09:09:39 2008
@@ -80,11 +80,14 @@
 	}
 	
 	private static string[]? get_packages_from_depsfile (string depsfile) {
-		string contents;
-		if (FileUtils.get_contents (depsfile, out contents)) {
+		try {
+			string contents;
+			FileUtils.get_contents (depsfile, out contents);
 			return contents.strip ().split ("\n");
+		} catch (FileError e) {
+			// deps files are optional
+			return null;
 		}
-		return null;
 	}
 
 	private int run () {



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