openvox 8.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1104) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +19 -0
  3. data/CODEOWNERS +11 -0
  4. data/CODE_OF_CONDUCT.md +70 -0
  5. data/Gemfile +87 -0
  6. data/Guardfile.example +76 -0
  7. data/LICENSE +202 -0
  8. data/README.md +63 -0
  9. data/Rakefile +170 -0
  10. data/bin/puppet +10 -0
  11. data/conf/environment.conf +18 -0
  12. data/conf/fileserver.conf +32 -0
  13. data/conf/hiera.yaml +11 -0
  14. data/conf/puppet.conf +6 -0
  15. data/examples/enc/regexp_nodes/classes/databases +2 -0
  16. data/examples/enc/regexp_nodes/classes/webservers +2 -0
  17. data/examples/enc/regexp_nodes/environment/development +2 -0
  18. data/examples/enc/regexp_nodes/parameters/service/prod +1 -0
  19. data/examples/enc/regexp_nodes/parameters/service/qa +3 -0
  20. data/examples/enc/regexp_nodes/parameters/service/sandbox +1 -0
  21. data/examples/enc/regexp_nodes/regexp_nodes.rb +270 -0
  22. data/examples/hiera/README.md +102 -0
  23. data/examples/hiera/data/common.yaml +12 -0
  24. data/examples/hiera/data/dc1.yaml +6 -0
  25. data/examples/hiera/hiera.yaml +15 -0
  26. data/examples/hiera/modules/ntp/data/common.yaml +4 -0
  27. data/examples/hiera/modules/ntp/hiera.yaml +9 -0
  28. data/examples/hiera/modules/ntp/manifests/config.pp +18 -0
  29. data/examples/hiera/modules/ntp/templates/ntp.conf.epp +3 -0
  30. data/examples/hiera/modules/users/manifests/common.pp +9 -0
  31. data/examples/hiera/modules/users/manifests/dc1.pp +9 -0
  32. data/examples/hiera/site.pp +3 -0
  33. data/examples/nagios/check_puppet.rb +123 -0
  34. data/ext/README.md +13 -0
  35. data/ext/build_defaults.yaml +18 -0
  36. data/ext/debian/puppet.default +4 -0
  37. data/ext/debian/puppet.init +113 -0
  38. data/ext/hiera/hiera.yaml +15 -0
  39. data/ext/osx/puppet.plist +32 -0
  40. data/ext/project_data.yaml +20 -0
  41. data/ext/redhat/client.init +169 -0
  42. data/ext/redhat/client.sysconfig +2 -0
  43. data/ext/solaris/smf/puppet +44 -0
  44. data/ext/solaris/smf/puppet.xml +46 -0
  45. data/ext/suse/client.init +141 -0
  46. data/ext/systemd/puppet.service +26 -0
  47. data/ext/windows/puppet_interactive.bat +6 -0
  48. data/ext/windows/puppet_shell.bat +9 -0
  49. data/ext/windows/run_puppet_interactive.bat +9 -0
  50. data/ext/windows/service/daemon.bat +6 -0
  51. data/ext/windows/service/daemon.rb +219 -0
  52. data/install.rb +428 -0
  53. data/lib/hiera/puppet_function.rb +86 -0
  54. data/lib/hiera/scope.rb +92 -0
  55. data/lib/hiera_puppet.rb +78 -0
  56. data/lib/puppet/agent/disabler.rb +55 -0
  57. data/lib/puppet/agent/locker.rb +46 -0
  58. data/lib/puppet/agent.rb +178 -0
  59. data/lib/puppet/application/agent.rb +527 -0
  60. data/lib/puppet/application/apply.rb +435 -0
  61. data/lib/puppet/application/catalog.rb +6 -0
  62. data/lib/puppet/application/config.rb +7 -0
  63. data/lib/puppet/application/describe.rb +255 -0
  64. data/lib/puppet/application/device.rb +440 -0
  65. data/lib/puppet/application/doc.rb +232 -0
  66. data/lib/puppet/application/epp.rb +7 -0
  67. data/lib/puppet/application/face_base.rb +277 -0
  68. data/lib/puppet/application/facts.rb +11 -0
  69. data/lib/puppet/application/filebucket.rb +324 -0
  70. data/lib/puppet/application/generate.rb +7 -0
  71. data/lib/puppet/application/help.rb +7 -0
  72. data/lib/puppet/application/indirection_base.rb +6 -0
  73. data/lib/puppet/application/lookup.rb +433 -0
  74. data/lib/puppet/application/module.rb +6 -0
  75. data/lib/puppet/application/node.rb +6 -0
  76. data/lib/puppet/application/parser.rb +7 -0
  77. data/lib/puppet/application/plugin.rb +6 -0
  78. data/lib/puppet/application/report.rb +6 -0
  79. data/lib/puppet/application/resource.rb +264 -0
  80. data/lib/puppet/application/script.rb +266 -0
  81. data/lib/puppet/application/ssl.rb +331 -0
  82. data/lib/puppet/application.rb +596 -0
  83. data/lib/puppet/application_support.rb +69 -0
  84. data/lib/puppet/coercion.rb +42 -0
  85. data/lib/puppet/compilable_resource_type.rb +17 -0
  86. data/lib/puppet/concurrent/lock.rb +15 -0
  87. data/lib/puppet/concurrent/synchronized.rb +15 -0
  88. data/lib/puppet/concurrent/thread_local_singleton.rb +18 -0
  89. data/lib/puppet/concurrent.rb +4 -0
  90. data/lib/puppet/configurer/downloader.rb +91 -0
  91. data/lib/puppet/configurer/fact_handler.rb +51 -0
  92. data/lib/puppet/configurer/plugin_handler.rb +61 -0
  93. data/lib/puppet/configurer.rb +759 -0
  94. data/lib/puppet/confine/any.rb +28 -0
  95. data/lib/puppet/confine/boolean.rb +47 -0
  96. data/lib/puppet/confine/exists.rb +21 -0
  97. data/lib/puppet/confine/false.rb +27 -0
  98. data/lib/puppet/confine/feature.rb +18 -0
  99. data/lib/puppet/confine/true.rb +28 -0
  100. data/lib/puppet/confine/variable.rb +61 -0
  101. data/lib/puppet/confine.rb +86 -0
  102. data/lib/puppet/confine_collection.rb +54 -0
  103. data/lib/puppet/confiner.rb +48 -0
  104. data/lib/puppet/context/trusted_information.rb +122 -0
  105. data/lib/puppet/context.rb +190 -0
  106. data/lib/puppet/daemon.rb +198 -0
  107. data/lib/puppet/data_binding.rb +16 -0
  108. data/lib/puppet/datatypes/error.rb +23 -0
  109. data/lib/puppet/datatypes/impl/error.rb +42 -0
  110. data/lib/puppet/datatypes.rb +218 -0
  111. data/lib/puppet/defaults.rb +2316 -0
  112. data/lib/puppet/environments.rb +599 -0
  113. data/lib/puppet/error.rb +142 -0
  114. data/lib/puppet/etc.rb +185 -0
  115. data/lib/puppet/external/dot.rb +315 -0
  116. data/lib/puppet/face/catalog/select.rb +51 -0
  117. data/lib/puppet/face/catalog.rb +167 -0
  118. data/lib/puppet/face/config.rb +266 -0
  119. data/lib/puppet/face/epp.rb +565 -0
  120. data/lib/puppet/face/facts.rb +176 -0
  121. data/lib/puppet/face/generate.rb +69 -0
  122. data/lib/puppet/face/help/action.erb +89 -0
  123. data/lib/puppet/face/help/face.erb +114 -0
  124. data/lib/puppet/face/help/global.erb +16 -0
  125. data/lib/puppet/face/help/man.erb +152 -0
  126. data/lib/puppet/face/help.rb +260 -0
  127. data/lib/puppet/face/module/changes.rb +44 -0
  128. data/lib/puppet/face/module/install.rb +149 -0
  129. data/lib/puppet/face/module/list.rb +271 -0
  130. data/lib/puppet/face/module/uninstall.rb +91 -0
  131. data/lib/puppet/face/module/upgrade.rb +89 -0
  132. data/lib/puppet/face/module.rb +21 -0
  133. data/lib/puppet/face/node/clean.rb +109 -0
  134. data/lib/puppet/face/node.rb +45 -0
  135. data/lib/puppet/face/parser.rb +226 -0
  136. data/lib/puppet/face/plugin.rb +62 -0
  137. data/lib/puppet/face/report.rb +54 -0
  138. data/lib/puppet/face/resource.rb +55 -0
  139. data/lib/puppet/face.rb +14 -0
  140. data/lib/puppet/facter_impl.rb +96 -0
  141. data/lib/puppet/feature/base.rb +76 -0
  142. data/lib/puppet/feature/bolt.rb +5 -0
  143. data/lib/puppet/feature/cfpropertylist.rb +5 -0
  144. data/lib/puppet/feature/eventlog.rb +7 -0
  145. data/lib/puppet/feature/hiera_eyaml.rb +5 -0
  146. data/lib/puppet/feature/hocon.rb +5 -0
  147. data/lib/puppet/feature/libuser.rb +10 -0
  148. data/lib/puppet/feature/msgpack.rb +5 -0
  149. data/lib/puppet/feature/pe_license.rb +6 -0
  150. data/lib/puppet/feature/pson.rb +6 -0
  151. data/lib/puppet/feature/selinux.rb +5 -0
  152. data/lib/puppet/feature/ssh.rb +5 -0
  153. data/lib/puppet/feature/telnet.rb +5 -0
  154. data/lib/puppet/feature/zlib.rb +7 -0
  155. data/lib/puppet/ffi/posix/constants.rb +16 -0
  156. data/lib/puppet/ffi/posix/functions.rb +25 -0
  157. data/lib/puppet/ffi/posix.rb +12 -0
  158. data/lib/puppet/ffi/windows/api_types.rb +313 -0
  159. data/lib/puppet/ffi/windows/constants.rb +406 -0
  160. data/lib/puppet/ffi/windows/functions.rb +629 -0
  161. data/lib/puppet/ffi/windows/structs.rb +339 -0
  162. data/lib/puppet/ffi/windows.rb +14 -0
  163. data/lib/puppet/file_bucket/dipper.rb +183 -0
  164. data/lib/puppet/file_bucket/file.rb +131 -0
  165. data/lib/puppet/file_bucket.rb +6 -0
  166. data/lib/puppet/file_serving/base.rb +94 -0
  167. data/lib/puppet/file_serving/configuration/parser.rb +116 -0
  168. data/lib/puppet/file_serving/configuration.rb +116 -0
  169. data/lib/puppet/file_serving/content.rb +45 -0
  170. data/lib/puppet/file_serving/fileset.rb +190 -0
  171. data/lib/puppet/file_serving/http_metadata.rb +61 -0
  172. data/lib/puppet/file_serving/metadata.rb +174 -0
  173. data/lib/puppet/file_serving/mount/file.rb +126 -0
  174. data/lib/puppet/file_serving/mount/locales.rb +35 -0
  175. data/lib/puppet/file_serving/mount/modules.rb +29 -0
  176. data/lib/puppet/file_serving/mount/pluginfacts.rb +35 -0
  177. data/lib/puppet/file_serving/mount/plugins.rb +35 -0
  178. data/lib/puppet/file_serving/mount/scripts.rb +27 -0
  179. data/lib/puppet/file_serving/mount/tasks.rb +26 -0
  180. data/lib/puppet/file_serving/mount.rb +41 -0
  181. data/lib/puppet/file_serving/terminus_helper.rb +33 -0
  182. data/lib/puppet/file_serving/terminus_selector.rb +33 -0
  183. data/lib/puppet/file_serving.rb +5 -0
  184. data/lib/puppet/file_system/file_impl.rb +189 -0
  185. data/lib/puppet/file_system/jruby.rb +25 -0
  186. data/lib/puppet/file_system/memory_file.rb +82 -0
  187. data/lib/puppet/file_system/memory_impl.rb +103 -0
  188. data/lib/puppet/file_system/path_pattern.rb +95 -0
  189. data/lib/puppet/file_system/posix.rb +52 -0
  190. data/lib/puppet/file_system/uniquefile.rb +190 -0
  191. data/lib/puppet/file_system/windows.rb +224 -0
  192. data/lib/puppet/file_system.rb +421 -0
  193. data/lib/puppet/forge/cache.rb +61 -0
  194. data/lib/puppet/forge/errors.rb +113 -0
  195. data/lib/puppet/forge/repository.rb +98 -0
  196. data/lib/puppet/forge.rb +257 -0
  197. data/lib/puppet/functions/abs.rb +64 -0
  198. data/lib/puppet/functions/alert.rb +16 -0
  199. data/lib/puppet/functions/all.rb +106 -0
  200. data/lib/puppet/functions/annotate.rb +110 -0
  201. data/lib/puppet/functions/any.rb +111 -0
  202. data/lib/puppet/functions/assert_type.rb +96 -0
  203. data/lib/puppet/functions/binary_file.rb +35 -0
  204. data/lib/puppet/functions/break.rb +49 -0
  205. data/lib/puppet/functions/call.rb +81 -0
  206. data/lib/puppet/functions/camelcase.rb +63 -0
  207. data/lib/puppet/functions/capitalize.rb +62 -0
  208. data/lib/puppet/functions/ceiling.rb +38 -0
  209. data/lib/puppet/functions/chomp.rb +58 -0
  210. data/lib/puppet/functions/chop.rb +68 -0
  211. data/lib/puppet/functions/compare.rb +127 -0
  212. data/lib/puppet/functions/contain.rb +58 -0
  213. data/lib/puppet/functions/convert_to.rb +36 -0
  214. data/lib/puppet/functions/crit.rb +16 -0
  215. data/lib/puppet/functions/debug.rb +16 -0
  216. data/lib/puppet/functions/defined.rb +163 -0
  217. data/lib/puppet/functions/dig.rb +70 -0
  218. data/lib/puppet/functions/downcase.rb +91 -0
  219. data/lib/puppet/functions/each.rb +169 -0
  220. data/lib/puppet/functions/emerg.rb +16 -0
  221. data/lib/puppet/functions/empty.rb +87 -0
  222. data/lib/puppet/functions/epp.rb +50 -0
  223. data/lib/puppet/functions/err.rb +16 -0
  224. data/lib/puppet/functions/eyaml_lookup_key.rb +103 -0
  225. data/lib/puppet/functions/filter.rb +138 -0
  226. data/lib/puppet/functions/find_file.rb +50 -0
  227. data/lib/puppet/functions/find_template.rb +65 -0
  228. data/lib/puppet/functions/flatten.rb +66 -0
  229. data/lib/puppet/functions/floor.rb +38 -0
  230. data/lib/puppet/functions/get.rb +152 -0
  231. data/lib/puppet/functions/getvar.rb +89 -0
  232. data/lib/puppet/functions/group_by.rb +62 -0
  233. data/lib/puppet/functions/hiera.rb +91 -0
  234. data/lib/puppet/functions/hiera_array.rb +83 -0
  235. data/lib/puppet/functions/hiera_hash.rb +94 -0
  236. data/lib/puppet/functions/hiera_include.rb +107 -0
  237. data/lib/puppet/functions/hocon_data.rb +41 -0
  238. data/lib/puppet/functions/import.rb +9 -0
  239. data/lib/puppet/functions/include.rb +56 -0
  240. data/lib/puppet/functions/index.rb +168 -0
  241. data/lib/puppet/functions/info.rb +16 -0
  242. data/lib/puppet/functions/inline_epp.rb +61 -0
  243. data/lib/puppet/functions/join.rb +58 -0
  244. data/lib/puppet/functions/json_data.rb +33 -0
  245. data/lib/puppet/functions/keys.rb +27 -0
  246. data/lib/puppet/functions/length.rb +45 -0
  247. data/lib/puppet/functions/lest.rb +57 -0
  248. data/lib/puppet/functions/lookup.rb +224 -0
  249. data/lib/puppet/functions/lstrip.rb +59 -0
  250. data/lib/puppet/functions/map.rb +137 -0
  251. data/lib/puppet/functions/match.rb +133 -0
  252. data/lib/puppet/functions/max.rb +250 -0
  253. data/lib/puppet/functions/min.rb +249 -0
  254. data/lib/puppet/functions/module_directory.rb +43 -0
  255. data/lib/puppet/functions/new.rb +1013 -0
  256. data/lib/puppet/functions/next.rb +35 -0
  257. data/lib/puppet/functions/notice.rb +16 -0
  258. data/lib/puppet/functions/partition.rb +62 -0
  259. data/lib/puppet/functions/reduce.rb +159 -0
  260. data/lib/puppet/functions/regsubst.rb +100 -0
  261. data/lib/puppet/functions/require.rb +81 -0
  262. data/lib/puppet/functions/return.rb +17 -0
  263. data/lib/puppet/functions/reverse_each.rb +96 -0
  264. data/lib/puppet/functions/round.rb +26 -0
  265. data/lib/puppet/functions/rstrip.rb +59 -0
  266. data/lib/puppet/functions/scanf.rb +46 -0
  267. data/lib/puppet/functions/size.rb +15 -0
  268. data/lib/puppet/functions/slice.rb +127 -0
  269. data/lib/puppet/functions/sort.rb +76 -0
  270. data/lib/puppet/functions/split.rb +78 -0
  271. data/lib/puppet/functions/step.rb +100 -0
  272. data/lib/puppet/functions/strftime.rb +214 -0
  273. data/lib/puppet/functions/strip.rb +59 -0
  274. data/lib/puppet/functions/then.rb +80 -0
  275. data/lib/puppet/functions/tree_each.rb +198 -0
  276. data/lib/puppet/functions/type.rb +74 -0
  277. data/lib/puppet/functions/unique.rb +135 -0
  278. data/lib/puppet/functions/unwrap.rb +61 -0
  279. data/lib/puppet/functions/upcase.rb +91 -0
  280. data/lib/puppet/functions/values.rb +27 -0
  281. data/lib/puppet/functions/versioncmp.rb +41 -0
  282. data/lib/puppet/functions/warning.rb +16 -0
  283. data/lib/puppet/functions/with.rb +34 -0
  284. data/lib/puppet/functions/yaml_data.rb +45 -0
  285. data/lib/puppet/functions.rb +858 -0
  286. data/lib/puppet/generate/models/type/property.rb +73 -0
  287. data/lib/puppet/generate/models/type/type.rb +68 -0
  288. data/lib/puppet/generate/templates/type/pcore.erb +42 -0
  289. data/lib/puppet/generate/type.rb +255 -0
  290. data/lib/puppet/gettext/config.rb +282 -0
  291. data/lib/puppet/gettext/module_translations.rb +43 -0
  292. data/lib/puppet/gettext/stubs.rb +13 -0
  293. data/lib/puppet/graph/key.rb +28 -0
  294. data/lib/puppet/graph/prioritizer.rb +31 -0
  295. data/lib/puppet/graph/rb_tree_map.rb +407 -0
  296. data/lib/puppet/graph/relationship_graph.rb +286 -0
  297. data/lib/puppet/graph/sequential_prioritizer.rb +33 -0
  298. data/lib/puppet/graph/simple_graph.rb +552 -0
  299. data/lib/puppet/graph.rb +11 -0
  300. data/lib/puppet/http/client.rb +529 -0
  301. data/lib/puppet/http/dns.rb +159 -0
  302. data/lib/puppet/http/errors.rb +50 -0
  303. data/lib/puppet/http/external_client.rb +89 -0
  304. data/lib/puppet/http/factory.rb +53 -0
  305. data/lib/puppet/http/pool.rb +174 -0
  306. data/lib/puppet/http/pool_entry.rb +19 -0
  307. data/lib/puppet/http/proxy.rb +139 -0
  308. data/lib/puppet/http/redirector.rb +87 -0
  309. data/lib/puppet/http/resolver/server_list.rb +88 -0
  310. data/lib/puppet/http/resolver/settings.rb +24 -0
  311. data/lib/puppet/http/resolver/srv.rb +42 -0
  312. data/lib/puppet/http/resolver.rb +50 -0
  313. data/lib/puppet/http/response.rb +104 -0
  314. data/lib/puppet/http/response_converter.rb +25 -0
  315. data/lib/puppet/http/response_net_http.rb +43 -0
  316. data/lib/puppet/http/retry_after_handler.rb +78 -0
  317. data/lib/puppet/http/service/ca.rb +133 -0
  318. data/lib/puppet/http/service/compiler.rb +356 -0
  319. data/lib/puppet/http/service/file_server.rb +200 -0
  320. data/lib/puppet/http/service/puppetserver.rb +54 -0
  321. data/lib/puppet/http/service/report.rb +62 -0
  322. data/lib/puppet/http/service.rb +177 -0
  323. data/lib/puppet/http/session.rb +124 -0
  324. data/lib/puppet/http/site.rb +44 -0
  325. data/lib/puppet/http.rb +48 -0
  326. data/lib/puppet/indirector/catalog/compiler.rb +432 -0
  327. data/lib/puppet/indirector/catalog/json.rb +42 -0
  328. data/lib/puppet/indirector/catalog/msgpack.rb +8 -0
  329. data/lib/puppet/indirector/catalog/rest.rb +51 -0
  330. data/lib/puppet/indirector/catalog/store_configs.rb +8 -0
  331. data/lib/puppet/indirector/catalog/yaml.rb +8 -0
  332. data/lib/puppet/indirector/code.rb +8 -0
  333. data/lib/puppet/indirector/data_binding/hiera.rb +8 -0
  334. data/lib/puppet/indirector/data_binding/none.rb +10 -0
  335. data/lib/puppet/indirector/direct_file_server.rb +20 -0
  336. data/lib/puppet/indirector/envelope.rb +13 -0
  337. data/lib/puppet/indirector/errors.rb +7 -0
  338. data/lib/puppet/indirector/exec.rb +40 -0
  339. data/lib/puppet/indirector/face.rb +142 -0
  340. data/lib/puppet/indirector/fact_search.rb +62 -0
  341. data/lib/puppet/indirector/facts/facter.rb +120 -0
  342. data/lib/puppet/indirector/facts/json.rb +29 -0
  343. data/lib/puppet/indirector/facts/memory.rb +11 -0
  344. data/lib/puppet/indirector/facts/network_device.rb +29 -0
  345. data/lib/puppet/indirector/facts/rest.rb +46 -0
  346. data/lib/puppet/indirector/facts/store_configs.rb +12 -0
  347. data/lib/puppet/indirector/facts/yaml.rb +31 -0
  348. data/lib/puppet/indirector/file_bucket_file/file.rb +268 -0
  349. data/lib/puppet/indirector/file_bucket_file/rest.rb +53 -0
  350. data/lib/puppet/indirector/file_bucket_file/selector.rb +54 -0
  351. data/lib/puppet/indirector/file_content/file.rb +9 -0
  352. data/lib/puppet/indirector/file_content/file_server.rb +9 -0
  353. data/lib/puppet/indirector/file_content/rest.rb +37 -0
  354. data/lib/puppet/indirector/file_content/selector.rb +32 -0
  355. data/lib/puppet/indirector/file_content.rb +7 -0
  356. data/lib/puppet/indirector/file_metadata/file.rb +9 -0
  357. data/lib/puppet/indirector/file_metadata/file_server.rb +9 -0
  358. data/lib/puppet/indirector/file_metadata/http.rb +49 -0
  359. data/lib/puppet/indirector/file_metadata/rest.rb +58 -0
  360. data/lib/puppet/indirector/file_metadata/selector.rb +32 -0
  361. data/lib/puppet/indirector/file_metadata.rb +7 -0
  362. data/lib/puppet/indirector/file_server.rb +57 -0
  363. data/lib/puppet/indirector/generic_http.rb +7 -0
  364. data/lib/puppet/indirector/hiera.rb +101 -0
  365. data/lib/puppet/indirector/indirection.rb +381 -0
  366. data/lib/puppet/indirector/json.rb +82 -0
  367. data/lib/puppet/indirector/memory.rb +37 -0
  368. data/lib/puppet/indirector/msgpack.rb +87 -0
  369. data/lib/puppet/indirector/node/exec.rb +70 -0
  370. data/lib/puppet/indirector/node/json.rb +9 -0
  371. data/lib/puppet/indirector/node/memory.rb +12 -0
  372. data/lib/puppet/indirector/node/msgpack.rb +9 -0
  373. data/lib/puppet/indirector/node/plain.rb +23 -0
  374. data/lib/puppet/indirector/node/rest.rb +31 -0
  375. data/lib/puppet/indirector/node/store_configs.rb +8 -0
  376. data/lib/puppet/indirector/node/yaml.rb +9 -0
  377. data/lib/puppet/indirector/none.rb +10 -0
  378. data/lib/puppet/indirector/plain.rb +11 -0
  379. data/lib/puppet/indirector/report/json.rb +36 -0
  380. data/lib/puppet/indirector/report/msgpack.rb +13 -0
  381. data/lib/puppet/indirector/report/processor.rb +63 -0
  382. data/lib/puppet/indirector/report/rest.rb +31 -0
  383. data/lib/puppet/indirector/report/yaml.rb +36 -0
  384. data/lib/puppet/indirector/request.rb +197 -0
  385. data/lib/puppet/indirector/resource/ral.rb +66 -0
  386. data/lib/puppet/indirector/resource/store_configs.rb +14 -0
  387. data/lib/puppet/indirector/resource/validator.rb +10 -0
  388. data/lib/puppet/indirector/rest.rb +66 -0
  389. data/lib/puppet/indirector/store_configs.rb +32 -0
  390. data/lib/puppet/indirector/terminus.rb +180 -0
  391. data/lib/puppet/indirector/yaml.rb +65 -0
  392. data/lib/puppet/indirector.rb +64 -0
  393. data/lib/puppet/info_service/class_information_service.rb +108 -0
  394. data/lib/puppet/info_service/plan_information_service.rb +38 -0
  395. data/lib/puppet/info_service/task_information_service.rb +45 -0
  396. data/lib/puppet/info_service.rb +27 -0
  397. data/lib/puppet/interface/action.rb +410 -0
  398. data/lib/puppet/interface/action_builder.rb +167 -0
  399. data/lib/puppet/interface/action_manager.rb +101 -0
  400. data/lib/puppet/interface/documentation.rb +363 -0
  401. data/lib/puppet/interface/face_collection.rb +141 -0
  402. data/lib/puppet/interface/option.rb +184 -0
  403. data/lib/puppet/interface/option_builder.rb +110 -0
  404. data/lib/puppet/interface/option_manager.rb +108 -0
  405. data/lib/puppet/interface.rb +240 -0
  406. data/lib/puppet/loaders.rb +31 -0
  407. data/lib/puppet/metatype/manager.rb +198 -0
  408. data/lib/puppet/module/plan.rb +166 -0
  409. data/lib/puppet/module/task.rb +288 -0
  410. data/lib/puppet/module.rb +487 -0
  411. data/lib/puppet/module_tool/applications/application.rb +96 -0
  412. data/lib/puppet/module_tool/applications/checksummer.rb +62 -0
  413. data/lib/puppet/module_tool/applications/installer.rb +402 -0
  414. data/lib/puppet/module_tool/applications/uninstaller.rb +121 -0
  415. data/lib/puppet/module_tool/applications/unpacker.rb +102 -0
  416. data/lib/puppet/module_tool/applications/upgrader.rb +288 -0
  417. data/lib/puppet/module_tool/applications.rb +14 -0
  418. data/lib/puppet/module_tool/checksums.rb +50 -0
  419. data/lib/puppet/module_tool/dependency.rb +42 -0
  420. data/lib/puppet/module_tool/errors/base.rb +17 -0
  421. data/lib/puppet/module_tool/errors/installer.rb +94 -0
  422. data/lib/puppet/module_tool/errors/shared.rb +228 -0
  423. data/lib/puppet/module_tool/errors/uninstaller.rb +51 -0
  424. data/lib/puppet/module_tool/errors/upgrader.rb +64 -0
  425. data/lib/puppet/module_tool/errors.rb +13 -0
  426. data/lib/puppet/module_tool/install_directory.rb +48 -0
  427. data/lib/puppet/module_tool/installed_modules.rb +99 -0
  428. data/lib/puppet/module_tool/local_tarball.rb +92 -0
  429. data/lib/puppet/module_tool/metadata.rb +227 -0
  430. data/lib/puppet/module_tool/shared_behaviors.rb +199 -0
  431. data/lib/puppet/module_tool/tar/gnu.rb +23 -0
  432. data/lib/puppet/module_tool/tar/mini.rb +118 -0
  433. data/lib/puppet/module_tool/tar.rb +20 -0
  434. data/lib/puppet/module_tool.rb +194 -0
  435. data/lib/puppet/network/authconfig.rb +9 -0
  436. data/lib/puppet/network/authorization.rb +21 -0
  437. data/lib/puppet/network/client_request.rb +32 -0
  438. data/lib/puppet/network/format.rb +116 -0
  439. data/lib/puppet/network/format_handler.rb +110 -0
  440. data/lib/puppet/network/format_support.rb +140 -0
  441. data/lib/puppet/network/formats.rb +338 -0
  442. data/lib/puppet/network/http/api/indirected_routes.rb +270 -0
  443. data/lib/puppet/network/http/api/indirection_type.rb +33 -0
  444. data/lib/puppet/network/http/api/master/v3/environments.rb +4 -0
  445. data/lib/puppet/network/http/api/master/v3.rb +4 -0
  446. data/lib/puppet/network/http/api/master.rb +5 -0
  447. data/lib/puppet/network/http/api/server/v3/environments.rb +54 -0
  448. data/lib/puppet/network/http/api/server/v3.rb +40 -0
  449. data/lib/puppet/network/http/api/server.rb +12 -0
  450. data/lib/puppet/network/http/api.rb +41 -0
  451. data/lib/puppet/network/http/connection.rb +288 -0
  452. data/lib/puppet/network/http/error.rb +75 -0
  453. data/lib/puppet/network/http/handler.rb +213 -0
  454. data/lib/puppet/network/http/issues.rb +14 -0
  455. data/lib/puppet/network/http/memory_response.rb +15 -0
  456. data/lib/puppet/network/http/request.rb +83 -0
  457. data/lib/puppet/network/http/response.rb +25 -0
  458. data/lib/puppet/network/http/route.rb +104 -0
  459. data/lib/puppet/network/http.rb +30 -0
  460. data/lib/puppet/network/http_pool.rb +78 -0
  461. data/lib/puppet/network/uri.rb +20 -0
  462. data/lib/puppet/network.rb +5 -0
  463. data/lib/puppet/node/environment.rb +638 -0
  464. data/lib/puppet/node/facts.rb +165 -0
  465. data/lib/puppet/node/server_facts.rb +46 -0
  466. data/lib/puppet/node.rb +256 -0
  467. data/lib/puppet/pal/catalog_compiler.rb +107 -0
  468. data/lib/puppet/pal/compiler.rb +227 -0
  469. data/lib/puppet/pal/function_signature.rb +54 -0
  470. data/lib/puppet/pal/json_catalog_encoder.rb +76 -0
  471. data/lib/puppet/pal/pal_api.rb +17 -0
  472. data/lib/puppet/pal/pal_impl.rb +585 -0
  473. data/lib/puppet/pal/plan_signature.rb +73 -0
  474. data/lib/puppet/pal/script_compiler.rb +75 -0
  475. data/lib/puppet/pal/task_signature.rb +64 -0
  476. data/lib/puppet/parameter/boolean.rb +17 -0
  477. data/lib/puppet/parameter/package_options.rb +33 -0
  478. data/lib/puppet/parameter/path.rb +61 -0
  479. data/lib/puppet/parameter/value.rb +93 -0
  480. data/lib/puppet/parameter/value_collection.rb +213 -0
  481. data/lib/puppet/parameter.rb +590 -0
  482. data/lib/puppet/parser/abstract_compiler.rb +35 -0
  483. data/lib/puppet/parser/ast/block_expression.rb +17 -0
  484. data/lib/puppet/parser/ast/branch.rb +21 -0
  485. data/lib/puppet/parser/ast/hostclass.rb +29 -0
  486. data/lib/puppet/parser/ast/leaf.rb +84 -0
  487. data/lib/puppet/parser/ast/node.rb +19 -0
  488. data/lib/puppet/parser/ast/pops_bridge.rb +245 -0
  489. data/lib/puppet/parser/ast/resource.rb +66 -0
  490. data/lib/puppet/parser/ast/resource_instance.rb +13 -0
  491. data/lib/puppet/parser/ast/resourceparam.rb +33 -0
  492. data/lib/puppet/parser/ast/top_level_construct.rb +6 -0
  493. data/lib/puppet/parser/ast.rb +62 -0
  494. data/lib/puppet/parser/catalog_compiler.rb +56 -0
  495. data/lib/puppet/parser/compiler/catalog_validator/relationship_validator.rb +41 -0
  496. data/lib/puppet/parser/compiler/catalog_validator.rb +35 -0
  497. data/lib/puppet/parser/compiler.rb +616 -0
  498. data/lib/puppet/parser/e4_parser_adapter.rb +61 -0
  499. data/lib/puppet/parser/files.rb +95 -0
  500. data/lib/puppet/parser/functions/assert_type.rb +62 -0
  501. data/lib/puppet/parser/functions/binary_file.rb +26 -0
  502. data/lib/puppet/parser/functions/break.rb +41 -0
  503. data/lib/puppet/parser/functions/contain.rb +32 -0
  504. data/lib/puppet/parser/functions/create_resources.rb +114 -0
  505. data/lib/puppet/parser/functions/defined.rb +109 -0
  506. data/lib/puppet/parser/functions/dig.rb +40 -0
  507. data/lib/puppet/parser/functions/digest.rb +7 -0
  508. data/lib/puppet/parser/functions/each.rb +106 -0
  509. data/lib/puppet/parser/functions/epp.rb +40 -0
  510. data/lib/puppet/parser/functions/fail.rb +13 -0
  511. data/lib/puppet/parser/functions/file.rb +35 -0
  512. data/lib/puppet/parser/functions/filter.rb +81 -0
  513. data/lib/puppet/parser/functions/find_file.rb +29 -0
  514. data/lib/puppet/parser/functions/fqdn_rand.rb +46 -0
  515. data/lib/puppet/parser/functions/generate.rb +39 -0
  516. data/lib/puppet/parser/functions/hiera.rb +105 -0
  517. data/lib/puppet/parser/functions/hiera_array.rb +93 -0
  518. data/lib/puppet/parser/functions/hiera_hash.rb +103 -0
  519. data/lib/puppet/parser/functions/hiera_include.rb +102 -0
  520. data/lib/puppet/parser/functions/include.rb +36 -0
  521. data/lib/puppet/parser/functions/inline_epp.rb +52 -0
  522. data/lib/puppet/parser/functions/inline_template.rb +28 -0
  523. data/lib/puppet/parser/functions/lest.rb +51 -0
  524. data/lib/puppet/parser/functions/lookup.rb +134 -0
  525. data/lib/puppet/parser/functions/map.rb +78 -0
  526. data/lib/puppet/parser/functions/match.rb +45 -0
  527. data/lib/puppet/parser/functions/md5.rb +7 -0
  528. data/lib/puppet/parser/functions/new.rb +992 -0
  529. data/lib/puppet/parser/functions/next.rb +40 -0
  530. data/lib/puppet/parser/functions/realize.rb +22 -0
  531. data/lib/puppet/parser/functions/reduce.rb +139 -0
  532. data/lib/puppet/parser/functions/regsubst.rb +65 -0
  533. data/lib/puppet/parser/functions/require.rb +43 -0
  534. data/lib/puppet/parser/functions/return.rb +94 -0
  535. data/lib/puppet/parser/functions/reverse_each.rb +85 -0
  536. data/lib/puppet/parser/functions/scanf.rb +40 -0
  537. data/lib/puppet/parser/functions/sha1.rb +7 -0
  538. data/lib/puppet/parser/functions/sha256.rb +7 -0
  539. data/lib/puppet/parser/functions/shellquote.rb +63 -0
  540. data/lib/puppet/parser/functions/slice.rb +41 -0
  541. data/lib/puppet/parser/functions/split.rb +29 -0
  542. data/lib/puppet/parser/functions/sprintf.rb +62 -0
  543. data/lib/puppet/parser/functions/step.rb +86 -0
  544. data/lib/puppet/parser/functions/strftime.rb +187 -0
  545. data/lib/puppet/parser/functions/tag.rb +15 -0
  546. data/lib/puppet/parser/functions/tagged.rb +24 -0
  547. data/lib/puppet/parser/functions/template.rb +42 -0
  548. data/lib/puppet/parser/functions/then.rb +75 -0
  549. data/lib/puppet/parser/functions/type.rb +55 -0
  550. data/lib/puppet/parser/functions/versioncmp.rb +31 -0
  551. data/lib/puppet/parser/functions/with.rb +30 -0
  552. data/lib/puppet/parser/functions.rb +324 -0
  553. data/lib/puppet/parser/parser_factory.rb +32 -0
  554. data/lib/puppet/parser/relationship.rb +90 -0
  555. data/lib/puppet/parser/resource/param.rb +37 -0
  556. data/lib/puppet/parser/resource.rb +353 -0
  557. data/lib/puppet/parser/scope.rb +1141 -0
  558. data/lib/puppet/parser/script_compiler.rb +123 -0
  559. data/lib/puppet/parser/templatewrapper.rb +105 -0
  560. data/lib/puppet/parser/type_loader.rb +151 -0
  561. data/lib/puppet/parser.rb +22 -0
  562. data/lib/puppet/plugins/configuration.rb +31 -0
  563. data/lib/puppet/plugins/syntax_checkers.rb +99 -0
  564. data/lib/puppet/plugins.rb +11 -0
  565. data/lib/puppet/pops/adaptable.rb +199 -0
  566. data/lib/puppet/pops/adapters.rb +159 -0
  567. data/lib/puppet/pops/evaluator/access_operator.rb +732 -0
  568. data/lib/puppet/pops/evaluator/callable_signature.rb +108 -0
  569. data/lib/puppet/pops/evaluator/closure.rb +370 -0
  570. data/lib/puppet/pops/evaluator/collector_transformer.rb +237 -0
  571. data/lib/puppet/pops/evaluator/collectors/abstract_collector.rb +88 -0
  572. data/lib/puppet/pops/evaluator/collectors/catalog_collector.rb +30 -0
  573. data/lib/puppet/pops/evaluator/collectors/exported_collector.rb +71 -0
  574. data/lib/puppet/pops/evaluator/collectors/fixed_set_collector.rb +38 -0
  575. data/lib/puppet/pops/evaluator/compare_operator.rb +269 -0
  576. data/lib/puppet/pops/evaluator/deferred_resolver.rb +227 -0
  577. data/lib/puppet/pops/evaluator/epp_evaluator.rb +121 -0
  578. data/lib/puppet/pops/evaluator/evaluator_impl.rb +1317 -0
  579. data/lib/puppet/pops/evaluator/external_syntax_support.rb +47 -0
  580. data/lib/puppet/pops/evaluator/json_strict_literal_evaluator.rb +83 -0
  581. data/lib/puppet/pops/evaluator/literal_evaluator.rb +100 -0
  582. data/lib/puppet/pops/evaluator/puppet_proc.rb +72 -0
  583. data/lib/puppet/pops/evaluator/relationship_operator.rb +188 -0
  584. data/lib/puppet/pops/evaluator/runtime3_converter.rb +225 -0
  585. data/lib/puppet/pops/evaluator/runtime3_resource_support.rb +119 -0
  586. data/lib/puppet/pops/evaluator/runtime3_support.rb +528 -0
  587. data/lib/puppet/pops/functions/dispatch.rb +107 -0
  588. data/lib/puppet/pops/functions/dispatcher.rb +76 -0
  589. data/lib/puppet/pops/functions/function.rb +137 -0
  590. data/lib/puppet/pops/issue_reporter.rb +140 -0
  591. data/lib/puppet/pops/issues.rb +933 -0
  592. data/lib/puppet/pops/label_provider.rb +92 -0
  593. data/lib/puppet/pops/loader/base_loader.rb +178 -0
  594. data/lib/puppet/pops/loader/dependency_loader.rb +95 -0
  595. data/lib/puppet/pops/loader/gem_support.rb +54 -0
  596. data/lib/puppet/pops/loader/generic_plan_instantiator.rb +30 -0
  597. data/lib/puppet/pops/loader/loader.rb +221 -0
  598. data/lib/puppet/pops/loader/loader_paths.rb +413 -0
  599. data/lib/puppet/pops/loader/module_loaders.rb +552 -0
  600. data/lib/puppet/pops/loader/predefined_loader.rb +28 -0
  601. data/lib/puppet/pops/loader/puppet_function_instantiator.rb +88 -0
  602. data/lib/puppet/pops/loader/puppet_plan_instantiator.rb +97 -0
  603. data/lib/puppet/pops/loader/puppet_resource_type_impl_instantiator.rb +80 -0
  604. data/lib/puppet/pops/loader/ruby_data_type_instantiator.rb +43 -0
  605. data/lib/puppet/pops/loader/ruby_function_instantiator.rb +49 -0
  606. data/lib/puppet/pops/loader/ruby_legacy_function_instantiator.rb +130 -0
  607. data/lib/puppet/pops/loader/runtime3_type_loader.rb +104 -0
  608. data/lib/puppet/pops/loader/simple_environment_loader.rb +20 -0
  609. data/lib/puppet/pops/loader/static_loader.rb +133 -0
  610. data/lib/puppet/pops/loader/task_instantiator.rb +46 -0
  611. data/lib/puppet/pops/loader/type_definition_instantiator.rb +104 -0
  612. data/lib/puppet/pops/loader/typed_name.rb +56 -0
  613. data/lib/puppet/pops/loader/uri_helper.rb +24 -0
  614. data/lib/puppet/pops/loaders.rb +550 -0
  615. data/lib/puppet/pops/lookup/configured_data_provider.rb +95 -0
  616. data/lib/puppet/pops/lookup/context.rb +208 -0
  617. data/lib/puppet/pops/lookup/data_adapter.rb +29 -0
  618. data/lib/puppet/pops/lookup/data_dig_function_provider.rb +146 -0
  619. data/lib/puppet/pops/lookup/data_hash_function_provider.rb +128 -0
  620. data/lib/puppet/pops/lookup/data_provider.rb +94 -0
  621. data/lib/puppet/pops/lookup/environment_data_provider.rb +37 -0
  622. data/lib/puppet/pops/lookup/explainer.rb +597 -0
  623. data/lib/puppet/pops/lookup/function_provider.rb +112 -0
  624. data/lib/puppet/pops/lookup/global_data_provider.rb +76 -0
  625. data/lib/puppet/pops/lookup/hiera_config.rb +823 -0
  626. data/lib/puppet/pops/lookup/interpolation.rb +166 -0
  627. data/lib/puppet/pops/lookup/invocation.rb +272 -0
  628. data/lib/puppet/pops/lookup/key_recorder.rb +21 -0
  629. data/lib/puppet/pops/lookup/location_resolver.rb +101 -0
  630. data/lib/puppet/pops/lookup/lookup_adapter.rb +533 -0
  631. data/lib/puppet/pops/lookup/lookup_key.rb +101 -0
  632. data/lib/puppet/pops/lookup/lookup_key_function_provider.rb +94 -0
  633. data/lib/puppet/pops/lookup/module_data_provider.rb +92 -0
  634. data/lib/puppet/pops/lookup/sub_lookup.rb +96 -0
  635. data/lib/puppet/pops/lookup.rb +102 -0
  636. data/lib/puppet/pops/merge_strategy.rb +447 -0
  637. data/lib/puppet/pops/migration/migration_checker.rb +61 -0
  638. data/lib/puppet/pops/model/ast.pp +669 -0
  639. data/lib/puppet/pops/model/ast.rb +4776 -0
  640. data/lib/puppet/pops/model/ast_transformer.rb +131 -0
  641. data/lib/puppet/pops/model/factory.rb +1157 -0
  642. data/lib/puppet/pops/model/model_label_provider.rb +137 -0
  643. data/lib/puppet/pops/model/model_tree_dumper.rb +447 -0
  644. data/lib/puppet/pops/model/pn_transformer.rb +384 -0
  645. data/lib/puppet/pops/model/tree_dumper.rb +62 -0
  646. data/lib/puppet/pops/parser/code_merger.rb +29 -0
  647. data/lib/puppet/pops/parser/egrammar.ra +889 -0
  648. data/lib/puppet/pops/parser/eparser.rb +3184 -0
  649. data/lib/puppet/pops/parser/epp_parser.rb +52 -0
  650. data/lib/puppet/pops/parser/epp_support.rb +266 -0
  651. data/lib/puppet/pops/parser/evaluating_parser.rb +166 -0
  652. data/lib/puppet/pops/parser/heredoc_support.rb +153 -0
  653. data/lib/puppet/pops/parser/interpolation_support.rb +249 -0
  654. data/lib/puppet/pops/parser/lexer2.rb +789 -0
  655. data/lib/puppet/pops/parser/lexer_support.rb +221 -0
  656. data/lib/puppet/pops/parser/locatable.rb +23 -0
  657. data/lib/puppet/pops/parser/locator.rb +361 -0
  658. data/lib/puppet/pops/parser/parser_support.rb +252 -0
  659. data/lib/puppet/pops/parser/pn_parser.rb +318 -0
  660. data/lib/puppet/pops/parser/slurp_support.rb +119 -0
  661. data/lib/puppet/pops/patterns.rb +60 -0
  662. data/lib/puppet/pops/pcore.rb +136 -0
  663. data/lib/puppet/pops/pn.rb +239 -0
  664. data/lib/puppet/pops/puppet_stack.rb +63 -0
  665. data/lib/puppet/pops/resource/param.rb +56 -0
  666. data/lib/puppet/pops/resource/resource_type_impl.rb +296 -0
  667. data/lib/puppet/pops/resource/resource_type_set.pcore +22 -0
  668. data/lib/puppet/pops/semantic_error.rb +31 -0
  669. data/lib/puppet/pops/serialization/abstract_reader.rb +182 -0
  670. data/lib/puppet/pops/serialization/abstract_writer.rb +224 -0
  671. data/lib/puppet/pops/serialization/deserializer.rb +83 -0
  672. data/lib/puppet/pops/serialization/extension.rb +166 -0
  673. data/lib/puppet/pops/serialization/from_data_converter.rb +231 -0
  674. data/lib/puppet/pops/serialization/instance_reader.rb +21 -0
  675. data/lib/puppet/pops/serialization/instance_writer.rb +16 -0
  676. data/lib/puppet/pops/serialization/json.rb +301 -0
  677. data/lib/puppet/pops/serialization/json_path.rb +129 -0
  678. data/lib/puppet/pops/serialization/object.rb +73 -0
  679. data/lib/puppet/pops/serialization/serializer.rb +144 -0
  680. data/lib/puppet/pops/serialization/time_factory.rb +68 -0
  681. data/lib/puppet/pops/serialization/to_data_converter.rb +316 -0
  682. data/lib/puppet/pops/serialization/to_stringified_converter.rb +227 -0
  683. data/lib/puppet/pops/serialization.rb +45 -0
  684. data/lib/puppet/pops/time/timespan.rb +728 -0
  685. data/lib/puppet/pops/time/timestamp.rb +167 -0
  686. data/lib/puppet/pops/types/annotatable.rb +37 -0
  687. data/lib/puppet/pops/types/annotation.rb +73 -0
  688. data/lib/puppet/pops/types/class_loader.rb +134 -0
  689. data/lib/puppet/pops/types/implementation_registry.rb +137 -0
  690. data/lib/puppet/pops/types/iterable.rb +375 -0
  691. data/lib/puppet/pops/types/p_binary_type.rb +232 -0
  692. data/lib/puppet/pops/types/p_init_type.rb +241 -0
  693. data/lib/puppet/pops/types/p_meta_type.rb +95 -0
  694. data/lib/puppet/pops/types/p_object_type.rb +1142 -0
  695. data/lib/puppet/pops/types/p_object_type_extension.rb +229 -0
  696. data/lib/puppet/pops/types/p_runtime_type.rb +117 -0
  697. data/lib/puppet/pops/types/p_sem_ver_range_type.rb +191 -0
  698. data/lib/puppet/pops/types/p_sem_ver_type.rb +155 -0
  699. data/lib/puppet/pops/types/p_sensitive_type.rb +81 -0
  700. data/lib/puppet/pops/types/p_timespan_type.rb +194 -0
  701. data/lib/puppet/pops/types/p_timestamp_type.rb +74 -0
  702. data/lib/puppet/pops/types/p_type_set_type.rb +394 -0
  703. data/lib/puppet/pops/types/p_uri_type.rb +198 -0
  704. data/lib/puppet/pops/types/puppet_object.rb +41 -0
  705. data/lib/puppet/pops/types/recursion_guard.rb +142 -0
  706. data/lib/puppet/pops/types/ruby_generator.rb +477 -0
  707. data/lib/puppet/pops/types/ruby_method.rb +32 -0
  708. data/lib/puppet/pops/types/string_converter.rb +1144 -0
  709. data/lib/puppet/pops/types/tree_iterators.rb +250 -0
  710. data/lib/puppet/pops/types/type_acceptor.rb +27 -0
  711. data/lib/puppet/pops/types/type_asserter.rb +49 -0
  712. data/lib/puppet/pops/types/type_assertion_error.rb +27 -0
  713. data/lib/puppet/pops/types/type_calculator.rb +829 -0
  714. data/lib/puppet/pops/types/type_conversion_error.rb +7 -0
  715. data/lib/puppet/pops/types/type_factory.rb +640 -0
  716. data/lib/puppet/pops/types/type_formatter.rb +796 -0
  717. data/lib/puppet/pops/types/type_mismatch_describer.rb +1105 -0
  718. data/lib/puppet/pops/types/type_parser.rb +690 -0
  719. data/lib/puppet/pops/types/type_set_reference.rb +62 -0
  720. data/lib/puppet/pops/types/type_with_members.rb +43 -0
  721. data/lib/puppet/pops/types/types.rb +3651 -0
  722. data/lib/puppet/pops/utils.rb +117 -0
  723. data/lib/puppet/pops/validation/checker4_0.rb +1155 -0
  724. data/lib/puppet/pops/validation/tasks_checker.rb +95 -0
  725. data/lib/puppet/pops/validation/validator_factory_4_0.rb +45 -0
  726. data/lib/puppet/pops/validation.rb +462 -0
  727. data/lib/puppet/pops/visitable.rb +8 -0
  728. data/lib/puppet/pops/visitor.rb +136 -0
  729. data/lib/puppet/pops.rb +124 -0
  730. data/lib/puppet/property/boolean.rb +9 -0
  731. data/lib/puppet/property/ensure.rb +107 -0
  732. data/lib/puppet/property/keyvalue.rb +159 -0
  733. data/lib/puppet/property/list.rb +71 -0
  734. data/lib/puppet/property/ordered_list.rb +30 -0
  735. data/lib/puppet/property.rb +610 -0
  736. data/lib/puppet/provider/aix_object.rb +491 -0
  737. data/lib/puppet/provider/command.rb +27 -0
  738. data/lib/puppet/provider/confine.rb +8 -0
  739. data/lib/puppet/provider/exec/posix.rb +63 -0
  740. data/lib/puppet/provider/exec/shell.rb +27 -0
  741. data/lib/puppet/provider/exec/windows.rb +57 -0
  742. data/lib/puppet/provider/exec.rb +107 -0
  743. data/lib/puppet/provider/file/posix.rb +162 -0
  744. data/lib/puppet/provider/file/windows.rb +151 -0
  745. data/lib/puppet/provider/group/aix.rb +101 -0
  746. data/lib/puppet/provider/group/directoryservice.rb +24 -0
  747. data/lib/puppet/provider/group/groupadd.rb +180 -0
  748. data/lib/puppet/provider/group/ldap.rb +51 -0
  749. data/lib/puppet/provider/group/pw.rb +52 -0
  750. data/lib/puppet/provider/group/windows_adsi.rb +116 -0
  751. data/lib/puppet/provider/ldap.rb +143 -0
  752. data/lib/puppet/provider/nameservice/directoryservice.rb +522 -0
  753. data/lib/puppet/provider/nameservice/objectadd.rb +22 -0
  754. data/lib/puppet/provider/nameservice/pw.rb +21 -0
  755. data/lib/puppet/provider/nameservice.rb +297 -0
  756. data/lib/puppet/provider/network_device.rb +74 -0
  757. data/lib/puppet/provider/package/aix.rb +171 -0
  758. data/lib/puppet/provider/package/appdmg.rb +113 -0
  759. data/lib/puppet/provider/package/apple.rb +49 -0
  760. data/lib/puppet/provider/package/apt.rb +265 -0
  761. data/lib/puppet/provider/package/aptitude.rb +35 -0
  762. data/lib/puppet/provider/package/aptrpm.rb +87 -0
  763. data/lib/puppet/provider/package/blastwave.rb +109 -0
  764. data/lib/puppet/provider/package/dnf.rb +57 -0
  765. data/lib/puppet/provider/package/dnfmodule.rb +143 -0
  766. data/lib/puppet/provider/package/dpkg.rb +191 -0
  767. data/lib/puppet/provider/package/fink.rb +99 -0
  768. data/lib/puppet/provider/package/freebsd.rb +49 -0
  769. data/lib/puppet/provider/package/gem.rb +296 -0
  770. data/lib/puppet/provider/package/hpux.rb +46 -0
  771. data/lib/puppet/provider/package/macports.rb +112 -0
  772. data/lib/puppet/provider/package/nim.rb +290 -0
  773. data/lib/puppet/provider/package/openbsd.rb +263 -0
  774. data/lib/puppet/provider/package/opkg.rb +85 -0
  775. data/lib/puppet/provider/package/pacman.rb +270 -0
  776. data/lib/puppet/provider/package/pip.rb +347 -0
  777. data/lib/puppet/provider/package/pip2.rb +18 -0
  778. data/lib/puppet/provider/package/pip3.rb +18 -0
  779. data/lib/puppet/provider/package/pkg.rb +300 -0
  780. data/lib/puppet/provider/package/pkgdmg.rb +159 -0
  781. data/lib/puppet/provider/package/pkgin.rb +88 -0
  782. data/lib/puppet/provider/package/pkgng.rb +178 -0
  783. data/lib/puppet/provider/package/pkgutil.rb +186 -0
  784. data/lib/puppet/provider/package/portage.rb +314 -0
  785. data/lib/puppet/provider/package/ports.rb +94 -0
  786. data/lib/puppet/provider/package/portupgrade.rb +233 -0
  787. data/lib/puppet/provider/package/puppet_gem.rb +25 -0
  788. data/lib/puppet/provider/package/puppetserver_gem.rb +174 -0
  789. data/lib/puppet/provider/package/rpm.rb +255 -0
  790. data/lib/puppet/provider/package/rug.rb +51 -0
  791. data/lib/puppet/provider/package/sun.rb +137 -0
  792. data/lib/puppet/provider/package/sunfreeware.rb +11 -0
  793. data/lib/puppet/provider/package/tdnf.rb +35 -0
  794. data/lib/puppet/provider/package/up2date.rb +40 -0
  795. data/lib/puppet/provider/package/urpmi.rb +57 -0
  796. data/lib/puppet/provider/package/windows/exe_package.rb +108 -0
  797. data/lib/puppet/provider/package/windows/msi_package.rb +72 -0
  798. data/lib/puppet/provider/package/windows/package.rb +113 -0
  799. data/lib/puppet/provider/package/windows.rb +131 -0
  800. data/lib/puppet/provider/package/xbps.rb +127 -0
  801. data/lib/puppet/provider/package/yum.rb +390 -0
  802. data/lib/puppet/provider/package/zypper.rb +206 -0
  803. data/lib/puppet/provider/package.rb +61 -0
  804. data/lib/puppet/provider/package_targetable.rb +71 -0
  805. data/lib/puppet/provider/parsedfile.rb +494 -0
  806. data/lib/puppet/provider/service/base.rb +135 -0
  807. data/lib/puppet/provider/service/bsd.rb +53 -0
  808. data/lib/puppet/provider/service/daemontools.rb +196 -0
  809. data/lib/puppet/provider/service/debian.rb +77 -0
  810. data/lib/puppet/provider/service/freebsd.rb +141 -0
  811. data/lib/puppet/provider/service/gentoo.rb +47 -0
  812. data/lib/puppet/provider/service/init.rb +194 -0
  813. data/lib/puppet/provider/service/launchd.rb +391 -0
  814. data/lib/puppet/provider/service/openbsd.rb +101 -0
  815. data/lib/puppet/provider/service/openrc.rb +72 -0
  816. data/lib/puppet/provider/service/openwrt.rb +37 -0
  817. data/lib/puppet/provider/service/rcng.rb +53 -0
  818. data/lib/puppet/provider/service/redhat.rb +75 -0
  819. data/lib/puppet/provider/service/runit.rb +107 -0
  820. data/lib/puppet/provider/service/service.rb +67 -0
  821. data/lib/puppet/provider/service/smf.rb +322 -0
  822. data/lib/puppet/provider/service/src.rb +147 -0
  823. data/lib/puppet/provider/service/systemd.rb +232 -0
  824. data/lib/puppet/provider/service/upstart.rb +385 -0
  825. data/lib/puppet/provider/service/windows.rb +179 -0
  826. data/lib/puppet/provider/user/aix.rb +365 -0
  827. data/lib/puppet/provider/user/directoryservice.rb +687 -0
  828. data/lib/puppet/provider/user/hpux.rb +93 -0
  829. data/lib/puppet/provider/user/ldap.rb +135 -0
  830. data/lib/puppet/provider/user/openbsd.rb +79 -0
  831. data/lib/puppet/provider/user/pw.rb +109 -0
  832. data/lib/puppet/provider/user/user_role_add.rb +243 -0
  833. data/lib/puppet/provider/user/useradd.rb +417 -0
  834. data/lib/puppet/provider/user/windows_adsi.rb +176 -0
  835. data/lib/puppet/provider.rb +613 -0
  836. data/lib/puppet/reference/configuration.rb +105 -0
  837. data/lib/puppet/reference/function.rb +19 -0
  838. data/lib/puppet/reference/indirection.rb +76 -0
  839. data/lib/puppet/reference/metaparameter.rb +35 -0
  840. data/lib/puppet/reference/providers.rb +119 -0
  841. data/lib/puppet/reference/report.rb +22 -0
  842. data/lib/puppet/reference/type.rb +111 -0
  843. data/lib/puppet/relationship.rb +85 -0
  844. data/lib/puppet/reports/http.rb +45 -0
  845. data/lib/puppet/reports/log.rb +15 -0
  846. data/lib/puppet/reports/store.rb +71 -0
  847. data/lib/puppet/reports.rb +95 -0
  848. data/lib/puppet/resource/catalog.rb +655 -0
  849. data/lib/puppet/resource/status.rb +231 -0
  850. data/lib/puppet/resource/type.rb +449 -0
  851. data/lib/puppet/resource/type_collection.rb +235 -0
  852. data/lib/puppet/resource.rb +673 -0
  853. data/lib/puppet/runtime.rb +67 -0
  854. data/lib/puppet/scheduler/job.rb +55 -0
  855. data/lib/puppet/scheduler/scheduler.rb +46 -0
  856. data/lib/puppet/scheduler/splay_job.rb +45 -0
  857. data/lib/puppet/scheduler/timer.rb +15 -0
  858. data/lib/puppet/scheduler.rb +18 -0
  859. data/lib/puppet/settings/alias_setting.rb +37 -0
  860. data/lib/puppet/settings/array_setting.rb +18 -0
  861. data/lib/puppet/settings/autosign_setting.rb +23 -0
  862. data/lib/puppet/settings/base_setting.rb +228 -0
  863. data/lib/puppet/settings/boolean_setting.rb +34 -0
  864. data/lib/puppet/settings/certificate_revocation_setting.rb +22 -0
  865. data/lib/puppet/settings/config_file.rb +148 -0
  866. data/lib/puppet/settings/directory_setting.rb +20 -0
  867. data/lib/puppet/settings/duration_setting.rb +33 -0
  868. data/lib/puppet/settings/enum_setting.rb +18 -0
  869. data/lib/puppet/settings/environment_conf.rb +228 -0
  870. data/lib/puppet/settings/errors.rb +14 -0
  871. data/lib/puppet/settings/file_or_directory_setting.rb +37 -0
  872. data/lib/puppet/settings/file_setting.rb +232 -0
  873. data/lib/puppet/settings/http_extra_headers_setting.rb +26 -0
  874. data/lib/puppet/settings/ini_file.rb +228 -0
  875. data/lib/puppet/settings/integer_setting.rb +19 -0
  876. data/lib/puppet/settings/path_setting.rb +10 -0
  877. data/lib/puppet/settings/port_setting.rb +17 -0
  878. data/lib/puppet/settings/priority_setting.rb +44 -0
  879. data/lib/puppet/settings/server_list_setting.rb +30 -0
  880. data/lib/puppet/settings/string_setting.rb +11 -0
  881. data/lib/puppet/settings/symbolic_enum_setting.rb +19 -0
  882. data/lib/puppet/settings/terminus_setting.rb +16 -0
  883. data/lib/puppet/settings/ttl_setting.rb +53 -0
  884. data/lib/puppet/settings/value_translator.rb +16 -0
  885. data/lib/puppet/settings.rb +1650 -0
  886. data/lib/puppet/ssl/base.rb +152 -0
  887. data/lib/puppet/ssl/certificate.rb +98 -0
  888. data/lib/puppet/ssl/certificate_request.rb +320 -0
  889. data/lib/puppet/ssl/certificate_request_attributes.rb +40 -0
  890. data/lib/puppet/ssl/certificate_signer.rb +39 -0
  891. data/lib/puppet/ssl/digest.rb +22 -0
  892. data/lib/puppet/ssl/error.rb +29 -0
  893. data/lib/puppet/ssl/oids.rb +199 -0
  894. data/lib/puppet/ssl/openssl_loader.rb +26 -0
  895. data/lib/puppet/ssl/ssl_context.rb +27 -0
  896. data/lib/puppet/ssl/ssl_provider.rb +354 -0
  897. data/lib/puppet/ssl/state_machine.rb +605 -0
  898. data/lib/puppet/ssl/verifier.rb +143 -0
  899. data/lib/puppet/ssl.rb +25 -0
  900. data/lib/puppet/syntax_checkers/base64.rb +42 -0
  901. data/lib/puppet/syntax_checkers/epp.rb +35 -0
  902. data/lib/puppet/syntax_checkers/json.rb +35 -0
  903. data/lib/puppet/syntax_checkers/pp.rb +35 -0
  904. data/lib/puppet/syntax_checkers.rb +5 -0
  905. data/lib/puppet/test/test_helper.rb +251 -0
  906. data/lib/puppet/thread_local.rb +6 -0
  907. data/lib/puppet/transaction/additional_resource_generator.rb +225 -0
  908. data/lib/puppet/transaction/event.rb +171 -0
  909. data/lib/puppet/transaction/event_manager.rb +180 -0
  910. data/lib/puppet/transaction/persistence.rb +119 -0
  911. data/lib/puppet/transaction/report.rb +511 -0
  912. data/lib/puppet/transaction/resource_harness.rb +331 -0
  913. data/lib/puppet/transaction.rb +493 -0
  914. data/lib/puppet/trusted_external.rb +46 -0
  915. data/lib/puppet/type/component.rb +96 -0
  916. data/lib/puppet/type/exec.rb +730 -0
  917. data/lib/puppet/type/file/checksum.rb +54 -0
  918. data/lib/puppet/type/file/checksum_value.rb +56 -0
  919. data/lib/puppet/type/file/content.rb +180 -0
  920. data/lib/puppet/type/file/ctime.rb +22 -0
  921. data/lib/puppet/type/file/data_sync.rb +101 -0
  922. data/lib/puppet/type/file/ensure.rb +194 -0
  923. data/lib/puppet/type/file/group.rb +50 -0
  924. data/lib/puppet/type/file/mode.rb +192 -0
  925. data/lib/puppet/type/file/mtime.rb +21 -0
  926. data/lib/puppet/type/file/owner.rb +52 -0
  927. data/lib/puppet/type/file/selcontext.rb +143 -0
  928. data/lib/puppet/type/file/source.rb +380 -0
  929. data/lib/puppet/type/file/target.rb +86 -0
  930. data/lib/puppet/type/file/type.rb +21 -0
  931. data/lib/puppet/type/file.rb +1139 -0
  932. data/lib/puppet/type/filebucket.rb +123 -0
  933. data/lib/puppet/type/group.rb +238 -0
  934. data/lib/puppet/type/notify.rb +48 -0
  935. data/lib/puppet/type/package.rb +715 -0
  936. data/lib/puppet/type/resources.rb +192 -0
  937. data/lib/puppet/type/schedule.rb +441 -0
  938. data/lib/puppet/type/service.rb +310 -0
  939. data/lib/puppet/type/stage.rb +29 -0
  940. data/lib/puppet/type/tidy.rb +382 -0
  941. data/lib/puppet/type/user.rb +865 -0
  942. data/lib/puppet/type/whit.rb +35 -0
  943. data/lib/puppet/type.rb +2629 -0
  944. data/lib/puppet/util/at_fork/noop.rb +20 -0
  945. data/lib/puppet/util/at_fork/solaris.rb +158 -0
  946. data/lib/puppet/util/at_fork.rb +37 -0
  947. data/lib/puppet/util/autoload.rb +221 -0
  948. data/lib/puppet/util/backups.rb +88 -0
  949. data/lib/puppet/util/character_encoding.rb +83 -0
  950. data/lib/puppet/util/checksums.rb +380 -0
  951. data/lib/puppet/util/classgen.rb +223 -0
  952. data/lib/puppet/util/colors.rb +102 -0
  953. data/lib/puppet/util/command_line/puppet_option_parser.rb +89 -0
  954. data/lib/puppet/util/command_line/trollop.rb +847 -0
  955. data/lib/puppet/util/command_line.rb +198 -0
  956. data/lib/puppet/util/constant_inflector.rb +25 -0
  957. data/lib/puppet/util/diff.rb +80 -0
  958. data/lib/puppet/util/docs.rb +132 -0
  959. data/lib/puppet/util/errors.rb +161 -0
  960. data/lib/puppet/util/execution.rb +446 -0
  961. data/lib/puppet/util/execution_stub.rb +28 -0
  962. data/lib/puppet/util/feature.rb +129 -0
  963. data/lib/puppet/util/file_watcher.rb +31 -0
  964. data/lib/puppet/util/fileparsing.rb +404 -0
  965. data/lib/puppet/util/filetype.rb +358 -0
  966. data/lib/puppet/util/http_proxy.rb +6 -0
  967. data/lib/puppet/util/inifile.rb +335 -0
  968. data/lib/puppet/util/instance_loader.rb +69 -0
  969. data/lib/puppet/util/json.rb +94 -0
  970. data/lib/puppet/util/json_lockfile.rb +47 -0
  971. data/lib/puppet/util/ldap/connection.rb +75 -0
  972. data/lib/puppet/util/ldap/generator.rb +44 -0
  973. data/lib/puppet/util/ldap/manager.rb +283 -0
  974. data/lib/puppet/util/ldap.rb +4 -0
  975. data/lib/puppet/util/libuser.conf +15 -0
  976. data/lib/puppet/util/libuser.rb +13 -0
  977. data/lib/puppet/util/limits.rb +14 -0
  978. data/lib/puppet/util/lockfile.rb +66 -0
  979. data/lib/puppet/util/log/destination.rb +50 -0
  980. data/lib/puppet/util/log/destinations.rb +253 -0
  981. data/lib/puppet/util/log.rb +436 -0
  982. data/lib/puppet/util/logging.rb +304 -0
  983. data/lib/puppet/util/metaid.rb +22 -0
  984. data/lib/puppet/util/metric.rb +68 -0
  985. data/lib/puppet/util/monkey_patches.rb +114 -0
  986. data/lib/puppet/util/multi_match.rb +55 -0
  987. data/lib/puppet/util/network_device/base.rb +24 -0
  988. data/lib/puppet/util/network_device/config.rb +105 -0
  989. data/lib/puppet/util/network_device/transport/base.rb +26 -0
  990. data/lib/puppet/util/network_device/transport.rb +7 -0
  991. data/lib/puppet/util/network_device.rb +19 -0
  992. data/lib/puppet/util/package/version/debian.rb +177 -0
  993. data/lib/puppet/util/package/version/gem.rb +18 -0
  994. data/lib/puppet/util/package/version/pip.rb +173 -0
  995. data/lib/puppet/util/package/version/range/eq.rb +17 -0
  996. data/lib/puppet/util/package/version/range/gt.rb +17 -0
  997. data/lib/puppet/util/package/version/range/gt_eq.rb +17 -0
  998. data/lib/puppet/util/package/version/range/lt.rb +17 -0
  999. data/lib/puppet/util/package/version/range/lt_eq.rb +17 -0
  1000. data/lib/puppet/util/package/version/range/min_max.rb +26 -0
  1001. data/lib/puppet/util/package/version/range/simple.rb +13 -0
  1002. data/lib/puppet/util/package/version/range.rb +57 -0
  1003. data/lib/puppet/util/package/version/rpm.rb +75 -0
  1004. data/lib/puppet/util/package.rb +43 -0
  1005. data/lib/puppet/util/pidlock.rb +103 -0
  1006. data/lib/puppet/util/platform.rb +72 -0
  1007. data/lib/puppet/util/plist.rb +161 -0
  1008. data/lib/puppet/util/posix.rb +206 -0
  1009. data/lib/puppet/util/profiler/aggregate.rb +82 -0
  1010. data/lib/puppet/util/profiler/around_profiler.rb +68 -0
  1011. data/lib/puppet/util/profiler/logging.rb +50 -0
  1012. data/lib/puppet/util/profiler/object_counts.rb +19 -0
  1013. data/lib/puppet/util/profiler/wall_clock.rb +36 -0
  1014. data/lib/puppet/util/profiler.rb +55 -0
  1015. data/lib/puppet/util/provider_features.rb +183 -0
  1016. data/lib/puppet/util/psych_support.rb +32 -0
  1017. data/lib/puppet/util/rdoc/code_objects.rb +293 -0
  1018. data/lib/puppet/util/rdoc/generators/puppet_generator.rb +902 -0
  1019. data/lib/puppet/util/rdoc/generators/template/puppet/puppet.rb +1068 -0
  1020. data/lib/puppet/util/rdoc/parser/puppet_parser_core.rb +262 -0
  1021. data/lib/puppet/util/rdoc/parser/puppet_parser_rdoc2.rb +16 -0
  1022. data/lib/puppet/util/rdoc/parser.rb +14 -0
  1023. data/lib/puppet/util/rdoc.rb +54 -0
  1024. data/lib/puppet/util/reference.rb +94 -0
  1025. data/lib/puppet/util/resource_template.rb +63 -0
  1026. data/lib/puppet/util/retry_action.rb +47 -0
  1027. data/lib/puppet/util/rpm_compare.rb +196 -0
  1028. data/lib/puppet/util/rubygems.rb +67 -0
  1029. data/lib/puppet/util/run_mode.rb +164 -0
  1030. data/lib/puppet/util/selinux.rb +331 -0
  1031. data/lib/puppet/util/skip_tags.rb +15 -0
  1032. data/lib/puppet/util/splayer.rb +20 -0
  1033. data/lib/puppet/util/storage.rb +100 -0
  1034. data/lib/puppet/util/suidmanager.rb +167 -0
  1035. data/lib/puppet/util/symbolic_file_mode.rb +156 -0
  1036. data/lib/puppet/util/tag_set.rb +29 -0
  1037. data/lib/puppet/util/tagging.rb +131 -0
  1038. data/lib/puppet/util/terminal.rb +18 -0
  1039. data/lib/puppet/util/user_attr.rb +23 -0
  1040. data/lib/puppet/util/warnings.rb +35 -0
  1041. data/lib/puppet/util/watched_file.rb +40 -0
  1042. data/lib/puppet/util/watcher/change_watcher.rb +35 -0
  1043. data/lib/puppet/util/watcher/periodic_watcher.rb +38 -0
  1044. data/lib/puppet/util/watcher/timer.rb +21 -0
  1045. data/lib/puppet/util/watcher.rb +17 -0
  1046. data/lib/puppet/util/windows/access_control_entry.rb +86 -0
  1047. data/lib/puppet/util/windows/access_control_list.rb +116 -0
  1048. data/lib/puppet/util/windows/adsi.rb +662 -0
  1049. data/lib/puppet/util/windows/com.rb +228 -0
  1050. data/lib/puppet/util/windows/daemon.rb +340 -0
  1051. data/lib/puppet/util/windows/error.rb +86 -0
  1052. data/lib/puppet/util/windows/eventlog.rb +191 -0
  1053. data/lib/puppet/util/windows/file.rb +359 -0
  1054. data/lib/puppet/util/windows/monkey_patches/process.rb +413 -0
  1055. data/lib/puppet/util/windows/principal.rb +204 -0
  1056. data/lib/puppet/util/windows/process.rb +360 -0
  1057. data/lib/puppet/util/windows/registry.rb +443 -0
  1058. data/lib/puppet/util/windows/root_certs.rb +110 -0
  1059. data/lib/puppet/util/windows/security.rb +909 -0
  1060. data/lib/puppet/util/windows/security_descriptor.rb +64 -0
  1061. data/lib/puppet/util/windows/service.rb +708 -0
  1062. data/lib/puppet/util/windows/sid.rb +291 -0
  1063. data/lib/puppet/util/windows/string.rb +17 -0
  1064. data/lib/puppet/util/windows/user.rb +551 -0
  1065. data/lib/puppet/util/windows.rb +58 -0
  1066. data/lib/puppet/util/yaml.rb +67 -0
  1067. data/lib/puppet/util.rb +759 -0
  1068. data/lib/puppet/vendor/require_vendored.rb +4 -0
  1069. data/lib/puppet/vendor.rb +59 -0
  1070. data/lib/puppet/version.rb +98 -0
  1071. data/lib/puppet/x509/cert_provider.rb +405 -0
  1072. data/lib/puppet/x509/pem_store.rb +57 -0
  1073. data/lib/puppet/x509.rb +13 -0
  1074. data/lib/puppet.rb +348 -0
  1075. data/lib/puppet_pal.rb +10 -0
  1076. data/lib/puppet_x.rb +16 -0
  1077. data/locales/config.yaml +29 -0
  1078. data/locales/en/puppet.po +19 -0
  1079. data/locales/puppet.pot +9738 -0
  1080. data/man/man5/puppet.conf.5 +1407 -0
  1081. data/man/man8/puppet-agent.8 +135 -0
  1082. data/man/man8/puppet-apply.8 +67 -0
  1083. data/man/man8/puppet-catalog.8 +194 -0
  1084. data/man/man8/puppet-config.8 +103 -0
  1085. data/man/man8/puppet-describe.8 +35 -0
  1086. data/man/man8/puppet-device.8 +83 -0
  1087. data/man/man8/puppet-doc.8 +30 -0
  1088. data/man/man8/puppet-epp.8 +232 -0
  1089. data/man/man8/puppet-facts.8 +156 -0
  1090. data/man/man8/puppet-filebucket.8 +134 -0
  1091. data/man/man8/puppet-generate.8 +54 -0
  1092. data/man/man8/puppet-help.8 +46 -0
  1093. data/man/man8/puppet-lookup.8 +71 -0
  1094. data/man/man8/puppet-module.8 +220 -0
  1095. data/man/man8/puppet-node.8 +142 -0
  1096. data/man/man8/puppet-parser.8 +87 -0
  1097. data/man/man8/puppet-plugin.8 +50 -0
  1098. data/man/man8/puppet-report.8 +84 -0
  1099. data/man/man8/puppet-resource.8 +63 -0
  1100. data/man/man8/puppet-script.8 +48 -0
  1101. data/man/man8/puppet-ssl.8 +45 -0
  1102. data/man/man8/puppet.8 +98 -0
  1103. data/tasks/tag.rake +34 -0
  1104. metadata +1336 -0
