puppet 4.4.2 → 4.5.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of puppet might be problematic. Click here for more details.
- data/CONTRIBUTING.md +5 -5
- data/Gemfile +2 -2
- data/LICENSE +2 -2
- data/README.md +5 -0
- data/ext/project_data.yaml +2 -0
- data/lib/hiera_puppet.rb +6 -14
- data/lib/puppet/application/agent.rb +2 -3
- data/lib/puppet/data_providers/hiera_config.rb +2 -4
- data/lib/puppet/data_providers/hiera_interpolate.rb +12 -154
- data/lib/puppet/data_providers/json_data_provider_factory.rb +0 -7
- data/lib/puppet/data_providers/yaml_data_provider_factory.rb +2 -8
- data/lib/puppet/defaults.rb +70 -7
- data/lib/puppet/functions.rb +69 -0
- data/lib/puppet/functions/dig.rb +39 -0
- data/lib/puppet/functions/lest.rb +53 -0
- data/lib/puppet/functions/lookup.rb +40 -27
- data/lib/puppet/functions/new.rb +502 -0
- data/lib/puppet/functions/regsubst.rb +11 -10
- data/lib/puppet/functions/then.rb +74 -0
- data/lib/puppet/functions/type.rb +4 -4
- data/lib/puppet/functions/with.rb +1 -1
- data/lib/puppet/indirector/catalog/compiler.rb +2 -0
- data/lib/puppet/indirector/resource_type/parser.rb +5 -0
- data/lib/puppet/indirector/rest.rb +5 -1
- data/lib/puppet/loaders.rb +2 -0
- data/lib/puppet/metatype/manager.rb +19 -2
- data/lib/puppet/module_tool/applications/application.rb +1 -1
- data/lib/puppet/module_tool/skeleton/templates/generator/Gemfile +6 -2
- data/lib/puppet/module_tool/skeleton/templates/generator/Rakefile +19 -4
- data/lib/puppet/module_tool/skeleton/templates/generator/{tests → examples}/init.pp.erb +1 -1
- data/lib/puppet/module_tool/skeleton/templates/generator/spec/classes/init_spec.rb.erb +0 -1
- data/lib/puppet/network/http/api/master/v3/environment.rb +6 -2
- data/lib/puppet/parser/ast/pops_bridge.rb +20 -3
- data/lib/puppet/parser/compiler/catalog_validator/relationship_validator.rb +24 -2
- data/lib/puppet/parser/e4_parser_adapter.rb +13 -12
- data/lib/puppet/parser/environment_compiler.rb +2 -2
- data/lib/puppet/parser/resource.rb +14 -5
- data/lib/puppet/parser/scope.rb +18 -15
- data/lib/puppet/plugins/data_providers/data_provider.rb +19 -8
- data/lib/puppet/pops.rb +6 -0
- data/lib/puppet/pops/adapters.rb +5 -1
- data/lib/puppet/pops/evaluator/access_operator.rb +52 -14
- data/lib/puppet/pops/evaluator/compare_operator.rb +34 -4
- data/lib/puppet/pops/evaluator/evaluator_impl.rb +75 -22
- data/lib/puppet/pops/evaluator/literal_evaluator.rb +7 -6
- data/lib/puppet/pops/evaluator/runtime3_converter.rb +13 -1
- data/lib/puppet/pops/evaluator/runtime3_support.rb +14 -4
- data/lib/puppet/pops/functions/dispatcher.rb +1 -1
- data/lib/puppet/pops/issues.rb +18 -2
- data/lib/puppet/pops/loader/base_loader.rb +48 -7
- data/lib/puppet/pops/loader/dependency_loader.rb +27 -2
- data/lib/puppet/pops/loader/loader.rb +12 -0
- data/lib/puppet/pops/loader/predefined_loader.rb +29 -0
- data/lib/puppet/pops/loader/runtime3_type_loader.rb +57 -0
- data/lib/puppet/pops/loader/static_loader.rb +92 -5
- data/lib/puppet/pops/loader/type_definition_instantiator.rb +25 -3
- data/lib/puppet/pops/loaders.rb +84 -14
- data/lib/puppet/pops/lookup/explainer.rb +38 -1
- data/lib/puppet/pops/lookup/interpolation.rb +115 -0
- data/lib/puppet/pops/lookup/sub_lookup.rb +86 -0
- data/lib/puppet/pops/model/ast_transformer.rb +8 -1
- data/lib/puppet/pops/model/factory.rb +31 -8
- data/lib/puppet/pops/model/model.rb +8 -0
- data/lib/puppet/pops/model/model_label_provider.rb +1 -0
- data/lib/puppet/pops/model/model_meta.rb +7 -1
- data/lib/puppet/pops/model/model_tree_dumper.rb +4 -0
- data/lib/puppet/pops/parser/egrammar.ra +24 -7
- data/lib/puppet/pops/parser/eparser.rb +863 -798
- data/lib/puppet/pops/parser/evaluating_parser.rb +4 -0
- data/lib/puppet/pops/parser/locator.rb +8 -4
- data/lib/puppet/pops/pcore.rb +30 -0
- data/lib/puppet/pops/types/class_loader.rb +2 -4
- data/lib/puppet/pops/types/implementation_registry.rb +146 -0
- data/lib/puppet/pops/types/iterable.rb +4 -4
- data/lib/puppet/pops/types/p_object_type.rb +846 -0
- data/lib/puppet/pops/types/p_runtime_type.rb +102 -0
- data/lib/puppet/pops/types/p_sem_ver_range_type.rb +164 -0
- data/lib/puppet/pops/types/p_sem_ver_type.rb +113 -0
- data/lib/puppet/pops/types/puppet_object.rb +21 -0
- data/lib/puppet/pops/types/ruby_generator.rb +258 -0
- data/lib/puppet/pops/types/string_converter.rb +922 -0
- data/lib/puppet/pops/types/type_calculator.rb +29 -5
- data/lib/puppet/pops/types/type_conversion_error.rb +15 -0
- data/lib/puppet/pops/types/type_factory.rb +49 -16
- data/lib/puppet/pops/types/type_formatter.rb +335 -112
- data/lib/puppet/pops/types/type_mismatch_describer.rb +110 -29
- data/lib/puppet/pops/types/type_parser.rb +205 -197
- data/lib/puppet/pops/types/types.rb +481 -103
- data/lib/puppet/pops/validation.rb +1 -1
- data/lib/puppet/pops/validation/checker4_0.rb +66 -4
- data/lib/puppet/pops/validation/validator_factory_4_0.rb +1 -0
- data/lib/puppet/pops/visitor.rb +3 -1
- data/lib/puppet/property.rb +1 -1
- data/lib/puppet/provider/augeas/augeas.rb +1 -1
- data/lib/puppet/provider/package/pip.rb +64 -20
- data/lib/puppet/provider/package/rpm.rb +112 -0
- data/lib/puppet/provider/package/yum.rb +7 -68
- data/lib/puppet/provider/service/daemontools.rb +3 -3
- data/lib/puppet/provider/service/init.rb +4 -2
- data/lib/puppet/provider/service/runit.rb +3 -3
- data/lib/puppet/provider/service/smf.rb +6 -3
- data/lib/puppet/provider/service/systemd.rb +59 -73
- data/lib/puppet/reference/providers.rb +1 -2
- data/lib/puppet/resource.rb +54 -37
- data/lib/puppet/resource/catalog.rb +31 -29
- data/lib/puppet/resource/type_collection.rb +23 -8
- data/lib/puppet/settings.rb +4 -2
- data/lib/puppet/settings/base_setting.rb +9 -3
- data/lib/puppet/settings/symbolic_enum_setting.rb +17 -0
- data/lib/puppet/test/test_helper.rb +0 -1
- data/lib/puppet/type.rb +9 -3
- data/lib/puppet/type/exec.rb +17 -17
- data/lib/puppet/type/file.rb +12 -0
- data/lib/puppet/type/file/content.rb +6 -6
- data/lib/puppet/type/file/ensure.rb +4 -4
- data/lib/puppet/type/file/source.rb +4 -4
- data/lib/puppet/type/file/target.rb +2 -2
- data/lib/puppet/type/mount.rb +18 -1
- data/lib/puppet/type/package.rb +3 -3
- data/lib/puppet/type/schedule.rb +4 -4
- data/lib/puppet/type/service.rb +15 -0
- data/lib/puppet/type/sshkey.rb +5 -3
- data/lib/puppet/type/tidy.rb +3 -3
- data/lib/puppet/type/zone.rb +5 -5
- data/lib/puppet/util/feature.rb +1 -1
- data/lib/puppet/util/monkey_patches.rb +8 -0
- data/lib/puppet/util/network_device/cisco/device.rb +16 -6
- data/lib/puppet/util/network_device/cisco/interface.rb +5 -6
- data/lib/puppet/util/plist.rb +3 -3
- data/lib/puppet/version.rb +1 -1
- data/spec/fixtures/unit/application/environments/production/data/common.yaml +13 -0
- data/spec/fixtures/unit/data_providers/environments/production/modules/abc/lib/puppet/functions/abc/data.rb +2 -1
- data/spec/fixtures/unit/data_providers/environments/production/modules/abc/manifests/init.pp +2 -1
- data/spec/fixtures/unit/functions/lookup/environments/production/modules/empty_key_json/data/empty_key.json +1 -0
- data/spec/fixtures/unit/functions/lookup/environments/production/modules/empty_key_json/hiera.yaml +5 -0
- data/spec/fixtures/unit/functions/lookup/environments/production/modules/empty_key_json/manifests/init.pp +2 -0
- data/spec/fixtures/unit/functions/lookup/environments/production/modules/empty_key_json/metadata.json +9 -0
- data/spec/fixtures/unit/functions/lookup/environments/production/modules/empty_key_yaml/data/empty_key.yaml +1 -0
- data/spec/fixtures/unit/functions/lookup/environments/production/modules/empty_key_yaml/hiera.yaml +5 -0
- data/spec/fixtures/unit/functions/lookup/environments/production/modules/empty_key_yaml/manifests/init.pp +2 -0
- data/spec/fixtures/unit/functions/lookup/environments/production/modules/empty_key_yaml/metadata.json +9 -0
- data/spec/fixtures/unit/functions/lookup/environments/production/modules/empty_yaml/data/empty.yaml +1 -0
- data/spec/fixtures/unit/pops/loaders/loaders/dependent_modules_with_metadata/modules/usee/lib/puppet/type/usee_type.rb +5 -0
- data/spec/fixtures/unit/pops/loaders/loaders/dependent_modules_with_metadata/modules/user/manifests/init.pp +6 -0
- data/spec/fixtures/unit/provider/service/smf/svcs.out +4 -3
- data/spec/integration/module_tool/tar/mini_spec.rb +27 -27
- data/spec/integration/parser/catalog_spec.rb +14 -2
- data/spec/integration/parser/compiler_spec.rb +94 -3
- data/spec/integration/parser/resource_expressions_spec.rb +1 -1
- data/spec/integration/resource/type_collection_spec.rb +8 -0
- data/spec/lib/puppet_spec/compiler.rb +11 -4
- data/spec/shared_contexts/types_setup.rb +4 -0
- data/spec/unit/application/lookup_spec.rb +91 -9
- data/spec/unit/appmgmt_spec.rb +44 -35
- data/spec/unit/capability_spec.rb +33 -53
- data/spec/unit/data_providers/function_data_provider_spec.rb +19 -1
- data/spec/unit/data_providers/hiera_data_provider_spec.rb +1 -1
- data/spec/unit/defaults_spec.rb +18 -0
- data/spec/unit/functions/assert_type_spec.rb +1 -1
- data/spec/unit/functions/dig_spec.rb +58 -0
- data/spec/unit/functions/lest_spec.rb +34 -0
- data/spec/unit/functions/lookup_spec.rb +108 -2
- data/spec/unit/functions/new_spec.rb +543 -0
- data/spec/unit/functions/regsubst_spec.rb +8 -0
- data/spec/unit/functions/then_spec.rb +40 -0
- data/spec/unit/functions4_spec.rb +78 -10
- data/spec/unit/hiera_puppet_spec.rb +49 -8
- data/spec/unit/indirector/resource_type/parser_spec.rb +5 -0
- data/spec/unit/indirector/rest_spec.rb +12 -0
- data/spec/unit/network/http/api/master/v3/environment_spec.rb +60 -0
- data/spec/unit/node/environment_spec.rb +10 -0
- data/spec/unit/parser/compiler_spec.rb +20 -1
- data/spec/unit/parser/functions/create_resources_spec.rb +2 -2
- data/spec/unit/parser/functions/shared.rb +1 -1
- data/spec/unit/parser/resource_spec.rb +8 -1
- data/spec/unit/parser/scope_spec.rb +45 -0
- data/spec/unit/pops/evaluator/access_ops_spec.rb +14 -0
- data/spec/unit/pops/evaluator/evaluating_parser_spec.rb +13 -5
- data/spec/unit/pops/loaders/static_loader_spec.rb +92 -1
- data/spec/unit/{data_providers/hiera_interpolation_spec.rb → pops/lookup/interpolation_spec.rb} +7 -5
- data/spec/unit/pops/parser/lexer2_spec.rb +2 -9
- data/spec/unit/pops/parser/parse_application_spec.rb +3 -8
- data/spec/unit/pops/parser/parse_basic_expressions_spec.rb +19 -0
- data/spec/unit/pops/parser/parse_capabilities_spec.rb +3 -10
- data/spec/unit/pops/parser/parse_site_spec.rb +19 -10
- data/spec/unit/pops/parser/parser_rspec_helper.rb +0 -4
- data/spec/unit/pops/types/enumeration_spec.rb +13 -12
- data/spec/unit/pops/types/iterable_spec.rb +2 -2
- data/spec/unit/pops/types/p_object_type_spec.rb +1060 -0
- data/spec/unit/pops/types/p_sem_ver_type_spec.rb +285 -0
- data/spec/unit/pops/types/recursion_guard_spec.rb +19 -17
- data/spec/unit/pops/types/ruby_generator_spec.rb +261 -0
- data/spec/unit/pops/types/string_converter_spec.rb +904 -0
- data/spec/unit/pops/types/type_calculator_spec.rb +430 -406
- data/spec/unit/pops/types/type_factory_spec.rb +119 -104
- data/spec/unit/pops/types/type_formatter_spec.rb +73 -6
- data/spec/unit/pops/types/type_mismatch_describer_spec.rb +2 -2
- data/spec/unit/pops/types/type_parser_spec.rb +54 -15
- data/spec/unit/pops/types/types_spec.rb +113 -8
- data/spec/unit/pops/validator/validator_spec.rb +84 -10
- data/spec/unit/provider/package/pip3_spec.rb +9 -270
- data/spec/unit/provider/package/pip_spec.rb +85 -30
- data/spec/unit/provider/package/rpm_spec.rb +160 -3
- data/spec/unit/provider/package/yum_spec.rb +23 -134
- data/spec/unit/provider/service/smf_spec.rb +14 -2
- data/spec/unit/provider/service/systemd_spec.rb +33 -41
- data/spec/unit/resource/capability_finder_spec.rb +10 -2
- data/spec/unit/settings/file_setting_spec.rb +6 -0
- data/spec/unit/transaction/additional_resource_generator_spec.rb +80 -65
- data/spec/unit/type/mount_spec.rb +51 -10
- data/spec/unit/type/service_spec.rb +16 -0
- data/spec/unit/type_spec.rb +14 -0
- data/spec/unit/util/feature_spec.rb +1 -1
- data/spec/unit/util/monkey_patches_spec.rb +60 -0
- data/spec/unit/util/network_device/cisco/device_spec.rb +1 -1
- metadata +63 -11
- data/lib/puppet/pops/types/types_meta.rb +0 -0
- data/spec/integration/provider/package_spec.rb +0 -35
@@ -4,6 +4,7 @@ require_relative 'recursion_guard'
|
|
4
4
|
require_relative 'type_acceptor'
|
5
5
|
require_relative 'type_asserter'
|
6
6
|
require_relative 'type_assertion_error'
|
7
|
+
require_relative 'type_conversion_error'
|
7
8
|
require_relative 'type_formatter'
|
8
9
|
require_relative 'type_calculator'
|
9
10
|
require_relative 'type_factory'
|
@@ -11,10 +12,10 @@ require_relative 'type_parser'
|
|
11
12
|
require_relative 'class_loader'
|
12
13
|
require_relative 'type_mismatch_describer'
|
13
14
|
|
14
|
-
require 'rgen/metamodel_builder'
|
15
|
-
|
16
15
|
module Puppet::Pops
|
17
16
|
module Types
|
17
|
+
|
18
|
+
EMPTY_HASH = {}.freeze
|
18
19
|
# The Types model is a model of Puppet Language types.
|
19
20
|
#
|
20
21
|
# The exact relationship between types is not visible in this model wrt. the PDataType which is an abstraction
|
@@ -115,6 +116,14 @@ class PAnyType < TypedModelObject
|
|
115
116
|
false
|
116
117
|
end
|
117
118
|
|
119
|
+
# Called from the `PTypeAliasType` when it detects self recursion. The default is to do nothing
|
120
|
+
# but some self recursive constructs are illegal such as when a `PObjectType` somehow inherits itself
|
121
|
+
# @param originator [PTypeAliasType] the starting point for the check
|
122
|
+
# @raise Puppet::Error if an illegal self recursion is detected
|
123
|
+
# @api private
|
124
|
+
def check_self_recursion(originator)
|
125
|
+
end
|
126
|
+
|
118
127
|
# Generalizes value specific types. Types that are not value specific will return `self` otherwise
|
119
128
|
# the generalized type is returned.
|
120
129
|
#
|
@@ -136,6 +145,18 @@ class PAnyType < TypedModelObject
|
|
136
145
|
self
|
137
146
|
end
|
138
147
|
|
148
|
+
# Called from the TypeParser once it has found a type using the Loader to enable that this type can
|
149
|
+
# resolve internal type expressions using a loader. Presently, this method is a no-op for all types
|
150
|
+
# except the {{PTypeAliasType}}.
|
151
|
+
#
|
152
|
+
# @param type_parser [TypeParser] type parser
|
153
|
+
# @param loader [Loader::Loader] loader to use
|
154
|
+
# @return [PTypeAliasType] the receiver of the call, i.e. `self`
|
155
|
+
# @api private
|
156
|
+
def resolve(type_parser, loader)
|
157
|
+
self
|
158
|
+
end
|
159
|
+
|
139
160
|
# Responds `true` for all callables, variants of callables and unless _optional_ is
|
140
161
|
# false, all optional callables.
|
141
162
|
# @param optional [Boolean]
|
@@ -217,6 +238,29 @@ class PAnyType < TypedModelObject
|
|
217
238
|
TypeFormatter.string(self)
|
218
239
|
end
|
219
240
|
|
241
|
+
# Returns the name of the type, without parameters
|
242
|
+
# @return [String] the name of the type
|
243
|
+
# @api public
|
244
|
+
def name
|
245
|
+
simple_name
|
246
|
+
end
|
247
|
+
|
248
|
+
def new_function(loader)
|
249
|
+
self.class.new_function(self, loader)
|
250
|
+
end
|
251
|
+
|
252
|
+
# This default implementation of of a new_function raises an Argument Error.
|
253
|
+
# Types for which creating a new instance is supported, should create and return
|
254
|
+
# a Puppet Function class by using Puppet:Loaders.create_loaded_function(:new, loader)
|
255
|
+
# and return that result.
|
256
|
+
#
|
257
|
+
# @raises ArgumentError
|
258
|
+
#
|
259
|
+
def self.new_function(instance, loader)
|
260
|
+
raise ArgumentError.new("Creation of new instance of type '#{instance.to_s}' is not supported")
|
261
|
+
end
|
262
|
+
|
263
|
+
|
220
264
|
# The default instance of this type. Each type in the type system has this constant
|
221
265
|
# declared.
|
222
266
|
#
|
@@ -229,19 +273,6 @@ class PAnyType < TypedModelObject
|
|
229
273
|
o.is_a?(PAnyType)
|
230
274
|
end
|
231
275
|
|
232
|
-
NAME_SEGMENT_SEPARATOR = '::'.freeze
|
233
|
-
|
234
|
-
# @api private
|
235
|
-
def class_from_string(str)
|
236
|
-
begin
|
237
|
-
str.split(NAME_SEGMENT_SEPARATOR).reduce(Object) do |memo, name_segment|
|
238
|
-
memo.const_get(name_segment)
|
239
|
-
end
|
240
|
-
rescue NameError
|
241
|
-
return nil
|
242
|
-
end
|
243
|
-
end
|
244
|
-
|
245
276
|
# Produces the tuple entry at the given index given a tuple type, its from/to constraints on the last
|
246
277
|
# type, and an index.
|
247
278
|
# Produces nil if the index is out of bounds
|
@@ -430,6 +461,15 @@ class PNotUndefType < PTypeWithContainedType
|
|
430
461
|
end
|
431
462
|
end
|
432
463
|
|
464
|
+
def new_function(loader)
|
465
|
+
# If only NotUndef, then use Unit's null converter
|
466
|
+
if type.nil?
|
467
|
+
PUnitType.new_function(self.class, loader)
|
468
|
+
else
|
469
|
+
type.new_function(loader)
|
470
|
+
end
|
471
|
+
end
|
472
|
+
|
433
473
|
DEFAULT = PNotUndefType.new
|
434
474
|
|
435
475
|
protected
|
@@ -470,6 +510,19 @@ class PUnitType < PAnyType
|
|
470
510
|
true
|
471
511
|
end
|
472
512
|
|
513
|
+
# A "null" implementation - that simply returns the given argument
|
514
|
+
def self.new_function(_, loader)
|
515
|
+
@new_function ||= Puppet::Functions.create_loaded_function(:new_unit, loader) do
|
516
|
+
dispatch :from_args do
|
517
|
+
param 'Any', :from
|
518
|
+
end
|
519
|
+
|
520
|
+
def from_args(from)
|
521
|
+
from
|
522
|
+
end
|
523
|
+
end
|
524
|
+
end
|
525
|
+
|
473
526
|
DEFAULT = PUnitType.new
|
474
527
|
|
475
528
|
protected
|
@@ -663,6 +716,56 @@ class PNumericType < PScalarType
|
|
663
716
|
@from == -Float::INFINITY && @to == Float::INFINITY
|
664
717
|
end
|
665
718
|
|
719
|
+
def self.new_function(_, loader)
|
720
|
+
@new_function ||= Puppet::Functions.create_loaded_function(:new_numeric, loader) do
|
721
|
+
local_types do
|
722
|
+
type 'Convertible = Variant[Undef, Integer, Float, Boolean, String]'
|
723
|
+
type 'NamedArgs = Struct[{from => Convertible}]'
|
724
|
+
end
|
725
|
+
|
726
|
+
dispatch :from_args do
|
727
|
+
param 'Convertible', :from
|
728
|
+
end
|
729
|
+
|
730
|
+
dispatch :from_hash do
|
731
|
+
param 'NamedArgs', :hash_args
|
732
|
+
end
|
733
|
+
def from_args(from)
|
734
|
+
case from
|
735
|
+
when NilClass
|
736
|
+
throw :undefined_value
|
737
|
+
when Float
|
738
|
+
from
|
739
|
+
when Integer
|
740
|
+
from
|
741
|
+
when TrueClass
|
742
|
+
1
|
743
|
+
when FalseClass
|
744
|
+
0
|
745
|
+
when String
|
746
|
+
begin
|
747
|
+
if from[0] == '0' && (from[1].downcase == 'b' || from[1].downcase == 'x')
|
748
|
+
Integer(from)
|
749
|
+
else
|
750
|
+
Puppet::Pops::Utils.to_n(from)
|
751
|
+
end
|
752
|
+
rescue TypeError => e
|
753
|
+
raise TypeConversionError.new(e.message)
|
754
|
+
rescue ArgumentError => e
|
755
|
+
raise TypeConversionError.new(e.message)
|
756
|
+
end
|
757
|
+
else
|
758
|
+
t = Puppet::Pops::Types::TypeCalculator.singleton.infer(from).generalize
|
759
|
+
raise TypeConversionError.new("Value of type '#{t}' cannot be converted to Numeric")
|
760
|
+
end
|
761
|
+
end
|
762
|
+
|
763
|
+
def from_hash(args_hash)
|
764
|
+
from_args(args_hash['from'])
|
765
|
+
end
|
766
|
+
end
|
767
|
+
end
|
768
|
+
|
666
769
|
DEFAULT = PNumericType.new(-Float::INFINITY)
|
667
770
|
|
668
771
|
protected
|
@@ -753,6 +856,67 @@ class PIntegerType < PNumericType
|
|
753
856
|
@from >= 0 ? self : PIntegerType.new(0, @to < 0 ? 0 : @to)
|
754
857
|
end
|
755
858
|
|
859
|
+
def new_function(loader)
|
860
|
+
@@new_function ||= Puppet::Functions.create_loaded_function(:new, loader) do
|
861
|
+
local_types do
|
862
|
+
type 'Radix = Variant[Default, Integer[2,2], Integer[8,8], Integer[10,10], Integer[16,16]]'
|
863
|
+
type 'Convertible = Variant[Undef, Integer, Float, Boolean, String]'
|
864
|
+
type 'NamedArgs = Struct[{from => Convertible, Optional[radix] => Radix}]'
|
865
|
+
end
|
866
|
+
|
867
|
+
dispatch :from_args do
|
868
|
+
param 'Convertible', :from
|
869
|
+
optional_param 'Radix', :radix
|
870
|
+
end
|
871
|
+
|
872
|
+
dispatch :from_hash do
|
873
|
+
param 'NamedArgs', :hash_args
|
874
|
+
end
|
875
|
+
|
876
|
+
def from_args(from, radix = :default)
|
877
|
+
case from
|
878
|
+
when NilClass
|
879
|
+
throw :undefined_value
|
880
|
+
when Float
|
881
|
+
from.to_i
|
882
|
+
when Integer
|
883
|
+
from
|
884
|
+
when TrueClass
|
885
|
+
1
|
886
|
+
when FalseClass
|
887
|
+
0
|
888
|
+
when String
|
889
|
+
begin
|
890
|
+
radix == :default ? Integer(from) : Integer(from, assert_radix(radix))
|
891
|
+
rescue TypeError => e
|
892
|
+
raise TypeConversionError.new(e.message)
|
893
|
+
rescue ArgumentError => e
|
894
|
+
raise TypeConversionError.new(e.message)
|
895
|
+
end
|
896
|
+
else
|
897
|
+
t = Puppet::Pops::Types::TypeCalculator.singleton.infer(from).generalize
|
898
|
+
raise TypeConversionError.new("Value of type '#{t}' cannot be converted to an Integer")
|
899
|
+
end
|
900
|
+
end
|
901
|
+
|
902
|
+
def from_hash(args_hash)
|
903
|
+
from = args_hash['from']
|
904
|
+
radix = args_hash['radix'] || :default
|
905
|
+
from_args(from, radix)
|
906
|
+
end
|
907
|
+
|
908
|
+
def assert_radix(radix)
|
909
|
+
case radix
|
910
|
+
when 2, 8, 10, 16, :default
|
911
|
+
else
|
912
|
+
raise ArgumentError.new("Illegal radix: '#{radix}', expected 2, 8, 10, 16, or default")
|
913
|
+
end
|
914
|
+
radix
|
915
|
+
end
|
916
|
+
|
917
|
+
end
|
918
|
+
end
|
919
|
+
|
756
920
|
DEFAULT = PIntegerType.new(-Float::INFINITY)
|
757
921
|
end
|
758
922
|
|
@@ -783,6 +947,59 @@ class PFloatType < PNumericType
|
|
783
947
|
end
|
784
948
|
end
|
785
949
|
|
950
|
+
# Returns a new function that produces a Float value
|
951
|
+
#
|
952
|
+
def self.new_function(_, loader)
|
953
|
+
@new_function ||= Puppet::Functions.create_loaded_function(:new_float, loader) do
|
954
|
+
local_types do
|
955
|
+
type 'Convertible = Variant[Undef, Integer, Float, Boolean, String]'
|
956
|
+
type 'NamedArgs = Struct[{from => Convertible}]'
|
957
|
+
end
|
958
|
+
|
959
|
+
dispatch :from_args do
|
960
|
+
param 'Convertible', :from
|
961
|
+
end
|
962
|
+
|
963
|
+
dispatch :from_hash do
|
964
|
+
param 'NamedArgs', :hash_args
|
965
|
+
end
|
966
|
+
|
967
|
+
def from_args(from)
|
968
|
+
case from
|
969
|
+
when NilClass
|
970
|
+
throw :undefined_value
|
971
|
+
when Float
|
972
|
+
from
|
973
|
+
when Integer
|
974
|
+
Float(from)
|
975
|
+
when TrueClass
|
976
|
+
1.0
|
977
|
+
when FalseClass
|
978
|
+
0.0
|
979
|
+
when String
|
980
|
+
begin
|
981
|
+
# support a binary as float
|
982
|
+
if from[0] == '0' && from[1].downcase == 'b'
|
983
|
+
from = Integer(from)
|
984
|
+
end
|
985
|
+
Float(from)
|
986
|
+
rescue TypeError => e
|
987
|
+
raise TypeConversionError.new(e.message)
|
988
|
+
rescue ArgumentError => e
|
989
|
+
raise TypeConversionError.new(e.message)
|
990
|
+
end
|
991
|
+
else
|
992
|
+
t = Puppet::Pops::Types::TypeCalculator.singleton.infer(from).generalize
|
993
|
+
raise TypeConversionError.new("Value of type '#{t}' cannot be converted to Float")
|
994
|
+
end
|
995
|
+
end
|
996
|
+
|
997
|
+
def from_hash(args_hash)
|
998
|
+
from_args(args_hash['from'])
|
999
|
+
end
|
1000
|
+
end
|
1001
|
+
end
|
1002
|
+
|
786
1003
|
DEFAULT = PFloatType.new(-Float::INFINITY)
|
787
1004
|
end
|
788
1005
|
|
@@ -792,10 +1009,11 @@ class PCollectionType < PAnyType
|
|
792
1009
|
attr_reader :element_type, :size_type
|
793
1010
|
|
794
1011
|
def initialize(element_type, size_type = nil)
|
795
|
-
@element_type = element_type
|
796
1012
|
@size_type = size_type
|
797
|
-
if
|
798
|
-
|
1013
|
+
if !size_type.nil? && size_type.from == 0 && size_type.to == 0
|
1014
|
+
@element_type = PUnitType::DEFAULT
|
1015
|
+
else
|
1016
|
+
@element_type = element_type
|
799
1017
|
end
|
800
1018
|
end
|
801
1019
|
|
@@ -1001,6 +1219,32 @@ class PStringType < PScalarType
|
|
1001
1219
|
end
|
1002
1220
|
end
|
1003
1221
|
|
1222
|
+
def self.new_function(_, loader)
|
1223
|
+
@new_function ||= Puppet::Functions.create_loaded_function(:new_string, loader) do
|
1224
|
+
local_types do
|
1225
|
+
type 'Format = Pattern[/^%([\s\+\-#0\[\{<\(\|]*)([1-9][0-9]*)?(?:\.([0-9]+))?([a-zA-Z])/]'
|
1226
|
+
type 'ContainerFormat = Struct[{
|
1227
|
+
Optional[format] => String,
|
1228
|
+
Optional[separator] => String,
|
1229
|
+
Optional[separator2] => String,
|
1230
|
+
Optional[string_formats] => Hash[Type, Format]
|
1231
|
+
}]'
|
1232
|
+
type 'TypeMap = Hash[Type, Variant[Format, ContainerFormat]]'
|
1233
|
+
type 'Convertible = Any'
|
1234
|
+
type 'Formats = Variant[Default, String[1], TypeMap]'
|
1235
|
+
end
|
1236
|
+
|
1237
|
+
dispatch :from_args do
|
1238
|
+
param 'Convertible', :from
|
1239
|
+
optional_param 'Formats', :string_formats
|
1240
|
+
end
|
1241
|
+
|
1242
|
+
def from_args(from, formats = :default)
|
1243
|
+
StringConverter.singleton.convert(from, formats)
|
1244
|
+
end
|
1245
|
+
end
|
1246
|
+
end
|
1247
|
+
|
1004
1248
|
DEFAULT = PStringType.new(nil)
|
1005
1249
|
NON_EMPTY = PStringType.new(PIntegerType.new(1))
|
1006
1250
|
|
@@ -1059,7 +1303,12 @@ class PRegexpType < PScalarType
|
|
1059
1303
|
attr_reader :pattern
|
1060
1304
|
|
1061
1305
|
def initialize(pattern)
|
1062
|
-
|
1306
|
+
if pattern.is_a?(Regexp)
|
1307
|
+
@regexp = pattern
|
1308
|
+
@pattern = pattern.source
|
1309
|
+
else
|
1310
|
+
@pattern = pattern
|
1311
|
+
end
|
1063
1312
|
end
|
1064
1313
|
|
1065
1314
|
def regexp
|
@@ -1146,6 +1395,34 @@ class PBooleanType < PScalarType
|
|
1146
1395
|
o == true || o == false
|
1147
1396
|
end
|
1148
1397
|
|
1398
|
+
def self.new_function(_, loader)
|
1399
|
+
@new_function ||= Puppet::Functions.create_loaded_function(:new_boolean, loader) do
|
1400
|
+
dispatch :from_args do
|
1401
|
+
param 'Variant[Undef, Integer, Float, Boolean, String]', :from
|
1402
|
+
end
|
1403
|
+
|
1404
|
+
def from_args(from)
|
1405
|
+
from = from.downcase if from.is_a?(String)
|
1406
|
+
case from
|
1407
|
+
when NilClass
|
1408
|
+
throw :undefined_value
|
1409
|
+
when Float
|
1410
|
+
from != 0.0
|
1411
|
+
when Integer
|
1412
|
+
from != 0
|
1413
|
+
when true, false
|
1414
|
+
from
|
1415
|
+
when 'false', 'no', 'n'
|
1416
|
+
false
|
1417
|
+
when 'true', 'yes', 'y'
|
1418
|
+
true
|
1419
|
+
else
|
1420
|
+
raise TypeConversionError.new("Value '#{from}' of type '#{from.class}' cannot be converted to Boolean")
|
1421
|
+
end
|
1422
|
+
end
|
1423
|
+
end
|
1424
|
+
end
|
1425
|
+
|
1149
1426
|
DEFAULT = PBooleanType.new
|
1150
1427
|
|
1151
1428
|
protected
|
@@ -1264,8 +1541,8 @@ class PStructType < PAnyType
|
|
1264
1541
|
tc = TypeCalculator.singleton
|
1265
1542
|
PIterableType.new(
|
1266
1543
|
PTupleType.new([
|
1267
|
-
|
1268
|
-
|
1544
|
+
PVariantType.maybe_create(@elements.map {|se| se.key_type }),
|
1545
|
+
PVariantType.maybe_create(@elements.map {|se| se.value_type })],
|
1269
1546
|
PHashType::KEY_PAIR_TUPLE_SIZE))
|
1270
1547
|
end
|
1271
1548
|
end
|
@@ -1294,6 +1571,12 @@ class PStructType < PAnyType
|
|
1294
1571
|
end && matched == o.size
|
1295
1572
|
end
|
1296
1573
|
|
1574
|
+
def new_function(loader)
|
1575
|
+
# Simply delegate to Hash type and let the higher level assertion deal with
|
1576
|
+
# compliance with the Struct type regarding the produced result.
|
1577
|
+
PHashType.new_function(self, loader)
|
1578
|
+
end
|
1579
|
+
|
1297
1580
|
DEFAULT = PStructType.new(EMPTY_ARRAY)
|
1298
1581
|
|
1299
1582
|
protected
|
@@ -1441,7 +1724,7 @@ class PTupleType < PAnyType
|
|
1441
1724
|
end
|
1442
1725
|
|
1443
1726
|
def iterable_type(guard = nil)
|
1444
|
-
PIterableType.new(
|
1727
|
+
PIterableType.new(PVariantType.maybe_create(types))
|
1445
1728
|
end
|
1446
1729
|
|
1447
1730
|
# Returns the number of elements accepted [min, max] in the tuple
|
@@ -1477,6 +1760,12 @@ class PTupleType < PAnyType
|
|
1477
1760
|
self.class == o.class && @types == o.types && @size_type == o.size_type
|
1478
1761
|
end
|
1479
1762
|
|
1763
|
+
def new_function(loader)
|
1764
|
+
# Simply delegate to Array type and let the higher level assertion deal with
|
1765
|
+
# compliance with the Tuple type regarding the produced result.
|
1766
|
+
PArrayType.new_function(self, loader)
|
1767
|
+
end
|
1768
|
+
|
1480
1769
|
DATA = PTupleType.new([PDataType::DEFAULT], PCollectionType::DEFAULT_SIZE)
|
1481
1770
|
DEFAULT = PTupleType.new(EMPTY_ARRAY)
|
1482
1771
|
|
@@ -1666,6 +1955,44 @@ class PArrayType < PCollectionType
|
|
1666
1955
|
size_t.nil? || size_t.instance?(o.size, guard)
|
1667
1956
|
end
|
1668
1957
|
|
1958
|
+
# Returns a new function that produces an Array
|
1959
|
+
#
|
1960
|
+
def self.new_function(_, loader)
|
1961
|
+
@new_function ||= Puppet::Functions.create_loaded_function(:new_array, loader) do
|
1962
|
+
|
1963
|
+
dispatch :from_args do
|
1964
|
+
param 'Any', :from
|
1965
|
+
optional_param 'Boolean', :wrap
|
1966
|
+
end
|
1967
|
+
|
1968
|
+
def from_args(from, wrap = false)
|
1969
|
+
case from
|
1970
|
+
when NilClass
|
1971
|
+
if wrap
|
1972
|
+
[nil]
|
1973
|
+
else
|
1974
|
+
throw :undefined_value
|
1975
|
+
end
|
1976
|
+
when Array
|
1977
|
+
from
|
1978
|
+
when Hash
|
1979
|
+
wrap ? [from] : from.to_a
|
1980
|
+
else
|
1981
|
+
if wrap
|
1982
|
+
[from]
|
1983
|
+
else
|
1984
|
+
if PIterableType::DEFAULT.instance?(from)
|
1985
|
+
Iterable.on(from).to_a
|
1986
|
+
else
|
1987
|
+
t = Puppet::Pops::Types::TypeCalculator.singleton.infer(from).generalize
|
1988
|
+
raise TypeConversionError.new("Value of type '#{t}' cannot be converted to Array")
|
1989
|
+
end
|
1990
|
+
end
|
1991
|
+
end
|
1992
|
+
end
|
1993
|
+
end
|
1994
|
+
end
|
1995
|
+
|
1669
1996
|
DATA = PArrayType.new(PDataType::DEFAULT, DEFAULT_SIZE)
|
1670
1997
|
DEFAULT = PArrayType.new(nil)
|
1671
1998
|
EMPTY = PArrayType.new(PUnitType::DEFAULT, ZERO_SIZE)
|
@@ -1716,9 +2043,10 @@ class PHashType < PCollectionType
|
|
1716
2043
|
|
1717
2044
|
def initialize(key_type, value_type, size_type = nil)
|
1718
2045
|
super(value_type, size_type)
|
1719
|
-
|
1720
|
-
|
1721
|
-
|
2046
|
+
if !size_type.nil? && size_type.from == 0 && size_type.to == 0
|
2047
|
+
@key_type = PUnitType::DEFAULT
|
2048
|
+
else
|
2049
|
+
@key_type = key_type
|
1722
2050
|
end
|
1723
2051
|
end
|
1724
2052
|
|
@@ -1788,6 +2116,53 @@ class PHashType < PCollectionType
|
|
1788
2116
|
self == EMPTY
|
1789
2117
|
end
|
1790
2118
|
|
2119
|
+
# Returns a new function that produces a Hash
|
2120
|
+
#
|
2121
|
+
def self.new_function(_, loader)
|
2122
|
+
@new_function ||= Puppet::Functions.create_loaded_function(:new_hash, loader) do
|
2123
|
+
local_types do
|
2124
|
+
type 'KeyValueArray = Array[Tuple[Any,Any],1]'
|
2125
|
+
end
|
2126
|
+
|
2127
|
+
dispatch :from_tuples do
|
2128
|
+
param 'KeyValueArray', :from
|
2129
|
+
end
|
2130
|
+
|
2131
|
+
dispatch :from_array do
|
2132
|
+
param 'Any', :from
|
2133
|
+
end
|
2134
|
+
|
2135
|
+
def from_tuples(tuple_array)
|
2136
|
+
Hash[tuple_array]
|
2137
|
+
end
|
2138
|
+
|
2139
|
+
def from_array(from)
|
2140
|
+
case from
|
2141
|
+
when NilClass
|
2142
|
+
throw :undefined_value
|
2143
|
+
when Array
|
2144
|
+
if from.size == 0
|
2145
|
+
{}
|
2146
|
+
else
|
2147
|
+
unless from.size % 2 == 0
|
2148
|
+
raise TypeConversionError.new("odd number of arguments for Hash")
|
2149
|
+
end
|
2150
|
+
Hash[*from]
|
2151
|
+
end
|
2152
|
+
when Hash
|
2153
|
+
from
|
2154
|
+
else
|
2155
|
+
if PIterableType::DEFAULT.instance?(from)
|
2156
|
+
Hash[*Iterable.on(from).to_a]
|
2157
|
+
else
|
2158
|
+
t = Puppet::Pops::Types::TypeCalculator.singleton.infer(from).generalize
|
2159
|
+
raise TypeConversionError.new("Value of type '#{t}' cannot be converted to Hash")
|
2160
|
+
end
|
2161
|
+
end
|
2162
|
+
end
|
2163
|
+
end
|
2164
|
+
end
|
2165
|
+
|
1791
2166
|
DEFAULT = PHashType.new(nil, nil)
|
1792
2167
|
KEY_PAIR_TUPLE_SIZE = PIntegerType.new(2,2)
|
1793
2168
|
DEFAULT_KEY_PAIR_TUPLE = PTupleType.new([PUnitType::DEFAULT, PUnitType::DEFAULT], KEY_PAIR_TUPLE_SIZE)
|
@@ -1826,9 +2201,21 @@ class PVariantType < PAnyType
|
|
1826
2201
|
|
1827
2202
|
attr_reader :types
|
1828
2203
|
|
2204
|
+
# Checks if the number of unique types in the given array is greater than one, and if so
|
2205
|
+
# creates a Variant with those types and returns it. If only one unique type is found,
|
2206
|
+
# that type is instead returned.
|
2207
|
+
#
|
2208
|
+
# @param types [Array<PAnyType>] the variants
|
2209
|
+
# @return [PAnyType] the resulting type
|
2210
|
+
# @api public
|
2211
|
+
def self.maybe_create(types)
|
2212
|
+
types = types.uniq
|
2213
|
+
types.size == 1 ? types[0] : new(types)
|
2214
|
+
end
|
2215
|
+
|
1829
2216
|
# @param types [Array[PAnyType]] the variants
|
1830
2217
|
def initialize(types)
|
1831
|
-
@types = types.
|
2218
|
+
@types = types.freeze
|
1832
2219
|
end
|
1833
2220
|
|
1834
2221
|
def accept(visitor, guard)
|
@@ -1848,7 +2235,7 @@ class PVariantType < PAnyType
|
|
1848
2235
|
if self == DEFAULT || self == DATA
|
1849
2236
|
self
|
1850
2237
|
else
|
1851
|
-
alter_type_array(@types, :generalize) { |altered| PVariantType.
|
2238
|
+
alter_type_array(@types, :generalize) { |altered| PVariantType.maybe_create(altered) }
|
1852
2239
|
end
|
1853
2240
|
end
|
1854
2241
|
|
@@ -1869,7 +2256,7 @@ class PVariantType < PAnyType
|
|
1869
2256
|
types[0]
|
1870
2257
|
elsif types.any? { |t| t.is_a?(PUndefType) }
|
1871
2258
|
# Undef entry present. Use an OptionalType with a normalized Variant of all types that are not Undef
|
1872
|
-
POptionalType.new(PVariantType.
|
2259
|
+
POptionalType.new(PVariantType.maybe_create(types.reject { |ot| ot.is_a?(PUndefType) }).normalize(guard)).normalize(guard)
|
1873
2260
|
else
|
1874
2261
|
# Merge all variants into this one
|
1875
2262
|
types = types.map do |t|
|
@@ -1889,11 +2276,12 @@ class PVariantType < PAnyType
|
|
1889
2276
|
types = merge_patterns(types)
|
1890
2277
|
types = merge_int_ranges(types)
|
1891
2278
|
types = merge_float_ranges(types)
|
2279
|
+
types = merge_version_ranges(types)
|
1892
2280
|
|
1893
2281
|
if types.size == 1
|
1894
2282
|
types[0]
|
1895
2283
|
else
|
1896
|
-
modified || types.size != size_before_merge ? PVariantType.
|
2284
|
+
modified || types.size != size_before_merge ? PVariantType.maybe_create(types) : self
|
1897
2285
|
end
|
1898
2286
|
end
|
1899
2287
|
end
|
@@ -1965,7 +2353,7 @@ class PVariantType < PAnyType
|
|
1965
2353
|
optionals = parts[0]
|
1966
2354
|
if optionals.size > 1
|
1967
2355
|
others = parts[1]
|
1968
|
-
others << POptionalType.new(PVariantType.
|
2356
|
+
others << POptionalType.new(PVariantType.maybe_create(optionals.map { |optional| optional.type }).normalize)
|
1969
2357
|
array = others
|
1970
2358
|
end
|
1971
2359
|
end
|
@@ -1979,7 +2367,7 @@ class PVariantType < PAnyType
|
|
1979
2367
|
not_undefs = parts[0]
|
1980
2368
|
if not_undefs.size > 1
|
1981
2369
|
others = parts[1]
|
1982
|
-
others << PNotUndefType.new(PVariantType.
|
2370
|
+
others << PNotUndefType.new(PVariantType.maybe_create(not_undefs.map { |not_undef| not_undef.type }).normalize)
|
1983
2371
|
array = others
|
1984
2372
|
end
|
1985
2373
|
end
|
@@ -2033,6 +2421,15 @@ class PVariantType < PAnyType
|
|
2033
2421
|
array
|
2034
2422
|
end
|
2035
2423
|
|
2424
|
+
def merge_version_ranges(array)
|
2425
|
+
if array.size > 1
|
2426
|
+
parts = array.partition {|t| t.is_a?(PSemVerType) }
|
2427
|
+
ranges = parts[0]
|
2428
|
+
array = [PSemVerType.new(*ranges.map(&:ranges).flatten)] + parts[1] if ranges.size > 1
|
2429
|
+
end
|
2430
|
+
array
|
2431
|
+
end
|
2432
|
+
|
2036
2433
|
# @api private
|
2037
2434
|
def merge_ranges(ranges)
|
2038
2435
|
result = []
|
@@ -2054,58 +2451,6 @@ class PVariantType < PAnyType
|
|
2054
2451
|
end
|
2055
2452
|
end
|
2056
2453
|
|
2057
|
-
# @api public
|
2058
|
-
#
|
2059
|
-
class PRuntimeType < PAnyType
|
2060
|
-
attr_reader :runtime, :runtime_type_name
|
2061
|
-
|
2062
|
-
def initialize(runtime, runtime_type_name = nil)
|
2063
|
-
@runtime = runtime
|
2064
|
-
@runtime_type_name = runtime_type_name
|
2065
|
-
end
|
2066
|
-
|
2067
|
-
def hash
|
2068
|
-
@runtime.hash ^ @runtime_type_name.hash
|
2069
|
-
end
|
2070
|
-
|
2071
|
-
def eql?(o)
|
2072
|
-
self.class == o.class && @runtime == o.runtime && @runtime_type_name == o.runtime_type_name
|
2073
|
-
end
|
2074
|
-
|
2075
|
-
def instance?(o, guard = nil)
|
2076
|
-
assignable?(TypeCalculator.infer(o), guard)
|
2077
|
-
end
|
2078
|
-
|
2079
|
-
def iterable?(guard = nil)
|
2080
|
-
c = class_from_string(@runtime_type_name)
|
2081
|
-
c.nil? ? false : c < Iterable
|
2082
|
-
end
|
2083
|
-
|
2084
|
-
def iterable_type(guard = nil)
|
2085
|
-
iterable?(guard) ? PIterableType.new(self) : nil
|
2086
|
-
end
|
2087
|
-
|
2088
|
-
DEFAULT = PRuntimeType.new(nil)
|
2089
|
-
|
2090
|
-
protected
|
2091
|
-
|
2092
|
-
# Assignable if o's has the same runtime and the runtime name resolves to
|
2093
|
-
# a class that is the same or subclass of t1's resolved runtime type name
|
2094
|
-
# @api private
|
2095
|
-
def _assignable?(o, guard)
|
2096
|
-
return false unless o.is_a?(PRuntimeType)
|
2097
|
-
return false unless @runtime == o.runtime
|
2098
|
-
return true if @runtime_type_name.nil? # t1 is wider
|
2099
|
-
return false if o.runtime_type_name.nil? # t1 not nil, so o can not be wider
|
2100
|
-
|
2101
|
-
# NOTE: This only supports Ruby, must change when/if the set of runtimes is expanded
|
2102
|
-
c1 = class_from_string(@runtime_type_name)
|
2103
|
-
c2 = class_from_string(o.runtime_type_name)
|
2104
|
-
return false unless c1.is_a?(Module) && c2.is_a?(Module)
|
2105
|
-
!!(c2 <= c1)
|
2106
|
-
end
|
2107
|
-
end
|
2108
|
-
|
2109
2454
|
# Abstract representation of a type that can be placed in a Catalog.
|
2110
2455
|
# @api public
|
2111
2456
|
#
|
@@ -2130,6 +2475,8 @@ end
|
|
2130
2475
|
class PHostClassType < PCatalogEntryType
|
2131
2476
|
attr_reader :class_name
|
2132
2477
|
|
2478
|
+
NAME = 'Class'.freeze
|
2479
|
+
|
2133
2480
|
def initialize(class_name)
|
2134
2481
|
@class_name = class_name
|
2135
2482
|
end
|
@@ -2141,6 +2488,10 @@ class PHostClassType < PCatalogEntryType
|
|
2141
2488
|
self.class == o.class && @class_name == o.class_name
|
2142
2489
|
end
|
2143
2490
|
|
2491
|
+
def simple_name
|
2492
|
+
NAME
|
2493
|
+
end
|
2494
|
+
|
2144
2495
|
DEFAULT = PHostClassType.new(nil)
|
2145
2496
|
|
2146
2497
|
protected
|
@@ -2159,19 +2510,20 @@ end
|
|
2159
2510
|
# @api public
|
2160
2511
|
#
|
2161
2512
|
class PResourceType < PCatalogEntryType
|
2162
|
-
attr_reader :type_name, :title
|
2513
|
+
attr_reader :type_name, :title, :downcased_name
|
2163
2514
|
|
2164
2515
|
def initialize(type_name, title = nil)
|
2165
|
-
@type_name = type_name
|
2166
|
-
@title = title
|
2516
|
+
@type_name = type_name.freeze
|
2517
|
+
@title = title.freeze
|
2518
|
+
@downcased_name = type_name.nil? ? nil : @type_name.downcase.freeze
|
2167
2519
|
end
|
2168
2520
|
|
2169
|
-
def
|
2170
|
-
@
|
2521
|
+
def eql?(o)
|
2522
|
+
self.class == o.class && @downcased_name == o.downcased_name && @title == o.title
|
2171
2523
|
end
|
2172
2524
|
|
2173
|
-
def
|
2174
|
-
|
2525
|
+
def hash
|
2526
|
+
@downcased_name.hash ^ @title.hash
|
2175
2527
|
end
|
2176
2528
|
|
2177
2529
|
DEFAULT = PResourceType.new(nil)
|
@@ -2180,11 +2532,7 @@ class PResourceType < PCatalogEntryType
|
|
2180
2532
|
|
2181
2533
|
# @api private
|
2182
2534
|
def _assignable?(o, guard)
|
2183
|
-
|
2184
|
-
return true if @type_name.nil?
|
2185
|
-
return false if @type_name != o.type_name
|
2186
|
-
return true if @title.nil?
|
2187
|
-
@title == o.title
|
2535
|
+
o.is_a?(PResourceType) && (@downcased_name.nil? || @downcased_name == o.downcased_name && (@title.nil? || @title == o.title))
|
2188
2536
|
end
|
2189
2537
|
end
|
2190
2538
|
|
@@ -2222,6 +2570,10 @@ class POptionalType < PTypeWithContainedType
|
|
2222
2570
|
end
|
2223
2571
|
end
|
2224
2572
|
|
2573
|
+
def new_function(loader)
|
2574
|
+
optional_type.new_function(loader)
|
2575
|
+
end
|
2576
|
+
|
2225
2577
|
DEFAULT = POptionalType.new(nil)
|
2226
2578
|
|
2227
2579
|
protected
|
@@ -2239,11 +2591,10 @@ class POptionalType < PTypeWithContainedType
|
|
2239
2591
|
end
|
2240
2592
|
|
2241
2593
|
class PTypeReferenceType < PAnyType
|
2242
|
-
attr_reader :
|
2594
|
+
attr_reader :type_string
|
2243
2595
|
|
2244
|
-
def initialize(
|
2245
|
-
@
|
2246
|
-
@parameters = parameters.nil? ? EMPTY_ARRAY : parameters
|
2596
|
+
def initialize(type_string)
|
2597
|
+
@type_string = type_string
|
2247
2598
|
end
|
2248
2599
|
|
2249
2600
|
def callable?(args)
|
@@ -2255,11 +2606,15 @@ class PTypeReferenceType < PAnyType
|
|
2255
2606
|
end
|
2256
2607
|
|
2257
2608
|
def hash
|
2258
|
-
@
|
2609
|
+
@type_string.hash
|
2259
2610
|
end
|
2260
2611
|
|
2261
2612
|
def eql?(o)
|
2262
|
-
super && o.
|
2613
|
+
super && o.type_string == @type_string
|
2614
|
+
end
|
2615
|
+
|
2616
|
+
def resolve(type_parser, loader)
|
2617
|
+
type_parser.parse(@type_string, loader)
|
2263
2618
|
end
|
2264
2619
|
|
2265
2620
|
protected
|
@@ -2278,6 +2633,7 @@ end
|
|
2278
2633
|
# might contain self recursion. Whether or not that is the case is computed and remembered when the alias
|
2279
2634
|
# is resolved since guarding against self recursive constructs is relatively expensive.
|
2280
2635
|
#
|
2636
|
+
# @api public
|
2281
2637
|
class PTypeAliasType < PAnyType
|
2282
2638
|
attr_reader :name
|
2283
2639
|
|
@@ -2313,6 +2669,10 @@ class PTypeAliasType < PAnyType
|
|
2313
2669
|
guarded_recursion(guard, false) { |g| resolved_type.callable_args?(callable, g) }
|
2314
2670
|
end
|
2315
2671
|
|
2672
|
+
def check_self_recursion(originator)
|
2673
|
+
resolved_type.check_self_recursion(originator) unless originator.equal?(self)
|
2674
|
+
end
|
2675
|
+
|
2316
2676
|
def kind_of_callable?(optional=true, guard = nil)
|
2317
2677
|
guarded_recursion(guard, false) { |g| resolved_type.kind_of_callable?(optional, g) }
|
2318
2678
|
end
|
@@ -2406,6 +2766,10 @@ class PTypeAliasType < PAnyType
|
|
2406
2766
|
@resolved_type = nil
|
2407
2767
|
raise
|
2408
2768
|
end
|
2769
|
+
else
|
2770
|
+
# An alias may appoint an Object type that isn't resolved yet. The default type
|
2771
|
+
# reference is used to prevent endless recursion and should not be resolved here.
|
2772
|
+
@resolved_type.resolve(type_parser, loader) unless @resolved_type.equal?(PTypeReferenceType::DEFAULT)
|
2409
2773
|
end
|
2410
2774
|
self
|
2411
2775
|
end
|
@@ -2416,7 +2780,7 @@ class PTypeAliasType < PAnyType
|
|
2416
2780
|
|
2417
2781
|
def accept(visitor, guard)
|
2418
2782
|
guarded_recursion(guard, nil) do |g|
|
2419
|
-
super
|
2783
|
+
super(visitor, g)
|
2420
2784
|
resolved_type.accept(visitor, g)
|
2421
2785
|
end
|
2422
2786
|
end
|
@@ -2459,6 +2823,10 @@ class PTypeAliasType < PAnyType
|
|
2459
2823
|
resolved_type.assignable?(o, guard)
|
2460
2824
|
end
|
2461
2825
|
|
2826
|
+
def new_function(loader)
|
2827
|
+
resolved_type.new_function(loader)
|
2828
|
+
end
|
2829
|
+
|
2462
2830
|
private
|
2463
2831
|
|
2464
2832
|
def guarded_recursion(guard, dflt)
|
@@ -2484,7 +2852,7 @@ class PTypeAliasType < PAnyType
|
|
2484
2852
|
if real_types.size == 1
|
2485
2853
|
@resolved_type = real_types[0]
|
2486
2854
|
else
|
2487
|
-
@resolved_type = PVariantType.
|
2855
|
+
@resolved_type = PVariantType.maybe_create(real_types)
|
2488
2856
|
end
|
2489
2857
|
# Drop self recursion status in case it's not self recursive anymore
|
2490
2858
|
guard = RecursionGuard.new
|
@@ -2492,9 +2860,19 @@ class PTypeAliasType < PAnyType
|
|
2492
2860
|
@self_recursion = guard.recursive_this?(self)
|
2493
2861
|
end
|
2494
2862
|
end
|
2863
|
+
@resolved_type.check_self_recursion(self) if @self_recursion
|
2495
2864
|
end
|
2496
2865
|
|
2497
2866
|
DEFAULT = PTypeAliasType.new('UnresolvedAlias', nil, PTypeReferenceType::DEFAULT)
|
2498
2867
|
end
|
2499
2868
|
end
|
2500
2869
|
end
|
2870
|
+
|
2871
|
+
require 'puppet/pops/pcore'
|
2872
|
+
|
2873
|
+
require_relative 'puppet_object'
|
2874
|
+
require_relative 'p_object_type'
|
2875
|
+
require_relative 'p_runtime_type'
|
2876
|
+
require_relative 'p_sem_ver_type'
|
2877
|
+
require_relative 'p_sem_ver_range_type'
|
2878
|
+
require_relative 'implementation_registry'
|