class Puppet::Pops::Types::PInitType
@api public
Constants
- DEFAULT
- EXACTLY_ONE
Attributes
init_args[R]
Public Class Methods
create(scope, value, func)
click to toggle source
# File lib/puppet/pops/types/p_init_type.rb 92 def self.create(scope, value, func) 93 func.call(scope, @target_type, value) 94 end
from_array(scope, value, func)
click to toggle source
# File lib/puppet/pops/types/p_init_type.rb 96 def self.from_array(scope, value, func) 97 # If there is a single argument that matches the array, then that gets priority over 98 # expanding the array into all arguments 99 if @single_type.instance?(value) || (@other_type && !@other_type.instance?(value) && @has_optional_single && @other_type.instance?([value])) 100 func.call(scope, @target_type, value) 101 else 102 func.call(scope, @target_type, *value) 103 end 104 end
new(type, init_args)
click to toggle source
Calls superclass method
# File lib/puppet/pops/types/p_init_type.rb 21 def initialize(type, init_args) 22 super(type) 23 @init_args = init_args.nil? ? EMPTY_ARRAY : init_args 24 25 if type.nil? 26 raise ArgumentError, _('Init cannot be parameterized with an undefined type and additional arguments') unless @init_args.empty? 27 @initialized = true 28 else 29 @initialized = false 30 end 31 end
register_ptype(loader, ir)
click to toggle source
# File lib/puppet/pops/types/p_init_type.rb 6 def self.register_ptype(loader, ir) 7 create_ptype(loader, ir, 'AnyType', 8 'type' => { 9 KEY_TYPE => POptionalType.new(PTypeType::DEFAULT), 10 KEY_VALUE => nil 11 }, 12 'init_args' => { 13 KEY_TYPE => PArrayType::DEFAULT, 14 KEY_VALUE => EMPTY_ARRAY 15 } 16 ) 17 end
Public Instance Methods
accept(visitor, guard)
click to toggle source
Calls superclass method
# File lib/puppet/pops/types/p_init_type.rb 201 def accept(visitor, guard) 202 guarded_recursion(guard, nil) do |g| 203 super(visitor, g) 204 @single_type.accept(visitor, guard) if @single_type 205 @other_type.accept(visitor, guard) if @other_type 206 end 207 end
assert_initialized()
click to toggle source
# File lib/puppet/pops/types/p_init_type.rb 140 def assert_initialized 141 return self if @initialized 142 143 @initialized = true 144 @self_recursion = true 145 146 begin 147 # Filter out types that will provide a new_function but are unsuitable to be contained in Init 148 # 149 # Calling Init#new would cause endless recursion 150 # The Optional is the same as Variant[T,Undef]. 151 # The NotUndef is not meaningful to create instances of 152 if @type.instance_of?(PInitType) || @type.instance_of?(POptionalType) || @type.instance_of?(PNotUndefType) 153 raise ArgumentError.new 154 end 155 new_func = @type.new_function 156 rescue ArgumentError 157 raise ArgumentError, _("Creation of new instance of type '%{type_name}' is not supported") % { type_name: @type.to_s } 158 end 159 param_tuples = new_func.dispatcher.signatures.map { |closure| closure.type.param_types } 160 161 # An instance of the contained type is always a match to this type. 162 single_types = [@type] 163 164 if @init_args.empty? 165 # A value that is assignable to the type of a single parameter is also a match 166 single_tuples, other_tuples = param_tuples.partition { |tuple| EXACTLY_ONE == tuple.size_range } 167 single_types.concat(single_tuples.map { |tuple| tuple.types[0] }) 168 else 169 tc = TypeCalculator.singleton 170 init_arg_types = @init_args.map { |arg| tc.infer_set(arg) } 171 arg_count = 1 + init_arg_types.size 172 173 # disqualify all parameter tuples that doesn't allow one value (type unknown at ths stage) + init args. 174 param_tuples = param_tuples.select do |tuple| 175 min, max = tuple.size_range 176 if arg_count >= min && arg_count <= max 177 # Aside from the first parameter, does the other parameters match? 178 tuple.assignable?(PTupleType.new(tuple.types[0..0].concat(init_arg_types))) 179 else 180 false 181 end 182 end 183 if param_tuples.empty? 184 raise ArgumentError, _("The type '%{type}' does not represent a valid set of parameters for %{subject}.new()") % 185 { type: to_s, subject: @type.generalize.name } 186 end 187 single_types.concat(param_tuples.map { |tuple| tuple.types[0] }) 188 other_tuples = EMPTY_ARRAY 189 end 190 @single_type = PVariantType.maybe_create(single_types) 191 unless other_tuples.empty? 192 @other_type = PVariantType.maybe_create(other_tuples) 193 @has_optional_single = other_tuples.any? { |tuple| tuple.size_range.min == 1 } 194 end 195 196 guard = RecursionGuard.new 197 accept(NoopTypeAcceptor::INSTANCE, guard) 198 @self_recursion = guard.recursive_this?(self) 199 end
create(scope, value)
click to toggle source
# File lib/puppet/pops/types/p_init_type.rb 110 def create(scope, value) 111 self.class.create(scope, value, loader.load(:function, 'new')) 112 end
eql?(o)
click to toggle source
Calls superclass method
# File lib/puppet/pops/types/p_init_type.rb 63 def eql?(o) 64 super && @init_args == o.init_args 65 end
from_array(scope, value)
click to toggle source
# File lib/puppet/pops/types/p_init_type.rb 106 def from_array(scope, value) 107 self.class.from_array(scope, value, loader.load(:function, 'new')) 108 end
hash()
click to toggle source
Calls superclass method
# File lib/puppet/pops/types/p_init_type.rb 67 def hash 68 super ^ @init_args.hash 69 end
instance?(o, guard = nil)
click to toggle source
# File lib/puppet/pops/types/p_init_type.rb 33 def instance?(o, guard = nil) 34 really_instance?(o, guard) == 1 35 end
new_function()
click to toggle source
Calls superclass method
# File lib/puppet/pops/types/p_init_type.rb 71 def new_function 72 return super if type.nil? 73 assert_initialized 74 75 target_type = type 76 single_type = @single_type 77 if @init_args.empty? 78 @new_function ||= Puppet::Functions.create_function(:new_Init, Puppet::Functions::InternalFunction) do 79 @target_type = target_type 80 @single_type = single_type 81 82 dispatch :from_array do 83 scope_param 84 param 'Array', :value 85 end 86 87 dispatch :create do 88 scope_param 89 param 'Any', :value 90 end 91 92 def self.create(scope, value, func) 93 func.call(scope, @target_type, value) 94 end 95 96 def self.from_array(scope, value, func) 97 # If there is a single argument that matches the array, then that gets priority over 98 # expanding the array into all arguments 99 if @single_type.instance?(value) || (@other_type && !@other_type.instance?(value) && @has_optional_single && @other_type.instance?([value])) 100 func.call(scope, @target_type, value) 101 else 102 func.call(scope, @target_type, *value) 103 end 104 end 105 106 def from_array(scope, value) 107 self.class.from_array(scope, value, loader.load(:function, 'new')) 108 end 109 110 def create(scope, value) 111 self.class.create(scope, value, loader.load(:function, 'new')) 112 end 113 end 114 else 115 init_args = @init_args 116 @new_function ||= Puppet::Functions.create_function(:new_Init, Puppet::Functions::InternalFunction) do 117 @target_type = target_type 118 @init_args = init_args 119 120 dispatch :create do 121 scope_param 122 param 'Any', :value 123 end 124 125 def self.create(scope, value, func) 126 func.call(scope, @target_type, value, *@init_args) 127 end 128 129 def create(scope, value) 130 self.class.create(scope, value, loader.load(:function, 'new')) 131 end 132 end 133 end 134 end
really_instance?(o, guard = nil)
click to toggle source
@api private
# File lib/puppet/pops/types/p_init_type.rb 38 def really_instance?(o, guard = nil) 39 if @type.nil? 40 TypeFactory.rich_data.really_instance?(o) 41 else 42 assert_initialized 43 guarded_recursion(guard, 0) do |g| 44 v = @type.really_instance?(o, g) 45 if v < 1 46 if @single_type 47 s = @single_type.really_instance?(o, g) 48 v = s if s > v 49 end 50 end 51 if v < 1 52 if @other_type 53 s = @other_type.really_instance?(o, g) 54 s = @other_type.really_instance?([o], g) if s < 0 && @has_optional_single 55 v = s if s > v 56 end 57 end 58 v 59 end 60 end 61 end
Protected Instance Methods
_assignable?(o, guard)
click to toggle source
# File lib/puppet/pops/types/p_init_type.rb 211 def _assignable?(o, guard) 212 guarded_recursion(guard, false) do |g| 213 assert_initialized 214 if o.is_a?(PInitType) 215 @type.nil? || @type.assignable?(o.type, g) 216 elsif @type.nil? 217 TypeFactory.rich_data.assignable?(o, g) 218 else 219 @type.assignable?(o, g) || 220 @single_type && @single_type.assignable?(o, g) || 221 @other_type && (@other_type.assignable?(o, g) || @has_optional_single && @other_type.assignable?(PTupleType.new([o]))) 222 end 223 end 224 end
Private Instance Methods
guarded_recursion(guard, dflt) { |guard| ... }
click to toggle source
# File lib/puppet/pops/types/p_init_type.rb 228 def guarded_recursion(guard, dflt) 229 if @self_recursion 230 guard ||= RecursionGuard.new 231 guard.with_this(self) { |state| (state & RecursionGuard::SELF_RECURSION_IN_THIS) == 0 ? yield(guard) : dflt } 232 else 233 yield(guard) 234 end 235 end