Class: Puppet::Pops::Types::PTypeAliasType
- Inherits:
-
PAnyType
- Object
- TypedModelObject
- PAnyType
- Puppet::Pops::Types::PTypeAliasType
- Defined in:
- lib/puppet/pops/types/types.rb
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
- #loader ⇒ Object readonly
- #name ⇒ Object readonly
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
Methods inherited from TypedModelObject
_pcore_type, create_ptype, register_ptypes
Methods included from PuppetObject
#_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.
3370 3371 3372 3373 3374 3375 |
# File 'lib/puppet/pops/types/types.rb', line 3370 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
3539 3540 3541 3542 |
# File 'lib/puppet/pops/types/types.rb', line 3539 def method_missing(name, *arguments, &block) super if @resolved_type.equal?(PTypeReferenceType::DEFAULT) resolved_type.send(name, *arguments, &block) end |
Instance Attribute Details
#loader ⇒ Object (readonly)
3365 3366 3367 |
# File 'lib/puppet/pops/types/types.rb', line 3365 def loader @loader end |
#name ⇒ Object (readonly)
3365 3366 3367 |
# File 'lib/puppet/pops/types/types.rb', line 3365 def name @name end |
Class Method Details
.register_ptype(loader, ir) ⇒ Object
3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 |
# File 'lib/puppet/pops/types/types.rb', line 3354 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
3514 3515 3516 3517 3518 3519 |
# File 'lib/puppet/pops/types/types.rb', line 3514 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
3377 3378 3379 3380 3381 3382 3383 3384 |
# File 'lib/puppet/pops/types/types.rb', line 3377 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
3396 3397 3398 |
# File 'lib/puppet/pops/types/types.rb', line 3396 def callable_args?(callable, guard) guarded_recursion(guard, false) { |g| resolved_type.callable_args?(callable, g) } end |
#check_self_recursion(originator) ⇒ Object
3400 3401 3402 |
# File 'lib/puppet/pops/types/types.rb', line 3400 def check_self_recursion(originator) resolved_type.check_self_recursion(originator) unless originator.equal?(self) end |
#eql?(o) ⇒ Boolean
3510 3511 3512 |
# File 'lib/puppet/pops/types/types.rb', line 3510 def eql?(o) super && o.name == @name end |
#hash ⇒ Object
3420 3421 3422 |
# File 'lib/puppet/pops/types/types.rb', line 3420 def hash @name.hash end |
#instance?(o, guard = nil) ⇒ Boolean
3408 3409 3410 |
# File 'lib/puppet/pops/types/types.rb', line 3408 def instance?(o, guard = nil) really_instance?(o, guard) == 1 end |
#iterable?(guard = nil) ⇒ Boolean
3412 3413 3414 |
# File 'lib/puppet/pops/types/types.rb', line 3412 def iterable?(guard = nil) guarded_recursion(guard, false) { |g| resolved_type.iterable?(g) } end |
#iterable_type(guard = nil) ⇒ Object
3416 3417 3418 |
# File 'lib/puppet/pops/types/types.rb', line 3416 def iterable_type(guard = nil) guarded_recursion(guard, nil) { |g| resolved_type.iterable_type(g) } end |
#kind_of_callable?(optional = true, guard = nil) ⇒ Boolean
3404 3405 3406 |
# File 'lib/puppet/pops/types/types.rb', line 3404 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.
3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 |
# File 'lib/puppet/pops/types/types.rb', line 3545 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 |
#resolve(loader) ⇒ PTypeAliasType
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.
3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495 3496 3497 3498 3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 |
# File 'lib/puppet/pops/types/types.rb', line 3470 def resolve(loader) @loader = loader if @resolved_type.nil? # resolved to PTypeReferenceType::DEFAULT during resolve to avoid endless recursion @resolved_type = PTypeReferenceType::DEFAULT @self_recursion = true # assumed while it being found out below begin if @type_expr.is_a?(PTypeReferenceType) @resolved_type = @type_expr.resolve(loader) else @resolved_type = TypeParser.singleton.interpret(@type_expr, loader).normalize end # Find out if this type is recursive. A recursive type has performance implications # on several methods and this knowledge is used to avoid that for non-recursive # types. 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) # All aliases involved must re-check status since this alias is now resolved if @self_recursion accept(AssertSelfRecursionStatusAcceptor.new, RecursionGuard.new) when_self_recursion_detected end rescue @resolved_type = nil raise end else # An alias may appoint an Object type that isn't resolved yet. The default type # reference is used to prevent endless recursion and should not be resolved here. @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.
3391 3392 3393 3394 |
# File 'lib/puppet/pops/types/types.rb', line 3391 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
3534 3535 3536 |
# File 'lib/puppet/pops/types/types.rb', line 3534 def respond_to_missing?(name, include_private) resolved_type.respond_to?(name, include_private) end |
#self_recursion? ⇒ Boolean
3521 3522 3523 |
# File 'lib/puppet/pops/types/types.rb', line 3521 def self_recursion? @self_recursion end |
#set_self_recursion_status ⇒ Object
3453 3454 3455 3456 3457 3458 3459 3460 |
# File 'lib/puppet/pops/types/types.rb', line 3453 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 # no difference end |
#to_s ⇒ String
Returns the expanded string the form of the alias, e.g. <alias name> = <resolved type>
3529 3530 3531 |
# File 'lib/puppet/pops/types/types.rb', line 3529 def to_s TypeFormatter.singleton.(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.
3558 3559 3560 |
# File 'lib/puppet/pops/types/types.rb', line 3558 def type_expr nil end |