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