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

            Line data    Source code
       1              : /* valaconstant.vala
       2              :  *
       3              :  * Copyright (C) 2006-2011  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 type member with a constant value.
      27              :  */
      28      2562483 : public class Vala.Constant : Symbol {
      29              :         /**
      30              :          * The data type of this constant.
      31              :          */
      32              :         public DataType type_reference {
      33      4433044 :                 get { return _data_type; }
      34      1675512 :                 private set {
      35      5258638 :                         _data_type = value;
      36      1675512 :                         _data_type.parent_node = this;
      37              :                 }
      38              :         }
      39              : 
      40              :         /**
      41              :          * The value of this constant.
      42              :          */
      43              :         public Expression? value {
      44      3030270 :                 get { return _value; }
      45      2560946 :                 private set {
      46      2561197 :                         _value = value;
      47      2560946 :                         if (_value != null) {
      48          251 :                                 _value.parent_node = this;
      49              :                         }
      50              :                 }
      51              :         }
      52              : 
      53      2560945 :         private DataType _data_type;
      54              : 
      55      2560945 :         private Expression _value;
      56              : 
      57              :         /**
      58              :          * Creates a new constant.
      59              :          *
      60              :          * @param name             constant name
      61              :          * @param type_reference   constant type
      62              :          * @param value            constant value
      63              :          * @param source_reference reference to source code
      64              :          * @return                 newly created constant
      65              :          */
      66      6185345 :         public Constant (string name, DataType? type_reference, Expression? value, SourceReference? source_reference = null, Comment? comment = null) {
      67      2560945 :                 base (name, source_reference, comment);
      68      2560945 :                 if (type_reference != null) {
      69      1063455 :                         this.type_reference = type_reference;
      70              :                 }
      71      2560945 :                 this.value = value;
      72              :         }
      73              : 
      74      1535470 :         public override void accept (CodeVisitor visitor) {
      75      1535470 :                 visitor.visit_constant (this);
      76              :         }
      77              : 
      78       612100 :         public override void accept_children (CodeVisitor visitor) {
      79       612100 :                 type_reference.accept (visitor);
      80              : 
      81       612100 :                 if (value != null) {
      82          186 :                         value.accept (visitor);
      83              :                 }
      84              :         }
      85              : 
      86            0 :         public override void replace_expression (Expression old_node, Expression new_node) {
      87            0 :                 if (value == old_node) {
      88            0 :                         value = new_node;
      89              :                 }
      90              :         }
      91              : 
      92       612057 :         public override void replace_type (DataType old_type, DataType new_type) {
      93       612057 :                 if (type_reference == old_type) {
      94       612057 :                         type_reference = new_type;
      95              :                 }
      96              :         }
      97              : 
      98      1160042 :         public override bool check (CodeContext context) {
      99      1160042 :                 if (checked) {
     100       137862 :                         return !error;
     101              :                 }
     102              : 
     103      1022180 :                 checked = true;
     104              : 
     105      1022180 :                 var old_source_file = context.analyzer.current_source_file;
     106      1022180 :                 var old_symbol = context.analyzer.current_symbol;
     107              : 
     108      1022180 :                 if (source_reference != null) {
     109      1022137 :                         context.analyzer.current_source_file = source_reference.file;
     110              :                 }
     111      1022180 :                 if (!(parent_symbol is Block)) {
     112              :                         // non-local constant
     113      1022157 :                         context.analyzer.current_symbol = this;
     114              :                 }
     115              : 
     116      1022180 :                 type_reference.check (context);
     117              : 
     118      1022180 :                 if (!check_const_type (type_reference, context)) {
     119            2 :                         error = true;
     120            2 :                         Report.error (source_reference, "`%s' not supported as type for constants", type_reference.to_string ());
     121            2 :                         return false;
     122              :                 }
     123              : 
     124              :                 // check whether constant type is at least as accessible as the constant
     125      1022178 :                 if (!type_reference.is_accessible (this)) {
     126            1 :                         error = true;
     127            1 :                         Report.error (source_reference, "constant type `%s' is less accessible than constant `%s'", type_reference.to_string (), get_full_name ());
     128              :                 }
     129              : 
     130      1022178 :                 if (!external) {
     131          185 :                         if (value == null) {
     132              :                                 // constants from fast-vapi files are special
     133            2 :                                 if (source_type != SourceFileType.FAST) {
     134            1 :                                         error = true;
     135            1 :                                         Report.error (source_reference, "A const field requires a value to be provided");
     136              :                                 }
     137              :                         } else {
     138          183 :                                 value.target_type = type_reference;
     139              : 
     140          183 :                                 if (!value.check (context) || type_reference.error) {
     141            1 :                                         error = true;
     142            1 :                                         return false;
     143              :                                 }
     144              : 
     145          182 :                                 if (!value.value_type.compatible (type_reference)) {
     146            1 :                                         error = true;
     147            1 :                                         Report.error (source_reference, "Cannot convert from `%s' to `%s'", value.value_type.to_string (), type_reference.to_string ());
     148            1 :                                         return false;
     149              :                                 }
     150              : 
     151              :                                 // support translated string constants for efficiency / convenience
     152              :                                 // even though the expression is not a compile-time constant
     153          181 :                                 unowned MethodCall? call = value as MethodCall;
     154            4 :                                 if (call != null) {
     155            4 :                                         unowned MethodType? method_type = call.call.value_type as MethodType;
     156            5 :                                         if (method_type != null && method_type.method_symbol.get_full_name () == "GLib._") {
     157              :                                                 // first argument is string
     158            1 :                                                 var literal = call.get_argument_list ().get (0) as StringLiteral;
     159            1 :                                                 if (literal != null) {
     160            1 :                                                         value = literal;
     161            1 :                                                         literal.translate = true;
     162              :                                                 }
     163              :                                         }
     164              :                                 }
     165              : 
     166          181 :                                 if (!value.is_constant ()) {
     167            1 :                                         error = true;
     168            1 :                                         Report.error (value.source_reference, "Value must be constant");
     169            1 :                                         return false;
     170              :                                 }
     171              : 
     172              :                                 // check whether initializer is at least as accessible as the constant
     173          180 :                                 if (!value.is_accessible (this)) {
     174            1 :                                         error = true;
     175            1 :                                         Report.error (value.source_reference, "value is less accessible than constant `%s'", get_full_name ());
     176              :                                 }
     177              :                         }
     178              :                 } else {
     179      1021993 :                         if (value != null) {
     180            1 :                                 error = true;
     181            1 :                                 Report.error (source_reference, "External constants cannot use values");
     182              :                         }
     183              :                 }
     184              : 
     185      1022175 :                 if (!external_package && !hides && get_hidden_member () != null) {
     186            0 :                         Report.warning (source_reference, "%s hides inherited constant `%s'. Use the `new' keyword if hiding was intentional", get_full_name (), get_hidden_member ().get_full_name ());
     187              :                 }
     188              : 
     189      1022175 :                 context.analyzer.current_source_file = old_source_file;
     190      1022175 :                 context.analyzer.current_symbol = old_symbol;
     191              : 
     192      1022175 :                 active = true;
     193              : 
     194      1022175 :                 return !error;
     195              :         }
     196              : 
     197      1022219 :         bool check_const_type (DataType type, CodeContext context) {
     198      1022219 :                 if (type is ValueType) {
     199      1022180 :                         return true;
     200       296794 :                 } else if (type is VoidType || type is PointerType) {
     201            2 :                         return false;
     202       296792 :                 } else if (type is ArrayType) {
     203           39 :                         unowned ArrayType array_type = (ArrayType) type;
     204           39 :                         return check_const_type (array_type.element_type, context);
     205       296753 :                 } else if (type is DelegateType) {
     206            2 :                         unowned DelegateType delegate_type = (DelegateType) type;
     207            2 :                         return !delegate_type.type_symbol.get_attribute_bool ("CCode", "has_target", true);
     208       296751 :                 } else if (type.type_symbol != null) {
     209       296751 :                         return type.type_symbol.is_subtype_of (context.analyzer.string_type.type_symbol);
     210              :                 } else {
     211            2 :                         return false;
     212              :                 }
     213              :         }
     214              : }
        

Generated by: LCOV version 2.0-1