puppet 4.2.3-x86-mingw32 → 4.3.0-x86-mingw32
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/Gemfile +3 -0
- data/README.md +1 -1
- data/ext/debian/puppet.init +0 -1
- data/ext/debian/puppet.logrotate +14 -5
- data/ext/osx/puppet.plist +0 -2
- data/ext/redhat/client.init +13 -5
- data/ext/redhat/logrotate +15 -3
- data/ext/redhat/puppet.spec.erb +5 -1
- data/ext/redhat/server.init +1 -1
- data/ext/systemd/puppet.service +1 -0
- data/lib/puppet.rb +12 -0
- data/lib/puppet/agent.rb +4 -4
- data/lib/puppet/agent/locker.rb +11 -2
- data/lib/puppet/application/agent.rb +5 -1
- data/lib/puppet/application/apply.rb +4 -0
- data/lib/puppet/application/filebucket.rb +78 -4
- data/lib/puppet/application/lookup.rb +356 -0
- data/lib/puppet/application/master.rb +3 -0
- data/lib/puppet/configurer.rb +9 -5
- data/lib/puppet/context.rb +16 -1
- data/lib/puppet/context/trusted_information.rb +21 -1
- data/lib/puppet/daemon.rb +17 -13
- data/lib/puppet/data_binding.rb +4 -2
- data/lib/puppet/data_providers.rb +12 -13
- data/lib/puppet/data_providers/data_adapter.rb +7 -68
- data/lib/puppet/data_providers/data_function_support.rb +5 -26
- data/lib/puppet/data_providers/function_env_data_provider.rb +0 -10
- data/lib/puppet/data_providers/function_module_data_provider.rb +0 -22
- data/lib/puppet/data_providers/hiera_config.rb +106 -0
- data/lib/puppet/data_providers/hiera_env_data_provider.rb +18 -0
- data/lib/puppet/data_providers/hiera_interpolate.rb +97 -0
- data/lib/puppet/data_providers/hiera_module_data_provider.rb +23 -0
- data/lib/puppet/data_providers/hiera_support.rb +37 -0
- data/lib/puppet/data_providers/json_data_provider_factory.rb +31 -0
- data/lib/puppet/data_providers/lookup_adapter.rb +200 -0
- data/lib/puppet/data_providers/yaml_data_provider_factory.rb +32 -0
- data/lib/puppet/defaults.rb +12 -2
- data/lib/puppet/error.rb +4 -0
- data/lib/puppet/face/module/changes.rb +2 -1
- data/lib/puppet/feature/cfacter.rb +1 -0
- data/lib/puppet/file_bucket/dipper.rb +58 -2
- data/lib/puppet/functions.rb +2 -4
- data/lib/puppet/functions/assert_type.rb +48 -12
- data/lib/puppet/functions/defined.rb +79 -48
- data/lib/puppet/functions/each.rb +85 -27
- data/lib/puppet/functions/filter.rb +58 -23
- data/lib/puppet/functions/hiera.rb +76 -3
- data/lib/puppet/functions/hiera_array.rb +65 -3
- data/lib/puppet/functions/hiera_hash.rb +74 -2
- data/lib/puppet/functions/hiera_include.rb +75 -2
- data/lib/puppet/functions/lookup.rb +19 -17
- data/lib/puppet/functions/map.rb +56 -21
- data/lib/puppet/functions/match.rb +29 -12
- data/lib/puppet/functions/reduce.rb +95 -58
- data/lib/puppet/functions/versioncmp.rb +36 -0
- data/lib/puppet/functions/with.rb +15 -7
- data/lib/puppet/indirector/catalog/compiler.rb +3 -3
- data/lib/puppet/indirector/catalog/static_compiler.rb +46 -30
- data/lib/puppet/indirector/data_binding/none.rb +4 -1
- data/lib/puppet/indirector/file_bucket_file/file.rb +58 -1
- data/lib/puppet/indirector/hiera.rb +4 -0
- data/lib/puppet/indirector/json.rb +1 -1
- data/lib/puppet/indirector/msgpack.rb +1 -1
- data/lib/puppet/indirector/request.rb +7 -8
- data/lib/puppet/indirector/resource_type/parser.rb +5 -3
- data/lib/puppet/info_service.rb +7 -0
- data/lib/puppet/info_service/class_information_service.rb +111 -0
- data/lib/puppet/module_tool/metadata.rb +32 -9
- data/lib/puppet/module_tool/skeleton/templates/generator/README.md.erb +42 -38
- data/lib/puppet/network/authconfig.rb +21 -1
- data/lib/puppet/network/authorization.rb +8 -1
- data/lib/puppet/network/http/api/master/v3.rb +7 -1
- data/lib/puppet/network/http/api/master/v3/environment.rb +59 -0
- data/lib/puppet/node/environment.rb +9 -2
- data/lib/puppet/parser.rb +3 -0
- data/lib/puppet/parser/ast/pops_bridge.rb +39 -1
- data/lib/puppet/parser/compiler.rb +302 -12
- data/lib/puppet/parser/compiler/catalog_validator.rb +33 -0
- data/lib/puppet/parser/compiler/catalog_validator/env_relationship_validator.rb +64 -0
- data/lib/puppet/parser/compiler/catalog_validator/relationship_validator.rb +38 -0
- data/lib/puppet/parser/compiler/catalog_validator/site_validator.rb +20 -0
- data/lib/puppet/parser/environment_compiler.rb +165 -0
- data/lib/puppet/parser/functions/assert_type.rb +46 -16
- data/lib/puppet/parser/functions/defined.rb +105 -68
- data/lib/puppet/parser/functions/each.rb +85 -27
- data/lib/puppet/parser/functions/filter.rb +59 -23
- data/lib/puppet/parser/functions/hiera.rb +83 -27
- data/lib/puppet/parser/functions/hiera_array.rb +71 -28
- data/lib/puppet/parser/functions/hiera_hash.rb +81 -30
- data/lib/puppet/parser/functions/hiera_include.rb +81 -40
- data/lib/puppet/parser/functions/map.rb +55 -20
- data/lib/puppet/parser/functions/match.rb +27 -12
- data/lib/puppet/parser/functions/reduce.rb +97 -60
- data/lib/puppet/parser/functions/with.rb +16 -8
- data/lib/puppet/parser/resource.rb +98 -19
- data/lib/puppet/plugins/configuration.rb +3 -2
- data/lib/puppet/plugins/data_providers.rb +12 -60
- data/lib/puppet/plugins/data_providers/data_provider.rb +283 -0
- data/lib/puppet/plugins/data_providers/registry.rb +84 -0
- data/lib/puppet/pops.rb +19 -17
- data/lib/puppet/pops/adapters.rb +12 -0
- data/lib/puppet/pops/binder/binder.rb +2 -2
- data/lib/puppet/pops/binder/bindings_checker.rb +1 -1
- data/lib/puppet/pops/binder/bindings_label_provider.rb +3 -1
- data/lib/puppet/pops/binder/bindings_loader.rb +6 -2
- data/lib/puppet/pops/binder/bindings_model_meta.rb +2 -2
- data/lib/puppet/pops/binder/config/binder_config.rb +1 -1
- data/lib/puppet/pops/binder/injector.rb +4 -4
- data/lib/puppet/pops/binder/key_factory.rb +3 -9
- data/lib/puppet/pops/binder/scheme_handler/module_scheme.rb +68 -9
- data/lib/puppet/pops/evaluator/access_operator.rb +27 -60
- data/lib/puppet/pops/evaluator/closure.rb +8 -8
- data/lib/puppet/pops/evaluator/collectors/abstract_collector.rb +1 -1
- data/lib/puppet/pops/evaluator/evaluator_impl.rb +5 -5
- data/lib/puppet/pops/evaluator/literal_evaluator.rb +87 -0
- data/lib/puppet/pops/evaluator/relationship_operator.rb +7 -1
- data/lib/puppet/pops/functions/dispatcher.rb +3 -3
- data/lib/puppet/pops/issues.rb +1 -1
- data/lib/puppet/pops/label_provider.rb +1 -1
- data/lib/puppet/pops/lookup.rb +25 -47
- data/lib/puppet/pops/lookup/explainer.rb +402 -0
- data/lib/puppet/pops/lookup/invocation.rb +117 -0
- data/lib/puppet/pops/merge_strategy.rb +73 -5
- data/lib/puppet/pops/model/factory.rb +34 -0
- data/lib/puppet/pops/model/model_label_provider.rb +10 -1
- data/lib/puppet/pops/model/model_meta.rb +15 -0
- data/lib/puppet/pops/model/model_tree_dumper.rb +18 -0
- data/lib/puppet/pops/parser/code_merger.rb +13 -1
- data/lib/puppet/pops/parser/egrammar.ra +56 -3
- data/lib/puppet/pops/parser/eparser.rb +1549 -1352
- data/lib/puppet/pops/parser/lexer2.rb +31 -6
- data/lib/puppet/pops/parser/locator.rb +1 -1
- data/lib/puppet/pops/parser/parser_support.rb +25 -13
- data/lib/puppet/pops/types/enumeration.rb +1 -2
- data/lib/puppet/pops/types/type_asserter.rb +16 -15
- data/lib/puppet/pops/types/type_assertion_error.rb +1 -0
- data/lib/puppet/pops/types/type_calculator.rb +171 -1020
- data/lib/puppet/pops/types/type_factory.rb +87 -148
- data/lib/puppet/pops/types/type_mismatch_describer.rb +743 -0
- data/lib/puppet/pops/types/type_parser.rb +116 -127
- data/lib/puppet/pops/types/types.rb +1394 -255
- data/lib/puppet/pops/types/types_meta.rb +0 -234
- data/lib/puppet/pops/validation.rb +7 -2
- data/lib/puppet/pops/validation/checker4_0.rb +28 -0
- data/lib/puppet/provider/augeas/augeas.rb +50 -0
- data/lib/puppet/provider/group/directoryservice.rb +10 -0
- data/lib/puppet/provider/package/dnf.rb +41 -0
- data/lib/puppet/provider/package/gem.rb +7 -2
- data/lib/puppet/provider/package/rpm.rb +1 -0
- data/lib/puppet/provider/package/windows/exe_package.rb +10 -8
- data/lib/puppet/provider/package/windows/msi_package.rb +4 -3
- data/lib/puppet/provider/package/windows/package.rb +9 -1
- data/lib/puppet/provider/package/yum.rb +14 -9
- data/lib/puppet/provider/service/bsd.rb +1 -1
- data/lib/puppet/provider/service/debian.rb +21 -0
- data/lib/puppet/provider/service/init.rb +6 -0
- data/lib/puppet/provider/service/rcng.rb +51 -0
- data/lib/puppet/provider/service/redhat.rb +2 -1
- data/lib/puppet/provider/service/smf.rb +43 -2
- data/lib/puppet/provider/service/src.rb +27 -0
- data/lib/puppet/provider/service/systemd.rb +15 -3
- data/lib/puppet/provider/sshkey/parsed.rb +19 -9
- data/lib/puppet/reference/report.rb +9 -12
- data/lib/puppet/reports.rb +5 -1
- data/lib/puppet/resource.rb +50 -73
- data/lib/puppet/resource/capability_finder.rb +95 -0
- data/lib/puppet/resource/catalog.rb +47 -7
- data/lib/puppet/resource/status.rb +0 -2
- data/lib/puppet/resource/type.rb +238 -44
- data/lib/puppet/resource/type_collection.rb +60 -2
- data/lib/puppet/settings.rb +2 -2
- data/lib/puppet/ssl/certificate_authority/interface.rb +2 -2
- data/lib/puppet/ssl/oids.rb +9 -1
- data/lib/puppet/transaction.rb +4 -1
- data/lib/puppet/transaction/additional_resource_generator.rb +71 -8
- data/lib/puppet/transaction/resource_harness.rb +9 -4
- data/lib/puppet/type.rb +74 -3
- data/lib/puppet/type/augeas.rb +8 -0
- data/lib/puppet/type/file/source.rb +14 -12
- data/lib/puppet/type/user.rb +4 -2
- data/lib/puppet/util/windows/security.rb +4 -1
- data/lib/puppet/util/windows/taskscheduler.rb +1 -1
- data/lib/puppet/version.rb +1 -1
- data/spec/fixtures/unit/application/environments/production/data/common.yaml +3 -0
- data/spec/fixtures/unit/application/environments/production/environment.conf +1 -0
- data/spec/fixtures/unit/data_providers/environments/hiera_bad_syntax_json/data/bad.json +3 -0
- data/spec/fixtures/unit/data_providers/environments/hiera_bad_syntax_json/environment.conf +2 -0
- data/spec/fixtures/unit/data_providers/environments/hiera_bad_syntax_json/hiera.yaml +5 -0
- data/spec/fixtures/unit/data_providers/environments/hiera_bad_syntax_json/manifests/site.pp +5 -0
- data/spec/fixtures/unit/data_providers/environments/hiera_bad_syntax_yaml/data/bad.yaml +3 -0
- data/spec/fixtures/unit/data_providers/environments/hiera_bad_syntax_yaml/environment.conf +2 -0
- data/spec/fixtures/unit/data_providers/environments/hiera_bad_syntax_yaml/hiera.yaml +5 -0
- data/spec/fixtures/unit/data_providers/environments/hiera_bad_syntax_yaml/manifests/site.pp +5 -0
- data/spec/fixtures/unit/data_providers/environments/hiera_defaults/data/common.yaml +2 -0
- data/spec/fixtures/unit/data_providers/environments/hiera_defaults/environment.conf +2 -0
- data/spec/fixtures/unit/data_providers/environments/hiera_defaults/manifests/site.pp +1 -0
- data/spec/fixtures/unit/data_providers/environments/hiera_defaults/modules/one/data/common.yaml +2 -0
- data/spec/fixtures/unit/data_providers/environments/hiera_defaults/modules/one/manifests/init.pp +5 -0
- data/spec/fixtures/unit/data_providers/environments/hiera_defaults/modules/one/metadata.json +9 -0
- data/spec/fixtures/unit/data_providers/environments/hiera_env_config/data1/first.json +3 -0
- data/spec/fixtures/unit/data_providers/environments/hiera_env_config/data1/name.yaml +2 -0
- data/spec/fixtures/unit/data_providers/environments/hiera_env_config/data1/second.json +3 -0
- data/spec/fixtures/unit/data_providers/environments/hiera_env_config/data1/single.yaml +2 -0
- data/spec/fixtures/unit/data_providers/environments/hiera_env_config/data2/single.yaml +2 -0
- data/spec/fixtures/unit/data_providers/environments/hiera_env_config/environment.conf +2 -0
- data/spec/fixtures/unit/data_providers/environments/hiera_env_config/hiera.yaml +18 -0
- data/spec/fixtures/unit/data_providers/environments/hiera_env_config/manifests/site.pp +5 -0
- data/spec/fixtures/unit/data_providers/environments/hiera_misc/data/common.yaml +46 -0
- data/spec/fixtures/unit/data_providers/environments/hiera_misc/environment.conf +2 -0
- data/spec/fixtures/unit/data_providers/environments/hiera_misc/manifests/site.pp +1 -0
- data/spec/fixtures/unit/data_providers/environments/hiera_misc/modules/one/data/common.yaml +30 -0
- data/spec/fixtures/unit/data_providers/environments/hiera_misc/modules/one/manifests/init.pp +13 -0
- data/spec/fixtures/unit/data_providers/environments/hiera_misc/modules/one/metadata.json +9 -0
- data/spec/fixtures/unit/data_providers/environments/hiera_module_config/environment.conf +2 -0
- data/spec/fixtures/unit/data_providers/environments/hiera_module_config/manifests/site.pp +1 -0
- data/spec/fixtures/unit/data_providers/environments/hiera_module_config/modules/one/data1/first.json +3 -0
- data/spec/fixtures/unit/data_providers/environments/hiera_module_config/modules/one/data1/name.yaml +1 -0
- data/spec/fixtures/unit/data_providers/environments/hiera_module_config/modules/one/data1/second.json +3 -0
- data/spec/fixtures/unit/data_providers/environments/hiera_module_config/modules/one/data1/single.yaml +2 -0
- data/spec/fixtures/unit/data_providers/environments/hiera_module_config/modules/one/data2/single.yaml +2 -0
- data/spec/fixtures/unit/data_providers/environments/hiera_module_config/modules/one/hiera.yaml +18 -0
- data/spec/fixtures/unit/data_providers/environments/hiera_module_config/modules/one/manifests/init.pp +5 -0
- data/spec/fixtures/unit/data_providers/environments/hiera_module_config/modules/one/metadata.json +9 -0
- data/spec/fixtures/unit/data_providers/environments/sample/modules/dataprovider/lib/puppet_x/helindbe/sample_env_data.rb +1 -0
- data/spec/fixtures/unit/data_providers/environments/sample/modules/dataprovider/lib/puppet_x/helindbe/sample_module_data.rb +1 -0
- data/spec/fixtures/unit/functions/lookup/environments/production/modules/hieraprovider/data/first.json +3 -0
- data/spec/fixtures/unit/functions/lookup/environments/production/modules/hieraprovider/hiera.yaml +8 -0
- data/spec/fixtures/unit/functions/lookup/environments/production/modules/hieraprovider/manifests/init.pp +5 -0
- data/spec/fixtures/unit/functions/lookup/environments/production/modules/hieraprovider/metadata.json +9 -0
- data/spec/fixtures/unit/functions/lookup/environments/production/modules/meta/lib/puppet/functions/meta/data.rb +9 -0
- data/spec/fixtures/unit/functions/lookup/environments/production/modules/meta/manifests/init.pp +3 -0
- data/spec/fixtures/unit/functions/lookup/environments/production/modules/meta/metadata.json +9 -0
- data/spec/fixtures/unit/functions/lookup/environments/production/modules/metawcp/lib/puppet/bindings/metawcp/default.rb +10 -0
- data/spec/fixtures/unit/functions/lookup/environments/production/modules/metawcp/lib/puppet_x/thallgren/sample_module_data.rb +23 -0
- data/spec/fixtures/unit/functions/lookup/environments/production/modules/metawcp/manifests/init.pp +3 -0
- data/spec/fixtures/unit/functions/lookup/environments/production/modules/metawcp/metadata.json +9 -0
- data/spec/fixtures/unit/provider/package/yum/yum-check-update-security.txt +184 -0
- data/spec/fixtures/vcr/cassettes/Puppet_Network_HTTP_Connection/when_handling_requests/_request_get/should_yield_to_the_block.yml +24 -0
- data/spec/fixtures/vcr/cassettes/Puppet_Network_HTTP_Connection/when_handling_requests/_request_head/should_yield_to_the_block.yml +24 -0
- data/spec/fixtures/vcr/cassettes/Puppet_Network_HTTP_Connection/when_handling_requests/_request_post/should_yield_to_the_block.yml +24 -0
- data/spec/integration/data_binding_spec.rb +229 -0
- data/spec/integration/file_bucket/file_spec.rb +2 -2
- data/spec/integration/parser/compiler_spec.rb +23 -19
- data/spec/integration/parser/resource_expressions_spec.rb +4 -4
- data/spec/integration/parser/undef_param_spec.rb +1 -1
- data/spec/integration/resource/catalog_spec.rb +1 -1
- data/spec/integration/type/package_spec.rb +2 -0
- data/spec/integration/util/windows/security_spec.rb +18 -0
- data/spec/lib/matchers/include_in_order.rb +2 -2
- data/spec/shared_behaviours/iterative_functions.rb +8 -8
- data/spec/spec_helper.rb +7 -0
- data/spec/unit/agent/locker_spec.rb +4 -4
- data/spec/unit/agent_spec.rb +0 -8
- data/spec/unit/application/agent_spec.rb +5 -0
- data/spec/unit/application/apply_spec.rb +8 -0
- data/spec/unit/application/filebucket_spec.rb +87 -1
- data/spec/unit/application/lookup_spec.rb +195 -0
- data/spec/unit/appmgmt_spec.rb +657 -0
- data/spec/unit/capability_spec.rb +414 -0
- data/spec/unit/configurer_spec.rb +7 -1
- data/spec/unit/context/trusted_information_spec.rb +24 -1
- data/spec/unit/daemon_spec.rb +18 -8
- data/spec/unit/data_providers/hiera_data_provider_spec.rb +201 -0
- data/spec/unit/file_bucket/dipper_spec.rb +210 -1
- data/spec/unit/functions/assert_type_spec.rb +5 -7
- data/spec/unit/functions/defined_spec.rb +2 -2
- data/spec/unit/functions/epp_spec.rb +2 -2
- data/spec/unit/functions/lookup_spec.rb +200 -9
- data/spec/unit/functions/regsubst_spec.rb +17 -8
- data/spec/unit/functions/scanf_spec.rb +1 -1
- data/spec/unit/functions/split_spec.rb +2 -2
- data/spec/unit/functions/versioncmp_spec.rb +36 -0
- data/spec/unit/functions4_spec.rb +58 -72
- data/spec/unit/indirector/catalog/compiler_spec.rb +28 -8
- data/spec/unit/indirector/catalog/static_compiler_spec.rb +38 -20
- data/spec/unit/indirector/data_binding/none_spec.rb +2 -2
- data/spec/unit/indirector/file_bucket_file/file_spec.rb +52 -1
- data/spec/unit/indirector/request_spec.rb +8 -8
- data/spec/unit/info_service_spec.rb +236 -0
- data/spec/unit/module_tool/metadata_spec.rb +31 -2
- data/spec/unit/network/authconfig_spec.rb +62 -32
- data/spec/unit/network/authorization_spec.rb +30 -2
- data/spec/unit/network/http/connection_spec.rb +14 -19
- data/spec/unit/parser/compiler_spec.rb +86 -2
- data/spec/unit/parser/functions/create_resources_spec.rb +1 -1
- data/spec/unit/parser/resource_spec.rb +2 -20
- data/spec/unit/pops/binder/config/binder_config_spec.rb +1 -1
- data/spec/unit/pops/binder/injector_spec.rb +3 -3
- data/spec/unit/pops/evaluator/access_ops_spec.rb +13 -11
- data/spec/unit/pops/evaluator/basic_expressions_spec.rb +1 -2
- data/spec/unit/pops/evaluator/evaluating_parser_spec.rb +19 -11
- data/spec/unit/pops/evaluator/literal_evaluator_spec.rb +43 -0
- data/spec/unit/pops/label_provider_spec.rb +5 -1
- data/spec/unit/pops/parser/lexer2_spec.rb +33 -7
- data/spec/unit/pops/parser/parse_application_spec.rb +40 -0
- data/spec/unit/pops/parser/parse_basic_expressions_spec.rb +4 -0
- data/spec/unit/pops/parser/parse_capabilities_spec.rb +47 -0
- data/spec/unit/pops/parser/parse_site_spec.rb +38 -0
- data/spec/unit/pops/parser/parser_rspec_helper.rb +5 -0
- data/spec/unit/pops/parser/parser_spec.rb +18 -0
- data/spec/unit/pops/types/type_calculator_spec.rb +427 -444
- data/spec/unit/pops/types/type_factory_spec.rb +12 -12
- data/spec/unit/pops/types/type_parser_spec.rb +7 -12
- data/spec/unit/pops/validator/validator_spec.rb +25 -0
- data/spec/unit/provider/augeas/augeas_spec.rb +50 -0
- data/spec/unit/provider/group/directoryservice_spec.rb +33 -0
- data/spec/unit/provider/group/windows_adsi_spec.rb +3 -0
- data/spec/unit/provider/package/dnf_spec.rb +92 -0
- data/spec/unit/provider/package/gem_spec.rb +7 -0
- data/spec/unit/provider/package/rpm_spec.rb +25 -2
- data/spec/unit/provider/package/windows/package_spec.rb +41 -0
- data/spec/unit/provider/package/yum_spec.rb +21 -13
- data/spec/unit/provider/scheduled_task/win32_taskscheduler_spec.rb +10 -0
- data/spec/unit/provider/service/debian_spec.rb +27 -0
- data/spec/unit/provider/service/rcng_spec.rb +41 -0
- data/spec/unit/provider/service/redhat_spec.rb +8 -1
- data/spec/unit/provider/service/smf_spec.rb +30 -5
- data/spec/unit/provider/service/src_spec.rb +19 -4
- data/spec/unit/provider/service/systemd_spec.rb +78 -29
- data/spec/unit/provider/sshkey/parsed_spec.rb +23 -0
- data/spec/unit/reports_spec.rb +10 -0
- data/spec/unit/resource/capability_finder_spec.rb +56 -0
- data/spec/unit/resource/catalog_spec.rb +31 -8
- data/spec/unit/resource/type_collection_spec.rb +23 -2
- data/spec/unit/resource/type_spec.rb +1 -1
- data/spec/unit/resource_spec.rb +22 -4
- data/spec/unit/settings_spec.rb +90 -1
- data/spec/unit/ssl/certificate_authority/interface_spec.rb +4 -3
- data/spec/unit/ssl/oids_spec.rb +8 -0
- data/spec/unit/transaction/additional_resource_generator_spec.rb +78 -5
- data/spec/unit/transaction/report_spec.rb +24 -1
- data/spec/unit/type/package_spec.rb +1 -0
- data/spec/unit/type/user_spec.rb +14 -7
- data/spec/unit/type_spec.rb +1 -1
- metadata +169 -5
- data/lib/puppet/pops/evaluator/callable_mismatch_describer.rb +0 -175
- data/spec/integration/data_binding.rb +0 -104
@@ -131,19 +131,42 @@ class Puppet::Pops::Parser::Lexer2
|
|
131
131
|
"type" => [:TYPE, 'type', 4],
|
132
132
|
"attr" => [:ATTR, 'attr', 4],
|
133
133
|
"private" => [:PRIVATE, 'private', 7],
|
134
|
-
# The following tokens exist in reserved form. Later they will be made
|
135
|
-
# live subject to a feature switch.
|
136
|
-
"application" => [:APPLICATION_R, 'application', 11],
|
137
|
-
"consumes" => [:CONSUMES_R, 'consumes', 8],
|
138
|
-
"produces" => [:PRODUCES_R, 'produces', 8],
|
139
134
|
}
|
140
135
|
|
141
136
|
KEYWORDS.each {|k,v| v[1].freeze; v.freeze }
|
142
137
|
KEYWORDS.freeze
|
143
138
|
|
139
|
+
# We maintain two different tables of tokens for the constructs
|
140
|
+
# introduced by application management. Which ones we use is decided in
|
141
|
+
# +initvars+; by selecting one or the other variant, we select whether we
|
142
|
+
# hit the appmgmt-specific code paths
|
143
|
+
APP_MANAGEMENT_TOKENS = {
|
144
|
+
:with_appm => {
|
145
|
+
"application" => [:APPLICATION, 'application', 11],
|
146
|
+
"consumes" => [:CONSUMES, 'consumes', 8],
|
147
|
+
"produces" => [:PRODUCES, 'produces', 8],
|
148
|
+
"site" => [:SITE, 'site', 4]
|
149
|
+
},
|
150
|
+
:without_appm => {
|
151
|
+
"application" => [:APPLICATION_R, 'application', 11],
|
152
|
+
"consumes" => [:CONSUMES_R, 'consumes', 8],
|
153
|
+
"produces" => [:PRODUCES_R, 'produces', 8],
|
154
|
+
"site" => [:SITE_R, 'site', 4]
|
155
|
+
}
|
156
|
+
}
|
157
|
+
|
158
|
+
APP_MANAGEMENT_TOKENS.each do |_, variant|
|
159
|
+
variant.each { |_,v| v[1].freeze; v.freeze }
|
160
|
+
variant.freeze
|
161
|
+
end
|
162
|
+
APP_MANAGEMENT_TOKENS.freeze
|
163
|
+
|
144
164
|
# Reverse lookup of keyword name to string
|
145
165
|
KEYWORD_NAMES = {}
|
146
166
|
KEYWORDS.each {|k, v| KEYWORD_NAMES[v[0]] = k }
|
167
|
+
APP_MANAGEMENT_TOKENS.each do |_, variant|
|
168
|
+
variant.each { |k,v| KEYWORD_NAMES[v[0]] = k }
|
169
|
+
end
|
147
170
|
KEYWORD_NAMES.freeze
|
148
171
|
|
149
172
|
PATTERN_WS = %r{[[:blank:]\r]+}
|
@@ -253,6 +276,8 @@ class Puppet::Pops::Parser::Lexer2
|
|
253
276
|
:brace_count => 0,
|
254
277
|
:after => nil,
|
255
278
|
}
|
279
|
+
appm_mode = Puppet[:app_management] ? :with_appm : :without_appm
|
280
|
+
@appm_keywords = APP_MANAGEMENT_TOKENS[appm_mode]
|
256
281
|
end
|
257
282
|
|
258
283
|
# Scans all of the content and returns it in an array
|
@@ -610,7 +635,7 @@ class Puppet::Pops::Parser::Lexer2
|
|
610
635
|
|
611
636
|
value = scn.scan(PATTERN_BARE_WORD)
|
612
637
|
if value && value =~ PATTERN_NAME
|
613
|
-
emit_completed(KEYWORDS[value] || [:NAME, value.freeze, scn.pos - before], before)
|
638
|
+
emit_completed(KEYWORDS[value] || @appm_keywords[value] || [:NAME, value.freeze, scn.pos - before], before)
|
614
639
|
elsif value
|
615
640
|
emit_completed([:WORD, value.freeze, scn.pos - before], before)
|
616
641
|
else
|
@@ -5,7 +5,7 @@ class Puppet::Pops::Parser::Locator
|
|
5
5
|
# performed of the given source string.
|
6
6
|
#
|
7
7
|
def self.locator(string, file, index = nil, char_offsets = false)
|
8
|
-
if
|
8
|
+
if char_offsets
|
9
9
|
LocatorForChars.new(string, file, index);
|
10
10
|
else
|
11
11
|
Locator19.new(string, file, index)
|
@@ -50,21 +50,28 @@ class Puppet::Pops::Parser::Parser
|
|
50
50
|
# lexer. Line and position is produced if the given semantic is a Positioned object and have been given an offset.
|
51
51
|
#
|
52
52
|
def error(semantic, message)
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
if semantic.is_a?(Puppet::Pops::Model::Positioned)
|
59
|
-
adapter = Puppet::Pops::Adapters::SourcePosAdapter.adapt(semantic)
|
60
|
-
adapter.locator = @lexer.locator
|
53
|
+
except = Puppet::ParseError.new(message)
|
54
|
+
if semantic.is_a?(Puppet::Pops::Parser::LexerSupport::TokenValue)
|
55
|
+
except.file = semantic[:file];
|
56
|
+
except.line = semantic[:line];
|
57
|
+
except.pos = semantic[:pos];
|
61
58
|
else
|
62
|
-
|
59
|
+
semantic = semantic.current() if semantic.is_a?(Puppet::Pops::Model::Factory)
|
60
|
+
|
61
|
+
# Adapt the model so it is possible to get location information.
|
62
|
+
# The model may not have been added to the source tree, so give it the lexer's locator
|
63
|
+
# directly instead of searching for the root Program where the locator is normally stored.
|
64
|
+
#
|
65
|
+
if semantic.is_a?(Puppet::Pops::Model::Positioned)
|
66
|
+
adapter = Puppet::Pops::Adapters::SourcePosAdapter.adapt(semantic)
|
67
|
+
adapter.locator = @lexer.locator
|
68
|
+
else
|
69
|
+
adapter = nil
|
70
|
+
end
|
71
|
+
except.file = @lexer.locator.file
|
72
|
+
except.line = adapter.line if adapter
|
73
|
+
except.pos = adapter.pos if adapter
|
63
74
|
end
|
64
|
-
except = Puppet::ParseError.new(message)
|
65
|
-
except.file = @lexer.locator.file
|
66
|
-
except.line = adapter.line if adapter
|
67
|
-
except.pos = adapter.pos if adapter
|
68
75
|
raise except
|
69
76
|
end
|
70
77
|
|
@@ -167,6 +174,11 @@ class Puppet::Pops::Parser::Parser
|
|
167
174
|
definition
|
168
175
|
end
|
169
176
|
|
177
|
+
def add_mapping(produces)
|
178
|
+
# The actual handling of mappings happens in PopsBridge
|
179
|
+
add_definition(produces)
|
180
|
+
end
|
181
|
+
|
170
182
|
# Transforms an array of expressions containing literal name expressions to calls if followed by an
|
171
183
|
# expression, or expression list
|
172
184
|
#
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# Utility module for type assertion
|
2
2
|
#
|
3
|
-
module Puppet::Pops::Types
|
3
|
+
module Puppet::Pops::Types
|
4
|
+
module TypeAsserter
|
4
5
|
# Asserts that a type_to_check is assignable to required_type and raises
|
5
6
|
# a {Puppet::ParseError} if that's not the case
|
6
7
|
#
|
@@ -9,8 +10,9 @@ module Puppet::Pops::Types::TypeAsserter
|
|
9
10
|
# @param type_to_check [PAnyType] Type to check against the required type
|
10
11
|
# @return The type_to_check argument
|
11
12
|
#
|
13
|
+
# @api public
|
12
14
|
def self.assert_assignable(subject, expected_type, type_to_check)
|
13
|
-
|
15
|
+
report_type_mismatch(subject, expected_type, type_to_check) unless expected_type.assignable?(type_to_check)
|
14
16
|
type_to_check
|
15
17
|
end
|
16
18
|
|
@@ -23,23 +25,22 @@ module Puppet::Pops::Types::TypeAsserter
|
|
23
25
|
# @param nil_ok [Boolean] Can be true to allow nil value. Optional and defaults to false
|
24
26
|
# @return The value argument
|
25
27
|
#
|
28
|
+
# @api public
|
26
29
|
def self.assert_instance_of(subject, expected_type, value, nil_ok = false)
|
27
|
-
|
28
|
-
|
29
|
-
check_assignability(tc, subject, expected_type, tc.infer_set(value), true)
|
30
|
+
unless value.nil? && nil_ok
|
31
|
+
report_type_mismatch(subject, expected_type, TypeCalculator.singleton.infer_set(value).generalize) unless expected_type.instance?(value)
|
30
32
|
end
|
31
33
|
value
|
32
34
|
end
|
33
35
|
|
34
|
-
def self.
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
raise Puppet::Pops::Types::TypeAssertionError.new(
|
41
|
-
"#{subject} value has wrong type, expected #{tc.string(expected_type)}, actual #{tc.string(actual_type)}", expected_type, actual_type)
|
42
|
-
end
|
36
|
+
def self.report_type_mismatch(subject, expected_type, actual_type)
|
37
|
+
# Do not give all the details for inferred types - i.e. format as Integer, instead of Integer[n, n] for exact
|
38
|
+
# value, which is just confusing. (OTOH: may need to revisit, or provide a better "type diff" output).
|
39
|
+
#
|
40
|
+
raise TypeAssertionError.new(
|
41
|
+
"#{subject} value has wrong type, expected #{expected_type}, actual #{actual_type}", expected_type, actual_type)
|
43
42
|
end
|
44
|
-
private_class_method :
|
43
|
+
private_class_method :report_type_mismatch
|
44
|
+
end
|
45
45
|
end
|
46
|
+
|
@@ -131,8 +131,8 @@ class Puppet::Pops::Types::TypeCalculator
|
|
131
131
|
end
|
132
132
|
|
133
133
|
# @api public
|
134
|
-
def self.generalize
|
135
|
-
singleton.generalize
|
134
|
+
def self.generalize(o)
|
135
|
+
singleton.generalize(o)
|
136
136
|
end
|
137
137
|
|
138
138
|
# @api public
|
@@ -150,86 +150,20 @@ class Puppet::Pops::Types::TypeCalculator
|
|
150
150
|
singleton.enumerable(t)
|
151
151
|
end
|
152
152
|
|
153
|
+
# @return [TypeCalculator] the singleton instance
|
154
|
+
#
|
153
155
|
# @api private
|
154
|
-
def self.singleton
|
156
|
+
def self.singleton
|
155
157
|
@tc_instance ||= new
|
156
158
|
end
|
157
159
|
|
158
160
|
# @api public
|
159
161
|
#
|
160
162
|
def initialize
|
161
|
-
@@
|
162
|
-
@@
|
163
|
-
@@
|
164
|
-
@@
|
165
|
-
@@string_visitor ||= Puppet::Pops::Visitor.new(nil,"string",0,0)
|
166
|
-
@@inspect_visitor ||= Puppet::Pops::Visitor.new(nil,"debug_string",0,0)
|
167
|
-
@@enumerable_visitor ||= Puppet::Pops::Visitor.new(nil,"enumerable",0,0)
|
168
|
-
@@extract_visitor ||= Puppet::Pops::Visitor.new(nil,"extract",0,0)
|
169
|
-
@@generalize_visitor ||= Puppet::Pops::Visitor.new(nil,"generalize",0,0)
|
170
|
-
@@callable_visitor ||= Puppet::Pops::Visitor.new(nil,"callable",1,1)
|
171
|
-
|
172
|
-
da = Types::PArrayType.new()
|
173
|
-
da.element_type = Types::PDataType.new()
|
174
|
-
@data_array = da
|
175
|
-
|
176
|
-
h = Types::PHashType.new()
|
177
|
-
h.element_type = Types::PDataType.new()
|
178
|
-
h.key_type = Types::PScalarType.new()
|
179
|
-
@data_hash = h
|
180
|
-
|
181
|
-
@data_t = Types::PDataType.new()
|
182
|
-
@scalar_t = Types::PScalarType.new()
|
183
|
-
@numeric_t = Types::PNumericType.new()
|
184
|
-
@t = Types::PAnyType.new()
|
185
|
-
|
186
|
-
# Data accepts a Tuple that has 0-infinity Data compatible entries (e.g. a Tuple equivalent to Array).
|
187
|
-
data_tuple = Types::PTupleType.new()
|
188
|
-
data_tuple.addTypes(Types::PDataType.new())
|
189
|
-
data_tuple.size_type = Types::PIntegerType.new()
|
190
|
-
data_tuple.size_type.from = 0
|
191
|
-
data_tuple.size_type.to = nil # infinity
|
192
|
-
@data_tuple_t = data_tuple
|
193
|
-
|
194
|
-
# Variant type compatible with Data
|
195
|
-
data_variant = Types::PVariantType.new()
|
196
|
-
data_variant.addTypes(@data_hash.copy)
|
197
|
-
data_variant.addTypes(@data_array.copy)
|
198
|
-
data_variant.addTypes(Types::PScalarType.new)
|
199
|
-
data_variant.addTypes(Types::PUndefType.new)
|
200
|
-
data_variant.addTypes(@data_tuple_t.copy)
|
201
|
-
@data_variant_t = data_variant
|
202
|
-
|
203
|
-
collection_default_size = Types::PIntegerType.new()
|
204
|
-
collection_default_size.from = 0
|
205
|
-
collection_default_size.to = nil # infinity
|
206
|
-
@collection_default_size_t = collection_default_size
|
207
|
-
|
208
|
-
non_empty_string = Types::PStringType.new
|
209
|
-
non_empty_string.size_type = Types::PIntegerType.new()
|
210
|
-
non_empty_string.size_type.from = 1
|
211
|
-
non_empty_string.size_type.to = nil # infinity
|
212
|
-
@non_empty_string_t = non_empty_string
|
213
|
-
|
214
|
-
@nil_t = Types::PUndefType.new
|
215
|
-
end
|
216
|
-
|
217
|
-
# Convenience method to get a data type for comparisons
|
218
|
-
# @api private the returned value may not be contained in another element
|
219
|
-
#
|
220
|
-
def data
|
221
|
-
@data_t
|
222
|
-
end
|
223
|
-
|
224
|
-
# Convenience method to get a variant compatible with the Data type.
|
225
|
-
# @api private the returned value may not be contained in another element
|
226
|
-
#
|
227
|
-
def data_variant
|
228
|
-
@data_variant_t
|
229
|
-
end
|
230
|
-
|
231
|
-
def self.data_variant
|
232
|
-
singleton.data_variant
|
163
|
+
@@infer_visitor ||= Puppet::Pops::Visitor.new(nil, 'infer',0,0)
|
164
|
+
@@string_visitor ||= Puppet::Pops::Visitor.new(nil, 'string',0,0)
|
165
|
+
@@inspect_visitor ||= Puppet::Pops::Visitor.new(nil, 'debug_string',0,0)
|
166
|
+
@@extract_visitor ||= Puppet::Pops::Visitor.new(nil, 'extract',0,0)
|
233
167
|
end
|
234
168
|
|
235
169
|
# Answers the question 'is it possible to inject an instance of the given class'
|
@@ -248,7 +182,7 @@ class Puppet::Pops::Types::TypeCalculator
|
|
248
182
|
|
249
183
|
# data types can not be injected (check again, it is not safe to assume that given RubyRuntime klazz arg was ok)
|
250
184
|
return false unless type(klazz).is_a?(Types::PRuntimeType)
|
251
|
-
if (klazz.respond_to?(:inject) && klazz.method(:inject).arity
|
185
|
+
if (klazz.respond_to?(:inject) && klazz.method(:inject).arity == -4) || klazz.instance_method(:initialize).arity == 0
|
252
186
|
klazz
|
253
187
|
else
|
254
188
|
nil
|
@@ -261,42 +195,22 @@ class Puppet::Pops::Types::TypeCalculator
|
|
261
195
|
# @api public
|
262
196
|
#
|
263
197
|
def assignable?(t, t2)
|
264
|
-
if t.is_a?(
|
198
|
+
if t.is_a?(Module)
|
265
199
|
t = type(t)
|
266
200
|
end
|
267
|
-
|
268
|
-
if t2.is_a?(Class)
|
269
|
-
t2 = type(t2)
|
270
|
-
end
|
271
|
-
t2_class = t2.class
|
272
|
-
|
273
|
-
# Unit can be assigned to anything
|
274
|
-
return true if t2_class == Types::PUnitType
|
275
|
-
|
276
|
-
if t2_class == Types::PVariantType
|
277
|
-
# Assignable if all contained types are assignable
|
278
|
-
t2.types.all? { |vt| @@assignable_visitor.visit_this_1(self, t, vt) }
|
279
|
-
else
|
280
|
-
# Turn NotUndef[T] into T when T is not assignable from Undef
|
281
|
-
if t2_class == Types::PNotUndefType && !(t2.type.nil? || assignable?(t2.type, @nil_t))
|
282
|
-
assignable?(t, t2.type)
|
283
|
-
else
|
284
|
-
@@assignable_visitor.visit_this_1(self, t, t2)
|
285
|
-
end
|
286
|
-
end
|
201
|
+
t.is_a?(Types::PAnyType) ? t.assignable?(t2) : false
|
287
202
|
end
|
288
203
|
|
289
204
|
# Returns an enumerable if the t represents something that can be iterated
|
290
205
|
def enumerable(t)
|
291
|
-
|
206
|
+
# Only PIntegerTypes are enumerable and only if not representing an infinite range
|
207
|
+
t.is_a?(Types::PIntegerType) && t.size < Float::INFINITY ? t : nil
|
292
208
|
end
|
293
209
|
|
294
210
|
# Answers, does the given callable accept the arguments given in args (an array or a tuple)
|
295
211
|
#
|
296
212
|
def callable?(callable, args)
|
297
|
-
|
298
|
-
# Note that polymorphism is for the args type, the callable is always a callable
|
299
|
-
@@callable_visitor.visit_this_1(self, args, callable)
|
213
|
+
callable.is_a?(Types::PAnyType) && callable.callable?(args)
|
300
214
|
end
|
301
215
|
|
302
216
|
# Answers if the two given types describe the same type
|
@@ -309,90 +223,46 @@ class Puppet::Pops::Types::TypeCalculator
|
|
309
223
|
end
|
310
224
|
|
311
225
|
# Answers 'what is the Puppet Type corresponding to the given Ruby class'
|
312
|
-
# @param c [
|
226
|
+
# @param c [Module] the class for which a puppet type is wanted
|
313
227
|
# @api public
|
314
228
|
#
|
315
229
|
def type(c)
|
316
|
-
raise ArgumentError,
|
230
|
+
raise ArgumentError, 'Argument must be a Module' unless c.is_a? Module
|
317
231
|
|
318
232
|
# Can't use a visitor here since we don't have an instance of the class
|
319
233
|
case
|
320
234
|
when c <= Integer
|
321
|
-
type = Types::PIntegerType
|
235
|
+
type = Types::PIntegerType::DEFAULT
|
322
236
|
when c == Float
|
323
|
-
type = Types::PFloatType
|
237
|
+
type = Types::PFloatType::DEFAULT
|
324
238
|
when c == Numeric
|
325
|
-
type = Types::PNumericType
|
239
|
+
type = Types::PNumericType::DEFAULT
|
326
240
|
when c == String
|
327
|
-
type = Types::PStringType
|
241
|
+
type = Types::PStringType::DEFAULT
|
328
242
|
when c == Regexp
|
329
|
-
type = Types::PRegexpType
|
243
|
+
type = Types::PRegexpType::DEFAULT
|
330
244
|
when c == NilClass
|
331
|
-
type = Types::PUndefType
|
245
|
+
type = Types::PUndefType::DEFAULT
|
332
246
|
when c == FalseClass, c == TrueClass
|
333
|
-
type = Types::PBooleanType
|
247
|
+
type = Types::PBooleanType::DEFAULT
|
334
248
|
when c == Class
|
335
|
-
type = Types::PType
|
249
|
+
type = Types::PType::DEFAULT
|
336
250
|
when c == Array
|
337
251
|
# Assume array of data values
|
338
|
-
type = Types::PArrayType
|
339
|
-
type.element_type = Types::PDataType.new()
|
252
|
+
type = Types::PArrayType::DATA
|
340
253
|
when c == Hash
|
341
254
|
# Assume hash with scalar keys and data values
|
342
|
-
type = Types::PHashType
|
343
|
-
|
344
|
-
type
|
345
|
-
else
|
346
|
-
type = Types::PRuntimeType.new(:runtime => :ruby, :runtime_type_name => c.name)
|
255
|
+
type = Types::PHashType::DATA
|
256
|
+
else
|
257
|
+
type = Types::PRuntimeType.new(:ruby, c.name)
|
347
258
|
end
|
348
259
|
type
|
349
260
|
end
|
350
261
|
|
351
|
-
# Generalizes value specific types. The
|
262
|
+
# Generalizes value specific types. The generalized type is returned.
|
352
263
|
# @api public
|
353
|
-
def generalize
|
354
|
-
|
355
|
-
o.eAllContents.each { |x| @@generalize_visitor.visit_this_0(self, x) }
|
356
|
-
o
|
357
|
-
end
|
358
|
-
|
359
|
-
def generalize_Object(o)
|
360
|
-
# do nothing, there is nothing to change for most types
|
361
|
-
end
|
362
|
-
|
363
|
-
# @return [Boolean] true if the given argument is contained in a struct element key
|
364
|
-
def is_struct_element_key?(o)
|
365
|
-
c = o.eContainer
|
366
|
-
if c.is_a?(Types::POptionalType)
|
367
|
-
o = c
|
368
|
-
c = c.eContainer
|
369
|
-
end
|
370
|
-
c.is_a?(Types::PStructElement) && c.key_type.equal?(o)
|
371
|
-
end
|
372
|
-
private :is_struct_element_key?
|
373
|
-
|
374
|
-
def generalize_PStringType(o)
|
375
|
-
# Skip generalization if the string is contained in a PStructElement key.
|
376
|
-
unless is_struct_element_key?(o)
|
377
|
-
o.values = []
|
378
|
-
o.size_type = nil
|
379
|
-
end
|
380
|
-
end
|
381
|
-
|
382
|
-
def generalize_PCollectionType(o)
|
383
|
-
# erase the size constraint from Array and Hash (if one exists, it is transformed to -Infinity - + Infinity, which is
|
384
|
-
# not desirable.
|
385
|
-
o.size_type = nil
|
386
|
-
end
|
387
|
-
|
388
|
-
def generalize_PFloatType(o)
|
389
|
-
o.to = nil
|
390
|
-
o.from = nil
|
391
|
-
end
|
392
|
-
|
393
|
-
def generalize_PIntegerType(o)
|
394
|
-
o.to = nil
|
395
|
-
o.from = nil
|
264
|
+
def generalize(o)
|
265
|
+
o.is_a?(Types::PAnyType) ? o.generalize : o
|
396
266
|
end
|
397
267
|
|
398
268
|
# Answers 'what is the single common Puppet Type describing o', or if o is an Array or Hash, what is the
|
@@ -400,153 +270,70 @@ class Puppet::Pops::Types::TypeCalculator
|
|
400
270
|
# @api public
|
401
271
|
#
|
402
272
|
def infer(o)
|
403
|
-
|
273
|
+
# Optimize the most common cases into direct calls.
|
274
|
+
case o
|
275
|
+
when String
|
276
|
+
infer_String(o)
|
277
|
+
when Integer
|
278
|
+
infer_Integer(o)
|
279
|
+
when Array
|
280
|
+
infer_Array(o)
|
281
|
+
when Hash
|
282
|
+
infer_Hash(o)
|
283
|
+
when Puppet::Pops::Evaluator::PuppetProc
|
284
|
+
infer_PuppetProc(o)
|
285
|
+
else
|
286
|
+
@@infer_visitor.visit_this_0(self, o)
|
287
|
+
end
|
404
288
|
end
|
405
289
|
|
406
290
|
def infer_generic(o)
|
407
|
-
|
408
|
-
result
|
291
|
+
generalize(infer(o))
|
409
292
|
end
|
410
293
|
|
411
294
|
# Answers 'what is the set of Puppet Types of o'
|
412
295
|
# @api public
|
413
296
|
#
|
414
297
|
def infer_set(o)
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
end
|
421
|
-
|
422
|
-
def instance_of_Object(t, o)
|
423
|
-
# Undef is Undef and Any, but nothing else when checking instance?
|
424
|
-
return false if (o.nil?) && t.class != Types::PAnyType
|
425
|
-
assignable?(t, infer(o))
|
426
|
-
end
|
427
|
-
|
428
|
-
# Anything is an instance of Unit
|
429
|
-
# @api private
|
430
|
-
def instance_of_PUnitType(t, o)
|
431
|
-
true
|
432
|
-
end
|
433
|
-
|
434
|
-
def instance_of_PArrayType(t, o)
|
435
|
-
return false unless o.is_a?(Array)
|
436
|
-
return false unless o.all? {|element| instance_of(t.element_type, element) }
|
437
|
-
size_t = t.size_type || @collection_default_size_t
|
438
|
-
# optimize by calling directly
|
439
|
-
return instance_of_PIntegerType(size_t, o.size)
|
440
|
-
end
|
441
|
-
|
442
|
-
# @api private
|
443
|
-
def instance_of_PIntegerType(t, o)
|
444
|
-
return false unless o.is_a?(Integer)
|
445
|
-
x = t.from
|
446
|
-
x = -Float::INFINITY if x.nil? || x == :default
|
447
|
-
y = t.to
|
448
|
-
y = Float::INFINITY if y.nil? || y == :default
|
449
|
-
return x < y ? x <= o && y >= o : y <= o && x >= o
|
450
|
-
end
|
451
|
-
|
452
|
-
# @api private
|
453
|
-
def instance_of_PStringType(t, o)
|
454
|
-
return false unless o.is_a?(String)
|
455
|
-
# true if size compliant
|
456
|
-
size_t = t.size_type
|
457
|
-
if size_t.nil? || instance_of_PIntegerType(size_t, o.size)
|
458
|
-
values = t.values
|
459
|
-
values.empty? || values.include?(o)
|
460
|
-
else
|
461
|
-
false
|
462
|
-
end
|
463
|
-
end
|
464
|
-
|
465
|
-
def instance_of_PTupleType(t, o)
|
466
|
-
return false unless o.is_a?(Array)
|
467
|
-
# compute the tuple's min/max size, and check if that size matches
|
468
|
-
size_t = t.size_type || Puppet::Pops::Types::TypeFactory.range(*t.size_range)
|
469
|
-
|
470
|
-
return false unless instance_of_PIntegerType(size_t, o.size)
|
471
|
-
o.each_with_index do |element, index|
|
472
|
-
return false unless instance_of(t.types[index] || t.types[-1], element)
|
473
|
-
end
|
474
|
-
true
|
475
|
-
end
|
476
|
-
|
477
|
-
def instance_of_PStructType(t, o)
|
478
|
-
return false unless o.is_a?(Hash)
|
479
|
-
matched = 0
|
480
|
-
t.elements.all? do |e|
|
481
|
-
key = e.name
|
482
|
-
v = o[key]
|
483
|
-
if v.nil? && !o.include?(key)
|
484
|
-
# Entry is missing. Only OK when key is optional
|
485
|
-
assignable?(e.key_type, @nil_t)
|
298
|
+
case o
|
299
|
+
when Array
|
300
|
+
infer_set_Array(o)
|
301
|
+
when Hash
|
302
|
+
infer_set_Hash(o)
|
486
303
|
else
|
487
|
-
|
488
|
-
|
489
|
-
end
|
490
|
-
end && matched == o.size
|
491
|
-
end
|
492
|
-
|
493
|
-
def instance_of_PHashType(t, o)
|
494
|
-
return false unless o.is_a?(Hash)
|
495
|
-
key_t = t.key_type
|
496
|
-
element_t = t.element_type
|
497
|
-
return false unless o.keys.all? {|key| instance_of(key_t, key) } && o.values.all? {|value| instance_of(element_t, value) }
|
498
|
-
size_t = t.size_type || @collection_default_size_t
|
499
|
-
# optimize by calling directly
|
500
|
-
return instance_of_PIntegerType(size_t, o.size)
|
501
|
-
end
|
502
|
-
|
503
|
-
def instance_of_PDataType(t, o)
|
504
|
-
instance_of(@data_variant_t, o)
|
505
|
-
end
|
506
|
-
|
507
|
-
def instance_of_PNotUndefType(t, o)
|
508
|
-
!(o.nil? || o == :undef) && (t.type.nil? || instance_of(t.type, o))
|
509
|
-
end
|
510
|
-
|
511
|
-
def instance_of_PUndefType(t, o)
|
512
|
-
o.nil? || o == :undef
|
513
|
-
end
|
514
|
-
|
515
|
-
def instance_of_POptionalType(t, o)
|
516
|
-
instance_of_PUndefType(t, o) || instance_of(t.optional_type, o)
|
517
|
-
end
|
518
|
-
|
519
|
-
def instance_of_PVariantType(t, o)
|
520
|
-
# instance of variant if o is instance? of any of variant's types
|
521
|
-
t.types.any? { |option_t| instance_of(option_t, o) }
|
304
|
+
infer_set_Object(o)
|
305
|
+
end
|
522
306
|
end
|
523
307
|
|
524
308
|
# Answers 'is o an instance of type t'
|
525
309
|
# @api public
|
526
310
|
#
|
527
311
|
def self.instance?(t, o)
|
528
|
-
singleton.
|
312
|
+
singleton.instance?(t,o)
|
529
313
|
end
|
530
314
|
|
531
315
|
# Answers 'is o an instance of type t'
|
532
316
|
# @api public
|
533
317
|
#
|
534
318
|
def instance?(t, o)
|
535
|
-
|
319
|
+
if t.is_a?(Module)
|
320
|
+
t = type(t)
|
321
|
+
end
|
322
|
+
t.is_a?(Types::PAnyType) ? t.instance?(o) : false
|
536
323
|
end
|
537
324
|
|
538
325
|
# Answers if t is a puppet type
|
539
326
|
# @api public
|
540
327
|
#
|
541
328
|
def is_ptype?(t)
|
542
|
-
|
329
|
+
t.is_a?(Types::PAnyType)
|
543
330
|
end
|
544
331
|
|
545
332
|
# Answers if t represents the puppet type PUndefType
|
546
333
|
# @api public
|
547
334
|
#
|
548
335
|
def is_pnil?(t)
|
549
|
-
|
336
|
+
t.nil? || t.is_a?(Types::PUndefType)
|
550
337
|
end
|
551
338
|
|
552
339
|
# Answers, 'What is the common type of t1 and t2?'
|
@@ -582,115 +369,85 @@ class Puppet::Pops::Types::TypeCalculator
|
|
582
369
|
|
583
370
|
# when both are arrays, return an array with common element type
|
584
371
|
if t1.is_a?(Types::PArrayType) && t2.is_a?(Types::PArrayType)
|
585
|
-
|
586
|
-
type.element_type = common_type(t1.element_type, t2.element_type)
|
587
|
-
return type
|
372
|
+
return Types::PArrayType.new(common_type(t1.element_type, t2.element_type))
|
588
373
|
end
|
589
374
|
|
590
375
|
# when both are hashes, return a hash with common key- and element type
|
591
376
|
if t1.is_a?(Types::PHashType) && t2.is_a?(Types::PHashType)
|
592
|
-
|
593
|
-
|
594
|
-
|
595
|
-
return type
|
377
|
+
key_type = common_type(t1.key_type, t2.key_type)
|
378
|
+
element_type = common_type(t1.element_type, t2.element_type)
|
379
|
+
return Types::PHashType.new(key_type, element_type)
|
596
380
|
end
|
597
381
|
|
598
382
|
# when both are host-classes, reduce to PHostClass[] (since one was not assignable to the other)
|
599
383
|
if t1.is_a?(Types::PHostClassType) && t2.is_a?(Types::PHostClassType)
|
600
|
-
return Types::PHostClassType
|
384
|
+
return Types::PHostClassType::DEFAULT
|
601
385
|
end
|
602
386
|
|
603
387
|
# when both are resources, reduce to Resource[T] or Resource[] (since one was not assignable to the other)
|
604
388
|
if t1.is_a?(Types::PResourceType) && t2.is_a?(Types::PResourceType)
|
605
|
-
result = Types::PResourceType.new()
|
606
389
|
# only Resource[] unless the type name is the same
|
607
|
-
|
608
|
-
# the cross assignability test above has already determined that they do not have the same type and title
|
609
|
-
return result
|
390
|
+
return t1.type_name == t2.type_name ? Types::PResourceType.new(t1.type_name, nil) : Types::PResourceType::DEFAULT
|
610
391
|
end
|
611
392
|
|
612
393
|
# Integers have range, expand the range to the common range
|
613
394
|
if t1.is_a?(Types::PIntegerType) && t2.is_a?(Types::PIntegerType)
|
614
|
-
|
615
|
-
t2range = from_to_ordered(t2.from, t2.to)
|
616
|
-
t = Types::PIntegerType.new()
|
617
|
-
from = [t1range[0], t2range[0]].min
|
618
|
-
to = [t1range[1], t2range[1]].max
|
619
|
-
t.from = from unless from == Float::INFINITY
|
620
|
-
t.to = to unless to == Float::INFINITY
|
621
|
-
return t
|
395
|
+
return Types::PIntegerType.new([t1.numeric_from, t2.numeric_from].min, [t1.numeric_to, t2.numeric_to].max)
|
622
396
|
end
|
623
397
|
|
624
398
|
# Floats have range, expand the range to the common range
|
625
399
|
if t1.is_a?(Types::PFloatType) && t2.is_a?(Types::PFloatType)
|
626
|
-
|
627
|
-
t2range = from_to_ordered(t2.from, t2.to)
|
628
|
-
t = Types::PFloatType.new()
|
629
|
-
from = [t1range[0], t2range[0]].min
|
630
|
-
to = [t1range[1], t2range[1]].max
|
631
|
-
t.from = from unless from == Float::INFINITY
|
632
|
-
t.to = to unless to == Float::INFINITY
|
633
|
-
return t
|
400
|
+
return Types::PFloatType.new([t1.numeric_from, t2.numeric_from].min, [t1.numeric_to, t2.numeric_to].max)
|
634
401
|
end
|
635
402
|
|
636
403
|
if t1.is_a?(Types::PStringType) && t2.is_a?(Types::PStringType)
|
637
|
-
|
638
|
-
|
639
|
-
|
640
|
-
return t
|
404
|
+
common_size_type = common_type(t1.size_type, t2.size_type) unless t1.size_type.nil? || t2.size_type.nil?
|
405
|
+
common_strings = t1.values.empty? || t2.values.empty? ? [] : t1.values | t2.values
|
406
|
+
return Types::PStringType.new(common_size_type, common_strings)
|
641
407
|
end
|
642
408
|
|
643
409
|
if t1.is_a?(Types::PPatternType) && t2.is_a?(Types::PPatternType)
|
644
|
-
|
645
|
-
# must make copies since patterns are contained types, not data-types
|
646
|
-
t.patterns = (t1.patterns | t2.patterns).map(&:copy)
|
647
|
-
return t
|
410
|
+
return Types::PPatternType.new(t1.patterns | t2.patterns)
|
648
411
|
end
|
649
412
|
|
650
413
|
if t1.is_a?(Types::PEnumType) && t2.is_a?(Types::PEnumType)
|
651
414
|
# The common type is one that complies with either set
|
652
|
-
|
653
|
-
t.values = t1.values | t2.values
|
654
|
-
return t
|
415
|
+
return Types::PEnumType.new(t1.values | t2.values)
|
655
416
|
end
|
656
417
|
|
657
418
|
if t1.is_a?(Types::PVariantType) && t2.is_a?(Types::PVariantType)
|
658
419
|
# The common type is one that complies with either set
|
659
|
-
|
660
|
-
t.types = (t1.types | t2.types).map(&:copy)
|
661
|
-
return t
|
420
|
+
return Types::PVariantType.new(t1.types | t2.types)
|
662
421
|
end
|
663
422
|
|
664
423
|
if t1.is_a?(Types::PRegexpType) && t2.is_a?(Types::PRegexpType)
|
665
424
|
# if they were identical, the general rule would return a parameterized regexp
|
666
425
|
# since they were not, the result is a generic regexp type
|
667
|
-
return Types::PPatternType
|
426
|
+
return Types::PPatternType::DEFAULT
|
668
427
|
end
|
669
428
|
|
670
429
|
if t1.is_a?(Types::PCallableType) && t2.is_a?(Types::PCallableType)
|
671
430
|
# They do not have the same signature, and one is not assignable to the other,
|
672
431
|
# what remains is the most general form of Callable
|
673
|
-
return Types::PCallableType
|
432
|
+
return Types::PCallableType::DEFAULT
|
674
433
|
end
|
675
434
|
|
676
435
|
# Common abstract types, from most specific to most general
|
677
436
|
if common_numeric?(t1, t2)
|
678
|
-
return Types::PNumericType
|
437
|
+
return Types::PNumericType::DEFAULT
|
679
438
|
end
|
680
439
|
|
681
440
|
if common_scalar?(t1, t2)
|
682
|
-
return Types::PScalarType
|
441
|
+
return Types::PScalarType::DEFAULT
|
683
442
|
end
|
684
443
|
|
685
444
|
if common_data?(t1,t2)
|
686
|
-
return Types::PDataType
|
445
|
+
return Types::PDataType::DEFAULT
|
687
446
|
end
|
688
447
|
|
689
448
|
# Meta types Type[Integer] + Type[String] => Type[Data]
|
690
449
|
if t1.is_a?(Types::PType) && t2.is_a?(Types::PType)
|
691
|
-
|
692
|
-
type.type = common_type(t1.type, t2.type)
|
693
|
-
return type
|
450
|
+
return Types::PType.new(common_type(t1.type, t2.type))
|
694
451
|
end
|
695
452
|
|
696
453
|
# If both are Runtime types
|
@@ -707,7 +464,7 @@ class Puppet::Pops::Types::TypeCalculator
|
|
707
464
|
superclasses(c1).each do|c1_super|
|
708
465
|
c2_superclasses.each do |c2_super|
|
709
466
|
if c1_super == c2_super
|
710
|
-
return Types::PRuntimeType.new(:
|
467
|
+
return Types::PRuntimeType.new(:ruby, c1_super.name)
|
711
468
|
end
|
712
469
|
end
|
713
470
|
end
|
@@ -715,9 +472,7 @@ class Puppet::Pops::Types::TypeCalculator
|
|
715
472
|
end
|
716
473
|
|
717
474
|
# They better both be Any type, or the wrong thing was asked and nil is returned
|
718
|
-
|
719
|
-
return Types::PAnyType.new()
|
720
|
-
end
|
475
|
+
t1.is_a?(Types::PAnyType) && t2.is_a?(Types::PAnyType) ? Types::PAnyType::DEFAULT : nil
|
721
476
|
end
|
722
477
|
|
723
478
|
# Produces the superclasses of the given class, including the class
|
@@ -734,6 +489,9 @@ class Puppet::Pops::Types::TypeCalculator
|
|
734
489
|
# @api public
|
735
490
|
#
|
736
491
|
def string(t)
|
492
|
+
if t.is_a?(Module)
|
493
|
+
t = type(t)
|
494
|
+
end
|
737
495
|
@@string_visitor.visit_this_0(self, t)
|
738
496
|
end
|
739
497
|
|
@@ -741,6 +499,9 @@ class Puppet::Pops::Types::TypeCalculator
|
|
741
499
|
# @api public
|
742
500
|
#
|
743
501
|
def debug_string(t)
|
502
|
+
if t.is_a?(Module)
|
503
|
+
t = type(t)
|
504
|
+
end
|
744
505
|
@@inspect_visitor.visit_this_0(self, t)
|
745
506
|
end
|
746
507
|
|
@@ -756,19 +517,19 @@ class Puppet::Pops::Types::TypeCalculator
|
|
756
517
|
# @api public
|
757
518
|
#
|
758
519
|
def infer_and_reduce_type(enumerable)
|
759
|
-
reduce_type(enumerable.
|
520
|
+
reduce_type(enumerable.map {|o| infer(o) })
|
760
521
|
end
|
761
522
|
|
762
|
-
# The type of all
|
523
|
+
# The type of all modules is PType
|
763
524
|
# @api private
|
764
525
|
#
|
765
|
-
def
|
766
|
-
Types::PType.new()
|
526
|
+
def infer_Module(o)
|
527
|
+
Types::PType::new(Types::PRuntimeType.new(:ruby, o.name))
|
767
528
|
end
|
768
529
|
|
769
530
|
# @api private
|
770
531
|
def infer_Closure(o)
|
771
|
-
o.type
|
532
|
+
o.type
|
772
533
|
end
|
773
534
|
|
774
535
|
# @api private
|
@@ -778,16 +539,14 @@ class Puppet::Pops::Types::TypeCalculator
|
|
778
539
|
|
779
540
|
# @api private
|
780
541
|
def infer_Object(o)
|
781
|
-
Types::PRuntimeType.new(:
|
542
|
+
Types::PRuntimeType.new(:ruby, o.class.name)
|
782
543
|
end
|
783
544
|
|
784
545
|
# The type of all types is PType
|
785
546
|
# @api private
|
786
547
|
#
|
787
548
|
def infer_PAnyType(o)
|
788
|
-
|
789
|
-
type.type = o.copy
|
790
|
-
type
|
549
|
+
Types::PType.new(o)
|
791
550
|
end
|
792
551
|
|
793
552
|
# The type of all types is PType
|
@@ -795,45 +554,32 @@ class Puppet::Pops::Types::TypeCalculator
|
|
795
554
|
# @api private
|
796
555
|
#
|
797
556
|
def infer_PType(o)
|
798
|
-
|
799
|
-
type.type = o.copy
|
800
|
-
type
|
557
|
+
Types::PType.new(o)
|
801
558
|
end
|
802
559
|
|
803
560
|
# @api private
|
804
561
|
def infer_String(o)
|
805
|
-
|
806
|
-
t.addValues(o)
|
807
|
-
t.size_type = size_as_type(o)
|
808
|
-
t
|
562
|
+
Types::PStringType.new(size_as_type(o), [o])
|
809
563
|
end
|
810
564
|
|
811
565
|
# @api private
|
812
566
|
def infer_Float(o)
|
813
|
-
|
814
|
-
t.from = o
|
815
|
-
t.to = o
|
816
|
-
t
|
567
|
+
Types::PFloatType.new(o, o)
|
817
568
|
end
|
818
569
|
|
819
570
|
# @api private
|
820
571
|
def infer_Integer(o)
|
821
|
-
|
822
|
-
t.from = o
|
823
|
-
t.to = o
|
824
|
-
t
|
572
|
+
Types::PIntegerType.new(o, o)
|
825
573
|
end
|
826
574
|
|
827
575
|
# @api private
|
828
576
|
def infer_Regexp(o)
|
829
|
-
|
830
|
-
t.pattern = o.source
|
831
|
-
t
|
577
|
+
Types::PRegexpType.new(o.source)
|
832
578
|
end
|
833
579
|
|
834
580
|
# @api private
|
835
581
|
def infer_NilClass(o)
|
836
|
-
Types::PUndefType
|
582
|
+
Types::PUndefType::DEFAULT
|
837
583
|
end
|
838
584
|
|
839
585
|
# @api private
|
@@ -845,12 +591,12 @@ class Puppet::Pops::Types::TypeCalculator
|
|
845
591
|
case p[0]
|
846
592
|
when :rest
|
847
593
|
max = :default
|
848
|
-
break
|
594
|
+
break Types::PAnyType::DEFAULT
|
849
595
|
when :req
|
850
596
|
min += 1
|
851
597
|
end
|
852
598
|
max += 1
|
853
|
-
|
599
|
+
Types::PAnyType::DEFAULT
|
854
600
|
end
|
855
601
|
mapped_types << min
|
856
602
|
mapped_types << max
|
@@ -867,7 +613,7 @@ class Puppet::Pops::Types::TypeCalculator
|
|
867
613
|
def infer_Symbol(o)
|
868
614
|
case o
|
869
615
|
when :default
|
870
|
-
Types::PDefaultType
|
616
|
+
Types::PDefaultType::DEFAULT
|
871
617
|
else
|
872
618
|
infer_Object(o)
|
873
619
|
end
|
@@ -875,64 +621,48 @@ class Puppet::Pops::Types::TypeCalculator
|
|
875
621
|
|
876
622
|
# @api private
|
877
623
|
def infer_TrueClass(o)
|
878
|
-
Types::PBooleanType
|
624
|
+
Types::PBooleanType::DEFAULT
|
879
625
|
end
|
880
626
|
|
881
627
|
# @api private
|
882
628
|
def infer_FalseClass(o)
|
883
|
-
Types::PBooleanType
|
629
|
+
Types::PBooleanType::DEFAULT
|
884
630
|
end
|
885
631
|
|
886
632
|
# @api private
|
887
633
|
# A Puppet::Parser::Resource, or Puppet::Resource
|
888
634
|
#
|
889
635
|
def infer_Resource(o)
|
890
|
-
t = Types::PResourceType.new()
|
891
|
-
t.type_name = o.type.to_s.downcase
|
892
636
|
# Only Puppet::Resource can have a title that is a symbol :undef, a PResource cannot.
|
893
637
|
# A mapping must be made to empty string. A nil value will result in an error later
|
894
638
|
title = o.title
|
895
|
-
|
896
|
-
|
897
|
-
type.type = t
|
898
|
-
type
|
639
|
+
title = '' if :undef == title
|
640
|
+
Types::PType.new(Types::PResourceType.new(o.type.to_s.downcase, title))
|
899
641
|
end
|
900
642
|
|
901
643
|
# @api private
|
902
644
|
def infer_Array(o)
|
903
|
-
type = Types::PArrayType.new()
|
904
|
-
type.element_type =
|
905
645
|
if o.empty?
|
906
|
-
Types::
|
646
|
+
Types::PArrayType::EMPTY
|
907
647
|
else
|
908
|
-
infer_and_reduce_type(o)
|
648
|
+
Types::PArrayType.new(infer_and_reduce_type(o), size_as_type(o))
|
909
649
|
end
|
910
|
-
type.size_type = size_as_type(o)
|
911
|
-
type
|
912
650
|
end
|
913
651
|
|
914
652
|
# @api private
|
915
653
|
def infer_Hash(o)
|
916
|
-
type = Types::PHashType.new()
|
917
654
|
if o.empty?
|
918
|
-
|
919
|
-
etype = Types::PUndefType.new()
|
655
|
+
Types::PHashType::EMPTY
|
920
656
|
else
|
921
|
-
ktype = infer_and_reduce_type(o.keys
|
922
|
-
etype = infer_and_reduce_type(o.values
|
657
|
+
ktype = infer_and_reduce_type(o.keys)
|
658
|
+
etype = infer_and_reduce_type(o.values)
|
659
|
+
Types::PHashType.new(ktype, etype, size_as_type(o))
|
923
660
|
end
|
924
|
-
type.key_type = ktype
|
925
|
-
type.element_type = etype
|
926
|
-
type.size_type = size_as_type(o)
|
927
|
-
type
|
928
661
|
end
|
929
662
|
|
930
663
|
def size_as_type(collection)
|
931
664
|
size = collection.size
|
932
|
-
|
933
|
-
t.from = size
|
934
|
-
t.to = size
|
935
|
-
t
|
665
|
+
Types::PIntegerType.new(size, size)
|
936
666
|
end
|
937
667
|
|
938
668
|
# Common case for everything that intrinsically only has a single type
|
@@ -942,41 +672,22 @@ class Puppet::Pops::Types::TypeCalculator
|
|
942
672
|
|
943
673
|
def infer_set_Array(o)
|
944
674
|
if o.empty?
|
945
|
-
|
946
|
-
type.element_type = Types::PUndefType.new()
|
947
|
-
type.size_type = size_as_type(o)
|
675
|
+
Types::PArrayType::EMPTY
|
948
676
|
else
|
949
|
-
|
950
|
-
type.types = o.map() {|x| infer_set(x) }
|
677
|
+
Types::PTupleType.new(o.map {|x| infer_set(x) })
|
951
678
|
end
|
952
|
-
type
|
953
679
|
end
|
954
680
|
|
955
681
|
def infer_set_Hash(o)
|
956
682
|
if o.empty?
|
957
|
-
|
958
|
-
|
959
|
-
|
960
|
-
type.size_type = size_as_type(o)
|
961
|
-
elsif o.keys.all? {|k| instance_of_PStringType(@non_empty_string_t, k) }
|
962
|
-
type = Types::PStructType.new
|
963
|
-
type.elements = o.map do |k,v|
|
964
|
-
element = Types::PStructElement.new
|
965
|
-
element.key_type = infer_String(k)
|
966
|
-
element.value_type = infer_set(v)
|
967
|
-
element
|
968
|
-
end
|
683
|
+
Types::PHashType::EMPTY
|
684
|
+
elsif o.keys.all? {|k| Types::PStringType::NON_EMPTY.instance?(k) }
|
685
|
+
Types::PStructType.new(o.each_pair.map { |k,v| Types::PStructElement.new(Types::PStringType.new(nil, [k]), infer_set(v)) })
|
969
686
|
else
|
970
|
-
|
971
|
-
|
972
|
-
ktype
|
973
|
-
etype = Types::PVariantType.new
|
974
|
-
etype.types = o.values.map {|e| infer_set(e) }
|
975
|
-
type.key_type = unwrap_single_variant(ktype)
|
976
|
-
type.element_type = unwrap_single_variant(etype)
|
977
|
-
type.size_type = size_as_type(o)
|
687
|
+
ktype = Types::PVariantType.new(o.keys.map {|k| infer_set(k) })
|
688
|
+
etype = Types::PVariantType.new(o.values.map {|e| infer_set(e) })
|
689
|
+
Types::PHashType.new(unwrap_single_variant(ktype), unwrap_single_variant(etype), size_as_type(o))
|
978
690
|
end
|
979
|
-
type
|
980
691
|
end
|
981
692
|
|
982
693
|
def unwrap_single_variant(possible_variant)
|
@@ -987,59 +698,6 @@ class Puppet::Pops::Types::TypeCalculator
|
|
987
698
|
end
|
988
699
|
end
|
989
700
|
|
990
|
-
# False in general type calculator
|
991
|
-
# @api private
|
992
|
-
def assignable_Object(t, t2)
|
993
|
-
false
|
994
|
-
end
|
995
|
-
|
996
|
-
# @api private
|
997
|
-
def assignable_PAnyType(t, t2)
|
998
|
-
t2.is_a?(Types::PAnyType)
|
999
|
-
end
|
1000
|
-
|
1001
|
-
# @api private
|
1002
|
-
def assignable_PNotUndefType(t, t2)
|
1003
|
-
!assignable?(t2, @nil_t) && (t.type.nil? || assignable?(t.type, t2))
|
1004
|
-
end
|
1005
|
-
|
1006
|
-
# @api private
|
1007
|
-
def assignable_PUndefType(t, t2)
|
1008
|
-
# Only undef/nil is assignable to nil type
|
1009
|
-
t2.is_a?(Types::PUndefType)
|
1010
|
-
end
|
1011
|
-
|
1012
|
-
# Anything is assignable to a Unit type
|
1013
|
-
# @api private
|
1014
|
-
def assignable_PUnitType(t, t2)
|
1015
|
-
true
|
1016
|
-
end
|
1017
|
-
|
1018
|
-
# @api private
|
1019
|
-
def assignable_PDefaultType(t, t2)
|
1020
|
-
# Only default is assignable to default type
|
1021
|
-
t2.is_a?(Types::PDefaultType)
|
1022
|
-
end
|
1023
|
-
|
1024
|
-
# @api private
|
1025
|
-
def assignable_PScalarType(t, t2)
|
1026
|
-
t2.is_a?(Types::PScalarType)
|
1027
|
-
end
|
1028
|
-
|
1029
|
-
# @api private
|
1030
|
-
def assignable_PNumericType(t, t2)
|
1031
|
-
t2.is_a?(Types::PNumericType)
|
1032
|
-
end
|
1033
|
-
|
1034
|
-
# @api private
|
1035
|
-
def assignable_PIntegerType(t, t2)
|
1036
|
-
return false unless t2.is_a?(Types::PIntegerType)
|
1037
|
-
trange = from_to_ordered(t.from, t.to)
|
1038
|
-
t2range = from_to_ordered(t2.from, t2.to)
|
1039
|
-
# If t2 min and max are within the range of t
|
1040
|
-
trange[0] <= t2range[0] && trange[1] >= t2range[1]
|
1041
|
-
end
|
1042
|
-
|
1043
701
|
# Transform int range to a size constraint
|
1044
702
|
# if range == nil the constraint is 1,1
|
1045
703
|
# if range.from == nil min size = 1
|
@@ -1058,117 +716,9 @@ class Puppet::Pops::Types::TypeCalculator
|
|
1058
716
|
end
|
1059
717
|
end
|
1060
718
|
|
1061
|
-
# @api private
|
1062
|
-
def from_to_ordered(from, to)
|
1063
|
-
x = (from.nil? || from == :default) ? -Float::INFINITY : from
|
1064
|
-
y = (to.nil? || to == :default) ? Float::INFINITY : to
|
1065
|
-
if x < y
|
1066
|
-
[x, y]
|
1067
|
-
else
|
1068
|
-
[y, x]
|
1069
|
-
end
|
1070
|
-
end
|
1071
|
-
|
1072
|
-
# @api private
|
1073
|
-
def assignable_PVariantType(t, t2)
|
1074
|
-
# Data is a specific variant
|
1075
|
-
t2 = @data_variant_t if t2.is_a?(Types::PDataType)
|
1076
|
-
if t2.is_a?(Types::PVariantType)
|
1077
|
-
# A variant is assignable if all of its options are assignable to one of this type's options
|
1078
|
-
return true if t == t2
|
1079
|
-
t2.types.all? do |other|
|
1080
|
-
# if the other is a Variant, all of its options, but be assignable to one of this type's options
|
1081
|
-
other = other.is_a?(Types::PDataType) ? @data_variant_t : other
|
1082
|
-
if other.is_a?(Types::PVariantType)
|
1083
|
-
assignable?(t, other)
|
1084
|
-
else
|
1085
|
-
t.types.any? {|option_t| assignable?(option_t, other) }
|
1086
|
-
end
|
1087
|
-
end
|
1088
|
-
else
|
1089
|
-
# A variant is assignable if t2 is assignable to any of its types
|
1090
|
-
t.types.any? { |option_t| assignable?(option_t, t2) }
|
1091
|
-
end
|
1092
|
-
end
|
1093
|
-
|
1094
|
-
# Catch all not callable combinations
|
1095
|
-
def callable_Object(o, callable_t)
|
1096
|
-
false
|
1097
|
-
end
|
1098
|
-
|
1099
|
-
def callable_PTupleType(args_tuple, callable_t)
|
1100
|
-
if args_tuple.size_type
|
1101
|
-
raise ArgumentError, "Callable tuple may not have a size constraint when used as args"
|
1102
|
-
end
|
1103
|
-
|
1104
|
-
params_tuple = callable_t.param_types
|
1105
|
-
param_block_t = callable_t.block_type
|
1106
|
-
arg_types = args_tuple.types
|
1107
|
-
arg_block_t = arg_types.last()
|
1108
|
-
if self.class.is_kind_of_callable?(arg_block_t)
|
1109
|
-
# Can't pass a block to a callable that doesn't accept one
|
1110
|
-
return false if param_block_t.nil?
|
1111
|
-
|
1112
|
-
# Check that the block is of the right tyṕe
|
1113
|
-
return false unless assignable?(param_block_t, arg_block_t)
|
1114
|
-
|
1115
|
-
# Check other arguments
|
1116
|
-
arg_count = arg_types.size - 1
|
1117
|
-
params_size_t = params_tuple.size_type || Types::TypeFactory.range(*params_tuple.size_range)
|
1118
|
-
return false unless assignable?(params_size_t, Types::TypeFactory.range(arg_count, arg_count))
|
1119
|
-
|
1120
|
-
ctypes = params_tuple.types
|
1121
|
-
args_assignable = false
|
1122
|
-
arg_count.times do |index|
|
1123
|
-
return false unless assignable?((ctypes[index] || ctypes[-1]), arg_types[index])
|
1124
|
-
end
|
1125
|
-
return true
|
1126
|
-
end
|
1127
|
-
|
1128
|
-
# Check that tuple is assignable and that the block (if declared) is optional
|
1129
|
-
assignable?(params_tuple, args_tuple) && (param_block_t.nil? || assignable?(param_block_t, @nil_t))
|
1130
|
-
end
|
1131
|
-
|
1132
719
|
# @api private
|
1133
720
|
def self.is_kind_of_callable?(t, optional = true)
|
1134
|
-
|
1135
|
-
when Types::PCallableType
|
1136
|
-
true
|
1137
|
-
when Types::POptionalType
|
1138
|
-
optional && is_kind_of_callable?(t.optional_type, optional)
|
1139
|
-
when Types::PVariantType
|
1140
|
-
t.types.all? {|t2| is_kind_of_callable?(t2, optional) }
|
1141
|
-
else
|
1142
|
-
false
|
1143
|
-
end
|
1144
|
-
end
|
1145
|
-
|
1146
|
-
# @api private
|
1147
|
-
def self.is_kind_of_optional?(t, optional = true)
|
1148
|
-
case t
|
1149
|
-
when Types::POptionalType
|
1150
|
-
true
|
1151
|
-
when Types::PVariantType
|
1152
|
-
t.types.all? {|t2| is_kind_of_optional?(t2, optional) }
|
1153
|
-
else
|
1154
|
-
false
|
1155
|
-
end
|
1156
|
-
end
|
1157
|
-
|
1158
|
-
def callable_PArrayType(args_array, callable_t)
|
1159
|
-
return false unless assignable?(callable_t.param_types, args_array)
|
1160
|
-
# does not support calling with a block, but have to check that callable is ok with missing block
|
1161
|
-
assignable?(callable_t.block_type || @nil_t, @nil_t)
|
1162
|
-
end
|
1163
|
-
|
1164
|
-
def callable_PUndefType(nil_t, callable_t)
|
1165
|
-
# if callable_t is Optional (or indeed PUndefType), this means that 'missing callable' is accepted
|
1166
|
-
assignable?(callable_t, nil_t)
|
1167
|
-
end
|
1168
|
-
|
1169
|
-
def callable_PCallableType(given_callable_t, required_callable_t)
|
1170
|
-
# If the required callable is euqal or more specific than the given, the given is callable
|
1171
|
-
assignable?(required_callable_t, given_callable_t)
|
721
|
+
t.is_a?(Types::PAnyType) && t.kind_of_callable?(optional)
|
1172
722
|
end
|
1173
723
|
|
1174
724
|
def max(a,b)
|
@@ -1179,41 +729,6 @@ class Puppet::Pops::Types::TypeCalculator
|
|
1179
729
|
a <= b ? a : b
|
1180
730
|
end
|
1181
731
|
|
1182
|
-
def assignable_PTupleType(t, t2)
|
1183
|
-
return true if t == t2 || t.types.empty? && (t2.is_a?(Types::PArrayType))
|
1184
|
-
size_t = t.size_type || Puppet::Pops::Types::TypeFactory.range(*t.size_range)
|
1185
|
-
|
1186
|
-
if t2.is_a?(Types::PTupleType)
|
1187
|
-
size_t2 = t2.size_type || Puppet::Pops::Types::TypeFactory.range(*t2.size_range)
|
1188
|
-
|
1189
|
-
# not assignable if the number of types in t2 is outside number of types in t1
|
1190
|
-
if assignable?(size_t, size_t2)
|
1191
|
-
t2.types.size.times do |index|
|
1192
|
-
return false unless assignable?((t.types[index] || t.types[-1]), t2.types[index])
|
1193
|
-
end
|
1194
|
-
return true
|
1195
|
-
else
|
1196
|
-
return false
|
1197
|
-
end
|
1198
|
-
elsif t2.is_a?(Types::PArrayType)
|
1199
|
-
t2_entry = t2.element_type
|
1200
|
-
|
1201
|
-
# Array of anything can not be assigned (unless tuple is tuple of anything) - this case
|
1202
|
-
# was handled at the top of this method.
|
1203
|
-
#
|
1204
|
-
return false if t2_entry.nil?
|
1205
|
-
size_t = t.size_type || Puppet::Pops::Types::TypeFactory.range(*t.size_range)
|
1206
|
-
size_t2 = t2.size_type || @collection_default_size_t
|
1207
|
-
return false unless assignable?(size_t, size_t2)
|
1208
|
-
min(t.types.size, size_t2.range()[1]).times do |index|
|
1209
|
-
return false unless assignable?((t.types[index] || t.types[-1]), t2_entry)
|
1210
|
-
end
|
1211
|
-
true
|
1212
|
-
else
|
1213
|
-
false
|
1214
|
-
end
|
1215
|
-
end
|
1216
|
-
|
1217
732
|
# Produces the tuple entry at the given index given a tuple type, its from/to constraints on the last
|
1218
733
|
# type, and an index.
|
1219
734
|
# Produces nil if the index is out of bounds
|
@@ -1233,332 +748,6 @@ class Puppet::Pops::Types::TypeCalculator
|
|
1233
748
|
end
|
1234
749
|
end
|
1235
750
|
|
1236
|
-
# @api private
|
1237
|
-
#
|
1238
|
-
def assignable_PStructType(t, t2)
|
1239
|
-
if t2.is_a?(Types::PStructType)
|
1240
|
-
h2 = t2.hashed_elements
|
1241
|
-
matched = 0
|
1242
|
-
t.elements.all? do |e1|
|
1243
|
-
e2 = h2[e1.name]
|
1244
|
-
if e2.nil?
|
1245
|
-
assignable?(e1.key_type, @nil_t)
|
1246
|
-
else
|
1247
|
-
matched += 1
|
1248
|
-
assignable?(e1.key_type, e2.key_type) && assignable?(e1.value_type, e2.value_type)
|
1249
|
-
end
|
1250
|
-
end && matched == h2.size
|
1251
|
-
elsif t2.is_a?(Types::PHashType)
|
1252
|
-
required = 0
|
1253
|
-
required_elements_assignable = t.elements.all? do |e|
|
1254
|
-
if assignable?(e.key_type, @nil_t)
|
1255
|
-
true
|
1256
|
-
else
|
1257
|
-
required += 1
|
1258
|
-
assignable?(e.value_type, t2.element_type)
|
1259
|
-
end
|
1260
|
-
end
|
1261
|
-
if required_elements_assignable
|
1262
|
-
size_t2 = t2.size_type || @collection_default_size_t
|
1263
|
-
size_t = Types::PIntegerType.new
|
1264
|
-
size_t.from = required
|
1265
|
-
size_t.to = t.elements.size
|
1266
|
-
assignable_PIntegerType(size_t, size_t2)
|
1267
|
-
end
|
1268
|
-
else
|
1269
|
-
false
|
1270
|
-
end
|
1271
|
-
end
|
1272
|
-
|
1273
|
-
# @api private
|
1274
|
-
def assignable_POptionalType(t, t2)
|
1275
|
-
return true if t2.is_a?(Types::PUndefType)
|
1276
|
-
return true if t.optional_type.nil?
|
1277
|
-
if t2.is_a?(Types::POptionalType)
|
1278
|
-
assignable?(t.optional_type, t2.optional_type || @t)
|
1279
|
-
else
|
1280
|
-
assignable?(t.optional_type, t2)
|
1281
|
-
end
|
1282
|
-
end
|
1283
|
-
|
1284
|
-
# @api private
|
1285
|
-
def assignable_PEnumType(t, t2)
|
1286
|
-
return true if t == t2
|
1287
|
-
if t.values.empty?
|
1288
|
-
return true if t2.is_a?(Types::PStringType) || t2.is_a?(Types::PEnumType) || t2.is_a?(Types::PPatternType)
|
1289
|
-
end
|
1290
|
-
case t2
|
1291
|
-
when Types::PStringType
|
1292
|
-
# if the set of strings are all found in the set of enums
|
1293
|
-
!t2.values.empty?() && t2.values.all? { |s| t.values.any? { |e| e == s }}
|
1294
|
-
when Types::PVariantType
|
1295
|
-
t2.types.all? {|variant_t| assignable_PEnumType(t, variant_t) }
|
1296
|
-
when Types::PEnumType
|
1297
|
-
# empty means any enum
|
1298
|
-
return true if t.values.empty?
|
1299
|
-
!t2.values.empty? && t2.values.all? { |s| t.values.any? {|e| e == s }}
|
1300
|
-
else
|
1301
|
-
false
|
1302
|
-
end
|
1303
|
-
end
|
1304
|
-
|
1305
|
-
# @api private
|
1306
|
-
def assignable_PStringType(t, t2)
|
1307
|
-
if t.values.empty?
|
1308
|
-
# A general string is assignable by any other string or pattern restricted string
|
1309
|
-
# if the string has a size constraint it does not match since there is no reasonable way
|
1310
|
-
# to compute the min/max length a pattern will match. For enum, it is possible to test that
|
1311
|
-
# each enumerator value is within range
|
1312
|
-
size_t = t.size_type || @collection_default_size_t
|
1313
|
-
case t2
|
1314
|
-
when Types::PStringType
|
1315
|
-
# true if size compliant
|
1316
|
-
size_t2 = t2.size_type || @collection_default_size_t
|
1317
|
-
assignable_PIntegerType(size_t, size_t2)
|
1318
|
-
|
1319
|
-
when Types::PPatternType
|
1320
|
-
# true if size constraint is at least 0 to +Infinity (which is the same as the default)
|
1321
|
-
assignable_PIntegerType(size_t, @collection_default_size_t)
|
1322
|
-
|
1323
|
-
when Types::PEnumType
|
1324
|
-
if t2.values && !t2.values.empty?
|
1325
|
-
# true if all enum values are within range
|
1326
|
-
min, max = t2.values.map(&:size).minmax
|
1327
|
-
trange = from_to_ordered(size_t.from, size_t.to)
|
1328
|
-
t2range = [min, max]
|
1329
|
-
# If t2 min and max are within the range of t
|
1330
|
-
trange[0] <= t2range[0] && trange[1] >= t2range[1]
|
1331
|
-
else
|
1332
|
-
# enum represents all enums, and thus all strings, a sized constrained string can thus not
|
1333
|
-
# be assigned any enum (unless it is max size).
|
1334
|
-
assignable_PIntegerType(size_t, @collection_default_size_t)
|
1335
|
-
end
|
1336
|
-
else
|
1337
|
-
# no other type matches string
|
1338
|
-
false
|
1339
|
-
end
|
1340
|
-
elsif t2.is_a?(Types::PStringType)
|
1341
|
-
# A specific string acts as a set of strings - must have exactly the same strings
|
1342
|
-
# In this case, size does not matter since the definition is very precise anyway
|
1343
|
-
Set.new(t.values) == Set.new(t2.values)
|
1344
|
-
else
|
1345
|
-
# All others are false, since no other type describes the same set of specific strings
|
1346
|
-
false
|
1347
|
-
end
|
1348
|
-
end
|
1349
|
-
|
1350
|
-
# @api private
|
1351
|
-
def assignable_PPatternType(t, t2)
|
1352
|
-
return true if t == t2
|
1353
|
-
case t2
|
1354
|
-
when Types::PStringType, Types::PEnumType
|
1355
|
-
values = t2.values
|
1356
|
-
when Types::PVariantType
|
1357
|
-
return t2.types.all? {|variant_t| assignable_PPatternType(t, variant_t) }
|
1358
|
-
when Types::PPatternType
|
1359
|
-
return t.patterns.empty? ? true : false
|
1360
|
-
else
|
1361
|
-
return false
|
1362
|
-
end
|
1363
|
-
|
1364
|
-
if t2.values.empty?
|
1365
|
-
# Strings / Enums (unknown which ones) cannot all match a pattern, but if there is no pattern it is ok
|
1366
|
-
# (There should really always be a pattern, but better safe than sorry).
|
1367
|
-
return t.patterns.empty? ? true : false
|
1368
|
-
end
|
1369
|
-
# all strings in String/Enum type must match one of the patterns in Pattern type,
|
1370
|
-
# or Pattern represents all Patterns == all Strings
|
1371
|
-
regexps = t.patterns.map {|p| p.regexp }
|
1372
|
-
regexps.empty? || t2.values.all? { |v| regexps.any? {|re| re.match(v) } }
|
1373
|
-
end
|
1374
|
-
|
1375
|
-
# @api private
|
1376
|
-
def assignable_PFloatType(t, t2)
|
1377
|
-
return false unless t2.is_a?(Types::PFloatType)
|
1378
|
-
trange = from_to_ordered(t.from, t.to)
|
1379
|
-
t2range = from_to_ordered(t2.from, t2.to)
|
1380
|
-
# If t2 min and max are within the range of t
|
1381
|
-
trange[0] <= t2range[0] && trange[1] >= t2range[1]
|
1382
|
-
end
|
1383
|
-
|
1384
|
-
# @api private
|
1385
|
-
def assignable_PBooleanType(t, t2)
|
1386
|
-
t2.is_a?(Types::PBooleanType)
|
1387
|
-
end
|
1388
|
-
|
1389
|
-
# @api private
|
1390
|
-
def assignable_PRegexpType(t, t2)
|
1391
|
-
t2.is_a?(Types::PRegexpType) && (t.pattern.nil? || t.pattern == t2.pattern)
|
1392
|
-
end
|
1393
|
-
|
1394
|
-
# @api private
|
1395
|
-
def assignable_PCallableType(t, t2)
|
1396
|
-
return false unless t2.is_a?(Types::PCallableType)
|
1397
|
-
# nil param_types means, any other Callable is assignable
|
1398
|
-
return true if t.param_types.nil?
|
1399
|
-
|
1400
|
-
# NOTE: these tests are made in reverse as it is calling the callable that is constrained
|
1401
|
-
# (it's lower bound), not its upper bound
|
1402
|
-
return false unless assignable?(t2.param_types, t.param_types)
|
1403
|
-
# names are ignored, they are just information
|
1404
|
-
# Blocks must be compatible
|
1405
|
-
this_block_t = t.block_type || @nil_t
|
1406
|
-
that_block_t = t2.block_type || @nil_t
|
1407
|
-
assignable?(that_block_t, this_block_t)
|
1408
|
-
|
1409
|
-
end
|
1410
|
-
|
1411
|
-
# @api private
|
1412
|
-
def assignable_PCollectionType(t, t2)
|
1413
|
-
size_t = t.size_type || @collection_default_size_t
|
1414
|
-
case t2
|
1415
|
-
when Types::PCollectionType
|
1416
|
-
size_t2 = t2.size_type || @collection_default_size_t
|
1417
|
-
assignable_PIntegerType(size_t, size_t2)
|
1418
|
-
when Types::PTupleType
|
1419
|
-
# compute the tuple's min/max size, and check if that size matches
|
1420
|
-
from, to = size_range(t2.size_type)
|
1421
|
-
t2s = Types::PIntegerType.new()
|
1422
|
-
t2s.from = t2.types.size - 1 + from
|
1423
|
-
t2s.to = t2.types.size - 1 + to
|
1424
|
-
assignable_PIntegerType(size_t, t2s)
|
1425
|
-
when Types::PStructType
|
1426
|
-
from = to = t2.elements.size
|
1427
|
-
t2s = Types::PIntegerType.new()
|
1428
|
-
t2s.from = from
|
1429
|
-
t2s.to = to
|
1430
|
-
assignable_PIntegerType(size_t, t2s)
|
1431
|
-
else
|
1432
|
-
false
|
1433
|
-
end
|
1434
|
-
end
|
1435
|
-
|
1436
|
-
# @api private
|
1437
|
-
def assignable_PType(t, t2)
|
1438
|
-
return false unless t2.is_a?(Types::PType)
|
1439
|
-
return true if t.type.nil? # wide enough to handle all types
|
1440
|
-
return false if t2.type.nil? # wider than t
|
1441
|
-
assignable?(t.type, t2.type)
|
1442
|
-
end
|
1443
|
-
|
1444
|
-
# Array is assignable if t2 is an Array and t2's element type is assignable, or if t2 is a Tuple
|
1445
|
-
# @api private
|
1446
|
-
def assignable_PArrayType(t, t2)
|
1447
|
-
if t2.is_a?(Types::PArrayType)
|
1448
|
-
return false unless t.element_type.nil? || assignable?(t.element_type, t2.element_type || @t)
|
1449
|
-
assignable_PCollectionType(t, t2)
|
1450
|
-
|
1451
|
-
elsif t2.is_a?(Types::PTupleType)
|
1452
|
-
return false unless t.element_type.nil? || t2.types.all? {|t2_element| assignable?(t.element_type, t2_element) }
|
1453
|
-
t2_regular = t2.types[0..-2]
|
1454
|
-
t2_ranged = t2.types[-1]
|
1455
|
-
t2_from, t2_to = size_range(t2.size_type)
|
1456
|
-
t2_required = t2_regular.size + t2_from
|
1457
|
-
|
1458
|
-
t_entry = t.element_type
|
1459
|
-
|
1460
|
-
# Tuple of anything can not be assigned (unless array is tuple of anything) - this case
|
1461
|
-
# was handled at the top of this method.
|
1462
|
-
#
|
1463
|
-
return false if t_entry.nil?
|
1464
|
-
|
1465
|
-
# array type may be size constrained
|
1466
|
-
size_t = t.size_type || @collection_default_size_t
|
1467
|
-
min, max = size_t.range
|
1468
|
-
# Tuple with fewer min entries can not be assigned
|
1469
|
-
return false if t2_required < min
|
1470
|
-
# Tuple with more optionally available entries can not be assigned
|
1471
|
-
return false if t2_regular.size + t2_to > max
|
1472
|
-
# each tuple type must be assignable to the element type
|
1473
|
-
t2_required.times do |index|
|
1474
|
-
t2_entry = tuple_entry_at(t2, t2_from, t2_to, index)
|
1475
|
-
return false unless assignable?(t_entry, t2_entry)
|
1476
|
-
end
|
1477
|
-
# ... and so must the last, possibly optional (ranged) type
|
1478
|
-
return assignable?(t_entry, t2_ranged)
|
1479
|
-
else
|
1480
|
-
false
|
1481
|
-
end
|
1482
|
-
end
|
1483
|
-
|
1484
|
-
# Hash is assignable if t2 is a Hash and t2's key and element types are assignable
|
1485
|
-
# @api private
|
1486
|
-
def assignable_PHashType(t, t2)
|
1487
|
-
case t2
|
1488
|
-
when Types::PHashType
|
1489
|
-
return true if (t.size_type.nil? || t.size_type.from == 0) && t2.is_the_empty_hash?
|
1490
|
-
return false unless t.key_type.nil? || assignable?(t.key_type, t2.key_type || @t)
|
1491
|
-
return false unless t.element_type.nil? || assignable?(t.element_type, t2.element_type || @t)
|
1492
|
-
assignable_PCollectionType(t, t2)
|
1493
|
-
when Types::PStructType
|
1494
|
-
# hash must accept String as key type
|
1495
|
-
# hash must accept all value types
|
1496
|
-
# hash must accept the size of the struct
|
1497
|
-
size_t = t.size_type || @collection_default_size_t
|
1498
|
-
min, max = size_t.range
|
1499
|
-
struct_size = t2.elements.size
|
1500
|
-
key_type = t.key_type
|
1501
|
-
element_type = t.element_type
|
1502
|
-
( struct_size >= min && struct_size <= max &&
|
1503
|
-
t2.elements.all? {|e| (key_type.nil? || instance_of(key_type, e.name)) && (element_type.nil? || assignable?(element_type, e.value_type)) })
|
1504
|
-
else
|
1505
|
-
false
|
1506
|
-
end
|
1507
|
-
end
|
1508
|
-
|
1509
|
-
# @api private
|
1510
|
-
def assignable_PCatalogEntryType(t1, t2)
|
1511
|
-
t2.is_a?(Types::PCatalogEntryType)
|
1512
|
-
end
|
1513
|
-
|
1514
|
-
# @api private
|
1515
|
-
def assignable_PHostClassType(t1, t2)
|
1516
|
-
return false unless t2.is_a?(Types::PHostClassType)
|
1517
|
-
# Class = Class[name}, Class[name] != Class
|
1518
|
-
return true if t1.class_name.nil?
|
1519
|
-
# Class[name] = Class[name]
|
1520
|
-
return t1.class_name == t2.class_name
|
1521
|
-
end
|
1522
|
-
|
1523
|
-
# @api private
|
1524
|
-
def assignable_PResourceType(t1, t2)
|
1525
|
-
return false unless t2.is_a?(Types::PResourceType)
|
1526
|
-
return true if t1.type_name.nil?
|
1527
|
-
return false if t1.type_name != t2.type_name
|
1528
|
-
return true if t1.title.nil?
|
1529
|
-
return t1.title == t2.title
|
1530
|
-
end
|
1531
|
-
|
1532
|
-
# Data is assignable by other Data and by Array[Data] and Hash[Scalar, Data]
|
1533
|
-
# @api private
|
1534
|
-
def assignable_PDataType(t, t2)
|
1535
|
-
# We cannot put the NotUndefType[Data] in the @data_variant_t since that causes an endless recursion
|
1536
|
-
case t2
|
1537
|
-
when Types::PDataType
|
1538
|
-
true
|
1539
|
-
when Types::PNotUndefType
|
1540
|
-
assignable?(t, t2.type || @t)
|
1541
|
-
else
|
1542
|
-
assignable?(@data_variant_t, t2)
|
1543
|
-
end
|
1544
|
-
end
|
1545
|
-
|
1546
|
-
# Assignable if t2's has the same runtime and the runtime name resolves to
|
1547
|
-
# a class that is the same or subclass of t1's resolved runtime type name
|
1548
|
-
# @api private
|
1549
|
-
def assignable_PRuntimeType(t1, t2)
|
1550
|
-
return false unless t2.is_a?(Types::PRuntimeType)
|
1551
|
-
return false unless t1.runtime == t2.runtime
|
1552
|
-
return true if t1.runtime_type_name.nil? # t1 is wider
|
1553
|
-
return false if t2.runtime_type_name.nil? # t1 not nil, so t2 can not be wider
|
1554
|
-
|
1555
|
-
# NOTE: This only supports Ruby, must change when/if the set of runtimes is expanded
|
1556
|
-
c1 = class_from_string(t1.runtime_type_name)
|
1557
|
-
c2 = class_from_string(t2.runtime_type_name)
|
1558
|
-
return false unless c1.is_a?(Class) && c2.is_a?(Class)
|
1559
|
-
!!(c2 <= c1)
|
1560
|
-
end
|
1561
|
-
|
1562
751
|
# @api private
|
1563
752
|
def debug_string_Object(t)
|
1564
753
|
string(t)
|
@@ -1567,7 +756,7 @@ class Puppet::Pops::Types::TypeCalculator
|
|
1567
756
|
# @api private
|
1568
757
|
def string_PType(t)
|
1569
758
|
if t.type.nil?
|
1570
|
-
|
759
|
+
'Type'
|
1571
760
|
else
|
1572
761
|
"Type[#{string(t.type)}]"
|
1573
762
|
end
|
@@ -1582,7 +771,7 @@ class Puppet::Pops::Types::TypeCalculator
|
|
1582
771
|
# @api private
|
1583
772
|
def string_Symbol(t) ; t.to_s ; end
|
1584
773
|
|
1585
|
-
def string_PAnyType(t) ;
|
774
|
+
def string_PAnyType(t) ; 'Any'; end
|
1586
775
|
|
1587
776
|
# @api private
|
1588
777
|
def string_PUndefType(t) ; 'Undef' ; end
|
@@ -1591,57 +780,57 @@ class Puppet::Pops::Types::TypeCalculator
|
|
1591
780
|
def string_PDefaultType(t) ; 'Default' ; end
|
1592
781
|
|
1593
782
|
# @api private
|
1594
|
-
def string_PBooleanType(t) ;
|
783
|
+
def string_PBooleanType(t) ; 'Boolean'; end
|
1595
784
|
|
1596
785
|
# @api private
|
1597
|
-
def string_PScalarType(t) ;
|
786
|
+
def string_PScalarType(t) ; 'Scalar'; end
|
1598
787
|
|
1599
788
|
# @api private
|
1600
|
-
def string_PDataType(t) ;
|
789
|
+
def string_PDataType(t) ; 'Data'; end
|
1601
790
|
|
1602
791
|
# @api private
|
1603
|
-
def string_PNumericType(t) ;
|
792
|
+
def string_PNumericType(t) ; 'Numeric'; end
|
1604
793
|
|
1605
794
|
# @api private
|
1606
795
|
def string_PIntegerType(t)
|
1607
796
|
range = range_array_part(t)
|
1608
|
-
|
1609
|
-
|
797
|
+
if range.empty?
|
798
|
+
'Integer'
|
1610
799
|
else
|
1611
|
-
"Integer"
|
800
|
+
"Integer[#{range.join(', ')}]"
|
1612
801
|
end
|
1613
802
|
end
|
1614
803
|
|
1615
804
|
# Produces a string from an Integer range type that is used inside other type strings
|
1616
805
|
# @api private
|
1617
806
|
def range_array_part(t)
|
1618
|
-
return [] if t.nil? ||
|
807
|
+
return [] if t.nil? || t.unbounded?
|
1619
808
|
[t.from.nil? ? 'default' : t.from , t.to.nil? ? 'default' : t.to ]
|
1620
809
|
end
|
1621
810
|
|
1622
811
|
# @api private
|
1623
812
|
def string_PFloatType(t)
|
1624
813
|
range = range_array_part(t)
|
1625
|
-
|
1626
|
-
|
814
|
+
if range.empty?
|
815
|
+
'Float'
|
1627
816
|
else
|
1628
|
-
"Float"
|
817
|
+
"Float[#{range.join(', ')}]"
|
1629
818
|
end
|
1630
819
|
end
|
1631
820
|
|
1632
821
|
# @api private
|
1633
822
|
def string_PRegexpType(t)
|
1634
|
-
t.pattern.nil? ?
|
823
|
+
t.pattern.nil? ? 'Regexp' : "Regexp[#{t.regexp.inspect}]"
|
1635
824
|
end
|
1636
825
|
|
1637
826
|
# @api private
|
1638
827
|
def string_PStringType(t)
|
1639
828
|
# skip values in regular output - see debug_string
|
1640
829
|
range = range_array_part(t.size_type)
|
1641
|
-
|
1642
|
-
|
830
|
+
if range.empty?
|
831
|
+
'String'
|
1643
832
|
else
|
1644
|
-
"String"
|
833
|
+
"String[#{range.join(', ')}]"
|
1645
834
|
end
|
1646
835
|
end
|
1647
836
|
|
@@ -1649,37 +838,37 @@ class Puppet::Pops::Types::TypeCalculator
|
|
1649
838
|
def debug_string_PStringType(t)
|
1650
839
|
range = range_array_part(t.size_type)
|
1651
840
|
range_part = range.empty? ? '' : '[' << range.join(' ,') << '], '
|
1652
|
-
|
841
|
+
'String[' << range_part << (t.values.map {|s| "'#{s}'" }).join(', ') << ']'
|
1653
842
|
end
|
1654
843
|
|
1655
844
|
# @api private
|
1656
845
|
def string_PEnumType(t)
|
1657
|
-
return
|
1658
|
-
|
846
|
+
return 'Enum' if t.values.empty?
|
847
|
+
'Enum[' << t.values.map {|s| "'#{s}'" }.join(', ') << ']'
|
1659
848
|
end
|
1660
849
|
|
1661
850
|
# @api private
|
1662
851
|
def string_PVariantType(t)
|
1663
|
-
return
|
1664
|
-
|
852
|
+
return 'Variant' if t.types.empty?
|
853
|
+
'Variant[' << t.types.map {|t2| string(t2) }.join(', ') << ']'
|
1665
854
|
end
|
1666
855
|
|
1667
856
|
# @api private
|
1668
857
|
def string_PTupleType(t)
|
1669
858
|
range = range_array_part(t.size_type)
|
1670
|
-
return
|
1671
|
-
s =
|
859
|
+
return 'Tuple' if t.types.empty?
|
860
|
+
s = 'Tuple[' << t.types.map {|t2| string(t2) }.join(', ')
|
1672
861
|
unless range.empty?
|
1673
|
-
s <<
|
862
|
+
s << ', ' << range.join(', ')
|
1674
863
|
end
|
1675
|
-
s <<
|
864
|
+
s << ']'
|
1676
865
|
s
|
1677
866
|
end
|
1678
867
|
|
1679
868
|
# @api private
|
1680
869
|
def string_PCallableType(t)
|
1681
870
|
# generic
|
1682
|
-
return
|
871
|
+
return 'Callable' if t.param_types.nil?
|
1683
872
|
|
1684
873
|
if t.param_types.types.empty?
|
1685
874
|
range = [0, 0]
|
@@ -1689,7 +878,7 @@ class Puppet::Pops::Types::TypeCalculator
|
|
1689
878
|
# translate to string, and skip Unit types
|
1690
879
|
types = t.param_types.types.map {|t2| string(t2) unless t2.class == Types::PUnitType }.compact
|
1691
880
|
|
1692
|
-
s =
|
881
|
+
s = 'Callable[' << types.join(', ')
|
1693
882
|
unless range.empty?
|
1694
883
|
(s << ', ') unless types.empty?
|
1695
884
|
s << range.join(', ')
|
@@ -1700,19 +889,19 @@ class Puppet::Pops::Types::TypeCalculator
|
|
1700
889
|
(s << ', ') unless types.empty? && range.empty?
|
1701
890
|
s << string(t.block_type)
|
1702
891
|
end
|
1703
|
-
s <<
|
892
|
+
s << ']'
|
1704
893
|
s
|
1705
894
|
end
|
1706
895
|
|
1707
896
|
# @api private
|
1708
897
|
def string_PStructType(t)
|
1709
|
-
return
|
1710
|
-
|
898
|
+
return 'Struct' if t.elements.empty?
|
899
|
+
'Struct[{' << t.elements.map {|element| string(element) }.join(', ') << '}]'
|
1711
900
|
end
|
1712
901
|
|
1713
902
|
def string_PStructElement(t)
|
1714
903
|
k = t.key_type
|
1715
|
-
value_optional = assignable?(
|
904
|
+
value_optional = t.value_type.assignable?(Types::PUndefType::DEFAULT)
|
1716
905
|
key_string =
|
1717
906
|
if k.is_a?(Types::POptionalType)
|
1718
907
|
# Output as literal String
|
@@ -1725,23 +914,23 @@ class Puppet::Pops::Types::TypeCalculator
|
|
1725
914
|
|
1726
915
|
# @api private
|
1727
916
|
def string_PPatternType(t)
|
1728
|
-
return
|
1729
|
-
|
917
|
+
return 'Pattern' if t.patterns.empty?
|
918
|
+
'Pattern[' << t.patterns.map {|s| "#{s.regexp.inspect}" }.join(', ') << ']'
|
1730
919
|
end
|
1731
920
|
|
1732
921
|
# @api private
|
1733
922
|
def string_PCollectionType(t)
|
1734
923
|
range = range_array_part(t.size_type)
|
1735
|
-
|
1736
|
-
|
924
|
+
if range.empty?
|
925
|
+
'Collection'
|
1737
926
|
else
|
1738
|
-
"Collection"
|
927
|
+
"Collection[#{range.join(', ')}]"
|
1739
928
|
end
|
1740
929
|
end
|
1741
930
|
|
1742
931
|
# @api private
|
1743
932
|
def string_PUnitType(t)
|
1744
|
-
|
933
|
+
'Unit'
|
1745
934
|
end
|
1746
935
|
|
1747
936
|
# @api private
|
@@ -1761,7 +950,7 @@ class Puppet::Pops::Types::TypeCalculator
|
|
1761
950
|
|
1762
951
|
# @api private
|
1763
952
|
def string_PCatalogEntryType(t)
|
1764
|
-
|
953
|
+
'CatalogEntry'
|
1765
954
|
end
|
1766
955
|
|
1767
956
|
# @api private
|
@@ -1769,7 +958,7 @@ class Puppet::Pops::Types::TypeCalculator
|
|
1769
958
|
if t.class_name
|
1770
959
|
"Class[#{t.class_name}]"
|
1771
960
|
else
|
1772
|
-
|
961
|
+
'Class'
|
1773
962
|
end
|
1774
963
|
end
|
1775
964
|
|
@@ -1782,7 +971,7 @@ class Puppet::Pops::Types::TypeCalculator
|
|
1782
971
|
capitalize_segments(t.type_name)
|
1783
972
|
end
|
1784
973
|
else
|
1785
|
-
|
974
|
+
'Resource'
|
1786
975
|
end
|
1787
976
|
end
|
1788
977
|
|
@@ -1803,7 +992,7 @@ class Puppet::Pops::Types::TypeCalculator
|
|
1803
992
|
def string_POptionalType(t)
|
1804
993
|
optional_type = t.optional_type
|
1805
994
|
if optional_type.nil?
|
1806
|
-
|
995
|
+
'Optional'
|
1807
996
|
else
|
1808
997
|
if optional_type.is_a?(Puppet::Pops::Types::PStringType) && optional_type.values.size == 1
|
1809
998
|
"Optional['#{optional_type.values[0]}']"
|
@@ -1813,34 +1002,6 @@ class Puppet::Pops::Types::TypeCalculator
|
|
1813
1002
|
end
|
1814
1003
|
end
|
1815
1004
|
|
1816
|
-
# Catches all non enumerable types
|
1817
|
-
# @api private
|
1818
|
-
def enumerable_Object(o)
|
1819
|
-
nil
|
1820
|
-
end
|
1821
|
-
|
1822
|
-
# @api private
|
1823
|
-
def enumerable_PIntegerType(t)
|
1824
|
-
# Not enumerable if representing an infinite range
|
1825
|
-
return nil if t.size == Float::INFINITY
|
1826
|
-
t
|
1827
|
-
end
|
1828
|
-
|
1829
|
-
def self.copy_as_tuple(t)
|
1830
|
-
case t
|
1831
|
-
when Types::PTupleType
|
1832
|
-
t.copy
|
1833
|
-
when Types::PArrayType
|
1834
|
-
# transform array to tuple
|
1835
|
-
result = Types::PTupleType.new
|
1836
|
-
result.addTypes(t.element_type.copy)
|
1837
|
-
result.size_type = t.size_type.nil? ? nil : t.size_type.copy
|
1838
|
-
result
|
1839
|
-
else
|
1840
|
-
raise ArgumentError, "Internal Error: Only Array and Tuple can be given to copy_as_tuple"
|
1841
|
-
end
|
1842
|
-
end
|
1843
|
-
|
1844
1005
|
# Debugging to_s to reduce the amount of output
|
1845
1006
|
def to_s
|
1846
1007
|
'[a TypeCalculator]'
|
@@ -1854,26 +1015,16 @@ class Puppet::Pops::Types::TypeCalculator
|
|
1854
1015
|
s.split(NAME_SEGMENT_SEPARATOR).map(&:capitalize).join(NAME_SEGMENT_SEPARATOR)
|
1855
1016
|
end
|
1856
1017
|
|
1857
|
-
def class_from_string(str)
|
1858
|
-
begin
|
1859
|
-
str.split(NAME_SEGMENT_SEPARATOR).inject(Object) do |memo, name_segment|
|
1860
|
-
memo.const_get(name_segment)
|
1861
|
-
end
|
1862
|
-
rescue NameError
|
1863
|
-
return nil
|
1864
|
-
end
|
1865
|
-
end
|
1866
|
-
|
1867
1018
|
def common_data?(t1, t2)
|
1868
|
-
assignable?(
|
1019
|
+
Types::PDataType::DEFAULT.assignable?(t1) && Types::PDataType::DEFAULT.assignable?(t2)
|
1869
1020
|
end
|
1870
1021
|
|
1871
1022
|
def common_scalar?(t1, t2)
|
1872
|
-
assignable?(
|
1023
|
+
Types::PScalarType::DEFAULT.assignable?(t1) && Types::PScalarType::DEFAULT.assignable?(t2)
|
1873
1024
|
end
|
1874
1025
|
|
1875
1026
|
def common_numeric?(t1, t2)
|
1876
|
-
assignable?(
|
1027
|
+
Types::PNumericType::DEFAULT.assignable?(t1) && Types::PNumericType::DEFAULT.assignable?(t2)
|
1877
1028
|
end
|
1878
1029
|
|
1879
1030
|
end
|