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

            Line data    Source code
       1              : /* valasliceexpression.vala
       2              :  *
       3              :  * Copyright (C) 2009 Robin Sonefors
       4              :  * Copyright (C) 2009-2013 Jürg Billeter
       5              :  *
       6              :  * This library is free software; you can redistribute it and/or
       7              :  * modify it under the terms of the GNU Lesser General Public
       8              :  * License as published by the Free Software Foundation; either
       9              :  * version 2.1 of the License, or (at your option) any later version.
      10              : 
      11              :  * This library is distributed in the hope that it will be useful,
      12              :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      13              :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      14              :  * Lesser General Public License for more details.
      15              : 
      16              :  * You should have received a copy of the GNU Lesser General Public
      17              :  * License along with this library; if not, write to the Free Software
      18              :  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
      19              :  *
      20              :  * Author:
      21              :  *      Robin Sonefors <ozamosi@flukkost.nu>
      22              :  *      Jürg Billeter <j@bitron.ch>
      23              :  */
      24              : 
      25              : using GLib;
      26              : 
      27              : /**
      28              :  * Represents an array slice expression.
      29              :  *
      30              :  * {{{ foo[1:5] }}}
      31              :  */
      32           51 : public class Vala.SliceExpression : Expression {
      33              :         public Expression container {
      34          568 :                 get {
      35          568 :                         return _container;
      36              :                 }
      37           40 :                 private set {
      38          120 :                         _container = value;
      39           40 :                         _container.parent_node = this;
      40              :                 }
      41              :         }
      42              : 
      43              :         public Expression start {
      44          399 :                 get {
      45          399 :                         return _start;
      46              :                 }
      47           40 :                 private set {
      48           80 :                         _start = value;
      49           40 :                         _start.parent_node = this;
      50              :                 }
      51              :         }
      52              : 
      53              :         public Expression stop {
      54          399 :                 get {
      55          399 :                         return _stop;
      56              :                 }
      57           40 :                 private set {
      58           80 :                         _stop = value;
      59           40 :                         _stop.parent_node = this;
      60              :                 }
      61              :         }
      62              : 
      63              :         /**
      64              :          * Null-safe access.
      65              :          */
      66           40 :         public bool null_safe_access { get; set; }
      67              : 
      68           40 :         Expression _container;
      69           40 :         Expression _start;
      70           40 :         Expression _stop;
      71              : 
      72          120 :         public SliceExpression (Expression container, Expression start, Expression stop, SourceReference? source_reference = null) {
      73           40 :                 this.container = container;
      74           40 :                 this.start = start;
      75           40 :                 this.stop = stop;
      76           40 :                 this.source_reference = source_reference;
      77              :         }
      78              : 
      79          136 :         public override void accept (CodeVisitor visitor) {
      80          136 :                 visitor.visit_slice_expression (this);
      81              : 
      82          136 :                 visitor.visit_expression (this);
      83              :         }
      84              : 
      85          136 :         public override void accept_children (CodeVisitor visitor) {
      86          136 :                 container.accept (visitor);
      87              : 
      88          136 :                 start.accept (visitor);
      89          136 :                 stop.accept (visitor);
      90              :         }
      91              : 
      92            0 :         public override void replace_expression (Expression old_node, Expression new_node) {
      93            0 :                 if (container == old_node) {
      94            0 :                         container = new_node;
      95              :                 }
      96            0 :                 if (start == old_node) {
      97            0 :                         start = new_node;
      98              :                 }
      99            0 :                 if (stop == old_node) {
     100            0 :                         stop = new_node;
     101              :                 }
     102              :         }
     103              : 
     104            0 :         public override bool is_pure () {
     105            0 :                 return false;
     106              :         }
     107              : 
     108            0 :         public override bool is_accessible (Symbol sym) {
     109            0 :                 return container.is_accessible (sym) && start.is_accessible (sym) && stop.is_accessible (sym);
     110              :         }
     111              : 
     112           42 :         public override bool check (CodeContext context) {
     113           42 :                 if (checked) {
     114            2 :                         return !error;
     115              :                 }
     116              : 
     117           40 :                 checked = true;
     118              : 
     119           40 :                 if (null_safe_access) {
     120            2 :                         error = !base.check (context);
     121            2 :                         return !error;
     122              :                 }
     123              : 
     124           38 :                 if (!container.check (context)) {
     125            0 :                         error = true;
     126            0 :                         return false;
     127              :                 }
     128              : 
     129           38 :                 if (container.value_type is ArrayType) {
     130           28 :                         unowned ArrayType array_type = (ArrayType) container.value_type;
     131           28 :                         start.target_type = array_type.length_type.copy ();
     132           28 :                         stop.target_type = array_type.length_type.copy ();
     133              :                 }
     134              : 
     135           38 :                 if (!start.check (context)) {
     136            0 :                         error = true;
     137            0 :                         return false;
     138              :                 }
     139              : 
     140           38 :                 if (!stop.check (context)) {
     141            0 :                         error = true;
     142            0 :                         return false;
     143              :                 }
     144              : 
     145           38 :                 if (container.value_type == null) {
     146            0 :                         error = true;
     147            0 :                         Report.error (container.source_reference, "Invalid container expression");
     148            0 :                         return false;
     149              :                 }
     150              : 
     151           38 :                 if (lvalue) {
     152            0 :                         error = true;
     153            0 :                         Report.error (container.source_reference, "Slice expressions cannot be used as lvalue");
     154            0 :                         return false;
     155              :                 }
     156              : 
     157           38 :                 if (container.value_type is ArrayType) {
     158           28 :                         value_type = container.value_type.copy ();
     159           28 :                         value_type.value_owned = false;
     160              : 
     161              :                         // inline allocated results are not compatible with non-constant start/stop expressions
     162           28 :                         unowned ArrayType array_type = (ArrayType) value_type;
     163           28 :                         array_type.fixed_length = false;
     164           28 :                         array_type.inline_allocated = false;
     165           28 :                         array_type.length = null;
     166              : 
     167           28 :                         value_type.check (context);
     168              : 
     169              :                         /* check if the index is of type integer */
     170           28 :                         if (!(start.value_type is IntegerType || start.value_type is EnumValueType)) {
     171            1 :                                 error = true;
     172            1 :                                 Report.error (start.source_reference, "Expression of integer type expected");
     173              :                         }
     174           28 :                         if (!(stop.value_type is IntegerType || stop.value_type is EnumValueType)) {
     175            1 :                                 error = true;
     176            1 :                                 Report.error (stop.source_reference, "Expression of integer type expected");
     177              :                         }
     178              :                 } else {
     179           10 :                         var slice_method = container.value_type.get_member ("slice") as Method;
     180            9 :                         if (slice_method != null) {
     181            9 :                                 var slice_call = new MethodCall (new MemberAccess (container, "slice", source_reference), source_reference);
     182            9 :                                 slice_call.add_argument (start);
     183            9 :                                 slice_call.add_argument (stop);
     184            9 :                                 slice_call.target_type = this.target_type;
     185            9 :                                 parent_node.replace_expression (this, slice_call);
     186            9 :                                 return slice_call.check (context);
     187              :                         }
     188              : 
     189            1 :                         error = true;
     190            1 :                         Report.error (source_reference, "The expression `%s' does not denote an array", container.value_type.to_string ());
     191              :                 }
     192              : 
     193           29 :                 return !error;
     194              :         }
     195              : 
     196           26 :         public override void emit (CodeGenerator codegen) {
     197           26 :                 container.emit (codegen);
     198              : 
     199           26 :                 start.emit (codegen);
     200           26 :                 stop.emit (codegen);
     201              : 
     202           26 :                 codegen.visit_slice_expression (this);
     203              : 
     204           26 :                 codegen.visit_expression (this);
     205              :         }
     206              : 
     207           78 :         public override void get_defined_variables (Collection<Variable> collection) {
     208           78 :                 container.get_defined_variables (collection);
     209           78 :                 start.get_defined_variables (collection);
     210           78 :                 stop.get_defined_variables (collection);
     211              :         }
     212              : 
     213           26 :         public override void get_used_variables (Collection<Variable> collection) {
     214           26 :                 container.get_used_variables (collection);
     215           26 :                 start.get_used_variables (collection);
     216           26 :                 stop.get_used_variables (collection);
     217              :         }
     218              : }
        

Generated by: LCOV version 2.0-1