rbs 4.1.0.pre.2-java

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 (574) hide show
  1. checksums.yaml +7 -0
  2. data/.clang-format +75 -0
  3. data/.clangd +2 -0
  4. data/.github/dependabot.yml +24 -0
  5. data/.github/workflows/bundle-update.yml +63 -0
  6. data/.github/workflows/c-check.yml +61 -0
  7. data/.github/workflows/comments.yml +37 -0
  8. data/.github/workflows/dependabot.yml +30 -0
  9. data/.github/workflows/jruby.yml +67 -0
  10. data/.github/workflows/milestone.yml +83 -0
  11. data/.github/workflows/ruby.yml +158 -0
  12. data/.github/workflows/rust.yml +184 -0
  13. data/.github/workflows/truffleruby.yml +54 -0
  14. data/.github/workflows/typecheck.yml +39 -0
  15. data/.github/workflows/wasm.yml +53 -0
  16. data/.github/workflows/windows.yml +49 -0
  17. data/.gitignore +38 -0
  18. data/.rubocop.yml +72 -0
  19. data/BSDL +22 -0
  20. data/CHANGELOG.md +2292 -0
  21. data/COPYING +56 -0
  22. data/README.md +240 -0
  23. data/Rakefile +869 -0
  24. data/Steepfile +53 -0
  25. data/config.yml +913 -0
  26. data/core/array.rbs +4142 -0
  27. data/core/basic_object.rbs +376 -0
  28. data/core/binding.rbs +148 -0
  29. data/core/builtin.rbs +278 -0
  30. data/core/class.rbs +223 -0
  31. data/core/comparable.rbs +192 -0
  32. data/core/complex.rbs +812 -0
  33. data/core/constants.rbs +96 -0
  34. data/core/data.rbs +415 -0
  35. data/core/dir.rbs +993 -0
  36. data/core/encoding.rbs +1368 -0
  37. data/core/enumerable.rbs +2506 -0
  38. data/core/enumerator/arithmetic_sequence.rbs +70 -0
  39. data/core/enumerator/product.rbs +92 -0
  40. data/core/enumerator.rbs +705 -0
  41. data/core/env.rbs +6 -0
  42. data/core/errno.rbs +682 -0
  43. data/core/errors.rbs +789 -0
  44. data/core/exception.rbs +485 -0
  45. data/core/false_class.rbs +82 -0
  46. data/core/fiber.rbs +570 -0
  47. data/core/fiber_error.rbs +11 -0
  48. data/core/file.rbs +2045 -0
  49. data/core/file_constants.rbs +463 -0
  50. data/core/file_stat.rbs +534 -0
  51. data/core/file_test.rbs +331 -0
  52. data/core/float.rbs +1316 -0
  53. data/core/gc.rbs +788 -0
  54. data/core/global_variables.rbs +184 -0
  55. data/core/hash.rbs +2183 -0
  56. data/core/integer.rbs +1374 -0
  57. data/core/io/buffer.rbs +995 -0
  58. data/core/io/wait.rbs +48 -0
  59. data/core/io.rbs +3472 -0
  60. data/core/kernel.rbs +3172 -0
  61. data/core/marshal.rbs +207 -0
  62. data/core/match_data.rbs +637 -0
  63. data/core/math.rbs +770 -0
  64. data/core/method.rbs +422 -0
  65. data/core/module.rbs +1856 -0
  66. data/core/nil_class.rbs +210 -0
  67. data/core/numeric.rbs +832 -0
  68. data/core/object.rbs +108 -0
  69. data/core/object_space/weak_key_map.rbs +166 -0
  70. data/core/object_space.rbs +197 -0
  71. data/core/pathname.rbs +1322 -0
  72. data/core/proc.rbs +905 -0
  73. data/core/process.rbs +2316 -0
  74. data/core/ractor.rbs +924 -0
  75. data/core/random.rbs +255 -0
  76. data/core/range.rbs +1209 -0
  77. data/core/rational.rbs +502 -0
  78. data/core/rb_config.rbs +88 -0
  79. data/core/rbs/ops.rbs +154 -0
  80. data/core/rbs/unnamed/argf.rbs +1236 -0
  81. data/core/rbs/unnamed/env_class.rbs +1214 -0
  82. data/core/rbs/unnamed/main_class.rbs +123 -0
  83. data/core/rbs/unnamed/random.rbs +186 -0
  84. data/core/refinement.rbs +59 -0
  85. data/core/regexp.rbs +1974 -0
  86. data/core/ruby.rbs +53 -0
  87. data/core/ruby_vm.rbs +809 -0
  88. data/core/rubygems/basic_specification.rbs +6 -0
  89. data/core/rubygems/config_file.rbs +38 -0
  90. data/core/rubygems/dependency_installer.rbs +6 -0
  91. data/core/rubygems/errors.rbs +109 -0
  92. data/core/rubygems/installer.rbs +15 -0
  93. data/core/rubygems/path_support.rbs +6 -0
  94. data/core/rubygems/platform.rbs +7 -0
  95. data/core/rubygems/request_set.rbs +49 -0
  96. data/core/rubygems/requirement.rbs +148 -0
  97. data/core/rubygems/rubygems.rbs +1105 -0
  98. data/core/rubygems/source_list.rbs +15 -0
  99. data/core/rubygems/specification.rbs +23 -0
  100. data/core/rubygems/stream_ui.rbs +5 -0
  101. data/core/rubygems/uninstaller.rbs +10 -0
  102. data/core/rubygems/version.rbs +293 -0
  103. data/core/set.rbs +751 -0
  104. data/core/signal.rbs +110 -0
  105. data/core/string.rbs +5532 -0
  106. data/core/struct.rbs +668 -0
  107. data/core/symbol.rbs +482 -0
  108. data/core/thread.rbs +1826 -0
  109. data/core/thread_group.rbs +79 -0
  110. data/core/time.rbs +1793 -0
  111. data/core/trace_point.rbs +483 -0
  112. data/core/true_class.rbs +98 -0
  113. data/core/unbound_method.rbs +337 -0
  114. data/core/warning.rbs +87 -0
  115. data/docs/CONTRIBUTING.md +107 -0
  116. data/docs/aliases.md +79 -0
  117. data/docs/architecture.md +110 -0
  118. data/docs/collection.md +192 -0
  119. data/docs/config.md +171 -0
  120. data/docs/data_and_struct.md +86 -0
  121. data/docs/encoding.md +56 -0
  122. data/docs/gem.md +56 -0
  123. data/docs/inline.md +634 -0
  124. data/docs/rbs_by_example.md +309 -0
  125. data/docs/repo.md +125 -0
  126. data/docs/rust.md +96 -0
  127. data/docs/sigs.md +167 -0
  128. data/docs/stdlib.md +147 -0
  129. data/docs/syntax.md +940 -0
  130. data/docs/tools.md +17 -0
  131. data/docs/type_fingerprint.md +21 -0
  132. data/docs/wasm_serialization.md +80 -0
  133. data/exe/rbs +7 -0
  134. data/ext/rbs_extension/ast_translation.c +1855 -0
  135. data/ext/rbs_extension/ast_translation.h +41 -0
  136. data/ext/rbs_extension/class_constants.c +187 -0
  137. data/ext/rbs_extension/class_constants.h +104 -0
  138. data/ext/rbs_extension/compat.h +10 -0
  139. data/ext/rbs_extension/extconf.rb +40 -0
  140. data/ext/rbs_extension/legacy_location.c +294 -0
  141. data/ext/rbs_extension/legacy_location.h +82 -0
  142. data/ext/rbs_extension/main.c +613 -0
  143. data/ext/rbs_extension/rbs_extension.h +16 -0
  144. data/ext/rbs_extension/rbs_string_bridging.c +9 -0
  145. data/ext/rbs_extension/rbs_string_bridging.h +24 -0
  146. data/goodcheck.yml +91 -0
  147. data/include/rbs/ast.h +1047 -0
  148. data/include/rbs/defines.h +99 -0
  149. data/include/rbs/lexer.h +207 -0
  150. data/include/rbs/location.h +40 -0
  151. data/include/rbs/parser.h +153 -0
  152. data/include/rbs/serialize.h +39 -0
  153. data/include/rbs/string.h +47 -0
  154. data/include/rbs/util/rbs_allocator.h +59 -0
  155. data/include/rbs/util/rbs_assert.h +20 -0
  156. data/include/rbs/util/rbs_buffer.h +83 -0
  157. data/include/rbs/util/rbs_constant_pool.h +155 -0
  158. data/include/rbs/util/rbs_encoding.h +282 -0
  159. data/include/rbs/util/rbs_unescape.h +24 -0
  160. data/include/rbs.h +14 -0
  161. data/lib/rbs/ancestor_graph.rb +92 -0
  162. data/lib/rbs/annotate/annotations.rb +199 -0
  163. data/lib/rbs/annotate/formatter.rb +82 -0
  164. data/lib/rbs/annotate/rdoc_annotator.rb +398 -0
  165. data/lib/rbs/annotate/rdoc_source.rb +131 -0
  166. data/lib/rbs/annotate.rb +8 -0
  167. data/lib/rbs/ast/annotation.rb +29 -0
  168. data/lib/rbs/ast/comment.rb +29 -0
  169. data/lib/rbs/ast/declarations.rb +472 -0
  170. data/lib/rbs/ast/directives.rb +49 -0
  171. data/lib/rbs/ast/members.rb +451 -0
  172. data/lib/rbs/ast/ruby/annotations.rb +451 -0
  173. data/lib/rbs/ast/ruby/comment_block.rb +247 -0
  174. data/lib/rbs/ast/ruby/declarations.rb +291 -0
  175. data/lib/rbs/ast/ruby/helpers/constant_helper.rb +28 -0
  176. data/lib/rbs/ast/ruby/helpers/location_helper.rb +15 -0
  177. data/lib/rbs/ast/ruby/members.rb +762 -0
  178. data/lib/rbs/ast/type_param.rb +235 -0
  179. data/lib/rbs/ast/visitor.rb +137 -0
  180. data/lib/rbs/buffer.rb +189 -0
  181. data/lib/rbs/builtin_names.rb +58 -0
  182. data/lib/rbs/cli/colored_io.rb +48 -0
  183. data/lib/rbs/cli/diff.rb +84 -0
  184. data/lib/rbs/cli/validate.rb +294 -0
  185. data/lib/rbs/cli.rb +1253 -0
  186. data/lib/rbs/collection/cleaner.rb +38 -0
  187. data/lib/rbs/collection/config/lockfile.rb +92 -0
  188. data/lib/rbs/collection/config/lockfile_generator.rb +269 -0
  189. data/lib/rbs/collection/config.rb +81 -0
  190. data/lib/rbs/collection/installer.rb +32 -0
  191. data/lib/rbs/collection/sources/base.rb +14 -0
  192. data/lib/rbs/collection/sources/git.rb +265 -0
  193. data/lib/rbs/collection/sources/local.rb +81 -0
  194. data/lib/rbs/collection/sources/rubygems.rb +48 -0
  195. data/lib/rbs/collection/sources/stdlib.rb +50 -0
  196. data/lib/rbs/collection/sources.rb +38 -0
  197. data/lib/rbs/collection.rb +16 -0
  198. data/lib/rbs/constant.rb +28 -0
  199. data/lib/rbs/definition.rb +415 -0
  200. data/lib/rbs/definition_builder/ancestor_builder.rb +678 -0
  201. data/lib/rbs/definition_builder/method_builder.rb +295 -0
  202. data/lib/rbs/definition_builder.rb +1054 -0
  203. data/lib/rbs/diff.rb +131 -0
  204. data/lib/rbs/environment/class_entry.rb +69 -0
  205. data/lib/rbs/environment/module_entry.rb +66 -0
  206. data/lib/rbs/environment/use_map.rb +77 -0
  207. data/lib/rbs/environment.rb +1028 -0
  208. data/lib/rbs/environment_loader.rb +167 -0
  209. data/lib/rbs/environment_walker.rb +155 -0
  210. data/lib/rbs/errors.rb +634 -0
  211. data/lib/rbs/factory.rb +18 -0
  212. data/lib/rbs/file_finder.rb +28 -0
  213. data/lib/rbs/inline_parser/comment_association.rb +117 -0
  214. data/lib/rbs/inline_parser.rb +568 -0
  215. data/lib/rbs/location_aux.rb +170 -0
  216. data/lib/rbs/locator.rb +247 -0
  217. data/lib/rbs/method_type.rb +145 -0
  218. data/lib/rbs/namespace.rb +154 -0
  219. data/lib/rbs/parser/lex_result.rb +15 -0
  220. data/lib/rbs/parser/token.rb +23 -0
  221. data/lib/rbs/parser_aux.rb +142 -0
  222. data/lib/rbs/prototype/helpers.rb +197 -0
  223. data/lib/rbs/prototype/node_usage.rb +99 -0
  224. data/lib/rbs/prototype/rb.rb +816 -0
  225. data/lib/rbs/prototype/rbi.rb +625 -0
  226. data/lib/rbs/prototype/runtime/helpers.rb +59 -0
  227. data/lib/rbs/prototype/runtime/reflection.rb +19 -0
  228. data/lib/rbs/prototype/runtime/value_object_generator.rb +279 -0
  229. data/lib/rbs/prototype/runtime.rb +680 -0
  230. data/lib/rbs/repository.rb +127 -0
  231. data/lib/rbs/resolver/constant_resolver.rb +219 -0
  232. data/lib/rbs/resolver/type_name_resolver.rb +167 -0
  233. data/lib/rbs/rewriter.rb +70 -0
  234. data/lib/rbs/sorter.rb +198 -0
  235. data/lib/rbs/source.rb +99 -0
  236. data/lib/rbs/substitution.rb +83 -0
  237. data/lib/rbs/subtractor.rb +204 -0
  238. data/lib/rbs/test/errors.rb +80 -0
  239. data/lib/rbs/test/guaranteed.rb +30 -0
  240. data/lib/rbs/test/hook.rb +212 -0
  241. data/lib/rbs/test/observer.rb +19 -0
  242. data/lib/rbs/test/setup.rb +84 -0
  243. data/lib/rbs/test/setup_helper.rb +50 -0
  244. data/lib/rbs/test/tester.rb +167 -0
  245. data/lib/rbs/test/type_check.rb +457 -0
  246. data/lib/rbs/test.rb +112 -0
  247. data/lib/rbs/type_alias_dependency.rb +100 -0
  248. data/lib/rbs/type_alias_regularity.rb +126 -0
  249. data/lib/rbs/type_name.rb +122 -0
  250. data/lib/rbs/types.rb +1604 -0
  251. data/lib/rbs/unit_test/convertibles.rb +177 -0
  252. data/lib/rbs/unit_test/spy.rb +138 -0
  253. data/lib/rbs/unit_test/type_assertions.rb +383 -0
  254. data/lib/rbs/unit_test/with_aliases.rb +145 -0
  255. data/lib/rbs/unit_test.rb +6 -0
  256. data/lib/rbs/validator.rb +186 -0
  257. data/lib/rbs/variance_calculator.rb +189 -0
  258. data/lib/rbs/vendorer.rb +71 -0
  259. data/lib/rbs/version.rb +5 -0
  260. data/lib/rbs/wasm/deserializer.rb +213 -0
  261. data/lib/rbs/wasm/jars/asm-analysis.jar +0 -0
  262. data/lib/rbs/wasm/jars/asm-commons.jar +0 -0
  263. data/lib/rbs/wasm/jars/asm-tree.jar +0 -0
  264. data/lib/rbs/wasm/jars/asm-util.jar +0 -0
  265. data/lib/rbs/wasm/jars/asm.jar +0 -0
  266. data/lib/rbs/wasm/jars/compiler.jar +0 -0
  267. data/lib/rbs/wasm/jars/log.jar +0 -0
  268. data/lib/rbs/wasm/jars/runtime.jar +0 -0
  269. data/lib/rbs/wasm/jars/wasi.jar +0 -0
  270. data/lib/rbs/wasm/jars/wasm.jar +0 -0
  271. data/lib/rbs/wasm/location.rb +61 -0
  272. data/lib/rbs/wasm/parser.rb +137 -0
  273. data/lib/rbs/wasm/rbs_parser.wasm +0 -0
  274. data/lib/rbs/wasm/runtime.rb +217 -0
  275. data/lib/rbs/wasm/serialization_schema.rb +110 -0
  276. data/lib/rbs/writer.rb +424 -0
  277. data/lib/rbs.rb +117 -0
  278. data/lib/rdoc/discover.rb +20 -0
  279. data/lib/rdoc_plugin/parser.rb +163 -0
  280. data/rbs.gemspec +68 -0
  281. data/schema/annotation.json +14 -0
  282. data/schema/comment.json +26 -0
  283. data/schema/decls.json +326 -0
  284. data/schema/function.json +87 -0
  285. data/schema/location.json +56 -0
  286. data/schema/members.json +266 -0
  287. data/schema/methodType.json +50 -0
  288. data/schema/typeParam.json +52 -0
  289. data/schema/types.json +317 -0
  290. data/sig/ancestor_builder.rbs +163 -0
  291. data/sig/ancestor_graph.rbs +60 -0
  292. data/sig/annotate/annotations.rbs +102 -0
  293. data/sig/annotate/formatter.rbs +24 -0
  294. data/sig/annotate/rdoc_annotater.rbs +85 -0
  295. data/sig/annotate/rdoc_source.rbs +32 -0
  296. data/sig/annotation.rbs +27 -0
  297. data/sig/ast/ruby/annotations.rbs +470 -0
  298. data/sig/ast/ruby/comment_block.rbs +127 -0
  299. data/sig/ast/ruby/declarations.rbs +158 -0
  300. data/sig/ast/ruby/helpers/constant_helper.rbs +11 -0
  301. data/sig/ast/ruby/helpers/location_helper.rbs +15 -0
  302. data/sig/ast/ruby/members.rbs +198 -0
  303. data/sig/buffer.rbs +108 -0
  304. data/sig/builtin_names.rbs +44 -0
  305. data/sig/cli/colored_io.rbs +15 -0
  306. data/sig/cli/diff.rbs +15 -0
  307. data/sig/cli/validate.rbs +47 -0
  308. data/sig/cli.rbs +89 -0
  309. data/sig/collection/cleaner.rbs +13 -0
  310. data/sig/collection/config/lockfile.rbs +74 -0
  311. data/sig/collection/config/lockfile_generator.rbs +68 -0
  312. data/sig/collection/config.rbs +46 -0
  313. data/sig/collection/installer.rbs +17 -0
  314. data/sig/collection/sources.rbs +214 -0
  315. data/sig/collection.rbs +4 -0
  316. data/sig/comment.rbs +26 -0
  317. data/sig/constant.rbs +21 -0
  318. data/sig/declarations.rbs +274 -0
  319. data/sig/definition.rbs +232 -0
  320. data/sig/definition_builder.rbs +181 -0
  321. data/sig/diff.rbs +28 -0
  322. data/sig/directives.rbs +77 -0
  323. data/sig/environment/class_entry.rbs +50 -0
  324. data/sig/environment/module_entry.rbs +50 -0
  325. data/sig/environment.rbs +286 -0
  326. data/sig/environment_loader.rbs +111 -0
  327. data/sig/environment_walker.rbs +65 -0
  328. data/sig/errors.rbs +408 -0
  329. data/sig/factory.rbs +5 -0
  330. data/sig/file_finder.rbs +28 -0
  331. data/sig/inline_parser/comment_association.rbs +71 -0
  332. data/sig/inline_parser.rbs +126 -0
  333. data/sig/location.rbs +135 -0
  334. data/sig/locator.rbs +56 -0
  335. data/sig/manifest.yaml +5 -0
  336. data/sig/members.rbs +258 -0
  337. data/sig/method_builder.rbs +89 -0
  338. data/sig/method_types.rbs +58 -0
  339. data/sig/namespace.rbs +161 -0
  340. data/sig/parser.rbs +164 -0
  341. data/sig/prototype/helpers.rbs +29 -0
  342. data/sig/prototype/node_usage.rbs +20 -0
  343. data/sig/prototype/rb.rbs +96 -0
  344. data/sig/prototype/rbi.rbs +75 -0
  345. data/sig/prototype/runtime.rbs +182 -0
  346. data/sig/rbs.rbs +21 -0
  347. data/sig/rdoc/rbs.rbs +67 -0
  348. data/sig/repository.rbs +85 -0
  349. data/sig/resolver/constant_resolver.rbs +92 -0
  350. data/sig/resolver/context.rbs +34 -0
  351. data/sig/resolver/type_name_resolver.rbs +61 -0
  352. data/sig/rewriter.rbs +45 -0
  353. data/sig/shims/bundler.rbs +38 -0
  354. data/sig/shims/enumerable.rbs +5 -0
  355. data/sig/shims/rubygems.rbs +19 -0
  356. data/sig/sorter.rbs +41 -0
  357. data/sig/source.rbs +48 -0
  358. data/sig/substitution.rbs +48 -0
  359. data/sig/subtractor.rbs +37 -0
  360. data/sig/test/errors.rbs +52 -0
  361. data/sig/test/guranteed.rbs +9 -0
  362. data/sig/test/type_check.rbs +19 -0
  363. data/sig/test.rbs +82 -0
  364. data/sig/type_alias_dependency.rbs +53 -0
  365. data/sig/type_alias_regularity.rbs +98 -0
  366. data/sig/type_param.rbs +115 -0
  367. data/sig/typename.rbs +89 -0
  368. data/sig/types.rbs +578 -0
  369. data/sig/unit_test/convertibles.rbs +154 -0
  370. data/sig/unit_test/spy.rbs +22 -0
  371. data/sig/unit_test/type_assertions.rbs +211 -0
  372. data/sig/unit_test/with_aliases.rbs +136 -0
  373. data/sig/use_map.rbs +35 -0
  374. data/sig/util.rbs +9 -0
  375. data/sig/validator.rbs +63 -0
  376. data/sig/variance_calculator.rbs +87 -0
  377. data/sig/vendorer.rbs +51 -0
  378. data/sig/version.rbs +3 -0
  379. data/sig/visitor.rbs +47 -0
  380. data/sig/wasm/deserializer.rbs +66 -0
  381. data/sig/wasm/serialization_schema.rbs +13 -0
  382. data/sig/writer.rbs +127 -0
  383. data/src/ast.c +1628 -0
  384. data/src/lexer.c +3217 -0
  385. data/src/lexer.re +155 -0
  386. data/src/lexstate.c +217 -0
  387. data/src/location.c +31 -0
  388. data/src/parser.c +4255 -0
  389. data/src/serialize.c +958 -0
  390. data/src/string.c +41 -0
  391. data/src/util/rbs_allocator.c +162 -0
  392. data/src/util/rbs_assert.c +19 -0
  393. data/src/util/rbs_buffer.c +54 -0
  394. data/src/util/rbs_constant_pool.c +268 -0
  395. data/src/util/rbs_encoding.c +21308 -0
  396. data/src/util/rbs_unescape.c +167 -0
  397. data/stdlib/abbrev/0/abbrev.rbs +66 -0
  398. data/stdlib/abbrev/0/array.rbs +26 -0
  399. data/stdlib/base64/0/base64.rbs +355 -0
  400. data/stdlib/benchmark/0/benchmark.rbs +452 -0
  401. data/stdlib/bigdecimal/0/big_decimal.rbs +1647 -0
  402. data/stdlib/bigdecimal-math/0/big_math.rbs +280 -0
  403. data/stdlib/bigdecimal-math/0/manifest.yaml +2 -0
  404. data/stdlib/cgi/0/core.rbs +911 -0
  405. data/stdlib/cgi/0/manifest.yaml +4 -0
  406. data/stdlib/cgi-escape/0/escape.rbs +171 -0
  407. data/stdlib/coverage/0/coverage.rbs +266 -0
  408. data/stdlib/csv/0/csv.rbs +3776 -0
  409. data/stdlib/csv/0/manifest.yaml +3 -0
  410. data/stdlib/date/0/date.rbs +1598 -0
  411. data/stdlib/date/0/date_time.rbs +617 -0
  412. data/stdlib/date/0/time.rbs +26 -0
  413. data/stdlib/dbm/0/dbm.rbs +421 -0
  414. data/stdlib/delegate/0/delegator.rbs +187 -0
  415. data/stdlib/delegate/0/kernel.rbs +47 -0
  416. data/stdlib/delegate/0/simple_delegator.rbs +96 -0
  417. data/stdlib/did_you_mean/0/did_you_mean.rbs +344 -0
  418. data/stdlib/digest/0/digest.rbs +687 -0
  419. data/stdlib/erb/0/erb.rbs +933 -0
  420. data/stdlib/etc/0/etc.rbs +884 -0
  421. data/stdlib/fileutils/0/fileutils.rbs +1753 -0
  422. data/stdlib/find/0/find.rbs +49 -0
  423. data/stdlib/forwardable/0/forwardable.rbs +271 -0
  424. data/stdlib/io-console/0/io-console.rbs +414 -0
  425. data/stdlib/ipaddr/0/ipaddr.rbs +436 -0
  426. data/stdlib/json/0/json.rbs +1963 -0
  427. data/stdlib/kconv/0/kconv.rbs +166 -0
  428. data/stdlib/logger/0/formatter.rbs +45 -0
  429. data/stdlib/logger/0/log_device.rbs +100 -0
  430. data/stdlib/logger/0/logger.rbs +796 -0
  431. data/stdlib/logger/0/manifest.yaml +2 -0
  432. data/stdlib/logger/0/period.rbs +17 -0
  433. data/stdlib/logger/0/severity.rbs +34 -0
  434. data/stdlib/minitest/0/kernel.rbs +42 -0
  435. data/stdlib/minitest/0/minitest/abstract_reporter.rbs +52 -0
  436. data/stdlib/minitest/0/minitest/assertion.rbs +17 -0
  437. data/stdlib/minitest/0/minitest/assertions.rbs +590 -0
  438. data/stdlib/minitest/0/minitest/backtrace_filter.rbs +23 -0
  439. data/stdlib/minitest/0/minitest/bench_spec.rbs +102 -0
  440. data/stdlib/minitest/0/minitest/benchmark.rbs +259 -0
  441. data/stdlib/minitest/0/minitest/composite_reporter.rbs +25 -0
  442. data/stdlib/minitest/0/minitest/compress.rbs +13 -0
  443. data/stdlib/minitest/0/minitest/error_on_warning.rbs +3 -0
  444. data/stdlib/minitest/0/minitest/expectation.rbs +2 -0
  445. data/stdlib/minitest/0/minitest/expectations.rbs +21 -0
  446. data/stdlib/minitest/0/minitest/guard.rbs +64 -0
  447. data/stdlib/minitest/0/minitest/mock.rbs +64 -0
  448. data/stdlib/minitest/0/minitest/parallel/executor.rbs +46 -0
  449. data/stdlib/minitest/0/minitest/parallel/test/class_methods.rbs +5 -0
  450. data/stdlib/minitest/0/minitest/parallel/test.rbs +3 -0
  451. data/stdlib/minitest/0/minitest/parallel.rbs +2 -0
  452. data/stdlib/minitest/0/minitest/pride_io.rbs +62 -0
  453. data/stdlib/minitest/0/minitest/pride_lol.rbs +19 -0
  454. data/stdlib/minitest/0/minitest/progress_reporter.rbs +11 -0
  455. data/stdlib/minitest/0/minitest/reportable.rbs +53 -0
  456. data/stdlib/minitest/0/minitest/reporter.rbs +5 -0
  457. data/stdlib/minitest/0/minitest/result.rbs +28 -0
  458. data/stdlib/minitest/0/minitest/runnable.rbs +163 -0
  459. data/stdlib/minitest/0/minitest/skip.rbs +6 -0
  460. data/stdlib/minitest/0/minitest/spec/dsl/instance_methods.rbs +48 -0
  461. data/stdlib/minitest/0/minitest/spec/dsl.rbs +129 -0
  462. data/stdlib/minitest/0/minitest/spec.rbs +11 -0
  463. data/stdlib/minitest/0/minitest/statistics_reporter.rbs +81 -0
  464. data/stdlib/minitest/0/minitest/summary_reporter.rbs +18 -0
  465. data/stdlib/minitest/0/minitest/test/lifecycle_hooks.rbs +92 -0
  466. data/stdlib/minitest/0/minitest/test.rbs +69 -0
  467. data/stdlib/minitest/0/minitest/unexpected_error.rbs +12 -0
  468. data/stdlib/minitest/0/minitest/unexpected_warning.rbs +6 -0
  469. data/stdlib/minitest/0/minitest/unit/test_case.rbs +3 -0
  470. data/stdlib/minitest/0/minitest/unit.rbs +4 -0
  471. data/stdlib/minitest/0/minitest.rbs +115 -0
  472. data/stdlib/monitor/0/monitor.rbs +363 -0
  473. data/stdlib/mutex_m/0/mutex_m.rbs +104 -0
  474. data/stdlib/net-http/0/manifest.yaml +3 -0
  475. data/stdlib/net-http/0/net-http.rbs +5580 -0
  476. data/stdlib/net-protocol/0/manifest.yaml +2 -0
  477. data/stdlib/net-protocol/0/net-protocol.rbs +56 -0
  478. data/stdlib/net-smtp/0/manifest.yaml +2 -0
  479. data/stdlib/net-smtp/0/net-smtp.rbs +55 -0
  480. data/stdlib/nkf/0/nkf.rbs +402 -0
  481. data/stdlib/objspace/0/objspace.rbs +470 -0
  482. data/stdlib/observable/0/observable.rbs +217 -0
  483. data/stdlib/open-uri/0/manifest.yaml +4 -0
  484. data/stdlib/open-uri/0/open-uri.rbs +433 -0
  485. data/stdlib/open3/0/open3.rbs +606 -0
  486. data/stdlib/openssl/0/manifest.yaml +3 -0
  487. data/stdlib/openssl/0/openssl.rbs +12231 -0
  488. data/stdlib/optparse/0/optparse.rbs +1734 -0
  489. data/stdlib/pathname/0/pathname.rbs +36 -0
  490. data/stdlib/pp/0/manifest.yaml +2 -0
  491. data/stdlib/pp/0/pp.rbs +301 -0
  492. data/stdlib/prettyprint/0/prettyprint.rbs +383 -0
  493. data/stdlib/pstore/0/pstore.rbs +608 -0
  494. data/stdlib/psych/0/core_ext.rbs +12 -0
  495. data/stdlib/psych/0/dbm.rbs +237 -0
  496. data/stdlib/psych/0/manifest.yaml +3 -0
  497. data/stdlib/psych/0/psych.rbs +455 -0
  498. data/stdlib/psych/0/store.rbs +57 -0
  499. data/stdlib/pty/0/pty.rbs +240 -0
  500. data/stdlib/random-formatter/0/random-formatter.rbs +277 -0
  501. data/stdlib/rdoc/0/code_object.rbs +52 -0
  502. data/stdlib/rdoc/0/comment.rbs +61 -0
  503. data/stdlib/rdoc/0/context.rbs +153 -0
  504. data/stdlib/rdoc/0/markup.rbs +117 -0
  505. data/stdlib/rdoc/0/options.rbs +76 -0
  506. data/stdlib/rdoc/0/parser.rbs +56 -0
  507. data/stdlib/rdoc/0/rdoc.rbs +393 -0
  508. data/stdlib/rdoc/0/ri.rbs +17 -0
  509. data/stdlib/rdoc/0/store.rbs +48 -0
  510. data/stdlib/rdoc/0/top_level.rbs +97 -0
  511. data/stdlib/resolv/0/manifest.yaml +3 -0
  512. data/stdlib/resolv/0/resolv.rbs +1787 -0
  513. data/stdlib/ripper/0/ripper.rbs +1654 -0
  514. data/stdlib/securerandom/0/manifest.yaml +2 -0
  515. data/stdlib/securerandom/0/securerandom.rbs +49 -0
  516. data/stdlib/shellwords/0/shellwords.rbs +229 -0
  517. data/stdlib/singleton/0/singleton.rbs +134 -0
  518. data/stdlib/socket/0/addrinfo.rbs +666 -0
  519. data/stdlib/socket/0/basic_socket.rbs +590 -0
  520. data/stdlib/socket/0/constants.rbs +2295 -0
  521. data/stdlib/socket/0/ip_socket.rbs +94 -0
  522. data/stdlib/socket/0/socket.rbs +4170 -0
  523. data/stdlib/socket/0/socket_error.rbs +5 -0
  524. data/stdlib/socket/0/tcp_server.rbs +192 -0
  525. data/stdlib/socket/0/tcp_socket.rbs +87 -0
  526. data/stdlib/socket/0/udp_socket.rbs +133 -0
  527. data/stdlib/socket/0/unix_server.rbs +169 -0
  528. data/stdlib/socket/0/unix_socket.rbs +172 -0
  529. data/stdlib/stringio/0/stringio.rbs +1681 -0
  530. data/stdlib/strscan/0/string_scanner.rbs +1648 -0
  531. data/stdlib/tempfile/0/tempfile.rbs +483 -0
  532. data/stdlib/time/0/time.rbs +434 -0
  533. data/stdlib/timeout/0/timeout.rbs +137 -0
  534. data/stdlib/tmpdir/0/tmpdir.rbs +69 -0
  535. data/stdlib/tsort/0/cyclic.rbs +8 -0
  536. data/stdlib/tsort/0/interfaces.rbs +20 -0
  537. data/stdlib/tsort/0/tsort.rbs +410 -0
  538. data/stdlib/uri/0/common.rbs +621 -0
  539. data/stdlib/uri/0/file.rbs +118 -0
  540. data/stdlib/uri/0/ftp.rbs +13 -0
  541. data/stdlib/uri/0/generic.rbs +1116 -0
  542. data/stdlib/uri/0/http.rbs +104 -0
  543. data/stdlib/uri/0/https.rbs +14 -0
  544. data/stdlib/uri/0/ldap.rbs +230 -0
  545. data/stdlib/uri/0/ldaps.rbs +14 -0
  546. data/stdlib/uri/0/mailto.rbs +92 -0
  547. data/stdlib/uri/0/rfc2396_parser.rbs +189 -0
  548. data/stdlib/uri/0/rfc3986_parser.rbs +2 -0
  549. data/stdlib/uri/0/ws.rbs +13 -0
  550. data/stdlib/uri/0/wss.rbs +9 -0
  551. data/stdlib/yaml/0/manifest.yaml +2 -0
  552. data/stdlib/yaml/0/yaml.rbs +1 -0
  553. data/stdlib/zlib/0/buf_error.rbs +10 -0
  554. data/stdlib/zlib/0/data_error.rbs +10 -0
  555. data/stdlib/zlib/0/deflate.rbs +211 -0
  556. data/stdlib/zlib/0/error.rbs +20 -0
  557. data/stdlib/zlib/0/gzip_file/crc_error.rbs +12 -0
  558. data/stdlib/zlib/0/gzip_file/error.rbs +23 -0
  559. data/stdlib/zlib/0/gzip_file/length_error.rbs +12 -0
  560. data/stdlib/zlib/0/gzip_file/no_footer.rbs +11 -0
  561. data/stdlib/zlib/0/gzip_file.rbs +156 -0
  562. data/stdlib/zlib/0/gzip_reader.rbs +293 -0
  563. data/stdlib/zlib/0/gzip_writer.rbs +168 -0
  564. data/stdlib/zlib/0/inflate.rbs +180 -0
  565. data/stdlib/zlib/0/mem_error.rbs +10 -0
  566. data/stdlib/zlib/0/need_dict.rbs +13 -0
  567. data/stdlib/zlib/0/stream_end.rbs +11 -0
  568. data/stdlib/zlib/0/stream_error.rbs +11 -0
  569. data/stdlib/zlib/0/version_error.rbs +11 -0
  570. data/stdlib/zlib/0/zlib.rbs +449 -0
  571. data/stdlib/zlib/0/zstream.rbs +201 -0
  572. data/wasm/README.md +59 -0
  573. data/wasm/rbs_wasm.c +411 -0
  574. metadata +660 -0
