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.
- checksums.yaml +7 -0
- data/.github/dependabot.yml +22 -0
- data/.github/workflows/comments.yml +35 -0
- data/.github/workflows/dependabot.yml +30 -0
- data/.github/workflows/ruby.yml +82 -0
- data/.github/workflows/typecheck.yml +38 -0
- data/.github/workflows/windows.yml +43 -0
- data/.gitignore +23 -0
- data/.rubocop.yml +68 -0
- data/BSDL +22 -0
- data/CHANGELOG.md +1868 -0
- data/COPYING +56 -0
- data/README.md +203 -0
- data/Rakefile +417 -0
- data/Steepfile +44 -0
- data/config.yml +313 -0
- data/core/array.rbs +4062 -0
- data/core/basic_object.rbs +375 -0
- data/core/binding.rbs +150 -0
- data/core/builtin.rbs +277 -0
- data/core/class.rbs +220 -0
- data/core/comparable.rbs +171 -0
- data/core/complex.rbs +786 -0
- data/core/constants.rbs +96 -0
- data/core/data.rbs +415 -0
- data/core/dir.rbs +981 -0
- data/core/encoding.rbs +1371 -0
- data/core/enumerable.rbs +2405 -0
- data/core/enumerator/product.rbs +92 -0
- data/core/enumerator.rbs +630 -0
- data/core/env.rbs +6 -0
- data/core/errno.rbs +673 -0
- data/core/errors.rbs +760 -0
- data/core/exception.rbs +485 -0
- data/core/false_class.rbs +82 -0
- data/core/fiber.rbs +550 -0
- data/core/fiber_error.rbs +11 -0
- data/core/file.rbs +2936 -0
- data/core/file_test.rbs +331 -0
- data/core/float.rbs +1151 -0
- data/core/gc.rbs +644 -0
- data/core/global_variables.rbs +184 -0
- data/core/hash.rbs +1861 -0
- data/core/integer.rbs +1413 -0
- data/core/io/buffer.rbs +984 -0
- data/core/io/wait.rbs +70 -0
- data/core/io.rbs +3406 -0
- data/core/kernel.rbs +3096 -0
- data/core/marshal.rbs +207 -0
- data/core/match_data.rbs +635 -0
- data/core/math.rbs +729 -0
- data/core/method.rbs +386 -0
- data/core/module.rbs +1704 -0
- data/core/nil_class.rbs +209 -0
- data/core/numeric.rbs +818 -0
- data/core/object.rbs +110 -0
- data/core/object_space/weak_key_map.rbs +166 -0
- data/core/object_space.rbs +190 -0
- data/core/proc.rbs +868 -0
- data/core/process.rbs +2296 -0
- data/core/ractor.rbs +1068 -0
- data/core/random.rbs +237 -0
- data/core/range.rbs +1107 -0
- data/core/rational.rbs +531 -0
- data/core/rb_config.rbs +88 -0
- data/core/rbs/unnamed/argf.rbs +1229 -0
- data/core/rbs/unnamed/env_class.rbs +1209 -0
- data/core/rbs/unnamed/random.rbs +293 -0
- data/core/refinement.rbs +59 -0
- data/core/regexp.rbs +1930 -0
- data/core/ruby_vm.rbs +765 -0
- data/core/rubygems/basic_specification.rbs +6 -0
- data/core/rubygems/config_file.rbs +38 -0
- data/core/rubygems/dependency_installer.rbs +6 -0
- data/core/rubygems/errors.rbs +176 -0
- data/core/rubygems/installer.rbs +15 -0
- data/core/rubygems/path_support.rbs +6 -0
- data/core/rubygems/platform.rbs +7 -0
- data/core/rubygems/request_set.rbs +49 -0
- data/core/rubygems/requirement.rbs +148 -0
- data/core/rubygems/rubygems.rbs +1171 -0
- data/core/rubygems/source_list.rbs +15 -0
- data/core/rubygems/specification.rbs +23 -0
- data/core/rubygems/stream_ui.rbs +5 -0
- data/core/rubygems/uninstaller.rbs +10 -0
- data/core/rubygems/version.rbs +294 -0
- data/core/set.rbs +621 -0
- data/core/signal.rbs +100 -0
- data/core/string.rbs +3583 -0
- data/core/struct.rbs +667 -0
- data/core/symbol.rbs +475 -0
- data/core/thread.rbs +1765 -0
- data/core/thread_group.rbs +79 -0
- data/core/time.rbs +1762 -0
- data/core/trace_point.rbs +477 -0
- data/core/true_class.rbs +98 -0
- data/core/unbound_method.rbs +329 -0
- data/core/warning.rbs +87 -0
- data/docs/CONTRIBUTING.md +106 -0
- data/docs/architecture.md +110 -0
- data/docs/collection.md +192 -0
- data/docs/data_and_struct.md +86 -0
- data/docs/gem.md +57 -0
- data/docs/rbs_by_example.md +309 -0
- data/docs/repo.md +125 -0
- data/docs/sigs.md +167 -0
- data/docs/stdlib.md +147 -0
- data/docs/syntax.md +910 -0
- data/docs/tools.md +17 -0
- data/exe/rbs +7 -0
- data/ext/rbs_extension/extconf.rb +15 -0
- data/ext/rbs_extension/lexer.c +2728 -0
- data/ext/rbs_extension/lexer.h +179 -0
- data/ext/rbs_extension/lexer.re +147 -0
- data/ext/rbs_extension/lexstate.c +175 -0
- data/ext/rbs_extension/location.c +325 -0
- data/ext/rbs_extension/location.h +85 -0
- data/ext/rbs_extension/main.c +33 -0
- data/ext/rbs_extension/parser.c +2973 -0
- data/ext/rbs_extension/parser.h +18 -0
- data/ext/rbs_extension/parserstate.c +397 -0
- data/ext/rbs_extension/parserstate.h +163 -0
- data/ext/rbs_extension/rbs_extension.h +31 -0
- data/ext/rbs_extension/unescape.c +32 -0
- data/goodcheck.yml +91 -0
- data/include/rbs/constants.h +82 -0
- data/include/rbs/ruby_objs.h +72 -0
- data/include/rbs/util/rbs_constant_pool.h +219 -0
- data/include/rbs.h +7 -0
- data/lib/rbs/ancestor_graph.rb +92 -0
- data/lib/rbs/annotate/annotations.rb +199 -0
- data/lib/rbs/annotate/formatter.rb +92 -0
- data/lib/rbs/annotate/rdoc_annotator.rb +400 -0
- data/lib/rbs/annotate/rdoc_source.rb +131 -0
- data/lib/rbs/annotate.rb +8 -0
- data/lib/rbs/ast/annotation.rb +29 -0
- data/lib/rbs/ast/comment.rb +29 -0
- data/lib/rbs/ast/declarations.rb +467 -0
- data/lib/rbs/ast/directives.rb +49 -0
- data/lib/rbs/ast/members.rb +451 -0
- data/lib/rbs/ast/type_param.rb +225 -0
- data/lib/rbs/ast/visitor.rb +137 -0
- data/lib/rbs/buffer.rb +67 -0
- data/lib/rbs/builtin_names.rb +58 -0
- data/lib/rbs/cli/colored_io.rb +48 -0
- data/lib/rbs/cli/diff.rb +83 -0
- data/lib/rbs/cli/validate.rb +357 -0
- data/lib/rbs/cli.rb +1223 -0
- data/lib/rbs/collection/cleaner.rb +38 -0
- data/lib/rbs/collection/config/lockfile.rb +92 -0
- data/lib/rbs/collection/config/lockfile_generator.rb +218 -0
- data/lib/rbs/collection/config.rb +81 -0
- data/lib/rbs/collection/installer.rb +32 -0
- data/lib/rbs/collection/sources/base.rb +14 -0
- data/lib/rbs/collection/sources/git.rb +258 -0
- data/lib/rbs/collection/sources/local.rb +81 -0
- data/lib/rbs/collection/sources/rubygems.rb +48 -0
- data/lib/rbs/collection/sources/stdlib.rb +50 -0
- data/lib/rbs/collection/sources.rb +38 -0
- data/lib/rbs/collection.rb +16 -0
- data/lib/rbs/constant.rb +28 -0
- data/lib/rbs/definition.rb +401 -0
- data/lib/rbs/definition_builder/ancestor_builder.rb +620 -0
- data/lib/rbs/definition_builder/method_builder.rb +254 -0
- data/lib/rbs/definition_builder.rb +845 -0
- data/lib/rbs/diff.rb +125 -0
- data/lib/rbs/environment/use_map.rb +77 -0
- data/lib/rbs/environment.rb +829 -0
- data/lib/rbs/environment_loader.rb +173 -0
- data/lib/rbs/environment_walker.rb +155 -0
- data/lib/rbs/errors.rb +645 -0
- data/lib/rbs/factory.rb +18 -0
- data/lib/rbs/file_finder.rb +28 -0
- data/lib/rbs/location_aux.rb +138 -0
- data/lib/rbs/locator.rb +243 -0
- data/lib/rbs/method_type.rb +143 -0
- data/lib/rbs/namespace.rb +125 -0
- data/lib/rbs/parser/lex_result.rb +15 -0
- data/lib/rbs/parser/token.rb +23 -0
- data/lib/rbs/parser_aux.rb +114 -0
- data/lib/rbs/prototype/helpers.rb +140 -0
- data/lib/rbs/prototype/node_usage.rb +99 -0
- data/lib/rbs/prototype/rb.rb +840 -0
- data/lib/rbs/prototype/rbi.rb +641 -0
- data/lib/rbs/prototype/runtime/helpers.rb +59 -0
- data/lib/rbs/prototype/runtime/reflection.rb +19 -0
- data/lib/rbs/prototype/runtime/value_object_generator.rb +279 -0
- data/lib/rbs/prototype/runtime.rb +667 -0
- data/lib/rbs/repository.rb +127 -0
- data/lib/rbs/resolver/constant_resolver.rb +219 -0
- data/lib/rbs/resolver/type_name_resolver.rb +91 -0
- data/lib/rbs/sorter.rb +198 -0
- data/lib/rbs/substitution.rb +83 -0
- data/lib/rbs/subtractor.rb +201 -0
- data/lib/rbs/test/errors.rb +80 -0
- data/lib/rbs/test/guaranteed.rb +30 -0
- data/lib/rbs/test/hook.rb +212 -0
- data/lib/rbs/test/observer.rb +19 -0
- data/lib/rbs/test/setup.rb +84 -0
- data/lib/rbs/test/setup_helper.rb +50 -0
- data/lib/rbs/test/tester.rb +167 -0
- data/lib/rbs/test/type_check.rb +435 -0
- data/lib/rbs/test.rb +112 -0
- data/lib/rbs/type_alias_dependency.rb +100 -0
- data/lib/rbs/type_alias_regularity.rb +126 -0
- data/lib/rbs/type_name.rb +109 -0
- data/lib/rbs/types.rb +1596 -0
- data/lib/rbs/unit_test/convertibles.rb +176 -0
- data/lib/rbs/unit_test/spy.rb +138 -0
- data/lib/rbs/unit_test/type_assertions.rb +347 -0
- data/lib/rbs/unit_test/with_aliases.rb +143 -0
- data/lib/rbs/unit_test.rb +6 -0
- data/lib/rbs/validator.rb +186 -0
- data/lib/rbs/variance_calculator.rb +189 -0
- data/lib/rbs/vendorer.rb +71 -0
- data/lib/rbs/version.rb +5 -0
- data/lib/rbs/writer.rb +424 -0
- data/lib/rbs.rb +94 -0
- data/lib/rdoc/discover.rb +20 -0
- data/lib/rdoc_plugin/parser.rb +163 -0
- data/rbs-relaxed.gemspec +48 -0
- data/schema/annotation.json +14 -0
- data/schema/comment.json +26 -0
- data/schema/decls.json +326 -0
- data/schema/function.json +87 -0
- data/schema/location.json +56 -0
- data/schema/members.json +266 -0
- data/schema/methodType.json +50 -0
- data/schema/typeParam.json +36 -0
- data/schema/types.json +317 -0
- data/sig/ancestor_builder.rbs +163 -0
- data/sig/ancestor_graph.rbs +60 -0
- data/sig/annotate/annotations.rbs +102 -0
- data/sig/annotate/formatter.rbs +24 -0
- data/sig/annotate/rdoc_annotater.rbs +82 -0
- data/sig/annotate/rdoc_source.rbs +30 -0
- data/sig/annotation.rbs +27 -0
- data/sig/buffer.rbs +32 -0
- data/sig/builtin_names.rbs +44 -0
- data/sig/cli/colored_io.rbs +15 -0
- data/sig/cli/diff.rbs +21 -0
- data/sig/cli/validate.rbs +43 -0
- data/sig/cli.rbs +87 -0
- data/sig/collection/cleaner.rbs +13 -0
- data/sig/collection/config/lockfile.rbs +74 -0
- data/sig/collection/config/lockfile_generator.rbs +66 -0
- data/sig/collection/config.rbs +46 -0
- data/sig/collection/installer.rbs +17 -0
- data/sig/collection/sources.rbs +214 -0
- data/sig/collection.rbs +4 -0
- data/sig/comment.rbs +26 -0
- data/sig/constant.rbs +21 -0
- data/sig/declarations.rbs +267 -0
- data/sig/definition.rbs +173 -0
- data/sig/definition_builder.rbs +165 -0
- data/sig/diff.rbs +28 -0
- data/sig/directives.rbs +77 -0
- data/sig/environment.rbs +279 -0
- data/sig/environment_loader.rbs +111 -0
- data/sig/environment_walker.rbs +65 -0
- data/sig/errors.rbs +405 -0
- data/sig/factory.rbs +5 -0
- data/sig/file_finder.rbs +28 -0
- data/sig/location.rbs +110 -0
- data/sig/locator.rbs +58 -0
- data/sig/manifest.yaml +7 -0
- data/sig/members.rbs +258 -0
- data/sig/method_builder.rbs +84 -0
- data/sig/method_types.rbs +58 -0
- data/sig/namespace.rbs +146 -0
- data/sig/parser.rbs +100 -0
- data/sig/prototype/helpers.rbs +27 -0
- data/sig/prototype/node_usage.rbs +20 -0
- data/sig/prototype/rb.rbs +96 -0
- data/sig/prototype/rbi.rbs +75 -0
- data/sig/prototype/runtime.rbs +182 -0
- data/sig/rbs.rbs +21 -0
- data/sig/rdoc/rbs.rbs +67 -0
- data/sig/repository.rbs +85 -0
- data/sig/resolver/constant_resolver.rbs +92 -0
- data/sig/resolver/context.rbs +34 -0
- data/sig/resolver/type_name_resolver.rbs +35 -0
- data/sig/shims/bundler.rbs +38 -0
- data/sig/shims/enumerable.rbs +5 -0
- data/sig/shims/rubygems.rbs +19 -0
- data/sig/sorter.rbs +41 -0
- data/sig/substitution.rbs +48 -0
- data/sig/subtractor.rbs +37 -0
- data/sig/test/errors.rbs +52 -0
- data/sig/test/guranteed.rbs +9 -0
- data/sig/test/type_check.rbs +19 -0
- data/sig/test.rbs +82 -0
- data/sig/type_alias_dependency.rbs +53 -0
- data/sig/type_alias_regularity.rbs +98 -0
- data/sig/type_param.rbs +110 -0
- data/sig/typename.rbs +79 -0
- data/sig/types.rbs +579 -0
- data/sig/unit_test/convertibles.rbs +154 -0
- data/sig/unit_test/spy.rbs +30 -0
- data/sig/unit_test/type_assertions.rbs +196 -0
- data/sig/unit_test/with_aliases.rbs +136 -0
- data/sig/use_map.rbs +35 -0
- data/sig/util.rbs +9 -0
- data/sig/validator.rbs +63 -0
- data/sig/variance_calculator.rbs +87 -0
- data/sig/vendorer.rbs +51 -0
- data/sig/version.rbs +3 -0
- data/sig/visitor.rbs +47 -0
- data/sig/writer.rbs +127 -0
- data/src/constants.c +153 -0
- data/src/ruby_objs.c +795 -0
- data/src/util/rbs_constant_pool.c +342 -0
- data/stdlib/abbrev/0/abbrev.rbs +66 -0
- data/stdlib/abbrev/0/array.rbs +26 -0
- data/stdlib/base64/0/base64.rbs +355 -0
- data/stdlib/benchmark/0/benchmark.rbs +452 -0
- data/stdlib/bigdecimal/0/big_decimal.rbs +1629 -0
- data/stdlib/bigdecimal-math/0/big_math.rbs +119 -0
- data/stdlib/bigdecimal-math/0/manifest.yaml +2 -0
- data/stdlib/cgi/0/core.rbs +1285 -0
- data/stdlib/cgi/0/manifest.yaml +3 -0
- data/stdlib/coverage/0/coverage.rbs +263 -0
- data/stdlib/csv/0/csv.rbs +3776 -0
- data/stdlib/csv/0/manifest.yaml +3 -0
- data/stdlib/date/0/date.rbs +1585 -0
- data/stdlib/date/0/date_time.rbs +616 -0
- data/stdlib/date/0/time.rbs +26 -0
- data/stdlib/dbm/0/dbm.rbs +421 -0
- data/stdlib/delegate/0/delegator.rbs +184 -0
- data/stdlib/delegate/0/kernel.rbs +47 -0
- data/stdlib/delegate/0/simple_delegator.rbs +96 -0
- data/stdlib/did_you_mean/0/did_you_mean.rbs +343 -0
- data/stdlib/digest/0/digest.rbs +577 -0
- data/stdlib/erb/0/erb.rbs +532 -0
- data/stdlib/etc/0/etc.rbs +865 -0
- data/stdlib/fileutils/0/fileutils.rbs +1734 -0
- data/stdlib/find/0/find.rbs +49 -0
- data/stdlib/forwardable/0/forwardable.rbs +268 -0
- data/stdlib/io-console/0/io-console.rbs +414 -0
- data/stdlib/ipaddr/0/ipaddr.rbs +428 -0
- data/stdlib/json/0/json.rbs +1916 -0
- data/stdlib/kconv/0/kconv.rbs +166 -0
- data/stdlib/logger/0/formatter.rbs +45 -0
- data/stdlib/logger/0/log_device.rbs +100 -0
- data/stdlib/logger/0/logger.rbs +796 -0
- data/stdlib/logger/0/manifest.yaml +2 -0
- data/stdlib/logger/0/period.rbs +17 -0
- data/stdlib/logger/0/severity.rbs +34 -0
- data/stdlib/minitest/0/kernel.rbs +42 -0
- data/stdlib/minitest/0/minitest/abstract_reporter.rbs +52 -0
- data/stdlib/minitest/0/minitest/assertion.rbs +17 -0
- data/stdlib/minitest/0/minitest/assertions.rbs +590 -0
- data/stdlib/minitest/0/minitest/backtrace_filter.rbs +23 -0
- data/stdlib/minitest/0/minitest/bench_spec.rbs +102 -0
- data/stdlib/minitest/0/minitest/benchmark.rbs +259 -0
- data/stdlib/minitest/0/minitest/composite_reporter.rbs +25 -0
- data/stdlib/minitest/0/minitest/compress.rbs +13 -0
- data/stdlib/minitest/0/minitest/error_on_warning.rbs +3 -0
- data/stdlib/minitest/0/minitest/expectation.rbs +2 -0
- data/stdlib/minitest/0/minitest/expectations.rbs +21 -0
- data/stdlib/minitest/0/minitest/guard.rbs +64 -0
- data/stdlib/minitest/0/minitest/mock.rbs +64 -0
- data/stdlib/minitest/0/minitest/parallel/executor.rbs +46 -0
- data/stdlib/minitest/0/minitest/parallel/test/class_methods.rbs +5 -0
- data/stdlib/minitest/0/minitest/parallel/test.rbs +3 -0
- data/stdlib/minitest/0/minitest/parallel.rbs +2 -0
- data/stdlib/minitest/0/minitest/pride_io.rbs +62 -0
- data/stdlib/minitest/0/minitest/pride_lol.rbs +19 -0
- data/stdlib/minitest/0/minitest/progress_reporter.rbs +11 -0
- data/stdlib/minitest/0/minitest/reportable.rbs +53 -0
- data/stdlib/minitest/0/minitest/reporter.rbs +5 -0
- data/stdlib/minitest/0/minitest/result.rbs +28 -0
- data/stdlib/minitest/0/minitest/runnable.rbs +163 -0
- data/stdlib/minitest/0/minitest/skip.rbs +6 -0
- data/stdlib/minitest/0/minitest/spec/dsl/instance_methods.rbs +48 -0
- data/stdlib/minitest/0/minitest/spec/dsl.rbs +129 -0
- data/stdlib/minitest/0/minitest/spec.rbs +11 -0
- data/stdlib/minitest/0/minitest/statistics_reporter.rbs +81 -0
- data/stdlib/minitest/0/minitest/summary_reporter.rbs +18 -0
- data/stdlib/minitest/0/minitest/test/lifecycle_hooks.rbs +92 -0
- data/stdlib/minitest/0/minitest/test.rbs +69 -0
- data/stdlib/minitest/0/minitest/unexpected_error.rbs +12 -0
- data/stdlib/minitest/0/minitest/unexpected_warning.rbs +6 -0
- data/stdlib/minitest/0/minitest/unit/test_case.rbs +3 -0
- data/stdlib/minitest/0/minitest/unit.rbs +4 -0
- data/stdlib/minitest/0/minitest.rbs +115 -0
- data/stdlib/monitor/0/monitor.rbs +363 -0
- data/stdlib/mutex_m/0/mutex_m.rbs +104 -0
- data/stdlib/net-http/0/manifest.yaml +3 -0
- data/stdlib/net-http/0/net-http.rbs +5552 -0
- data/stdlib/net-protocol/0/manifest.yaml +2 -0
- data/stdlib/net-protocol/0/net-protocol.rbs +56 -0
- data/stdlib/net-smtp/0/manifest.yaml +2 -0
- data/stdlib/net-smtp/0/net-smtp.rbs +55 -0
- data/stdlib/nkf/0/nkf.rbs +402 -0
- data/stdlib/objspace/0/objspace.rbs +487 -0
- data/stdlib/observable/0/observable.rbs +217 -0
- data/stdlib/open-uri/0/manifest.yaml +4 -0
- data/stdlib/open-uri/0/open-uri.rbs +393 -0
- data/stdlib/open3/0/open3.rbs +147 -0
- data/stdlib/openssl/0/manifest.yaml +3 -0
- data/stdlib/openssl/0/openssl.rbs +12113 -0
- data/stdlib/optparse/0/optparse.rbs +1725 -0
- data/stdlib/pathname/0/pathname.rbs +1406 -0
- data/stdlib/pp/0/manifest.yaml +2 -0
- data/stdlib/pp/0/pp.rbs +300 -0
- data/stdlib/prettyprint/0/prettyprint.rbs +383 -0
- data/stdlib/pstore/0/pstore.rbs +603 -0
- data/stdlib/psych/0/core_ext.rbs +12 -0
- data/stdlib/psych/0/dbm.rbs +237 -0
- data/stdlib/psych/0/manifest.yaml +3 -0
- data/stdlib/psych/0/psych.rbs +402 -0
- data/stdlib/psych/0/store.rbs +59 -0
- data/stdlib/pty/0/pty.rbs +237 -0
- data/stdlib/rdoc/0/code_object.rbs +51 -0
- data/stdlib/rdoc/0/comment.rbs +59 -0
- data/stdlib/rdoc/0/context.rbs +153 -0
- data/stdlib/rdoc/0/markup.rbs +117 -0
- data/stdlib/rdoc/0/parser.rbs +56 -0
- data/stdlib/rdoc/0/rdoc.rbs +391 -0
- data/stdlib/rdoc/0/ri.rbs +17 -0
- data/stdlib/rdoc/0/store.rbs +48 -0
- data/stdlib/rdoc/0/top_level.rbs +97 -0
- data/stdlib/resolv/0/manifest.yaml +3 -0
- data/stdlib/resolv/0/resolv.rbs +1830 -0
- data/stdlib/ripper/0/ripper.rbs +1648 -0
- data/stdlib/securerandom/0/securerandom.rbs +62 -0
- data/stdlib/shellwords/0/shellwords.rbs +229 -0
- data/stdlib/singleton/0/singleton.rbs +131 -0
- data/stdlib/socket/0/addrinfo.rbs +666 -0
- data/stdlib/socket/0/basic_socket.rbs +590 -0
- data/stdlib/socket/0/constants.rbs +2295 -0
- data/stdlib/socket/0/ip_socket.rbs +92 -0
- data/stdlib/socket/0/socket.rbs +4157 -0
- data/stdlib/socket/0/socket_error.rbs +5 -0
- data/stdlib/socket/0/tcp_server.rbs +192 -0
- data/stdlib/socket/0/tcp_socket.rbs +79 -0
- data/stdlib/socket/0/udp_socket.rbs +133 -0
- data/stdlib/socket/0/unix_server.rbs +169 -0
- data/stdlib/socket/0/unix_socket.rbs +172 -0
- data/stdlib/stringio/0/stringio.rbs +567 -0
- data/stdlib/strscan/0/string_scanner.rbs +1627 -0
- data/stdlib/tempfile/0/tempfile.rbs +479 -0
- data/stdlib/time/0/time.rbs +432 -0
- data/stdlib/timeout/0/timeout.rbs +81 -0
- data/stdlib/tmpdir/0/tmpdir.rbs +69 -0
- data/stdlib/tsort/0/cyclic.rbs +5 -0
- data/stdlib/tsort/0/interfaces.rbs +20 -0
- data/stdlib/tsort/0/tsort.rbs +409 -0
- data/stdlib/uri/0/common.rbs +582 -0
- data/stdlib/uri/0/file.rbs +118 -0
- data/stdlib/uri/0/ftp.rbs +13 -0
- data/stdlib/uri/0/generic.rbs +1108 -0
- data/stdlib/uri/0/http.rbs +104 -0
- data/stdlib/uri/0/https.rbs +14 -0
- data/stdlib/uri/0/ldap.rbs +230 -0
- data/stdlib/uri/0/ldaps.rbs +14 -0
- data/stdlib/uri/0/mailto.rbs +92 -0
- data/stdlib/uri/0/rfc2396_parser.rbs +189 -0
- data/stdlib/uri/0/rfc3986_parser.rbs +2 -0
- data/stdlib/uri/0/ws.rbs +13 -0
- data/stdlib/uri/0/wss.rbs +9 -0
- data/stdlib/yaml/0/manifest.yaml +2 -0
- data/stdlib/yaml/0/yaml.rbs +1 -0
- data/stdlib/zlib/0/buf_error.rbs +10 -0
- data/stdlib/zlib/0/data_error.rbs +10 -0
- data/stdlib/zlib/0/deflate.rbs +210 -0
- data/stdlib/zlib/0/error.rbs +20 -0
- data/stdlib/zlib/0/gzip_file/crc_error.rbs +12 -0
- data/stdlib/zlib/0/gzip_file/error.rbs +23 -0
- data/stdlib/zlib/0/gzip_file/length_error.rbs +12 -0
- data/stdlib/zlib/0/gzip_file/no_footer.rbs +11 -0
- data/stdlib/zlib/0/gzip_file.rbs +156 -0
- data/stdlib/zlib/0/gzip_reader.rbs +293 -0
- data/stdlib/zlib/0/gzip_writer.rbs +166 -0
- data/stdlib/zlib/0/inflate.rbs +180 -0
- data/stdlib/zlib/0/mem_error.rbs +10 -0
- data/stdlib/zlib/0/need_dict.rbs +13 -0
- data/stdlib/zlib/0/stream_end.rbs +11 -0
- data/stdlib/zlib/0/stream_error.rbs +11 -0
- data/stdlib/zlib/0/version_error.rbs +11 -0
- data/stdlib/zlib/0/zlib.rbs +449 -0
- data/stdlib/zlib/0/zstream.rbs +200 -0
- 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
|