class Puppet::Pops::Types::ImplementationRegistry
The {ImplementationRegistry} maps names types in the Puppet
Type
System to names of corresponding implementation modules/classes. Each mapping is unique and bidirectional so that for any given type name there is only one implementation and vice versa.
@api private
Constants
- TYPE_REGEXP_SUBST
Public Class Methods
Create a new instance. This method is normally only called once
@param parent [ImplementationRegistry, nil] the parent of this registry
# File lib/puppet/pops/types/implementation_registry.rb 14 def initialize(parent = nil) 15 @parent = parent 16 @type_names_per_implementation = {} 17 @implementations_per_type_name = {} 18 @type_name_substitutions = [] 19 @impl_name_substitutions = [] 20 end
Public Instance Methods
Find the module that corresponds to the given type or type name
@param type [PAnyType,String] the name of the type @return [Module,nil] the name of the implementation module, or `nil` if no mapping was found
# File lib/puppet/pops/types/implementation_registry.rb 89 def module_for_type(type) 90 name = module_name_for_type(type) 91 # TODO Shouldn't ClassLoader be module specific? 92 name.nil? ? nil : ClassLoader.provide(name) 93 end
Find the name for the module that corresponds to the given type or type name
@param type [PAnyType,String] the name of the type @return [String,nil] the name of the implementation module, or `nil` if no mapping was found
# File lib/puppet/pops/types/implementation_registry.rb 79 def module_name_for_type(type) 80 type = type.name if type.is_a?(PAnyType) 81 name = @parent.module_name_for_type(type) unless @parent.nil? 82 name.nil? ? find_mapping(type, @implementations_per_type_name, @type_name_substitutions) : name 83 end
Register a bidirectional mapping between a type and an implementation
@param type [PAnyType,String] the type or type name @param impl_module the module or module name
# File lib/puppet/pops/types/implementation_registry.rb 67 def register_implementation(type, impl_module, _ = nil) 68 type = type.name if type.is_a?(PAnyType) 69 impl_module = impl_module.name if impl_module.is_a?(Module) 70 @type_names_per_implementation[impl_module] = type 71 @implementations_per_type_name[type] = impl_module 72 nil 73 end
Register a bidirectional namespace mapping
@param type_namespace [String] the namespace for the puppet types @param impl_namespace [String] the namespace for the implementations
# File lib/puppet/pops/types/implementation_registry.rb 46 def register_implementation_namespace(type_namespace, impl_namespace, _ = nil) 47 ns = TypeFormatter::NAME_SEGMENT_SEPARATOR 48 register_implementation_regexp( 49 [/\A#{type_namespace}#{ns}(\w+)\z/, "#{impl_namespace}#{ns}\\1"], 50 [/\A#{impl_namespace}#{ns}(\w+)\z/, "#{type_namespace}#{ns}\\1"]) 51 end
Register a bidirectional regexp mapping
@param type_name_subst [Array(Regexp,String)] regexp and replacement mapping type names to runtime names @param impl_name_subst [Array(Regexp,String)] regexp and replacement mapping runtime names to type names
# File lib/puppet/pops/types/implementation_registry.rb 57 def register_implementation_regexp(type_name_subst, impl_name_subst, _ = nil) 58 @type_name_substitutions << type_name_subst 59 @impl_name_substitutions << impl_name_subst 60 nil 61 end
Register a bidirectional type mapping.
@overload register_type_mapping
(runtime_type, puppet_type)
@param runtime_type [PRuntimeType] type that represents the runtime module or class to map to a puppet type @param puppet_type [PAnyType] type that will be mapped to the runtime module or class
@overload register_type_mapping
(runtime_type, pattern_replacement)
@param runtime_type [PRuntimeType] type containing the pattern and replacement to map the runtime type to a puppet type @param puppet_type [Array(Regexp,String)] the pattern and replacement to map a puppet type to a runtime type
# File lib/puppet/pops/types/implementation_registry.rb 30 def register_type_mapping(runtime_type, puppet_type_or_pattern, _ = nil) 31 TypeAsserter.assert_assignable('First argument of type mapping', PRuntimeType::RUBY, runtime_type) 32 expr = runtime_type.name_or_pattern 33 if expr.is_a?(Array) 34 TypeAsserter.assert_instance_of('Second argument of type mapping', TYPE_REGEXP_SUBST, puppet_type_or_pattern) 35 register_implementation_regexp(puppet_type_or_pattern, expr) 36 else 37 TypeAsserter.assert_instance_of('Second argument of type mapping', PTypeType::DEFAULT, puppet_type_or_pattern) 38 register_implementation(puppet_type_or_pattern, expr) 39 end 40 end
Find the name for, and then load, the type that corresponds to the given runtime module or module name The method will return `nil` if no mapping is found, a TypeReference if a mapping was found but the loader didn't find the type, or the loaded type.
@param impl_module [Module,String] the implementation class or class name @return [PAnyType,nil] the type, or `nil` if no mapping was found
# File lib/puppet/pops/types/implementation_registry.rb 111 def type_for_module(impl_module) 112 name = type_name_for_module(impl_module) 113 if name.nil? 114 nil 115 else 116 TypeParser.singleton.parse(name) 117 end 118 end
Find the type name and loader that corresponds to the given runtime module or module name
@param impl_module [Module,String] the implementation class or class name @return [String,nil] the name of the type, or `nil` if no mapping was found
# File lib/puppet/pops/types/implementation_registry.rb 99 def type_name_for_module(impl_module) 100 impl_module = impl_module.name if impl_module.is_a?(Module) 101 name = @parent.type_name_for_module(impl_module) unless @parent.nil? 102 name.nil? ? find_mapping(impl_module, @type_names_per_implementation, @impl_name_substitutions) : name 103 end
Private Instance Methods
# File lib/puppet/pops/types/implementation_registry.rb 122 def find_mapping(name, names, substitutions) 123 found = names[name] 124 if found.nil? 125 substitutions.each do |subst| 126 substituted = name.sub(*subst) 127 return substituted unless substituted == name 128 end 129 end 130 found 131 end