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

            Line data    Source code
       1              : /* valapostfixexpression.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 postfix increment or decrement expression.
      27              :  */
      28         8131 : public class Vala.PostfixExpression : Expression {
      29              :         /**
      30              :          * The operand, must be a variable or a property.
      31              :          */
      32              :         public Expression inner {
      33       105115 :                 get { return _inner; }
      34         6602 :                 private set {
      35         6602 :                         _inner = value;
      36         6602 :                         _inner.parent_node = this;
      37              :                 }
      38              :         }
      39              : 
      40              :         /**
      41              :          * Specifies whether value should be incremented or decremented.
      42              :          */
      43         7130 :         public bool increment { get; private set; }
      44              : 
      45         6602 :         private Expression _inner;
      46              : 
      47              :         /**
      48              :          * Creates a new postfix expression.
      49              :          *
      50              :          * @param _inner  operand expression
      51              :          * @param inc     true for increment, false for decrement
      52              :          * @param source  reference to source code
      53              :          * @return newly  created postfix expression
      54              :          */
      55        19806 :         public PostfixExpression (Expression _inner, bool inc, SourceReference? source = null) {
      56         6602 :                 inner = _inner;
      57         6602 :                 increment = inc;
      58         6602 :                 source_reference = source;
      59              :         }
      60              : 
      61        16726 :         public override void accept (CodeVisitor visitor) {
      62        16726 :                 visitor.visit_postfix_expression (this);
      63              : 
      64        16726 :                 visitor.visit_expression (this);
      65              :         }
      66              : 
      67        10502 :         public override void accept_children (CodeVisitor visitor) {
      68        10502 :                 inner.accept (visitor);
      69              :         }
      70              : 
      71            0 :         public override bool is_pure () {
      72            0 :                 return false;
      73              :         }
      74              : 
      75            0 :         public override bool is_accessible (Symbol sym) {
      76            0 :                 return inner.is_accessible (sym);
      77              :         }
      78              : 
      79        13002 :         public override void get_defined_variables (Collection<Variable> collection) {
      80        13002 :                 inner.get_defined_variables (collection);
      81        13002 :                 unowned LocalVariable? local = inner.symbol_reference as LocalVariable;
      82        13002 :                 unowned Parameter? param = inner.symbol_reference as Parameter;
      83        13002 :                 if (local != null) {
      84         9402 :                         collection.add (local);
      85         3600 :                 } else if (param != null && param.direction == ParameterDirection.OUT) {
      86           27 :                         collection.add (param);
      87              :                 }
      88              :         }
      89              : 
      90         4334 :         public override void get_used_variables (Collection<Variable> collection) {
      91         4334 :                 inner.get_used_variables (collection);
      92              :         }
      93              : 
      94            0 :         public override void replace_expression (Expression old_node, Expression new_node) {
      95            0 :                 if (inner == old_node) {
      96            0 :                         inner = new_node;
      97              :                 }
      98              :         }
      99              : 
     100         6179 :         public override bool check (CodeContext context) {
     101         6179 :                 if (checked) {
     102           35 :                         return !error;
     103              :                 }
     104              : 
     105         6144 :                 checked = true;
     106              : 
     107         6144 :                 inner.lvalue = true;
     108         6144 :                 if (!inner.check (context)) {
     109            0 :                         error = true;
     110            0 :                         return false;
     111              :                 }
     112              : 
     113         6144 :                 if (!(inner.value_type is IntegerType) && !(inner.value_type is FloatingType) && !(inner.value_type is PointerType)) {
     114            0 :                         error = true;
     115            0 :                         Report.error (source_reference, "unsupported lvalue in postfix expression");
     116            0 :                         return false;
     117              :                 }
     118              : 
     119         6144 :                 if (inner is MemberAccess) {
     120         6143 :                         unowned MemberAccess ma = (MemberAccess) inner;
     121              : 
     122         6143 :                         if (ma.prototype_access) {
     123            0 :                                 error = true;
     124            0 :                                 Report.error (source_reference, "Access to instance member `%s' denied", ma.symbol_reference.get_full_name ());
     125            0 :                                 return false;
     126              :                         }
     127              : 
     128         6143 :                         if (ma.error || ma.symbol_reference == null) {
     129            0 :                                 error = true;
     130              :                                 /* if no symbol found, skip this check */
     131            0 :                                 return false;
     132              :                         }
     133            1 :                 } else if (inner is ElementAccess) {
     134            1 :                         unowned ElementAccess ea = (ElementAccess) inner;
     135            1 :                         if (!(ea.container.value_type is ArrayType)) {
     136            0 :                                 error = true;
     137            0 :                                 Report.error (source_reference, "unsupported lvalue in postfix expression");
     138            0 :                                 return false;
     139              :                         }
     140              :                 } else {
     141            0 :                         error = true;
     142            0 :                         Report.error (source_reference, "unsupported lvalue in postfix expression");
     143            0 :                         return false;
     144              :                 }
     145              : 
     146         6144 :                 if (inner is MemberAccess) {
     147         6143 :                         unowned MemberAccess ma = (MemberAccess) inner;
     148              : 
     149         6143 :                         if (ma.symbol_reference is Property) {
     150           39 :                                 unowned Property prop = (Property) ma.symbol_reference;
     151              : 
     152           39 :                                 if (prop.set_accessor == null || !prop.set_accessor.writable) {
     153            0 :                                         ma.error = true;
     154            0 :                                         Report.error (ma.source_reference, "Property `%s' is read-only", prop.get_full_name ());
     155            0 :                                         return false;
     156              :                                 }
     157              :                         }
     158              :                 }
     159              : 
     160         6144 :                 value_type = inner.value_type;
     161              : 
     162         6144 :                 return !error;
     163              :         }
     164              : 
     165          528 :         public override void emit (CodeGenerator codegen) {
     166          528 :                 inner.emit (codegen);
     167              : 
     168          528 :                 codegen.visit_postfix_expression (this);
     169              : 
     170          528 :                 codegen.visit_expression (this);
     171              :         }
     172              : 
     173            0 :         public override string to_string () {
     174            0 :                 return "(%s%s)".printf (inner.to_string (), increment ? "++" : "--");
     175              :         }
     176              : }
        

Generated by: LCOV version 2.0-1