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

            Line data    Source code
       1              : /* valaparameter.vala
       2              :  *
       3              :  * Copyright (C) 2006-2012  Jürg Billeter
       4              :  * Copyright (C) 2006-2008  Raffaele Sandrini
       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              :  *      Jürg Billeter <j@bitron.ch>
      22              :  *      Raffaele Sandrini <raffaele@sandrini.ch>
      23              :  */
      24              : 
      25              : using GLib;
      26              : 
      27              : /**
      28              :  * Represents a formal parameter in method and callback signatures.
      29              :  */
      30     14950475 : public class Vala.Parameter : Variable {
      31     11268044 :         public ParameterDirection direction { get; set; default = ParameterDirection.IN; }
      32              : 
      33              :         /**
      34              :          * Specifies whether the methods accepts an indefinite number of
      35              :          * parameters.
      36              :          */
      37     17146725 :         public bool ellipsis { get; set; }
      38              : 
      39              :         /**
      40              :          * Specifies whether the methods accepts an indefinite number of
      41              :          * parameters.
      42              :          */
      43     45336202 :         public bool params_array { get; set; }
      44              : 
      45        77087 :         public bool captured { get; set; }
      46              : 
      47              :         public bool format_arg {
      48        39252 :                 get {
      49        39252 :                         return has_attribute ("FormatArg");
      50              :                 }
      51              :         }
      52              : 
      53              :         /**
      54              :          * The base parameter of this parameter relative to the base method.
      55              :          */
      56     28534532 :         public Parameter base_parameter { get; set; }
      57              : 
      58              :         /**
      59              :          * Creates a new formal parameter.
      60              :          *
      61              :          * @param name              parameter name
      62              :          * @param variable_type     parameter type
      63              :          * @param source_reference  reference to source code
      64              :          * @return                  newly created formal parameter
      65              :          */
      66     44466732 :         public Parameter (string name, DataType? variable_type, SourceReference? source_reference = null) {
      67     14822244 :                 base (variable_type, name, null, source_reference);
      68              : 
      69     14822244 :                 access = SymbolAccessibility.PUBLIC;
      70              :         }
      71              : 
      72              :         /**
      73              :          * Creates a new ellipsis parameter representing an indefinite number of
      74              :          * parameters.
      75              :          */
      76       126695 :         public Parameter.with_ellipsis (SourceReference? source_reference = null) {
      77       126695 :                 base (null, null, null, source_reference);
      78       126695 :                 ellipsis = true;
      79              : 
      80       126695 :                 access = SymbolAccessibility.PUBLIC;
      81              :         }
      82              : 
      83     14265070 :         public override void accept (CodeVisitor visitor) {
      84     14265070 :                 visitor.visit_formal_parameter (this);
      85              :         }
      86              : 
      87     15424953 :         public override void accept_children (CodeVisitor visitor) {
      88     15424953 :                 if (!ellipsis) {
      89     15201361 :                         variable_type.accept (visitor);
      90              : 
      91     15201361 :                         if (initializer != null) {
      92      1932012 :                                 initializer.accept (visitor);
      93              :                         }
      94              :                 }
      95              :         }
      96              : 
      97      7606324 :         public override void replace_type (DataType old_type, DataType new_type) {
      98      7606324 :                 if (variable_type == old_type) {
      99      7606324 :                         variable_type = new_type;
     100              :                 }
     101              :         }
     102              : 
     103            0 :         public override void replace_expression (Expression old_node, Expression new_node) {
     104            0 :                 if (initializer == old_node) {
     105            0 :                         initializer = new_node;
     106              :                 }
     107              :         }
     108              : 
     109          161 :         public Parameter copy () {
     110          161 :                 if (!ellipsis) {
     111          161 :                         var result = new Parameter (name, variable_type.copy (), source_reference);
     112          161 :                         result.params_array = params_array;
     113          161 :                         result.direction = this.direction;
     114          161 :                         result.initializer = this.initializer;
     115              : 
     116              :                         // cannot use List.copy()
     117              :                         // as it returns a list of unowned elements
     118          221 :                         foreach (Attribute a in this.attributes) {
     119           60 :                                 result.attributes.append (a);
     120              :                         }
     121              : 
     122          161 :                         return result;
     123              :                 } else {
     124            0 :                         return new Parameter.with_ellipsis ();
     125              :                 }
     126              :         }
     127              : 
     128     14458829 :         public override bool check (CodeContext context) {
     129     14458829 :                 if (checked) {
     130       948636 :                         return !error;
     131              :                 }
     132              : 
     133     13510193 :                 checked = true;
     134              : 
     135     13510193 :                 var old_source_file = context.analyzer.current_source_file;
     136     13510193 :                 var old_symbol = context.analyzer.current_symbol;
     137              : 
     138     13510193 :                 if (source_reference != null) {
     139     13510052 :                         context.analyzer.current_source_file = source_reference.file;
     140              :                 }
     141     13510193 :                 context.analyzer.current_symbol = parent_symbol;
     142              : 
     143     13510193 :                 if (variable_type != null) {
     144     13392848 :                         if (variable_type is VoidType) {
     145            1 :                                 error = true;
     146            1 :                                 Report.error (source_reference, "'void' not supported as parameter type");
     147            1 :                                 return false;
     148              :                         }
     149     13392847 :                         variable_type.check (context);
     150              :                 }
     151              : 
     152     13510192 :                 if (!ellipsis) {
     153     13392823 :                         variable_type.check (context);
     154              : 
     155     13392823 :                         if (params_array) {
     156         2909 :                                 if (!(variable_type is ArrayType)) {
     157            1 :                                         error = true;
     158            1 :                                         Report.error (source_reference, "parameter array expected");
     159            1 :                                         return false;
     160         2908 :                                 } else if (((ArrayType) variable_type).rank != 1) {
     161            1 :                                         error = true;
     162            1 :                                         Report.error (source_reference, "multi-dimensional parameter array not allowed");
     163            1 :                                         return false;
     164              :                                 }
     165              :                         }
     166              : 
     167     13402998 :                         if (has_attribute_argument ("CCode", "scope") && variable_type is DelegateType) {
     168        10177 :                                 var delegate_type = (DelegateType) variable_type;
     169        10177 :                                 delegate_type.is_called_once = get_attribute_string ("CCode", "scope") == "async";
     170              :                         }
     171              : 
     172     13392821 :                         if (initializer != null) {
     173      1009561 :                                 initializer.target_type = variable_type.copy ();
     174      1009561 :                                 initializer.check (context);
     175      1009561 :                                 if (initializer.value_type == null) {
     176            1 :                                         initializer.value_type = new InvalidType ();
     177              :                                 }
     178              :                         }
     179              : 
     180     13392821 :                         unowned ArrayType? variable_array_type = variable_type as ArrayType;
     181       328538 :                         if (variable_array_type != null && variable_array_type.inline_allocated
     182           50 :                                 && !variable_array_type.fixed_length) {
     183            2 :                                 error = true;
     184            2 :                                 Report.error (source_reference, "Inline allocated array as parameter requires to have fixed length");
     185              :                         }
     186              :                 }
     187              : 
     188     13510190 :                 if (initializer != null && !initializer.error) {
     189      1009560 :                         if (initializer is NullLiteral
     190       690734 :                             && !variable_type.nullable
     191       114685 :                             && direction != ParameterDirection.OUT) {
     192            1 :                                 Report.warning (source_reference, "`null' incompatible with parameter type `%s'", variable_type.to_string ());
     193      1009559 :                         } else if (!(initializer is NullLiteral) && direction == ParameterDirection.OUT) {
     194            1 :                                 error = true;
     195            1 :                                 Report.error (source_reference, "only `null' is allowed as default value for out parameters");
     196      1009558 :                         } else if (direction == ParameterDirection.IN && !initializer.value_type.compatible (variable_type)) {
     197            2 :                                 error = true;
     198            2 :                                 Report.error (initializer.source_reference, "Cannot convert from `%s' to `%s'", initializer.value_type.to_string (), variable_type.to_string ());
     199      1009556 :                         } else if (direction == ParameterDirection.REF) {
     200            1 :                                 error = true;
     201            1 :                                 Report.error (source_reference, "default value not allowed for ref parameter");
     202      1009555 :                         } else if (!initializer.is_accessible (this)) {
     203            1 :                                 error = true;
     204            1 :                                 Report.error (initializer.source_reference, "default value is less accessible than method `%s'", parent_symbol.get_full_name ());
     205              :                         }
     206              :                 }
     207              : 
     208     13510190 :                 if (!ellipsis) {
     209     13392821 :                         if (!external_package) {
     210        10422 :                                 context.analyzer.check_type (variable_type);
     211        10422 :                                 variable_type.check_type_arguments (context, !(variable_type is DelegateType));
     212              : 
     213              :                                 // check symbol availability
     214        10422 :                                 if ((parent_symbol == null || !parent_symbol.external_package) && variable_type.type_symbol != null) {
     215        10088 :                                         variable_type.type_symbol.version.check (context, source_reference);
     216              :                                 }
     217              :                         }
     218              : 
     219              :                         // check whether parameter type is at least as accessible as the method
     220     13392821 :                         if (!variable_type.is_accessible (this)) {
     221            1 :                                 error = true;
     222            1 :                                 Report.error (source_reference, "parameter type `%s' is less accessible than method `%s'", variable_type.to_string (), parent_symbol.get_full_name ());
     223              :                         }
     224              :                 }
     225              : 
     226     13510190 :                 unowned Method? m = parent_symbol as Method;
     227     12557706 :                 if (m != null) {
     228     12557706 :                         unowned Method? base_method = null;
     229     12557706 :                         if (m.base_method != null && m.base_method != m) {
     230        27036 :                                 base_method = m.base_method;
     231     12530670 :                         } else if (m.base_interface_method != null && m.base_interface_method != m) {
     232        29493 :                                 base_method = m.base_interface_method;
     233              :                         }
     234        56529 :                         if (base_method != null) {
     235        56529 :                                 int index = m.get_parameters ().index_of (this);
     236        56529 :                                 if (index >= 0) {
     237        26368 :                                         base_parameter = base_method.get_parameters ().get (index);
     238              :                                 }
     239              :                         }
     240              :                 }
     241              : 
     242     13510190 :                 context.analyzer.current_source_file = old_source_file;
     243     13510190 :                 context.analyzer.current_symbol = old_symbol;
     244              : 
     245     13510190 :                 return !error;
     246              :         }
     247              : }
     248              : 
     249              : public enum Vala.ParameterDirection {
     250              :         IN,
     251              :         OUT,
     252              :         REF
     253              : }
     254              : 
        

Generated by: LCOV version 2.0-1