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

            Line data    Source code
       1              : /* valafield.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 type or namespace field.
      27              :  */
      28       600434 : public class Vala.Field : Variable, Lockable {
      29              :         /**
      30              :          * Specifies whether this field may only be accessed with an instance of
      31              :          * the contained type.
      32              :          */
      33      1825935 :         public MemberBinding binding { get; set; default = MemberBinding.INSTANCE; }
      34              : 
      35              :         /**
      36              :          * Specifies whether the field is volatile. Volatile fields are
      37              :          * necessary to allow multi-threaded access.
      38              :          */
      39         3146 :         public bool is_volatile { get; set; }
      40              : 
      41         4206 :         public bool lock_used { get; set; }
      42              : 
      43              :         /**
      44              :          * Creates a new field.
      45              :          *
      46              :          * @param name              field name
      47              :          * @param variable_type     field type
      48              :          * @param initializer       initializer expression
      49              :          * @param source_reference  reference to source code
      50              :          * @return                  newly created field
      51              :          */
      52      1774703 :         public Field (string name, DataType variable_type, Expression? initializer, SourceReference? source_reference = null, Comment? comment = null) {
      53       597358 :                 base (variable_type, name, initializer, source_reference, comment);
      54              :         }
      55              : 
      56      1302624 :         public override void accept (CodeVisitor visitor) {
      57      1302624 :                 visitor.visit_field (this);
      58              :         }
      59              : 
      60       542235 :         public override void accept_children (CodeVisitor visitor) {
      61       542235 :                 variable_type.accept (visitor);
      62              : 
      63       542235 :                 if (initializer != null) {
      64          409 :                         initializer.accept (visitor);
      65              :                 }
      66              :         }
      67              : 
      68           15 :         public override void replace_expression (Expression old_node, Expression new_node) {
      69           15 :                 if (initializer == old_node) {
      70           15 :                         initializer = new_node;
      71              :                 }
      72              :         }
      73              : 
      74       482496 :         public override void replace_type (DataType old_type, DataType new_type) {
      75       482496 :                 if (variable_type == old_type) {
      76       482496 :                         variable_type = new_type;
      77              :                 }
      78              :         }
      79              : 
      80       660136 :         public override bool check (CodeContext context) {
      81       660136 :                 if (checked) {
      82       102625 :                         return !error;
      83              :                 }
      84              : 
      85       557511 :                 checked = true;
      86              : 
      87       557511 :                 var old_source_file = context.analyzer.current_source_file;
      88       823454 :                 var old_symbol = context.analyzer.current_symbol;
      89              : 
      90       557511 :                 if (source_reference != null) {
      91       557511 :                         context.analyzer.current_source_file = source_reference.file;
      92              :                 }
      93       557511 :                 context.analyzer.current_symbol = this;
      94              : 
      95       557511 :                 if (variable_type is VoidType) {
      96            2 :                         error = true;
      97            2 :                         Report.error (source_reference, "'void' not supported as field type");
      98            2 :                         return false;
      99              :                 }
     100              : 
     101       557509 :                 if (variable_type.type_symbol == context.analyzer.va_list_type.type_symbol) {
     102            1 :                         error = true;
     103            1 :                         Report.error (source_reference, "`%s' not supported as field type", variable_type.type_symbol.get_full_name ());
     104            1 :                         return false;
     105              :                 }
     106              : 
     107       557508 :                 if (has_attribute ("GtkChild") && variable_type.value_owned) {
     108            1 :                         Report.warning (source_reference, "[GtkChild] fields must be declared as `unowned'");
     109            1 :                         variable_type.value_owned = false;
     110              :                 }
     111              : 
     112       557508 :                 variable_type.check (context);
     113       557508 :                 if (!external_package) {
     114         2534 :                         context.analyzer.check_type (variable_type);
     115         2534 :                         variable_type.check_type_arguments (context, true);
     116              : 
     117              :                         // check symbol availability
     118         2534 :                         if (variable_type.type_symbol != null) {
     119         2304 :                                 variable_type.type_symbol.version.check (context, source_reference);
     120              :                         }
     121              :                 }
     122              : 
     123              :                 // check whether field type is at least as accessible as the field
     124       557508 :                 if (!variable_type.is_accessible (this)) {
     125            1 :                         error = true;
     126            1 :                         Report.error (source_reference, "field type `%s' is less accessible than field `%s'", variable_type.to_string (), get_full_name ());
     127            1 :                         return false;
     128              :                 }
     129              : 
     130       557507 :                 unowned ArrayType? variable_array_type = variable_type as ArrayType;
     131        38609 :                 if (variable_array_type != null && variable_array_type.inline_allocated
     132         2240 :                     && initializer is ArrayCreationExpression && ((ArrayCreationExpression) initializer).initializer_list == null) {
     133            0 :                         Report.warning (source_reference, "Inline allocated arrays don't require an explicit instantiation");
     134            0 :                         initializer = null;
     135              :                 }
     136              : 
     137       557507 :                 if (variable_array_type != null && variable_array_type.inline_allocated
     138         2240 :                     && !variable_array_type.fixed_length) {
     139            2 :                         Report.error (source_reference, "Inline allocated array as field requires to have fixed length");
     140              :                 }
     141              : 
     142       557507 :                 if (initializer != null) {
     143          409 :                         initializer.target_type = variable_type;
     144              : 
     145              :                         // Catch initializer list transformation:
     146          409 :                         bool is_initializer_list = false;
     147          409 :                         int initializer_size = -1;
     148              : 
     149          409 :                         if (initializer is InitializerList) {
     150           19 :                                 initializer_size = ((InitializerList) initializer).size;
     151           19 :                                 is_initializer_list = true;
     152              :                         }
     153              : 
     154          409 :                         if (!initializer.check (context)) {
     155            2 :                                 error = true;
     156            2 :                                 return false;
     157              :                         }
     158              : 
     159          407 :                         if (initializer.value_type == null) {
     160            0 :                                 error = true;
     161            0 :                                 Report.error (initializer.source_reference, "expression type not allowed as initializer");
     162            0 :                                 return false;
     163              :                         }
     164              : 
     165          407 :                         if (!initializer.value_type.compatible (variable_type)) {
     166            2 :                                 error = true;
     167            2 :                                 Report.error (source_reference, "Cannot convert from `%s' to `%s'", initializer.value_type.to_string (), variable_type.to_string ());
     168            2 :                                 return false;
     169              :                         }
     170              : 
     171          405 :                         if (variable_array_type != null && variable_array_type.inline_allocated && !variable_array_type.fixed_length && is_initializer_list) {
     172            0 :                                 variable_array_type.length = new IntegerLiteral (initializer_size.to_string ());
     173            0 :                                 variable_array_type.fixed_length = true;
     174            0 :                                 variable_array_type.nullable = false;
     175              :                         }
     176              : 
     177          405 :                         if (variable_array_type != null && variable_array_type.inline_allocated && !(initializer.value_type is ArrayType)) {
     178            0 :                                 error = true;
     179            0 :                                 Report.error (source_reference, "only arrays are allowed as initializer for arrays with fixed length");
     180            0 :                                 return false;
     181              :                         }
     182              : 
     183          405 :                         if (initializer.value_type.is_disposable ()) {
     184              :                                 /* rhs transfers ownership of the expression */
     185          137 :                                 if (!(variable_type is PointerType) && !variable_type.value_owned) {
     186              :                                         /* lhs doesn't own the value */
     187            1 :                                         error = true;
     188            1 :                                         Report.error (source_reference, "Invalid assignment from owned expression to unowned variable");
     189            1 :                                         return false;
     190              :                                 }
     191              :                         }
     192              : 
     193          404 :                         if (parent_symbol is Namespace && !initializer.is_constant ()) {
     194            2 :                                 error = true;
     195            2 :                                 Report.error (source_reference, "Non-constant field initializers not supported in this context");
     196            2 :                                 return false;
     197              :                         }
     198              : 
     199          402 :                         if (parent_symbol is Namespace && initializer.is_constant () && initializer.is_non_null ()) {
     200            7 :                                 if (variable_type.is_disposable () && variable_type.value_owned) {
     201            2 :                                         error = true;
     202            2 :                                         Report.error (source_reference, "Owned namespace fields can only be initialized in a function or method");
     203            2 :                                         return false;
     204              :                                 }
     205              :                         }
     206              : 
     207          400 :                         if (binding == MemberBinding.STATIC && parent_symbol is Class && ((Class)parent_symbol).is_compact && !initializer.is_constant ()) {
     208            1 :                                 error = true;
     209            1 :                                 Report.error (source_reference, "Static fields in compact classes cannot have non-constant initializers");
     210            1 :                                 return false;
     211              :                         }
     212              : 
     213          399 :                         if (external) {
     214            1 :                                 error = true;
     215            1 :                                 Report.error (source_reference, "External fields cannot use initializers");
     216              :                         }
     217              :                 }
     218              : 
     219       557497 :                 if (binding == MemberBinding.INSTANCE && parent_symbol is Interface) {
     220            1 :                         error = true;
     221            1 :                         Report.error (source_reference, "Interfaces may not have instance fields");
     222            1 :                         return false;
     223              :                 }
     224              : 
     225       557496 :                 bool field_in_header = !is_internal_symbol ();
     226       823439 :                 if (parent_symbol is Class) {
     227       265943 :                         var cl = (Class) parent_symbol;
     228       265943 :                         if (cl.is_compact && !cl.is_internal_symbol ()) {
     229              :                                 // compact classes don't have priv structs
     230       265943 :                                 field_in_header = true;
     231              :                         }
     232              :                 }
     233              : 
     234       557496 :                 if (!external_package && !hides && get_hidden_member () != null) {
     235            0 :                         Report.warning (source_reference, "%s hides inherited field `%s'. Use the `new' keyword if hiding was intentional", get_full_name (), get_hidden_member ().get_full_name ());
     236              :                 }
     237              : 
     238       557496 :                 context.analyzer.current_source_file = old_source_file;
     239       557496 :                 context.analyzer.current_symbol = old_symbol;
     240              : 
     241       557496 :                 return !error;
     242              :         }
     243              : }
        

Generated by: LCOV version 2.0-1