vala r874 - in trunk: . gobject vala vapigen



Author: juergbi
Date: Mon Jan 21 17:09:24 2008
New Revision: 874
URL: http://svn.gnome.org/viewvc/vala?rev=874&view=rev

Log:
2008-01-21  Juerg Billeter  <j bitron ch>

	* vala/valasemanticanalyzer.vala: improve generic type resolution, add
	  type checking for element type in foreach statement,
	  based on patch by Hans Vercammen, fixes bug 510852

	* gobject/valaccodegenerator.vala,
	  gobject/valaccodegeneratormethod.vala, vapigen/valagidlparser.vala:
	  fix foreach statements


Modified:
   trunk/ChangeLog
   trunk/gobject/valaccodegenerator.vala
   trunk/gobject/valaccodegeneratormethod.vala
   trunk/vala/valasemanticanalyzer.vala
   trunk/vapigen/valagidlparser.vala

Modified: trunk/gobject/valaccodegenerator.vala
==============================================================================
--- trunk/gobject/valaccodegenerator.vala	(original)
+++ trunk/gobject/valaccodegenerator.vala	Mon Jan 21 17:09:24 2008
@@ -787,11 +787,11 @@
 			}
 			
 			if (stmt.ccodenode is CCodeFragment) {
-				foreach (CCodeStatement cstmt in ((CCodeFragment) stmt.ccodenode).get_children ()) {
+				foreach (CCodeNode cstmt in ((CCodeFragment) stmt.ccodenode).get_children ()) {
 					cblock.add_statement (cstmt);
 				}
 			} else {
-				cblock.add_statement ((CCodeStatement) stmt.ccodenode);
+				cblock.add_statement (stmt.ccodenode);
 			}
 		}
 
