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

            Line data    Source code
       1              : /* valadelegatetype.vala
       2              :  *
       3              :  * Copyright (C) 2007-2012  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              :  * The type of an instance of a delegate.
      27              :  */
      28       583368 : public class Vala.DelegateType : CallableType {
      29              :         public weak Delegate delegate_symbol {
      30      1651657 :                 get {
      31      1651657 :                         return (Delegate) symbol;
      32              :                 }
      33              :         }
      34              : 
      35       682371 :         public bool is_called_once { get; set; }
      36              : 
      37       581939 :         DelegateTargetField? target_field;
      38       581939 :         DelegateDestroyField? destroy_field;
      39              : 
      40      1745817 :         public DelegateType (Delegate delegate_symbol, SourceReference? source_reference = null) {
      41       581939 :                 base (delegate_symbol, source_reference);
      42       581939 :                 this.is_called_once = (delegate_symbol.get_attribute_string ("CCode", "scope") == "async");
      43              :         }
      44              : 
      45           21 :         public override Symbol? get_member (string member_name) {
      46           21 :                 if (member_name == "target") {
      47           21 :                         return get_target_field ();
      48            6 :                 } else if (member_name == "destroy") {
      49           12 :                         return get_destroy_field ();
      50              :                 }
      51           21 :                 return null;
      52              :         }
      53              : 
      54           15 :         unowned DelegateTargetField get_target_field () {
      55           15 :                 if (target_field == null) {
      56           15 :                         target_field = new DelegateTargetField (source_reference);
      57           15 :                         target_field.access = SymbolAccessibility.PUBLIC;
      58              :                 }
      59           15 :                 return target_field;
      60              :         }
      61              : 
      62            6 :         unowned DelegateDestroyField get_destroy_field () {
      63            6 :                 if (destroy_field == null) {
      64            6 :                         destroy_field = new DelegateDestroyField (source_reference);
      65            6 :                         destroy_field.access = SymbolAccessibility.PUBLIC;
      66              :                 }
      67            6 :                 return destroy_field;
      68              :         }
      69              : 
      70        89443 :         public override DataType copy () {
      71        89443 :                 var result = new DelegateType (delegate_symbol, source_reference);
      72        89443 :                 result.value_owned = value_owned;
      73        89443 :                 result.nullable = nullable;
      74              : 
      75       122005 :                 foreach (DataType arg in get_type_arguments ()) {
      76        16281 :                         result.add_type_argument (arg.copy ());
      77              :                 }
      78              : 
      79        89443 :                 result.is_called_once = is_called_once;
      80              : 
      81        89443 :                 return result;
      82              :         }
      83              : 
      84           39 :         public override bool equals (DataType type2) {
      85           39 :                 return compatible (type2);
      86              :         }
      87              : 
      88       480778 :         public override bool is_accessible (Symbol sym) {
      89       480778 :                 return delegate_symbol.is_accessible (sym);
      90              :         }
      91              : 
      92       912799 :         public override bool check (CodeContext context) {
      93       912799 :                 if (is_called_once && !value_owned) {
      94            1 :                         Report.warning (source_reference, "delegates with scope=\"async\" must be owned");
      95              :                 }
      96              : 
      97       912799 :                 if (!delegate_symbol.check (context)) {
      98            0 :                         error = true;
      99            0 :                         return false;
     100              :                 }
     101              : 
     102              :                 // check whether there is the expected amount of type-arguments
     103       912799 :                 if (!check_type_arguments (context, true)) {
     104            3 :                         error = true;
     105            3 :                         return false;
     106              :                 }
     107              : 
     108       912799 :                 return true;
     109              :         }
     110              : 
     111         8898 :         public override bool compatible (DataType target_type) {
     112         8898 :                 unowned DelegateType? dt_target = target_type as DelegateType;
     113         8902 :                 if (dt_target == null) {
     114           48 :                         return false;
     115              :                 }
     116              : 
     117              :                 // trivial case
     118         8854 :                 if (delegate_symbol == dt_target.delegate_symbol) {
     119         8850 :                         return true;
     120              :                 }
     121              : 
     122           31 :                 if (delegate_symbol.has_target != dt_target.delegate_symbol.has_target) {
     123           48 :                         return false;
     124              :                 }
     125              : 
     126              :                 // target-delegate is allowed to ensure stricter return type (stronger postcondition)
     127           30 :                 if (!get_return_type ().stricter (dt_target.get_return_type ().get_actual_type (dt_target, null, this))) {
     128           48 :                         return false;
     129              :                 }
     130              : 
     131           30 :                 var parameters = get_parameters ();
     132           30 :                 Iterator<Parameter> params_it = parameters.iterator ();
     133              : 
     134           50 :                 if (dt_target.delegate_symbol.parent_symbol is Signal && dt_target.delegate_symbol.sender_type != null && parameters.size == dt_target.get_parameters ().size + 1) {
     135              :                         // target-delegate has sender parameter
     136           20 :                         params_it.next ();
     137              : 
     138              :                         // target-delegate is allowed to accept arguments of looser types (weaker precondition)
     139           20 :                         var p = params_it.get ();
     140           20 :                         if (!dt_target.delegate_symbol.sender_type.stricter (p.variable_type)) {
     141            0 :                                 return false;
     142              :                         }
     143              :                 }
     144              : 
     145           88 :                 foreach (Parameter param in dt_target.get_parameters ()) {
     146           31 :                         if (!params_it.next ()) {
     147            1 :                                 return false;
     148              :                         }
     149              : 
     150           30 :                         var p = params_it.get ();
     151           30 :                         if (p != null && (param.ellipsis || param.params_array)) {
     152            1 :                                 if (param.ellipsis != p.ellipsis || param.params_array != p.params_array) {
     153            0 :                                         return false;
     154              :                                 }
     155            1 :                                 break;
     156              :                         }
     157              : 
     158              :                         // target-delegate is allowed to accept arguments of looser types (weaker precondition)
     159           29 :                         if (!param.variable_type.get_actual_type (this, null, this).stricter (p.variable_type)) {
     160            0 :                                 return false;
     161              :                         }
     162              :                 }
     163              : 
     164              :                 /* target-delegate may not expect more arguments */
     165           29 :                 if (params_it.next ()) {
     166            0 :                         return false;
     167              :                 }
     168              : 
     169              :                 // target-delegate may throw less but not more errors than the delegate
     170           29 :                 var error_types = new ArrayList<DataType> ();
     171           29 :                 delegate_symbol.get_error_types (error_types);
     172           29 :                 foreach (DataType error_type in error_types) {
     173            2 :                         bool match = false;
     174            2 :                         var delegate_error_types = new ArrayList<DataType> ();
     175            2 :                         dt_target.delegate_symbol.get_error_types (delegate_error_types);
     176            6 :                         foreach (DataType delegate_error_type in delegate_error_types) {
     177            2 :                                 if (error_type.compatible (delegate_error_type)) {
     178            0 :                                         match = true;
     179            0 :                                         break;
     180              :                                 }
     181              :                         }
     182              : 
     183            0 :                         if (!match) {
     184            2 :                                 return false;
     185              :                         }
     186              :                 }
     187              : 
     188           27 :                 return true;
     189              :         }
     190              : 
     191        19125 :         public override bool is_disposable () {
     192        19125 :                 return delegate_symbol.has_target && value_owned && !is_called_once;
     193              :         }
     194              : }
        

Generated by: LCOV version 2.0-1