rigortype 0.3.6 → 0.3.8
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 +4 -4
- data/README.md +1 -1
- data/data/builtins/ruby_core/date.yml +6 -3
- data/data/builtins/ruby_core/enumerable.yml +1 -0
- data/data/builtins/ruby_core/exception.yml +2 -1
- data/data/builtins/ruby_core/file.yml +28 -14
- data/data/builtins/ruby_core/hash.yml +5 -2
- data/data/builtins/ruby_core/io.yml +33 -16
- data/data/builtins/ruby_core/random.yml +2 -1
- data/data/builtins/ruby_core/re.yml +6 -3
- data/data/builtins/ruby_core/struct.yml +2 -0
- data/data/builtins/ruby_core/time.yml +2 -1
- data/data/gem_overlay/activesupport/core_ext.rbs +409 -11
- data/docs/handbook/11-sig-gen.md +24 -14
- data/docs/manual/02-cli-reference.md +23 -7
- data/docs/manual/04-diagnostics.md +1 -1
- data/docs/manual/05-inspecting-types.md +20 -8
- data/docs/manual/07-plugins.md +4 -0
- data/docs/manual/plugins/rigor-actionpack.md +61 -0
- data/docs/manual/plugins/rigor-activerecord.md +74 -1
- data/docs/manual/plugins/rigor-activesupport-core-ext.md +114 -12
- data/docs/manual/plugins/rigor-sidekiq.md +22 -0
- data/lib/rigor/analysis/check_rules/always_truthy_condition_collector.rb +12 -0
- data/lib/rigor/analysis/check_rules/dead_version_guard_arms.rb +98 -0
- data/lib/rigor/analysis/check_rules/ivar_write_collector.rb +3 -3
- data/lib/rigor/analysis/check_rules/published_constant_guard.rb +199 -0
- data/lib/rigor/analysis/check_rules/rule_walk.rb +1 -2
- data/lib/rigor/analysis/check_rules/self_closedness_scanner.rb +2 -2
- data/lib/rigor/analysis/check_rules/shadowed_rescue_collector.rb +6 -12
- data/lib/rigor/analysis/check_rules.rb +383 -48
- data/lib/rigor/analysis/crash_signature.rb +188 -0
- data/lib/rigor/analysis/dependency_recorder.rb +18 -3
- data/lib/rigor/analysis/dependency_source_inference/walker.rb +2 -1
- data/lib/rigor/analysis/incremental.rb +28 -0
- data/lib/rigor/analysis/incremental_session.rb +63 -16
- data/lib/rigor/analysis/plugin_fact_fingerprint.rb +1 -2
- data/lib/rigor/analysis/reachability/graph.rb +14 -5
- data/lib/rigor/analysis/reachability/scan.rb +7 -3
- data/lib/rigor/analysis/result.rb +32 -0
- data/lib/rigor/analysis/run_cache_key.rb +41 -1
- data/lib/rigor/analysis/runner/diagnostic_aggregator.rb +233 -16
- data/lib/rigor/analysis/runner/pool_coordinator.rb +266 -47
- data/lib/rigor/analysis/runner/project_pre_passes.rb +15 -11
- data/lib/rigor/analysis/runner/run_snapshots.rb +12 -2
- data/lib/rigor/analysis/runner.rb +212 -16
- data/lib/rigor/analysis/worker_session.rb +37 -3
- data/lib/rigor/bleeding_edge.rb +7 -6
- data/lib/rigor/builtins/hkt_builtins.rb +45 -6
- data/lib/rigor/builtins/imported_refinements.rb +11 -9
- data/lib/rigor/builtins/predefined_constant_refinements.rb +108 -59
- data/lib/rigor/builtins/static_return_refinements.rb +20 -1
- data/lib/rigor/cache/annotation_location.rb +72 -0
- data/lib/rigor/cache/descriptor.rb +42 -2
- data/lib/rigor/cache/incremental_snapshot.rb +40 -3
- data/lib/rigor/cache/rbs_environment_marshal_patch.rb +70 -8
- data/lib/rigor/cache/store.rb +17 -1
- data/lib/rigor/cli/coverage_command.rb +23 -18
- data/lib/rigor/cli/coverage_mutation.rb +13 -17
- data/lib/rigor/cli/coverage_scan.rb +47 -6
- data/lib/rigor/cli/fused_protection_renderer.rb +19 -2
- data/lib/rigor/cli/fused_protection_report.rb +23 -2
- data/lib/rigor/cli/measurement_integrity_warning.rb +57 -0
- data/lib/rigor/cli/mutation_protection_renderer.rb +22 -2
- data/lib/rigor/cli/mutation_protection_report.rb +31 -2
- data/lib/rigor/cli/sig_gen_command.rb +47 -0
- data/lib/rigor/cli/type_of_command.rb +188 -41
- data/lib/rigor/cli/type_of_renderer.rb +72 -3
- data/lib/rigor/cli/type_scan_command.rb +10 -1
- data/lib/rigor/cli.rb +1 -1
- data/lib/rigor/configuration.rb +7 -4
- data/lib/rigor/effects/plugin_facts.rb +1 -1
- data/lib/rigor/effects/scanner.rb +2 -3
- data/lib/rigor/environment/bundle_sig_discovery.rb +64 -13
- data/lib/rigor/environment/failure_slot.rb +28 -0
- data/lib/rigor/environment/lockfile_resolver.rb +15 -5
- data/lib/rigor/environment/missing_gem_constant_index.rb +45 -4
- data/lib/rigor/environment/rbs_hierarchy.rb +16 -22
- data/lib/rigor/environment/rbs_loader.rb +743 -93
- data/lib/rigor/environment.rb +125 -25
- data/lib/rigor/inference/acceptance.rb +172 -20
- data/lib/rigor/inference/captured_locals.rb +62 -0
- data/lib/rigor/inference/content_join.rb +347 -0
- data/lib/rigor/inference/def_handle.rb +15 -3
- data/lib/rigor/inference/def_node_resolver.rb +62 -3
- data/lib/rigor/inference/expression_typer.rb +1020 -141
- data/lib/rigor/inference/fork_map.rb +6 -1
- data/lib/rigor/inference/hkt_reducer.rb +12 -1
- data/lib/rigor/inference/hkt_registry.rb +61 -3
- data/lib/rigor/inference/hkt_sugar_translator.rb +87 -0
- data/lib/rigor/inference/index_write_widening.rb +48 -0
- data/lib/rigor/inference/indexed_narrowing.rb +14 -0
- data/lib/rigor/inference/method_dispatcher/block_folding.rb +7 -5
- data/lib/rigor/inference/method_dispatcher/constant_folding.rb +10 -0
- data/lib/rigor/inference/method_dispatcher/json_folding.rb +58 -0
- data/lib/rigor/inference/method_dispatcher/overload_selector.rb +81 -38
- data/lib/rigor/inference/method_dispatcher/rbs_dispatch.rb +54 -17
- data/lib/rigor/inference/method_dispatcher/shape_dispatch.rb +1 -2
- data/lib/rigor/inference/method_dispatcher/singleton_mixin_dispatch.rb +63 -0
- data/lib/rigor/inference/method_dispatcher/struct_folding.rb +63 -10
- data/lib/rigor/inference/method_dispatcher/struct_materialization.rb +104 -0
- data/lib/rigor/inference/method_dispatcher/universal_object_dispatch.rb +81 -0
- data/lib/rigor/inference/method_dispatcher.rb +155 -14
- data/lib/rigor/inference/method_parameter_binder.rb +3 -3
- data/lib/rigor/inference/mutation_widening.rb +244 -174
- data/lib/rigor/inference/narrowing.rb +331 -27
- data/lib/rigor/inference/parameter_inference_collector.rb +1 -0
- data/lib/rigor/inference/pre_eval_constants.rb +15 -0
- data/lib/rigor/inference/precision_scanner.rb +5 -2
- data/lib/rigor/inference/project_patched_scanner.rb +2 -1
- data/lib/rigor/inference/rbs_type_translator.rb +89 -39
- data/lib/rigor/inference/scope_indexer.rb +1493 -140
- data/lib/rigor/inference/statement_evaluator.rb +276 -91
- data/lib/rigor/inference/struct_fold_safety.rb +186 -27
- data/lib/rigor/inference/version_guard.rb +229 -0
- data/lib/rigor/language_server/selection_range_provider.rb +1 -1
- data/lib/rigor/plugin/base.rb +3 -2
- data/lib/rigor/plugin/inflector.rb +14 -5
- data/lib/rigor/plugin/io_boundary.rb +107 -4
- data/lib/rigor/plugin/loader.rb +14 -0
- data/lib/rigor/plugin/registry.rb +25 -2
- data/lib/rigor/protection/analysis_guard.rb +60 -0
- data/lib/rigor/protection/closure_kill_oracle.rb +43 -38
- data/lib/rigor/protection/diagnostic_oracle.rb +12 -4
- data/lib/rigor/protection/discovery_seed.rb +1 -1
- data/lib/rigor/protection/measurement_integrity.rb +36 -0
- data/lib/rigor/protection/mutation_scanner.rb +61 -6
- data/lib/rigor/protection/mutator.rb +121 -18
- data/lib/rigor/rbs_extended/envelope_scanner.rb +8 -7
- data/lib/rigor/rbs_extended/hkt_directives.rb +16 -1
- data/lib/rigor/rbs_extended/reporter.rb +93 -13
- data/lib/rigor/rbs_extended.rb +6 -1
- data/lib/rigor/reflection.rb +182 -30
- data/lib/rigor/scope/discovery_index.rb +39 -1
- data/lib/rigor/scope.rb +385 -4
- data/lib/rigor/sig_gen/classification.rb +12 -1
- data/lib/rigor/sig_gen/generator.rb +320 -85
- data/lib/rigor/sig_gen/renderer.rb +14 -12
- data/lib/rigor/sig_gen/writer.rb +3 -0
- data/lib/rigor/source/constant_path.rb +79 -2
- data/lib/rigor/triage/catalogue.rb +1 -1
- data/lib/rigor/type/combinator.rb +10 -0
- data/lib/rigor/type/maybe.rb +47 -0
- data/lib/rigor/type/refined.rb +1 -2
- data/lib/rigor/type/result.rb +53 -0
- data/lib/rigor/type.rb +2 -0
- data/lib/rigor/version.rb +1 -1
- data/plugins/rigor-actioncable/lib/rigor/plugin/actioncable/analyzer.rb +3 -1
- data/plugins/rigor-actioncable/lib/rigor/plugin/actioncable/channel_discoverer.rb +58 -8
- data/plugins/rigor-actioncable/lib/rigor/plugin/actioncable/channel_index.rb +15 -2
- data/plugins/rigor-actioncable/lib/rigor/plugin/actioncable.rb +4 -1
- data/plugins/rigor-actionmailer/lib/rigor/plugin/actionmailer/analyzer.rb +3 -1
- data/plugins/rigor-actionmailer/lib/rigor/plugin/actionmailer/mailer_discoverer.rb +39 -14
- data/plugins/rigor-actionmailer/lib/rigor/plugin/actionmailer/mailer_index.rb +36 -3
- data/plugins/rigor-actionmailer/lib/rigor/plugin/actionmailer.rb +6 -2
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/analyzer.rb +21 -5
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/controller_discoverer.rb +47 -8
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/controller_index.rb +13 -3
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack.rb +242 -4
- data/plugins/rigor-activejob/lib/rigor/plugin/activejob/analyzer.rb +3 -1
- data/plugins/rigor-activejob/lib/rigor/plugin/activejob/effects.rb +7 -3
- data/plugins/rigor-activejob/lib/rigor/plugin/activejob/job_discoverer.rb +62 -11
- data/plugins/rigor-activejob/lib/rigor/plugin/activejob/job_index.rb +15 -2
- data/plugins/rigor-activejob/lib/rigor/plugin/activejob/recurring_scan.rb +3 -1
- data/plugins/rigor-activejob/lib/rigor/plugin/activejob.rb +5 -1
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/analyzer.rb +2 -2
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/model_discoverer.rb +798 -22
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/model_index.rb +156 -13
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord.rb +140 -40
- data/plugins/rigor-activestorage/lib/rigor/plugin/activestorage/analyzer.rb +2 -2
- data/plugins/rigor-activestorage/lib/rigor/plugin/activestorage/attachment_discoverer.rb +20 -6
- data/plugins/rigor-activestorage/lib/rigor/plugin/activestorage/attachment_index.rb +14 -4
- data/plugins/rigor-activestorage/lib/rigor/plugin/activestorage.rb +6 -3
- data/plugins/rigor-activesupport-core-ext/lib/rigor/plugin/activesupport_core_ext/effects.rb +23 -6
- data/plugins/rigor-activesupport-core-ext/lib/rigor/plugin/activesupport_core_ext.rb +264 -9
- data/plugins/rigor-activesupport-core-ext/sig/active_support/core_ext.rbs +876 -23
- data/plugins/rigor-dry-monads/lib/rigor/plugin/dry_monads.rb +99 -0
- data/plugins/rigor-dry-monads/lib/rigor-dry-monads.rb +5 -0
- data/plugins/rigor-ethon/lib/rigor/plugin/ethon.rb +34 -0
- data/plugins/rigor-ethon/lib/rigor-ethon.rb +3 -0
- data/plugins/rigor-ethon/sig/ethon.rbs +27 -0
- data/plugins/rigor-factorybot/lib/rigor/plugin/factorybot/factory_discoverer.rb +3 -2
- data/plugins/rigor-ffi/lib/rigor/plugin/ffi/analyzer.rb +198 -0
- data/plugins/rigor-ffi/lib/rigor/plugin/ffi/binding_recognizer.rb +75 -0
- data/plugins/rigor-ffi/lib/rigor/plugin/ffi/catalog.rb +64 -0
- data/plugins/rigor-ffi/lib/rigor/plugin/ffi/discoverer.rb +173 -0
- data/plugins/rigor-ffi/lib/rigor/plugin/ffi/target_detector.rb +46 -0
- data/plugins/rigor-ffi/lib/rigor/plugin/ffi/types.rb +161 -0
- data/plugins/rigor-ffi/lib/rigor/plugin/ffi.rb +121 -0
- data/plugins/rigor-ffi/lib/rigor-ffi.rb +3 -0
- data/plugins/rigor-ffi/sig/ffi.rbs +67 -0
- data/plugins/rigor-ffi-rzmq/lib/rigor/plugin/ffi_rzmq.rb +19 -0
- data/plugins/rigor-ffi-rzmq/lib/rigor-ffi-rzmq.rb +3 -0
- data/plugins/rigor-ffi-rzmq/sig/ffi_rzmq.rbs +29 -0
- data/plugins/rigor-graphql/lib/rigor/plugin/graphql/type_scanner.rb +2 -4
- data/plugins/rigor-pundit/lib/rigor/plugin/pundit/authorization_scan.rb +2 -1
- data/plugins/rigor-pundit/lib/rigor/plugin/pundit/policy_discoverer.rb +2 -1
- data/plugins/rigor-rails-i18n/lib/rigor/plugin/rails_i18n/locale_loader.rb +2 -1
- data/plugins/rigor-rails-i18n/lib/rigor/plugin/rails_i18n.rb +2 -1
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes.rb +2 -1
- data/plugins/rigor-railties/lib/rigor/plugin/railties.rb +156 -11
- data/plugins/rigor-rbnacl/lib/rigor/plugin/rbnacl.rb +30 -0
- data/plugins/rigor-rbnacl/lib/rigor-rbnacl.rb +3 -0
- data/plugins/rigor-rbnacl/sig/rbnacl.rbs +22 -0
- data/plugins/rigor-sassc/lib/rigor/plugin/sassc.rb +55 -0
- data/plugins/rigor-sassc/lib/rigor-sassc.rb +3 -0
- data/plugins/rigor-sassc/sig/sassc.rbs +24 -0
- data/plugins/rigor-shoulda-matchers/lib/rigor/plugin/shoulda_matchers/analyzer.rb +32 -11
- data/plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq/analyzer.rb +3 -1
- data/plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq/schedule_scan.rb +4 -1
- data/plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq/worker_discoverer.rb +63 -10
- data/plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq/worker_index.rb +15 -2
- data/plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq.rb +61 -2
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/catalog_walker.rb +2 -2
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet.rb +4 -2
- data/sig/rigor/analysis/baseline.rbs +1 -1
- data/sig/rigor/environment.rbs +9 -0
- data/sig/rigor/inference.rbs +4 -1
- data/sig/rigor/plugin/io_boundary.rbs +2 -0
- data/sig/rigor/reflection.rbs +3 -1
- data/sig/rigor/scope.rbs +25 -1
- data/sig/rigor/type.rbs +95 -1
- data/sig/rigor.rbs +16 -0
- metadata +71 -3
|
@@ -22,13 +22,19 @@ module Rigor
|
|
|
22
22
|
#
|
|
23
23
|
# `version` is the resolved version string (e.g. "8.0.1"); `platform` is the lockfile's platform tag,
|
|
24
24
|
# normalised to `"ruby"` when the lockfile records `ruby` and to the raw String otherwise (e.g.
|
|
25
|
-
# "aarch64-linux-gnu").
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
# "aarch64-linux-gnu"). `git_source` is true when the lockfile's `GIT` stanza (rather than `GEM`)
|
|
26
|
+
# resolved this gem — see {BundleSigDiscovery}, which needs it to tell a genuine git install apart
|
|
27
|
+
# from a same-named gem the bundle tree has an out-of-band `bundler/gems/` leftover for (e.g. a
|
|
28
|
+
# dependency that moved from a `git:` source to a released version without a `bundle clean`, so its
|
|
29
|
+
# git-installed directory is still sitting there under the OLD source's name). Defaults `false` so
|
|
30
|
+
# existing callers that construct a `LockedGem` without an opinion stay conservative.
|
|
31
|
+
LockedGem = Data.define(:name, :version, :platform, :git_source) do
|
|
32
|
+
def initialize(name:, version:, platform:, git_source: false)
|
|
28
33
|
super(
|
|
29
34
|
name: -name.to_s,
|
|
30
35
|
version: -version.to_s,
|
|
31
|
-
platform: -platform.to_s
|
|
36
|
+
platform: -platform.to_s,
|
|
37
|
+
git_source: git_source ? true : false
|
|
32
38
|
)
|
|
33
39
|
end
|
|
34
40
|
end
|
|
@@ -94,8 +100,12 @@ module Rigor
|
|
|
94
100
|
# (references/rbs/sig/shims/bundler.rbs) does NOT declare `LazySpecification#platform` so the call
|
|
95
101
|
# site needs a suppression marker.
|
|
96
102
|
platform = spec.platform.to_s # rigor:disable undefined-method
|
|
103
|
+
# `#source` is the `Bundler::Source::*` this spec resolved from — `Git` for a `GIT` lockfile
|
|
104
|
+
# stanza, `Rubygems` for a `GEM` one, `Path`/`Gemspec` for `path:`. Only `Git` sources land under
|
|
105
|
+
# {BundleSigDiscovery}'s `bundler/gems/` walk.
|
|
97
106
|
h[spec.name.to_s] = LockedGem.new(
|
|
98
|
-
name: spec.name, version: spec.version.to_s, platform: platform
|
|
107
|
+
name: spec.name, version: spec.version.to_s, platform: platform,
|
|
108
|
+
git_source: spec.source.is_a?(Bundler::Source::Git)
|
|
99
109
|
)
|
|
100
110
|
end
|
|
101
111
|
locked.freeze
|
|
@@ -47,9 +47,10 @@ module Rigor
|
|
|
47
47
|
# (external gem without RBS) is true under either owner.
|
|
48
48
|
def build(gems, bundle_path: nil, spec_resolver: method(:installed_gem_dir))
|
|
49
49
|
bundle_dirs = bundle_gem_dirs(bundle_path)
|
|
50
|
+
git_dirs = git_gem_dirs(bundle_path)
|
|
50
51
|
index = {}
|
|
51
52
|
gems.each do |gem_name, version|
|
|
52
|
-
dir = bundle_dirs["#{gem_name}-#{version}"] || spec_resolver.call(gem_name, version)
|
|
53
|
+
dir = bundle_dirs["#{gem_name}-#{version}"] || git_dirs[gem_name] || spec_resolver.call(gem_name, version)
|
|
53
54
|
next unless dir
|
|
54
55
|
|
|
55
56
|
entry_files(dir, gem_name).each do |file|
|
|
@@ -60,9 +61,10 @@ module Rigor
|
|
|
60
61
|
end
|
|
61
62
|
|
|
62
63
|
# `{"<name>-<version>" => gem_dir}` for the target's bundle, or `{}` when no bundle is resolvable. The
|
|
63
|
-
# glob
|
|
64
|
-
# basename so a platform-tagged variant
|
|
65
|
-
# `<name>-<version>` lookup — those gems ship
|
|
64
|
+
# glob covers the RUBYGEMS-sourced layout only, `<bundle>/ruby/X.Y.Z/gems/<name>-<version>/`; the
|
|
65
|
+
# git-sourced layout is {.git_gem_dirs}'s. Keyed on the dir basename so a platform-tagged variant
|
|
66
|
+
# (`ffi-1.17.4-aarch64-linux-gnu`) simply doesn't match a `<name>-<version>` lookup — those gems ship
|
|
67
|
+
# native code, not the pure-Ruby constants this indexes.
|
|
66
68
|
def bundle_gem_dirs(bundle_path)
|
|
67
69
|
return {} if bundle_path.nil?
|
|
68
70
|
|
|
@@ -74,6 +76,45 @@ module Rigor
|
|
|
74
76
|
end
|
|
75
77
|
end
|
|
76
78
|
|
|
79
|
+
# Issue #763 — `{gem_name => gem_dir}` for the target's GIT-sourced gems,
|
|
80
|
+
# `<bundle>/ruby/X.Y.Z/bundler/gems/<repo>-<12-hex-revision>/`. Before this, a `git:`-sourced gem was
|
|
81
|
+
# invisible to the index, so every constant reaching into it recorded the generic engine-gap cause
|
|
82
|
+
# where the honest story is add-RBS — the same mislabelling #530 measures from two other directions.
|
|
83
|
+
#
|
|
84
|
+
# Keyed on the name read from the directory's `*.gemspec` FILENAME, not on the directory basename: a
|
|
85
|
+
# git install's directory carries the repository name, which need not equal the gem name (a fork
|
|
86
|
+
# hosted under a different repo name, a gem inside a monorepo). No gem code is loaded — this is the
|
|
87
|
+
# filename, not an evaluated gemspec. A directory with no gemspec, or more than one, contributes
|
|
88
|
+
# nothing rather than a guess.
|
|
89
|
+
#
|
|
90
|
+
# Deliberately NOT gated on the lockfile's `git_source` the way {BundleSigDiscovery} is, and the
|
|
91
|
+
# difference is worth stating because the two look like the same problem. There, a stale
|
|
92
|
+
# `bundler/gems/` directory left behind by a gem that moved to a released version made the loader
|
|
93
|
+
# load the WRONG SIGNATURES, collapsing the RBS environment. Here the index's whole output is a gem
|
|
94
|
+
# NAME, so reading a stale checkout of the same gem yields the same answer; and the rubygems lookup
|
|
95
|
+
# is consulted FIRST in {.build}, so a gem now installed from RubyGems never reaches this map at all.
|
|
96
|
+
def git_gem_dirs(bundle_path)
|
|
97
|
+
return {} if bundle_path.nil?
|
|
98
|
+
|
|
99
|
+
base = Pathname.new(bundle_path)
|
|
100
|
+
return {} unless base.directory?
|
|
101
|
+
|
|
102
|
+
Dir.glob(base.join("ruby", "*", "bundler", "gems", "*")).each_with_object({}) do |dir, acc|
|
|
103
|
+
name = gemspec_gem_name(dir)
|
|
104
|
+
acc[name] ||= dir if name
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
# The gem name a checkout declares, from the single `*.gemspec` at its root, or nil when there is not
|
|
109
|
+
# exactly one. Bundler requires a git-sourced gem to ship one, so "not exactly one" means this is not
|
|
110
|
+
# the shape we think it is — and a guess from the directory basename is what this exists to avoid.
|
|
111
|
+
def gemspec_gem_name(dir)
|
|
112
|
+
specs = Dir.glob(File.join(dir, "*.gemspec"))
|
|
113
|
+
return nil unless specs.size == 1
|
|
114
|
+
|
|
115
|
+
File.basename(specs.first, ".gemspec")
|
|
116
|
+
end
|
|
117
|
+
|
|
77
118
|
# RubyGems spec metadata lookup — the gem's on-disk source root, without loading any of its code.
|
|
78
119
|
# Exact-version first, any-version fallback. See the class note on why this is only a fallback.
|
|
79
120
|
def installed_gem_dir(name, version)
|
|
@@ -41,32 +41,26 @@ module Rigor
|
|
|
41
41
|
end
|
|
42
42
|
end
|
|
43
43
|
|
|
44
|
+
# Issue #696 review, second pass — the ancestry lookup moved to {RbsLoader#ancestor_names_for}, and
|
|
45
|
+
# what moved with it is the reason.
|
|
46
|
+
#
|
|
47
|
+
# This method used to fetch `Cache::RbsClassAncestorTable` DIRECTLY, bypassing the loader's own
|
|
48
|
+
# accessor, and branch on `loader.cache_store`: a whole-universe table build with a store, a
|
|
49
|
+
# single-class demand without one. Same project, same question, three different answers to "which
|
|
50
|
+
# classes failed to build" — 504 on a cold store, 0 on a warm one, 2 with no store. On the DEFAULT
|
|
51
|
+
# `--workers=0` path nothing pre-warms the store, so the cold answer was the one written into the
|
|
52
|
+
# run-result cache and replayed until a file changed.
|
|
53
|
+
#
|
|
54
|
+
# The cache-state branch still exists — it is worth 50x on the warm path — but it lives behind the
|
|
55
|
+
# loader now, where both of its sides are marked as RIGOR'S OWN demand. Ordering two classes is not
|
|
56
|
+
# the analysis asking whether either one's methods resolve, so neither side reaches the diagnostic,
|
|
57
|
+
# and the answer is identical on both (the table's producer computes exactly this, keyed the same
|
|
58
|
+
# way). What this method keeps is its own per-name memo, which is about repeated comparisons.
|
|
44
59
|
def ancestor_names(class_name)
|
|
45
60
|
key = normalize_name(class_name)
|
|
46
61
|
return @ancestor_names_cache[key] if @ancestor_names_cache.key?(key)
|
|
47
62
|
|
|
48
|
-
@ancestor_names_cache[key] =
|
|
49
|
-
if loader.cache_store
|
|
50
|
-
ancestor_table.fetch(key, [].freeze)
|
|
51
|
-
else
|
|
52
|
-
compute_ancestor_names(key)
|
|
53
|
-
end
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
def compute_ancestor_names(key)
|
|
57
|
-
definition = loader.instance_definition(key)
|
|
58
|
-
return [].freeze if definition.nil?
|
|
59
|
-
|
|
60
|
-
definition.ancestors.ancestors.map { |ancestor| normalize_name(ancestor.name.to_s) }.uniq.freeze
|
|
61
|
-
rescue StandardError
|
|
62
|
-
[].freeze
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
def ancestor_table
|
|
66
|
-
@ancestor_table ||= begin
|
|
67
|
-
require_relative "../cache/rbs_class_ancestor_table"
|
|
68
|
-
Cache::RbsClassAncestorTable.fetch(loader: loader, store: loader.cache_store)
|
|
69
|
-
end
|
|
63
|
+
@ancestor_names_cache[key] = loader.ancestor_names_for(key)
|
|
70
64
|
end
|
|
71
65
|
|
|
72
66
|
def normalize_name(name)
|