]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
Move foreach statement checking to ForeachStatement.check
authorJürg Billeter <j@bitron.ch>
Fri, 7 Nov 2008 09:19:18 +0000 (09:19 +0000)
committerJürg Billeter <juergbi@src.gnome.org>
Fri, 7 Nov 2008 09:19:18 +0000 (09:19 +0000)
2008-11-07  Jürg Billeter  <j@bitron.ch>

* vala/valaforeachstatement.vala:
* vala/valasemanticanalyzer.vala:

Move foreach statement checking to ForeachStatement.check

svn path=/trunk/; revision=1995

ChangeLog
vala/valaforeachstatement.vala
vala/valasemanticanalyzer.vala

index ef673339bbedeaa7537970f52e9ea91f5ff020cb..4d0319c04511ce4453f7dd6afbc62d48657c0f4e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2008-11-07  Jürg Billeter  <j@bitron.ch>
+
+       * vala/valaforeachstatement.vala:
+       * vala/valasemanticanalyzer.vala:
+
+       Move foreach statement checking to ForeachStatement.check
+
 2008-11-07  Jürg Billeter  <j@bitron.ch>
 
        * vala/valaelementaccess.vala:
index 5133a286b9e84a15e1575d9a09a5ebbb7d53de9b..2e53d5c7a8213742172fc16d53318d326f320e90 100644 (file)
@@ -134,4 +134,119 @@ public class Vala.ForeachStatement : Block {
                        type_reference = new_type;
                }
        }
+
+       public override bool check (SemanticAnalyzer analyzer) {
+               if (checked) {
+                       return !error;
+               }
+
+               checked = true;
+
+               // analyze collection expression first, used for type inference
+               collection.accept (analyzer);
+
+               if (collection.error) {
+                       // ignore inner error
+                       error = true;
+                       return false;
+               } else if (collection.value_type == null) {
+                       Report.error (collection.source_reference, "invalid collection expression");
+                       error = true;
+                       return false;
+               }
+
+               var collection_type = collection.value_type.copy ();
+               collection.target_type = collection_type.copy ();
+               
+               DataType element_data_type = null;
+               bool element_owned = false;
+
+               if (collection_type.is_array ()) {
+                       var array_type = (ArrayType) collection_type;
+                       element_data_type = array_type.element_type;
+               } else if (collection_type.compatible (analyzer.glist_type) || collection_type.compatible (analyzer.gslist_type)) {
+                       if (collection_type.get_type_arguments ().size > 0) {
+                               element_data_type = (DataType) collection_type.get_type_arguments ().get (0);
+                       }
+               } else if (analyzer.iterable_type != null && collection_type.compatible (analyzer.iterable_type)) {
+                       element_owned = true;
+
+                       if (analyzer.list_type == null || !collection_type.compatible (new ObjectType (analyzer.list_type))) {
+                               // don't use iterator objects for lists for performance reasons
+                               var foreach_iterator_type = new ObjectType (analyzer.iterator_type);
+                               foreach_iterator_type.value_owned = true;
+                               foreach_iterator_type.add_type_argument (type_reference);
+                               iterator_variable = new LocalVariable (foreach_iterator_type, "%s_it".printf (variable_name));
+
+                               add_local_variable (iterator_variable);
+                               iterator_variable.active = true;
+                       }
+
+                       var it_method = (Method) analyzer.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, this);
+                               } else {
+                                       element_data_type = type_arg;
+                               }
+                       }
+               } else {
+                       error = true;
+                       Report.error (source_reference, "Gee.List not iterable");
+                       return false;
+               }
+
+               if (element_data_type == null) {
+                       error = true;
+                       Report.error (collection.source_reference, "missing type argument for collection");
+                       return false;
+               }
+
+               // analyze element type
+               if (type_reference == null) {
+                       // var type
+                       type_reference = element_data_type.copy ();
+               } else if (!element_data_type.compatible (type_reference)) {
+                       error = true;
+                       Report.error (source_reference, "Foreach: Cannot convert from `%s' to `%s'".printf (element_data_type.to_string (), type_reference.to_string ()));
+                       return false;
+               } else if (element_data_type.is_disposable () && element_owned && !type_reference.value_owned) {
+                       error = true;
+                       Report.error (source_reference, "Foreach: Invalid assignment from owned expression to unowned variable");
+                       return false;
+               }
+               
+               analyzer.current_source_file.add_type_dependency (type_reference, SourceFileDependencyType.SOURCE);
+
+               element_variable = new LocalVariable (type_reference, variable_name);
+
+               body.scope.add (variable_name, element_variable);
+
+               body.add_local_variable (element_variable);
+               element_variable.active = true;
+
+               // analyze body
+               owner = analyzer.current_symbol.scope;
+               analyzer.current_symbol = this;
+
+               body.accept (analyzer);
+
+               foreach (LocalVariable local in get_local_variables ()) {
+                       local.active = false;
+               }
+
+               analyzer.current_symbol = analyzer.current_symbol.parent_symbol;
+
+               collection_variable = new LocalVariable (collection_type, "%s_collection".printf (variable_name));
+
+               add_local_variable (collection_variable);
+               collection_variable.active = true;
+
+
+               add_error_types (collection.get_error_types ());
+               add_error_types (body.get_error_types ());
+
+               return !error;
+       }
 }
