Class: Puppet::Pops::Types::PInitType
- Inherits:
-
PTypeWithContainedType
- Object
- TypedModelObject
- PAnyType
- PTypeWithContainedType
- Puppet::Pops::Types::PInitType
- Defined in:
- lib/puppet/pops/types/p_init_type.rb
Constant Summary collapse
- DEFAULT =
PInitType.new(nil, EMPTY_ARRAY)
- EXACTLY_ONE =
[1, 1].freeze
Instance Attribute Summary collapse
- #init_args ⇒ Object readonly
Attributes inherited from PTypeWithContainedType
Class Method Summary collapse
Instance Method Summary collapse
- #accept(visitor, guard) ⇒ Object
- #assert_initialized ⇒ Object
- #eql?(o) ⇒ Boolean
- #hash ⇒ Object
-
#initialize(type, init_args) ⇒ PInitType
constructor
A new instance of PInitType.
- #instance?(o, guard = nil) ⇒ Boolean
- #new_function ⇒ Object
- #really_instance?(o, guard = nil) ⇒ Boolean private
Methods inherited from PTypeWithContainedType
#generalize, #normalize, #resolve
Methods inherited from PAnyType
#==, #assignable?, #callable?, #callable_args?, #callable_with?, #check_self_recursion, create, #create, #generalize, #iterable?, #iterable_type, #kind_of_callable?, #loader, #name, new_function, #normalize, #resolve, #roundtrip_with_string?, #simple_name, simple_name, #to_alias_expanded_s, #to_s
Methods inherited from TypedModelObject
_pcore_type, create_ptype, register_ptypes
Methods included from PuppetObject
#_pcore_all_contents, #_pcore_contents, #_pcore_init_hash, #_pcore_type, #to_s
Constructor Details
#initialize(type, init_args) ⇒ PInitType
Returns a new instance of PInitType.
21 22 23 24 25 26 27 28 29 30 31 32 |
# File 'lib/puppet/pops/types/p_init_type.rb', line 21 def initialize(type, init_args) super(type) @init_args = init_args.nil? ? EMPTY_ARRAY : init_args if type.nil? raise ArgumentError, _('Init cannot be parameterized with an undefined type and additional arguments') unless @init_args.empty? @initialized = true else @initialized = false end end |
Instance Attribute Details
#init_args ⇒ Object (readonly)
19 20 21 |
# File 'lib/puppet/pops/types/p_init_type.rb', line 19 def init_args @init_args end |
Class Method Details
.register_ptype(loader, ir) ⇒ Object
7 8 9 10 11 12 13 14 15 16 17 |
# File 'lib/puppet/pops/types/p_init_type.rb', line 7 def self.register_ptype(loader, ir) create_ptype(loader, ir, 'AnyType', 'type' => { KEY_TYPE => POptionalType.new(PTypeType::DEFAULT), KEY_VALUE => nil }, 'init_args' => { KEY_TYPE => PArrayType::DEFAULT, KEY_VALUE => EMPTY_ARRAY }) end |
Instance Method Details
#accept(visitor, guard) ⇒ Object
204 205 206 207 208 209 210 |
# File 'lib/puppet/pops/types/p_init_type.rb', line 204 def accept(visitor, guard) guarded_recursion(guard, nil) do |g| super(visitor, g) @single_type.accept(visitor, guard) if @single_type @other_type.accept(visitor, guard) if @other_type end end |
#assert_initialized ⇒ Object
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 |
# File 'lib/puppet/pops/types/p_init_type.rb', line 142 def assert_initialized return self if @initialized @initialized = true @self_recursion = true begin # Filter out types that will provide a new_function but are unsuitable to be contained in Init # # Calling Init#new would cause endless recursion # The Optional is the same as Variant[T,Undef]. # The NotUndef is not meaningful to create instances of if @type.instance_of?(PInitType) || @type.instance_of?(POptionalType) || @type.instance_of?(PNotUndefType) raise ArgumentError end new_func = @type.new_function rescue ArgumentError raise ArgumentError, _("Creation of new instance of type '%{type_name}' is not supported") % { type_name: @type.to_s } end param_tuples = new_func.dispatcher.signatures.map { |closure| closure.type.param_types } # An instance of the contained type is always a match to this type. single_types = [@type] if @init_args.empty? # A value that is assignable to the type of a single parameter is also a match single_tuples, other_tuples = param_tuples.partition { |tuple| EXACTLY_ONE == tuple.size_range } single_types.concat(single_tuples.map { |tuple| tuple.types[0] }) else tc = TypeCalculator.singleton init_arg_types = @init_args.map { |arg| tc.infer_set(arg) } arg_count = 1 + init_arg_types.size # disqualify all parameter tuples that doesn't allow one value (type unknown at ths stage) + init args. param_tuples = param_tuples.select do |tuple| min, max = tuple.size_range if arg_count >= min && arg_count <= max # Aside from the first parameter, does the other parameters match? tuple.assignable?(PTupleType.new(tuple.types[0..0].concat(init_arg_types))) else false end end if param_tuples.empty? raise ArgumentError, _("The type '%{type}' does not represent a valid set of parameters for %{subject}.new()") % { type: to_s, subject: @type.generalize.name } end single_types.concat(param_tuples.map { |tuple| tuple.types[0] }) other_tuples = EMPTY_ARRAY end @single_type = PVariantType.maybe_create(single_types) unless other_tuples.empty? @other_type = PVariantType.maybe_create(other_tuples) @has_optional_single = other_tuples.any? { |tuple| tuple.size_range.min == 1 } end guard = RecursionGuard.new accept(NoopTypeAcceptor::INSTANCE, guard) @self_recursion = guard.recursive_this?(self) end |
#eql?(o) ⇒ Boolean
64 65 66 |
# File 'lib/puppet/pops/types/p_init_type.rb', line 64 def eql?(o) super && @init_args == o.init_args end |
#hash ⇒ Object
68 69 70 |
# File 'lib/puppet/pops/types/p_init_type.rb', line 68 def hash super ^ @init_args.hash end |
#instance?(o, guard = nil) ⇒ Boolean
34 35 36 |
# File 'lib/puppet/pops/types/p_init_type.rb', line 34 def instance?(o, guard = nil) really_instance?(o, guard) == 1 end |
#new_function ⇒ Object
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
# File 'lib/puppet/pops/types/p_init_type.rb', line 72 def new_function return super if type.nil? assert_initialized target_type = type single_type = @single_type if @init_args.empty? @new_function ||= Puppet::Functions.create_function(:new_Init, Puppet::Functions::InternalFunction) do @target_type = target_type @single_type = single_type dispatch :from_array do scope_param param 'Array', :value end dispatch :create do scope_param param 'Any', :value end def self.create(scope, value, func) func.call(scope, @target_type, value) end def self.from_array(scope, value, func) # If there is a single argument that matches the array, then that gets priority over # expanding the array into all arguments if @single_type.instance?(value) || (@other_type && !@other_type.instance?(value) && @has_optional_single && @other_type.instance?([value])) func.call(scope, @target_type, value) else func.call(scope, @target_type, *value) end end def from_array(scope, value) self.class.from_array(scope, value, loader.load(:function, 'new')) end def create(scope, value) self.class.create(scope, value, loader.load(:function, 'new')) end end else init_args = @init_args @new_function ||= Puppet::Functions.create_function(:new_Init, Puppet::Functions::InternalFunction) do @target_type = target_type @init_args = init_args dispatch :create do scope_param param 'Any', :value end def self.create(scope, value, func) func.call(scope, @target_type, value, *@init_args) end def create(scope, value) self.class.create(scope, value, loader.load(:function, 'new')) end end end end |
#really_instance?(o, guard = nil) ⇒ Boolean
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
# File 'lib/puppet/pops/types/p_init_type.rb', line 39 def really_instance?(o, guard = nil) if @type.nil? TypeFactory.rich_data.really_instance?(o) else assert_initialized guarded_recursion(guard, 0) do |g| v = @type.really_instance?(o, g) if v < 1 if @single_type s = @single_type.really_instance?(o, g) v = s if s > v end end if v < 1 if @other_type s = @other_type.really_instance?(o, g) s = @other_type.really_instance?([o], g) if s < 0 && @has_optional_single v = s if s > v end end v end end end |