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

            Line data    Source code
       1              : /* valareturnstatement.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              : 
      24              : /**
      25              :  * Represents a return statement in the source code.
      26              :  */
      27       175532 : public class Vala.ReturnStatement : CodeNode, Statement {
      28              :         /**
      29              :          * The optional expression to return.
      30              :          */
      31              :         public Expression? return_expression {
      32      3535073 :                 get { return _return_expression; }
      33       185286 :                 private set {
      34       185286 :                         _return_expression = value;
      35       185286 :                         if (_return_expression != null) {
      36       184962 :                                 _return_expression.parent_node = this;
      37              :                         }
      38              :                 }
      39              :         }
      40              : 
      41       172458 :         private Expression _return_expression;
      42              : 
      43              :         /**
      44              :          * Creates a new return statement.
      45              :          *
      46              :          * @param return_expression the return expression
      47              :          * @param source_reference  reference to source code
      48              :          * @return                  newly created return statement
      49              :          */
      50       344916 :         public ReturnStatement (Expression? return_expression = null, SourceReference? source_reference = null) {
      51       172458 :                 this.source_reference = source_reference;
      52       172458 :                 this.return_expression = return_expression;
      53              :         }
      54              : 
      55       274757 :         public override void accept (CodeVisitor visitor) {
      56       274757 :                 visitor.visit_return_statement (this);
      57              :         }
      58              : 
      59       274757 :         public override void accept_children (CodeVisitor visitor) {
      60       274757 :                 if (return_expression != null) {
      61       274119 :                         return_expression.accept (visitor);
      62              : 
      63       274119 :                         visitor.visit_end_full_expression (return_expression);
      64              :                 }
      65              :         }
      66              : 
      67        12828 :         public override void replace_expression (Expression old_node, Expression new_node) {
      68        12828 :                 if (return_expression == old_node) {
      69        12828 :                         return_expression = new_node;
      70              :                 }
      71              :         }
      72              : 
      73       158458 :         public override void get_error_types (Collection<DataType> collection, SourceReference? source_reference = null) {
      74       158458 :                 if (return_expression != null) {
      75       158123 :                         return_expression.get_error_types (collection, source_reference);
      76              :                 }
      77              :         }
      78              : 
      79       158428 :         public override bool check (CodeContext context) {
      80       158428 :                 if (checked) {
      81            0 :                         return !error;
      82              :                 }
      83              : 
      84       158428 :                 checked = true;
      85              : 
      86       158428 :                 if (context.analyzer.current_return_type == null) {
      87            0 :                         error = true;
      88            0 :                         Report.error (source_reference, "Return not allowed in this context");
      89            0 :                         return false;
      90              :                 }
      91              : 
      92       158428 :                 if (return_expression == null) {
      93          323 :                         if (!(context.analyzer.current_return_type is VoidType)) {
      94            1 :                                 error = true;
      95            1 :                                 Report.error (source_reference, "Return without value in non-void function");
      96              :                         }
      97          323 :                         return !error;
      98              :                 }
      99              : 
     100       158105 :                 if (context.analyzer.current_return_type is VoidType) {
     101            1 :                         error = true;
     102            1 :                         Report.error (source_reference, "Return with value in void function");
     103            1 :                         return false;
     104              :                 }
     105              : 
     106       158104 :                 return_expression.target_type = context.analyzer.current_return_type.copy ();
     107              : 
     108       158104 :                 if (!return_expression.check (context)) {
     109              :                         // ignore inner error
     110            3 :                         error = true;
     111            3 :                         return false;
     112              :                 }
     113              : 
     114       158101 :                 if (return_expression.value_type == null) {
     115            0 :                         error = true;
     116            0 :                         Report.error (source_reference, "Invalid expression in return value");
     117            0 :                         return false;
     118              :                 }
     119              : 
     120       158101 :                 if (!return_expression.value_type.compatible (context.analyzer.current_return_type)) {
     121            2 :                         error = true;
     122            2 :                         Report.error (source_reference, "Return: Cannot convert from `%s' to `%s'", return_expression.value_type.to_string (), context.analyzer.current_return_type.to_string ());
     123            2 :                         return false;
     124              :                 }
     125              : 
     126       158099 :                 if (return_expression.value_type.is_disposable () &&
     127        20613 :                     !context.analyzer.current_return_type.value_owned) {
     128            1 :                         error = true;
     129            1 :                         Report.error (source_reference, "Return value transfers ownership but method return type hasn't been declared to transfer ownership");
     130            1 :                         return false;
     131              :                 }
     132              : 
     133       158098 :                 unowned LocalVariable? local = return_expression.symbol_reference as LocalVariable;
     134        30221 :                 if (local != null && local.variable_type.is_disposable () &&
     135        14585 :                     !context.analyzer.current_return_type.value_owned) {
     136            1 :                         error = true;
     137            1 :                         Report.error (source_reference, "Local variable with strong reference used as return value and method return type has not been declared to transfer ownership");
     138            1 :                         return false;
     139              :                 }
     140              : 
     141       158097 :                 if (return_expression is NullLiteral
     142         4522 :                     && !context.analyzer.current_return_type.nullable) {
     143           11 :                         Report.warning (source_reference, "`null' incompatible with return type `%s'", context.analyzer.current_return_type.to_string ());
     144              :                 }
     145              : 
     146       158097 :                 return !error;
     147              :         }
     148              : 
     149         4212 :         public override void emit (CodeGenerator codegen) {
     150         4212 :                 if (return_expression != null) {
     151         3895 :                         return_expression.emit (codegen);
     152              : 
     153         3895 :                         codegen.visit_end_full_expression (return_expression);
     154              :                 }
     155              : 
     156         4212 :                 codegen.visit_return_statement (this);
     157              :         }
     158              : 
     159       327174 :         public override void get_defined_variables (Collection<Variable> collection) {
     160       327174 :                 if (return_expression != null) {
     161       326232 :                         return_expression.get_defined_variables (collection);
     162              :                 }
     163              :         }
     164              : 
     165       109058 :         public override void get_used_variables (Collection<Variable> collection) {
     166       109058 :                 if (return_expression != null) {
     167       108744 :                         return_expression.get_used_variables (collection);
     168              :                 }
     169              :         }
     170              : }
        

Generated by: LCOV version 2.0-1