File: //usr/lib/ruby/site_ruby/1.8/puppet/pops/types/types.rb
require 'rgen/metamodel_builder'
# The Types model is a model of Puppet Language types.
# It consists of two parts; the meta-model expressed using RGen (in types_meta.rb) and this file which
# mixes in the implementation.
#
# @api public
#
module Puppet::Pops
require 'puppet/pops/types/types_meta'
# TODO: See PUP-2978 for possible performance optimization
# Mix in implementation part of the Bindings Module
module Types
# Used as end in a range
INFINITY = 1.0 / 0.0
NEGATIVE_INFINITY = -INFINITY
class TypeModelObject < RGen::MetamodelBuilder::MMBase
include Puppet::Pops::Visitable
include Puppet::Pops::Adaptable
include Puppet::Pops::Containment
end
class PAnyType < TypeModelObject
module ClassModule
# Produce a deep copy of the type
def copy
Marshal.load(Marshal.dump(self))
end
def hash
self.class.hash
end
def ==(o)
self.class == o.class
end
alias eql? ==
def to_s
Puppet::Pops::Types::TypeCalculator.string(self)
end
end
end
class PNotUndefType < PAnyType
module ClassModule
def hash
[self.class, type].hash
end
def ==(o)
self.class == o.class && type == o.type
end
end
end
class PType < PAnyType
module ClassModule
def hash
[self.class, type].hash
end
def ==(o)
self.class == o.class && type == o.type
end
end
end
class PDataType < PAnyType
module ClassModule
def ==(o)
self.class == o.class ||
o.class == PVariantType && o == Puppet::Pops::Types::TypeCalculator.data_variant()
end
end
end
class PVariantType < PAnyType
module ClassModule
def hash
[self.class, Set.new(self.types)].hash
end
def ==(o)
(self.class == o.class && Set.new(types) == Set.new(o.types)) ||
(o.class == PDataType && self == Puppet::Pops::Types::TypeCalculator.data_variant())
end
end
end
class PEnumType < PScalarType
module ClassModule
def hash
[self.class, Set.new(self.values)].hash
end
def ==(o)
self.class == o.class && Set.new(values) == Set.new(o.values)
end
end
end
class PIntegerType < PNumericType
module ClassModule
# The integer type is enumerable when it defines a range
include Enumerable
# Returns Float.Infinity if one end of the range is unbound
def size
return INFINITY if from.nil? || to.nil?
1+(to-from).abs
end
# Returns the range as an array ordered so the smaller number is always first.
# The number may be Infinity or -Infinity.
def range
f = from || NEGATIVE_INFINITY
t = to || INFINITY
[f, t]
end
# Returns Enumerator if no block is given
# Returns self if size is infinity (does not yield)
def each
return self.to_enum unless block_given?
return nil if from.nil? || to.nil?
from.upto(to) {|x| yield x }
end
def hash
[self.class, from, to].hash
end
def ==(o)
self.class == o.class && from == o.from && to == o.to
end
end
end
class PFloatType < PNumericType
module ClassModule
def hash
[self.class, from, to].hash
end
def ==(o)
self.class == o.class && from == o.from && to == o.to
end
end
end
class PStringType < PScalarType
module ClassModule
def hash
[self.class, self.size_type, Set.new(self.values)].hash
end
def ==(o)
self.class == o.class && self.size_type == o.size_type && Set.new(values) == Set.new(o.values)
end
end
end
class PRegexpType < PScalarType
module ClassModule
def regexp_derived
@_regexp = Regexp.new(pattern) unless @_regexp && @_regexp.source == pattern
@_regexp
end
def hash
[self.class, pattern].hash
end
def ==(o)
self.class == o.class && pattern == o.pattern
end
end
end
class PPatternType < PScalarType
module ClassModule
def hash
[self.class, Set.new(patterns)].hash
end
def ==(o)
self.class == o.class && Set.new(patterns) == Set.new(o.patterns)
end
end
end
class PCollectionType < PAnyType
module ClassModule
# Returns an array with from (min) size to (max) size
def size_range
return [0, INFINITY] if size_type.nil?
f = size_type.from || 0
t = size_type.to || INFINITY
[f, t]
end
def hash
[self.class, element_type, size_type].hash
end
def ==(o)
self.class == o.class && element_type == o.element_type && size_type == o.size_type
end
end
end
class PStructElement < TypeModelObject
module ClassModule
def hash
[self.class, value_type, key_type].hash
end
def name
k = key_type
k = k.optional_type if k.is_a?(POptionalType)
k.values[0]
end
def ==(o)
self.class == o.class && value_type == o.value_type && key_type == o.key_type
end
end
end
class PStructType < PAnyType
module ClassModule
def hashed_elements_derived
@_hashed ||= elements.reduce({}) {|memo, e| memo[e.name] = e; memo }
@_hashed
end
def clear_hashed_elements
@_hashed = nil
end
def hash
[self.class, Set.new(elements)].hash
end
def ==(o)
self.class == o.class && hashed_elements == o.hashed_elements
end
end
end
class PTupleType < PAnyType
module ClassModule
# Returns the number of elements accepted [min, max] in the tuple
def size_range
types_size = types.size
size_type.nil? ? [types_size, types_size] : size_type.range
end
# Returns the number of accepted occurrences [min, max] of the last type in the tuple
# The defaults is [1,1]
#
def repeat_last_range
types_size = types.size
if size_type.nil?
return [1, 1]
end
from, to = size_type.range()
min = from - (types_size-1)
min = min <= 0 ? 0 : min
max = to - (types_size-1)
[min, max]
end
def hash
[self.class, size_type, Set.new(types)].hash
end
def ==(o)
self.class == o.class && types == o.types && size_type == o.size_type
end
end
end
class PCallableType < PAnyType
module ClassModule
# Returns the number of accepted arguments [min, max]
def size_range
param_types.size_range
end
# Returns the number of accepted arguments for the last parameter type [min, max]
#
def last_range
param_types.repeat_last_range
end
# Range [0,0], [0,1], or [1,1] for the block
#
def block_range
case block_type
when Puppet::Pops::Types::POptionalType
[0,1]
when Puppet::Pops::Types::PVariantType, Puppet::Pops::Types::PCallableType
[1,1]
else
[0,0]
end
end
def hash
[self.class, Set.new(param_types), block_type].hash
end
def ==(o)
self.class == o.class && args_type == o.args_type && block_type == o.block_type
end
end
end
class PArrayType < PCollectionType
module ClassModule
def hash
[self.class, self.element_type, self.size_type].hash
end
def ==(o)
self.class == o.class && self.element_type == o.element_type && self.size_type == o.size_type
end
end
end
class PHashType < PCollectionType
module ClassModule
def hash
[self.class, key_type, self.element_type, self.size_type].hash
end
def ==(o)
self.class == o.class &&
key_type == o.key_type &&
self.element_type == o.element_type &&
self.size_type == o.size_type
end
def is_the_empty_hash?
size_type.is_a?(PIntegerType) && size_type.from == 0 && size_type.to == 0 && key_type.is_a?(PUndefType) && element_type.is_a?(PUndefType)
end
end
end
class PRuntimeType < PAnyType
module ClassModule
def hash
[self.class, runtime, runtime_type_name].hash
end
def ==(o)
self.class == o.class && runtime == o.runtime && runtime_type_name == o.runtime_type_name
end
end
end
class PHostClassType < PCatalogEntryType
module ClassModule
def hash
[self.class, class_name].hash
end
def ==(o)
self.class == o.class && class_name == o.class_name
end
end
end
class PResourceType < PCatalogEntryType
module ClassModule
def hash
[self.class, type_name, title].hash
end
def ==(o)
self.class == o.class && type_name == o.type_name && title == o.title
end
end
end
class POptionalType < PAnyType
module ClassModule
def hash
[self.class, optional_type].hash
end
def ==(o)
self.class == o.class && optional_type == o.optional_type
end
end
end
end
end