vala r2069 - in trunk: . gobject vala
- From: juergbi svn gnome org
- To: svn-commits-list gnome org
- Subject: vala r2069 - in trunk: . gobject vala
- Date: Fri, 28 Nov 2008 14:50:50 +0000 (UTC)
Author: juergbi
Date: Fri Nov 28 14:50:49 2008
New Revision: 2069
URL: http://svn.gnome.org/viewvc/vala?rev=2069&view=rev
Log:
2008-11-28 JÃrg Billeter <j bitron ch>
* vala/valablock.vala:
* vala/valaforeachstatement.vala:
* vala/valasemanticanalyzer.vala:
* gobject/valaccodebasemodule.vala:
* gobject/valaccodecontrolflowmodule.vala:
Don't require libgee for foreach statements
Modified:
trunk/ChangeLog
trunk/gobject/valaccodebasemodule.vala
trunk/gobject/valaccodecontrolflowmodule.vala
trunk/vala/valablock.vala
trunk/vala/valaforeachstatement.vala
trunk/vala/valasemanticanalyzer.vala
Modified: trunk/gobject/valaccodebasemodule.vala
==============================================================================
--- trunk/gobject/valaccodebasemodule.vala (original)
+++ trunk/gobject/valaccodebasemodule.vala Fri Nov 28 14:50:49 2008
@@ -113,8 +113,6 @@
public DataType gquark_type;
public Struct mutex_type;
public TypeSymbol type_module_type;
- public Interface iterable_type;
- public Interface iterator_type;
public Interface collection_type;
public Interface list_type;
public Interface map_type;
@@ -553,8 +551,6 @@
var gee_ns = root_symbol.scope.lookup ("Gee");
if (gee_ns != null) {
- iterable_type = (Interface) gee_ns.scope.lookup ("Iterable");
- iterator_type = (Interface) gee_ns.scope.lookup ("Iterator");
collection_type = (Interface) gee_ns.scope.lookup ("Collection");
list_type = (Interface) gee_ns.scope.lookup ("List");
map_type = (Interface) gee_ns.scope.lookup ("Map");
Modified: trunk/gobject/valaccodecontrolflowmodule.vala
==============================================================================
--- trunk/gobject/valaccodecontrolflowmodule.vala (original)
+++ trunk/gobject/valaccodecontrolflowmodule.vala Fri Nov 28 14:50:49 2008
@@ -453,98 +453,6 @@
cfor.add_iterator (new CCodeAssignment (new CCodeIdentifier (it_name), new CCodeMemberAccess.pointer (new CCodeIdentifier (it_name), "next")));
cblock.add_statement (cfor);
- } else if (list_type != null && stmt.collection.value_type.compatible (new ObjectType (list_type))) {
- // iterating over a Gee.List, use integer to avoid the cost of an iterator object
-
- var it_name = "%s_it".printf (stmt.variable_name);
-
- var citdecl = new CCodeDeclaration ("int");
- citdecl.add_declarator (new CCodeVariableDeclarator (it_name));
- cblock.add_statement (citdecl);
-
- var cbody = new CCodeBlock ();
-
- var get_method = (Method) list_type.scope.lookup ("get");
- var get_ccall = new CCodeFunctionCall (new CCodeIdentifier (get_method.get_cname ()));
- get_ccall.add_argument (new InstanceCast (new CCodeIdentifier (collection_backup.name), list_type));
- get_ccall.add_argument (new CCodeIdentifier (it_name));
- CCodeExpression element_expr = get_ccall;
-
- var element_type = SemanticAnalyzer.get_actual_type (stmt.collection.value_type, (GenericType) get_method.return_type, stmt);
-
- element_expr = convert_from_generic_pointer (element_expr, element_type);
- element_expr = transform_expression (element_expr, element_type, stmt.type_reference);
-
- var cfrag = new CCodeFragment ();
- append_temp_decl (cfrag, temp_vars);
- cbody.add_statement (cfrag);
- temp_vars.clear ();
-
- var cdecl = new CCodeDeclaration (stmt.type_reference.get_cname ());
- var cvardecl = new CCodeVariableDeclarator.with_initializer (stmt.variable_name, element_expr);
- cvardecl.line = cblock.line;
- cdecl.add_declarator (cvardecl);
- cbody.add_statement (cdecl);
-
- cbody.add_statement (stmt.body.ccodenode);
-
- var list_len = new CCodeFunctionCall (new CCodeIdentifier ("gee_collection_get_size"));
- list_len.add_argument (new InstanceCast (new CCodeIdentifier (collection_backup.name), this.collection_type));
-
- var ccond = new CCodeBinaryExpression (CCodeBinaryOperator.LESS_THAN, new CCodeIdentifier (it_name), list_len);
-
- var cfor = new CCodeForStatement (ccond, cbody);
- cfor.add_initializer (new CCodeAssignment (new CCodeIdentifier (it_name), new CCodeConstant ("0")));
- cfor.add_iterator (new CCodeAssignment (new CCodeIdentifier (it_name), new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, new CCodeIdentifier (it_name), new CCodeConstant ("1"))));
- cfor.line = cblock.line;
- cblock.add_statement (cfor);
- } else if (iterable_type != null && stmt.collection.value_type.compatible (new ObjectType (iterable_type))) {
- // iterating over a Gee.Iterable, use iterator
-
- 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));
- var citvardecl = new CCodeVariableDeclarator.with_initializer (it_name, it_ccall);
- citvardecl.line = cblock.line;
- citdecl.add_declarator (citvardecl);
- 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;
-
- Iterator<DataType> type_arg_it = it_method.return_type.get_type_arguments ().iterator ();
- type_arg_it.next ();
- var it_type = SemanticAnalyzer.get_actual_type (stmt.collection.value_type, (GenericType) type_arg_it.get (), stmt);
-
- element_expr = transform_expression (element_expr, it_type, stmt.type_reference);
-
- var cfrag = new CCodeFragment ();
- append_temp_decl (cfrag, temp_vars);
- cbody.add_statement (cfrag);
- temp_vars.clear ();
-
- var cdecl = new CCodeDeclaration (stmt.type_reference.get_cname ());
- var cvardecl = new CCodeVariableDeclarator.with_initializer (stmt.variable_name, element_expr);
- cvardecl.line = cblock.line;
- cdecl.add_declarator (cvardecl);
- 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));
-
- var cwhile = new CCodeWhileStatement (next_ccall, cbody);
- cwhile.line = cblock.line;
- cblock.add_statement (cwhile);
}
foreach (LocalVariable local in stmt.get_local_variables ()) {
Modified: trunk/vala/valablock.vala
==============================================================================
--- trunk/vala/valablock.vala (original)
+++ trunk/vala/valablock.vala Fri Nov 28 14:50:49 2008
@@ -53,7 +53,11 @@
public void add_statement (Statement stmt) {
statement_list.add (stmt);
}
-
+
+ public void insert_statement (int index, Statement stmt) {
+ statement_list.insert (index, stmt);
+ }
+
/**
* Returns a copy of the list of statements.
*
Modified: trunk/vala/valaforeachstatement.vala
==============================================================================
--- trunk/vala/valaforeachstatement.vala (original)
+++ trunk/vala/valaforeachstatement.vala Fri Nov 28 14:50:49 2008
@@ -71,6 +71,8 @@
}
}
+ public bool use_iterator { get; private set; }
+
/**
* Specifies the declarator for the generated element variable.
*/
@@ -109,10 +111,20 @@
}
public override void accept (CodeVisitor visitor) {
+ if (use_iterator) {
+ base.accept (visitor);
+ return;
+ }
+
visitor.visit_foreach_statement (this);
}
public override void accept_children (CodeVisitor visitor) {
+ if (use_iterator) {
+ base.accept_children (visitor);
+ return;
+ }
+
collection.accept (visitor);
visitor.visit_end_full_expression (collection);
@@ -156,65 +168,116 @@
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;
+
+ return check_without_iterator (analyzer, collection_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);
+ if (collection_type.get_type_arguments ().size != 1) {
+ error = true;
+ Report.error (collection.source_reference, "missing type argument for collection");
+ return false;
}
- } 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));
+ return check_without_iterator (analyzer, collection_type, collection_type.get_type_arguments ().get (0));
+ } else {
+ return check_with_iterator (analyzer, collection_type);
+ }
+ }
- add_local_variable (iterator_variable);
- iterator_variable.active = true;
- }
+ bool check_with_iterator (SemanticAnalyzer analyzer, DataType collection_type) {
+ use_iterator = 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 is GenericType) {
- element_data_type = SemanticAnalyzer.get_actual_type (collection_type, (GenericType) type_arg, this);
- } else {
- element_data_type = type_arg;
- }
- }
- } else {
+ var iterator_method = collection_type.get_member ("iterator") as Method;
+ if (iterator_method == null) {
+ Report.error (collection.source_reference, "`%s' does not have an `iterator' method".printf (collection_type.to_string ()));
error = true;
- Report.error (source_reference, "Gee.List not iterable");
return false;
}
-
- if (element_data_type == null) {
+ if (iterator_method.get_parameters ().size != 0) {
+ Report.error (collection.source_reference, "`%s' must not have any parameters".printf (iterator_method.get_full_name ()));
+ error = true;
+ return false;
+ }
+ var iterator_type = iterator_method.return_type.get_actual_type (collection_type, this);
+ if (iterator_type is VoidType) {
+ Report.error (collection.source_reference, "`%s' must return an iterator".printf (iterator_method.get_full_name ()));
+ error = true;
+ return false;
+ }
+ var next_method = iterator_type.get_member ("next") as Method;
+ if (next_method == null) {
+ Report.error (collection.source_reference, "`%s' does not have a `next' method".printf (iterator_type.to_string ()));
+ error = true;
+ return false;
+ }
+ if (next_method.get_parameters ().size != 0) {
+ Report.error (collection.source_reference, "`%s' must not have any parameters".printf (next_method.get_full_name ()));
+ error = true;
+ return false;
+ }
+ if (!next_method.return_type.compatible (analyzer.bool_type)) {
+ Report.error (collection.source_reference, "`%s' must return a boolean value".printf (next_method.get_full_name ()));
+ error = true;
+ return false;
+ }
+ var get_method = iterator_type.get_member ("get") as Method;
+ if (get_method == null) {
+ Report.error (collection.source_reference, "`%s' does not have a `get' method".printf (iterator_type.to_string ()));
+ error = true;
+ return false;
+ }
+ if (get_method.get_parameters ().size != 0) {
+ Report.error (collection.source_reference, "`%s' must not have any parameters".printf (get_method.get_full_name ()));
+ error = true;
+ return false;
+ }
+ var element_type = get_method.return_type.get_actual_type (iterator_type, this);
+ if (element_type is VoidType) {
+ Report.error (collection.source_reference, "`%s' must return an element".printf (get_method.get_full_name ()));
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)) {
+ type_reference = element_type.copy ();
+ } else if (!element_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 ()));
+ Report.error (source_reference, "Foreach: Cannot convert from `%s' to `%s'".printf (element_type.to_string (), type_reference.to_string ()));
return false;
- } else if (element_data_type.is_disposable () && element_owned && !type_reference.value_owned) {
+ } else if (element_type.is_disposable () && element_type.value_owned && !type_reference.value_owned) {
error = true;
Report.error (source_reference, "Foreach: Invalid assignment from owned expression to unowned variable");
return false;
}
-
+
+ var iterator_call = new MethodCall (new MemberAccess (collection, "iterator"));
+ add_statement (new DeclarationStatement (new LocalVariable (iterator_type, "%s_it".printf (variable_name), iterator_call, source_reference), source_reference));
+
+ var next_call = new MethodCall (new MemberAccess (new MemberAccess.simple ("%s_it".printf (variable_name)), "next"));
+ var loop = new WhileStatement (next_call, body);
+ add_statement (loop);
+
+ var get_call = new MethodCall (new MemberAccess (new MemberAccess.simple ("%s_it".printf (variable_name)), "get"));
+ body.insert_statement (0, new DeclarationStatement (new LocalVariable (type_reference, variable_name, get_call, source_reference), source_reference));
+
+ checked = false;
+ return base.check (analyzer);
+ }
+
+ bool check_without_iterator (SemanticAnalyzer analyzer, DataType collection_type, DataType element_type) {
+ // analyze element type
+ if (type_reference == null) {
+ // var type
+ type_reference = element_type.copy ();
+ } else if (!element_type.compatible (type_reference)) {
+ error = true;
+ Report.error (source_reference, "Foreach: Cannot convert from `%s' to `%s'".printf (element_type.to_string (), type_reference.to_string ()));
+ return false;
+ }
+
analyzer.current_source_file.add_type_dependency (type_reference, SourceFileDependencyType.SOURCE);
element_variable = new LocalVariable (type_reference, variable_name);
@@ -242,7 +305,6 @@
add_local_variable (collection_variable);
collection_variable.active = true;
-
add_error_types (collection.get_error_types ());
add_error_types (body.get_error_types ());
Modified: trunk/vala/valasemanticanalyzer.vala
==============================================================================
--- trunk/vala/valasemanticanalyzer.vala (original)
+++ trunk/vala/valasemanticanalyzer.vala Fri Nov 28 14:50:49 2008
@@ -58,8 +58,6 @@
public DataType gslist_type;
public DataType garray_type;
public Class gerror_type;
- public DataType iterable_type;
- public Interface iterator_type;
public Interface list_type;
public Interface collection_type;
public Interface map_type;
@@ -116,8 +114,6 @@
var gee_ns = root_symbol.scope.lookup ("Gee");
if (gee_ns != null) {
- iterable_type = new ObjectType ((Interface) gee_ns.scope.lookup ("Iterable"));
- iterator_type = (Interface) gee_ns.scope.lookup ("Iterator");
list_type = (Interface) gee_ns.scope.lookup ("List");
collection_type = (Interface) gee_ns.scope.lookup ("Collection");
map_type = (Interface) gee_ns.scope.lookup ("Map");
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]