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
data/lib/rbs/cli.rb ADDED
@@ -0,0 +1,1253 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "open3"
4
+ require "optparse"
5
+ require "shellwords"
6
+ require "stringio"
7
+
8
+ module RBS
9
+ class CLI
10
+ autoload :ColoredIO, 'rbs/cli/colored_io'
11
+ autoload :Diff, 'rbs/cli/diff'
12
+ autoload :Validate, 'rbs/cli/validate'
13
+
14
+ class LibraryOptions
15
+ attr_accessor :core_root
16
+ attr_accessor :config_path
17
+ attr_reader :repos
18
+ attr_reader :libs
19
+ attr_reader :dirs
20
+
21
+ def initialize()
22
+ @core_root = EnvironmentLoader::DEFAULT_CORE_ROOT
23
+ @repos = []
24
+
25
+ @libs = []
26
+ @dirs = []
27
+ @config_path = Collection::Config.find_config_path || Collection::Config::PATH
28
+ end
29
+
30
+ def loader
31
+ repository = Repository.new(no_stdlib: core_root.nil?)
32
+ repos.each do |repo|
33
+ repository.add(Pathname(repo))
34
+ end
35
+
36
+ loader = EnvironmentLoader.new(core_root: core_root, repository: repository)
37
+ if config_path
38
+ lock_path = Collection::Config.to_lockfile_path(config_path)
39
+ if lock_path.file?
40
+ lock = Collection::Config::Lockfile.from_lockfile(lockfile_path: lock_path, data: YAML.load_file(lock_path.to_s))
41
+ end
42
+ end
43
+ loader.add_collection(lock) if lock
44
+
45
+ dirs.each do |dir|
46
+ loader.add(path: Pathname(dir))
47
+ end
48
+
49
+ libs.each do |lib|
50
+ name, version = lib.split(/:/, 2)
51
+ next unless name
52
+ loader.add(library: name, version: version)
53
+ end
54
+
55
+ loader
56
+ end
57
+
58
+ def setup_library_options(opts)
59
+ opts.on("-r LIBRARY", "Load RBS files of the library") do |lib|
60
+ libs << lib
61
+ end
62
+
63
+ opts.on("-I DIR", "Load RBS files from the directory") do |dir|
64
+ dirs << dir
65
+ end
66
+
67
+ opts.on("--no-stdlib", "Skip loading standard library signatures") do
68
+ self.core_root = nil
69
+ end
70
+
71
+ opts.on('--collection PATH', "File path of collection configuration (default: #{@config_path})") do |path|
72
+ self.config_path = Pathname(path).expand_path
73
+ end
74
+
75
+ opts.on('--no-collection', 'Ignore collection configuration') do
76
+ self.config_path = nil
77
+ end
78
+
79
+ opts.on("--repo DIR", "Add RBS repository") do |dir|
80
+ repos << dir
81
+ end
82
+
83
+ opts
84
+ end
85
+ end
86
+
87
+ attr_reader :stdout
88
+ attr_reader :stderr
89
+ attr_reader :original_args
90
+
91
+ def initialize(stdout:, stderr:)
92
+ @stdout = stdout
93
+ @stderr = stderr
94
+ end
95
+
96
+ COMMANDS = [:ast, :annotate, :list, :ancestors, :methods, :method, :validate, :constant, :paths, :prototype, :vendor, :parse, :test, :collection, :subtract, :diff]
97
+
98
+ def parse_logging_options(opts)
99
+ opts.on("--log-level LEVEL", "Specify log level (defaults to `warn`)") do |level|
100
+ RBS.logger_level = level
101
+ end
102
+
103
+ opts.on("--log-output OUTPUT", "Specify the file to output log (defaults to stderr)") do |output|
104
+ io = File.open(output, "a") or raise
105
+ RBS.logger_output = io
106
+ end
107
+
108
+ opts
109
+ end
110
+
111
+ def has_parser?
112
+ defined?(RubyVM::AbstractSyntaxTree) ? true : false
113
+ end
114
+
115
+ def run(args)
116
+ @original_args = args.dup
117
+
118
+ options = LibraryOptions.new
119
+
120
+ opts = OptionParser.new
121
+ opts.banner = <<~USAGE
122
+ Usage: rbs [options...] [command...]
123
+
124
+ Available commands: #{COMMANDS.join(", ")}, version, help.
125
+
126
+ Options:
127
+ USAGE
128
+ options.setup_library_options(opts)
129
+ parse_logging_options(opts)
130
+ opts.version = RBS::VERSION
131
+
132
+ opts.order!(args)
133
+
134
+ command = args.shift&.to_sym
135
+
136
+ case command
137
+ when :version
138
+ stdout.puts opts.ver
139
+ 0
140
+ when *COMMANDS
141
+ __send__ :"run_#{command}", args, options
142
+ else
143
+ stdout.puts opts.help
144
+ 0
145
+ end
146
+ end
147
+
148
+ def run_ast(args, options)
149
+ OptionParser.new do |opts|
150
+ opts.banner = <<EOB
151
+ Usage: rbs ast [patterns...]
152
+
153
+ Print JSON AST of loaded environment.
154
+ You can specify patterns to filter declarations with the file names.
155
+
156
+ Examples:
157
+
158
+ $ rbs ast
159
+ $ rbs ast 'basic_object.rbs'
160
+ $ rbs -I ./sig ast ./sig
161
+ $ rbs -I ./sig ast '*/models/*.rbs'
162
+ EOB
163
+ end.order!(args)
164
+
165
+ patterns = args.map do |arg|
166
+ path = Pathname(arg)
167
+ if path.exist?
168
+ # Pathname means a directory or a file
169
+ path
170
+ else
171
+ # String means a `fnmatch` pattern
172
+ arg
173
+ end
174
+ end
175
+
176
+ loader = options.loader()
177
+
178
+ env = Environment.from_loader(loader).resolve_type_names
179
+
180
+ decls = env.sources.select do |source|
181
+ # @type var name: String
182
+ name = source.buffer.name.to_s
183
+
184
+ patterns.empty? || patterns.any? do |pat|
185
+ case pat
186
+ when Pathname
187
+ Pathname(name).ascend.any? {|p| p == pat }
188
+ when String
189
+ name.end_with?(pat) || File.fnmatch(pat, name, File::FNM_EXTGLOB)
190
+ end
191
+ end
192
+ end.flat_map { _1.declarations }
193
+
194
+ stdout.print JSON.generate(decls)
195
+ stdout.flush
196
+
197
+ 0
198
+ end
199
+
200
+ def run_list(args, options)
201
+ # @type var list: Set[:class | :module | :interface]
202
+ list = Set[]
203
+
204
+ OptionParser.new do |opts|
205
+ opts.banner = <<EOB
206
+ Usage: rbs list [options...]
207
+
208
+ List classes, modules, and interfaces.
209
+
210
+ Examples:
211
+
212
+ $ rbs list
213
+ $ rbs list --class --module --interface
214
+
215
+ Options:
216
+ EOB
217
+ opts.on("--class", "List classes") { list << :class }
218
+ opts.on("--module", "List modules") { list << :module }
219
+ opts.on("--interface", "List interfaces") { list << :interface }
220
+ end.order!(args)
221
+
222
+ list.merge(_ = [:class, :module, :interface]) if list.empty?
223
+
224
+ loader = options.loader()
225
+
226
+ env = Environment.from_loader(loader).resolve_type_names
227
+
228
+ if list.include?(:class) || list.include?(:module)
229
+ env.class_decls.each do |name, entry|
230
+ case entry
231
+ when Environment::ModuleEntry
232
+ if list.include?(:module)
233
+ stdout.puts "#{name} (module)"
234
+ end
235
+ when Environment::ClassEntry
236
+ if list.include?(:class)
237
+ stdout.puts "#{name} (class)"
238
+ end
239
+ end
240
+ end
241
+
242
+ env.class_alias_decls.each do |name, entry|
243
+ case entry
244
+ when Environment::ModuleAliasEntry
245
+ if list.include?(:module)
246
+ stdout.puts "#{name} (module alias)"
247
+ end
248
+ when Environment::ClassAliasEntry
249
+ if list.include?(:class)
250
+ stdout.puts "#{name} (class alias)"
251
+ end
252
+ end
253
+ end
254
+ end
255
+
256
+ if list.include?(:interface)
257
+ env.interface_decls.each do |name, entry|
258
+ stdout.puts "#{name} (interface)"
259
+ end
260
+ end
261
+
262
+ 0
263
+ end
264
+
265
+ def run_ancestors(args, options)
266
+ # @type var kind: :instance | :singleton
267
+ kind = :instance
268
+
269
+ OptionParser.new do |opts|
270
+ opts.banner = <<EOU
271
+ Usage: rbs ancestors [options...] [type_name]
272
+
273
+ Show ancestors of the given class or module.
274
+
275
+ Examples:
276
+
277
+ $ rbs ancestors --instance String
278
+ $ rbs ancestors --singleton Array
279
+
280
+ Options:
281
+ EOU
282
+ opts.on("--instance", "Ancestors of instance of the given type_name (default)") { kind = :instance }
283
+ opts.on("--singleton", "Ancestors of singleton of the given type_name") { kind = :singleton }
284
+ end.order!(args)
285
+
286
+ unless args.size == 1
287
+ stdout.puts "Expected one argument."
288
+ return 1
289
+ end
290
+
291
+ loader = options.loader()
292
+
293
+ env = Environment.from_loader(loader).resolve_type_names
294
+
295
+ builder = DefinitionBuilder::AncestorBuilder.new(env: env)
296
+ type_name = TypeName.parse(args[0]).absolute!
297
+
298
+ case env.constant_entry(type_name)
299
+ when Environment::ClassEntry, Environment::ModuleEntry, Environment::ClassAliasEntry, Environment::ModuleAliasEntry
300
+ type_name = env.normalize_module_name(type_name)
301
+
302
+ ancestors = case kind
303
+ when :instance
304
+ builder.instance_ancestors(type_name)
305
+ when :singleton
306
+ builder.singleton_ancestors(type_name)
307
+ else
308
+ raise
309
+ end
310
+
311
+ ancestors.ancestors.each do |ancestor|
312
+ case ancestor
313
+ when Definition::Ancestor::Singleton
314
+ stdout.puts "singleton(#{ancestor.name})"
315
+ when Definition::Ancestor::Instance
316
+ if ancestor.args.empty?
317
+ stdout.puts ancestor.name.to_s
318
+ else
319
+ stdout.puts "#{ancestor.name}[#{ancestor.args.join(", ")}]"
320
+ end
321
+ end
322
+ end
323
+ else
324
+ stdout.puts "Cannot find class: #{type_name}"
325
+ end
326
+
327
+ 0
328
+ end
329
+
330
+ def run_methods(args, options)
331
+ # @type var kind: :instance | :singleton
332
+ kind = :instance
333
+ inherit = true
334
+
335
+ OptionParser.new do |opts|
336
+ opts.banner = <<EOU
337
+ Usage: rbs methods [options...] [type_name]
338
+
339
+ Show methods defined in the class or module.
340
+
341
+ Examples:
342
+
343
+ $ rbs methods --instance Kernel
344
+ $ rbs methods --singleton --no-inherit String
345
+
346
+ Options:
347
+ EOU
348
+ opts.on("--instance", "Show instance methods (default)") { kind = :instance }
349
+ opts.on("--singleton", "Show singleton methods") { kind = :singleton }
350
+ opts.on("--[no-]inherit", "Show methods defined in super class and mixed modules too") {|v| inherit = v }
351
+ end.order!(args)
352
+
353
+ unless args.size == 1
354
+ stdout.puts "Expected one argument."
355
+ return 1
356
+ end
357
+
358
+ loader = options.loader()
359
+
360
+ env = Environment.from_loader(loader).resolve_type_names
361
+
362
+ builder = DefinitionBuilder.new(env: env)
363
+ type_name = TypeName.parse(args[0]).absolute!
364
+
365
+ if env.module_name?(type_name)
366
+ definition = case kind
367
+ when :instance
368
+ builder.build_instance(type_name)
369
+ when :singleton
370
+ builder.build_singleton(type_name)
371
+ else
372
+ raise
373
+ end
374
+
375
+ definition.methods.keys.sort.each do |name|
376
+ method = definition.methods[name]
377
+ if inherit || method.implemented_in == type_name
378
+ stdout.puts "#{name} (#{method.accessibility})"
379
+ end
380
+ end
381
+ else
382
+ stdout.puts "Cannot find class: #{type_name}"
383
+ end
384
+
385
+ 0
386
+ end
387
+
388
+ def run_method(args, options)
389
+ # @type var kind: :instance | :singleton
390
+ kind = :instance
391
+
392
+ OptionParser.new do |opts|
393
+ opts.banner = <<EOU
394
+ Usage: rbs method [options...] [type_name] [method_name]
395
+
396
+ Show the information of the method specified by type_name and method_name.
397
+
398
+ Examples:
399
+
400
+ $ rbs method --instance Kernel puts
401
+ $ rbs method --singleton String try_convert
402
+
403
+ Options:
404
+ EOU
405
+ opts.on("--instance", "Show an instance method (default)") { kind = :instance }
406
+ opts.on("--singleton", "Show a singleton method") { kind = :singleton }
407
+ end.order!(args)
408
+
409
+ unless args.size == 2
410
+ stdout.puts "Expected two arguments, but given #{args.size}."
411
+ return 1
412
+ end
413
+
414
+ loader = options.loader()
415
+ env = Environment.from_loader(loader).resolve_type_names
416
+
417
+ builder = DefinitionBuilder.new(env: env)
418
+ type_name = TypeName.parse(args[0]).absolute!
419
+ method_name = args[1].to_sym
420
+
421
+ unless env.module_name?(type_name)
422
+ stdout.puts "Cannot find class: #{type_name}"
423
+ return 1
424
+ end
425
+
426
+ definition = case kind
427
+ when :instance
428
+ builder.build_instance(type_name)
429
+ when :singleton
430
+ builder.build_singleton(type_name)
431
+ else
432
+ raise
433
+ end
434
+
435
+ method = definition.methods[method_name]
436
+
437
+ unless method
438
+ stdout.puts "Cannot find method: #{method_name}"
439
+ return 1
440
+ end
441
+
442
+ stdout.puts "#{type_name}#{kind == :instance ? "#" : "."}#{method_name}"
443
+ stdout.puts " defined_in: #{method.defined_in}"
444
+ stdout.puts " implementation: #{method.implemented_in}"
445
+ stdout.puts " accessibility: #{method.accessibility}"
446
+ stdout.puts " types:"
447
+ separator = " "
448
+ length_max = method.method_types.map { |type| type.to_s.length }.max or raise
449
+ method.method_types.each do |type|
450
+ stdout.puts format(" %s %-#{length_max}s at %s", separator, type, type.location)
451
+ separator = "|"
452
+ end
453
+
454
+ 0
455
+ end
456
+
457
+ def run_validate(args, options)
458
+ CLI::Validate.new(args: args, options: options).run
459
+ end
460
+
461
+ def run_constant(args, options)
462
+ # @type var context: String?
463
+ context = nil
464
+
465
+ OptionParser.new do |opts|
466
+ opts.banner = <<EOU
467
+ Usage: rbs constant [options...] [name]
468
+
469
+ Resolve constant based on RBS.
470
+
471
+ Examples:
472
+
473
+ $ rbs constant ::Object
474
+ $ rbs constant UTF_8
475
+ $ rbs constant --context=::Encoding UTF_8
476
+
477
+ Options:
478
+ EOU
479
+ opts.on("--context CONTEXT", "Name of the module where the constant resolution starts") {|c| context = c }
480
+ end.order!(args)
481
+
482
+ unless args.size == 1
483
+ stdout.puts "Expected one argument."
484
+ return 1
485
+ end
486
+
487
+ loader = options.loader()
488
+ env = Environment.from_loader(loader).resolve_type_names
489
+
490
+ builder = DefinitionBuilder.new(env: env)
491
+ resolver = Resolver::ConstantResolver.new(builder: builder)
492
+
493
+ resolver_context = context ? [nil, TypeName.parse(context).absolute!] : nil #: Resolver::context
494
+ stdout.puts "Context: #{context}"
495
+ const_name = TypeName.parse(args[0])
496
+ stdout.puts "Constant name: #{const_name}"
497
+
498
+ if const_name.absolute?
499
+ constant = resolver.table.constant(const_name)
500
+ else
501
+ head, *components = const_name.to_namespace.path
502
+ head or raise
503
+
504
+ constant = resolver.resolve(head, context: resolver_context)
505
+ constant = components.inject(constant) do |const, component|
506
+ if const
507
+ resolver.resolve_child(const.name, component)
508
+ end
509
+ end
510
+ end
511
+
512
+ if constant
513
+ stdout.puts " => #{constant.name}: #{constant.type}"
514
+ else
515
+ stdout.puts " => [no constant]"
516
+ end
517
+
518
+ 0
519
+ end
520
+
521
+ def run_paths(args, options)
522
+ OptionParser.new do |opts|
523
+ opts.banner = <<EOU
524
+ Usage: rbs paths
525
+
526
+ Show paths to directories where the RBS files are loaded from.
527
+
528
+ Examples:
529
+
530
+ $ rbs paths
531
+ $ rbs -r set paths
532
+ EOU
533
+ end.parse!(args)
534
+
535
+ loader = options.loader()
536
+
537
+ kind_of = -> (path) {
538
+ # @type var path: Pathname
539
+ case
540
+ when path.file?
541
+ "file"
542
+ when path.directory?
543
+ "dir"
544
+ when !path.exist?
545
+ "absent"
546
+ else
547
+ "unknown"
548
+ end
549
+ }
550
+
551
+ loader.each_dir do |source, dir|
552
+ case source
553
+ when :core
554
+ stdout.puts "#{dir} (#{kind_of[dir]}, core)"
555
+ when Pathname
556
+ stdout.puts "#{dir} (#{kind_of[dir]})"
557
+ when EnvironmentLoader::Library
558
+ stdout.puts "#{dir} (#{kind_of[dir]}, library, name=#{source.name})"
559
+ end
560
+ end
561
+
562
+ 0
563
+ end
564
+
565
+ def run_prototype(args, options)
566
+ format = args.shift
567
+
568
+ case format
569
+ when "rbi", "rb"
570
+ run_prototype_file(format, args)
571
+ when "runtime"
572
+ require_libs = [] #: Array[String]
573
+ relative_libs = [] #: Array[String]
574
+ merge = false
575
+ todo = false
576
+ owners_included = [] #: Array[Symbol]
577
+ outline = false
578
+ autoload = false
579
+
580
+ OptionParser.new do |opts|
581
+ opts.banner = <<EOU
582
+ Usage: rbs prototype runtime [options...] [pattern...]
583
+
584
+ Generate RBS prototype based on runtime introspection.
585
+ It loads Ruby code specified in [options] and generates RBS prototypes for classes matches to [pattern].
586
+
587
+ Examples:
588
+
589
+ $ rbs prototype runtime String
590
+ $ rbs prototype runtime --require set Set
591
+ $ rbs prototype runtime -R lib/rbs RBS RBS::*
592
+
593
+ Options:
594
+ EOU
595
+ opts.on("-r", "--require LIB", "Load library using `require`") do |lib|
596
+ require_libs << lib
597
+ end
598
+ opts.on("-R", "--require-relative LIB", "Load library using `require_relative`") do |lib|
599
+ relative_libs << lib
600
+ end
601
+ opts.on("--merge", "Merge generated prototype RBS with existing RBS") do
602
+ merge = true
603
+ end
604
+ opts.on("--todo", "Generates only undefined methods compared to objects") do
605
+ Warning.warn("Generating prototypes with `--todo` option is experimental\n", category: :experimental)
606
+ todo = true
607
+ end
608
+ opts.on("--method-owner CLASS", "Generate method prototypes if the owner of the method is [CLASS]") do |klass|
609
+ owners_included << klass.to_sym
610
+ end
611
+ opts.on("--outline", "Generates only module/class/constant declaration (no method definition)") do
612
+ outline = true
613
+ end
614
+ opts.on("--autoload", "Load all autoload path") do
615
+ autoload = true
616
+ end
617
+ end.parse!(args)
618
+
619
+ loader = options.loader()
620
+ env = Environment.from_loader(loader).resolve_type_names
621
+
622
+ # @type var autoloader: ^() { () -> void } -> void
623
+ autoloader = ->(&block) {
624
+ if autoload
625
+ hook = Module.new do
626
+ def autoload(name, path)
627
+ super
628
+ end
629
+ end
630
+ ::Module.prepend(hook)
631
+ ::Kernel.prepend(hook)
632
+
633
+ arguments = [] #: Array[[Module, interned]]
634
+ TracePoint.new(:call) do |tp|
635
+ base = tp.self.kind_of?(Module) ? tp.self : Kernel #: Module
636
+ name = (tp.binding or raise).local_variable_get(:name)
637
+ arguments << [base, name]
638
+ end.enable(target: hook.instance_method(:autoload), &block)
639
+
640
+ arguments.each do |(base, name)|
641
+ begin
642
+ base.const_get(name)
643
+ rescue LoadError, StandardError
644
+ end
645
+ end
646
+ else
647
+ block.call
648
+ end
649
+ }
650
+ autoloader.call do
651
+ require_libs.each do |lib|
652
+ require(lib)
653
+ end
654
+ relative_libs.each do |lib|
655
+ eval("require_relative(lib)", binding, "rbs")
656
+ end
657
+ end
658
+
659
+ runtime = Prototype::Runtime.new(patterns: args, env: env, merge: merge, todo: todo, owners_included: owners_included)
660
+ runtime.outline = outline
661
+
662
+ decls = runtime.decls
663
+
664
+ writer = Writer.new(out: stdout)
665
+ writer.write decls
666
+
667
+ 0
668
+ else
669
+ stdout.puts <<EOU
670
+ Usage: rbs prototype [generator...] [args...]
671
+
672
+ Generate prototype of RBS files.
673
+ Supported generators are rb, rbi, runtime.
674
+
675
+ Examples:
676
+
677
+ $ rbs prototype rb foo.rb
678
+ $ rbs prototype rbi foo.rbi
679
+ $ rbs prototype runtime String
680
+ EOU
681
+ 1
682
+ end
683
+ end
684
+
685
+ def run_prototype_file(format, args)
686
+ availability = unless has_parser?
687
+ "\n** This command does not work on this interpreter (#{RUBY_ENGINE}) **\n"
688
+ end
689
+
690
+ # @type var output_dir: Pathname?
691
+ output_dir = nil
692
+ # @type var base_dir: Pathname?
693
+ base_dir = nil
694
+ # @type var force: bool
695
+ force = false
696
+
697
+ opts = OptionParser.new
698
+ opts.banner = <<EOU
699
+ Usage: rbs prototype #{format} [files...]
700
+ #{availability}
701
+ Generate RBS prototype from source code.
702
+ It parses specified Ruby code and and generates RBS prototypes.
703
+
704
+ It only works on MRI because it parses Ruby code with `RubyVM::AbstractSyntaxTree`.
705
+
706
+ Examples:
707
+
708
+ $ rbs prototype rb lib/foo.rb
709
+ $ rbs prototype rbi sorbet/rbi/foo.rbi
710
+
711
+ You can run the tool in *batch* mode by passing `--out-dir` option.
712
+
713
+ $ rbs prototype rb --out-dir=sig lib/foo.rb
714
+ $ rbs prototype rbi --out-dir=sig/models --base-dir=app/models app/models
715
+ EOU
716
+
717
+ opts.on("--out-dir=DIR", "Specify the path to save the generated RBS files") do |path|
718
+ output_dir = Pathname(path)
719
+ end
720
+
721
+ opts.on("--base-dir=DIR", "Specify the path to calculate the relative path to save the generated RBS files") do |path|
722
+ base_dir = Pathname(path)
723
+ end
724
+
725
+ opts.on("--force", "Overwrite existing RBS files") do
726
+ force = true
727
+ end
728
+
729
+ opts.parse!(args)
730
+
731
+ unless has_parser?
732
+ stdout.puts "Not supported on this interpreter (#{RUBY_ENGINE})."
733
+ return 1
734
+ end
735
+
736
+ if args.empty?
737
+ stdout.puts opts
738
+ return 1
739
+ end
740
+
741
+ new_parser = -> do
742
+ case format
743
+ when "rbi"
744
+ Prototype::RBI.new()
745
+ when "rb"
746
+ Prototype::RB.new()
747
+ else
748
+ raise
749
+ end
750
+ end
751
+
752
+ input_paths = args.map {|arg| Pathname(arg) }
753
+
754
+ if output_dir
755
+ # @type var skip_paths: Array[Pathname]
756
+ skip_paths = []
757
+
758
+ # batch mode
759
+ input_paths.each do |path|
760
+ stdout.puts "Processing `#{path}`..."
761
+ ruby_files =
762
+ if path.file?
763
+ [path]
764
+ else
765
+ path.glob("**/*.rb").sort
766
+ end
767
+
768
+ ruby_files.each do |file_path|
769
+ stdout.puts " Generating RBS for `#{file_path}`..."
770
+
771
+ relative_path =
772
+ if base_dir
773
+ file_path.relative_path_from(base_dir)
774
+ else
775
+ if top = file_path.descend.first
776
+ case
777
+ when top == Pathname("lib")
778
+ file_path.relative_path_from(top)
779
+ when top == Pathname("app")
780
+ file_path.relative_path_from(top)
781
+ else
782
+ file_path
783
+ end
784
+ else
785
+ file_path
786
+ end
787
+ end
788
+ relative_path = relative_path.cleanpath()
789
+
790
+ if relative_path.absolute? || relative_path.descend.first&.to_s == ".."
791
+ stdout.puts " ⚠️ Cannot write the RBS to outside of the output dir: `#{relative_path}`"
792
+ next
793
+ end
794
+
795
+ output_path = (output_dir + relative_path).sub_ext(".rbs")
796
+
797
+ parser = new_parser[]
798
+ begin
799
+ parser.parse file_path.read()
800
+ rescue SyntaxError
801
+ stdout.puts " ⚠️ Unable to parse due to SyntaxError: `#{file_path}`"
802
+ next
803
+ end
804
+
805
+ if output_path.file?
806
+ if force
807
+ stdout.puts " - Writing RBS to existing file `#{output_path}`..."
808
+ else
809
+ stdout.puts " - Skipping existing file `#{output_path}`..."
810
+ skip_paths << file_path
811
+ next
812
+ end
813
+ else
814
+ stdout.puts " - Writing RBS to `#{output_path}`..."
815
+ end
816
+
817
+ (output_path.parent).mkpath
818
+ output_path.open("w") do |io|
819
+ writer = Writer.new(out: io)
820
+ writer.write(parser.decls)
821
+ end
822
+ end
823
+ end
824
+
825
+ unless skip_paths.empty?
826
+ stdout.puts
827
+ stdout.puts ">>>> Skipped existing #{skip_paths.size} files. Use `--force` option to update the files."
828
+ command = original_args.take(original_args.size - input_paths.size)
829
+
830
+ skip_paths.take(10).each do |path|
831
+ stdout.puts " #{defined?(Bundler) ? "bundle exec " : ""}rbs #{Shellwords.join(command)} --force #{Shellwords.escape(path.to_s)}"
832
+ end
833
+ if skip_paths.size > 10
834
+ stdout.puts " ..."
835
+ end
836
+ end
837
+ else
838
+ # file mode
839
+ parser = new_parser[]
840
+
841
+ input_paths.each do |file|
842
+ parser.parse file.read()
843
+ end
844
+
845
+ writer = Writer.new(out: stdout)
846
+ writer.write parser.decls
847
+ end
848
+
849
+ 0
850
+ end
851
+
852
+ def run_vendor(args, options)
853
+ clean = false
854
+ vendor_dir = Pathname("vendor/sigs")
855
+
856
+ OptionParser.new do |opts|
857
+ opts.banner = <<-EOB
858
+ Usage: rbs vendor [options...] [gems...]
859
+
860
+ Vendor signatures in the project directory.
861
+ This command ignores the RBS loading global options, `-r` and `-I`.
862
+
863
+ Examples:
864
+
865
+ $ rbs vendor
866
+ $ rbs vendor --vendor-dir=sig
867
+ $ rbs vendor --no-stdlib
868
+
869
+ Options:
870
+ EOB
871
+
872
+ opts.on("--[no-]clean", "Clean vendor directory (default: no)") do |v|
873
+ clean = v
874
+ end
875
+
876
+ opts.on("--vendor-dir [DIR]", "Specify the directory for vendored signatures (default: vendor/sigs)") do |path|
877
+ vendor_dir = Pathname(path)
878
+ end
879
+ end.parse!(args)
880
+
881
+ stdout.puts "Vendoring signatures to #{vendor_dir}..."
882
+
883
+ loader = options.loader()
884
+
885
+ args.each do |gem|
886
+ name, version = gem.split(/:/, 2)
887
+
888
+ next unless name
889
+
890
+ stdout.puts " Loading library: #{name}, version=#{version}..."
891
+ loader.add(library: name, version: version)
892
+ end
893
+
894
+ vendorer = Vendorer.new(vendor_dir: vendor_dir, loader: loader)
895
+
896
+ if clean
897
+ stdout.puts " Deleting #{vendor_dir}..."
898
+ vendorer.clean!
899
+ end
900
+
901
+ stdout.puts " Copying RBS files..."
902
+ vendorer.copy!
903
+
904
+ 0
905
+ end
906
+
907
+ def run_parse(args, options)
908
+ parse_method = :parse_signature
909
+ # @type var e_code: String?
910
+ e_code = nil
911
+
912
+ OptionParser.new do |opts|
913
+ opts.banner = <<-EOB
914
+ Usage: rbs parse [files...]
915
+
916
+ Parse given RBS files and print syntax errors.
917
+
918
+ Examples:
919
+
920
+ $ rbs parse sig/app/models.rbs sig/app/controllers.rbs
921
+
922
+ Options:
923
+ EOB
924
+
925
+ opts.on('-e CODE', 'One line RBS script to parse') { |e| e_code = e }
926
+ opts.on('--type', 'Parse code as a type') { |e| parse_method = :parse_type }
927
+ opts.on('--method-type', 'Parse code as a method type') { |e| parse_method = :parse_method_type }
928
+ end.parse!(args)
929
+
930
+ syntax_error = false
931
+ bufs = args.flat_map do |path|
932
+ path = Pathname(path)
933
+ FileFinder.each_file(path, skip_hidden: false).map do |file_path|
934
+ Buffer.new(content: file_path.read, name: file_path)
935
+ end
936
+ end
937
+ bufs << Buffer.new(content: e_code, name: Pathname('-e')) if e_code
938
+
939
+ bufs.each do |buf|
940
+ RBS.logger.info "Parsing #{buf.name}..."
941
+ case parse_method
942
+ when :parse_signature
943
+ Parser.parse_signature(buf)
944
+ else
945
+ Parser.public_send(parse_method, buf, require_eof: true)
946
+ end
947
+ rescue RBS::ParsingError => ex
948
+ stdout.print ex.detailed_message(highlight: true)
949
+ syntax_error = true
950
+ end
951
+
952
+ if syntax_error
953
+ 1
954
+ else
955
+ 0
956
+ end
957
+ end
958
+
959
+ def run_annotate(args, options)
960
+ require "rbs/annotate"
961
+
962
+ source = RBS::Annotate::RDocSource.new()
963
+ annotator = RBS::Annotate::RDocAnnotator.new(source: source)
964
+
965
+ OptionParser.new do |opts|
966
+ opts.banner = <<-EOB
967
+ Usage: rbs annotate [options...] [files...]
968
+
969
+ Import documents from RDoc and update RBS files.
970
+
971
+ Examples:
972
+
973
+ $ rbs annotate stdlib/logger/**/*.rbs
974
+
975
+ Options:
976
+ EOB
977
+
978
+ opts.on("--[no-]system", "Load RDoc from system (defaults to true)") {|b| source.with_system_dir = b }
979
+ opts.on("--[no-]gems", "Load RDoc from gems (defaults to false)") {|b| source.with_gems_dir = b }
980
+ opts.on("--[no-]site", "Load RDoc from site directory (defaults to false)") {|b| source.with_site_dir = b }
981
+ opts.on("--[no-]home", "Load RDoc from home directory (defaults to false)") {|b| source.with_home_dir = b }
982
+ opts.on("-d", "--dir DIRNAME", "Load RDoc from DIRNAME") {|d| source.extra_dirs << Pathname(d) }
983
+ opts.on("--[no-]arglists", "Generate arglists section (defaults to true)") {|b| annotator.include_arg_lists = b }
984
+ opts.on("--[no-]filename", "Include source file name in the documentation (defaults to true)") {|b| annotator.include_filename = b }
985
+ opts.on("--[no-]preserve", "[Deprecated] It always preserves the format") { stdout.puts "The `--preserve` option is deprecated. The tool always preserves the format of RBS files." }
986
+ end.parse!(args)
987
+
988
+ source.load()
989
+
990
+ args.each do |file|
991
+ path = Pathname(file)
992
+ if path.directory?
993
+ Pathname.glob((path + "**/*.rbs").to_s).each do |path|
994
+ stdout.puts "Processing #{path}..."
995
+ annotator.annotate_file(path)
996
+ end
997
+ else
998
+ stdout.puts "Processing #{path}..."
999
+ annotator.annotate_file(path)
1000
+ end
1001
+ end
1002
+
1003
+ 0
1004
+ end
1005
+
1006
+ def test_opt options
1007
+ opts = [] #: Array[String]
1008
+
1009
+ opts.push(*options.repos.map {|dir| "--repo #{Shellwords.escape(dir)}"})
1010
+ opts.push(*options.dirs.map {|dir| "-I #{Shellwords.escape(dir)}"})
1011
+ opts.push(*options.libs.map {|lib| "-r#{Shellwords.escape(lib)}"})
1012
+
1013
+ opts.empty? ? nil : opts.join(" ")
1014
+ end
1015
+
1016
+ def run_test(args, options)
1017
+ # @type var unchecked_classes: Array[String]
1018
+ unchecked_classes = []
1019
+ # @type var targets: Array[String]
1020
+ targets = []
1021
+ # @type var sample_size: String?
1022
+ sample_size = nil
1023
+ # @type var double_suite: String?
1024
+ double_suite = nil
1025
+
1026
+ (opts = OptionParser.new do |opts|
1027
+ opts.banner = <<EOB
1028
+ Usage: rbs [rbs options...] test [test options...] COMMAND
1029
+
1030
+ Examples:
1031
+
1032
+ $ rbs test rake test
1033
+ $ rbs --log-level=debug test --target SomeModule::* rspec
1034
+ $ rbs test --target SomeModule::* --target AnotherModule::* --target SomeClass rake test
1035
+
1036
+ Options:
1037
+ EOB
1038
+ opts.on("--target TARGET", "Sets the runtime test target") do |target|
1039
+ targets << target
1040
+ end
1041
+
1042
+ opts.on("--sample-size SAMPLE_SIZE", "Sets the sample size") do |size|
1043
+ sample_size = size
1044
+ end
1045
+
1046
+ opts.on("--unchecked-class UNCHECKED_CLASS", "Sets the class that would not be checked") do |unchecked_class|
1047
+ unchecked_classes << unchecked_class
1048
+ end
1049
+
1050
+ opts.on("--double-suite DOUBLE_SUITE", "Sets the double suite in use (currently supported: rspec | minitest)") do |suite|
1051
+ double_suite = suite
1052
+ end
1053
+ end).order!(args)
1054
+
1055
+ if args.length.zero?
1056
+ stdout.puts opts.help
1057
+ return 1
1058
+ end
1059
+
1060
+ # @type var env_hash: Hash[String, String?]
1061
+ env_hash = {
1062
+ 'RUBYOPT' => "#{ENV['RUBYOPT']} -rrbs/test/setup",
1063
+ 'RBS_TEST_OPT' => test_opt(options),
1064
+ 'RBS_TEST_LOGLEVEL' => %w(DEBUG INFO WARN ERROR FATAL)[RBS.logger_level || 5] || "UNKNOWN",
1065
+ 'RBS_TEST_SAMPLE_SIZE' => sample_size,
1066
+ 'RBS_TEST_DOUBLE_SUITE' => double_suite,
1067
+ 'RBS_TEST_UNCHECKED_CLASSES' => (unchecked_classes.join(',') unless unchecked_classes.empty?),
1068
+ 'RBS_TEST_TARGET' => (targets.join(',') unless targets.empty?)
1069
+ }
1070
+
1071
+ # @type var out: String
1072
+ # @type var err: String
1073
+ # @type var status: Process::Status
1074
+ out, err, status = __skip__ = Open3.capture3(env_hash, *args)
1075
+ stdout.print(out)
1076
+ stderr.print(err)
1077
+
1078
+ status.to_i
1079
+ end
1080
+
1081
+ def run_collection(args, options)
1082
+ require 'bundler'
1083
+
1084
+ opts = collection_options(args)
1085
+ params = {} #: Hash[Symbol, untyped]
1086
+ opts.order args.drop(1), into: params
1087
+ config_path = options.config_path or raise
1088
+ lock_path = Collection::Config.to_lockfile_path(config_path)
1089
+
1090
+ case args[0]
1091
+ when 'install', 'instal', 'insta', 'inst', 'ins', 'in', 'i'
1092
+ unless params[:frozen]
1093
+ Collection::Config.generate_lockfile(config_path: config_path, definition: Bundler.definition)
1094
+ end
1095
+ Collection::Installer.new(lockfile_path: lock_path, stdout: stdout).install_from_lockfile
1096
+ when 'update', 'updat', 'upda', 'upd', 'up', 'u'
1097
+ # TODO: Be aware of argv to update only specified gem
1098
+ Collection::Config.generate_lockfile(config_path: config_path, definition: Bundler.definition, with_lockfile: false)
1099
+ Collection::Installer.new(lockfile_path: lock_path, stdout: stdout).install_from_lockfile
1100
+ when 'init'
1101
+ if config_path.exist?
1102
+ puts "#{config_path} already exists"
1103
+ return 1
1104
+ end
1105
+
1106
+ config_path.write(<<~'YAML')
1107
+ # Download sources
1108
+ sources:
1109
+ - type: git
1110
+ name: ruby/gem_rbs_collection
1111
+ remote: https://github.com/ruby/gem_rbs_collection.git
1112
+ revision: main
1113
+ repo_dir: gems
1114
+
1115
+ # You can specify local directories as sources also.
1116
+ # - type: local
1117
+ # path: path/to/your/local/repository
1118
+
1119
+ # A directory to install the downloaded RBSs
1120
+ path: .gem_rbs_collection
1121
+
1122
+ # gems:
1123
+ # # If you want to avoid installing rbs files for gems, you can specify them here.
1124
+ # - name: GEM_NAME
1125
+ # ignore: true
1126
+ YAML
1127
+ stdout.puts "created: #{config_path}"
1128
+ when 'clean'
1129
+ unless lock_path.exist?
1130
+ puts "#{lock_path} should exist to clean"
1131
+ return 1
1132
+ end
1133
+ Collection::Cleaner.new(lockfile_path: lock_path)
1134
+ when 'help', 'hel', 'he', 'h'
1135
+ puts opts.help
1136
+ else
1137
+ puts opts.help
1138
+ return 1
1139
+ end
1140
+
1141
+ 0
1142
+ end
1143
+
1144
+ def collection_options(args)
1145
+ OptionParser.new do |opts|
1146
+ opts.banner = <<~HELP
1147
+ Usage: rbs collection [install|update|init|clean|help]
1148
+
1149
+ Manage RBS collection, which contains third party RBS.
1150
+
1151
+ Examples:
1152
+
1153
+ # Initialize the configuration file
1154
+ $ rbs collection init
1155
+
1156
+ # Generate the lock file and install RBSs from the lock file
1157
+ $ rbs collection install
1158
+
1159
+ # Update the RBSs
1160
+ $ rbs collection update
1161
+
1162
+ Options:
1163
+ HELP
1164
+ opts.on('--frozen') if args[0] == 'install'
1165
+ end
1166
+ end
1167
+
1168
+ def run_subtract(args, _)
1169
+ write_to_file = false
1170
+ # @type var subtrahend_paths: Array[String]
1171
+ subtrahend_paths = []
1172
+
1173
+ opts = OptionParser.new do |opts|
1174
+ opts.banner = <<~HELP
1175
+ Usage:
1176
+ rbs subtract [options...] minuend.rbs [minuend2.rbs, ...] subtrahend.rbs
1177
+ rbs subtract [options...] minuend.rbs [minuend2.rbs, ...] --subtrahend subtrahend_1.rbs --subtrahend subtrahend_2.rbs
1178
+
1179
+ Remove duplications between RBS files.
1180
+
1181
+ Examples:
1182
+
1183
+ # Generate RBS files from the codebase.
1184
+ $ rbs prototype rb lib/ > generated.rbs
1185
+
1186
+ # Write more descriptive types by hand.
1187
+ $ $EDITOR handwritten.rbs
1188
+
1189
+ # Remove hand-written method definitions from generated.rbs.
1190
+ $ rbs subtract --write generated.rbs handwritten.rbs
1191
+
1192
+ Options:
1193
+ HELP
1194
+ opts.on('-w', '--write', 'Overwrite files directory') { write_to_file = true }
1195
+ opts.on('--subtrahend=PATH', '') { |path| subtrahend_paths << path }
1196
+ opts.parse!(args)
1197
+ end
1198
+
1199
+ if subtrahend_paths.empty?
1200
+ *minuend_paths, subtrahend_path = args
1201
+ unless subtrahend_path
1202
+ stdout.puts opts.help
1203
+ return 1
1204
+ end
1205
+ subtrahend_paths << subtrahend_path
1206
+ else
1207
+ minuend_paths = args
1208
+ end
1209
+
1210
+ if minuend_paths.empty?
1211
+ stdout.puts opts.help
1212
+ return 1
1213
+ end
1214
+
1215
+ subtrahend = Environment.new.tap do |env|
1216
+ loader = EnvironmentLoader.new(core_root: nil)
1217
+ subtrahend_paths.each do |path|
1218
+ loader.add(path: Pathname(path))
1219
+ end
1220
+ loader.load(env: env)
1221
+ end
1222
+
1223
+ minuend_paths.each do |minuend_path|
1224
+ FileFinder.each_file(Pathname(minuend_path), skip_hidden: true) do |rbs_path|
1225
+ buf = Buffer.new(name: rbs_path, content: rbs_path.read)
1226
+ _, dirs, decls = Parser.parse_signature(buf)
1227
+ subtracted = Subtractor.new(decls, subtrahend).call
1228
+
1229
+ io = StringIO.new
1230
+ w = Writer.new(out: io)
1231
+ w.write(dirs)
1232
+ w.write(subtracted)
1233
+
1234
+ if write_to_file
1235
+ if io.string.empty?
1236
+ rbs_path.delete
1237
+ else
1238
+ rbs_path.write(io.string)
1239
+ end
1240
+ else
1241
+ stdout.puts(io.string)
1242
+ end
1243
+ end
1244
+ end
1245
+
1246
+ 0
1247
+ end
1248
+
1249
+ def run_diff(argv, library_options)
1250
+ Diff.new(stdout: stdout, stderr: stderr).run(argv: argv, library_options: library_options)
1251
+ end
1252
+ end
1253
+ end