1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 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
|
require 'uri'
module Puppet::Pops
module Pcore
include Types::PuppetObject
TYPE_URI_RX = Types::TypeFactory.regexp(URI.regexp)
TYPE_URI = Types::TypeFactory.pattern(TYPE_URI_RX)
TYPE_URI_ALIAS = Types::PTypeAliasType.new('Pcore::URI', nil, TYPE_URI)
TYPE_SIMPLE_TYPE_NAME = Types::TypeFactory.pattern(/\A[A-Z]\w*\z/)
TYPE_QUALIFIED_REFERENCE = Types::TypeFactory.pattern(/\A[A-Z][\w]*(?:::[A-Z][\w]*)*\z/)
TYPE_MEMBER_NAME = Types::PPatternType.new([Types::PRegexpType.new(Patterns::PARAM_NAME)])
KEY_PCORE_URI = 'pcore_uri'.freeze
KEY_PCORE_VERSION = 'pcore_version'.freeze
PCORE_URI = 'http://puppet.com/2016.1/pcore'
PCORE_VERSION = SemanticPuppet::Version.new(1,0,0)
PARSABLE_PCORE_VERSIONS = SemanticPuppet::VersionRange.parse('1.x')
RUNTIME_NAME_AUTHORITY = 'http://puppet.com/2016.1/runtime'
def self._pcore_type
@type
end
def self.annotate(instance, annotations_hash)
annotations_hash.each_pair do |type, init_hash|
type.implementation_class.annotate(instance) { init_hash }
end
instance
end
def self.init_env(loader)
if Puppet[:tasks]
add_object_type('Task', <<-PUPPET, loader)
{
attributes => {
# Fully qualified name of the task
name => { type => Pattern[/\\A[a-z][a-z0-9_]*(?:::[a-z][a-z0-9_]*)*\\z/] },
# List of file references referenced by metadata and their paths on disk.
# If there are no implementations listed in metadata, the first file is always
# the task executable.
files => { type => Array[Struct[name => String, path => String]] },
# Task metadata
metadata => { type => Hash[String, Any] },
# Map parameter names to their parsed data type
parameters => { type => Optional[Hash[Pattern[/\\A[a-z][a-z0-9_]*\\z/], Type]], value => undef },
}
}
PUPPET
end
end
def self.init(loader, ir)
add_alias('Pcore::URI_RX', TYPE_URI_RX, loader)
add_type(TYPE_URI_ALIAS, loader)
add_alias('Pcore::SimpleTypeName', TYPE_SIMPLE_TYPE_NAME, loader)
add_alias('Pcore::MemberName', TYPE_MEMBER_NAME, loader)
add_alias('Pcore::TypeName', TYPE_QUALIFIED_REFERENCE, loader)
add_alias('Pcore::QRef', TYPE_QUALIFIED_REFERENCE, loader)
Types::TypedModelObject.register_ptypes(loader, ir)
@type = create_object_type(loader, ir, Pcore, 'Pcore', nil)
ir.register_implementation_namespace('Pcore', 'Puppet::Pops::Pcore')
ir.register_implementation_namespace('Puppet::AST', 'Puppet::Pops::Model')
ir.register_implementation('Puppet::AST::Locator', 'Puppet::Pops::Parser::Locator::Locator19')
Resource.register_ptypes(loader, ir)
Lookup::Context.register_ptype(loader, ir);
Lookup::DataProvider.register_types(loader)
add_object_type('Deferred', <<-PUPPET, loader)
{
attributes => {
# Fully qualified name of the function
name => { type => Pattern[/\\A[$]?[a-z][a-z0-9_]*(?:::[a-z][a-z0-9_]*)*\\z/] },
arguments => { type => Optional[Array[Any]], value => undef},
}
}
PUPPET
end
# Create and register a new `Object` type in the Puppet Type System and map it to an implementation class
#
# @param loader [Loader::Loader] The loader where the new type will be registered
# @param ir [ImplementationRegistry] The implementation registry that maps this class to the new type
# @param impl_class [Class] The class that is the implementation of the type
# @param type_name [String] The fully qualified name of the new type
# @param parent_name [String,nil] The fully qualified name of the parent type
# @param attributes_hash [Hash{String => Object}] A hash of attribute definitions for the new type
# @param functions_hash [Hash{String => Object}] A hash of function definitions for the new type
# @param equality [Array<String>] An array with names of attributes that participate in equality comparison
# @return [PObjectType] the created type. Not yet resolved
#
# @api private
def self.create_object_type(loader, ir, impl_class, type_name, parent_name, attributes_hash = EMPTY_HASH, functions_hash = EMPTY_HASH, equality = nil)
init_hash = {}
init_hash[Types::KEY_PARENT] = Types::PTypeReferenceType.new(parent_name) unless parent_name.nil?
init_hash[Types::KEY_ATTRIBUTES] = attributes_hash unless attributes_hash.empty?
init_hash[Types::KEY_FUNCTIONS] = functions_hash unless functions_hash.empty?
init_hash[Types::KEY_EQUALITY] = equality unless equality.nil?
ir.register_implementation(type_name, impl_class)
add_type(Types::PObjectType.new(type_name, init_hash), loader)
end
def self.add_object_type(name, body, loader)
add_type(Types::PObjectType.new(name, Parser::EvaluatingParser.new.parse_string(body).body), loader)
end
def self.add_alias(name, type, loader, name_authority = RUNTIME_NAME_AUTHORITY)
add_type(Types::PTypeAliasType.new(name, nil, type), loader, name_authority)
end
def self.add_type(type, loader, name_authority = RUNTIME_NAME_AUTHORITY)
loader.set_entry(Loader::TypedName.new(:type, type.name, name_authority), type)
type
end
def self.register_implementations(impls, name_authority = RUNTIME_NAME_AUTHORITY)
Loaders.loaders.register_implementations(impls, name_authority)
end
def self.register_aliases(aliases, name_authority = RUNTIME_NAME_AUTHORITY, loader = Loaders.loaders.private_environment_loader)
aliases.each do |name, type_string|
add_type(Types::PTypeAliasType.new(name, Types::TypeFactory.type_reference(type_string), nil), loader, name_authority)
end
aliases.each_key.map { |name| loader.load(:type, name).resolve(loader) }
end
end
end
|