rbs-relaxed 3.9.0.1

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