LCOV - code coverage report
Current view: top level - vala - valaforstatement.vala (source / functions) Coverage Total Hit
Test: vala 0.57.0.298-a8cae1 Lines: 76.1 % 67 51
Test Date: 2024-04-25 11:34:36 Functions: - 0 0

            Line data    Source code
       1              : /* valaforstatement.vala
       2              :  *
       3              :  * Copyright (C) 2006-2010  Jürg Billeter
       4              :  *
       5              :  * This library is free software; you can redistribute it and/or
       6              :  * modify it under the terms of the GNU Lesser General Public
       7              :  * License as published by the Free Software Foundation; either
       8              :  * version 2.1 of the License, or (at your option) any later version.
       9              : 
      10              :  * This library is distributed in the hope that it will be useful,
      11              :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      12              :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      13              :  * Lesser General Public License for more details.
      14              : 
      15              :  * You should have received a copy of the GNU Lesser General Public
      16              :  * License along with this library; if not, write to the Free Software
      17              :  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
      18              :  *
      19              :  * Author:
      20              :  *      Jürg Billeter <j@bitron.ch>
      21              :  */
      22              : 
      23              : using GLib;
      24              : 
      25              : /**
      26              :  * Represents a for iteration statement in the source code.
      27              :  */
      28        12590 : public class Vala.ForStatement : Loop, Statement {
      29         9532 :         private List<Expression> initializer = new ArrayList<Expression> ();
      30         9532 :         private List<Expression> iterator = new ArrayList<Expression> ();
      31              : 
      32              :         /**
      33              :          * Creates a new for statement.
      34              :          *
      35              :          * @param condition        loop condition
      36              :          * @param body             loop body
      37              :          * @param source_reference reference to source code
      38              :          * @return                 newly created for statement
      39              :          */
      40        14298 :         public ForStatement (Expression? condition, Block body, SourceReference? source_reference = null) {
      41         4766 :                 base (condition, body, source_reference);
      42              :         }
      43              : 
      44              :         /**
      45              :          * Appends the specified expression to the list of initializers.
      46              :          *
      47              :          * @param init an initializer expression
      48              :          */
      49         3078 :         public void add_initializer (Expression init) {
      50         3078 :                 init.parent_node = this;
      51         3078 :                 initializer.add (init);
      52              :         }
      53              : 
      54              :         /**
      55              :          * Returns the list of initializers.
      56              :          *
      57              :          * @return initializer list
      58              :          */
      59            0 :         public unowned List<Expression> get_initializer () {
      60            0 :                 return initializer;
      61              :         }
      62              : 
      63              :         /**
      64              :          * Appends the specified expression to the iterator.
      65              :          *
      66              :          * @param iter an iterator expression
      67              :          */
      68         4769 :         public void add_iterator (Expression iter) {
      69         4769 :                 iter.parent_node = this;
      70         4769 :                 iterator.add (iter);
      71              :         }
      72              : 
      73              :         /**
      74              :          * Returns the iterator.
      75              :          *
      76              :          * @return iterator
      77              :          */
      78            0 :         public unowned List<Expression> get_iterator () {
      79            0 :                 return iterator;
      80              :         }
      81              : 
      82         4442 :         public override void accept (CodeVisitor visitor) {
      83         4442 :                 visitor.visit_for_statement (this);
      84              :         }
      85              : 
      86         4442 :         public override void accept_children (CodeVisitor visitor) {
      87        10166 :                 foreach (Expression init_expr in initializer) {
      88         2862 :                         init_expr.accept (visitor);
      89         2862 :                         visitor.visit_end_full_expression (init_expr);
      90              :                 }
      91              : 
      92         4442 :                 if (condition != null) {
      93         4441 :                         condition.accept (visitor);
      94              : 
      95         4441 :                         visitor.visit_end_full_expression (condition);
      96              :                 }
      97              : 
      98        13332 :                 foreach (Expression it_expr in iterator) {
      99         4445 :                         it_expr.accept (visitor);
     100         4445 :                         visitor.visit_end_full_expression (it_expr);
     101              :                 }
     102              : 
     103         4442 :                 body.accept (visitor);
     104              :         }
     105              : 
     106            0 :         public override void replace_expression (Expression old_node, Expression new_node) {
     107            0 :                 base.replace_expression (old_node, new_node);
     108              : 
     109            0 :                 for (int i=0; i < initializer.size; i++) {
     110            0 :                         if (initializer[i] == old_node) {
     111            0 :                                 initializer[i] = new_node;
     112            0 :                                 new_node.parent_node = this;
     113              :                         }
     114              :                 }
     115            0 :                 for (int i=0; i < iterator.size; i++) {
     116            0 :                         if (iterator[i] == old_node) {
     117            0 :                                 iterator[i] = new_node;
     118            0 :                                 new_node.parent_node = this;
     119              :                         }
     120              :                 }
     121              :         }
     122              : 
     123         4424 :         public override bool check (CodeContext context) {
     124         4424 :                 if (checked) {
     125            0 :                         return !error;
     126              :                 }
     127              : 
     128         4424 :                 checked = true;
     129              : 
     130              :                 // convert to simple loop
     131              : 
     132         4424 :                 var block = new Block (source_reference);
     133              : 
     134              :                 // initializer
     135        10124 :                 foreach (var init_expr in initializer) {
     136         2850 :                         block.add_statement (new ExpressionStatement (init_expr, init_expr.source_reference));
     137              :                 }
     138              : 
     139              :                 // do not generate if block if condition is always true
     140         4424 :                 if (condition == null || condition.is_always_true ()) {
     141         8843 :                 } else if (condition.is_always_false ()) {
     142              :                         // do not generate if block if condition is always false
     143            1 :                         body.insert_statement (0, new BreakStatement (condition.source_reference));
     144              :                 } else {
     145              :                         // condition
     146         4421 :                         var if_condition = new UnaryExpression (UnaryOperator.LOGICAL_NEGATION, condition, condition.source_reference);
     147         4421 :                         var true_block = new Block (condition.source_reference);
     148         4421 :                         true_block.add_statement (new BreakStatement (condition.source_reference));
     149         4421 :                         var if_stmt = new IfStatement (if_condition, true_block, null, condition.source_reference);
     150         4421 :                         body.insert_statement (0, if_stmt);
     151              :                 }
     152              : 
     153              :                 // iterator
     154         4424 :                 var first_local = new LocalVariable (context.analyzer.bool_type.copy (), get_temp_name (), new BooleanLiteral (true, source_reference), source_reference);
     155         4424 :                 block.add_statement (new DeclarationStatement (first_local, source_reference));
     156              : 
     157         4424 :                 var iterator_block = new Block (source_reference);
     158        13278 :                 foreach (var it_expr in iterator) {
     159         4427 :                         iterator_block.add_statement (new ExpressionStatement (it_expr, it_expr.source_reference));
     160              :                 }
     161              : 
     162         4424 :                 var first_if = new IfStatement (new UnaryExpression (UnaryOperator.LOGICAL_NEGATION, new MemberAccess.simple (first_local.name, source_reference), source_reference), iterator_block, null, source_reference);
     163         4424 :                 body.insert_statement (0, first_if);
     164         4424 :                 body.insert_statement (1, new ExpressionStatement (new Assignment (new MemberAccess.simple (first_local.name, source_reference), new BooleanLiteral (false, source_reference), AssignmentOperator.SIMPLE, source_reference), source_reference));
     165              : 
     166         4424 :                 block.add_statement (new LoopStatement (body, source_reference));
     167              : 
     168         4424 :                 unowned Block parent_block = (Block) parent_node;
     169         4424 :                 parent_block.replace_statement (this, block);
     170              : 
     171         4424 :                 if (!block.check (context)) {
     172            0 :                         error = true;
     173              :                 }
     174              : 
     175         4424 :                 return !error;
     176              :         }
     177              : }
        

Generated by: LCOV version 2.0-1