@@ -1431,11 +1431,11 @@
 			var cblock = new CCodeBlock ();
 			foreach (CodeNode body_stmt in section.get_statements ()) {
 				if (body_stmt.ccodenode is CCodeFragment) {
-					foreach (CCodeStatement cstmt in ((CCodeFragment) body_stmt.ccodenode).get_children ()) {
+					foreach (CCodeNode cstmt in ((CCodeFragment) body_stmt.ccodenode).get_children ()) {
 						cblock.add_statement (cstmt);
 					}
 				} else {
-					cblock.add_statement ((CCodeStatement) body_stmt.ccodenode);
+					cblock.add_statement (body_stmt.ccodenode);
 				}
 			}
 
@@ -1555,6 +1555,10 @@
 
 				CCodeExpression element_expr = new CCodeIdentifier ("*%s".printf (it_name));
 
+				var element_data_type = new DataType ();
+				element_data_type.data_type = arr.element_type;
+				element_expr = get_implicit_cast_expression (element_expr, element_data_type, stmt.type_reference);
+
 				if (stmt.type_reference.takes_ownership) {
 					var ma = new MemberAccess.simple (stmt.variable_name);
 					ma.static_type = stmt.type_reference;
@@ -1597,6 +1601,10 @@
 
 				CCodeExpression element_expr = new CCodeElementAccess (new CCodeIdentifier (collection_backup.name), new CCodeIdentifier (it_name));
 
+				var element_data_type = new DataType ();
+				element_data_type.data_type = arr.element_type;
+				element_expr = get_implicit_cast_expression (element_expr, element_data_type, stmt.type_reference);
+
 				if (stmt.type_reference.takes_ownership) {
 					var ma = new MemberAccess.simple (stmt.variable_name);
 					ma.static_type = stmt.type_reference;
@@ -1655,6 +1663,15 @@
 
 			CCodeExpression element_expr = new CCodeMemberAccess.pointer (new CCodeIdentifier (it_name), "data");
 
+			if (collection_type.get_type_arguments ().size != 1) {
+				Report.error (stmt.source_reference, "internal error: missing generic type argument");
+				stmt.error = true;
+				return;
+			}
+
+			var element_data_type = collection_type.get_type_arguments ().get (0);
+			element_expr = get_implicit_cast_expression (element_expr, element_data_type, stmt.type_reference);
+
 			element_expr = convert_from_generic_pointer (element_expr, stmt.type_reference);
 
 			if (stmt.type_reference.takes_ownership) {
@@ -1710,6 +1727,8 @@
 			type_arg_it.next ();
 			var it_type = SemanticAnalyzer.get_actual_type (stmt.collection.static_type, it_method, type_arg_it.get (), stmt);
 
+			element_expr = get_implicit_cast_expression (element_expr, it_type, stmt.type_reference);
+
 			if (stmt.type_reference.takes_ownership && !it_type.takes_ownership) {
 				var ma = new MemberAccess.simple (stmt.variable_name);
 				ma.static_type = stmt.type_reference;
@@ -1767,7 +1786,7 @@
 
 		var local_vars = b.get_local_variables ();
 		foreach (VariableDeclarator decl in local_vars) {
-			if (decl.active && decl.type_reference.data_type.is_reference_type () && decl.type_reference.takes_ownership) {
+			if (decl.active && decl.type_reference.data_type != null && decl.type_reference.data_type.is_reference_type () && decl.type_reference.takes_ownership) {
 				var ma = new MemberAccess.simple (decl.name);
 				ma.symbol_reference = decl;
 				cfrag.append (new CCodeExpressionStatement (get_unref_expression (new CCodeIdentifier (get_variable_cname (decl.name)), decl.type_reference, ma)));

Modified: trunk/gobject/valaccodegeneratormethod.vala
==============================================================================
--- trunk/gobject/valaccodegeneratormethod.vala	(original)
+++ trunk/gobject/valaccodegeneratormethod.vala	Mon Jan 21 17:09:24 2008
@@ -68,11 +68,11 @@
 				foreach (CodeNode stmt in m.body.get_statements ()) {
 					if (((ExpressionStatement) stmt).assigned_property ().set_accessor.construction) {
 						if (stmt.ccodenode is CCodeFragment) {
-							foreach (CCodeStatement cstmt in ((CCodeFragment) stmt.ccodenode).get_children ()) {
+							foreach (CCodeNode cstmt in ((CCodeFragment) stmt.ccodenode).get_children ()) {
 								cblock.add_statement (cstmt);
 							}
 						} else {
-							cblock.add_statement ((CCodeStatement) stmt.ccodenode);
+							cblock.add_statement (stmt.ccodenode);
 						}
 					}
 				}
@@ -82,11 +82,11 @@
 				foreach (CodeNode stmt in m.body.get_statements ()) {
 					if (!((ExpressionStatement) stmt).assigned_property ().set_accessor.construction) {
 						if (stmt.ccodenode is CCodeFragment) {
-							foreach (CCodeStatement cstmt in ((CCodeFragment) stmt.ccodenode).get_children ()) {
+							foreach (CCodeNode cstmt in ((CCodeFragment) stmt.ccodenode).get_children ()) {
 								cblock.add_statement (cstmt);
 							}
 						} else {
-							cblock.add_statement ((CCodeStatement) stmt.ccodenode);
+							cblock.add_statement (stmt.ccodenode);
 						}
 					}
 				}

Modified: trunk/vala/valasemanticanalyzer.vala
==============================================================================
--- trunk/vala/valasemanticanalyzer.vala	(original)
+++ trunk/vala/valasemanticanalyzer.vala	Mon Jan 21 17:09:24 2008
@@ -937,9 +937,21 @@
 
 		stmt.add_local_variable (stmt.collection_variable_declarator);
 		stmt.collection_variable_declarator.active = true;
-
+	
 		var collection_type = stmt.collection.static_type;
-		if (iterable_type != null && collection_type.compatible (iterable_type)) {
+		var element_data_type = new DataType ();
+		bool need_type_check = false;
+	
+		if (collection_type.is_array ()) {
+			var arr = (Array) collection_type.data_type;
+			element_data_type.data_type = arr.element_type;
+			need_type_check = true;
+		} else if (collection_type.compatible (glist_type) || collection_type.compatible (gslist_type)) {		
+			if (collection_type.get_type_arguments ().size > 0) {
+				element_data_type = (DataType) collection_type.get_type_arguments ().get (0);
+				need_type_check = true;
+			}
+		} else if (iterable_type != null && collection_type.compatible (iterable_type)) {
 			stmt.iterator_variable_declarator = new VariableDeclarator ("%s_it".printf (stmt.variable_name));
 			stmt.iterator_variable_declarator.type_reference = new InterfaceType (iterator_type);
 			stmt.iterator_variable_declarator.type_reference.takes_ownership = true;
@@ -947,12 +959,32 @@
 
 			stmt.add_local_variable (stmt.iterator_variable_declarator);
 			stmt.iterator_variable_declarator.active = true;
-		} else if (!(collection_type.is_array () || collection_type.compatible (glist_type) || collection_type.compatible (gslist_type))) {
+
+			var it_method = (Method) iterable_type.data_type.scope.lookup ("iterator");
+			if (it_method.return_type.get_type_arguments ().size > 0) {
+				var type_arg = it_method.return_type.get_type_arguments ().get (0);
+				if (type_arg.type_parameter != null) {
+					element_data_type = SemanticAnalyzer.get_actual_type (collection_type, it_method, type_arg, stmt);
+				} else {
+					element_data_type = type_arg;
+				}
+				need_type_check = true;
+			}
+		} else {
 			stmt.error = true;
 			Report.error (stmt.source_reference, "Collection not iterable");
 			return;
 		}
 
+		if (need_type_check && element_data_type != null) {
+			/* allow implicit upcasts ? */
+			if (!element_data_type.compatible (stmt.type_reference)) {
+				stmt.error = true;
+				Report.error (stmt.source_reference, "Foreach: Cannot convert from `%s' to `%s'".printf (element_data_type.to_string (), stmt.type_reference.to_string ()));
+				return;
+			}
+		}
+
 		stmt.tree_can_fail = stmt.collection.tree_can_fail || stmt.body.tree_can_fail;
 	}
 
@@ -1514,25 +1546,28 @@
 		}
 
 		// resolve generic return values
+		var ma = expr.call as MemberAccess;
 		if (ret_type.type_parameter != null) {
-			if (!(expr.call is MemberAccess)) {
-				Report.error (expr.source_reference, "internal error: unsupported generic return value");
-				expr.error = true;
-				return;
-			}
-			var ma = (MemberAccess) expr.call;
-			if (ma.inner == null) {
-				// TODO resolve generic return values within the type hierarchy if possible
-				Report.error (expr.source_reference, "internal error: resolving generic return values within type hierarchy not supported yet");
-				expr.error = true;
-				return;
-			} else {
+			if (ma != null && ma.inner != null) {
 				ret_type = get_actual_type (ma.inner.static_type, ma.symbol_reference, ret_type, expr);
 				if (ret_type == null) {
 					return;
 				}
 			}
 		}
+		Gee.List<DataType> resolved_type_args = new ArrayList<DataType> ();
+		foreach (DataType type_arg in ret_type.get_type_arguments ()) {
+			if (type_arg.type_parameter != null && ma != null && ma.inner != null) {
+				resolved_type_args.add (get_actual_type (ma.inner.static_type, ma.symbol_reference, type_arg, expr));
+			} else {
+				resolved_type_args.add (type_arg);
+			}
+		}
+		ret_type = ret_type.copy ();
+		ret_type.remove_all_type_arguments ();
+		foreach (DataType resolved_type_arg in resolved_type_args) {
+			ret_type.add_type_argument (resolved_type_arg);
+		}
 
 		if (mtype is MethodType) {
 			var m = ((MethodType) mtype).method_symbol;

Modified: trunk/vapigen/valagidlparser.vala
==============================================================================
--- trunk/vapigen/valagidlparser.vala	(original)
+++ trunk/vapigen/valagidlparser.vala	Mon Jan 21 17:09:24 2008
@@ -37,7 +37,7 @@
 	private Namespace current_namespace;
 	private Typesymbol current_data_type;
 	private Map<string,string> codenode_attributes_map;
-	private Map<pointer,string> codenode_attributes_patterns;
+	private Map<PatternSpec*,string> codenode_attributes_patterns;
 	private Gee.Set<string> current_type_symbol_set;
 
 	private Map<string,Typesymbol> cname_type_map;
@@ -1421,7 +1421,7 @@
 			var colon_required = (null != codenode.chr (-1, ':'));
 
 			var pattern_specs = codenode_attributes_patterns.get_keys ();
-			foreach (weak PatternSpec pattern in pattern_specs) {
+			foreach (PatternSpec* pattern in pattern_specs) {
 				var pspec = codenode_attributes_patterns[pattern];
 
 				if ((dot_required && null == pspec.chr (-1, '.')) ||
@@ -1429,7 +1429,7 @@
 					continue;
 				}
 
-				if (pattern.match_string (codenode)) {
+				if (pattern->match_string (codenode)) {
 					return get_attributes (pspec);
 				}
 			}



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