rigortype 0.1.16 → 0.1.18
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 +4 -2
- data/lib/rigor/analysis/check_rules/always_truthy_condition_collector.rb +18 -1
- data/lib/rigor/analysis/check_rules/rule_walk.rb +67 -0
- data/lib/rigor/analysis/check_rules/self_closedness_scanner.rb +100 -0
- data/lib/rigor/analysis/check_rules/unreachable_clause_collector.rb +226 -0
- data/lib/rigor/analysis/check_rules.rb +180 -73
- data/lib/rigor/analysis/dependency_recorder.rb +122 -0
- data/lib/rigor/analysis/diagnostic.rb +18 -0
- data/lib/rigor/analysis/incremental.rb +162 -0
- data/lib/rigor/analysis/incremental_session.rb +337 -0
- data/lib/rigor/analysis/rule_catalog.rb +48 -0
- data/lib/rigor/analysis/runner/diagnostic_aggregator.rb +580 -0
- data/lib/rigor/analysis/runner/pool_coordinator.rb +569 -0
- data/lib/rigor/analysis/runner/project_pre_passes.rb +318 -0
- data/lib/rigor/analysis/runner/run_snapshots.rb +46 -0
- data/lib/rigor/analysis/runner.rb +477 -1110
- data/lib/rigor/analysis/self_call_resolution_recorder.rb +121 -0
- data/lib/rigor/analysis/worker_session.rb +47 -8
- data/lib/rigor/builtins/static_return_refinements.rb +7 -1
- data/lib/rigor/cache/descriptor.rb +50 -49
- data/lib/rigor/cache/incremental_snapshot.rb +153 -0
- data/lib/rigor/cache/rbs_cache_producer.rb +34 -0
- data/lib/rigor/cache/rbs_class_ancestor_table.rb +2 -8
- data/lib/rigor/cache/rbs_class_type_param_names.rb +2 -8
- data/lib/rigor/cache/rbs_constant_table.rb +2 -8
- data/lib/rigor/cache/rbs_environment.rb +2 -8
- data/lib/rigor/cache/rbs_known_class_names.rb +2 -8
- data/lib/rigor/cache/store.rb +145 -14
- data/lib/rigor/cli/annotate_command.rb +2 -7
- data/lib/rigor/cli/baseline_command.rb +2 -7
- data/lib/rigor/cli/check_command.rb +705 -0
- data/lib/rigor/cli/ci_detector.rb +94 -0
- data/lib/rigor/cli/command.rb +47 -0
- data/lib/rigor/cli/coverage_command.rb +3 -23
- data/lib/rigor/cli/coverage_renderer.rb +3 -8
- data/lib/rigor/cli/diagnostic_formats.rb +345 -0
- data/lib/rigor/cli/diff_command.rb +3 -7
- data/lib/rigor/cli/explain_command.rb +2 -7
- data/lib/rigor/cli/lsp_command.rb +3 -7
- data/lib/rigor/cli/mcp_command.rb +3 -7
- data/lib/rigor/cli/options.rb +57 -0
- data/lib/rigor/cli/plugin_command.rb +3 -7
- data/lib/rigor/cli/plugins_command.rb +2 -7
- data/lib/rigor/cli/prism_colorizer.rb +10 -3
- data/lib/rigor/cli/renderable.rb +26 -0
- data/lib/rigor/cli/sig_gen_command.rb +2 -7
- data/lib/rigor/cli/skill_command.rb +3 -7
- data/lib/rigor/cli/trace_command.rb +143 -0
- data/lib/rigor/cli/trace_renderer.rb +310 -0
- data/lib/rigor/cli/triage_command.rb +2 -7
- data/lib/rigor/cli/type_of_command.rb +5 -38
- data/lib/rigor/cli/type_of_renderer.rb +4 -9
- data/lib/rigor/cli/type_scan_command.rb +3 -23
- data/lib/rigor/cli/type_scan_renderer.rb +4 -9
- data/lib/rigor/cli.rb +15 -532
- data/lib/rigor/configuration/dependencies.rb +18 -1
- data/lib/rigor/configuration/severity_profile.rb +22 -3
- data/lib/rigor/configuration.rb +16 -3
- data/lib/rigor/environment/rbs_loader.rb +129 -71
- data/lib/rigor/environment.rb +1 -1
- data/lib/rigor/inference/acceptance.rb +10 -0
- data/lib/rigor/inference/block_parameter_binder.rb +1 -2
- data/lib/rigor/inference/builtins/array_catalog.rb +2 -5
- data/lib/rigor/inference/builtins/comparable_catalog.rb +2 -5
- data/lib/rigor/inference/builtins/complex_catalog.rb +2 -5
- data/lib/rigor/inference/builtins/date_catalog.rb +2 -5
- data/lib/rigor/inference/builtins/encoding_catalog.rb +2 -5
- data/lib/rigor/inference/builtins/enumerable_catalog.rb +2 -5
- data/lib/rigor/inference/builtins/exception_catalog.rb +2 -5
- data/lib/rigor/inference/builtins/hash_catalog.rb +2 -5
- data/lib/rigor/inference/builtins/method_catalog.rb +15 -0
- data/lib/rigor/inference/builtins/numeric_catalog.rb +21 -93
- data/lib/rigor/inference/builtins/pathname_catalog.rb +2 -5
- data/lib/rigor/inference/builtins/proc_catalog.rb +2 -5
- data/lib/rigor/inference/builtins/random_catalog.rb +2 -5
- data/lib/rigor/inference/builtins/range_catalog.rb +2 -5
- data/lib/rigor/inference/builtins/rational_catalog.rb +2 -5
- data/lib/rigor/inference/builtins/re_catalog.rb +2 -5
- data/lib/rigor/inference/builtins/set_catalog.rb +2 -5
- data/lib/rigor/inference/builtins/string_catalog.rb +2 -5
- data/lib/rigor/inference/builtins/struct_catalog.rb +2 -5
- data/lib/rigor/inference/builtins/time_catalog.rb +2 -5
- data/lib/rigor/inference/expression_typer.rb +149 -63
- data/lib/rigor/inference/flow_tracer.rb +180 -0
- data/lib/rigor/inference/macro_block_self_type.rb +10 -11
- data/lib/rigor/inference/method_dispatcher/block_folding.rb +5 -1
- data/lib/rigor/inference/method_dispatcher/call_context.rb +65 -0
- data/lib/rigor/inference/method_dispatcher/cgi_folding.rb +11 -10
- data/lib/rigor/inference/method_dispatcher/constant_folding.rb +12 -6
- data/lib/rigor/inference/method_dispatcher/data_folding.rb +246 -0
- data/lib/rigor/inference/method_dispatcher/file_folding.rb +6 -2
- data/lib/rigor/inference/method_dispatcher/iterator_dispatch.rb +6 -2
- data/lib/rigor/inference/method_dispatcher/kernel_dispatch.rb +4 -1
- data/lib/rigor/inference/method_dispatcher/literal_string_folding.rb +4 -1
- data/lib/rigor/inference/method_dispatcher/math_folding.rb +6 -6
- data/lib/rigor/inference/method_dispatcher/method_folding.rb +12 -7
- data/lib/rigor/inference/method_dispatcher/overload_selector.rb +33 -1
- data/lib/rigor/inference/method_dispatcher/rbs_dispatch.rb +23 -13
- data/lib/rigor/inference/method_dispatcher/regexp_folding.rb +9 -9
- data/lib/rigor/inference/method_dispatcher/set_folding.rb +6 -6
- data/lib/rigor/inference/method_dispatcher/shape_dispatch.rb +120 -9
- data/lib/rigor/inference/method_dispatcher/shellwords_folding.rb +12 -12
- data/lib/rigor/inference/method_dispatcher/singleton_folding.rb +49 -0
- data/lib/rigor/inference/method_dispatcher/time_folding.rb +6 -6
- data/lib/rigor/inference/method_dispatcher/uri_folding.rb +9 -9
- data/lib/rigor/inference/method_dispatcher.rb +185 -84
- data/lib/rigor/inference/narrowing.rb +262 -5
- data/lib/rigor/inference/scope_indexer.rb +208 -21
- data/lib/rigor/inference/statement_evaluator.rb +110 -48
- data/lib/rigor/language_server/buffer_resolution.rb +33 -0
- data/lib/rigor/language_server/completion_provider.rb +4 -4
- data/lib/rigor/language_server/document_symbol_provider.rb +4 -4
- data/lib/rigor/language_server/folding_range_provider.rb +4 -4
- data/lib/rigor/language_server/hover_provider.rb +4 -4
- data/lib/rigor/language_server/selection_range_provider.rb +4 -4
- data/lib/rigor/language_server/signature_help_provider.rb +4 -4
- data/lib/rigor/plugin/additional_initializer.rb +61 -38
- data/lib/rigor/plugin/base.rb +302 -45
- data/lib/rigor/plugin/node_rule_walk.rb +147 -0
- data/lib/rigor/plugin/registry.rb +281 -15
- data/lib/rigor/plugin.rb +1 -0
- data/lib/rigor/rbs_extended/conformance_checker.rb +293 -0
- data/lib/rigor/rbs_extended.rb +39 -0
- data/lib/rigor/scope/discovery_index.rb +58 -0
- data/lib/rigor/scope.rb +150 -167
- data/lib/rigor/sig_gen/observation_collector.rb +6 -6
- data/lib/rigor/source/literals.rb +14 -0
- data/lib/rigor/type/acceptance_router.rb +19 -0
- data/lib/rigor/type/accepts_result.rb +3 -10
- data/lib/rigor/type/app.rb +3 -7
- data/lib/rigor/type/bot.rb +2 -3
- data/lib/rigor/type/bound_method.rb +5 -12
- data/lib/rigor/type/combinator.rb +22 -0
- data/lib/rigor/type/constant.rb +2 -3
- data/lib/rigor/type/data_class.rb +80 -0
- data/lib/rigor/type/data_instance.rb +100 -0
- data/lib/rigor/type/difference.rb +5 -10
- data/lib/rigor/type/dynamic.rb +5 -10
- data/lib/rigor/type/hash_shape.rb +5 -15
- data/lib/rigor/type/integer_range.rb +5 -10
- data/lib/rigor/type/intersection.rb +5 -10
- data/lib/rigor/type/nominal.rb +5 -10
- data/lib/rigor/type/refined.rb +5 -10
- data/lib/rigor/type/singleton.rb +5 -10
- data/lib/rigor/type/top.rb +2 -3
- data/lib/rigor/type/tuple.rb +5 -10
- data/lib/rigor/type/union.rb +5 -10
- data/lib/rigor/type.rb +2 -0
- data/lib/rigor/value_semantics.rb +77 -0
- data/lib/rigor/version.rb +1 -1
- data/lib/rigor.rb +1 -1
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/analyzer.rb +1 -2
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/model_discoverer.rb +2 -4
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord.rb +70 -32
- data/plugins/rigor-activestorage/lib/rigor/plugin/activestorage/analyzer.rb +3 -3
- data/plugins/rigor-activestorage/lib/rigor/plugin/activestorage.rb +15 -21
- data/plugins/rigor-activesupport-core-ext/lib/rigor/plugin/activesupport_core_ext.rb +1 -1
- data/plugins/rigor-factorybot/lib/rigor/plugin/factorybot/factory_discoverer.rb +1 -2
- data/plugins/rigor-graphql/lib/rigor/plugin/graphql/type_scanner.rb +2 -2
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes.rb +12 -2
- data/plugins/rigor-rspec/lib/rigor/plugin/rspec/let_scope_index.rb +12 -2
- data/plugins/rigor-rspec/lib/rigor/plugin/rspec/matcher_analyzer.rb +1 -1
- data/plugins/rigor-rspec/lib/rigor/plugin/rspec.rb +35 -18
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/absurd_recognizer.rb +8 -29
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/catalog.rb +17 -1
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/sigil_detector.rb +2 -2
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet.rb +83 -36
- data/sig/rigor/cache.rbs +19 -0
- data/sig/rigor/environment.rbs +0 -2
- data/sig/rigor/inference.rbs +27 -0
- data/sig/rigor/plugin/base.rbs +1 -2
- data/sig/rigor/rbs_extended.rbs +2 -0
- data/sig/rigor/scope.rbs +42 -25
- data/sig/rigor/source.rbs +1 -0
- data/sig/rigor/type.rbs +58 -1
- data/sig/rigor.rbs +6 -1
- data/skills/rigor-ci-setup/SKILL.md +319 -0
- metadata +36 -2
- data/lib/rigor/cache/rbs_instance_definitions.rb +0 -79
|
@@ -6,7 +6,7 @@ module Rigor
|
|
|
6
6
|
# Per-run table of method signatures keyed by the
|
|
7
7
|
# `(class_name, method_name, kind)` triple. Built by
|
|
8
8
|
# {CatalogWalker} during the plugin's lazy pre-walk; read
|
|
9
|
-
# by
|
|
9
|
+
# by the plugin's `dynamic_return` rule at every gated call site.
|
|
10
10
|
#
|
|
11
11
|
# The catalog is mutable while it is being built, then
|
|
12
12
|
# frozen via {#freeze!} before the first read. Construction
|
|
@@ -80,6 +80,22 @@ module Rigor
|
|
|
80
80
|
@entries.empty?
|
|
81
81
|
end
|
|
82
82
|
|
|
83
|
+
# ADR-52 slice 4 — the distinct method names the catalog
|
|
84
|
+
# carries at least one signature for, across every
|
|
85
|
+
# `(class_name, kind)` owner. Feeds the plugin's run-time
|
|
86
|
+
# `dynamic_return methods:` name gate: the engine only
|
|
87
|
+
# consults the plugin for a call whose name appears here
|
|
88
|
+
# (or in the static assertion vocabulary), and the
|
|
89
|
+
# precise `(class, kind)` lookup stays in the rule block.
|
|
90
|
+
# Computed fresh per call — the plugin memoises the
|
|
91
|
+
# resolved set, and `freeze!` freezes the catalog itself
|
|
92
|
+
# so a lazy memo ivar here would raise.
|
|
93
|
+
#
|
|
94
|
+
# @return [Array<Symbol>]
|
|
95
|
+
def method_names
|
|
96
|
+
@entries.keys.map { |key| key[1] }.uniq
|
|
97
|
+
end
|
|
98
|
+
|
|
83
99
|
def size
|
|
84
100
|
@entries.size
|
|
85
101
|
end
|
|
@@ -24,8 +24,8 @@ module Rigor
|
|
|
24
24
|
# identically — per-call-site sigil honouring (e.g. only
|
|
25
25
|
# firing `T.let` recognition in `# typed: true`+ files)
|
|
26
26
|
# requires threading the file path through
|
|
27
|
-
#
|
|
28
|
-
# plugin-contract widening slice.
|
|
27
|
+
# the per-call recognition path, which lives behind a
|
|
28
|
+
# future plugin-contract widening slice.
|
|
29
29
|
module SigilDetector
|
|
30
30
|
# Sorbet's strictness-level names. Stored as symbols to
|
|
31
31
|
# match the analyzer's existing convention for level
|
|
@@ -39,8 +39,8 @@ module Rigor
|
|
|
39
39
|
# access by walking every configured `paths:` entry's `.rb`
|
|
40
40
|
# files plus every `rbi_paths:` entry's `.rbi` files (slice
|
|
41
41
|
# 4) via the plugin's `IoBoundary`. The catalog is frozen
|
|
42
|
-
# after the first build and consulted by
|
|
43
|
-
#
|
|
42
|
+
# after the first build and consulted by the `dynamic_return`
|
|
43
|
+
# rule at every gated call site. RBI files
|
|
44
44
|
# share the catalog with project-source sigs — both produce
|
|
45
45
|
# `MethodSignature` entries keyed by
|
|
46
46
|
# `(class_name, method_name, kind)`. When a key collides
|
|
@@ -101,7 +101,7 @@ module Rigor
|
|
|
101
101
|
@enforce_sigil = config.fetch("enforce_sigil")
|
|
102
102
|
# ADR-11 deferred follow-up — per-call-site assertion
|
|
103
103
|
# gating. Catalog harvest's `@sigil_by_path` cache is
|
|
104
|
-
# consulted at every
|
|
104
|
+
# consulted at every per-call recognition so
|
|
105
105
|
# `T.let` / `T.cast` / `T.must` / `T.bind` /
|
|
106
106
|
# `T.assert_type!` only fire in files Sorbet itself
|
|
107
107
|
# would enforce (`# typed: true` / `:strict` /
|
|
@@ -118,7 +118,7 @@ module Rigor
|
|
|
118
118
|
@parse_errors_by_path = {}
|
|
119
119
|
@catalog_built = false
|
|
120
120
|
# ADR-11 slice 6 — Prism nodes for `T.absurd` calls
|
|
121
|
-
# we observed in `
|
|
121
|
+
# we observed in the `dynamic_return` rule to be
|
|
122
122
|
# *reachable* (i.e., their discriminant didn't narrow
|
|
123
123
|
# to `bot`). `diagnostics_for_file` walks the per-file
|
|
124
124
|
# AST and surfaces these as `plugin.sorbet.absurd-reachable`
|
|
@@ -128,7 +128,7 @@ module Rigor
|
|
|
128
128
|
# plugin hooks.
|
|
129
129
|
@reachable_absurd_nodes = {}.compare_by_identity
|
|
130
130
|
# ADR-11 light follow-up — `T.reveal_type` calls
|
|
131
|
-
# observed in `
|
|
131
|
+
# observed in the `dynamic_return` rule, paired with the
|
|
132
132
|
# display string for the inferred type at the call site.
|
|
133
133
|
# Mirrors the absurd-node compare-by-identity hash;
|
|
134
134
|
# `diagnostics_for_file` surfaces each entry as a
|
|
@@ -136,7 +136,7 @@ module Rigor
|
|
|
136
136
|
@reveal_type_calls = {}.compare_by_identity
|
|
137
137
|
# T.bind / T.assert_type! priority slice 1 —
|
|
138
138
|
# `T.assert_type!` calls observed in
|
|
139
|
-
# `
|
|
139
|
+
# the `dynamic_return` rule whose static subtype check
|
|
140
140
|
# FAILED, paired with the inferred + asserted type
|
|
141
141
|
# display strings. Same compare-by-identity discipline.
|
|
142
142
|
# `diagnostics_for_file` walks the file AST for
|
|
@@ -160,9 +160,52 @@ module Rigor
|
|
|
160
160
|
diagnostics
|
|
161
161
|
end
|
|
162
162
|
|
|
163
|
-
# ADR-
|
|
164
|
-
#
|
|
165
|
-
#
|
|
163
|
+
# ADR-52 slice 4 — the per-call return-type path, migrated off
|
|
164
|
+
# the legacy `flow_contribution_for` hook onto the
|
|
165
|
+
# method-name-gated `dynamic_return` DSL. The recognised name
|
|
166
|
+
# set is only known at run time (the catalog's `def` names come
|
|
167
|
+
# from the lazy catalog build), so it is declared as a
|
|
168
|
+
# callable: the engine `instance_exec`s it once per run on
|
|
169
|
+
# first dispatch (always after `#prepare`) and memoises the
|
|
170
|
+
# resolved Symbol Set. The gate is a safe over-approximation —
|
|
171
|
+
# a project method merely *named* `cast` or `find` passes it
|
|
172
|
+
# and is declined by the block's own `T.`-receiver / catalog
|
|
173
|
+
# checks, exactly as the ungated hook used to decline.
|
|
174
|
+
dynamic_return methods: -> { recognised_method_names } do |call_node, scope|
|
|
175
|
+
contribution_return_type(call_node, scope)
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
# ADR-52 slice 4 — `T.bind(self, T)`'s self-narrowing fact,
|
|
179
|
+
# migrated off the legacy hook's `post_return_facts` slot onto
|
|
180
|
+
# the method-gated `type_specifier` DSL (once
|
|
181
|
+
# `flow_contribution_for` is gone, the statement evaluator
|
|
182
|
+
# consults only this path for narrowing facts). The
|
|
183
|
+
# return-type half (`Constant[nil]`) flows through the
|
|
184
|
+
# `dynamic_return` rule above; the block re-checks the `T.`
|
|
185
|
+
# receiver via the recogniser, so an unrelated `bind` call
|
|
186
|
+
# contributes nothing.
|
|
187
|
+
type_specifier methods: [:bind] do |call_node, scope|
|
|
188
|
+
bind_post_return_facts(call_node, scope)
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
private
|
|
192
|
+
|
|
193
|
+
# ADR-52 slice 4 — the run-time method-name gate for the
|
|
194
|
+
# `dynamic_return` rule: the static assertion vocabulary
|
|
195
|
+
# (`T.let` / `T.cast` / …), `T.absurd`, and every method name
|
|
196
|
+
# the catalog carries a sig for.
|
|
197
|
+
def recognised_method_names
|
|
198
|
+
ensure_catalog
|
|
199
|
+
names = AssertionRecognizer::SORBET_ASSERTIONS.dup
|
|
200
|
+
names << :absurd
|
|
201
|
+
names.concat(@catalog.method_names)
|
|
202
|
+
names
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
# The migrated body of the legacy `flow_contribution_for` —
|
|
206
|
+
# same recognition order, but returns the bare `Rigor::Type`
|
|
207
|
+
# the `dynamic_return` contract expects. Resolves the receiver
|
|
208
|
+
# in two passes:
|
|
166
209
|
#
|
|
167
210
|
# 1. Constant receiver (`User.find(...)`) → singleton-side
|
|
168
211
|
# catalog lookup.
|
|
@@ -173,18 +216,22 @@ module Rigor
|
|
|
173
216
|
# Implicit-self calls (no receiver, current-class method)
|
|
174
217
|
# are deferred to slice 2 — slice 1 covers the common case
|
|
175
218
|
# where the sig is on the called method's own class.
|
|
176
|
-
def
|
|
219
|
+
def contribution_return_type(call_node, scope)
|
|
177
220
|
return nil unless call_node.is_a?(Prism::CallNode)
|
|
178
221
|
|
|
179
222
|
# ADR-11 slice 6 — `T.absurd(x)` exhaustiveness. Always
|
|
180
|
-
# contributes a `bot` return
|
|
181
|
-
#
|
|
182
|
-
#
|
|
183
|
-
# the
|
|
184
|
-
# `
|
|
223
|
+
# contributes a `bot` return (matches Sorbet's runtime
|
|
224
|
+
# behaviour: `T.absurd` raises, so its value type is `bot`
|
|
225
|
+
# and the engine's flow analysis treats code after it as
|
|
226
|
+
# unreachable; the legacy contribution's `exceptional:
|
|
227
|
+
# :raises` slot was never consumed on the dispatcher path —
|
|
228
|
+
# only `return_type` survives the merge). When the
|
|
229
|
+
# discriminant *isn't* narrowed to `bot` at this scope, also
|
|
230
|
+
# records the call node so `diagnostics_for_file` can surface
|
|
231
|
+
# a `plugin.sorbet.absurd-reachable` warning.
|
|
185
232
|
if AbsurdRecognizer.absurd_call?(call_node)
|
|
186
233
|
@reachable_absurd_nodes[call_node] = true unless AbsurdRecognizer.exhaustive?(call_node, scope)
|
|
187
|
-
return
|
|
234
|
+
return Rigor::Type::Combinator.bot
|
|
188
235
|
end
|
|
189
236
|
|
|
190
237
|
# ADR-11 slice 2 — `T.let` / `T.cast` / `T.must` /
|
|
@@ -214,31 +261,31 @@ module Rigor
|
|
|
214
261
|
if assertion
|
|
215
262
|
record_reveal_type_call(call_node, assertion.return_type) if call_node.name == :reveal_type
|
|
216
263
|
record_assert_type_check(call_node, scope) if call_node.name == :assert_type!
|
|
217
|
-
return assertion
|
|
264
|
+
return assertion.return_type
|
|
218
265
|
end
|
|
219
266
|
end
|
|
220
267
|
|
|
221
268
|
return nil if @catalog.nil? || @catalog.empty?
|
|
222
269
|
|
|
223
|
-
|
|
224
|
-
|
|
270
|
+
lookup_signature(call_node, scope)&.return_type
|
|
271
|
+
end
|
|
225
272
|
|
|
226
|
-
|
|
227
|
-
|
|
273
|
+
# The `type_specifier` body for `T.bind` — same sigil gate as
|
|
274
|
+
# the return-type path, then the recogniser's
|
|
275
|
+
# `post_return_facts` (the `Fact(target_kind: :self)` that
|
|
276
|
+
# narrows `scope.self_type` for the rest of the block).
|
|
277
|
+
def bind_post_return_facts(call_node, scope)
|
|
278
|
+
return nil unless call_node.is_a?(Prism::CallNode)
|
|
228
279
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
node: call_node,
|
|
235
|
-
descriptor: nil
|
|
236
|
-
)
|
|
280
|
+
ensure_catalog
|
|
281
|
+
return nil unless assertion_enforced_here?(scope)
|
|
282
|
+
|
|
283
|
+
contribution = AssertionRecognizer.recognize(
|
|
284
|
+
call_node: call_node, scope: scope, plugin_id: manifest.id
|
|
237
285
|
)
|
|
286
|
+
contribution&.post_return_facts
|
|
238
287
|
end
|
|
239
288
|
|
|
240
|
-
private
|
|
241
|
-
|
|
242
289
|
# ADR-11 deferred follow-up — per-call-site assertion
|
|
243
290
|
# gating. With `enforce_sigil: false`, the gate is fully
|
|
244
291
|
# open (matches the pre-feature behaviour). With
|
|
@@ -441,7 +488,7 @@ module Rigor
|
|
|
441
488
|
# magic comment by skipping the file entirely.
|
|
442
489
|
level = SigilDetector.detect(contents)
|
|
443
490
|
# Per-call-site assertion gating consults this map at
|
|
444
|
-
#
|
|
491
|
+
# recognition time. Recorded BEFORE the ignored
|
|
445
492
|
# short-circuit so a `# typed: ignore` file still
|
|
446
493
|
# reports its level to the gate (the gate then chooses
|
|
447
494
|
# to suppress assertions there too — `ignore` is
|
|
@@ -481,7 +528,7 @@ module Rigor
|
|
|
481
528
|
# nodes and emits a `plugin.sorbet.absurd-reachable`
|
|
482
529
|
# warning for any whose object identity matches
|
|
483
530
|
# `@reachable_absurd_nodes` (populated during the engine's
|
|
484
|
-
# earlier pass through `
|
|
531
|
+
# earlier pass through the `dynamic_return` rule). Pops
|
|
485
532
|
# matched entries so a duplicate run doesn't double-emit.
|
|
486
533
|
def absurd_reachable_diagnostics(path, root)
|
|
487
534
|
return [] if @reachable_absurd_nodes.empty?
|
|
@@ -569,8 +616,8 @@ module Rigor
|
|
|
569
616
|
# static subtype check at recogniser time and records the
|
|
570
617
|
# call only when the inferred type is *provably
|
|
571
618
|
# incompatible* with the asserted type. Gradual
|
|
572
|
-
# consistency rules (`
|
|
573
|
-
#
|
|
619
|
+
# consistency rules (`Type#accepts` mode `:gradual`): a
|
|
620
|
+
# `Dynamic[top]` inferred type
|
|
574
621
|
# silences the check; a definite `:no` records for
|
|
575
622
|
# diagnostic emission; `:maybe` (uncertain) is treated as
|
|
576
623
|
# "trust the user" and silenced — the runtime check is
|
|
@@ -582,7 +629,7 @@ module Rigor
|
|
|
582
629
|
inferred, asserted = check
|
|
583
630
|
return if inferred.nil?
|
|
584
631
|
|
|
585
|
-
result =
|
|
632
|
+
result = asserted.accepts(inferred)
|
|
586
633
|
return unless result.no?
|
|
587
634
|
|
|
588
635
|
@assert_type_mismatches[call_node] = [display_for_type(inferred), display_for_type(asserted)]
|
data/sig/rigor/cache.rbs
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module Rigor
|
|
2
|
+
module Cache
|
|
3
|
+
# Structural interface for the RBS-derived cache producers: a class
|
|
4
|
+
# object that responds to `.fetch(loader:, store:)` and yields the
|
|
5
|
+
# cached (or freshly computed) value. A structural *interface*
|
|
6
|
+
# (duck-typed), not a "protocol" (reserved for ADR-28). Satisfied by
|
|
7
|
+
# `RbsCacheProducer` and every subclass; matches the _Type and
|
|
8
|
+
# _DispatchTier interfaces declared elsewhere in sig/.
|
|
9
|
+
interface _CacheProducer
|
|
10
|
+
def fetch: (loader: untyped, store: untyped) -> untyped
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# Base owning the shared producer `fetch` wiring; subclasses add a
|
|
14
|
+
# PRODUCER_ID constant and a private `self.compute(loader)`.
|
|
15
|
+
class RbsCacheProducer
|
|
16
|
+
def self.fetch: (loader: untyped, store: untyped) -> untyped
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
data/sig/rigor/environment.rbs
CHANGED
|
@@ -58,10 +58,8 @@ module Rigor
|
|
|
58
58
|
def rbs_module?: (String | Symbol name) -> bool
|
|
59
59
|
def instance_definition: (String | Symbol class_name) -> untyped?
|
|
60
60
|
def instance_method: (class_name: String | Symbol, method_name: String | Symbol) -> untyped?
|
|
61
|
-
def uncached_instance_definition: (String | Symbol class_name) -> untyped?
|
|
62
61
|
def singleton_definition: (String | Symbol class_name) -> untyped?
|
|
63
62
|
def singleton_method: (class_name: String | Symbol, method_name: String | Symbol) -> untyped?
|
|
64
|
-
def uncached_singleton_definition: (String | Symbol class_name) -> untyped?
|
|
65
63
|
def class_type_param_names: (String | Symbol class_name) -> Array[Symbol]
|
|
66
64
|
def class_ordering: (String | Symbol lhs, String | Symbol rhs) -> ordering
|
|
67
65
|
def constant_type: (String name) -> Type::t?
|
data/sig/rigor/inference.rbs
CHANGED
|
@@ -57,6 +57,28 @@ module Rigor
|
|
|
57
57
|
module MethodDispatcher
|
|
58
58
|
def self?.dispatch: (receiver_type: Type::t?, method_name: Symbol, arg_types: Array[Type::t], ?block_type: Type::t?, ?environment: Environment?) -> Type::t?
|
|
59
59
|
def self?.expected_block_param_types: (receiver_type: Type::t?, method_name: Symbol, arg_types: Array[Type::t], ?environment: Environment?) -> Array[Type::t]
|
|
60
|
+
|
|
61
|
+
# Immutable value object threaded through every dispatch tier.
|
|
62
|
+
class CallContext
|
|
63
|
+
attr_reader receiver: Type::t?
|
|
64
|
+
attr_reader method_name: Symbol
|
|
65
|
+
attr_reader args: Array[Type::t]
|
|
66
|
+
attr_reader block_type: Type::t?
|
|
67
|
+
attr_reader environment: Environment?
|
|
68
|
+
attr_reader call_node: untyped
|
|
69
|
+
attr_reader scope: untyped
|
|
70
|
+
attr_reader self_type_override: Type::t?
|
|
71
|
+
attr_reader public_only: bool
|
|
72
|
+
|
|
73
|
+
def self.build: (receiver: Type::t?, method_name: Symbol, args: Array[Type::t], ?block_type: Type::t?, ?environment: Environment?, ?call_node: untyped, ?scope: untyped, ?self_type_override: Type::t?, ?public_only: bool) -> CallContext
|
|
74
|
+
def with: (**untyped) -> CallContext
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# The interface every dispatch tier observes: fold one call site,
|
|
78
|
+
# returning a `Type::t` or nil to defer to the next tier.
|
|
79
|
+
interface _DispatchTier
|
|
80
|
+
def try_dispatch: (CallContext) -> Type::t?
|
|
81
|
+
end
|
|
60
82
|
end
|
|
61
83
|
|
|
62
84
|
class MethodParameterBinder
|
|
@@ -87,6 +109,9 @@ module Rigor
|
|
|
87
109
|
def self?.narrow_not_class: (Type::t type, String class_name, ?exact: bool, ?environment: Environment) -> Type::t
|
|
88
110
|
def self?.narrow_not_refinement: (Type::t current_type, Type::t refinement_type) -> Type::t
|
|
89
111
|
def self?.narrow_for_fact: (Type::t current, untyped fact, untyped environment) -> Type::t
|
|
112
|
+
def self?.predicate_certainty: (Type::t? type) -> (:truthy | :falsey | nil)
|
|
113
|
+
def self?.class_pattern_certainty: (Type::t subject_type, String class_name, environment: Environment) -> (:yes | :no | :maybe)
|
|
114
|
+
def self?.value_pattern_certainty: (Type::t subject_type, untyped pattern_value) -> (:yes | :no | :maybe)
|
|
90
115
|
def self?.predicate_scopes: (untyped node, Scope scope) -> [Scope, Scope]
|
|
91
116
|
def self?.case_when_scopes: (untyped subject, Array[untyped] conditions, Scope scope) -> [Scope, Scope]
|
|
92
117
|
def self?.analyse: (untyped node, Scope scope) -> untyped
|
|
@@ -95,6 +120,8 @@ module Rigor
|
|
|
95
120
|
def self?.trusted_equality_literal?: (untyped literal) -> bool
|
|
96
121
|
def self?.falsey_value?: (untyped value) -> bool
|
|
97
122
|
def self?.falsey_nominal?: (Type::Nominal nominal) -> bool
|
|
123
|
+
|
|
124
|
+
VALUE_EQUALITY_CLASSES: Array[Class]
|
|
98
125
|
end
|
|
99
126
|
|
|
100
127
|
module ClosureEscapeAnalyzer
|
data/sig/rigor/plugin/base.rbs
CHANGED
|
@@ -23,7 +23,7 @@ class Rigor::Plugin::Base
|
|
|
23
23
|
def self.node_file_context: () { (untyped root, untyped scope) -> untyped } -> untyped
|
|
24
24
|
def self.node_file_context_block: () -> untyped
|
|
25
25
|
|
|
26
|
-
def self.dynamic_return: (receivers: Array[String]) { (untyped call_node, untyped scope) -> untyped } -> nil
|
|
26
|
+
def self.dynamic_return: (?receivers: (Array[String] | ^() -> Array[String])?, ?methods: (Array[untyped] | ^() -> Array[untyped])?) { (untyped call_node, untyped scope) -> untyped } -> nil
|
|
27
27
|
def self.dynamic_returns: () -> Array[untyped]
|
|
28
28
|
|
|
29
29
|
def self.type_specifier: (methods: Array[untyped]) { (untyped call_node, untyped scope) -> untyped } -> nil
|
|
@@ -41,7 +41,6 @@ class Rigor::Plugin::Base
|
|
|
41
41
|
# Overridable lifecycle / extension hooks (default no-ops).
|
|
42
42
|
def init: (untyped services) -> nil
|
|
43
43
|
def prepare: (untyped services) -> nil
|
|
44
|
-
def flow_contribution_for: (call_node: untyped, scope: untyped) -> untyped
|
|
45
44
|
def diagnostics_for_file: (path: untyped, scope: untyped, root: untyped) -> Array[untyped]
|
|
46
45
|
|
|
47
46
|
# Engine-executed dispatch over the declared DSLs.
|
data/sig/rigor/rbs_extended.rbs
CHANGED
data/sig/rigor/scope.rbs
CHANGED
|
@@ -4,25 +4,52 @@ module Rigor
|
|
|
4
4
|
attr_reader locals: Hash[Symbol, Type::t]
|
|
5
5
|
attr_reader fact_store: Analysis::FactStore
|
|
6
6
|
attr_reader self_type: Type::t?
|
|
7
|
-
attr_reader declared_types: Hash[untyped, Type::t]
|
|
8
7
|
attr_reader ivars: Hash[Symbol, Type::t]
|
|
9
8
|
attr_reader cvars: Hash[Symbol, Type::t]
|
|
10
9
|
attr_reader globals: Hash[Symbol, Type::t]
|
|
11
|
-
attr_reader
|
|
12
|
-
attr_reader class_cvars: Hash[String, Hash[Symbol, Type::t]]
|
|
13
|
-
attr_reader program_globals: Hash[Symbol, Type::t]
|
|
14
|
-
attr_reader discovered_classes: Hash[String, Type::Singleton]
|
|
15
|
-
attr_reader in_source_constants: Hash[String, Type::t]
|
|
16
|
-
attr_reader discovered_methods: Hash[String, Hash[Symbol, Symbol]]
|
|
17
|
-
attr_reader discovered_def_nodes: Hash[String, Hash[Symbol, untyped]]
|
|
18
|
-
attr_reader discovered_def_sources: Hash[String, Hash[Symbol, String]]
|
|
19
|
-
attr_reader discovered_method_visibilities: Hash[String, Hash[Symbol, Symbol]]
|
|
20
|
-
attr_reader discovered_superclasses: Hash[String, String]
|
|
21
|
-
attr_reader discovered_includes: Hash[String, Array[String]]
|
|
10
|
+
attr_reader discovery: DiscoveryIndex
|
|
22
11
|
attr_reader indexed_narrowings: Hash[IndexedKey, Type::t]
|
|
23
12
|
attr_reader method_chain_narrowings: Hash[ChainKey, Type::t]
|
|
24
13
|
attr_reader source_path: String?
|
|
25
14
|
|
|
15
|
+
# ADR-53 Track A — the seed-time discovery tables live on the
|
|
16
|
+
# DiscoveryIndex; Scope keeps per-table readers as delegates.
|
|
17
|
+
def declared_types: () -> Hash[untyped, Type::t]
|
|
18
|
+
def class_ivars: () -> Hash[String, Hash[Symbol, Type::t]]
|
|
19
|
+
def class_cvars: () -> Hash[String, Hash[Symbol, Type::t]]
|
|
20
|
+
def program_globals: () -> Hash[Symbol, Type::t]
|
|
21
|
+
def discovered_classes: () -> Hash[String, Type::Singleton]
|
|
22
|
+
def in_source_constants: () -> Hash[String, Type::t]
|
|
23
|
+
def discovered_methods: () -> Hash[String, Hash[Symbol, Symbol]]
|
|
24
|
+
def discovered_def_nodes: () -> Hash[String, Hash[Symbol, untyped]]
|
|
25
|
+
def discovered_def_sources: () -> Hash[String, Hash[Symbol, String]]
|
|
26
|
+
def discovered_method_visibilities: () -> Hash[String, Hash[Symbol, Symbol]]
|
|
27
|
+
def discovered_superclasses: () -> Hash[String, String]
|
|
28
|
+
def discovered_includes: () -> Hash[String, Array[String]]
|
|
29
|
+
def discovered_class_sources: () -> Hash[String, Set[String]]
|
|
30
|
+
def data_member_layouts: () -> Hash[String, Array[Symbol]]
|
|
31
|
+
|
|
32
|
+
class DiscoveryIndex
|
|
33
|
+
attr_reader declared_types: Hash[untyped, Type::t]
|
|
34
|
+
attr_reader class_ivars: Hash[String, Hash[Symbol, Type::t]]
|
|
35
|
+
attr_reader class_cvars: Hash[String, Hash[Symbol, Type::t]]
|
|
36
|
+
attr_reader program_globals: Hash[Symbol, Type::t]
|
|
37
|
+
attr_reader discovered_classes: Hash[String, Type::Singleton]
|
|
38
|
+
attr_reader in_source_constants: Hash[String, Type::t]
|
|
39
|
+
attr_reader discovered_methods: Hash[String, Hash[Symbol, Symbol]]
|
|
40
|
+
attr_reader discovered_def_nodes: Hash[String, Hash[Symbol, untyped]]
|
|
41
|
+
attr_reader discovered_def_sources: Hash[String, Hash[Symbol, String]]
|
|
42
|
+
attr_reader discovered_method_visibilities: Hash[String, Hash[Symbol, Symbol]]
|
|
43
|
+
attr_reader discovered_superclasses: Hash[String, String]
|
|
44
|
+
attr_reader discovered_includes: Hash[String, Array[String]]
|
|
45
|
+
attr_reader discovered_class_sources: Hash[String, Set[String]]
|
|
46
|
+
attr_reader data_member_layouts: Hash[String, Array[Symbol]]
|
|
47
|
+
|
|
48
|
+
EMPTY: DiscoveryIndex
|
|
49
|
+
|
|
50
|
+
def with: (?declared_types: Hash[untyped, Type::t], ?class_ivars: Hash[String, Hash[Symbol, Type::t]], ?class_cvars: Hash[String, Hash[Symbol, Type::t]], ?program_globals: Hash[Symbol, Type::t], ?discovered_classes: Hash[String, Type::Singleton], ?in_source_constants: Hash[String, Type::t], ?discovered_methods: Hash[String, Hash[Symbol, Symbol]], ?discovered_def_nodes: Hash[String, Hash[Symbol, untyped]], ?discovered_def_sources: Hash[String, Hash[Symbol, String]], ?discovered_method_visibilities: Hash[String, Hash[Symbol, Symbol]], ?discovered_superclasses: Hash[String, String], ?discovered_includes: Hash[String, Array[String]], ?discovered_class_sources: Hash[String, Set[String]], ?data_member_layouts: Hash[String, Array[Symbol]]) -> DiscoveryIndex
|
|
51
|
+
end
|
|
52
|
+
|
|
26
53
|
class IndexedKey
|
|
27
54
|
attr_reader receiver_kind: Symbol
|
|
28
55
|
attr_reader receiver_name: Symbol
|
|
@@ -37,8 +64,9 @@ module Rigor
|
|
|
37
64
|
|
|
38
65
|
def self.empty: (?environment: Environment, ?source_path: String?) -> Scope
|
|
39
66
|
|
|
40
|
-
def initialize: (environment: Environment, locals: Hash[Symbol, Type::t], ?fact_store: Analysis::FactStore, ?self_type: Type::t?, ?
|
|
67
|
+
def initialize: (environment: Environment, locals: Hash[Symbol, Type::t], ?fact_store: Analysis::FactStore, ?self_type: Type::t?, ?ivars: Hash[Symbol, Type::t], ?cvars: Hash[Symbol, Type::t], ?globals: Hash[Symbol, Type::t], ?discovery: DiscoveryIndex, ?source_path: String?) -> void
|
|
41
68
|
def with_source_path: (String? path) -> Scope
|
|
69
|
+
def with_discovery: (DiscoveryIndex index) -> Scope
|
|
42
70
|
def local: (String | Symbol name) -> Type::t?
|
|
43
71
|
def ivar: (String | Symbol name) -> Type::t?
|
|
44
72
|
def cvar: (String | Symbol name) -> Type::t?
|
|
@@ -48,26 +76,16 @@ module Rigor
|
|
|
48
76
|
def with_cvar: (String | Symbol name, Type::t type) -> Scope
|
|
49
77
|
def with_global: (String | Symbol name, Type::t type) -> Scope
|
|
50
78
|
def class_ivars_for: (String | Symbol? class_name) -> Hash[Symbol, Type::t]
|
|
51
|
-
def with_class_ivars: (Hash[String, Hash[Symbol, Type::t]] table) -> Scope
|
|
52
79
|
def class_cvars_for: (String | Symbol? class_name) -> Hash[Symbol, Type::t]
|
|
53
|
-
def with_class_cvars: (Hash[String, Hash[Symbol, Type::t]] table) -> Scope
|
|
54
|
-
def with_program_globals: (Hash[Symbol, Type::t] table) -> Scope
|
|
55
|
-
def with_discovered_classes: (Hash[String, Type::Singleton] table) -> Scope
|
|
56
|
-
def with_in_source_constants: (Hash[String, Type::t] table) -> Scope
|
|
57
|
-
def with_discovered_methods: (Hash[String, Hash[Symbol, Symbol]] table) -> Scope
|
|
58
80
|
def discovered_method?: (String | Symbol class_name, String | Symbol method_name, Symbol kind) -> bool
|
|
59
|
-
def with_discovered_def_nodes: (Hash[String, Hash[Symbol, untyped]] table) -> Scope
|
|
60
|
-
def with_discovered_def_sources: (Hash[String, Hash[Symbol, String]] table) -> Scope
|
|
61
81
|
def user_def_for: (String | Symbol class_name, String | Symbol method_name) -> untyped?
|
|
62
82
|
def user_def_site_for: (String | Symbol class_name, String | Symbol method_name) -> String?
|
|
63
83
|
def top_level_def_for: (String | Symbol method_name) -> untyped?
|
|
64
84
|
def toplevel?: () -> bool
|
|
65
|
-
def with_discovered_method_visibilities: (Hash[String, Hash[Symbol, Symbol]] table) -> Scope
|
|
66
85
|
def discovered_method_visibility: (String | Symbol class_name, String | Symbol method_name) -> Symbol?
|
|
67
86
|
def superclass_of: (String | Symbol class_name) -> String?
|
|
68
|
-
def
|
|
87
|
+
def data_member_layout: (String | Symbol class_name) -> Array[Symbol]?
|
|
69
88
|
def includes_of: (String | Symbol class_name) -> Array[String]
|
|
70
|
-
def with_discovered_includes: (Hash[String, Array[String]] table) -> Scope
|
|
71
89
|
def indexed_narrowing: (Symbol receiver_kind, String | Symbol receiver_name, untyped key) -> Type::t?
|
|
72
90
|
def with_indexed_narrowing: (Symbol receiver_kind, String | Symbol receiver_name, untyped key, Type::t type) -> Scope
|
|
73
91
|
def without_indexed_narrowing: (Symbol receiver_kind, String | Symbol receiver_name, untyped key) -> Scope
|
|
@@ -78,7 +96,6 @@ module Rigor
|
|
|
78
96
|
def without_method_chain_narrowings_for: (Symbol receiver_kind, String | Symbol receiver_name) -> Scope
|
|
79
97
|
def with_fact: (Analysis::FactStore::Fact fact) -> Scope
|
|
80
98
|
def with_self_type: (Type::t? type) -> Scope
|
|
81
|
-
def with_declared_types: (Hash[untyped, Type::t] table) -> Scope
|
|
82
99
|
def facts_for: (?target: Analysis::FactStore::Target?, ?bucket: Symbol?) -> Array[Analysis::FactStore::Fact]
|
|
83
100
|
def local_facts: (String | Symbol name, ?bucket: Symbol?) -> Array[Analysis::FactStore::Fact]
|
|
84
101
|
def type_of: (untyped node, ?tracer: Inference::FallbackTracer?) -> Type::t
|
data/sig/rigor/source.rbs
CHANGED
|
@@ -16,6 +16,7 @@ module Rigor
|
|
|
16
16
|
def self?.symbol_or_string_name: (untyped? node) -> String?
|
|
17
17
|
def self?.symbol: (untyped? node) -> Symbol?
|
|
18
18
|
def self?.symbol_name: (untyped? node) -> String?
|
|
19
|
+
def self?.symbol_named?: (untyped? node, String name) -> bool
|
|
19
20
|
def self?.symbol_arguments: (untyped? call_node) -> Array[Symbol]
|
|
20
21
|
def self?.symbol_arg: (untyped? call_node, Integer index) -> Symbol?
|
|
21
22
|
end
|
data/sig/rigor/type.rbs
CHANGED
|
@@ -1,9 +1,32 @@
|
|
|
1
1
|
module Rigor
|
|
2
2
|
module Type
|
|
3
|
-
type t = Top | Bot | Dynamic | Constant | IntegerRange | Nominal | Singleton | Union | Difference | Tuple | HashShape
|
|
3
|
+
type t = Top | Bot | Dynamic | Constant | IntegerRange | Nominal | Singleton | Union | Difference | Tuple | HashShape | DataClass | DataInstance
|
|
4
4
|
|
|
5
5
|
type accepts_mode = :strict | :gradual | :loose
|
|
6
6
|
|
|
7
|
+
# The structural interface every `Type::*` carrier satisfies — the
|
|
8
|
+
# internal type-object API (see
|
|
9
|
+
# docs/internal-spec/internal-type-api.md). A structural *interface*
|
|
10
|
+
# (duck-typed: satisfied by having the methods, no `implements`
|
|
11
|
+
# clause), not a "protocol" — that word is reserved for ADR-28
|
|
12
|
+
# path-scoped protocol contracts. The closed `type t` union above is
|
|
13
|
+
# what the engine threads day-to-day; this records the shared
|
|
14
|
+
# per-carrier method contract in one place. Carriers supply the
|
|
15
|
+
# identity trio via `Rigor::ValueSemantics` and `accepts` via
|
|
16
|
+
# `Rigor::Type::AcceptanceRouter`.
|
|
17
|
+
interface _Type
|
|
18
|
+
def describe: (?Symbol verbosity) -> String
|
|
19
|
+
def erase_to_rbs: () -> String
|
|
20
|
+
def top: () -> Trinary
|
|
21
|
+
def bot: () -> Trinary
|
|
22
|
+
def dynamic: () -> Trinary
|
|
23
|
+
def accepts: (Type::t other, ?mode: accepts_mode) -> AcceptsResult
|
|
24
|
+
def ==: (untyped other) -> bool
|
|
25
|
+
def eql?: (untyped other) -> bool
|
|
26
|
+
def hash: () -> Integer
|
|
27
|
+
def inspect: () -> String
|
|
28
|
+
end
|
|
29
|
+
|
|
7
30
|
class Top
|
|
8
31
|
def self.instance: () -> Top
|
|
9
32
|
def describe: (?Symbol verbosity) -> String
|
|
@@ -222,6 +245,38 @@ module Rigor
|
|
|
222
245
|
def inspect: () -> String
|
|
223
246
|
end
|
|
224
247
|
|
|
248
|
+
class DataClass
|
|
249
|
+
attr_reader members: Array[Symbol]
|
|
250
|
+
attr_reader class_name: String?
|
|
251
|
+
def initialize: (Array[Symbol] members, ?String? class_name) -> void
|
|
252
|
+
def describe: (?Symbol verbosity) -> String
|
|
253
|
+
def erase_to_rbs: () -> String
|
|
254
|
+
def top: () -> Trinary
|
|
255
|
+
def bot: () -> Trinary
|
|
256
|
+
def dynamic: () -> Trinary
|
|
257
|
+
def accepts: (Type::t other, ?mode: accepts_mode) -> AcceptsResult
|
|
258
|
+
def ==: (untyped other) -> bool
|
|
259
|
+
def hash: () -> Integer
|
|
260
|
+
def inspect: () -> String
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
class DataInstance
|
|
264
|
+
attr_reader members: Hash[Symbol, Type::t]
|
|
265
|
+
attr_reader class_name: String?
|
|
266
|
+
def initialize: (Hash[Symbol, Type::t] members, ?String? class_name) -> void
|
|
267
|
+
def member_names: () -> Array[Symbol]
|
|
268
|
+
def member_type: (Symbol name) -> Type::t?
|
|
269
|
+
def describe: (?Symbol verbosity) -> String
|
|
270
|
+
def erase_to_rbs: () -> String
|
|
271
|
+
def top: () -> Trinary
|
|
272
|
+
def bot: () -> Trinary
|
|
273
|
+
def dynamic: () -> Trinary
|
|
274
|
+
def accepts: (Type::t other, ?mode: accepts_mode) -> AcceptsResult
|
|
275
|
+
def ==: (untyped other) -> bool
|
|
276
|
+
def hash: () -> Integer
|
|
277
|
+
def inspect: () -> String
|
|
278
|
+
end
|
|
279
|
+
|
|
225
280
|
class AcceptsResult
|
|
226
281
|
attr_reader trinary: Trinary
|
|
227
282
|
attr_reader mode: accepts_mode
|
|
@@ -282,6 +337,8 @@ module Rigor
|
|
|
282
337
|
def self?.universal_int: () -> IntegerRange
|
|
283
338
|
def self?.tuple_of: (*Type::t elements) -> Tuple
|
|
284
339
|
def self?.hash_shape_of: (?Hash[untyped, Type::t]? pairs, **untyped options) -> HashShape
|
|
340
|
+
def self?.data_class_of: (members: Array[Symbol], ?class_name: String?) -> DataClass
|
|
341
|
+
def self?.data_instance_of: (members: Hash[Symbol, Type::t], ?class_name: String?) -> DataInstance
|
|
285
342
|
def self?.union: (*Type::t types) -> Type::t
|
|
286
343
|
def self?.key_of: (Type::t type) -> Type::t
|
|
287
344
|
def self?.value_of: (Type::t type) -> Type::t
|
data/sig/rigor.rbs
CHANGED
|
@@ -113,8 +113,13 @@ module Rigor
|
|
|
113
113
|
attr_reader cache_store: untyped
|
|
114
114
|
attr_reader plugin_registry: untyped
|
|
115
115
|
attr_reader buffer: untyped
|
|
116
|
-
|
|
116
|
+
attr_reader file_dependencies: Hash[String, untyped]
|
|
117
|
+
attr_reader analyzed_files: Array[String]
|
|
118
|
+
def initialize: (configuration: Configuration, ?explain: bool, ?cache_store: untyped, ?plugin_requirer: untyped, ?workers: Integer, ?collect_stats: bool, ?buffer: untyped, ?prebuilt: untyped, ?environment: untyped, ?record_dependencies: bool, ?analyze_only: untyped) -> void
|
|
117
119
|
def run: (?Array[String] paths) -> Result
|
|
120
|
+
def run_source: (source: String, ?path: String) -> Result
|
|
121
|
+
def analysis_file_set: (?Array[String] paths) -> Array[String]
|
|
122
|
+
def file_dependents: () -> Hash[String, untyped]
|
|
118
123
|
def prepare_project_scan: (?paths: Array[String]) -> untyped
|
|
119
124
|
end
|
|
120
125
|
end
|