diff options
author | Jürg Billeter <j@bitron.ch> | 2010-08-11 23:46:41 +0200 |
---|---|---|
committer | Jürg Billeter <j@bitron.ch> | 2010-09-09 15:54:17 +0200 |
commit | 3439cb38316dc1f1834e3e691ff2d4a56cdc2306 (patch) | |
tree | 532bc84a281402401b008284468428ea92690dff /vala/valaforeachstatement.vala | |
parent | 7ef23e9eb53def8b3f65ff1152b75dc077e0164f (diff) | |
download | vala-3439cb38316dc1f1834e3e691ff2d4a56cdc2306.tar.gz |
Support iteration via index to improve performance
Diffstat (limited to 'vala/valaforeachstatement.vala')
-rw-r--r-- | vala/valaforeachstatement.vala | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/vala/valaforeachstatement.vala b/vala/valaforeachstatement.vala index bc0cf3d07..469c51e18 100644 --- a/vala/valaforeachstatement.vala +++ b/vala/valaforeachstatement.vala @@ -189,9 +189,42 @@ public class Vala.ForeachStatement : Block { } } + bool check_with_index (SemanticAnalyzer analyzer, DataType collection_type) { + var get_method = collection_type.get_member ("get") as Method; + if (get_method == null) { + return false; + } + if (get_method.get_parameters ().size != 1) { + return false; + } + var size_property = collection_type.get_member ("size") as Property; + if (size_property == null) { + return false; + } + + add_statement (new DeclarationStatement (new LocalVariable (null, "_%s_list".printf (variable_name), collection, source_reference), source_reference)); + add_statement (new DeclarationStatement (new LocalVariable (null, "_%s_size".printf (variable_name), new MemberAccess (new MemberAccess.simple ("_%s_list".printf (variable_name), source_reference), "size", source_reference), source_reference), source_reference)); + add_statement (new DeclarationStatement (new LocalVariable (null, "_%s_index".printf (variable_name), new UnaryExpression (UnaryOperator.MINUS, new IntegerLiteral ("1", source_reference), source_reference), source_reference), source_reference)); + var next = new UnaryExpression (UnaryOperator.INCREMENT, new MemberAccess.simple ("_%s_index".printf (variable_name), source_reference), source_reference); + var conditional = new BinaryExpression (BinaryOperator.LESS_THAN, next, new MemberAccess.simple ("_%s_size".printf (variable_name), source_reference), source_reference); + var loop = new WhileStatement (conditional, body, source_reference); + add_statement (loop); + + var get_call = new MethodCall (new MemberAccess (new MemberAccess.simple ("_%s_list".printf (variable_name), source_reference), "get", source_reference), source_reference); + get_call.add_argument (new MemberAccess.simple ("_%s_index".printf (variable_name), source_reference)); + 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_with_iterator (SemanticAnalyzer analyzer, DataType collection_type) { use_iterator = true; + if (check_with_index (analyzer, collection_type)) { + return true; + } + 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 ())); |