Class: Puppet::Pops::Types::PTypeAliasType
Overview
Describes a named alias for another Type. The alias is created with a name and an unresolved type expression. The type expression may in turn contain other aliases (including the alias that contains it) which means that an alias might contain self recursion. Whether or not that is the case is computed and remembered when the alias is resolved since guarding against self recursive constructs is relatively expensive.
Defined Under Namespace
Classes: AssertOtherTypeAcceptor, AssertSelfRecursionStatusAcceptor
Instance Attribute Summary collapse
Class Method Summary
collapse
Instance Method Summary
collapse
-
#accept(visitor, guard) ⇒ Object
-
#assignable?(o, guard = nil) ⇒ Boolean
-
#callable_args?(callable, guard) ⇒ Boolean
-
#check_self_recursion(originator) ⇒ Object
-
#eql?(o) ⇒ Boolean
-
#hash ⇒ Object
-
#initialize(name, type_expr, resolved_type = nil) ⇒ PTypeAliasType
constructor
A new instance of PTypeAliasType.
-
#instance?(o, guard = nil) ⇒ Boolean
-
#iterable?(guard = nil) ⇒ Boolean
-
#iterable_type(guard = nil) ⇒ Object
-
#kind_of_callable?(optional = true, guard = nil) ⇒ Boolean
-
#method_missing(name, *arguments, &block) ⇒ Object
Delegates to resolved type.
-
#really_instance?(o, guard = nil) ⇒ Boolean
private
-
#resolve(loader) ⇒ PTypeAliasType
private
Called from the TypeParser once it has found a type using the Loader.
-
#resolved_type ⇒ PAnyType
Returns the resolved type.
-
#respond_to_missing?(name, include_private) ⇒ Boolean
Delegates to resolved type.
-
#self_recursion? ⇒ Boolean
-
#set_self_recursion_status ⇒ Object
-
#to_s ⇒ String
Returns the expanded string the form of the alias, e.g.
-
#type_expr ⇒ Object
private
nil to prevent serialization of the type_expr used when first initializing this instance.
Methods inherited from PAnyType
#==, #callable?, #callable_with?, create, #create, #generalize, new_function, #normalize, #roundtrip_with_string?, #simple_name, simple_name, #to_alias_expanded_s
_pcore_type, create_ptype, register_ptypes
#_pcore_all_contents, #_pcore_contents, #_pcore_init_hash, #_pcore_type
Constructor Details
#initialize(name, type_expr, resolved_type = nil) ⇒ PTypeAliasType
Returns a new instance of PTypeAliasType.
3251
3252
3253
3254
3255
3256
|
# File 'lib/puppet/pops/types/types.rb', line 3251
def initialize(name, type_expr, resolved_type = nil)
@name = name
@type_expr = type_expr
@resolved_type = resolved_type
@self_recursion = false
end
|
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(name, *arguments, &block) ⇒ Object
Delegates to resolved type
3420
3421
3422
3423
|
# File 'lib/puppet/pops/types/types.rb', line 3420
def method_missing(name, *arguments, &block)
super if @resolved_type.equal?(PTypeReferenceType::DEFAULT)
resolved_type.send(name, *arguments, &block)
end
|
Instance Attribute Details
3246
3247
3248
|
# File 'lib/puppet/pops/types/types.rb', line 3246
def loader
@loader
end
|
3246
3247
3248
|
# File 'lib/puppet/pops/types/types.rb', line 3246
def name
@name
end
|
Class Method Details
.register_ptype(loader, ir) ⇒ Object
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
|
# File 'lib/puppet/pops/types/types.rb', line 3235
def self.register_ptype(loader, ir)
create_ptype(loader, ir, 'AnyType',
'name' => PStringType::NON_EMPTY,
'type_expr' => PAnyType::DEFAULT,
'resolved_type' => {
KEY_TYPE => POptionalType.new(PTypeType::DEFAULT),
KEY_VALUE => nil
}
)
end
|
Instance Method Details
#accept(visitor, guard) ⇒ Object
3395
3396
3397
3398
3399
3400
|
# File 'lib/puppet/pops/types/types.rb', line 3395
def accept(visitor, guard)
guarded_recursion(guard, nil) do |g|
super(visitor, g)
@resolved_type.accept(visitor, g) unless @resolved_type.nil?
end
end
|
#assignable?(o, guard = nil) ⇒ Boolean
3258
3259
3260
3261
3262
3263
3264
3265
|
# File 'lib/puppet/pops/types/types.rb', line 3258
def assignable?(o, guard = nil)
if @self_recursion
guard ||= RecursionGuard.new
guard.with_this(self) { |state| state == RecursionGuard::SELF_RECURSION_IN_BOTH ? true : super(o, guard) }
else
super(o, guard)
end
end
|
#callable_args?(callable, guard) ⇒ Boolean
3277
3278
3279
|
# File 'lib/puppet/pops/types/types.rb', line 3277
def callable_args?(callable, guard)
guarded_recursion(guard, false) { |g| resolved_type.callable_args?(callable, g) }
end
|
#check_self_recursion(originator) ⇒ Object
3281
3282
3283
|
# File 'lib/puppet/pops/types/types.rb', line 3281
def check_self_recursion(originator)
resolved_type.check_self_recursion(originator) unless originator.equal?(self)
end
|
#eql?(o) ⇒ Boolean
3391
3392
3393
|
# File 'lib/puppet/pops/types/types.rb', line 3391
def eql?(o)
super && o.name == @name
end
|
3301
3302
3303
|
# File 'lib/puppet/pops/types/types.rb', line 3301
def hash
@name.hash
end
|
#instance?(o, guard = nil) ⇒ Boolean
3289
3290
3291
|
# File 'lib/puppet/pops/types/types.rb', line 3289
def instance?(o, guard = nil)
really_instance?(o, guard) == 1
end
|
#iterable?(guard = nil) ⇒ Boolean
3293
3294
3295
|
# File 'lib/puppet/pops/types/types.rb', line 3293
def iterable?(guard = nil)
guarded_recursion(guard, false) { |g| resolved_type.iterable?(g) }
end
|
#iterable_type(guard = nil) ⇒ Object
3297
3298
3299
|
# File 'lib/puppet/pops/types/types.rb', line 3297
def iterable_type(guard = nil)
guarded_recursion(guard, nil) { |g| resolved_type.iterable_type(g) }
end
|
#kind_of_callable?(optional = true, guard = nil) ⇒ Boolean
3285
3286
3287
|
# File 'lib/puppet/pops/types/types.rb', line 3285
def kind_of_callable?(optional=true, guard = nil)
guarded_recursion(guard, false) { |g| resolved_type.kind_of_callable?(optional, g) }
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.
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
|
# File 'lib/puppet/pops/types/types.rb', line 3426
def really_instance?(o, guard = nil)
if @self_recursion
guard ||= RecursionGuard.new
guard.with_that(o) do
guard.with_this(self) { |state| state == RecursionGuard::SELF_RECURSION_IN_BOTH ? 0 : resolved_type.really_instance?(o, guard) }
end
else
resolved_type.really_instance?(o, guard)
end
end
|
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.
Called from the TypeParser once it has found a type using the Loader. The TypeParser will interpret the contained expression and the resolved type is remembered. This method also checks and remembers if the resolve type contains self recursion.
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
|
# File 'lib/puppet/pops/types/types.rb', line 3351
def resolve(loader)
@loader = loader
if @resolved_type.nil?
@resolved_type = PTypeReferenceType::DEFAULT
@self_recursion = true
begin
if @type_expr.is_a?(PTypeReferenceType)
@resolved_type = @type_expr.resolve(loader)
else
@resolved_type = TypeParser.singleton.interpret(@type_expr, loader).normalize
end
guard = RecursionGuard.new
real_type_asserter = AssertOtherTypeAcceptor.new
accept(real_type_asserter, guard)
unless real_type_asserter.other_type_detected?
raise ArgumentError, "Type alias '#{name}' cannot be resolved to a real type"
end
@self_recursion = guard.recursive_this?(self)
if @self_recursion
accept(AssertSelfRecursionStatusAcceptor.new, RecursionGuard.new)
when_self_recursion_detected
end
rescue
@resolved_type = nil
raise
end
else
@resolved_type.resolve(loader) unless @resolved_type.equal?(PTypeReferenceType::DEFAULT)
end
self
end
|
#resolved_type ⇒ PAnyType
Returns the resolved type. The type must have been resolved by a call prior to calls to this method or an error will be raised.
3272
3273
3274
3275
|
# File 'lib/puppet/pops/types/types.rb', line 3272
def resolved_type
raise Puppet::Error, "Reference to unresolved type #{@name}" unless @resolved_type
@resolved_type
end
|
#respond_to_missing?(name, include_private) ⇒ Boolean
Delegates to resolved type
3415
3416
3417
|
# File 'lib/puppet/pops/types/types.rb', line 3415
def respond_to_missing?(name, include_private)
resolved_type.respond_to?(name, include_private)
end
|
#self_recursion? ⇒ Boolean
3402
3403
3404
|
# File 'lib/puppet/pops/types/types.rb', line 3402
def self_recursion?
@self_recursion
end
|
#set_self_recursion_status ⇒ Object
3334
3335
3336
3337
3338
3339
3340
3341
|
# File 'lib/puppet/pops/types/types.rb', line 3334
def set_self_recursion_status
return if @self_recursion || @resolved_type.is_a?(PTypeReferenceType)
@self_recursion = true
guard = RecursionGuard.new
accept(NoopTypeAcceptor::INSTANCE, guard)
@self_recursion = guard.recursive_this?(self)
when_self_recursion_detected if @self_recursion
end
|
#to_s ⇒ String
Returns the expanded string the form of the alias, e.g. <alias name> = <resolved type>
3410
3411
3412
|
# File 'lib/puppet/pops/types/types.rb', line 3410
def to_s
TypeFormatter.singleton.alias_expanded_string(self)
end
|
#type_expr ⇒ Object
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.
Returns nil to prevent serialization of the type_expr used when first initializing this instance.
3439
3440
3441
|
# File 'lib/puppet/pops/types/types.rb', line 3439
def type_expr
nil
end
|