index ecbd73683388abdbb69c08fe27adea48830cf1d2..0a4a7a2e4bc5a2afecb4a2a08f593e8ebc26663d 100644 (file)
@@ -717,110 +717,7 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
        }
 
        public override void visit_foreach_statement (ForeachStatement stmt) {
-               // analyze collection expression first, used for type inference
-               stmt.collection.accept (this);
-
-               if (stmt.collection.error) {
-                       // ignore inner error
-                       stmt.error = true;
-                       return;
-               } else if (stmt.collection.value_type == null) {
-                       Report.error (stmt.collection.source_reference, "invalid collection expression");
-                       stmt.error = true;
-                       return;
-               }
-
-               var collection_type = stmt.collection.value_type.copy ();
-               stmt.collection.target_type = collection_type.copy ();
-               
-               DataType element_data_type = null;
-               bool element_owned = false;
-
-               if (collection_type.is_array ()) {
-                       var array_type = (ArrayType) collection_type;
-                       element_data_type = array_type.element_type;
-               } 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);
-                       }
-               } else if (iterable_type != null && collection_type.compatible (iterable_type)) {
-                       element_owned = true;
-
-                       if (list_type == null || !collection_type.compatible (new ObjectType (list_type))) {
-                               // don't use iterator objects for lists for performance reasons
-                               var foreach_iterator_type = new ObjectType (iterator_type);
-                               foreach_iterator_type.value_owned = true;
-                               foreach_iterator_type.add_type_argument (stmt.type_reference);
-                               stmt.iterator_variable = new LocalVariable (foreach_iterator_type, "%s_it".printf (stmt.variable_name));
-
-                               stmt.add_local_variable (stmt.iterator_variable);
-                               stmt.iterator_variable.active = true;
-                       }
-
-                       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;
-                               }
-                       }
-               } else {
-                       stmt.error = true;
-                       Report.error (stmt.source_reference, "Gee.List not iterable");
-                       return;
-               }
-
-               if (element_data_type == null) {
-                       stmt.error = true;
-                       Report.error (stmt.collection.source_reference, "missing type argument for collection");
-                       return;
-               }
-
-               // analyze element type
-               if (stmt.type_reference == null) {
-                       // var type
-                       stmt.type_reference = element_data_type.copy ();
-               } else 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;
-               } else if (element_data_type.is_disposable () && element_owned && !stmt.type_reference.value_owned) {
-                       stmt.error = true;
-                       Report.error (stmt.source_reference, "Foreach: Invalid assignment from owned expression to unowned variable");
-                       return;
-               }
-               
-               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;
-
-               // analyze body
-               stmt.owner = current_symbol.scope;
-               current_symbol = stmt;
-
-               stmt.body.accept (this);
-
-               foreach (LocalVariable local in stmt.get_local_variables ()) {
-                       local.active = false;
-               }
-
-               current_symbol = current_symbol.parent_symbol;
-
-               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;
-
-
-               stmt.add_error_types (stmt.collection.get_error_types ());
-               stmt.add_error_types (stmt.body.get_error_types ());
+               stmt.check (this);
        }
 
        public override void visit_return_statement (ReturnStatement stmt) {