@@ -0,0 +1,3651 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'iterable'
4
+ require_relative 'recursion_guard'
5
+ require_relative 'type_acceptor'
6
+ require_relative 'type_asserter'
7
+ require_relative 'type_assertion_error'
8
+ require_relative 'type_conversion_error'
9
+ require_relative 'type_formatter'
10
+ require_relative 'type_calculator'
11
+ require_relative 'type_factory'
12
+ require_relative 'type_parser'
13
+ require_relative 'class_loader'
14
+ require_relative 'type_mismatch_describer'
15
+ require_relative 'puppet_object'
16
+
17
+ module Puppet::Pops
18
+ module Types
19
+ # The EMPTY_xxx declarations is for backward compatibility. They should not be explicitly referenced
20
+
21
+ # @api private
22
+ # @deprecated
23
+ EMPTY_HASH = Puppet::Pops::EMPTY_HASH
24
+
25
+ # @api private
26
+ # @deprecated
27
+ EMPTY_ARRAY = Puppet::Pops::EMPTY_ARRAY
28
+
29
+ # @api private
30
+ # @deprecated
31
+ EMPTY_STRING = Puppet::Pops::EMPTY_STRING
32
+
33
+ # The Types model is a model of Puppet Language types.
34
+ #
35
+ # The {TypeCalculator} should be used to answer questions about types. The {TypeFactory} or {TypeParser} should be used
36
+ # to create an instance of a type whenever one is needed.
37
+ #
38
+ # The implementation of the Types model contains methods that are required for the type objects to behave as
39
+ # expected when comparing them and using them as keys in hashes. (No other logic is, or should be included directly in
40
+ # the model's classes).
41
+ #
42
+ # @api public
43
+ #
44
+ class TypedModelObject < Object
45
+ include PuppetObject
46
+ include Visitable
47
+ include Adaptable
48
+
49
+ def self._pcore_type
50
+ @type
51
+ end
52
+
53
+ def self.create_ptype(loader, ir, parent_name, attributes_hash = EMPTY_HASH)
54
+ @type = Pcore.create_object_type(loader, ir, self, "Pcore::#{simple_name}Type", "Pcore::#{parent_name}", attributes_hash)
55
+ end
56
+
57
+ def self.register_ptypes(loader, ir)
58
+ types = [
59
+ Annotation.register_ptype(loader, ir),
60
+ RubyMethod.register_ptype(loader, ir)
61
+ ]
62
+ Types.constants.each do |c|
63
+ next if c == :PType || c == :PHostClassType
64
+
65
+ cls = Types.const_get(c)
66
+ next unless cls.is_a?(Class) && cls < self
67
+
68
+ type = cls.register_ptype(loader, ir)
69
+ types << type unless type.nil?
70
+ end
71
+ types.each { |type| type.resolve(loader) }
72
+ end
73
+ end
74
+
75
+ # Base type for all types
76
+ # @api public
77
+ #
78
+ class PAnyType < TypedModelObject
79
+ def self.register_ptype(loader, ir)
80
+ @type = Pcore.create_object_type(loader, ir, self, 'Pcore::AnyType', 'Any', EMPTY_HASH)
81
+ end
82
+
83
+ def self.create(*args)
84
+ # NOTE! Important to use self::DEFAULT and not just DEFAULT since the latter yields PAnyType::DEFAULT
85
+ args.empty? ? self::DEFAULT : new(*args)
86
+ end
87
+
88
+ # Accept a visitor that will be sent the message `visit`, once with `self` as the
89
+ # argument. The visitor will then visit all types that this type contains.
90
+ #
91
+ def accept(visitor, guard)
92
+ visitor.visit(self, guard)
93
+ end
94
+
95
+ # Checks if _o_ is a type that is assignable to this type.
96
+ # If _o_ is a `Class` then it is first converted to a type.
97
+ # If _o_ is a Variant, then it is considered assignable when all its types are assignable
98
+ #
99
+ # The check for assignable must be guarded against self recursion since `self`, the given type _o_,
100
+ # or both, might be a `TypeAlias`. The initial caller of this method will typically never care
101
+ # about this and hence pass only the first argument, but as soon as a check of a contained type
102
+ # encounters a `TypeAlias`, then a `RecursionGuard` instance is created and passed on in all
103
+ # subsequent calls. The recursion is allowed to continue until self recursion has been detected in
104
+ # both `self` and in the given type. At that point the given type is considered to be assignable
105
+ # to `self` since all checks up to that point were positive.
106
+ #
107
+ # @param o [Class,PAnyType] the class or type to test
108
+ # @param guard [RecursionGuard] guard against recursion. Only used by internal calls
109
+ # @return [Boolean] `true` when _o_ is assignable to this type
110
+ # @api public
111
+ def assignable?(o, guard = nil)
112
+ case o
113
+ when Class
114
+ # Safe to call _assignable directly since a Class never is a Unit or Variant
115
+ _assignable?(TypeCalculator.singleton.type(o), guard)
116
+ when PUnitType
117
+ true
118
+ when PTypeAliasType
119
+ # An alias may contain self recursive constructs.
120
+ if o.self_recursion?
121
+ guard ||= RecursionGuard.new
122
+ if guard.add_that(o) == RecursionGuard::SELF_RECURSION_IN_BOTH
123
+ # Recursion detected both in self and other. This means that other is assignable
124
+ # to self. This point would not have been reached otherwise
125
+ true
126
+ else
127
+ assignable?(o.resolved_type, guard)
128
+ end
129
+ else
130
+ assignable?(o.resolved_type, guard)
131
+ end
132
+ when PVariantType
133
+ # Assignable if all contained types are assignable, or if this is exactly Any
134
+ return true if instance_of?(PAnyType)
135
+ # An empty variant may be assignable to NotUndef[T] if T is assignable to empty variant
136
+ return _assignable?(o, guard) if is_a?(PNotUndefType) && o.types.empty?
137
+
138
+ !o.types.empty? && o.types.all? { |vt| assignable?(vt, guard) }
139
+ when POptionalType
140
+ # Assignable if undef and contained type is assignable
141
+ assignable?(PUndefType::DEFAULT) && (o.type.nil? || assignable?(o.type))
142
+ when PNotUndefType
143
+ if !(o.type.nil? || o.type.assignable?(PUndefType::DEFAULT))
144
+ assignable?(o.type, guard)
145
+ else
146
+ _assignable?(o, guard)
147
+ end
148
+ else
149
+ _assignable?(o, guard)
150
+ end
151
+ end
152
+
153
+ # Returns `true` if this instance is a callable that accepts the given _args_type_ type
154
+ #
155
+ # @param args_type [PAnyType] the arguments to test
156
+ # @param guard [RecursionGuard] guard against recursion. Only used by internal calls
157
+ # @return [Boolean] `true` if this instance is a callable that accepts the given _args_
158
+ def callable?(args_type, guard = nil)
159
+ args_type.is_a?(PAnyType) && kind_of_callable? && args_type.callable_args?(self, guard)
160
+ end
161
+
162
+ # Returns `true` if this instance is a callable that accepts the given _args_
163
+ #
164
+ # @param args [Array] the arguments to test
165
+ # @param block [Proc] block, or nil if not called with a block
166
+ # @return [Boolean] `true` if this instance is a callable that accepts the given _args_
167
+ def callable_with?(args, block = nil)
168
+ false
169
+ end
170
+
171
+ # Returns `true` if this instance is considered valid as arguments to the given `callable`
172
+ # @param callable [PAnyType] the callable
173
+ # @param guard [RecursionGuard] guard against recursion. Only used by internal calls
174
+ # @return [Boolean] `true` if this instance is considered valid as arguments to the given `callable`
175
+ # @api private
176
+ def callable_args?(callable, guard)
177
+ false
178
+ end
179
+
180
+ # Called from the `PTypeAliasType` when it detects self recursion. The default is to do nothing
181
+ # but some self recursive constructs are illegal such as when a `PObjectType` somehow inherits itself
182
+ # @param originator [PTypeAliasType] the starting point for the check
183
+ # @raise Puppet::Error if an illegal self recursion is detected
184
+ # @api private
185
+ def check_self_recursion(originator)
186
+ end
187
+
188
+ # Generalizes value specific types. Types that are not value specific will return `self` otherwise
189
+ # the generalized type is returned.
190
+ #
191
+ # @return [PAnyType] The generalized type
192
+ # @api public
193
+ def generalize
194
+ # Applicable to all types that have no variables
195
+ self
196
+ end
197
+
198
+ # Returns the loader that loaded this type.
199
+ # @return [Loaders::Loader] the loader
200
+ def loader
201
+ Loaders.static_loader
202
+ end
203
+
204
+ # Normalizes the type. This does not change the characteristics of the type but it will remove duplicates
205
+ # and constructs like NotUndef[T] where T is not assignable from Undef and change Variant[*T] where all
206
+ # T are enums into an Enum.
207
+ #
208
+ # @param guard [RecursionGuard] guard against recursion. Only used by internal calls
209
+ # @return [PAnyType] The iterable type that this type is assignable to or `nil`
210
+ # @api public
211
+ def normalize(guard = nil)
212
+ self
213
+ end
214
+
215
+ # Called from the TypeParser once it has found a type using the Loader to enable that this type can
216
+ # resolve internal type expressions using a loader. Presently, this method is a no-op for all types
217
+ # except the {{PTypeAliasType}}.
218
+ #
219
+ # @param loader [Loader::Loader] loader to use
220
+ # @return [PTypeAliasType] the receiver of the call, i.e. `self`
221
+ # @api private
222
+ def resolve(loader)
223
+ self
224
+ end
225
+
226
+ # Responds `true` for all callables, variants of callables and unless _optional_ is
227
+ # false, all optional callables.
228
+ # @param optional [Boolean]
229
+ # @param guard [RecursionGuard] guard against recursion. Only used by internal calls
230
+ # @return [Boolean] `true`if this type is considered callable
231
+ # @api private
232
+ def kind_of_callable?(optional = true, guard = nil)
233
+ false
234
+ end
235
+
236
+ # Returns `true` if an instance of this type is iterable, `false` otherwise
237
+ # The method #iterable_type must produce a `PIterableType` instance when this
238
+ # method returns `true`
239
+ #
240
+ # @param guard [RecursionGuard] guard against recursion. Only used by internal calls
241
+ # @return [Boolean] flag to indicate if instances of this type is iterable.
242
+ def iterable?(guard = nil)
243
+ false
244
+ end
245
+
246
+ # Returns the `PIterableType` that this type should be assignable to, or `nil` if no such type exists.
247
+ # A type that returns a `PIterableType` must respond `true` to `#iterable?`.
248
+ #
249
+ # @example
250
+ # Any Collection[T] is assignable to an Iterable[T]
251
+ # A String is assignable to an Iterable[String] iterating over the strings characters
252
+ # An Integer is assignable to an Iterable[Integer] iterating over the 'times' enumerator
253
+ # A Type[T] is assignable to an Iterable[Type[T]] if T is an Integer or Enum
254
+ #
255
+ # @param guard [RecursionGuard] guard against recursion. Only used by internal calls
256
+ # @return [PIterableType,nil] The iterable type that this type is assignable to or `nil`
257
+ # @api private
258
+ def iterable_type(guard = nil)
259
+ nil
260
+ end
261
+
262
+ def hash
263
+ self.class.hash
264
+ end
265
+
266
+ # Returns true if the given argument _o_ is an instance of this type
267
+ # @param guard [RecursionGuard] guard against recursion. Only used by internal calls
268
+ # @return [Boolean]
269
+ # @api public
270
+ def instance?(o, guard = nil)
271
+ true
272
+ end
273
+
274
+ # An object is considered to really be an instance of a type when something other than a
275
+ # TypeAlias or a Variant responds true to a call to {#instance?}.
276
+ #
277
+ # @return [Integer] -1 = is not instance, 0 = recursion detected, 1 = is instance
278
+ # @api private
279
+ def really_instance?(o, guard = nil)
280
+ instance?(o, guard) ? 1 : -1
281
+ end
282
+
283
+ def eql?(o)
284
+ self.class == o.class
285
+ end
286
+
287
+ def ==(o)
288
+ eql?(o)
289
+ end
290
+
291
+ def simple_name
292
+ self.class.simple_name
293
+ end
294
+
295
+ # Strips the class name from all module prefixes, the leading 'P' and the ending 'Type'. I.e.
296
+ # an instance of PVariantType will return 'Variant'
297
+ # @return [String] the simple name of this type
298
+ def self.simple_name
299
+ @simple_name ||= (
300
+ n = name
301
+ n[n.rindex(DOUBLE_COLON) + 3..n.size - 5].freeze
302
+ )
303
+ end
304
+
305
+ def to_alias_expanded_s
306
+ TypeFormatter.new.alias_expanded_string(self)
307
+ end
308
+
309
+ def to_s
310
+ TypeFormatter.string(self)
311
+ end
312
+
313
+ # Returns the name of the type, without parameters
314
+ # @return [String] the name of the type
315
+ # @api public
316
+ def name
317
+ simple_name
318
+ end
319
+
320
+ def create(*args)
321
+ Loaders.find_loader(nil).load(:function, 'new').call({}, self, *args)
322
+ end
323
+
324
+ # Create an instance of this type.
325
+ # The default implementation will just dispatch the call to the class method with the
326
+ # same name and pass `self` as the first argument.
327
+ #
328
+ # @return [Function] the created function
329
+ # @raises ArgumentError
330
+ #
331
+ def new_function
332
+ self.class.new_function(self)
333
+ end
334
+
335
+ # This default implementation of of a new_function raises an Argument Error.
336
+ # Types for which creating a new instance is supported, should create and return
337
+ # a Puppet Function class by using Puppet:Loaders.create_loaded_function(:new, loader)
338
+ # and return that result.
339
+ #
340
+ # @param type [PAnyType] the type to create a new function for
341
+ # @return [Function] the created function
342
+ # @raises ArgumentError
343
+ #
344
+ def self.new_function(type)
345
+ raise ArgumentError, "Creation of new instance of type '#{type}' is not supported"
346
+ end
347
+
348
+ # Answers the question if instances of this type can represent themselves as a string that
349
+ # can then be passed to the create method
350
+ #
351
+ # @return [Boolean] whether or not the instance has a canonical string representation
352
+ def roundtrip_with_string?
353
+ false
354
+ end
355
+
356
+ # The default instance of this type. Each type in the type system has this constant
357
+ # declared.
358
+ #
359
+ DEFAULT = PAnyType.new
360
+
361
+ protected
362
+
363
+ # @api private
364
+ def _assignable?(o, guard)
365
+ o.is_a?(PAnyType)
366
+ end
367
+
368
+ # Produces the tuple entry at the given index given a tuple type, its from/to constraints on the last
369
+ # type, and an index.
370
+ # Produces nil if the index is out of bounds
371
+ # from must be less than to, and from may not be less than 0
372
+ #
373
+ # @api private
374
+ #
375
+ def tuple_entry_at(tuple_t, to, index)
376
+ regular = (tuple_t.types.size - 1)
377
+ if index < regular
378
+ tuple_t.types[index]
379
+ elsif index < regular + to
380
+ # in the varargs part
381
+ tuple_t.types[-1]
382
+ else
383
+ nil
384
+ end
385
+ end
386
+
387
+ # Applies a transformation by sending the given _method_ and _method_args_ to each of the types of the given array
388
+ # and collecting the results in a new array. If all transformation calls returned the type instance itself (i.e. no
389
+ # transformation took place), then this method will return `self`. If a transformation did occur, then this method
390
+ # will either return the transformed array or in case a block was given, the result of calling a given block with
391
+ # the transformed array.
392
+ #
393
+ # @param types [Array<PAnyType>] the array of types to transform
394
+ # @param method [Symbol] The method to call on each type
395
+ # @param method_args [Object] The arguments to pass to the method, if any
396
+ # @return [Object] self, the transformed array, or the result of calling a given block with the transformed array
397
+ # @yieldparam altered_types [Array<PAnyType>] the altered type array
398
+ # @api private
399
+ def alter_type_array(types, method, *method_args)
400
+ modified = false
401
+ modified_types = types.map do |t|
402
+ t_mod = t.send(method, *method_args)
403
+ modified ||= !t.equal?(t_mod)
404
+ t_mod
405
+ end
406
+ if modified
407
+ block_given? ? yield(modified_types) : modified_types
408
+ else
409
+ self
410
+ end
411
+ end
412
+ end
413
+
414
+ # @abstract Encapsulates common behavior for a type that contains one type
415
+ # @api public
416
+ class PTypeWithContainedType < PAnyType
417
+ def self.register_ptype(loader, ir)
418
+ # Abstract type. It doesn't register anything
419
+ end
420
+
421
+ attr_reader :type
422
+
423
+ def initialize(type)
424
+ @type = type
425
+ end
426
+
427
+ def accept(visitor, guard)
428
+ super
429
+ @type.accept(visitor, guard) unless @type.nil?
430
+ end
431
+
432
+ def generalize
433
+ if @type.nil?
434
+ self.class::DEFAULT
435
+ else
436
+ ge_type = @type.generalize
437
+ @type.equal?(ge_type) ? self : self.class.new(ge_type)
438
+ end
439
+ end
440
+
441
+ def normalize(guard = nil)
442
+ if @type.nil?
443
+ self.class::DEFAULT
444
+ else
445
+ ne_type = @type.normalize(guard)
446
+ @type.equal?(ne_type) ? self : self.class.new(ne_type)
447
+ end
448
+ end
449
+
450
+ def hash
451
+ self.class.hash ^ @type.hash
452
+ end
453
+
454
+ def eql?(o)
455
+ self.class == o.class && @type == o.type
456
+ end
457
+
458
+ def resolve(loader)
459
+ rtype = @type
460
+ rtype = rtype.resolve(loader) unless rtype.nil?
461
+ rtype.equal?(@type) ? self : self.class.new(rtype)
462
+ end
463
+ end
464
+
465
+ # The type of types.
466
+ # @api public
467
+ #
468
+ class PTypeType < PTypeWithContainedType
469
+ def self.register_ptype(loader, ir)
470
+ create_ptype(loader, ir, 'AnyType',
471
+ 'type' => {
472
+ KEY_TYPE => POptionalType.new(PTypeType::DEFAULT),
473
+ KEY_VALUE => nil
474
+ })
475
+ end
476
+
477
+ # Returns a new function that produces a Type instance
478
+ #
479
+ def self.new_function(type)
480
+ @new_function ||= Puppet::Functions.create_loaded_function(:new_type, type.loader) do
481
+ dispatch :from_string do
482
+ param 'String[1]', :type_string
483
+ end
484
+
485
+ def from_string(type_string)
486
+ TypeParser.singleton.parse(type_string, loader)
487
+ end
488
+ end
489
+ end
490
+
491
+ def instance?(o, guard = nil)
492
+ case o
493
+ when PAnyType
494
+ type.nil? || type.assignable?(o, guard)
495
+ when Module, Puppet::Resource, Puppet::Parser::Resource
496
+ @type.nil? ? true : assignable?(TypeCalculator.infer(o))
497
+ else
498
+ false
499
+ end
500
+ end
501
+
502
+ def iterable?(guard = nil)
503
+ case @type
504
+ when PEnumType
505
+ true
506
+ when PIntegerType
507
+ @type.finite_range?
508
+ else
509
+ false
510
+ end
511
+ end
512
+
513
+ def iterable_type(guard = nil)
514
+ # The types PIntegerType and PEnumType are Iterable
515
+ case @type
516
+ when PEnumType
517
+ # @type describes the element type perfectly since the iteration is made over the
518
+ # contained choices.
519
+ PIterableType.new(@type)
520
+ when PIntegerType
521
+ # @type describes the element type perfectly since the iteration is made over the
522
+ # specified range.
523
+ @type.finite_range? ? PIterableType.new(@type) : nil
524
+ else
525
+ nil
526
+ end
527
+ end
528
+
529
+ def eql?(o)
530
+ self.class == o.class && @type == o.type
531
+ end
532
+
533
+ DEFAULT = PTypeType.new(nil)
534
+
535
+ protected
536
+
537
+ # @api private
538
+ def _assignable?(o, guard)
539
+ return false unless o.is_a?(PTypeType)
540
+ return true if @type.nil? # wide enough to handle all types
541
+ return false if o.type.nil? # wider than t
542
+
543
+ @type.assignable?(o.type, guard)
544
+ end
545
+ end
546
+
547
+ # For backward compatibility
548
+ PType = PTypeType
549
+
550
+ class PNotUndefType < PTypeWithContainedType
551
+ def self.register_ptype(loader, ir)
552
+ create_ptype(loader, ir, 'AnyType',
553
+ 'type' => {
554
+ KEY_TYPE => POptionalType.new(PTypeType::DEFAULT),
555
+ KEY_VALUE => nil
556
+ })
557
+ end
558
+
559
+ def initialize(type = nil)
560
+ super(type.instance_of?(PAnyType) ? nil : type)
561
+ end
562
+
563
+ def instance?(o, guard = nil)
564
+ !(o.nil? || o == :undef) && (@type.nil? || @type.instance?(o, guard))
565
+ end
566
+
567
+ def normalize(guard = nil)
568
+ n = super
569
+ if n.type.nil?
570
+ n
571
+ elsif n.type.is_a?(POptionalType)
572
+ PNotUndefType.new(n.type.type).normalize
573
+ # No point in having an optional in a NotUndef
574
+ elsif !n.type.assignable?(PUndefType::DEFAULT)
575
+ # THe type is NotUndef anyway, so it can be stripped of
576
+ n.type
577
+ else
578
+ n
579
+ end
580
+ end
581
+
582
+ def new_function
583
+ # If only NotUndef, then use Unit's null converter
584
+ if type.nil?
585
+ PUnitType.new_function(self)
586
+ else
587
+ type.new_function
588
+ end
589
+ end
590
+
591
+ DEFAULT = PNotUndefType.new
592
+
593
+ protected
594
+
595
+ # @api private
596
+ def _assignable?(o, guard)
597
+ o.is_a?(PAnyType) && !o.assignable?(PUndefType::DEFAULT, guard) && (@type.nil? || @type.assignable?(o, guard))
598
+ end
599
+ end
600
+
601
+ # @api public
602
+ #
603
+ class PUndefType < PAnyType
604
+ def self.register_ptype(loader, ir)
605
+ create_ptype(loader, ir, 'AnyType')
606
+ end
607
+
608
+ def instance?(o, guard = nil)
609
+ o.nil? || :undef == o
610
+ end
611
+
612
+ # @api private
613
+ def callable_args?(callable_t, guard)
614
+ # if callable_t is Optional (or indeed PUndefType), this means that 'missing callable' is accepted
615
+ callable_t.assignable?(DEFAULT, guard)
616
+ end
617
+
618
+ DEFAULT = PUndefType.new
619
+
620
+ protected
621
+
622
+ # @api private
623
+ def _assignable?(o, guard)
624
+ o.is_a?(PUndefType)
625
+ end
626
+ end
627
+
628
+ # A type private to the type system that describes "ignored type" - i.e. "I am what you are"
629
+ # @api private
630
+ #
631
+ class PUnitType < PAnyType
632
+ def self.register_ptype(loader, ir)
633
+ create_ptype(loader, ir, 'AnyType')
634
+ end
635
+
636
+ def instance?(o, guard = nil)
637
+ true
638
+ end
639
+
640
+ # A "null" implementation - that simply returns the given argument
641
+ def self.new_function(type)
642
+ @new_function ||= Puppet::Functions.create_loaded_function(:new_unit, type.loader) do
643
+ dispatch :from_args do
644
+ param 'Any', :from
645
+ end
646
+
647
+ def from_args(from)
648
+ from
649
+ end
650
+ end
651
+ end
652
+
653
+ DEFAULT = PUnitType.new
654
+
655
+ def assignable?(o, guard = nil)
656
+ true
657
+ end
658
+
659
+ protected
660
+
661
+ # @api private
662
+ def _assignable?(o, guard)
663
+ true
664
+ end
665
+ end
666
+
667
+ # @api public
668
+ #
669
+ class PDefaultType < PAnyType
670
+ def self.register_ptype(loader, ir)
671
+ create_ptype(loader, ir, 'AnyType')
672
+ end
673
+
674
+ def instance?(o, guard = nil)
675
+ # Ensure that Symbol.== is called here instead of something unknown
676
+ # that is implemented on o
677
+ :default == o
678
+ end
679
+
680
+ DEFAULT = PDefaultType.new
681
+
682
+ protected
683
+
684
+ # @api private
685
+ def _assignable?(o, guard)
686
+ o.is_a?(PDefaultType)
687
+ end
688
+ end
689
+
690
+ # Type that is a Scalar
691
+ # @api public
692
+ #
693
+ class PScalarType < PAnyType
694
+ def self.register_ptype(loader, ir)
695
+ create_ptype(loader, ir, 'AnyType')
696
+ end
697
+
698
+ def instance?(o, guard = nil)
699
+ if o.is_a?(String) || o.is_a?(Numeric) || o.is_a?(TrueClass) || o.is_a?(FalseClass) || o.is_a?(Regexp)
700
+ true
701
+ elsif o.instance_of?(Array) || o.instance_of?(Hash) || o.is_a?(PAnyType) || o.is_a?(NilClass)
702
+ false
703
+ else
704
+ assignable?(TypeCalculator.infer(o))
705
+ end
706
+ end
707
+
708
+ def roundtrip_with_string?
709
+ true
710
+ end
711
+
712
+ DEFAULT = PScalarType.new
713
+
714
+ protected
715
+
716
+ # @api private
717
+ def _assignable?(o, guard)
718
+ o.is_a?(PScalarType) ||
719
+ PStringType::DEFAULT.assignable?(o, guard) ||
720
+ PIntegerType::DEFAULT.assignable?(o, guard) ||
721
+ PFloatType::DEFAULT.assignable?(o, guard) ||
722
+ PBooleanType::DEFAULT.assignable?(o, guard) ||
723
+ PRegexpType::DEFAULT.assignable?(o, guard) ||
724
+ PSemVerType::DEFAULT.assignable?(o, guard) ||
725
+ PSemVerRangeType::DEFAULT.assignable?(o, guard) ||
726
+ PTimespanType::DEFAULT.assignable?(o, guard) ||
727
+ PTimestampType::DEFAULT.assignable?(o, guard)
728
+ end
729
+ end
730
+
731
+ # Like Scalar but limited to Json Data.
732
+ # @api public
733
+ #
734
+ class PScalarDataType < PScalarType
735
+ def self.register_ptype(loader, ir)
736
+ create_ptype(loader, ir, 'ScalarType')
737
+ end
738
+
739
+ def instance?(o, guard = nil)
740
+ o.instance_of?(String) || o.is_a?(Integer) || o.is_a?(Float) || o.is_a?(TrueClass) || o.is_a?(FalseClass)
741
+ end
742
+
743
+ DEFAULT = PScalarDataType.new
744
+
745
+ protected
746
+
747
+ # @api private
748
+ def _assignable?(o, guard)
749
+ o.is_a?(PScalarDataType) ||
750
+ PStringType::DEFAULT.assignable?(o, guard) ||
751
+ PIntegerType::DEFAULT.assignable?(o, guard) ||
752
+ PFloatType::DEFAULT.assignable?(o, guard) ||
753
+ PBooleanType::DEFAULT.assignable?(o, guard)
754
+ end
755
+ end
756
+
757
+ # A string type describing the set of strings having one of the given values
758
+ # @api public
759
+ #
760
+ class PEnumType < PScalarDataType
761
+ def self.register_ptype(loader, ir)
762
+ create_ptype(loader, ir, 'ScalarDataType',
763
+ 'values' => PArrayType.new(PStringType::NON_EMPTY),
764
+ 'case_insensitive' => { 'type' => PBooleanType::DEFAULT, 'value' => false })
765
+ end
766
+
767
+ attr_reader :values, :case_insensitive
768
+
769
+ def initialize(values, case_insensitive = false)
770
+ @values = values.uniq.sort.freeze
771
+ @case_insensitive = case_insensitive
772
+ end
773
+
774
+ def case_insensitive?
775
+ @case_insensitive
776
+ end
777
+
778
+ # Returns Enumerator if no block is given, otherwise, calls the given
779
+ # block with each of the strings for this enum
780
+ def each(&block)
781
+ r = Iterable.on(self)
782
+ block_given? ? r.each(&block) : r
783
+ end
784
+
785
+ def generalize
786
+ # General form of an Enum is a String
787
+ if @values.empty?
788
+ PStringType::DEFAULT
789
+ else
790
+ range = @values.map(&:size).minmax
791
+ PStringType.new(PIntegerType.new(range.min, range.max))
792
+ end
793
+ end
794
+
795
+ def iterable?(guard = nil)
796
+ true
797
+ end
798
+
799
+ def iterable_type(guard = nil)
800
+ # An instance of an Enum is a String
801
+ PStringType::ITERABLE_TYPE
802
+ end
803
+
804
+ def hash
805
+ @values.hash ^ @case_insensitive.hash
806
+ end
807
+
808
+ def eql?(o)
809
+ self.class == o.class && @values == o.values && @case_insensitive == o.case_insensitive?
810
+ end
811
+
812
+ def instance?(o, guard = nil)
813
+ if o.is_a?(String)
814
+ @case_insensitive ? @values.any? { |p| p.casecmp(o) == 0 } : @values.any? { |p| p == o }
815
+ else
816
+ false
817
+ end
818
+ end
819
+
820
+ DEFAULT = PEnumType.new(EMPTY_ARRAY)
821
+
822
+ protected
823
+
824
+ # @api private
825
+ def _assignable?(o, guard)
826
+ return true if self == o
827
+
828
+ svalues = values
829
+ if svalues.empty?
830
+ return true if o.is_a?(PStringType) || o.is_a?(PEnumType) || o.is_a?(PPatternType)
831
+ end
832
+ case o
833
+ when PStringType
834
+ # if the contained string is found in the set of enums
835
+ instance?(o.value, guard)
836
+ when PEnumType
837
+ !o.values.empty? && (case_insensitive? || !o.case_insensitive?) && o.values.all? { |s| instance?(s, guard) }
838
+ else
839
+ false
840
+ end
841
+ end
842
+ end
843
+
844
+ INTEGER_HEX = '(?:0[xX][0-9A-Fa-f]+)'
845
+ INTEGER_OCT = '(?:0[0-7]+)'
846
+ INTEGER_BIN = '(?:0[bB][01]+)'
847
+ INTEGER_DEC = '(?:0|[1-9]\d*)'
848
+ INTEGER_DEC_OR_OCT = '(?:\d+)'
849
+ SIGN_PREFIX = '[+-]?\s*'
850
+
851
+ OPTIONAL_FRACTION = '(?:\.\d+)?'
852
+ OPTIONAL_EXPONENT = '(?:[eE]-?\d+)?'
853
+ FLOAT_DEC = '(?:' + INTEGER_DEC + OPTIONAL_FRACTION + OPTIONAL_EXPONENT + ')'
854
+
855
+ INTEGER_PATTERN = '\A' + SIGN_PREFIX + '(?:' + INTEGER_DEC + '|' + INTEGER_HEX + '|' + INTEGER_OCT + '|' + INTEGER_BIN + ')\z'
856
+ INTEGER_PATTERN_LENIENT = '\A' + SIGN_PREFIX + '(?:' + INTEGER_DEC_OR_OCT + '|' + INTEGER_HEX + '|' + INTEGER_BIN + ')\z'
857
+ FLOAT_PATTERN = '\A' + SIGN_PREFIX + '(?:' + FLOAT_DEC + '|' + INTEGER_HEX + '|' + INTEGER_OCT + '|' + INTEGER_BIN + ')\z'
858
+
859
+ # @api public
860
+ #
861
+ class PNumericType < PScalarDataType
862
+ def self.register_ptype(loader, ir)
863
+ create_ptype(loader, ir, 'ScalarDataType',
864
+ 'from' => { KEY_TYPE => POptionalType.new(PNumericType::DEFAULT), KEY_VALUE => nil },
865
+ 'to' => { KEY_TYPE => POptionalType.new(PNumericType::DEFAULT), KEY_VALUE => nil })
866
+ end
867
+
868
+ def self.new_function(type)
869
+ @new_function ||= Puppet::Functions.create_loaded_function(:new_numeric, type.loader) do
870
+ local_types do
871
+ type "Convertible = Variant[Integer, Float, Boolean, Pattern[/#{FLOAT_PATTERN}/], Timespan, Timestamp]"
872
+ type 'NamedArgs = Struct[{from => Convertible, Optional[abs] => Boolean}]'
873
+ end
874
+
875
+ dispatch :from_args do
876
+ param 'Convertible', :from
877
+ optional_param 'Boolean', :abs
878
+ end
879
+
880
+ dispatch :from_hash do
881
+ param 'NamedArgs', :hash_args
882
+ end
883
+
884
+ argument_mismatch :on_error do
885
+ param 'Any', :from
886
+ optional_param 'Boolean', :abs
887
+ end
888
+
889
+ def from_args(from, abs = false)
890
+ result = from_convertible(from)
891
+ abs ? result.abs : result
892
+ end
893
+
894
+ def from_hash(args_hash)
895
+ from_args(args_hash['from'], args_hash['abs'] || false)
896
+ end
897
+
898
+ def from_convertible(from)
899
+ case from
900
+ when Float
901
+ from
902
+ when Integer
903
+ from
904
+ when Time::TimeData
905
+ from.to_f
906
+ when TrueClass
907
+ 1
908
+ when FalseClass
909
+ 0
910
+ else
911
+ begin
912
+ if from[0] == '0'
913
+ second_char = (from[1] || '').downcase
914
+ if second_char == 'b' || second_char == 'x'
915
+ # use built in conversion
916
+ return Integer(from)
917
+ end
918
+ end
919
+
920
+ Puppet::Pops::Utils.to_n(from)
921
+ rescue TypeError => e
922
+ raise TypeConversionError, e.message
923
+ rescue ArgumentError => e
924
+ raise TypeConversionError, e.message
925
+ end
926
+ end
927
+ end
928
+
929
+ def on_error(from, abs = false)
930
+ if from.is_a?(String)
931
+ _("The string '%{str}' cannot be converted to Numeric") % { str: from }
932
+ else
933
+ t = TypeCalculator.singleton.infer(from).generalize
934
+ _("Value of type %{type} cannot be converted to Numeric") % { type: t }
935
+ end
936
+ end
937
+ end
938
+ end
939
+
940
+ def initialize(from, to = Float::INFINITY)
941
+ from = -Float::INFINITY if from.nil? || from == :default
942
+ to = Float::INFINITY if to.nil? || to == :default
943
+ raise ArgumentError, "'from' must be less or equal to 'to'. Got (#{from}, #{to}" if from > to
944
+
945
+ @from = from
946
+ @to = to
947
+ end
948
+
949
+ # Checks if this numeric range intersects with another
950
+ #
951
+ # @param o [PNumericType] the range to compare with
952
+ # @return [Boolean] `true` if this range intersects with the other range
953
+ # @api public
954
+ def intersect?(o)
955
+ instance_of?(o.class) && !(@to < o.numeric_from || o.numeric_to < @from)
956
+ end
957
+
958
+ # Returns the lower bound of the numeric range or `nil` if no lower bound is set.
959
+ # @return [Float,Integer]
960
+ def from
961
+ @from == -Float::INFINITY ? nil : @from
962
+ end
963
+
964
+ # Returns the upper bound of the numeric range or `nil` if no upper bound is set.
965
+ # @return [Float,Integer]
966
+ def to
967
+ @to == Float::INFINITY ? nil : @to
968
+ end
969
+
970
+ # Same as #from but will return `-Float::Infinity` instead of `nil` if no lower bound is set.
971
+ # @return [Float,Integer]
972
+ def numeric_from
973
+ @from
974
+ end
975
+
976
+ # Same as #to but will return `Float::Infinity` instead of `nil` if no lower bound is set.
977
+ # @return [Float,Integer]
978
+ def numeric_to
979
+ @to
980
+ end
981
+
982
+ def hash
983
+ @from.hash ^ @to.hash
984
+ end
985
+
986
+ def eql?(o)
987
+ self.class == o.class && @from == o.numeric_from && @to == o.numeric_to
988
+ end
989
+
990
+ def instance?(o, guard = nil)
991
+ (o.is_a?(Float) || o.is_a?(Integer)) && o >= @from && o <= @to
992
+ end
993
+
994
+ def unbounded?
995
+ @from == -Float::INFINITY && @to == Float::INFINITY
996
+ end
997
+
998
+ protected
999
+
1000
+ # @api_private
1001
+ def _assignable?(o, guard)
1002
+ return false unless o.is_a?(self.class)
1003
+
1004
+ # If o min and max are within the range of t
1005
+ @from <= o.numeric_from && @to >= o.numeric_to
1006
+ end
1007
+
1008
+ DEFAULT = PNumericType.new(-Float::INFINITY)
1009
+ end
1010
+
1011
+ # @api public
1012
+ #
1013
+ class PIntegerType < PNumericType
1014
+ def self.register_ptype(loader, ir)
1015
+ create_ptype(loader, ir, 'NumericType')
1016
+ end
1017
+
1018
+ # Will respond `true` for any range that is bounded at both ends.
1019
+ #
1020
+ # @return [Boolean] `true` if the type describes a finite range.
1021
+ def finite_range?
1022
+ @from != -Float::INFINITY && @to != Float::INFINITY
1023
+ end
1024
+
1025
+ def generalize
1026
+ DEFAULT
1027
+ end
1028
+
1029
+ def instance?(o, guard = nil)
1030
+ o.is_a?(Integer) && o >= numeric_from && o <= numeric_to
1031
+ end
1032
+
1033
+ # Checks if this range is adjacent to the given range
1034
+ #
1035
+ # @param o [PIntegerType] the range to compare with
1036
+ # @return [Boolean] `true` if this range is adjacent to the other range
1037
+ # @api public
1038
+ def adjacent?(o)
1039
+ o.is_a?(PIntegerType) && (@to + 1 == o.from || o.to + 1 == @from)
1040
+ end
1041
+
1042
+ # Concatenates this range with another range provided that the ranges intersect or
1043
+ # are adjacent. When that's not the case, this method will return `nil`
1044
+ #
1045
+ # @param o [PIntegerType] the range to concatenate with this range
1046
+ # @return [PIntegerType,nil] the concatenated range or `nil` when the ranges were apart
1047
+ # @api public
1048
+ def merge(o)
1049
+ if intersect?(o) || adjacent?(o)
1050
+ min = @from <= o.numeric_from ? @from : o.numeric_from
1051
+ max = @to >= o.numeric_to ? @to : o.numeric_to
1052
+ PIntegerType.new(min, max)
1053
+ else
1054
+ nil
1055
+ end
1056
+ end
1057
+
1058
+ def iterable?(guard = nil)
1059
+ true
1060
+ end
1061
+
1062
+ def iterable_type(guard = nil)
1063
+ # It's unknown if the iterable will be a range (min, max) or a "times" (0, max)
1064
+ PIterableType.new(PIntegerType::DEFAULT)
1065
+ end
1066
+
1067
+ # Returns Float.Infinity if one end of the range is unbound
1068
+ def size
1069
+ return Float::INFINITY if @from == -Float::INFINITY || @to == Float::INFINITY
1070
+
1071
+ 1 + (to - from).abs
1072
+ end
1073
+
1074
+ # Returns the range as an array ordered so the smaller number is always first.
1075
+ # The number may be Infinity or -Infinity.
1076
+ def range
1077
+ [@from, @to]
1078
+ end
1079
+
1080
+ # Returns Enumerator if no block is given
1081
+ # Returns nil if size is infinity (does not yield)
1082
+ def each(&block)
1083
+ r = Iterable.on(self)
1084
+ block_given? ? r.each(&block) : r
1085
+ end
1086
+
1087
+ # Returns a range where both to and from are positive numbers. Negative
1088
+ # numbers are converted to zero
1089
+ # @return [PIntegerType] a positive range
1090
+ def to_size
1091
+ if @from >= 0
1092
+ self
1093
+ else
1094
+ PIntegerType.new(0, @to < 0 ? 0 : @to)
1095
+ end
1096
+ end
1097
+
1098
+ def new_function
1099
+ @@new_function ||= Puppet::Functions.create_loaded_function(:new, loader) do
1100
+ local_types do
1101
+ type 'Radix = Variant[Default, Integer[2,2], Integer[8,8], Integer[10,10], Integer[16,16]]'
1102
+ type "Convertible = Variant[Numeric, Boolean, Pattern[/#{INTEGER_PATTERN_LENIENT}/], Timespan, Timestamp]"
1103
+ type 'NamedArgs = Struct[{from => Convertible, Optional[radix] => Radix, Optional[abs] => Boolean}]'
1104
+ end
1105
+
1106
+ dispatch :from_args do
1107
+ param 'Convertible', :from
1108
+ optional_param 'Radix', :radix
1109
+ optional_param 'Boolean', :abs
1110
+ end
1111
+
1112
+ dispatch :from_hash do
1113
+ param 'NamedArgs', :hash_args
1114
+ end
1115
+
1116
+ argument_mismatch :on_error_hash do
1117
+ param 'Hash', :hash_args
1118
+ end
1119
+
1120
+ argument_mismatch :on_error do
1121
+ param 'Any', :from
1122
+ optional_param 'Integer', :radix
1123
+ optional_param 'Boolean', :abs
1124
+ end
1125
+
1126
+ def from_args(from, radix = :default, abs = false)
1127
+ result = from_convertible(from, radix)
1128
+ abs ? result.abs : result
1129
+ end
1130
+
1131
+ def from_hash(args_hash)
1132
+ from_args(args_hash['from'], args_hash['radix'] || :default, args_hash['abs'] || false)
1133
+ end
1134
+
1135
+ def from_convertible(from, radix)
1136
+ case from
1137
+ when Float, Time::TimeData
1138
+ from.to_i
1139
+ when Integer
1140
+ from
1141
+ when TrueClass
1142
+ 1
1143
+ when FalseClass
1144
+ 0
1145
+ else
1146
+ begin
1147
+ radix == :default ? Integer(from) : Integer(from, radix)
1148
+ rescue TypeError => e
1149
+ raise TypeConversionError, e.message
1150
+ rescue ArgumentError => e
1151
+ # Test for special case where there is whitespace between sign and number
1152
+ match = Patterns::WS_BETWEEN_SIGN_AND_NUMBER.match(from)
1153
+ if match
1154
+ begin
1155
+ # Try again, this time with whitespace removed
1156
+ return from_args(match[1] + match[2], radix)
1157
+ rescue TypeConversionError
1158
+ # Ignored to retain original error
1159
+ end
1160
+ end
1161
+ raise TypeConversionError, e.message
1162
+ end
1163
+ end
1164
+ end
1165
+
1166
+ def on_error_hash(args_hash)
1167
+ if args_hash.include?('from')
1168
+ from = args_hash['from']
1169
+ return on_error(from) unless loader.load(:type, 'convertible').instance?(from)
1170
+ end
1171
+ radix = args_hash['radix']
1172
+ assert_radix(radix) unless radix.nil? || radix == :default
1173
+ TypeAsserter.assert_instance_of('Integer.new', loader.load(:type, 'namedargs'), args_hash)
1174
+ end
1175
+
1176
+ def on_error(from, radix = :default, abs = nil)
1177
+ assert_radix(radix) unless radix == :default
1178
+ if from.is_a?(String)
1179
+ _("The string '%{str}' cannot be converted to Integer") % { str: from }
1180
+ else
1181
+ t = TypeCalculator.singleton.infer(from).generalize
1182
+ _("Value of type %{type} cannot be converted to Integer") % { type: t }
1183
+ end
1184
+ end
1185
+
1186
+ def assert_radix(radix)
1187
+ case radix
1188
+ when 2, 8, 10, 16
1189
+ # do nothing
1190
+ else
1191
+ raise ArgumentError, _("Illegal radix: %{radix}, expected 2, 8, 10, 16, or default") % { radix: radix }
1192
+ end
1193
+ radix
1194
+ end
1195
+ end
1196
+ end
1197
+
1198
+ DEFAULT = PIntegerType.new(-Float::INFINITY)
1199
+ end
1200
+
1201
+ # @api public
1202
+ #
1203
+ class PFloatType < PNumericType
1204
+ def self.register_ptype(loader, ir)
1205
+ create_ptype(loader, ir, 'NumericType')
1206
+ end
1207
+
1208
+ def generalize
1209
+ DEFAULT
1210
+ end
1211
+
1212
+ def instance?(o, guard = nil)
1213
+ o.is_a?(Float) && o >= numeric_from && o <= numeric_to
1214
+ end
1215
+
1216
+ # Concatenates this range with another range provided that the ranges intersect. When that's not the case, this
1217
+ # method will return `nil`
1218
+ #
1219
+ # @param o [PFloatType] the range to concatenate with this range
1220
+ # @return [PFloatType,nil] the concatenated range or `nil` when the ranges were apart
1221
+ # @api public
1222
+ def merge(o)
1223
+ if intersect?(o)
1224
+ min = @from <= o.from ? @from : o.from
1225
+ max = @to >= o.to ? @to : o.to
1226
+ PFloatType.new(min, max)
1227
+ else
1228
+ nil
1229
+ end
1230
+ end
1231
+
1232
+ # Returns a new function that produces a Float value
1233
+ #
1234
+ def self.new_function(type)
1235
+ @new_function ||= Puppet::Functions.create_loaded_function(:new_float, type.loader) do
1236
+ local_types do
1237
+ type "Convertible = Variant[Numeric, Boolean, Pattern[/#{FLOAT_PATTERN}/], Timespan, Timestamp]"
1238
+ type 'NamedArgs = Struct[{from => Convertible, Optional[abs] => Boolean}]'
1239
+ end
1240
+
1241
+ dispatch :from_args do
1242
+ param 'Convertible', :from
1243
+ optional_param 'Boolean', :abs
1244
+ end
1245
+
1246
+ dispatch :from_hash do
1247
+ param 'NamedArgs', :hash_args
1248
+ end
1249
+
1250
+ argument_mismatch :on_error do
1251
+ param 'Any', :from
1252
+ optional_param 'Boolean', :abs
1253
+ end
1254
+
1255
+ def from_args(from, abs = false)
1256
+ result = from_convertible(from)
1257
+ abs ? result.abs : result
1258
+ end
1259
+
1260
+ def from_hash(args_hash)
1261
+ from_args(args_hash['from'], args_hash['abs'] || false)
1262
+ end
1263
+
1264
+ def from_convertible(from)
1265
+ case from
1266
+ when Float
1267
+ from
1268
+ when Integer
1269
+ Float(from)
1270
+ when Time::TimeData
1271
+ from.to_f
1272
+ when TrueClass
1273
+ 1.0
1274
+ when FalseClass
1275
+ 0.0
1276
+ else
1277
+ begin
1278
+ # support a binary as float
1279
+ if from[0] == '0' && from[1].casecmp('b').zero?
1280
+ from = Integer(from)
1281
+ end
1282
+ Float(from)
1283
+ rescue TypeError => e
1284
+ raise TypeConversionError, e.message
1285
+ rescue ArgumentError => e
1286
+ # Test for special case where there is whitespace between sign and number
1287
+ match = Patterns::WS_BETWEEN_SIGN_AND_NUMBER.match(from)
1288
+ if match
1289
+ begin
1290
+ # Try again, this time with whitespace removed
1291
+ return from_args(match[1] + match[2])
1292
+ rescue TypeConversionError
1293
+ # Ignored to retain original error
1294
+ end
1295
+ end
1296
+ raise TypeConversionError, e.message
1297
+ end
1298
+ end
1299
+ end
1300
+
1301
+ def on_error(from, _ = false)
1302
+ if from.is_a?(String)
1303
+ _("The string '%{str}' cannot be converted to Float") % { str: from }
1304
+ else
1305
+ t = TypeCalculator.singleton.infer(from).generalize
1306
+ _("Value of type %{type} cannot be converted to Float") % { type: t }
1307
+ end
1308
+ end
1309
+ end
1310
+ end
1311
+
1312
+ DEFAULT = PFloatType.new(-Float::INFINITY)
1313
+ end
1314
+
1315
+ # @api public
1316
+ #
1317
+ class PCollectionType < PAnyType
1318
+ def self.register_ptype(loader, ir)
1319
+ create_ptype(loader, ir, 'AnyType',
1320
+ 'size_type' => {
1321
+ KEY_TYPE => POptionalType.new(PTypeType.new(PIntegerType::DEFAULT)),
1322
+ KEY_VALUE => nil
1323
+ })
1324
+ end
1325
+
1326
+ attr_reader :size_type
1327
+
1328
+ def initialize(size_type)
1329
+ @size_type = size_type.nil? ? nil : size_type.to_size
1330
+ end
1331
+
1332
+ def accept(visitor, guard)
1333
+ super
1334
+ @size_type.accept(visitor, guard) unless @size_type.nil?
1335
+ end
1336
+
1337
+ def generalize
1338
+ DEFAULT
1339
+ end
1340
+
1341
+ def normalize(guard = nil)
1342
+ DEFAULT
1343
+ end
1344
+
1345
+ def instance?(o, guard = nil)
1346
+ # The inferred type of a class derived from Array or Hash is either Runtime or Object. It's not assignable to the Collection type.
1347
+ if o.instance_of?(Array) || o.instance_of?(Hash)
1348
+ @size_type.nil? || @size_type.instance?(o.size)
1349
+ else
1350
+ false
1351
+ end
1352
+ end
1353
+
1354
+ # Returns an array with from (min) size to (max) size
1355
+ def size_range
1356
+ (@size_type || DEFAULT_SIZE).range
1357
+ end
1358
+
1359
+ def has_empty_range?
1360
+ from, to = size_range
1361
+ from == 0 && to == 0
1362
+ end
1363
+
1364
+ def hash
1365
+ @size_type.hash
1366
+ end
1367
+
1368
+ def iterable?(guard = nil)
1369
+ true
1370
+ end
1371
+
1372
+ def eql?(o)
1373
+ self.class == o.class && @size_type == o.size_type
1374
+ end
1375
+
1376
+ DEFAULT_SIZE = PIntegerType.new(0)
1377
+ ZERO_SIZE = PIntegerType.new(0, 0)
1378
+ NOT_EMPTY_SIZE = PIntegerType.new(1)
1379
+ DEFAULT = PCollectionType.new(nil)
1380
+
1381
+ protected
1382
+
1383
+ # @api private
1384
+ #
1385
+ def _assignable?(o, guard)
1386
+ case o
1387
+ when PCollectionType
1388
+ (@size_type || DEFAULT_SIZE).assignable?(o.size_type || DEFAULT_SIZE, guard)
1389
+ when PTupleType
1390
+ # compute the tuple's min/max size, and check if that size matches
1391
+ size_s = size_type || DEFAULT_SIZE
1392
+ size_o = o.size_type
1393
+ if size_o.nil?
1394
+ type_count = o.types.size
1395
+ size_o = PIntegerType.new(type_count, type_count)
1396
+ end
1397
+ size_s.assignable?(size_o)
1398
+ when PStructType
1399
+ from = to = o.elements.size
1400
+ (@size_type || DEFAULT_SIZE).assignable?(PIntegerType.new(from, to), guard)
1401
+ else
1402
+ false
1403
+ end
1404
+ end
1405
+ end
1406
+
1407
+ class PIterableType < PTypeWithContainedType
1408
+ def self.register_ptype(loader, ir)
1409
+ create_ptype(loader, ir, 'AnyType',
1410
+ 'type' => {
1411
+ KEY_TYPE => POptionalType.new(PTypeType::DEFAULT),
1412
+ KEY_VALUE => nil
1413
+ })
1414
+ end
1415
+
1416
+ def element_type
1417
+ @type
1418
+ end
1419
+
1420
+ def instance?(o, guard = nil)
1421
+ if @type.nil? || @type.assignable?(PAnyType::DEFAULT, guard)
1422
+ # Any element_type will do
1423
+ case o
1424
+ when Iterable, String, Hash, Array, Range, PEnumType
1425
+ true
1426
+ when Integer
1427
+ o >= 0
1428
+ when PIntegerType
1429
+ o.finite_range?
1430
+ when PTypeAliasType
1431
+ instance?(o.resolved_type, guard)
1432
+ else
1433
+ false
1434
+ end
1435
+ else
1436
+ assignable?(TypeCalculator.infer(o), guard)
1437
+ end
1438
+ end
1439
+
1440
+ def iterable?(guard = nil)
1441
+ true
1442
+ end
1443
+
1444
+ def iterable_type(guard = nil)
1445
+ self
1446
+ end
1447
+
1448
+ DEFAULT = PIterableType.new(nil)
1449
+
1450
+ protected
1451
+
1452
+ # @api private
1453
+ def _assignable?(o, guard)
1454
+ if @type.nil? || @type.assignable?(PAnyType::DEFAULT, guard)
1455
+ # Don't request the iterable_type. Since this Iterable accepts Any element, it is enough that o is iterable.
1456
+ o.iterable?
1457
+ else
1458
+ o = o.iterable_type
1459
+ o.nil? || o.element_type.nil? ? false : @type.assignable?(o.element_type, guard)
1460
+ end
1461
+ end
1462
+ end
1463
+
1464
+ # @api public
1465
+ #
1466
+ class PIteratorType < PTypeWithContainedType
1467
+ def self.register_ptype(loader, ir)
1468
+ create_ptype(loader, ir, 'AnyType',
1469
+ 'type' => {
1470
+ KEY_TYPE => POptionalType.new(PTypeType::DEFAULT),
1471
+ KEY_VALUE => nil
1472
+ })
1473
+ end
1474
+
1475
+ def element_type
1476
+ @type
1477
+ end
1478
+
1479
+ def instance?(o, guard = nil)
1480
+ o.is_a?(Iterable) && (@type.nil? || @type.assignable?(o.element_type, guard))
1481
+ end
1482
+
1483
+ def iterable?(guard = nil)
1484
+ true
1485
+ end
1486
+
1487
+ def iterable_type(guard = nil)
1488
+ @type.nil? ? PIterableType::DEFAULT : PIterableType.new(@type)
1489
+ end
1490
+
1491
+ DEFAULT = PIteratorType.new(nil)
1492
+
1493
+ protected
1494
+
1495
+ # @api private
1496
+ def _assignable?(o, guard)
1497
+ o.is_a?(PIteratorType) && (@type.nil? || @type.assignable?(o.element_type, guard))
1498
+ end
1499
+ end
1500
+
1501
+ # @api public
1502
+ #
1503
+ class PStringType < PScalarDataType
1504
+ def self.register_ptype(loader, ir)
1505
+ create_ptype(loader, ir, 'ScalarDataType',
1506
+ 'size_type_or_value' => {
1507
+ KEY_TYPE => POptionalType.new(PVariantType.new([PStringType::DEFAULT, PTypeType.new(PIntegerType::DEFAULT)])),
1508
+ KEY_VALUE => nil
1509
+ })
1510
+ end
1511
+
1512
+ attr_reader :size_type_or_value
1513
+
1514
+ def initialize(size_type_or_value, deprecated_multi_args = EMPTY_ARRAY)
1515
+ unless deprecated_multi_args.empty?
1516
+ if Puppet[:strict] != :off
1517
+ # TRANSLATORS 'PStringType#initialize' is a class and method name and should not be translated
1518
+ Puppet.warn_once('deprecations', "PStringType#initialize_multi_args",
1519
+ _("Passing more than one argument to PStringType#initialize is deprecated"))
1520
+ end
1521
+ size_type_or_value = deprecated_multi_args[0]
1522
+ end
1523
+ @size_type_or_value = size_type_or_value.is_a?(PIntegerType) ? size_type_or_value.to_size : size_type_or_value
1524
+ end
1525
+
1526
+ def accept(visitor, guard)
1527
+ super
1528
+ @size_type_or_value.accept(visitor, guard) if @size_type_or_value.is_a?(PIntegerType)
1529
+ end
1530
+
1531
+ def generalize
1532
+ DEFAULT
1533
+ end
1534
+
1535
+ def hash
1536
+ @size_type_or_value.hash
1537
+ end
1538
+
1539
+ def iterable?(guard = nil)
1540
+ true
1541
+ end
1542
+
1543
+ def iterable_type(guard = nil)
1544
+ ITERABLE_TYPE
1545
+ end
1546
+
1547
+ def eql?(o)
1548
+ self.class == o.class && @size_type_or_value == o.size_type_or_value
1549
+ end
1550
+
1551
+ def instance?(o, guard = nil)
1552
+ # true if size compliant
1553
+ if o.is_a?(String)
1554
+ if @size_type_or_value.is_a?(PIntegerType)
1555
+ @size_type_or_value.instance?(o.size, guard)
1556
+ else
1557
+ @size_type_or_value.nil? ? true : o == value
1558
+ end
1559
+ else
1560
+ false
1561
+ end
1562
+ end
1563
+
1564
+ def value
1565
+ @size_type_or_value.is_a?(PIntegerType) ? nil : @size_type_or_value
1566
+ end
1567
+
1568
+ # @deprecated
1569
+ # @api private
1570
+ def values
1571
+ if Puppet[:strict] != :off
1572
+ # TRANSLATORS 'PStringType#values' and '#value' are classes and method names and should not be translated
1573
+ Puppet.warn_once('deprecations', "PStringType#values", _("Method PStringType#values is deprecated. Use #value instead"))
1574
+ end
1575
+ @value.is_a?(String) ? [@value] : EMPTY_ARRAY
1576
+ end
1577
+
1578
+ def size_type
1579
+ @size_type_or_value.is_a?(PIntegerType) ? @size_type_or_value : nil
1580
+ end
1581
+
1582
+ def derived_size_type
1583
+ case @size_type_or_value
1584
+ when PIntegerType
1585
+ @size_type_or_value
1586
+ when String
1587
+ sz = @size_type_or_value.size
1588
+ PIntegerType.new(sz, sz)
1589
+ else
1590
+ PCollectionType::DEFAULT_SIZE
1591
+ end
1592
+ end
1593
+
1594
+ def self.new_function(type)
1595
+ @new_function ||= Puppet::Functions.create_loaded_function(:new_string, type.loader) do
1596
+ local_types do
1597
+ type "Format = Pattern[/#{StringConverter::Format::FMT_PATTERN_STR}/]"
1598
+ type 'ContainerFormat = Struct[{
1599
+ Optional[format] => Format,
1600
+ Optional[separator] => String,
1601
+ Optional[separator2] => String,
1602
+ Optional[string_formats] => Hash[Type, Format]
1603
+ }]'
1604
+ type 'TypeMap = Hash[Type, Variant[Format, ContainerFormat]]'
1605
+ type 'Convertible = Any'
1606
+ type 'Formats = Variant[Default, String[1], TypeMap]'
1607
+ end
1608
+
1609
+ dispatch :from_args do
1610
+ param 'Convertible', :from
1611
+ optional_param 'Formats', :string_formats
1612
+ end
1613
+
1614
+ def from_args(from, formats = :default)
1615
+ StringConverter.singleton.convert(from, formats)
1616
+ end
1617
+ end
1618
+ end
1619
+
1620
+ DEFAULT = PStringType.new(nil)
1621
+ NON_EMPTY = PStringType.new(PCollectionType::NOT_EMPTY_SIZE)
1622
+
1623
+ # Iterates over each character of the string
1624
+ ITERABLE_TYPE = PIterableType.new(PStringType.new(PIntegerType.new(1, 1)))
1625
+
1626
+ protected
1627
+
1628
+ # @api private
1629
+ def _assignable?(o, guard)
1630
+ if @size_type_or_value.is_a?(PIntegerType)
1631
+ # A general string is assignable by any other string or pattern restricted string
1632
+ # if the string has a size constraint it does not match since there is no reasonable way
1633
+ # to compute the min/max length a pattern will match. For enum, it is possible to test that
1634
+ # each enumerator value is within range
1635
+ case o
1636
+ when PStringType
1637
+ @size_type_or_value.assignable?(o.derived_size_type, guard)
1638
+
1639
+ when PEnumType
1640
+ if o.values.empty?
1641
+ # enum represents all enums, and thus all strings, a sized constrained string can thus not
1642
+ # be assigned any enum (unless it is max size).
1643
+ @size_type_or_value.assignable?(PCollectionType::DEFAULT_SIZE, guard)
1644
+ else
1645
+ # true if all enum values are within range
1646
+ orange = o.values.map(&:size).minmax
1647
+ srange = @size_type_or_value.range
1648
+ # If o min and max are within the range of t
1649
+ srange[0] <= orange[0] && srange[1] >= orange[1]
1650
+ end
1651
+
1652
+ when PPatternType
1653
+ # true if size constraint is at least 0 to +Infinity (which is the same as the default)
1654
+ @size_type_or_value.assignable?(PCollectionType::DEFAULT_SIZE, guard)
1655
+ else
1656
+ # no other type matches string
1657
+ false
1658
+ end
1659
+ else
1660
+ case o
1661
+ when PStringType
1662
+ # Must match exactly when value is a string
1663
+ @size_type_or_value.nil? || @size_type_or_value == o.size_type_or_value
1664
+ when PEnumType
1665
+ @size_type_or_value.nil? ? true : o.values.size == 1 && !o.case_insensitive? && o.values[0]
1666
+ when PPatternType
1667
+ @size_type_or_value.nil?
1668
+ else
1669
+ # All others are false, since no other type describes the same set of specific strings
1670
+ false
1671
+ end
1672
+ end
1673
+ end
1674
+ end
1675
+
1676
+ # @api public
1677
+ #
1678
+ class PRegexpType < PScalarType
1679
+ def self.register_ptype(loader, ir)
1680
+ create_ptype(loader, ir, 'ScalarType',
1681
+ 'pattern' => {
1682
+ KEY_TYPE => PVariantType.new([PUndefType::DEFAULT, PStringType::DEFAULT, PRegexpType::DEFAULT]),
1683
+ KEY_VALUE => nil
1684
+ })
1685
+ end
1686
+
1687
+ # Returns a new function that produces a Regexp instance
1688
+ #
1689
+ def self.new_function(type)
1690
+ @new_function ||= Puppet::Functions.create_loaded_function(:new_float, type.loader) do
1691
+ dispatch :from_string do
1692
+ param 'String', :pattern
1693
+ optional_param 'Boolean', :escape
1694
+ end
1695
+
1696
+ def from_string(pattern, escape = false)
1697
+ Regexp.new(escape ? Regexp.escape(pattern) : pattern)
1698
+ end
1699
+ end
1700
+ end
1701
+
1702
+ attr_reader :pattern
1703
+
1704
+ # @param regexp [Regexp] the regular expression
1705
+ # @return [String] the Regexp as a slash delimited string with slashes escaped
1706
+ def self.regexp_to_s_with_delimiters(regexp)
1707
+ regexp.options == 0 ? regexp.inspect : "/#{regexp}/"
1708
+ end
1709
+
1710
+ # @param regexp [Regexp] the regular expression
1711
+ # @return [String] the Regexp as a string without escaped slash
1712
+ def self.regexp_to_s(regexp)
1713
+ append_flags_group(regexp.source, regexp.options)
1714
+ end
1715
+
1716
+ def self.append_flags_group(rx_string, options)
1717
+ if options == 0
1718
+ rx_string
1719
+ else
1720
+ bld = '(?'.dup
1721
+ bld << 'i' if (options & Regexp::IGNORECASE) != 0
1722
+ bld << 'm' if (options & Regexp::MULTILINE) != 0
1723
+ bld << 'x' if (options & Regexp::EXTENDED) != 0
1724
+ unless options == (Regexp::IGNORECASE | Regexp::MULTILINE | Regexp::EXTENDED)
1725
+ bld << '-'
1726
+ bld << 'i' if (options & Regexp::IGNORECASE) == 0
1727
+ bld << 'm' if (options & Regexp::MULTILINE) == 0
1728
+ bld << 'x' if (options & Regexp::EXTENDED) == 0
1729
+ end
1730
+ bld << ':' << rx_string << ')'
1731
+ bld.freeze
1732
+ end
1733
+ end
1734
+
1735
+ def initialize(pattern)
1736
+ if pattern.is_a?(Regexp)
1737
+ @regexp = pattern
1738
+ @pattern = PRegexpType.regexp_to_s(pattern)
1739
+ else
1740
+ @pattern = pattern
1741
+ end
1742
+ end
1743
+
1744
+ def regexp
1745
+ @regexp ||= Regexp.new(@pattern || '')
1746
+ end
1747
+
1748
+ def hash
1749
+ @pattern.hash
1750
+ end
1751
+
1752
+ def eql?(o)
1753
+ self.class == o.class && @pattern == o.pattern
1754
+ end
1755
+
1756
+ def instance?(o, guard = nil)
1757
+ o.is_a?(Regexp) && @pattern.nil? || regexp == o
1758
+ end
1759
+
1760
+ DEFAULT = PRegexpType.new(nil)
1761
+
1762
+ protected
1763
+
1764
+ # @api private
1765
+ #
1766
+ def _assignable?(o, guard)
1767
+ o.is_a?(PRegexpType) && (@pattern.nil? || @pattern == o.pattern)
1768
+ end
1769
+ end
1770
+
1771
+ # Represents a subtype of String that narrows the string to those matching the patterns
1772
+ # If specified without a pattern it is basically the same as the String type.
1773
+ #
1774
+ # @api public
1775
+ #
1776
+ class PPatternType < PScalarDataType
1777
+ def self.register_ptype(loader, ir)
1778
+ create_ptype(loader, ir, 'ScalarDataType', 'patterns' => PArrayType.new(PRegexpType::DEFAULT))
1779
+ end
1780
+
1781
+ attr_reader :patterns
1782
+
1783
+ def initialize(patterns)
1784
+ @patterns = patterns.freeze
1785
+ end
1786
+
1787
+ def accept(visitor, guard)
1788
+ super
1789
+ @patterns.each { |p| p.accept(visitor, guard) }
1790
+ end
1791
+
1792
+ def hash
1793
+ @patterns.hash
1794
+ end
1795
+
1796
+ def eql?(o)
1797
+ self.class == o.class && @patterns.size == o.patterns.size && (@patterns - o.patterns).empty?
1798
+ end
1799
+
1800
+ def instance?(o, guard = nil)
1801
+ o.is_a?(String) && (@patterns.empty? || @patterns.any? { |p| p.regexp.match(o) })
1802
+ end
1803
+
1804
+ DEFAULT = PPatternType.new(EMPTY_ARRAY)
1805
+
1806
+ protected
1807
+
1808
+ # @api private
1809
+ #
1810
+ def _assignable?(o, guard)
1811
+ return true if self == o
1812
+
1813
+ case o
1814
+ when PStringType
1815
+ v = o.value
1816
+ if v.nil?
1817
+ # Strings cannot all match a pattern, but if there is no pattern it is ok
1818
+ # (There should really always be a pattern, but better safe than sorry).
1819
+ @patterns.empty?
1820
+ else
1821
+ # the string in String type must match one of the patterns in Pattern type,
1822
+ # or Pattern represents all Patterns == all Strings
1823
+ regexps = @patterns.map(&:regexp)
1824
+ regexps.empty? || regexps.any? { |re| re.match(v) }
1825
+ end
1826
+ when PEnumType
1827
+ if o.values.empty?
1828
+ # Enums (unknown which ones) cannot all match a pattern, but if there is no pattern it is ok
1829
+ # (There should really always be a pattern, but better safe than sorry).
1830
+ @patterns.empty?
1831
+ else
1832
+ # all strings in String/Enum type must match one of the patterns in Pattern type,
1833
+ # or Pattern represents all Patterns == all Strings
1834
+ regexps = @patterns.map(&:regexp)
1835
+ regexps.empty? || o.values.all? { |s| regexps.any? { |re| re.match(s) } }
1836
+ end
1837
+ when PPatternType
1838
+ @patterns.empty?
1839
+ else
1840
+ false
1841
+ end
1842
+ end
1843
+ end
1844
+
1845
+ # @api public
1846
+ #
1847
+ class PBooleanType < PScalarDataType
1848
+ def self.register_ptype(loader, ir)
1849
+ create_ptype(loader, ir, 'ScalarDataType')
1850
+ end
1851
+
1852
+ attr_reader :value
1853
+
1854
+ def initialize(value = nil)
1855
+ @value = value
1856
+ end
1857
+
1858
+ def eql?(o)
1859
+ o.is_a?(PBooleanType) && @value == o.value
1860
+ end
1861
+
1862
+ def generalize
1863
+ PBooleanType::DEFAULT
1864
+ end
1865
+
1866
+ def hash
1867
+ 31 ^ @value.hash
1868
+ end
1869
+
1870
+ def instance?(o, guard = nil)
1871
+ (o == true || o == false) && (@value.nil? || value == o)
1872
+ end
1873
+
1874
+ def self.new_function(type)
1875
+ @new_function ||= Puppet::Functions.create_loaded_function(:new_boolean, type.loader) do
1876
+ dispatch :from_args do
1877
+ param "Variant[Integer, Float, Boolean, Enum['false','true','yes','no','y','n',true]]", :from
1878
+ end
1879
+
1880
+ argument_mismatch :on_error do
1881
+ param 'Any', :from
1882
+ end
1883
+
1884
+ def from_args(from)
1885
+ from = from.downcase if from.is_a?(String)
1886
+ case from
1887
+ when Float, Integer
1888
+ !from.zero?
1889
+ when false, 'false', 'no', 'n'
1890
+ false
1891
+ else
1892
+ true
1893
+ end
1894
+ end
1895
+
1896
+ def on_error(from)
1897
+ if from.is_a?(String)
1898
+ _("The string '%{str}' cannot be converted to Boolean") % { str: from }
1899
+ else
1900
+ t = TypeCalculator.singleton.infer(from).generalize
1901
+ _("Value of type %{type} cannot be converted to Boolean") % { type: t }
1902
+ end
1903
+ end
1904
+ end
1905
+ end
1906
+
1907
+ DEFAULT = PBooleanType.new
1908
+ TRUE = PBooleanType.new(true)
1909
+ FALSE = PBooleanType.new(false)
1910
+
1911
+ protected
1912
+
1913
+ # @api private
1914
+ #
1915
+ def _assignable?(o, guard)
1916
+ o.is_a?(PBooleanType) && (@value.nil? || @value == o.value)
1917
+ end
1918
+ end
1919
+
1920
+ # @api public
1921
+ #
1922
+ # @api public
1923
+ #
1924
+ class PStructElement < TypedModelObject
1925
+ def self.register_ptype(loader, ir)
1926
+ @type = Pcore.create_object_type(loader, ir, self, 'Pcore::StructElement', nil,
1927
+ 'key_type' => PTypeType::DEFAULT,
1928
+ 'value_type' => PTypeType::DEFAULT)
1929
+ end
1930
+
1931
+ attr_accessor :key_type, :value_type
1932
+
1933
+ def accept(visitor, guard)
1934
+ @key_type.accept(visitor, guard)
1935
+ @value_type.accept(visitor, guard)
1936
+ end
1937
+
1938
+ def hash
1939
+ value_type.hash ^ key_type.hash
1940
+ end
1941
+
1942
+ def name
1943
+ k = key_type
1944
+ k = k.optional_type if k.is_a?(POptionalType)
1945
+ k.value
1946
+ end
1947
+
1948
+ def initialize(key_type, value_type)
1949
+ @key_type = key_type
1950
+ @value_type = value_type
1951
+ end
1952
+
1953
+ def generalize
1954
+ gv_type = @value_type.generalize
1955
+ @value_type.equal?(gv_type) ? self : PStructElement.new(@key_type, gv_type)
1956
+ end
1957
+
1958
+ def normalize(guard = nil)
1959
+ nv_type = @value_type.normalize(guard)
1960
+ @value_type.equal?(nv_type) ? self : PStructElement.new(@key_type, nv_type)
1961
+ end
1962
+
1963
+ def resolve(loader)
1964
+ rkey_type = @key_type.resolve(loader)
1965
+ rvalue_type = @value_type.resolve(loader)
1966
+ rkey_type.equal?(@key_type) && rvalue_type.equal?(@value_type) ? self : self.class.new(rkey_type, rvalue_type)
1967
+ end
1968
+
1969
+ def <=>(o)
1970
+ name <=> o.name
1971
+ end
1972
+
1973
+ def eql?(o)
1974
+ self == o
1975
+ end
1976
+
1977
+ def ==(o)
1978
+ self.class == o.class && value_type == o.value_type && key_type == o.key_type
1979
+ end
1980
+
1981
+ # Special boostrap method to overcome the hen and egg problem with the Object initializer that contains
1982
+ # types that are derived from Object (such as Annotation)
1983
+ #
1984
+ # @api private
1985
+ def replace_value_type(new_type)
1986
+ @value_type = new_type
1987
+ end
1988
+ end
1989
+
1990
+ # @api public
1991
+ #
1992
+ class PStructType < PAnyType
1993
+ include Enumerable
1994
+
1995
+ def self.register_ptype(loader, ir)
1996
+ create_ptype(loader, ir, 'AnyType', 'elements' => PArrayType.new(PTypeReferenceType.new('Pcore::StructElement')))
1997
+ end
1998
+
1999
+ def initialize(elements)
2000
+ @elements = elements.freeze
2001
+ end
2002
+
2003
+ def accept(visitor, guard)
2004
+ super
2005
+ @elements.each { |elem| elem.accept(visitor, guard) }
2006
+ end
2007
+
2008
+ def each
2009
+ if block_given?
2010
+ elements.each { |elem| yield elem }
2011
+ else
2012
+ elements.to_enum
2013
+ end
2014
+ end
2015
+
2016
+ def generalize
2017
+ if @elements.empty?
2018
+ DEFAULT
2019
+ else
2020
+ alter_type_array(@elements, :generalize) { |altered| PStructType.new(altered) }
2021
+ end
2022
+ end
2023
+
2024
+ def normalize(guard = nil)
2025
+ if @elements.empty?
2026
+ DEFAULT
2027
+ else
2028
+ alter_type_array(@elements, :normalize, guard) { |altered| PStructType.new(altered) }
2029
+ end
2030
+ end
2031
+
2032
+ # rubocop:disable Naming/MemoizedInstanceVariableName
2033
+ def hashed_elements
2034
+ @hashed ||= @elements.each_with_object({}) { |e, memo| memo[e.name] = e; }
2035
+ end
2036
+ # rubocop:enable Naming/MemoizedInstanceVariableName
2037
+
2038
+ def hash
2039
+ @elements.hash
2040
+ end
2041
+
2042
+ def iterable?(guard = nil)
2043
+ true
2044
+ end
2045
+
2046
+ def iterable_type(guard = nil)
2047
+ if self == DEFAULT
2048
+ PIterableType.new(PHashType::DEFAULT_KEY_PAIR_TUPLE)
2049
+ else
2050
+ PIterableType.new(
2051
+ PTupleType.new([
2052
+ PVariantType.maybe_create(@elements.map(&:key_type)),
2053
+ PVariantType.maybe_create(@elements.map(&:value_type))
2054
+ ],
2055
+ PHashType::KEY_PAIR_TUPLE_SIZE)
2056
+ )
2057
+ end
2058
+ end
2059
+
2060
+ def resolve(loader)
2061
+ changed = false
2062
+ relements = @elements.map do |elem|
2063
+ relem = elem.resolve(loader)
2064
+ changed ||= !relem.equal?(elem)
2065
+ relem
2066
+ end
2067
+ changed ? self.class.new(relements) : self
2068
+ end
2069
+
2070
+ def eql?(o)
2071
+ self.class == o.class && @elements == o.elements
2072
+ end
2073
+
2074
+ def elements
2075
+ @elements
2076
+ end
2077
+
2078
+ def instance?(o, guard = nil)
2079
+ # The inferred type of a class derived from Hash is either Runtime or Object. It's not assignable to the Struct type.
2080
+ return false unless o.instance_of?(Hash)
2081
+
2082
+ matched = 0
2083
+ @elements.all? do |e|
2084
+ key = e.name
2085
+ v = o[key]
2086
+ if v.nil? && !o.include?(key)
2087
+ # Entry is missing. Only OK when key is optional
2088
+ e.key_type.assignable?(PUndefType::DEFAULT, guard)
2089
+ else
2090
+ matched += 1
2091
+ e.value_type.instance?(v, guard)
2092
+ end
2093
+ end && matched == o.size
2094
+ end
2095
+
2096
+ def new_function
2097
+ # Simply delegate to Hash type and let the higher level assertion deal with
2098
+ # compliance with the Struct type regarding the produced result.
2099
+ PHashType.new_function(self)
2100
+ end
2101
+
2102
+ DEFAULT = PStructType.new(EMPTY_ARRAY)
2103
+
2104
+ protected
2105
+
2106
+ # @api private
2107
+ def _assignable?(o, guard)
2108
+ case o
2109
+ when Types::PStructType
2110
+ h2 = o.hashed_elements
2111
+ matched = 0
2112
+ elements.all? do |e1|
2113
+ e2 = h2[e1.name]
2114
+ if e2.nil?
2115
+ e1.key_type.assignable?(PUndefType::DEFAULT, guard)
2116
+ else
2117
+ matched += 1
2118
+ e1.key_type.assignable?(e2.key_type, guard) && e1.value_type.assignable?(e2.value_type, guard)
2119
+ end
2120
+ end && matched == h2.size
2121
+ when Types::PHashType
2122
+ required = 0
2123
+ required_elements_assignable = elements.all? do |e|
2124
+ key_type = e.key_type
2125
+ if key_type.assignable?(PUndefType::DEFAULT)
2126
+ # Element is optional so Hash does not need to provide it
2127
+ true
2128
+ else
2129
+ required += 1
2130
+ if e.value_type.assignable?(o.value_type, guard)
2131
+ # Hash must have something that is assignable. We don't care about the name or size of the key though
2132
+ # because we have no instance of a hash to compare against.
2133
+ key_type.generalize.assignable?(o.key_type)
2134
+ else
2135
+ false
2136
+ end
2137
+ end
2138
+ end
2139
+ if required_elements_assignable
2140
+ size_o = o.size_type || PCollectionType::DEFAULT_SIZE
2141
+ PIntegerType.new(required, elements.size).assignable?(size_o, guard)
2142
+ else
2143
+ false
2144
+ end
2145
+ else
2146
+ false
2147
+ end
2148
+ end
2149
+ end
2150
+
2151
+ # @api public
2152
+ #
2153
+ class PTupleType < PAnyType
2154
+ include Enumerable
2155
+
2156
+ def self.register_ptype(loader, ir)
2157
+ create_ptype(loader, ir, 'AnyType',
2158
+ 'types' => PArrayType.new(PTypeType::DEFAULT),
2159
+ 'size_type' => {
2160
+ KEY_TYPE => POptionalType.new(PTypeType.new(PIntegerType::DEFAULT)),
2161
+ KEY_VALUE => nil
2162
+ })
2163
+ end
2164
+
2165
+ # If set, describes min and max required of the given types - if max > size of
2166
+ # types, the last type entry repeats
2167
+ #
2168
+ attr_reader :size_type
2169
+
2170
+ attr_reader :types
2171
+
2172
+ def accept(visitor, guard)
2173
+ super
2174
+ @size_type.accept(visitor, guard) unless @size_type.nil?
2175
+ @types.each { |elem| elem.accept(visitor, guard) }
2176
+ end
2177
+
2178
+ # @api private
2179
+ def callable_args?(callable_t, guard)
2180
+ unless size_type.nil?
2181
+ raise ArgumentError, 'Callable tuple may not have a size constraint when used as args'
2182
+ end
2183
+
2184
+ params_tuple = callable_t.param_types
2185
+ param_block_t = callable_t.block_type
2186
+ arg_types = @types
2187
+ arg_block_t = arg_types.last
2188
+ if arg_block_t.kind_of_callable?(true, guard)
2189
+ # Can't pass a block to a callable that doesn't accept one
2190
+ return false if param_block_t.nil?
2191
+
2192
+ # Check that the block is of the right tyṕe
2193
+ return false unless param_block_t.assignable?(arg_block_t, guard)
2194
+
2195
+ # Check other arguments
2196
+ arg_count = arg_types.size - 1
2197
+ params_size_t = params_tuple.size_type || PIntegerType.new(*params_tuple.size_range)
2198
+ return false unless params_size_t.assignable?(PIntegerType.new(arg_count, arg_count), guard)
2199
+
2200
+ ctypes = params_tuple.types
2201
+ arg_count.times do |index|
2202
+ return false unless (ctypes[index] || ctypes[-1]).assignable?(arg_types[index], guard)
2203
+ end
2204
+ return true
2205
+ end
2206
+
2207
+ # Check that tuple is assignable and that the block (if declared) is optional
2208
+ params_tuple.assignable?(self, guard) && (param_block_t.nil? || param_block_t.assignable?(PUndefType::DEFAULT, guard))
2209
+ end
2210
+
2211
+ def initialize(types, size_type = nil)
2212
+ @types = types
2213
+ @size_type = size_type.nil? ? nil : size_type.to_size
2214
+ end
2215
+
2216
+ # Returns Enumerator for the types if no block is given, otherwise, calls the given
2217
+ # block with each of the types in this tuple
2218
+ def each
2219
+ if block_given?
2220
+ types.each { |x| yield x }
2221
+ else
2222
+ types.to_enum
2223
+ end
2224
+ end
2225
+
2226
+ def generalize
2227
+ if self == DEFAULT
2228
+ DEFAULT
2229
+ else
2230
+ alter_type_array(@types, :generalize) { |altered_types| PTupleType.new(altered_types, @size_type) }
2231
+ end
2232
+ end
2233
+
2234
+ def normalize(guard = nil)
2235
+ if self == DEFAULT
2236
+ DEFAULT
2237
+ else
2238
+ alter_type_array(@types, :normalize, guard) { |altered_types| PTupleType.new(altered_types, @size_type) }
2239
+ end
2240
+ end
2241
+
2242
+ def resolve(loader)
2243
+ changed = false
2244
+ rtypes = @types.map do |type|
2245
+ rtype = type.resolve(loader)
2246
+ changed ||= !rtype.equal?(type)
2247
+ rtype
2248
+ end
2249
+ changed ? self.class.new(rtypes, @size_type) : self
2250
+ end
2251
+
2252
+ def instance?(o, guard = nil)
2253
+ # The inferred type of a class derived from Array is either Runtime or Object. It's not assignable to the Tuple type.
2254
+ return false unless o.instance_of?(Array)
2255
+
2256
+ if @size_type
2257
+ return false unless @size_type.instance?(o.size, guard)
2258
+ else
2259
+ return false unless @types.empty? || @types.size == o.size
2260
+ end
2261
+ index = -1
2262
+ @types.empty? || o.all? do |element|
2263
+ @types.fetch(index += 1) { @types.last }.instance?(element, guard)
2264
+ end
2265
+ end
2266
+
2267
+ def iterable?(guard = nil)
2268
+ true
2269
+ end
2270
+
2271
+ def iterable_type(guard = nil)
2272
+ PIterableType.new(PVariantType.maybe_create(types))
2273
+ end
2274
+
2275
+ # Returns the number of elements accepted [min, max] in the tuple
2276
+ def size_range
2277
+ if @size_type.nil?
2278
+ types_size = @types.size
2279
+ types_size == 0 ? [0, Float::INFINITY] : [types_size, types_size]
2280
+ else
2281
+ @size_type.range
2282
+ end
2283
+ end
2284
+
2285
+ # Returns the number of accepted occurrences [min, max] of the last type in the tuple
2286
+ # The defaults is [1,1]
2287
+ #
2288
+ def repeat_last_range
2289
+ if @size_type.nil?
2290
+ return [1, 1]
2291
+ end
2292
+
2293
+ types_size = @types.size
2294
+ from, to = @size_type.range
2295
+ min = from - (types_size - 1)
2296
+ min = min <= 0 ? 0 : min
2297
+ max = to - (types_size - 1)
2298
+ [min, max]
2299
+ end
2300
+
2301
+ def hash
2302
+ @size_type.hash ^ @types.hash
2303
+ end
2304
+
2305
+ def eql?(o)
2306
+ self.class == o.class && @types == o.types && @size_type == o.size_type
2307
+ end
2308
+
2309
+ def new_function
2310
+ # Simply delegate to Array type and let the higher level assertion deal with
2311
+ # compliance with the Tuple type regarding the produced result.
2312
+ PArrayType.new_function(self)
2313
+ end
2314
+
2315
+ DEFAULT = PTupleType.new(EMPTY_ARRAY)
2316
+
2317
+ protected
2318
+
2319
+ # @api private
2320
+ def _assignable?(o, guard)
2321
+ return true if self == o
2322
+ return false unless o.is_a?(PTupleType) || o.is_a?(PArrayType)
2323
+
2324
+ s_types = types
2325
+ size_s = size_type || PIntegerType.new(*size_range)
2326
+
2327
+ if o.is_a?(PTupleType)
2328
+ size_o = o.size_type || PIntegerType.new(*o.size_range)
2329
+ return false unless size_s.assignable?(size_o, guard)
2330
+
2331
+ unless s_types.empty?
2332
+ o_types = o.types
2333
+ return size_s.numeric_from == 0 if o_types.empty?
2334
+
2335
+ o_types.size.times do |index|
2336
+ return false unless (s_types[index] || s_types[-1]).assignable?(o_types[index], guard)
2337
+ end
2338
+ end
2339
+ else
2340
+ size_o = o.size_type || PCollectionType::DEFAULT_SIZE
2341
+ return false unless size_s.assignable?(size_o, guard)
2342
+
2343
+ unless s_types.empty?
2344
+ o_entry = o.element_type
2345
+ # Array of anything can not be assigned (unless tuple is tuple of anything) - this case
2346
+ # was handled at the top of this method.
2347
+ #
2348
+ return false if o_entry.nil?
2349
+
2350
+ [s_types.size, size_o.range[1]].min.times { |index| return false unless (s_types[index] || s_types[-1]).assignable?(o_entry, guard) }
2351
+ end
2352
+ end
2353
+ true
2354
+ end
2355
+ end
2356
+
2357
+ # @api public
2358
+ #
2359
+ class PCallableType < PAnyType
2360
+ def self.register_ptype(loader, ir)
2361
+ create_ptype(loader, ir, 'AnyType',
2362
+ 'param_types' => {
2363
+ KEY_TYPE => POptionalType.new(PTypeType.new(PTupleType::DEFAULT)),
2364
+ KEY_VALUE => nil
2365
+ },
2366
+ 'block_type' => {
2367
+ KEY_TYPE => POptionalType.new(PTypeType.new(PCallableType::DEFAULT)),
2368
+ KEY_VALUE => nil
2369
+ },
2370
+ 'return_type' => {
2371
+ KEY_TYPE => POptionalType.new(PTypeType::DEFAULT),
2372
+ KEY_VALUE => PAnyType::DEFAULT
2373
+ })
2374
+ end
2375
+
2376
+ # @return [PAnyType] The type for the values returned by this callable. Returns `nil` if return value is unconstrained
2377
+ attr_reader :return_type
2378
+
2379
+ # Types of parameters as a Tuple with required/optional count, or an Integer with min (required), max count
2380
+ # @return [PTupleType] the tuple representing the parameter types
2381
+ attr_reader :param_types
2382
+
2383
+ # Although being an abstract type reference, only Callable, or all Callables wrapped in
2384
+ # Optional or Variant are supported
2385
+ # If not set, the meaning is that block is not supported.
2386
+ # @return [PAnyType|nil] the block type
2387
+ attr_reader :block_type
2388
+
2389
+ # @param param_types [PTupleType]
2390
+ # @param block_type [PAnyType]
2391
+ # @param return_type [PAnyType]
2392
+ def initialize(param_types, block_type = nil, return_type = nil)
2393
+ @param_types = param_types
2394
+ @block_type = block_type
2395
+ @return_type = return_type == PAnyType::DEFAULT ? nil : return_type
2396
+ end
2397
+
2398
+ def accept(visitor, guard)
2399
+ super
2400
+ @param_types.accept(visitor, guard) unless @param_types.nil?
2401
+ @block_type.accept(visitor, guard) unless @block_type.nil?
2402
+ @return_type.accept(visitor, guard) unless @return_type.nil?
2403
+ end
2404
+
2405
+ def generalize
2406
+ if self == DEFAULT
2407
+ DEFAULT
2408
+ else
2409
+ params_t = @param_types.nil? ? nil : @param_types.generalize
2410
+ block_t = @block_type.nil? ? nil : @block_type.generalize
2411
+ return_t = @return_type.nil? ? nil : @return_type.generalize
2412
+ @param_types.equal?(params_t) && @block_type.equal?(block_t) && @return_type.equal?(return_t) ? self : PCallableType.new(params_t, block_t, return_t)
2413
+ end
2414
+ end
2415
+
2416
+ def normalize(guard = nil)
2417
+ if self == DEFAULT
2418
+ DEFAULT
2419
+ else
2420
+ params_t = @param_types.nil? ? nil : @param_types.normalize(guard)
2421
+ block_t = @block_type.nil? ? nil : @block_type.normalize(guard)
2422
+ return_t = @return_type.nil? ? nil : @return_type.normalize(guard)
2423
+ @param_types.equal?(params_t) && @block_type.equal?(block_t) && @return_type.equal?(return_t) ? self : PCallableType.new(params_t, block_t, return_t)
2424
+ end
2425
+ end
2426
+
2427
+ def instance?(o, guard = nil)
2428
+ (o.is_a?(Proc) || o.is_a?(Evaluator::Closure) || o.is_a?(Functions::Function)) && assignable?(TypeCalculator.infer(o), guard)
2429
+ end
2430
+
2431
+ # Returns `true` if this instance is a callable that accepts the given _args_
2432
+ #
2433
+ # @param args [Array] the arguments to test
2434
+ # @return [Boolean] `true` if this instance is a callable that accepts the given _args_
2435
+ def callable_with?(args, block = nil)
2436
+ # nil param_types and compatible return type means other Callable is assignable
2437
+ return true if @param_types.nil?
2438
+ return false unless @param_types.instance?(args)
2439
+
2440
+ if @block_type.nil?
2441
+ block.nil?
2442
+ else
2443
+ @block_type.instance?(block)
2444
+ end
2445
+ end
2446
+
2447
+ # @api private
2448
+ def callable_args?(required_callable_t, guard)
2449
+ # If the required callable is equal or more specific than self, self is acceptable arguments
2450
+ required_callable_t.assignable?(self, guard)
2451
+ end
2452
+
2453
+ def kind_of_callable?(optional = true, guard = nil)
2454
+ true
2455
+ end
2456
+
2457
+ # Returns the number of accepted arguments [min, max]
2458
+ def size_range
2459
+ @param_types.nil? ? nil : @param_types.size_range
2460
+ end
2461
+
2462
+ # Returns the number of accepted arguments for the last parameter type [min, max]
2463
+ #
2464
+ def last_range
2465
+ @param_types.nil? ? nil : @param_types.repeat_last_range
2466
+ end
2467
+
2468
+ # Range [0,0], [0,1], or [1,1] for the block
2469
+ #
2470
+ def block_range
2471
+ case block_type
2472
+ when POptionalType
2473
+ [0, 1]
2474
+ when PVariantType, PCallableType
2475
+ [1, 1]
2476
+ else
2477
+ [0, 0]
2478
+ end
2479
+ end
2480
+
2481
+ def hash
2482
+ [@param_types, @block_type, @return_type].hash
2483
+ end
2484
+
2485
+ def eql?(o)
2486
+ self.class == o.class && @param_types == o.param_types && @block_type == o.block_type && @return_type == o.return_type
2487
+ end
2488
+
2489
+ def resolve(loader)
2490
+ params_t = @param_types.nil? ? nil : @param_types.resolve(loader)
2491
+ block_t = @block_type.nil? ? nil : @block_type.resolve(loader)
2492
+ return_t = @return_type.nil? ? nil : @return_type.resolve(loader)
2493
+ @param_types.equal?(params_t) && @block_type.equal?(block_t) && @return_type.equal?(return_t) ? self : self.class.new(params_t, block_t, return_t)
2494
+ end
2495
+
2496
+ DEFAULT = PCallableType.new(nil, nil, nil)
2497
+
2498
+ protected
2499
+
2500
+ # @api private
2501
+ def _assignable?(o, guard)
2502
+ return false unless o.is_a?(PCallableType)
2503
+ return false unless @return_type.nil? || @return_type.assignable?(o.return_type || PAnyType::DEFAULT, guard)
2504
+
2505
+ # nil param_types and compatible return type means other Callable is assignable
2506
+ return true if @param_types.nil?
2507
+
2508
+ # NOTE: these tests are made in reverse as it is calling the callable that is constrained
2509
+ # (it's lower bound), not its upper bound
2510
+ other_param_types = o.param_types
2511
+
2512
+ return false if other_param_types.nil? || !other_param_types.assignable?(@param_types, guard)
2513
+
2514
+ # names are ignored, they are just information
2515
+ # Blocks must be compatible
2516
+ this_block_t = @block_type || PUndefType::DEFAULT
2517
+ that_block_t = o.block_type || PUndefType::DEFAULT
2518
+ that_block_t.assignable?(this_block_t, guard)
2519
+ end
2520
+ end
2521
+
2522
+ # @api public
2523
+ #
2524
+ class PArrayType < PCollectionType
2525
+ def self.register_ptype(loader, ir)
2526
+ create_ptype(loader, ir, 'CollectionType',
2527
+ 'element_type' => {
2528
+ KEY_TYPE => POptionalType.new(PTypeType::DEFAULT),
2529
+ KEY_VALUE => PAnyType::DEFAULT
2530
+ })
2531
+ end
2532
+
2533
+ attr_reader :element_type
2534
+
2535
+ def initialize(element_type, size_type = nil)
2536
+ super(size_type)
2537
+ if !size_type.nil? && size_type.from == 0 && size_type.to == 0
2538
+ @element_type = PUnitType::DEFAULT
2539
+ else
2540
+ @element_type = element_type.nil? ? PAnyType::DEFAULT : element_type
2541
+ end
2542
+ end
2543
+
2544
+ def accept(visitor, guard)
2545
+ super
2546
+ @element_type.accept(visitor, guard)
2547
+ end
2548
+
2549
+ # @api private
2550
+ def callable_args?(callable, guard = nil)
2551
+ param_t = callable.param_types
2552
+ block_t = callable.block_type
2553
+ # does not support calling with a block, but have to check that callable is ok with missing block
2554
+ (param_t.nil? || param_t.assignable?(self, guard)) && (block_t.nil? || block_t.assignable?(PUndefType::DEFAULT, guard))
2555
+ end
2556
+
2557
+ def generalize
2558
+ if PAnyType::DEFAULT.eql?(@element_type)
2559
+ DEFAULT
2560
+ else
2561
+ ge_type = @element_type.generalize
2562
+ @size_type.nil? && @element_type.equal?(ge_type) ? self : self.class.new(ge_type, nil)
2563
+ end
2564
+ end
2565
+
2566
+ def eql?(o)
2567
+ super && @element_type == o.element_type
2568
+ end
2569
+
2570
+ def hash
2571
+ super ^ @element_type.hash
2572
+ end
2573
+
2574
+ def normalize(guard = nil)
2575
+ if PAnyType::DEFAULT.eql?(@element_type)
2576
+ DEFAULT
2577
+ else
2578
+ ne_type = @element_type.normalize(guard)
2579
+ @element_type.equal?(ne_type) ? self : self.class.new(ne_type, @size_type)
2580
+ end
2581
+ end
2582
+
2583
+ def resolve(loader)
2584
+ relement_type = @element_type.resolve(loader)
2585
+ relement_type.equal?(@element_type) ? self : self.class.new(relement_type, @size_type)
2586
+ end
2587
+
2588
+ def instance?(o, guard = nil)
2589
+ # The inferred type of a class derived from Array is either Runtime or Object. It's not assignable to the Array type.
2590
+ return false unless o.instance_of?(Array)
2591
+ return false unless o.all? { |element| @element_type.instance?(element, guard) }
2592
+
2593
+ size_t = size_type
2594
+ size_t.nil? || size_t.instance?(o.size, guard)
2595
+ end
2596
+
2597
+ def iterable_type(guard = nil)
2598
+ PAnyType::DEFAULT.eql?(@element_type) ? PIterableType::DEFAULT : PIterableType.new(@element_type)
2599
+ end
2600
+
2601
+ # Returns a new function that produces an Array
2602
+ #
2603
+ def self.new_function(type)
2604
+ @new_function ||= Puppet::Functions.create_loaded_function(:new_array, type.loader) do
2605
+ dispatch :to_array do
2606
+ param 'Variant[Array,Hash,Binary,Iterable]', :from
2607
+ optional_param 'Boolean[false]', :wrap
2608
+ end
2609
+
2610
+ dispatch :wrapped do
2611
+ param 'Any', :from
2612
+ param 'Boolean[true]', :wrap
2613
+ end
2614
+
2615
+ argument_mismatch :on_error do
2616
+ param 'Any', :from
2617
+ optional_param 'Boolean', :wrap
2618
+ end
2619
+
2620
+ def wrapped(from, _)
2621
+ from.is_a?(Array) ? from : [from]
2622
+ end
2623
+
2624
+ def to_array(from, _ = false)
2625
+ case from
2626
+ when Array
2627
+ from
2628
+ when Hash
2629
+ from.to_a
2630
+ when PBinaryType::Binary
2631
+ # For older rubies, the #bytes method returns an Enumerator that must be rolled out
2632
+ from.binary_buffer.bytes.to_a
2633
+ else
2634
+ Iterable.on(from).to_a
2635
+ end
2636
+ end
2637
+
2638
+ def on_error(from, _ = false)
2639
+ t = TypeCalculator.singleton.infer(from).generalize
2640
+ _("Value of type %{type} cannot be converted to Array") % { type: t }
2641
+ end
2642
+ end
2643
+ end
2644
+
2645
+ DEFAULT = PArrayType.new(nil)
2646
+ EMPTY = PArrayType.new(PUnitType::DEFAULT, ZERO_SIZE)
2647
+
2648
+ protected
2649
+
2650
+ # Array is assignable if o is an Array and o's element type is assignable, or if o is a Tuple
2651
+ # @api private
2652
+ def _assignable?(o, guard)
2653
+ case o
2654
+ when PTupleType
2655
+ o_types = o.types
2656
+ size_s = size_type || DEFAULT_SIZE
2657
+ size_o = o.size_type
2658
+ if size_o.nil?
2659
+ type_count = o_types.size
2660
+ size_o = PIntegerType.new(type_count, type_count)
2661
+ end
2662
+ size_s.assignable?(size_o) && o_types.all? { |ot| @element_type.assignable?(ot, guard) }
2663
+ when PArrayType
2664
+ super && @element_type.assignable?(o.element_type, guard)
2665
+ else
2666
+ false
2667
+ end
2668
+ end
2669
+ end
2670
+
2671
+ # @api public
2672
+ #
2673
+ class PHashType < PCollectionType
2674
+ def self.register_ptype(loader, ir)
2675
+ create_ptype(loader, ir, 'CollectionType',
2676
+ 'key_type' => {
2677
+ KEY_TYPE => POptionalType.new(PTypeType::DEFAULT),
2678
+ KEY_VALUE => PAnyType::DEFAULT
2679
+ },
2680
+ 'value_type' => {
2681
+ KEY_TYPE => POptionalType.new(PTypeType::DEFAULT),
2682
+ KEY_VALUE => PAnyType::DEFAULT
2683
+ })
2684
+ end
2685
+
2686
+ attr_accessor :key_type, :value_type
2687
+
2688
+ def initialize(key_type, value_type, size_type = nil)
2689
+ super(size_type)
2690
+ if !size_type.nil? && size_type.from == 0 && size_type.to == 0
2691
+ @key_type = PUnitType::DEFAULT
2692
+ @value_type = PUnitType::DEFAULT
2693
+ else
2694
+ @key_type = key_type.nil? ? PAnyType::DEFAULT : key_type
2695
+ @value_type = value_type.nil? ? PAnyType::DEFAULT : value_type
2696
+ end
2697
+ end
2698
+
2699
+ def accept(visitor, guard)
2700
+ super
2701
+ @key_type.accept(visitor, guard)
2702
+ @value_type.accept(visitor, guard)
2703
+ end
2704
+
2705
+ def element_type
2706
+ if Puppet[:strict] != :off
2707
+ # TRANSLATOR 'Puppet::Pops::Types::PHashType#element_type' and '#value_type' are class and method names and should not be translated
2708
+ Puppet.warn_once('deprecations', 'Puppet::Pops::Types::PHashType#element_type',
2709
+ _('Puppet::Pops::Types::PHashType#element_type is deprecated, use #value_type instead'))
2710
+ end
2711
+ @value_type
2712
+ end
2713
+
2714
+ def generalize
2715
+ if self == DEFAULT || self == EMPTY
2716
+ self
2717
+ else
2718
+ key_t = @key_type
2719
+ key_t = key_t.generalize
2720
+ value_t = @value_type
2721
+ value_t = value_t.generalize
2722
+ @size_type.nil? && @key_type.equal?(key_t) && @value_type.equal?(value_t) ? self : PHashType.new(key_t, value_t, nil)
2723
+ end
2724
+ end
2725
+
2726
+ def normalize(guard = nil)
2727
+ if self == DEFAULT || self == EMPTY
2728
+ self
2729
+ else
2730
+ key_t = @key_type.normalize(guard)
2731
+ value_t = @value_type.normalize(guard)
2732
+ @size_type.nil? && @key_type.equal?(key_t) && @value_type.equal?(value_t) ? self : PHashType.new(key_t, value_t, @size_type)
2733
+ end
2734
+ end
2735
+
2736
+ def hash
2737
+ super ^ @key_type.hash ^ @value_type.hash
2738
+ end
2739
+
2740
+ def instance?(o, guard = nil)
2741
+ # The inferred type of a class derived from Hash is either Runtime or Object. It's not assignable to the Hash type.
2742
+ return false unless o.instance_of?(Hash)
2743
+
2744
+ if o.keys.all? { |key| @key_type.instance?(key, guard) } && o.values.all? { |value| @value_type.instance?(value, guard) }
2745
+ size_t = size_type
2746
+ size_t.nil? || size_t.instance?(o.size, guard)
2747
+ else
2748
+ false
2749
+ end
2750
+ end
2751
+
2752
+ def iterable?(guard = nil)
2753
+ true
2754
+ end
2755
+
2756
+ def iterable_type(guard = nil)
2757
+ if self == DEFAULT || self == EMPTY
2758
+ PIterableType.new(DEFAULT_KEY_PAIR_TUPLE)
2759
+ else
2760
+ PIterableType.new(PTupleType.new([@key_type, @value_type], KEY_PAIR_TUPLE_SIZE))
2761
+ end
2762
+ end
2763
+
2764
+ def eql?(o)
2765
+ super && @key_type == o.key_type && @value_type == o.value_type
2766
+ end
2767
+
2768
+ def is_the_empty_hash?
2769
+ self == EMPTY
2770
+ end
2771
+
2772
+ def resolve(loader)
2773
+ rkey_type = @key_type.resolve(loader)
2774
+ rvalue_type = @value_type.resolve(loader)
2775
+ rkey_type.equal?(@key_type) && rvalue_type.equal?(@value_type) ? self : self.class.new(rkey_type, rvalue_type, @size_type)
2776
+ end
2777
+
2778
+ def self.array_as_hash(value)
2779
+ return value unless value.is_a?(Array)
2780
+
2781
+ result = {}
2782
+ value.each_with_index { |v, idx| result[idx] = array_as_hash(v) }
2783
+ result
2784
+ end
2785
+
2786
+ # Returns a new function that produces a Hash
2787
+ #
2788
+ def self.new_function(type)
2789
+ @new_function ||= Puppet::Functions.create_loaded_function(:new_hash, type.loader) do
2790
+ local_types do
2791
+ type 'KeyValueArray = Array[Tuple[Any,Any],1]'
2792
+ type 'TreeArray = Array[Tuple[Array,Any],1]'
2793
+ type 'NewHashOption = Enum[tree, hash_tree]'
2794
+ end
2795
+
2796
+ dispatch :from_tree do
2797
+ param 'TreeArray', :from
2798
+ optional_param 'NewHashOption', :build_option
2799
+ end
2800
+
2801
+ dispatch :from_tuples do
2802
+ param 'KeyValueArray', :from
2803
+ end
2804
+
2805
+ dispatch :from_array do
2806
+ param 'Any', :from
2807
+ end
2808
+
2809
+ def from_tuples(tuple_array)
2810
+ tuple_array.to_h
2811
+ end
2812
+
2813
+ def from_tree(tuple_array, build_option = nil)
2814
+ if build_option.nil?
2815
+ return from_tuples(tuple_array)
2816
+ end
2817
+
2818
+ # only remaining possible options is 'tree' or 'hash_tree'
2819
+
2820
+ all_hashes = build_option == 'hash_tree'
2821
+ result = {}
2822
+ tuple_array.each do |entry|
2823
+ path = entry[0]
2824
+ value = entry[1]
2825
+ if path.empty?
2826
+ # root node (index [] was included - values merge into the result)
2827
+ # An array must be changed to a hash first as this is the root
2828
+ # (Cannot return an array from a Hash.new)
2829
+ if value.is_a?(Array)
2830
+ value.each_with_index { |v, idx| result[idx] = v }
2831
+ else
2832
+ result.merge!(value)
2833
+ end
2834
+ else
2835
+ r = path[0..-2].reduce(result) { |memo, idx| (memo.is_a?(Array) || memo.has_key?(idx)) ? memo[idx] : memo[idx] = {} }
2836
+ r[path[-1]] = (all_hashes ? PHashType.array_as_hash(value) : value)
2837
+ end
2838
+ end
2839
+ result
2840
+ end
2841
+
2842
+ def from_array(from)
2843
+ case from
2844
+ when Array
2845
+ if from.size == 0
2846
+ {}
2847
+ else
2848
+ unless from.size.even?
2849
+ raise TypeConversionError, _('odd number of arguments for Hash')
2850
+ end
2851
+
2852
+ Hash[*from]
2853
+ end
2854
+ when Hash
2855
+ from
2856
+ else
2857
+ if PIterableType::DEFAULT.instance?(from)
2858
+ Hash[*Iterable.on(from).to_a]
2859
+ else
2860
+ t = TypeCalculator.singleton.infer(from).generalize
2861
+ raise TypeConversionError, _("Value of type %{type} cannot be converted to Hash") % { type: t }
2862
+ end
2863
+ end
2864
+ end
2865
+ end
2866
+ end
2867
+
2868
+ DEFAULT = PHashType.new(nil, nil)
2869
+ KEY_PAIR_TUPLE_SIZE = PIntegerType.new(2, 2)
2870
+ DEFAULT_KEY_PAIR_TUPLE = PTupleType.new([PUnitType::DEFAULT, PUnitType::DEFAULT], KEY_PAIR_TUPLE_SIZE)
2871
+ EMPTY = PHashType.new(PUnitType::DEFAULT, PUnitType::DEFAULT, PIntegerType.new(0, 0))
2872
+
2873
+ protected
2874
+
2875
+ # Hash is assignable if o is a Hash and o's key and element types are assignable
2876
+ # @api private
2877
+ def _assignable?(o, guard)
2878
+ case o
2879
+ when PHashType
2880
+ size_s = size_type
2881
+ return true if (size_s.nil? || size_s.from == 0) && o.is_the_empty_hash?
2882
+ return false unless @key_type.assignable?(o.key_type, guard) && @value_type.assignable?(o.value_type, guard)
2883
+
2884
+ super
2885
+ when PStructType
2886
+ # hash must accept String as key type
2887
+ # hash must accept all value types
2888
+ # hash must accept the size of the struct
2889
+ o_elements = o.elements
2890
+ (size_type || DEFAULT_SIZE).instance?(o_elements.size, guard) &&
2891
+ o_elements.all? { |e| @key_type.instance?(e.name, guard) && @value_type.assignable?(e.value_type, guard) }
2892
+ else
2893
+ false
2894
+ end
2895
+ end
2896
+ end
2897
+
2898
+ # A flexible type describing an any? of other types
2899
+ # @api public
2900
+ #
2901
+ class PVariantType < PAnyType
2902
+ include Enumerable
2903
+
2904
+ def self.register_ptype(loader, ir)
2905
+ create_ptype(loader, ir, 'AnyType', 'types' => PArrayType.new(PTypeType::DEFAULT))
2906
+ end
2907
+
2908
+ attr_reader :types
2909
+
2910
+ # Checks if the number of unique types in the given array is greater than one, and if so
2911
+ # creates a Variant with those types and returns it. If only one unique type is found,
2912
+ # that type is instead returned.
2913
+ #
2914
+ # @param types [Array<PAnyType>] the variants
2915
+ # @return [PAnyType] the resulting type
2916
+ # @api public
2917
+ def self.maybe_create(types)
2918
+ types = flatten_variants(types).uniq
2919
+ types.size == 1 ? types[0] : new(types)
2920
+ end
2921
+
2922
+ # @param types [Array[PAnyType]] the variants
2923
+ def initialize(types)
2924
+ @types = types.freeze
2925
+ end
2926
+
2927
+ def accept(visitor, guard)
2928
+ super
2929
+ @types.each { |t| t.accept(visitor, guard) }
2930
+ end
2931
+
2932
+ def each
2933
+ if block_given?
2934
+ types.each { |t| yield t }
2935
+ else
2936
+ types.to_enum
2937
+ end
2938
+ end
2939
+
2940
+ def generalize
2941
+ if self == DEFAULT
2942
+ self
2943
+ else
2944
+ alter_type_array(@types, :generalize) { |altered| PVariantType.maybe_create(altered) }
2945
+ end
2946
+ end
2947
+
2948
+ def normalize(guard = nil)
2949
+ if self == DEFAULT || @types.empty?
2950
+ self
2951
+ else
2952
+ # Normalize all contained types
2953
+ modified = false
2954
+ types = alter_type_array(@types, :normalize, guard)
2955
+ if types == self
2956
+ types = @types
2957
+ else
2958
+ modified = true
2959
+ end
2960
+
2961
+ if types.size == 1
2962
+ types[0]
2963
+ elsif types.any? { |t| t.is_a?(PUndefType) || t.is_a?(POptionalType) }
2964
+ # Undef entry present. Use an OptionalType with a normalized Variant without Undefs and Optional wrappers
2965
+ POptionalType.new(PVariantType.maybe_create(types.reject { |t| t.is_a?(PUndefType) }.map { |t| t.is_a?(POptionalType) ? t.type : t })).normalize
2966
+ else
2967
+ # Merge all variants into this one
2968
+ types = PVariantType.flatten_variants(types)
2969
+ size_before_merge = types.size
2970
+
2971
+ types = swap_not_undefs(types)
2972
+ types = merge_enums(types)
2973
+ types = merge_patterns(types)
2974
+ types = merge_version_ranges(types)
2975
+ types = merge_numbers(PIntegerType, types)
2976
+ types = merge_numbers(PFloatType, types)
2977
+ types = merge_numbers(PTimespanType, types)
2978
+ types = merge_numbers(PTimestampType, types)
2979
+
2980
+ if types.size == 1
2981
+ types[0]
2982
+ else
2983
+ modified || types.size != size_before_merge ? PVariantType.maybe_create(types) : self
2984
+ end
2985
+ end
2986
+ end
2987
+ end
2988
+
2989
+ def self.flatten_variants(types)
2990
+ modified = false
2991
+ types = types.map do |t|
2992
+ if t.is_a?(PVariantType)
2993
+ modified = true
2994
+ t.types
2995
+ else
2996
+ t
2997
+ end
2998
+ end
2999
+ types.flatten! if modified
3000
+ types
3001
+ end
3002
+
3003
+ def hash
3004
+ @types.hash
3005
+ end
3006
+
3007
+ def instance?(o, guard = nil)
3008
+ # instance of variant if o is instance? of any of variant's types
3009
+ @types.any? { |type| type.instance?(o, guard) }
3010
+ end
3011
+
3012
+ def really_instance?(o, guard = nil)
3013
+ @types.reduce(-1) do |memo, type|
3014
+ ri = type.really_instance?(o, guard)
3015
+ break ri if ri > 0
3016
+
3017
+ ri > memo ? ri : memo
3018
+ end
3019
+ end
3020
+
3021
+ def kind_of_callable?(optional = true, guard = nil)
3022
+ @types.all? { |type| type.kind_of_callable?(optional, guard) }
3023
+ end
3024
+
3025
+ def eql?(o)
3026
+ self.class == o.class && @types.size == o.types.size && (@types - o.types).empty?
3027
+ end
3028
+
3029
+ DEFAULT = PVariantType.new(EMPTY_ARRAY)
3030
+
3031
+ def assignable?(o, guard = nil)
3032
+ # an empty Variant does not match Undef (it is void - not even undef)
3033
+ if o.is_a?(PUndefType) && types.empty?
3034
+ return false
3035
+ end
3036
+
3037
+ return super unless o.is_a?(PVariantType)
3038
+ # If empty, all Variant types match irrespective of the types they hold (including being empty)
3039
+ return true if types.empty?
3040
+
3041
+ # Since this variant is not empty, an empty Variant cannot match, because it matches nothing
3042
+ # otherwise all types in o must be assignable to this
3043
+ !o.types.empty? && o.types.all? { |vt| super(vt, guard) }
3044
+ end
3045
+
3046
+ protected
3047
+
3048
+ # @api private
3049
+ def _assignable?(o, guard)
3050
+ # A variant is assignable if o is assignable to any of its types
3051
+ types.any? { |option_t| option_t.assignable?(o, guard) }
3052
+ end
3053
+
3054
+ # @api private
3055
+ def swap_not_undefs(array)
3056
+ if array.size > 1
3057
+ parts = array.partition { |t| t.is_a?(PNotUndefType) }
3058
+ not_undefs = parts[0]
3059
+ if not_undefs.size > 1
3060
+ others = parts[1]
3061
+ others << PNotUndefType.new(PVariantType.maybe_create(not_undefs.map(&:type)).normalize)
3062
+ array = others
3063
+ end
3064
+ end
3065
+ array
3066
+ end
3067
+
3068
+ # @api private
3069
+ def merge_enums(array)
3070
+ # Merge case sensitive enums and strings
3071
+ if array.size > 1
3072
+ parts = array.partition { |t| t.is_a?(PEnumType) && !t.values.empty? && !t.case_insensitive? || t.is_a?(PStringType) && !t.value.nil? }
3073
+ enums = parts[0]
3074
+ if enums.size > 1
3075
+ others = parts[1]
3076
+ others << PEnumType.new(enums.map { |enum| enum.is_a?(PStringType) ? enum.value : enum.values }.flatten.uniq)
3077
+ array = others
3078
+ end
3079
+ end
3080
+
3081
+ # Merge case insensitive enums
3082
+ if array.size > 1
3083
+ parts = array.partition { |t| t.is_a?(PEnumType) && !t.values.empty? && t.case_insensitive? }
3084
+ enums = parts[0]
3085
+ if enums.size > 1
3086
+ others = parts[1]
3087
+ values = []
3088
+ enums.each { |enum| enum.values.each { |value| values << value.downcase } }
3089
+ values.uniq!
3090
+ others << PEnumType.new(values, true)
3091
+ array = others
3092
+ end
3093
+ end
3094
+ array
3095
+ end
3096
+
3097
+ # @api private
3098
+ def merge_patterns(array)
3099
+ if array.size > 1
3100
+ parts = array.partition { |t| t.is_a?(PPatternType) }
3101
+ patterns = parts[0]
3102
+ if patterns.size > 1
3103
+ others = parts[1]
3104
+ others << PPatternType.new(patterns.map(&:patterns).flatten.uniq)
3105
+ array = others
3106
+ end
3107
+ end
3108
+ array
3109
+ end
3110
+
3111
+ # @api private
3112
+ def merge_numbers(clazz, array)
3113
+ if array.size > 1
3114
+ parts = array.partition { |t| t.is_a?(clazz) }
3115
+ ranges = parts[0]
3116
+ array = merge_ranges(ranges) + parts[1] if ranges.size > 1
3117
+ end
3118
+ array
3119
+ end
3120
+
3121
+ def merge_version_ranges(array)
3122
+ if array.size > 1
3123
+ parts = array.partition { |t| t.is_a?(PSemVerType) }
3124
+ ranges = parts[0]
3125
+ array = [PSemVerType.new(ranges.map(&:ranges).flatten)] + parts[1] if ranges.size > 1
3126
+ end
3127
+ array
3128
+ end
3129
+
3130
+ # @api private
3131
+ def merge_ranges(ranges)
3132
+ result = []
3133
+ until ranges.empty?
3134
+ unmerged = []
3135
+ x = ranges.pop
3136
+ result << ranges.inject(x) do |memo, y|
3137
+ merged = memo.merge(y)
3138
+ if merged.nil?
3139
+ unmerged << y
3140
+ else
3141
+ memo = merged
3142
+ end
3143
+ memo
3144
+ end
3145
+ ranges = unmerged
3146
+ end
3147
+ result
3148
+ end
3149
+ end
3150
+
3151
+ # Abstract representation of a type that can be placed in a Catalog.
3152
+ # @api public
3153
+ #
3154
+ class PCatalogEntryType < PAnyType
3155
+ def self.register_ptype(loader, ir)
3156
+ create_ptype(loader, ir, 'AnyType')
3157
+ end
3158
+
3159
+ DEFAULT = PCatalogEntryType.new
3160
+
3161
+ def instance?(o, guard = nil)
3162
+ assignable?(TypeCalculator.infer(o), guard)
3163
+ end
3164
+
3165
+ protected
3166
+
3167
+ # @api private
3168
+ def _assignable?(o, guard)
3169
+ o.is_a?(PCatalogEntryType)
3170
+ end
3171
+ end
3172
+
3173
+ # Represents a (host-) class in the Puppet Language.
3174
+ # @api public
3175
+ #
3176
+ class PClassType < PCatalogEntryType
3177
+ attr_reader :class_name
3178
+
3179
+ def self.register_ptype(loader, ir)
3180
+ create_ptype(loader, ir, 'CatalogEntryType',
3181
+ 'class_name' => {
3182
+ KEY_TYPE => POptionalType.new(PStringType::NON_EMPTY),
3183
+ KEY_VALUE => nil
3184
+ })
3185
+ end
3186
+
3187
+ def initialize(class_name)
3188
+ @class_name = class_name
3189
+ end
3190
+
3191
+ def hash
3192
+ 11 ^ @class_name.hash
3193
+ end
3194
+
3195
+ def eql?(o)
3196
+ self.class == o.class && @class_name == o.class_name
3197
+ end
3198
+
3199
+ DEFAULT = PClassType.new(nil)
3200
+
3201
+ protected
3202
+
3203
+ # @api private
3204
+ def _assignable?(o, guard)
3205
+ return false unless o.is_a?(PClassType)
3206
+ # Class = Class[name}, Class[name] != Class
3207
+ return true if @class_name.nil?
3208
+
3209
+ # Class[name] = Class[name]
3210
+ @class_name == o.class_name
3211
+ end
3212
+ end
3213
+
3214
+ # For backward compatibility
3215
+ PHostClassType = PClassType
3216
+
3217
+ # Represents a Resource Type in the Puppet Language
3218
+ # @api public
3219
+ #
3220
+ class PResourceType < PCatalogEntryType
3221
+ def self.register_ptype(loader, ir)
3222
+ create_ptype(loader, ir, 'CatalogEntryType',
3223
+ 'type_name' => {
3224
+ KEY_TYPE => POptionalType.new(PStringType::NON_EMPTY),
3225
+ KEY_VALUE => nil
3226
+ },
3227
+ 'title' => {
3228
+ KEY_TYPE => POptionalType.new(PStringType::NON_EMPTY),
3229
+ KEY_VALUE => nil
3230
+ })
3231
+ end
3232
+
3233
+ attr_reader :type_name, :title, :downcased_name
3234
+
3235
+ def initialize(type_name, title = nil)
3236
+ @type_name = type_name.freeze
3237
+ @title = title.freeze
3238
+ @downcased_name = type_name.nil? ? nil : @type_name.downcase.freeze
3239
+ end
3240
+
3241
+ def eql?(o)
3242
+ self.class == o.class && @downcased_name == o.downcased_name && @title == o.title
3243
+ end
3244
+
3245
+ def hash
3246
+ @downcased_name.hash ^ @title.hash
3247
+ end
3248
+
3249
+ DEFAULT = PResourceType.new(nil)
3250
+
3251
+ protected
3252
+
3253
+ # @api private
3254
+ def _assignable?(o, guard)
3255
+ o.is_a?(PResourceType) && (@downcased_name.nil? || @downcased_name == o.downcased_name && (@title.nil? || @title == o.title))
3256
+ end
3257
+ end
3258
+
3259
+ # Represents a type that accept PUndefType instead of the type parameter
3260
+ # required_type - is a short hand for Variant[T, Undef]
3261
+ # @api public
3262
+ #
3263
+ class POptionalType < PTypeWithContainedType
3264
+ def self.register_ptype(loader, ir)
3265
+ create_ptype(loader, ir, 'AnyType',
3266
+ 'type' => {
3267
+ KEY_TYPE => POptionalType.new(PTypeType::DEFAULT),
3268
+ KEY_VALUE => nil
3269
+ })
3270
+ end
3271
+
3272
+ def optional_type
3273
+ @type
3274
+ end
3275
+
3276
+ def kind_of_callable?(optional = true, guard = nil)
3277
+ optional && !@type.nil? && @type.kind_of_callable?(optional, guard)
3278
+ end
3279
+
3280
+ def instance?(o, guard = nil)
3281
+ PUndefType::DEFAULT.instance?(o, guard) || (!@type.nil? && @type.instance?(o, guard))
3282
+ end
3283
+
3284
+ def normalize(guard = nil)
3285
+ n = super
3286
+ if n.type.nil?
3287
+ n
3288
+ elsif n.type.is_a?(PNotUndefType)
3289
+ POptionalType.new(n.type.type).normalize
3290
+ # No point in having an NotUndef in an Optional
3291
+ elsif n.type.assignable?(PUndefType::DEFAULT)
3292
+ # THe type is Optional anyway, so it can be stripped of
3293
+ n.type
3294
+ else
3295
+ n
3296
+ end
3297
+ end
3298
+
3299
+ def new_function
3300
+ optional_type.new_function
3301
+ end
3302
+
3303
+ DEFAULT = POptionalType.new(nil)
3304
+
3305
+ protected
3306
+
3307
+ # @api private
3308
+ def _assignable?(o, guard)
3309
+ return true if o.is_a?(PUndefType)
3310
+ return true if @type.nil?
3311
+
3312
+ if o.is_a?(POptionalType)
3313
+ @type.assignable?(o.optional_type, guard)
3314
+ else
3315
+ @type.assignable?(o, guard)
3316
+ end
3317
+ end
3318
+ end
3319
+
3320
+ class PTypeReferenceType < PAnyType
3321
+ def self.register_ptype(loader, ir)
3322
+ create_ptype(loader, ir, 'AnyType', 'type_string' => PStringType::NON_EMPTY)
3323
+ end
3324
+
3325
+ attr_reader :type_string
3326
+
3327
+ def initialize(type_string)
3328
+ @type_string = type_string
3329
+ end
3330
+
3331
+ def callable?(args)
3332
+ false
3333
+ end
3334
+
3335
+ def instance?(o, guard = nil)
3336
+ false
3337
+ end
3338
+
3339
+ def hash
3340
+ @type_string.hash
3341
+ end
3342
+
3343
+ def eql?(o)
3344
+ super && o.type_string == @type_string
3345
+ end
3346
+
3347
+ def resolve(loader)
3348
+ TypeParser.singleton.parse(@type_string, loader)
3349
+ end
3350
+
3351
+ protected
3352
+
3353
+ def _assignable?(o, guard)
3354
+ # A type must be assignable to itself or a lot of unit tests will break
3355
+ o == self
3356
+ end
3357
+
3358
+ DEFAULT = PTypeReferenceType.new('UnresolvedReference')
3359
+ end
3360
+
3361
+ # Describes a named alias for another Type.
3362
+ # The alias is created with a name and an unresolved type expression. The type expression may
3363
+ # in turn contain other aliases (including the alias that contains it) which means that an alias
3364
+ # might contain self recursion. Whether or not that is the case is computed and remembered when the alias
3365
+ # is resolved since guarding against self recursive constructs is relatively expensive.
3366
+ #
3367
+ # @api public
3368
+ class PTypeAliasType < PAnyType
3369
+ def self.register_ptype(loader, ir)
3370
+ create_ptype(loader, ir, 'AnyType',
3371
+ 'name' => PStringType::NON_EMPTY,
3372
+ 'type_expr' => PAnyType::DEFAULT,
3373
+ 'resolved_type' => {
3374
+ KEY_TYPE => POptionalType.new(PTypeType::DEFAULT),
3375
+ KEY_VALUE => nil
3376
+ })
3377
+ end
3378
+
3379
+ attr_reader :loader, :name
3380
+
3381
+ # @param name [String] The name of the type
3382
+ # @param type_expr [Model::PopsObject] The expression that describes the aliased type
3383
+ # @param resolved_type [PAnyType] the resolve type (only used for the DEFAULT initialization)
3384
+ def initialize(name, type_expr, resolved_type = nil)
3385
+ @name = name
3386
+ @type_expr = type_expr
3387
+ @resolved_type = resolved_type
3388
+ @self_recursion = false
3389
+ end
3390
+
3391
+ def assignable?(o, guard = nil)
3392
+ if @self_recursion
3393
+ guard ||= RecursionGuard.new
3394
+ guard.with_this(self) { |state| state == RecursionGuard::SELF_RECURSION_IN_BOTH ? true : super(o, guard) }
3395
+ else
3396
+ super(o, guard)
3397
+ end
3398
+ end
3399
+
3400
+ # Returns the resolved type. The type must have been resolved by a call prior to calls to this
3401
+ # method or an error will be raised.
3402
+ #
3403
+ # @return [PAnyType] The resolved type of this alias.
3404
+ # @raise [Puppet::Error] unless the type has been resolved prior to calling this method
3405
+ def resolved_type
3406
+ raise Puppet::Error, "Reference to unresolved type #{@name}" unless @resolved_type
3407
+
3408
+ @resolved_type
3409
+ end
3410
+
3411
+ def callable_args?(callable, guard)
3412
+ guarded_recursion(guard, false) { |g| resolved_type.callable_args?(callable, g) }
3413
+ end
3414
+
3415
+ def check_self_recursion(originator)
3416
+ resolved_type.check_self_recursion(originator) unless originator.equal?(self)
3417
+ end
3418
+
3419
+ def kind_of_callable?(optional = true, guard = nil)
3420
+ guarded_recursion(guard, false) { |g| resolved_type.kind_of_callable?(optional, g) }
3421
+ end
3422
+
3423
+ def instance?(o, guard = nil)
3424
+ really_instance?(o, guard) == 1
3425
+ end
3426
+
3427
+ def iterable?(guard = nil)
3428
+ guarded_recursion(guard, false) { |g| resolved_type.iterable?(g) }
3429
+ end
3430
+
3431
+ def iterable_type(guard = nil)
3432
+ guarded_recursion(guard, nil) { |g| resolved_type.iterable_type(g) }
3433
+ end
3434
+
3435
+ def hash
3436
+ @name.hash
3437
+ end
3438
+
3439
+ # Acceptor used when checking for self recursion and that a type contains
3440
+ # something other than aliases or type references
3441
+ #
3442
+ # @api private
3443
+ class AssertOtherTypeAcceptor
3444
+ def initialize
3445
+ @other_type_detected = false
3446
+ end
3447
+
3448
+ def visit(type, _)
3449
+ unless type.is_a?(PTypeAliasType) || type.is_a?(PVariantType)
3450
+ @other_type_detected = true
3451
+ end
3452
+ end
3453
+
3454
+ def other_type_detected?
3455
+ @other_type_detected
3456
+ end
3457
+ end
3458
+
3459
+ # Acceptor used when re-checking for self recursion after a self recursion has been detected
3460
+ #
3461
+ # @api private
3462
+ class AssertSelfRecursionStatusAcceptor
3463
+ def visit(type, _)
3464
+ type.set_self_recursion_status if type.is_a?(PTypeAliasType)
3465
+ end
3466
+ end
3467
+
3468
+ def set_self_recursion_status
3469
+ return if @self_recursion || @resolved_type.is_a?(PTypeReferenceType)
3470
+
3471
+ @self_recursion = true
3472
+ guard = RecursionGuard.new
3473
+ accept(NoopTypeAcceptor::INSTANCE, guard)
3474
+ @self_recursion = guard.recursive_this?(self)
3475
+ when_self_recursion_detected if @self_recursion # no difference
3476
+ end
3477
+
3478
+ # Called from the TypeParser once it has found a type using the Loader. The TypeParser will
3479
+ # interpret the contained expression and the resolved type is remembered. This method also
3480
+ # checks and remembers if the resolve type contains self recursion.
3481
+ #
3482
+ # @param type_parser [TypeParser] type parser that will interpret the type expression
3483
+ # @param loader [Loader::Loader] loader to use when loading type aliases
3484
+ # @return [PTypeAliasType] the receiver of the call, i.e. `self`
3485
+ # @api private
3486
+ def resolve(loader)
3487
+ @loader = loader
3488
+ if @resolved_type.nil?
3489
+ # resolved to PTypeReferenceType::DEFAULT during resolve to avoid endless recursion
3490
+ @resolved_type = PTypeReferenceType::DEFAULT
3491
+ @self_recursion = true # assumed while it being found out below
3492
+ begin
3493
+ if @type_expr.is_a?(PTypeReferenceType)
3494
+ @resolved_type = @type_expr.resolve(loader)
3495
+ else
3496
+ @resolved_type = TypeParser.singleton.interpret(@type_expr, loader).normalize
3497
+ end
3498
+
3499
+ # Find out if this type is recursive. A recursive type has performance implications
3500
+ # on several methods and this knowledge is used to avoid that for non-recursive
3501
+ # types.
3502
+ guard = RecursionGuard.new
3503
+ real_type_asserter = AssertOtherTypeAcceptor.new
3504
+ accept(real_type_asserter, guard)
3505
+ unless real_type_asserter.other_type_detected?
3506
+ raise ArgumentError, "Type alias '#{name}' cannot be resolved to a real type"
3507
+ end
3508
+
3509
+ @self_recursion = guard.recursive_this?(self)
3510
+ # All aliases involved must re-check status since this alias is now resolved
3511
+ if @self_recursion
3512
+ accept(AssertSelfRecursionStatusAcceptor.new, RecursionGuard.new)
3513
+ when_self_recursion_detected
3514
+ end
3515
+ rescue
3516
+ @resolved_type = nil
3517
+ raise
3518
+ end
3519
+ else
3520
+ # An alias may appoint an Object type that isn't resolved yet. The default type
3521
+ # reference is used to prevent endless recursion and should not be resolved here.
3522
+ @resolved_type.resolve(loader) unless @resolved_type.equal?(PTypeReferenceType::DEFAULT)
3523
+ end
3524
+ self
3525
+ end
3526
+
3527
+ def eql?(o)
3528
+ super && o.name == @name
3529
+ end
3530
+
3531
+ def accept(visitor, guard)
3532
+ guarded_recursion(guard, nil) do |g|
3533
+ super(visitor, g)
3534
+ @resolved_type.accept(visitor, g) unless @resolved_type.nil?
3535
+ end
3536
+ end
3537
+
3538
+ def self_recursion?
3539
+ @self_recursion
3540
+ end
3541
+
3542
+ # Returns the expanded string the form of the alias, e.g. <alias name> = <resolved type>
3543
+ #
3544
+ # @return [String] the expanded form of this alias
3545
+ # @api public
3546
+ def to_s
3547
+ TypeFormatter.singleton.alias_expanded_string(self)
3548
+ end
3549
+
3550
+ # Delegates to resolved type
3551
+ def respond_to_missing?(name, include_private)
3552
+ resolved_type.respond_to?(name, include_private)
3553
+ end
3554
+
3555
+ # Delegates to resolved type
3556
+ def method_missing(name, *arguments, &block)
3557
+ super if @resolved_type.equal?(PTypeReferenceType::DEFAULT)
3558
+ resolved_type.send(name, *arguments, &block)
3559
+ end
3560
+
3561
+ # @api private
3562
+ def really_instance?(o, guard = nil)
3563
+ if @self_recursion
3564
+ guard ||= RecursionGuard.new
3565
+ guard.with_that(o) do
3566
+ guard.with_this(self) { |state| state == RecursionGuard::SELF_RECURSION_IN_BOTH ? 0 : resolved_type.really_instance?(o, guard) }
3567
+ end
3568
+ else
3569
+ resolved_type.really_instance?(o, guard)
3570
+ end
3571
+ end
3572
+
3573
+ # @return `nil` to prevent serialization of the type_expr used when first initializing this instance
3574
+ # @api private
3575
+ def type_expr
3576
+ nil
3577
+ end
3578
+
3579
+ protected
3580
+
3581
+ def _assignable?(o, guard)
3582
+ resolved_type.assignable?(o, guard)
3583
+ end
3584
+
3585
+ def new_function
3586
+ resolved_type.new_function
3587
+ end
3588
+
3589
+ private
3590
+
3591
+ def guarded_recursion(guard, dflt)
3592
+ if @self_recursion
3593
+ guard ||= RecursionGuard.new
3594
+ guard.with_this(self) { |state| (state & RecursionGuard::SELF_RECURSION_IN_THIS) == 0 ? yield(guard) : dflt }
3595
+ else
3596
+ yield(guard)
3597
+ end
3598
+ end
3599
+
3600
+ def when_self_recursion_detected
3601
+ if @resolved_type.is_a?(PVariantType)
3602
+ # Drop variants that are not real types
3603
+ resolved_types = @resolved_type.types
3604
+ real_types = resolved_types.select do |type|
3605
+ next false if type == self
3606
+
3607
+ real_type_asserter = AssertOtherTypeAcceptor.new
3608
+ type.accept(real_type_asserter, RecursionGuard.new)
3609
+ real_type_asserter.other_type_detected?
3610
+ end
3611
+ if real_types.size != resolved_types.size
3612
+ if real_types.size == 1
3613
+ @resolved_type = real_types[0]
3614
+ else
3615
+ @resolved_type = PVariantType.maybe_create(real_types)
3616
+ end
3617
+ # Drop self recursion status in case it's not self recursive anymore
3618
+ guard = RecursionGuard.new
3619
+ accept(NoopTypeAcceptor::INSTANCE, guard)
3620
+ @self_recursion = guard.recursive_this?(self)
3621
+ end
3622
+ end
3623
+ @resolved_type.check_self_recursion(self) if @self_recursion
3624
+ end
3625
+
3626
+ DEFAULT = PTypeAliasType.new('UnresolvedAlias', nil, PTypeReferenceType::DEFAULT)
3627
+ end
3628
+ end
3629
+ end
3630
+
3631
+ require_relative '../../../puppet/pops/pcore'
3632
+
3633
+ require_relative 'annotatable'
3634
+ require_relative 'p_meta_type'
3635
+ require_relative 'p_object_type'
3636
+ require_relative 'annotation'
3637
+ require_relative 'ruby_method'
3638
+ require_relative 'p_runtime_type'
3639
+ require_relative 'p_sem_ver_type'
3640
+ require_relative 'p_sem_ver_range_type'
3641
+ require_relative 'p_sensitive_type'
3642
+ require_relative 'p_type_set_type'
3643
+ require_relative 'p_timespan_type'
3644
+ require_relative 'p_timestamp_type'
3645
+ require_relative 'p_binary_type'
3646
+ require_relative 'p_init_type'
3647
+ require_relative 'p_object_type_extension'
3648
+ require_relative 'p_uri_type'
3649
+ require_relative 'type_set_reference'
3650
+ require_relative 'implementation_registry'
3651
+ require_relative 'tree_iterators'