Commit 5df444cb authored by Jürg Billeter's avatar Jürg Billeter Committed by Jürg Billeter
Browse files

add support for iteration over Gee.Iterable collections

2007-07-24  Juerg Billeter  <j@bitron.ch>

	* vala/valasemanticanalyzer.vala, gobject/valacodegenerator.vala:
	  add support for iteration over Gee.Iterable collections

svn path=/trunk/; revision=383
parent 760d8a87
2007-07-24 Jürg Billeter <j@bitron.ch>
* vala/valasemanticanalyzer.vala, gobject/valacodegenerator.vala:
add support for iteration over Gee.Iterable collections
2007-07-24 Jürg Billeter <j@bitron.ch>
* vala/valamemorymanager.vala: skip memory manager for VAPI files
......
......@@ -99,6 +99,8 @@ public class Vala.CodeGenerator : CodeVisitor {
DataType slist_type;
TypeReference mutex_type;
DataType type_module_type;
DataType iterable_type;
DataType iterator_type;
Method substring_method;
......@@ -252,6 +254,12 @@ public class Vala.CodeGenerator : CodeVisitor {
}
}
}
var gee_ns = root_symbol.scope.lookup ("Gee");
if (gee_ns != null) {
iterable_type = (DataType) gee_ns.scope.lookup ("Iterable");
iterator_type = (DataType) gee_ns.scope.lookup ("Iterator");
}
/* we're only interested in non-pkg source files */
var source_files = context.get_source_files ();
......@@ -1381,6 +1389,53 @@ public class Vala.CodeGenerator : CodeVisitor {
cfor.add_iterator (new CCodeAssignment (new CCodeIdentifier (it_name), new CCodeMemberAccess.pointer (new CCodeIdentifier (it_name), "next")));
cblock.add_statement (cfor);
} else if (stmt.collection.static_type.data_type == iterable_type ||
stmt.collection.static_type.data_type.is_subtype_of (iterable_type)) {
var it_name = "%s_it".printf (stmt.variable_name);
var citdecl = new CCodeDeclaration (iterator_type.get_cname () + "*");
var it_method = (Method) iterable_type.scope.lookup ("iterator");
var it_ccall = new CCodeFunctionCall (new CCodeIdentifier (it_method.get_cname ()));
it_ccall.add_argument (new InstanceCast (new CCodeIdentifier (collection_backup.name), iterable_type));
citdecl.add_declarator (new CCodeVariableDeclarator.with_initializer (it_name, it_ccall));
cblock.add_statement (citdecl);
var cbody = new CCodeBlock ();
var get_method = (Method) iterator_type.scope.lookup ("get");
var get_ccall = new CCodeFunctionCall (new CCodeIdentifier (get_method.get_cname ()));
get_ccall.add_argument (new CCodeIdentifier (it_name));
CCodeExpression element_expr = get_ccall;
/* cast pointer to actual type if appropriate */
if (stmt.type_reference.data_type is Struct) {
var st = (Struct) stmt.type_reference.data_type;
if (st == uint_type.data_type) {
var cconv = new CCodeFunctionCall (new CCodeIdentifier ("GPOINTER_TO_UINT"));
cconv.add_argument (element_expr);
element_expr = cconv;
} else if (st == bool_type.data_type || st.is_integer_type ()) {
var cconv = new CCodeFunctionCall (new CCodeIdentifier ("GPOINTER_TO_INT"));
cconv.add_argument (element_expr);
element_expr = cconv;
}
}
var cdecl = new CCodeDeclaration (stmt.type_reference.get_cname ());
cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer (stmt.variable_name, element_expr));
cbody.add_statement (cdecl);
cbody.add_statement (stmt.body.ccodenode);
var next_method = (Method) iterator_type.scope.lookup ("next");
var next_ccall = new CCodeFunctionCall (new CCodeIdentifier (next_method.get_cname ()));
next_ccall.add_argument (new CCodeIdentifier (it_name));
cblock.add_statement (new CCodeWhileStatement (next_ccall, cbody));
var it_unref_ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_object_unref"));
it_unref_ccall.add_argument (new CCodeIdentifier (it_name));
cblock.add_statement (new CCodeExpressionStatement (it_unref_ccall));
}
if (memory_management && stmt.collection.static_type.transfers_ownership) {
......
......@@ -54,6 +54,7 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
DataType glist_type;
DataType gslist_type;
DataType gerror_type;
DataType iterable_type;
private int next_lambda_id = 0;
......@@ -104,6 +105,11 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
gerror_type = (DataType) glib_ns.scope.lookup ("Error");
}
var gee_ns = root_symbol.scope.lookup ("Gee");
if (gee_ns != null) {
iterable_type = (DataType) gee_ns.scope.lookup ("Iterable");
}
current_symbol = root_symbol;
context.accept (this);
}
......@@ -855,7 +861,7 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
public override void visit_end_foreach_statement (ForeachStatement! stmt) {
var collection_type = stmt.collection.static_type.data_type;
if (!(collection_type is Array || collection_type == glist_type || collection_type == gslist_type)) {
if (!(collection_type is Array || collection_type == glist_type || collection_type == gslist_type || collection_type == iterable_type || collection_type.is_subtype_of (iterable_type))) {
stmt.error = true;
Report.error (stmt.source_reference, "Collection not iterable");
return;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment