[Date Prev][Date Next] [Thread Prev][Thread Next]
[Thread Index]
[Date Index]
[Author Index]
[Vala] Improved foreach
- From: Jamie McCracken <jamie mccrack googlemail com>
- To: vala <vala paldo org>
- Subject: [Vala] Improved foreach
- Date: Sun, 25 May 2008 00:51:19 -0400
patch allows:
Var to be used in foreach
or
Existing local variable (in scope)
This patch is needed for genie although it may be useful for vala too...
jamie
Index: vala/valasemanticanalyzer.vala
===================================================================
--- vala/valasemanticanalyzer.vala (revision 1419)
+++ vala/valasemanticanalyzer.vala (working copy)
@@ -1016,7 +1016,7 @@
stmt.error = true;
Report.error (stmt.condition.source_reference, "Condition must be boolean");
return;
- }
+ }
}
public override void visit_for_statement (ForStatement stmt) {
@@ -1035,21 +1035,31 @@
}
}
- public override void visit_foreach_statement (ForeachStatement stmt) {
- current_source_file.add_type_dependency (stmt.type_reference, SourceFileDependencyType.SOURCE);
- stmt.element_variable = new LocalVariable (stmt.type_reference, stmt.variable_name);
+ LocalVariable? get_local_variable_in_scope (string variable_name) {
+ Symbol symbol_reference = null;
+ var sym = current_symbol;
+ LocalVariable result = null;
+
+
+ while (sym != null && symbol_reference == null && !(symbol_reference is LocalVariable)) {
+ symbol_reference = symbol_lookup_inherited (sym, variable_name);
+ sym = sym.parent_symbol;
+ }
+
+ result = (LocalVariable) symbol_reference;
+
+ return result;
+ }
- stmt.body.scope.add (stmt.variable_name, stmt.element_variable);
+ public override void visit_foreach_statement (ForeachStatement stmt) {
- stmt.body.add_local_variable (stmt.element_variable);
- stmt.element_variable.active = true;
-
stmt.owner = current_symbol.scope;
current_symbol = stmt;
- stmt.accept_children (this);
-
+ /* handle collection first in case we need to infer the data type of the type reference */
+ stmt.accept_collection (this);
+
foreach (LocalVariable local in stmt.get_local_variables ()) {
local.active = false;
}
@@ -1067,11 +1077,7 @@
}
var collection_type = stmt.collection.value_type.copy ();
- stmt.collection_variable = new LocalVariable (collection_type, "%s_collection".printf (stmt.variable_name));
-
- stmt.add_local_variable (stmt.collection_variable);
- stmt.collection_variable.active = true;
-
+
DataType element_data_type = null;
bool need_type_check = false;
@@ -1108,7 +1114,42 @@
Report.error (stmt.source_reference, "Collection not iterable");
return;
}
+
+
+ /* can be null if inference or existing local variable in scope is availble */
+ if (stmt.type_reference == null) {
+
+ var sym = get_local_variable_in_scope (stmt.variable_name);
+ /* means no existing variable with that name found so create a new local var */
+ if (sym == null) {
+ stmt.type_reference = element_data_type.copy ();
+ current_source_file.add_type_dependency (stmt.type_reference, SourceFileDependencyType.SOURCE);
+ stmt.element_variable = new LocalVariable (stmt.type_reference, stmt.variable_name);
+ stmt.body.scope.add (stmt.variable_name, stmt.element_variable);
+ stmt.body.add_local_variable (stmt.element_variable);
+ stmt.element_variable.active = true;
+ } else {
+ stmt.element_variable = sym;
+ stmt.type_reference = sym.variable_type;
+ need_type_check = true;
+ }
+
+ } else {
+ current_source_file.add_type_dependency (stmt.type_reference, SourceFileDependencyType.SOURCE);
+ stmt.element_variable = new LocalVariable (stmt.type_reference, stmt.variable_name);
+ stmt.body.scope.add (stmt.variable_name, stmt.element_variable);
+ stmt.body.add_local_variable (stmt.element_variable);
+ stmt.element_variable.active = true;
+ }
+
+ stmt.accept_children (this);
+
+ stmt.collection_variable = new LocalVariable (collection_type, "%s_collection".printf (stmt.variable_name));
+
+ stmt.add_local_variable (stmt.collection_variable);
+ stmt.collection_variable.active = true;
+
if (need_type_check && element_data_type != null) {
/* allow implicit upcasts ? */
if (!element_data_type.compatible (stmt.type_reference)) {
@@ -1486,11 +1527,10 @@
// don't call g_object_ref_sink on inner and outer expression
expr.value_type.floating_reference = false;
}
-
+
public override void visit_member_access (MemberAccess expr) {
Symbol base_symbol = null;
bool may_access_instance_members = false;
-
expr.symbol_reference = null;
if (expr.inner == null) {
Index: vala/valaforeachstatement.vala
===================================================================
--- vala/valaforeachstatement.vala (revision 1419)
+++ vala/valaforeachstatement.vala (working copy)
@@ -30,11 +30,13 @@
/**
* Specifies the element type.
*/
- public DataType type_reference {
+ public DataType? type_reference {
get { return _data_type; }
set {
_data_type = value;
- _data_type.parent_node = this;
+ if (_data_type != null) {
+ _data_type.parent_node = this;
+ }
}
}
@@ -98,7 +100,7 @@
* @param source reference to source code
* @return newly created foreach statement
*/
- public ForeachStatement (DataType type_reference, string variable_name, Expression collection, Block body, SourceReference source_reference) {
+ public ForeachStatement (DataType? type_reference, string variable_name, Expression collection, Block body, SourceReference source_reference) {
this.variable_name = variable_name;
this.collection = collection;
this.body = body;
@@ -111,13 +113,22 @@
}
public override void accept_children (CodeVisitor visitor) {
- type_reference.accept (visitor);
-
- collection.accept (visitor);
- visitor.visit_end_full_expression (collection);
-
+
+ if (type_reference == null) {
+ collection.accept (visitor);
+ } else {
+
+ type_reference.accept (visitor);
+ collection.accept (visitor);
+ visitor.visit_end_full_expression (collection);
+ }
body.accept (visitor);
+
}
+
+ public void accept_collection (CodeVisitor visitor) {
+ collection.accept (visitor);
+ }
public override void replace_expression (Expression old_node, Expression new_node) {
if (collection == old_node) {
[Date Prev][Date Next] [Thread Prev][Thread Next]
[Thread Index]
[Date Index]
[Author Index]