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
- #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(type_parser, 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?, #generalize, new_function, #normalize, #simple_name, simple_name, #to_alias_expanded_s
Methods inherited from TypedModelObject
_ptype, create_ptype, register_ptypes
Methods included from PuppetObject
Constructor Details
#initialize(name, type_expr, resolved_type = nil) ⇒ PTypeAliasType
Returns a new instance of PTypeAliasType.
3010 3011 3012 3013 3014 3015 |
# File 'lib/puppet/pops/types/types.rb', line 3010 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
3177 3178 3179 3180 |
# File 'lib/puppet/pops/types/types.rb', line 3177 def method_missing(name, *arguments, &block) super if @resolved_type.equal?(PTypeReferenceType::DEFAULT) resolved_type.send(name, *arguments, &block) end |
Instance Attribute Details
#name ⇒ Object (readonly)
3005 3006 3007 |
# File 'lib/puppet/pops/types/types.rb', line 3005 def name @name end |
Class Method Details
.register_ptype(loader, ir) ⇒ Object
2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 |
# File 'lib/puppet/pops/types/types.rb', line 2994 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(PType::DEFAULT), KEY_VALUE => nil } ) end |
Instance Method Details
#accept(visitor, guard) ⇒ Object
3152 3153 3154 3155 3156 3157 |
# File 'lib/puppet/pops/types/types.rb', line 3152 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
3017 3018 3019 3020 3021 3022 3023 |
# File 'lib/puppet/pops/types/types.rb', line 3017 def assignable?(o, guard = nil) if @self_recursion guard ||= RecursionGuard.new return true if guard.add_this(self) == RecursionGuard::SELF_RECURSION_IN_BOTH end super(o, guard) end |
#callable_args?(callable, guard) ⇒ Boolean
3035 3036 3037 |
# File 'lib/puppet/pops/types/types.rb', line 3035 def callable_args?(callable, guard) guarded_recursion(guard, false) { |g| resolved_type.callable_args?(callable, g) } end |
#check_self_recursion(originator) ⇒ Object
3039 3040 3041 |
# File 'lib/puppet/pops/types/types.rb', line 3039 def check_self_recursion(originator) resolved_type.check_self_recursion(originator) unless originator.equal?(self) end |
#eql?(o) ⇒ Boolean
3148 3149 3150 |
# File 'lib/puppet/pops/types/types.rb', line 3148 def eql?(o) super && o.name == @name end |
#hash ⇒ Object
3059 3060 3061 |
# File 'lib/puppet/pops/types/types.rb', line 3059 def hash @name.hash end |
#instance?(o, guard = nil) ⇒ Boolean
3047 3048 3049 |
# File 'lib/puppet/pops/types/types.rb', line 3047 def instance?(o, guard = nil) really_instance?(o, guard) == 1 end |
#iterable?(guard = nil) ⇒ Boolean
3051 3052 3053 |
# File 'lib/puppet/pops/types/types.rb', line 3051 def iterable?(guard = nil) guarded_recursion(guard, false) { |g| resolved_type.iterable?(g) } end |
#iterable_type(guard = nil) ⇒ Object
3055 3056 3057 |
# File 'lib/puppet/pops/types/types.rb', line 3055 def iterable_type(guard = nil) guarded_recursion(guard, nil) { |g| resolved_type.iterable_type(g) } end |
#kind_of_callable?(optional = true, guard = nil) ⇒ Boolean
3043 3044 3045 |
# File 'lib/puppet/pops/types/types.rb', line 3043 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.
3183 3184 3185 3186 3187 3188 3189 3190 |
# File 'lib/puppet/pops/types/types.rb', line 3183 def really_instance?(o, guard = nil) if @self_recursion guard ||= RecursionGuard.new guard.add_that(o) return 0 if guard.add_this(self) == RecursionGuard::SELF_RECURSION_IN_BOTH end resolved_type.really_instance?(o, guard) end |
#resolve(type_parser, 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.
3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 |
# File 'lib/puppet/pops/types/types.rb', line 3109 def resolve(type_parser, 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(type_parser, loader) else @resolved_type = type_parser.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(type_parser, 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.
3030 3031 3032 3033 |
# File 'lib/puppet/pops/types/types.rb', line 3030 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
3172 3173 3174 |
# File 'lib/puppet/pops/types/types.rb', line 3172 def respond_to_missing?(name, include_private) resolved_type.respond_to?(name, include_private) end |
#self_recursion? ⇒ Boolean
3159 3160 3161 |
# File 'lib/puppet/pops/types/types.rb', line 3159 def self_recursion? @self_recursion end |
#set_self_recursion_status ⇒ Object
3092 3093 3094 3095 3096 3097 3098 3099 |
# File 'lib/puppet/pops/types/types.rb', line 3092 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>
3167 3168 3169 |
# File 'lib/puppet/pops/types/types.rb', line 3167 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.
3194 3195 3196 |
# File 'lib/puppet/pops/types/types.rb', line 3194 def type_expr nil end |