@@ -0,0 +1,212 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rbs"
4
+ require "pp"
5
+
6
+ module RBS
7
+ module Test
8
+ module Hook
9
+ OPERATORS = {
10
+ :[] => "indexlookup",
11
+ :[]= => "indexset",
12
+ :== => "eqeq",
13
+ :=== => "eqeqeq",
14
+ :!= => "noteq",
15
+ :+ => "plus",
16
+ :- => "minus",
17
+ :* => "star",
18
+ :/ => "slash",
19
+ :> => "gt",
20
+ :>= => "gteq",
21
+ :< => "lt",
22
+ :<= => "lteq",
23
+ :<=> => "ufo",
24
+ :& => "amp",
25
+ :| => "vbar",
26
+ :^ => "hat",
27
+ :! => "not",
28
+ :<< => "lshift",
29
+ :>> => "rshift",
30
+ :~ => "tilde",
31
+ :=~ => "eqtilde",
32
+ :% => "percent",
33
+ :+@ => "unary_plus",
34
+ :-@ => "unary_minus"
35
+ }
36
+ def self.alias_names(target, random)
37
+ suffix = "#{RBS::Test.suffix}_#{random}"
38
+
39
+ case target
40
+ when *OPERATORS.keys
41
+ name = OPERATORS[target]
42
+ [
43
+ "#{name}____with__#{suffix}",
44
+ "#{name}____without__#{suffix}"
45
+ ]
46
+ else
47
+ aliased_target, punctuation = target.to_s.sub(/([?!=])$/, ''), $1
48
+
49
+ [
50
+ "#{aliased_target}__with__#{suffix}#{punctuation}",
51
+ "#{aliased_target}__without__#{suffix}#{punctuation}"
52
+ ]
53
+ end
54
+ end
55
+
56
+ def self.setup_alias_method_chain(klass, target, random:)
57
+ with_method, without_method = alias_names(target, random)
58
+
59
+ RBS.logger.debug "alias name: #{target}, #{with_method}, #{without_method}"
60
+
61
+ klass.instance_eval do
62
+ alias_method without_method, target
63
+ alias_method target, with_method
64
+
65
+ case
66
+ when public_method_defined?(without_method)
67
+ public target
68
+ when protected_method_defined?(without_method)
69
+ protected target
70
+ when private_method_defined?(without_method)
71
+ private target
72
+ end
73
+ end
74
+ end
75
+
76
+ def self.hook_method_source(prefix, method_name, key, random:, params:)
77
+ with_name, without_name = alias_names(method_name, random)
78
+ full_method_name = "#{prefix}#{method_name}"
79
+
80
+ param_source = params.take_while {|param| param[0] == :req }
81
+ .map.with_index {|pair, index| pair[1] || "__req__#{random}__#{index}" }
82
+ param_source.push("*rest_args__#{random}")
83
+ block_param = "block__#{random}"
84
+
85
+ RBS.logger.debug {
86
+ "Generating method definition: def #{with_name}(#{param_source.join(", ")}, &#{block_param}) ..."
87
+ }
88
+
89
+ [__LINE__ + 1, <<RUBY]
90
+ def #{with_name}(#{param_source.join(", ")}, &#{block_param})
91
+ args = [#{param_source.join(", ")}]
92
+ ::RBS.logger.debug { "#{full_method_name} with arguments: [" + args.map(&:inspect).join(", ") + "]" }
93
+
94
+ begin
95
+ return_from_call = false
96
+ block_calls = []
97
+
98
+ if block_given?
99
+ block_receives_block = #{block_param}.parameters.last&.yield_self {|type, _| type == :block }
100
+
101
+ wrapped_block = Object.new.instance_exec do
102
+ new_object = self
103
+
104
+ proc do |*block_args, &block2|
105
+ return_from_block = false
106
+
107
+ begin
108
+ block_result = if self.equal?(new_object)
109
+ if block_receives_block
110
+ #{block_param}.call(*block_args, &block2)
111
+ else
112
+ yield(*block_args)
113
+ end
114
+ else
115
+ # Detected that `self` inside `proc` is not equal to the `self` outside block (which is saved to `new_object`).
116
+ # This means that the block is called with `instance_exec` or `instance_eval`.
117
+ self.instance_exec(*block_args, &#{block_param})
118
+ end
119
+
120
+ return_from_block = true
121
+ ensure
122
+ exn = $!
123
+
124
+ case
125
+ when return_from_block
126
+ # Returned from yield
127
+ block_calls << ::RBS::Test::ArgumentsReturn.return(
128
+ arguments: block_args,
129
+ value: block_result
130
+ )
131
+ when exn
132
+ # Exception
133
+ block_calls << ::RBS::Test::ArgumentsReturn.exception(
134
+ arguments: block_args,
135
+ exception: exn
136
+ )
137
+ else
138
+ # break?
139
+ block_calls << ::RBS::Test::ArgumentsReturn.break(
140
+ arguments: block_args
141
+ )
142
+ end
143
+ end
144
+
145
+ block_result
146
+ end.ruby2_keywords
147
+ end
148
+
149
+ result = __send__(:"#{without_name}", *args, &wrapped_block)
150
+ else
151
+ result = __send__(:"#{without_name}", *args)
152
+ end
153
+ return_from_call = true
154
+ result
155
+ ensure
156
+ exn = $!
157
+
158
+ case
159
+ when return_from_call
160
+ ::RBS.logger.debug { "#{full_method_name} return with value: " + result.inspect }
161
+ method_call = ::RBS::Test::ArgumentsReturn.return(
162
+ arguments: args,
163
+ value: result
164
+ )
165
+ when exn
166
+ ::RBS.logger.debug { "#{full_method_name} exit with exception: " + exn.inspect }
167
+ method_call = ::RBS::Test::ArgumentsReturn.exception(
168
+ arguments: args,
169
+ exception: exn
170
+ )
171
+ else
172
+ ::RBS.logger.debug { "#{full_method_name} exit with jump" }
173
+ method_call = ::RBS::Test::ArgumentsReturn.break(arguments: args)
174
+ end
175
+
176
+ trace = ::RBS::Test::CallTrace.new(
177
+ method_name: #{method_name.inspect},
178
+ method_call: method_call,
179
+ block_calls: block_calls,
180
+ block_given: block_given?,
181
+ )
182
+
183
+ ::RBS::Test::Observer.notify(#{key.inspect}, self, trace)
184
+ end
185
+
186
+ result
187
+ end
188
+
189
+ ruby2_keywords :#{with_name}
190
+ RUBY
191
+ end
192
+
193
+ def self.hook_instance_method(klass, method, key:)
194
+ random = SecureRandom.hex(4)
195
+ params = klass.instance_method(method).parameters
196
+ line, source = hook_method_source("#{klass}#", method, key, random: random, params: params)
197
+
198
+ klass.module_eval(source, __FILE__, line)
199
+ setup_alias_method_chain klass, method, random: random
200
+ end
201
+
202
+ def self.hook_singleton_method(klass, method, key:)
203
+ random = SecureRandom.hex(4)
204
+ params = klass.method(method).parameters
205
+ line, source = hook_method_source("#{klass}.",method, key, random: random, params: params)
206
+
207
+ klass.singleton_class.module_eval(source, __FILE__, line)
208
+ setup_alias_method_chain klass.singleton_class, method, random: random
209
+ end
210
+ end
211
+ end
212
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RBS
4
+ module Test
5
+ module Observer
6
+ @@observers = {}
7
+
8
+ class <<self
9
+ def notify(key, *args)
10
+ @@observers[key]&.call(*args)
11
+ end
12
+
13
+ def register(key, object = nil, &block)
14
+ @@observers[key] = object || block
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,84 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rbs"
4
+ require "rbs/test"
5
+ require "optparse"
6
+ require "shellwords"
7
+ require "rbs/cli"
8
+
9
+ include RBS::Test::SetupHelper
10
+
11
+ logger = Logger.new(STDERR)
12
+
13
+ begin
14
+ opts = Shellwords.shellsplit(ENV["RBS_TEST_OPT"] || "-I sig")
15
+ filter = ENV.fetch('RBS_TEST_TARGET', "").split(',').map! { |e| e.strip }
16
+ skips = (ENV['RBS_TEST_SKIP'] || '').split(',').map! { |e| e.strip }
17
+ RBS.logger_level = (ENV["RBS_TEST_LOGLEVEL"] || "info")
18
+ logger.level = RBS.logger_level
19
+ sample_size = get_sample_size(ENV['RBS_TEST_SAMPLE_SIZE'] || '')
20
+ double_class = to_double_class(ENV['RBS_TEST_DOUBLE_SUITE'])
21
+ unchecked_classes = (ENV['RBS_TEST_UNCHECKED_CLASSES'] || '').split(',').map! { |unchecked_class| unchecked_class.strip }.push(*double_class)
22
+ rescue InvalidSampleSizeError => exception
23
+ RBS.logger.error exception.message
24
+ exit 1
25
+ end
26
+
27
+ if filter.empty?
28
+ STDERR.puts "rbs/test/setup handles the following environment variables:"
29
+ STDERR.puts " [REQUIRED] RBS_TEST_TARGET: test target class name, `Foo::Bar,Foo::Baz` for each class or `Foo::*` for all classes under `Foo`"
30
+ STDERR.puts " [OPTIONAL] RBS_TEST_SKIP: skip testing classes"
31
+ STDERR.puts " [OPTIONAL] RBS_TEST_OPT: options for signatures (`-r` for libraries or `-I` for signatures)"
32
+ STDERR.puts " [OPTIONAL] RBS_TEST_LOGLEVEL: one of debug|info|warn|error|fatal (defaults to info)"
33
+ STDERR.puts " [OPTIONAL] RBS_TEST_SAMPLE_SIZE: sets the amount of values in a collection to be type-checked (Set to `ALL` to type check all the values)"
34
+ STDERR.puts " [OPTIONAL] RBS_TEST_DOUBLE_SUITE: sets the double suite in use (currently supported: minitest | rspec)"
35
+ STDERR.puts " [OPTIONAL] RBS_TEST_UNCHECKED_CLASSES: sets the classes that would not be checked"
36
+ exit 1
37
+ end
38
+
39
+ options = RBS::CLI::LibraryOptions.new()
40
+
41
+ OptionParser.new do |opts|
42
+ options.setup_library_options(opts)
43
+ end.parse!(opts)
44
+
45
+ loader = options.loader
46
+ env = RBS::Environment.from_loader(loader).resolve_type_names
47
+
48
+ def match(filter, name)
49
+ if filter.end_with?("*")
50
+ size = filter.size
51
+ name.start_with?(filter[0, size - 1]) || name == filter[0, size-3]
52
+ else
53
+ filter == name
54
+ end
55
+ end
56
+
57
+ def to_absolute_typename(type_name)
58
+ RBS::Factory.new().type_name(type_name).absolute!
59
+ end
60
+
61
+ tester = RBS::Test::Tester.new(env: env)
62
+
63
+ module_name = Module.instance_method(:name)
64
+
65
+ TracePoint.trace :end do |tp|
66
+ class_name = module_name.bind(tp.self).call&.yield_self {|name| to_absolute_typename name }
67
+
68
+ if class_name
69
+ if filter.any? {|f| match(to_absolute_typename(f).to_s, class_name.to_s) } && skips.none? {|f| match(f, class_name.to_s) }
70
+ if env.module_name?(class_name)
71
+ logger.info "Setting up hooks for #{class_name}"
72
+ tester.install!(tp.self, sample_size: sample_size, unchecked_classes: unchecked_classes)
73
+ end
74
+ end
75
+ end
76
+ end
77
+
78
+ at_exit do
79
+ if $!.nil? || $!.is_a?(SystemExit) && $!.success?
80
+ if tester.targets.empty?
81
+ logger.debug { "No type checker was installed!" }
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RBS
4
+ module Test
5
+ module SetupHelper
6
+ class InvalidSampleSizeError < StandardError
7
+ attr_reader :string
8
+
9
+ def initialize(string)
10
+ @string = string
11
+ super("Sample size should be a positive integer: `#{string}`")
12
+ end
13
+ end
14
+
15
+ DEFAULT_SAMPLE_SIZE = 100
16
+
17
+ def get_sample_size(string)
18
+ case string
19
+ when ""
20
+ DEFAULT_SAMPLE_SIZE
21
+ when 'ALL'
22
+ nil
23
+ else
24
+ int_size = string.to_i
25
+ raise InvalidSampleSizeError.new(string) unless int_size.positive?
26
+ int_size
27
+ end
28
+ end
29
+
30
+ def to_double_class(double_suite)
31
+ return nil unless double_suite
32
+
33
+ case double_suite.downcase.strip
34
+ when 'rspec'
35
+ [
36
+ '::RSpec::Mocks::Double',
37
+ '::RSpec::Mocks::InstanceVerifyingDouble',
38
+ '::RSpec::Mocks::ObjectVerifyingDouble',
39
+ '::RSpec::Mocks::ClassVerifyingDouble',
40
+ ]
41
+ when 'minitest'
42
+ ['::Minitest::Mock']
43
+ else
44
+ RBS.logger.warn "Unknown test suite - defaults to nil"
45
+ nil
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,167 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RBS
4
+ module Test
5
+ class Tester
6
+ attr_reader :env
7
+ attr_reader :targets
8
+ attr_reader :instance_testers
9
+ attr_reader :singleton_testers
10
+
11
+ def initialize(env:)
12
+ @env = env
13
+ @targets = []
14
+ @instance_testers = {}
15
+ @singleton_testers = {}
16
+ end
17
+
18
+ def factory
19
+ @factory ||= Factory.new
20
+ end
21
+
22
+ def builder
23
+ @builder ||= DefinitionBuilder.new(env: env)
24
+ end
25
+
26
+ def skip_method?(type_name, method)
27
+ if method.implemented_in == type_name
28
+ if method.annotations.any? {|a| a.string == "rbs:test:skip" }
29
+ :skip
30
+ else
31
+ false
32
+ end
33
+ else
34
+ if method.annotations.any? {|a| a.string == "rbs:test:target" }
35
+ false
36
+ else
37
+ :implemented_in
38
+ end
39
+ end
40
+ end
41
+
42
+ def install!(klass, sample_size:, unchecked_classes:)
43
+ RBS.logger.info { "Installing runtime type checker in #{klass}..." }
44
+
45
+ type_name = factory.type_name(klass.name).absolute!
46
+
47
+ builder.build_instance(type_name).tap do |definition|
48
+ instance_key = new_key(type_name, "InstanceChecker")
49
+ tester, set = instance_testers[klass] ||= [
50
+ MethodCallTester.new(klass, builder, definition, kind: :instance, sample_size: sample_size, unchecked_classes: unchecked_classes),
51
+ Set[]
52
+ ]
53
+ Observer.register(instance_key, tester)
54
+
55
+ definition.methods.each do |name, method|
56
+ if reason = skip_method?(type_name, method)
57
+ unless reason == :implemented_in
58
+ RBS.logger.info { "Skipping ##{name} because of `#{reason}`..." }
59
+ end
60
+ else
61
+ if !set.include?(name) && (
62
+ name == :initialize ||
63
+ klass.instance_methods(false).include?(name) ||
64
+ klass.private_instance_methods(false).include?(name))
65
+ RBS.logger.info { "Setting up method hook in ##{name}..." }
66
+ Hook.hook_instance_method klass, name, key: instance_key
67
+ set << name
68
+ end
69
+ end
70
+ end
71
+ end
72
+
73
+ builder.build_singleton(type_name).tap do |definition|
74
+ singleton_key = new_key(type_name, "SingletonChecker")
75
+ tester, set = singleton_testers[klass] ||= [
76
+ MethodCallTester.new(klass.singleton_class, builder, definition, kind: :singleton, sample_size: sample_size, unchecked_classes: unchecked_classes),
77
+ Set[]
78
+ ]
79
+ Observer.register(singleton_key, tester)
80
+
81
+ definition.methods.each do |name, method|
82
+ if reason = skip_method?(type_name, method)
83
+ unless reason == :implemented_in
84
+ RBS.logger.info { "Skipping .#{name} because of `#{reason}`..." }
85
+ end
86
+ else
87
+ if klass.methods(false).include?(name) && !set.include?(name)
88
+ RBS.logger.info { "Setting up method hook in .#{name}..." }
89
+ Hook.hook_singleton_method klass, name, key: singleton_key
90
+ set << name
91
+ end
92
+ end
93
+ end
94
+ end
95
+
96
+ targets << klass
97
+ end
98
+
99
+ def new_key(type_name, prefix)
100
+ "#{prefix}__#{type_name}__#{SecureRandom.hex(10)}"
101
+ end
102
+
103
+ class TypeError < Exception
104
+ attr_reader :errors
105
+
106
+ def initialize(errors)
107
+ @errors = errors
108
+
109
+ super "TypeError: #{errors.map {|e| Errors.to_string(e) }.join(", ")}"
110
+ end
111
+ end
112
+
113
+ class MethodCallTester
114
+ attr_reader :self_class
115
+ attr_reader :definition
116
+ attr_reader :builder
117
+ attr_reader :kind
118
+ attr_reader :sample_size
119
+ attr_reader :unchecked_classes
120
+
121
+ def initialize(self_class, builder, definition, kind:, sample_size:, unchecked_classes:)
122
+ @self_class = self_class
123
+ @definition = definition
124
+ @builder = builder
125
+ @kind = kind
126
+ @sample_size = sample_size
127
+ @unchecked_classes = unchecked_classes
128
+ end
129
+
130
+ def env
131
+ builder.env
132
+ end
133
+
134
+ def check
135
+ @check ||= TypeCheck.new(self_class: self_class, builder: builder, sample_size: sample_size, unchecked_classes: unchecked_classes)
136
+ end
137
+
138
+ def format_method_name(name)
139
+ case kind
140
+ when :instance
141
+ "##{name}"
142
+ when :singleton
143
+ ".#{name}"
144
+ end
145
+ end
146
+
147
+ def call(receiver, trace)
148
+ method_name = trace.method_name
149
+ method = definition.methods[method_name]
150
+ if method
151
+ RBS.logger.debug { "Type checking `#{self_class}#{format_method_name(method_name)}`..."}
152
+ errors = check.overloaded_call(method, method_name, trace, errors: [])
153
+
154
+ if errors.empty?
155
+ RBS.logger.debug { "No type error detected 👏" }
156
+ else
157
+ RBS.logger.debug { "Detected type error 🚨" }
158
+ raise TypeError.new(errors)
159
+ end
160
+ else
161
+ RBS.logger.error { "Type checking `#{self_class}#{method_name}` call but no method found in definition" }
162
+ end
163
+ end
164
+ end
165
+ end
166
+ end
167
+ end