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

            Line data    Source code
       1              : /* valablock.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 source code block.
      27              :  */
      28       866182 : public class Vala.Block : Symbol, Statement {
      29              :         /**
      30              :          * Specifies whether this block contains a jump statement. This
      31              :          * information can be used to remove unreachable block cleanup code.
      32              :          */
      33            0 :         public bool contains_jump_statement { get; set; }
      34              : 
      35              :         /**
      36              :          * Specifies whether the end of this block is unreachable.
      37              :          */
      38       107275 :         public bool unreachable_exit { get; set; }
      39              : 
      40        72069 :         public bool captured { get; set; }
      41              : 
      42       863106 :         private List<Statement> statement_list = new ArrayList<Statement> ();
      43       863106 :         private List<LocalVariable> local_variables = new ArrayList<LocalVariable> ();
      44       863106 :         private List<Constant> local_constants = new ArrayList<Constant> ();
      45              : 
      46              :         /**
      47              :          * Creates a new block.
      48              :          *
      49              :          * @param source_reference  reference to source code
      50              :          */
      51       430275 :         public Block (SourceReference? source_reference = null) {
      52       431554 :                 base (null, source_reference);
      53              :         }
      54              : 
      55              :         /**
      56              :          * Append a statement to this block.
      57              :          *
      58              :          * @param stmt a statement
      59              :          */
      60       732253 :         public void add_statement (Statement stmt) {
      61       732253 :                 stmt.parent_node = this;
      62       732253 :                 statement_list.add (stmt);
      63              :         }
      64              : 
      65        23487 :         public void insert_statement (int index, Statement stmt) {
      66        23487 :                 stmt.parent_node = this;
      67        23487 :                 statement_list.insert (index, stmt);
      68              :         }
      69              : 
      70              :         /**
      71              :          * Returns a copy of the list of statements.
      72              :          *
      73              :          * @return statement list
      74              :          */
      75       419656 :         public List<Statement> get_statements () {
      76       419656 :                 var list = new ArrayList<Statement> ();
      77      1929140 :                 foreach (Statement stmt in statement_list) {
      78       754742 :                         unowned StatementList? stmt_list = stmt as StatementList;
      79       713372 :                         if (stmt_list != null) {
      80       182210 :                                 for (int i = 0; i < stmt_list.length; i++) {
      81       140840 :                                         list.add (stmt_list.get (i));
      82              :                                 }
      83              :                         } else {
      84       713372 :                                 list.add (stmt);
      85              :                         }
      86              :                 }
      87              :                 return list;
      88              :         }
      89              : 
      90              :         /**
      91              :          * Add a local variable to this block.
      92              :          *
      93              :          * @param local a variable declarator
      94              :          */
      95       166285 :         public void add_local_variable (LocalVariable local) {
      96       166285 :                 unowned Symbol? parent_block = parent_symbol;
      97       444007 :                 while (parent_block is Block || parent_block is Method || parent_block is PropertyAccessor) {
      98       277722 :                         if (parent_block.scope.lookup (local.name) != null) {
      99            0 :                                 Report.error (local.source_reference, "Local variable `%s' conflicts with a local variable or constant declared in a parent scope", local.name);
     100            0 :                                 break;
     101              :                         }
     102       277722 :                         parent_block = parent_block.parent_symbol;
     103              :                 }
     104       166285 :                 local_variables.add (local);
     105              :         }
     106              : 
     107        14814 :         public void remove_local_variable (LocalVariable local) {
     108        14814 :                 local_variables.remove (local);
     109              :         }
     110              : 
     111              :         /**
     112              :          * Returns the list of local variables.
     113              :          *
     114              :          * @return variable declarator list
     115              :          */
     116       431671 :         public unowned List<LocalVariable> get_local_variables () {
     117       431671 :                 return local_variables;
     118              :         }
     119              : 
     120           24 :         public void add_local_constant (Constant constant) {
     121           24 :                 unowned Symbol? parent_block = parent_symbol;
     122           24 :                 while (parent_block is Block || parent_block is Method || parent_block is PropertyAccessor) {
     123            0 :                         if (parent_block.scope.lookup (constant.name) != null) {
     124            0 :                                 Report.error (constant.source_reference, "Local constant `%s' conflicts with a local variable or constant declared in a parent scope", constant.name);
     125            0 :                                 break;
     126              :                         }
     127            0 :                         parent_block = parent_block.parent_symbol;
     128              :                 }
     129           24 :                 local_constants.add (constant);
     130           24 :                 scope.add (constant.name, constant);
     131              :         }
     132              : 
     133              :         /**
     134              :          * Returns the list of local constants.
     135              :          *
     136              :          * @return constants list
     137              :          */
     138            0 :         public unowned List<Constant> get_local_constants () {
     139            0 :                 return local_constants;
     140              :         }
     141              : 
     142       653634 :         public override void accept (CodeVisitor visitor) {
     143       653634 :                 visitor.visit_block (this);
     144              :         }
     145              : 
     146       558922 :         public override void accept_children (CodeVisitor visitor) {
     147      2656158 :                 foreach (Statement stmt in statement_list) {
     148      1048618 :                         stmt.accept (visitor);
     149              :                 }
     150              :         }
     151              : 
     152       391764 :         public override bool check (CodeContext context) {
     153       391764 :                 if (checked) {
     154           88 :                         return !error;
     155              :                 }
     156              : 
     157       391676 :                 checked = true;
     158              : 
     159       391676 :                 owner = context.analyzer.current_symbol.scope;
     160              : 
     161      1566704 :                 var old_symbol = context.analyzer.current_symbol;
     162       391676 :                 var old_insert_block = context.analyzer.insert_block;
     163       391676 :                 context.analyzer.current_symbol = this;
     164       783352 :                 context.analyzer.insert_block = this;
     165              : 
     166      1087448 :                 for (int i = 0; i < statement_list.size; i++) {
     167       695772 :                         if (!statement_list[i].check (context)) {
     168          257 :                                 error = true;
     169              :                         }
     170              :                 }
     171              : 
     172       717768 :                 foreach (LocalVariable local in get_local_variables ()) {
     173       163046 :                         local.active = false;
     174              :                 }
     175              : 
     176       391722 :                 foreach (Constant constant in local_constants) {
     177           23 :                         constant.active = false;
     178              :                 }
     179              : 
     180       391676 :                 context.analyzer.current_symbol = old_symbol;
     181       657984 :                 context.analyzer.insert_block = old_insert_block;
     182              : 
     183       391676 :                 return !error;
     184              :         }
     185              : 
     186       392383 :         public override void get_error_types (Collection<DataType> collection, SourceReference? source_reference = null) {
     187              :                 // use get_statements () instead of statement_list to not miss errors within StatementList objects
     188      1971233 :                 foreach (Statement stmt in get_statements ()) {
     189       789425 :                         stmt.get_error_types (collection, source_reference);
     190              :                 }
     191              :         }
     192              : 
     193        26709 :         public override void emit (CodeGenerator codegen) {
     194        26709 :                 codegen.visit_block (this);
     195              :         }
     196              : 
     197        93225 :         public void insert_before (Statement stmt, Statement new_stmt) {
     198       832827 :                 for (int i = 0; i < statement_list.size; i++) {
     199       369801 :                         var stmt_list = statement_list[i] as StatementList;
     200       369801 :                         if (stmt_list != null) {
     201       176415 :                                 for (int j = 0; j < stmt_list.length; j++) {
     202       164995 :                                         if (stmt_list.get (j) == stmt) {
     203        54299 :                                                 stmt_list.insert (j, new_stmt);
     204        54299 :                                                 new_stmt.parent_node = this;
     205        54299 :                                                 break;
     206              :                                         }
     207              :                                 }
     208       304082 :                         } else if (statement_list[i] == stmt) {
     209        38926 :                                 stmt_list = new StatementList (source_reference);
     210        38926 :                                 stmt_list.add (new_stmt);
     211        38926 :                                 stmt_list.add (stmt);
     212        38926 :                                 statement_list[i] = stmt_list;
     213        38926 :                                 new_stmt.parent_node = this;
     214              :                         }
     215              :                 }
     216              :         }
     217              : 
     218        25341 :         public void replace_statement (Statement old_stmt, Statement new_stmt) {
     219        83493 :                 for (int i = 0; i < statement_list.size; i++) {
     220        54408 :                         var stmt_list = statement_list[i] as StatementList;
     221        54408 :                         if (stmt_list != null) {
     222         5830 :                                 for (int j = 0; j < stmt_list.length; j++) {
     223         4380 :                                         if (stmt_list.get (j) == old_stmt) {
     224            9 :                                                 stmt_list.set (j, new_stmt);
     225            9 :                                                 new_stmt.parent_node = this;
     226            9 :                                                 break;
     227              :                                         }
     228              :                                 }
     229        52949 :                         } else if (statement_list[i] == old_stmt) {
     230        25332 :                                 statement_list[i] = new_stmt;
     231        25332 :                                 new_stmt.parent_node = this;
     232        25332 :                                 break;
     233              :                         }
     234              :                 }
     235              :         }
     236              : }
        

Generated by: LCOV version 2.0-1