rigortype 0.4.7 → 0.4.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 +3 -1
- data/data/core_overlay/bigdecimal.rbs +33 -0
- data/data/core_overlay/resolv.rbs +30 -0
- data/data/gem_overlay/activesupport/core_ext.rbs +29 -0
- data/data/gem_overlay/addressable/addressable.rbs +40 -0
- data/docs/handbook/01-getting-started.md +1 -1
- data/docs/handbook/11-sig-gen.md +35 -0
- data/docs/install.md +20 -0
- data/docs/manual/01-installation.md +67 -26
- data/docs/manual/02-cli-reference.md +307 -91
- data/docs/manual/03-configuration.md +41 -3
- data/docs/manual/04-diagnostics.md +5 -4
- data/docs/manual/08-skills.md +11 -0
- data/docs/manual/09-editor-integration.md +8 -0
- data/docs/manual/14-rails-quickstart.md +1 -1
- data/docs/manual/19-effect-labels.md +3 -4
- data/docs/manual/plugins/rigor-actionpack.md +15 -6
- data/docs/manual/plugins/rigor-activesupport-core-ext.md +3 -0
- data/docs/manual/plugins/rigor-sorbet.md +17 -3
- data/lib/rigor/analysis/check_rules/always_raises_shield.rb +147 -0
- data/lib/rigor/analysis/check_rules/call_facts.rb +58 -0
- data/lib/rigor/analysis/check_rules/declaration_sourced_guard.rb +8 -0
- data/lib/rigor/analysis/check_rules/ivar_write_collector.rb +13 -2
- data/lib/rigor/analysis/check_rules/lexical_method_sites.rb +6 -0
- data/lib/rigor/analysis/check_rules/plugin_api_surface.rb +195 -0
- data/lib/rigor/analysis/check_rules/published_constant_guard.rb +40 -11
- data/lib/rigor/analysis/check_rules/rbs_receiver_surface.rb +27 -1
- data/lib/rigor/analysis/check_rules/replaced_singleton_defs.rb +96 -0
- data/lib/rigor/analysis/check_rules/rule_ids.rb +8 -1
- data/lib/rigor/analysis/check_rules/void_value_use_collector.rb +1 -1
- data/lib/rigor/analysis/check_rules.rb +598 -99
- data/lib/rigor/analysis/crash_signature.rb +43 -1
- data/lib/rigor/analysis/dependency_recorder.rb +233 -76
- data/lib/rigor/analysis/incremental.rb +11 -1
- data/lib/rigor/analysis/incremental_run_slot/write_guard.rb +2 -1
- data/lib/rigor/analysis/incremental_session.rb +279 -37
- data/lib/rigor/analysis/reachability/plugin_roots.rb +6 -3
- data/lib/rigor/analysis/rule_catalog.rb +37 -1
- data/lib/rigor/analysis/run_cache_key.rb +27 -3
- data/lib/rigor/analysis/run_disclosure_credit.rb +26 -6
- data/lib/rigor/analysis/runner/buffer_pool_dispatcher.rb +4 -0
- data/lib/rigor/analysis/runner/declaration_position.rb +7 -7
- data/lib/rigor/analysis/runner/diagnostic_aggregator.rb +72 -20
- data/lib/rigor/analysis/runner/effect_envelope_pass.rb +3 -8
- data/lib/rigor/analysis/runner/pool_coordinator.rb +26 -5
- data/lib/rigor/analysis/runner/project_pre_passes.rb +4 -37
- data/lib/rigor/analysis/runner.rb +222 -39
- data/lib/rigor/analysis/self_call_resolution_recorder.rb +61 -22
- data/lib/rigor/analysis/worker_session.rb +42 -41
- data/lib/rigor/bleeding_edge.rb +19 -4
- data/lib/rigor/cache/file_digest.rb +39 -31
- data/lib/rigor/cache/incremental_snapshot.rb +66 -7
- data/lib/rigor/cache/rbs_descriptor.rb +37 -2
- data/lib/rigor/cache/rbs_environment.rb +5 -1
- data/lib/rigor/cli/baseline_command.rb +15 -2
- data/lib/rigor/cli/check_command.rb +4 -2
- data/lib/rigor/cli/effects_snapshot_command.rb +8 -1
- data/lib/rigor/cli/lens_command.rb +17 -2
- data/lib/rigor/cli/sig_gen_command.rb +8 -0
- data/lib/rigor/cli/skill_describe.rb +1 -0
- data/lib/rigor/cli.rb +5 -2
- data/lib/rigor/config_audit.rb +32 -18
- data/lib/rigor/configuration/severity_profile.rb +9 -0
- data/lib/rigor/configuration.rb +32 -5
- data/lib/rigor/effects/collector.rb +53 -21
- data/lib/rigor/environment/bundle_sig_discovery.rb +63 -28
- data/lib/rigor/environment/constant_type_cache_holder.rb +5 -0
- data/lib/rigor/environment/default_libraries.rb +17 -0
- data/lib/rigor/environment/deferred_signature_plan.rb +104 -6
- data/lib/rigor/environment/hkt_registry_holder.rb +6 -0
- data/lib/rigor/environment/rbs_collection_discovery.rb +123 -8
- data/lib/rigor/environment/rbs_coverage_report.rb +12 -11
- data/lib/rigor/environment/rbs_hierarchy.rb +6 -0
- data/lib/rigor/environment/rbs_loader.rb +312 -63
- data/lib/rigor/environment.rb +131 -35
- data/lib/rigor/inference/acceptance.rb +50 -15
- data/lib/rigor/inference/alias_mutation_floor/foreign_locals.rb +117 -0
- data/lib/rigor/inference/alias_mutation_floor/memos.rb +85 -0
- data/lib/rigor/inference/alias_mutation_floor/reach.rb +119 -0
- data/lib/rigor/inference/alias_mutation_floor/site_collector.rb +252 -0
- data/lib/rigor/inference/alias_mutation_floor.rb +339 -0
- data/lib/rigor/inference/anonymous_meta_class.rb +18 -0
- data/lib/rigor/inference/block_auto_splat.rb +1 -1
- data/lib/rigor/inference/block_run_count.rb +9 -2
- data/lib/rigor/inference/builtins/array_catalog.rb +2 -2
- data/lib/rigor/inference/callee_mutation_chain.rb +1 -1
- data/lib/rigor/inference/captured_locals.rb +2 -0
- data/lib/rigor/inference/census_foreign_block.rb +354 -0
- data/lib/rigor/inference/clause_widening.rb +1 -1
- data/lib/rigor/inference/closure_escape_analyzer.rb +11 -4
- data/lib/rigor/inference/construction_escape.rb +56 -15
- data/lib/rigor/inference/declaration_walk.rb +4 -0
- data/lib/rigor/inference/def_node_resolver.rb +32 -14
- data/lib/rigor/inference/def_return_typer.rb +1 -1
- data/lib/rigor/inference/definer_resolution.rb +15 -7
- data/lib/rigor/inference/definers_index.rb +72 -16
- data/lib/rigor/inference/error_info.rb +16 -0
- data/lib/rigor/inference/expression_typer.rb +1459 -287
- data/lib/rigor/inference/flow_tracer.rb +31 -14
- data/lib/rigor/inference/fork_map.rb +3 -0
- data/lib/rigor/inference/fresh_frame_blocks.rb +52 -1
- data/lib/rigor/inference/global_write_census.rb +8 -6
- data/lib/rigor/inference/in_effect_refinements.rb +7 -0
- data/lib/rigor/inference/indexed_narrowing.rb +57 -8
- data/lib/rigor/inference/ivar_writer_census.rb +106 -11
- data/lib/rigor/inference/key_presence_guard.rb +51 -25
- data/lib/rigor/inference/last_line/self_evidence.rb +30 -0
- data/lib/rigor/inference/last_line.rb +5 -2
- data/lib/rigor/inference/loop_value_record.rb +63 -15
- data/lib/rigor/inference/match_rebinding/frame.rb +11 -0
- data/lib/rigor/inference/match_rebinding/yielding_match.rb +74 -18
- data/lib/rigor/inference/match_rebinding.rb +21 -8
- data/lib/rigor/inference/method_dispatcher/block_folding.rb +43 -29
- data/lib/rigor/inference/method_dispatcher/class_keyed_block_params.rb +65 -0
- data/lib/rigor/inference/method_dispatcher/core_enumerable_receiver.rb +44 -0
- data/lib/rigor/inference/method_dispatcher/declared_constructor.rb +151 -0
- data/lib/rigor/inference/method_dispatcher/facet_distribution.rb +1 -1
- data/lib/rigor/inference/method_dispatcher/imprecise_argument.rb +2 -2
- data/lib/rigor/inference/method_dispatcher/interface_shape.rb +181 -0
- data/lib/rigor/inference/method_dispatcher/overload_selector.rb +12 -0
- data/lib/rigor/inference/method_dispatcher/rbs_dispatch.rb +409 -67
- data/lib/rigor/inference/method_dispatcher/self_substitute.rb +1 -1
- data/lib/rigor/inference/method_dispatcher/shape_dispatch.rb +384 -64
- data/lib/rigor/inference/method_dispatcher/singleton_type_params.rb +104 -0
- data/lib/rigor/inference/method_dispatcher.rb +66 -18
- data/lib/rigor/inference/method_parameter_binder.rb +136 -56
- data/lib/rigor/inference/module_function_state/spellings.rb +2 -2
- data/lib/rigor/inference/module_function_state.rb +13 -2
- data/lib/rigor/inference/multi_target_binder.rb +1 -1
- data/lib/rigor/inference/mutation_widening.rb +44 -4
- data/lib/rigor/inference/narrowing.rb +201 -27
- data/lib/rigor/inference/operand_effects.rb +43 -2
- data/lib/rigor/inference/optimistic_origin.rb +133 -8
- data/lib/rigor/inference/origin_lookup.rb +1 -1
- data/lib/rigor/inference/precision_scanner.rb +1 -1
- data/lib/rigor/inference/project_method_ownership.rb +28 -10
- data/lib/rigor/inference/project_patched_methods.rb +65 -13
- data/lib/rigor/inference/project_patched_scanner.rb +120 -25
- data/lib/rigor/inference/project_patched_visibility.rb +39 -3
- data/lib/rigor/inference/rbs_type_translator.rb +68 -15
- data/lib/rigor/inference/receiver_writer_call.rb +67 -0
- data/lib/rigor/inference/recursion_rebinding.rb +157 -0
- data/lib/rigor/inference/refined_dispatch/constructed_class.rb +56 -18
- data/lib/rigor/inference/refined_dispatch/own_method.rb +51 -17
- data/lib/rigor/inference/refined_dispatch.rb +13 -0
- data/lib/rigor/inference/reflective_ivar_write.rb +19 -11
- data/lib/rigor/inference/remover_holder_scan.rb +76 -22
- data/lib/rigor/inference/scope_indexer/class_cvars_collector.rb +13 -6
- data/lib/rigor/inference/scope_indexer/declared_param_writes.rb +12 -11
- data/lib/rigor/inference/scope_indexer/ivar_contributions.rb +188 -28
- data/lib/rigor/inference/scope_indexer/mixin_accumulator.rb +136 -9
- data/lib/rigor/inference/scope_indexer.rb +2079 -183
- data/lib/rigor/inference/self_call_ivar_writes.rb +26 -7
- data/lib/rigor/inference/self_preserving_block.rb +87 -0
- data/lib/rigor/inference/singleton_hook_decline.rb +41 -6
- data/lib/rigor/inference/singleton_object_constant.rb +32 -2
- data/lib/rigor/inference/statement_evaluator.rb +970 -250
- data/lib/rigor/inference/string_mutation.rb +14 -0
- data/lib/rigor/inference/synthetic_method_scanner.rb +35 -11
- data/lib/rigor/inference/toplevel_def_census.rb +14 -6
- data/lib/rigor/inference/unknown_store_widening.rb +1 -1
- data/lib/rigor/inference/untyped_rejoin.rb +1 -1
- data/lib/rigor/inference/void_tail_summary.rb +29 -10
- data/lib/rigor/lens/claims/comparison.rb +78 -0
- data/lib/rigor/lens/claims/request.rb +131 -0
- data/lib/rigor/lens/claims/type_reader.rb +216 -0
- data/lib/rigor/lens/claims.rb +208 -0
- data/lib/rigor/lens/contract_reader.rb +5 -0
- data/lib/rigor/lens/document.rb +1 -1
- data/lib/rigor/lens/file_reader.rb +21 -8
- data/lib/rigor/lens/run.rb +8 -0
- data/lib/rigor/lens.rb +1 -1
- data/lib/rigor/library_probe.rb +68 -0
- data/lib/rigor/memo_audit.rb +282 -0
- data/lib/rigor/plugin/base.rb +15 -2
- data/lib/rigor/plugin/io_boundary.rb +25 -3
- data/lib/rigor/plugin/manifest.rb +7 -3
- data/lib/rigor/plugin/registry.rb +13 -2
- data/lib/rigor/plugin/trust_policy.rb +46 -0
- data/lib/rigor/protection/mutation_cache.rb +4 -1
- data/lib/rigor/reflection/constant_ancestors.rb +79 -22
- data/lib/rigor/reflection/declaration_collectors.rb +55 -0
- data/lib/rigor/reflection/declarations.rb +58 -0
- data/lib/rigor/reflection/project_method.rb +177 -0
- data/lib/rigor/reflection.rb +2 -0
- data/lib/rigor/rooted_glob.rb +18 -1
- data/lib/rigor/run_scoped_slots.rb +20 -20
- data/lib/rigor/scope/discovery_index.rb +149 -2
- data/lib/rigor/scope/resolution_chain/relevance.rb +14 -1
- data/lib/rigor/scope/resolution_chain.rb +900 -55
- data/lib/rigor/scope.rb +307 -34
- data/lib/rigor/sig_gen/bot_proposal_guard.rb +306 -0
- data/lib/rigor/sig_gen/classification.rb +14 -1
- data/lib/rigor/sig_gen/generator.rb +222 -13
- data/lib/rigor/sig_gen/method_candidate.rb +14 -0
- data/lib/rigor/sig_gen/observation_collector.rb +11 -2
- data/lib/rigor/sig_gen/platform_guarded_files.rb +184 -0
- data/lib/rigor/sig_gen/skip_reason_catalog.rb +47 -0
- data/lib/rigor/sig_gen/writer.rb +21 -0
- data/lib/rigor/sig_gen.rb +1 -0
- data/lib/rigor/source/forwardable_delegators.rb +122 -0
- data/lib/rigor/source/node_children.rb +13 -0
- data/lib/rigor/type/combinator.rb +164 -8
- data/lib/rigor/type/interface.rb +60 -0
- data/lib/rigor/type.rb +1 -0
- data/lib/rigor/type_of_memo/serving.rb +99 -0
- data/lib/rigor/type_of_memo/stats.rb +43 -0
- data/lib/rigor/type_of_memo.rb +337 -0
- data/lib/rigor/typing_state.rb +1094 -0
- data/lib/rigor/version.rb +1 -1
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/view_assigns.rb +2 -2
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack.rb +57 -25
- data/plugins/rigor-active-model-serializers/lib/rigor/plugin/active_model_serializers.rb +3 -6
- data/plugins/rigor-activejob/lib/rigor/plugin/activejob/analyzer.rb +25 -1
- data/plugins/rigor-activejob/lib/rigor/plugin/activejob/job_discoverer.rb +16 -6
- data/plugins/rigor-activejob/lib/rigor/plugin/activejob/job_index.rb +4 -2
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/analyzer.rb +2 -1
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/schema_parser.rb +130 -30
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/schema_table.rb +20 -5
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/structure_sql_parser.rb +7 -4
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord.rb +49 -13
- data/plugins/rigor-activerecord/sig/active_record/relation.rbs +19 -5
- data/plugins/rigor-activestorage/lib/rigor/plugin/activestorage.rb +4 -2
- data/plugins/rigor-activesupport-core-ext/lib/rigor/plugin/activesupport_core_ext.rb +13 -5
- data/plugins/rigor-activesupport-core-ext/sig/active_support/core_ext.rbs +29 -0
- data/plugins/rigor-alba/lib/rigor/plugin/alba/resource_collector.rb +15 -21
- data/plugins/rigor-alba/lib/rigor/plugin/alba/resource_discoverer.rb +1 -6
- data/plugins/rigor-ffi/lib/rigor/plugin/ffi.rb +4 -2
- data/plugins/rigor-graphql/lib/rigor/plugin/graphql.rb +12 -2
- data/plugins/rigor-mangrove/lib/rigor/plugin/mangrove.rb +6 -0
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/analyzer.rb +199 -1
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes.rb +3 -2
- data/plugins/rigor-rspec/lib/rigor/plugin/rspec/matcher_analyzer.rb +4 -4
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/catalog.rb +209 -2
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/catalog_walker.rb +146 -7
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/type_translator.rb +52 -34
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet.rb +80 -3
- data/plugins/rigor-typelizer/lib/rigor/plugin/typelizer/serializer_collector.rb +16 -16
- data/plugins/rigor-typelizer/lib/rigor/plugin/typelizer/serializer_discoverer.rb +1 -6
- data/sig/rigor/analysis/check_rules/rule_walk.rbs +6 -0
- data/sig/rigor/analysis/fact_store.rbs +2 -3
- data/sig/rigor/cache/descriptor.rbs +14 -0
- data/sig/rigor/environment.rbs +4 -1
- data/sig/rigor/plugin/base.rbs +53 -19
- data/sig/rigor/plugin/interfaces.rbs +51 -0
- data/sig/rigor/plugin/io_boundary.rbs +2 -3
- data/sig/rigor/plugin/node_context.rbs +21 -0
- data/sig/rigor/reflection.rbs +37 -0
- data/sig/rigor/scope.rbs +22 -3
- data/sig/rigor/trinary.rbs +1 -0
- data/sig/rigor/type.rbs +9 -3
- data/sig/rigor.rbs +3 -2
- data/skills/rigor-ask/SKILL.md +1 -0
- data/skills/rigor-project-init/references/01-detect.md +1 -0
- data/skills/rigor-project-init/references/03-baseline-and-bugs.md +5 -1
- data/skills/rigor-project-init/references/06-agent-contract.md +4 -4
- data/skills/rigor-rbs-contract/SKILL.md +147 -0
- data/skills/rigor-rbs-contract/references/01-finding-candidates.md +212 -0
- data/skills/rigor-rbs-contract/references/02-contract-rules.md +157 -0
- data/skills/rigor-rbs-contract/references/03-target-own-code.md +90 -0
- data/skills/rigor-rbs-contract/references/04-target-gem-rbs-collection.md +210 -0
- data/skills/rigor-rbs-contract/references/05-declaration-mutants.md +182 -0
- data/skills/rigor-rbs-setup/SKILL.md +3 -1
- data/skills/rigor-type-oracle/SKILL.md +26 -1
- data/skills/rigor-type-oracle/references/02-agents-md-fragment.md +4 -3
- metadata +48 -2
- data/lib/rigor/inference/memo_audit.rb +0 -55
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: d2aa3cbe98e027e6ed461d3252980ae558778e4df0b2c78f658b848e73b13d8b
|
|
4
|
+
data.tar.gz: 611f238af77124e90cab5844f65be0720898b93469eb7a908d1e82eb4d9a1177
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8b82ef7bdde5d2f8ca978379190effc8730bd6dcb7224207282b9b820d06a2853cc61f87314ad6b8b7a0d81351f3aedd869d1f8449bb6f75e74f83baa56590b8
|
|
7
|
+
data.tar.gz: fe1685b7aad2412ea38090bdc53e350972c25522036330375eba7424457e086057018bad9827c35c1e4e0c65ca48d496bb54e5a8f58f0213668f4609053c7fdd
|
data/README.md
CHANGED
|
@@ -20,6 +20,8 @@ rigor check app lib # find bugs in the code you already have
|
|
|
20
20
|
global `-g` install keeps it off your project's pins. See
|
|
21
21
|
[Get started](#get-started-in-one-prompt).)
|
|
22
22
|
|
|
23
|
+
If your project's bundle also lists `rbs` (directly, or through Steep or `rbs_rails`), the `rbs` that `gem:rigortype` puts on `PATH` can shadow it; see the [install guide's note on `rbs` shadowing](docs/install.md#case-a--mise-is-available-recommended).
|
|
24
|
+
|
|
23
25
|
No annotations required, no runtime dependency, no changes to your
|
|
24
26
|
code — and any RBS you do add, Rigor reads and uses. Rigor parses Ruby
|
|
25
27
|
with
|
|
@@ -232,7 +234,7 @@ rigor docs --list # list every bundled page
|
|
|
232
234
|
|
|
233
235
|
## Status
|
|
234
236
|
|
|
235
|
-
Current release: **`v0.4.
|
|
237
|
+
Current release: **`v0.4.8`** (2026-11-15) — on the
|
|
236
238
|
`0.4.x` line, continuing the evaluation era opened by `v0.2.0`, the first
|
|
237
239
|
publicly-announced (general / evaluation) release. The line publishes
|
|
238
240
|
an enumerated [compatibility surface](docs/compatibility.md) as a
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Rigor core overlay — supplemental core signatures.
|
|
2
|
+
#
|
|
3
|
+
# --- BigDecimal precision readers (issue #2969) ---
|
|
4
|
+
#
|
|
5
|
+
# rbs 4.2 ships `stdlib/bigdecimal/0/big_decimal.rbs` without `precision`, `scale`,
|
|
6
|
+
# `precision_scale` or `n_significant_digits`, and the bigdecimal gem's own `sig/` (4.1.3)
|
|
7
|
+
# omits them too, so `BigDecimal("1.5").precision` reported `call.undefined-method` on correct code.
|
|
8
|
+
#
|
|
9
|
+
# Upstream: bigdecimal 4.1.3 `ext/bigdecimal/bigdecimal.c` registers the four readers as instance
|
|
10
|
+
# methods (`rb_define_method(rb_cBigDecimal, "precision", ...)`, and likewise for the other three).
|
|
11
|
+
# Their documented results: `precision -> integer` (decimal digits), `scale -> integer`,
|
|
12
|
+
# `precision_scale -> [integer, integer]`, and `n_significant_digits -> integer`.
|
|
13
|
+
#
|
|
14
|
+
# bigdecimal is a bundled gem, not a default library, so this file is gated on it
|
|
15
|
+
# (`Rigor::Environment::RbsLoader::LIBRARY_SUPPLEMENT_CORE_OVERLAYS`). Without the library the file would
|
|
16
|
+
# open a phantom `BigDecimal` that nothing else declares.
|
|
17
|
+
#
|
|
18
|
+
# The methods sit on a module the class includes, not as direct `def`s, so a later rbs or a project
|
|
19
|
+
# `sig/` that declares one of them directly overrides it instead of raising
|
|
20
|
+
# `DuplicatedMethodDefinitionError` (the same shape as `process.rbs` and `ruby41_core_overlay`).
|
|
21
|
+
|
|
22
|
+
module RigorCoreOverlay
|
|
23
|
+
module BigDecimalPrecision
|
|
24
|
+
def precision: () -> Integer
|
|
25
|
+
def scale: () -> Integer
|
|
26
|
+
def precision_scale: () -> [Integer, Integer]
|
|
27
|
+
def n_significant_digits: () -> Integer
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
class BigDecimal
|
|
32
|
+
include RigorCoreOverlay::BigDecimalPrecision
|
|
33
|
+
end
|
|
@@ -29,3 +29,33 @@ class Resolv
|
|
|
29
29
|
def initialize: (?(Array[Resolv::Hosts | Resolv::DNS] | Hash[Symbol, untyped])? resolvers, ?use_ipv6: bool?) -> untyped
|
|
30
30
|
| ...
|
|
31
31
|
end
|
|
32
|
+
|
|
33
|
+
# --- Resolv::DNS#getresources / #getresource / #each_resource ---
|
|
34
|
+
#
|
|
35
|
+
# `rbs` declares the three typeclass lookups as answering the base class
|
|
36
|
+
# whatever the typeclass argument names:
|
|
37
|
+
#
|
|
38
|
+
# def getresources: (dns_name name, singleton(Resolv::DNS::Query) typeclass) -> Array[Resolv::DNS::Resource]
|
|
39
|
+
#
|
|
40
|
+
# so `dns.getresources(d, Resolv::DNS::Resource::IN::MX).map(&:exchange)`
|
|
41
|
+
# false-fires `call.undefined-method` (`exchange` is declared on
|
|
42
|
+
# `Resolv::DNS::Resource::MX`, not on `Resource`). At runtime every returned
|
|
43
|
+
# record is an instance of the typeclass (rigortype/rigor#2828).
|
|
44
|
+
#
|
|
45
|
+
# The overlay prepends a generic overload binding `T` from `singleton(T)`, so
|
|
46
|
+
# the answer is `Array[Resolv::DNS::Resource::IN::MX]`. An argument the
|
|
47
|
+
# binder cannot read as a class object under the `Resource` bound leaves `T`
|
|
48
|
+
# unbound, and the base overload (`| ...`) still accepts every `Query`
|
|
49
|
+
# typeclass the upstream signature does.
|
|
50
|
+
class Resolv
|
|
51
|
+
class DNS
|
|
52
|
+
def each_resource: [T < Resolv::DNS::Resource] (Resolv::DNS::dns_name name, singleton(T) typeclass) { (T) -> void } -> void
|
|
53
|
+
| ...
|
|
54
|
+
|
|
55
|
+
def getresource: [T < Resolv::DNS::Resource] (Resolv::DNS::dns_name name, singleton(T) typeclass) -> T
|
|
56
|
+
| ...
|
|
57
|
+
|
|
58
|
+
def getresources: [T < Resolv::DNS::Resource] (Resolv::DNS::dns_name name, singleton(T) typeclass) -> Array[T]
|
|
59
|
+
| ...
|
|
60
|
+
end
|
|
61
|
+
end
|
|
@@ -347,6 +347,35 @@ class Float
|
|
|
347
347
|
def gigabytes: () -> Float
|
|
348
348
|
end
|
|
349
349
|
|
|
350
|
+
# ---------------------------------------------------------------
|
|
351
|
+
# NumericWithFormat — ActiveSupport's `core_ext/numeric/conversions`, included into Integer, Float and
|
|
352
|
+
# BigDecimal. Declared on the module and included, not as a `def` on each class, so a project `sig/` that
|
|
353
|
+
# declares `Integer#to_fs` itself overrides it instead of raising `DuplicatedMethodDefinitionError` (the
|
|
354
|
+
# `process.rbs` shape). Not pure: the Symbol formats read `I18n` for their locale. An Integer or String
|
|
355
|
+
# format is `to_s(format)`, and no format is `to_s`, so every form answers a String. `options` is any
|
|
356
|
+
# Hash-like value: ActiveSupport calls `symbolize_keys` on it, so String keys and a HashWithIndifferentAccess
|
|
357
|
+
# are both valid.
|
|
358
|
+
# ---------------------------------------------------------------
|
|
359
|
+
|
|
360
|
+
module ActiveSupport
|
|
361
|
+
module NumericWithFormat
|
|
362
|
+
def to_fs: (?(Symbol | Integer | String | nil) format, ?Hash[untyped, untyped]? options) -> String
|
|
363
|
+
def to_formatted_s: (?(Symbol | Integer | String | nil) format, ?Hash[untyped, untyped]? options) -> String
|
|
364
|
+
end
|
|
365
|
+
end
|
|
366
|
+
|
|
367
|
+
class Integer
|
|
368
|
+
include ActiveSupport::NumericWithFormat
|
|
369
|
+
end
|
|
370
|
+
|
|
371
|
+
class Float
|
|
372
|
+
include ActiveSupport::NumericWithFormat
|
|
373
|
+
end
|
|
374
|
+
|
|
375
|
+
class BigDecimal
|
|
376
|
+
include ActiveSupport::NumericWithFormat
|
|
377
|
+
end
|
|
378
|
+
|
|
350
379
|
# ---------------------------------------------------------------
|
|
351
380
|
# ActiveSupport::Duration — issue #632
|
|
352
381
|
# ---------------------------------------------------------------
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Addressable — `rbs collection` correction overlay (issue #2857).
|
|
2
|
+
#
|
|
3
|
+
# gem_rbs_collection's `gems/addressable/*/addressable.rbs` declares
|
|
4
|
+
# `Addressable::URI.parse` as `(String | URI uri) -> instance`, but
|
|
5
|
+
# `Addressable::URI.parse(nil)` returns nil, so `Addressable::URI.parse(x)`
|
|
6
|
+
# on a `String?` — the mastodon `fetch_link_card_service.rb` shape — drew a
|
|
7
|
+
# false `call.argument-type-mismatch` on correct code.
|
|
8
|
+
#
|
|
9
|
+
# Unlike the activesupport overlay this directory does NOT ride the ADR-72
|
|
10
|
+
# `:missing` gate: it loads only when `rbs collection` supplies the gem's
|
|
11
|
+
# RBS (`:rbs_collection` coverage — `Environment::GEM_OVERLAY_COVERAGE_SOURCES`).
|
|
12
|
+
# The deferred-signature plan (#2422) then composes this declaration over the
|
|
13
|
+
# collection's copy as an overload continuation, so `parse(nil)` binds nil
|
|
14
|
+
# while `parse(String | URI)` keeps the URI answer and a `String?` argument
|
|
15
|
+
# mismatches nothing. Under `:missing` coverage — no sigs at all — the
|
|
16
|
+
# overlay stays unloaded on purpose: this partial `Addressable::URI`
|
|
17
|
+
# declaration would make every member it omits (`host`, `path`, …) a false
|
|
18
|
+
# `call.undefined-method`, which is worse than the `Dynamic` silence a
|
|
19
|
+
# sig-less gem already has.
|
|
20
|
+
module Addressable
|
|
21
|
+
class URI
|
|
22
|
+
# Two arms, URI-carrying first — the order is load-bearing, not cosmetic.
|
|
23
|
+
# `Addressable::URI` is RBS-known but not loadable in the analyzer's host
|
|
24
|
+
# process, so `NilClass`-vs-`Addressable::URI` acceptance answers `maybe`,
|
|
25
|
+
# and the overload selector's strict pass takes the FIRST maybe-match: a
|
|
26
|
+
# leading `(::NilClass)` arm would shadow this one and type
|
|
27
|
+
# `parse(existing_uri)` as `nil`. With the URI arm first it answers `yes`
|
|
28
|
+
# and wins; `nil` still reaches the second arm.
|
|
29
|
+
#
|
|
30
|
+
# `::NilClass`, not the `nil` keyword: they accept the same arguments, but
|
|
31
|
+
# RBS types `nil` as `Types::Bases::Nil`, which the
|
|
32
|
+
# `call.argument-type-mismatch` non-nil channel reads as "undecidable →
|
|
33
|
+
# admits", silently dropping `Addressable::URI.parse(123)`. `NilClass` is
|
|
34
|
+
# a `ClassInstance`, so the channel still refutes what no overload admits.
|
|
35
|
+
#
|
|
36
|
+
# The collection's own `(String | URI uri) -> instance` stays reachable as
|
|
37
|
+
# the `| ...` fallback the deferred plan appends.
|
|
38
|
+
def self.parse: (String | URI uri) -> URI | (::NilClass) -> nil
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -59,7 +59,7 @@ mise use gem:rigortype
|
|
|
59
59
|
With mise activated in your shell, `rigor` is on your `PATH`. The
|
|
60
60
|
gem is named `rigortype` (the name `rigor` was taken on RubyGems);
|
|
61
61
|
the executable it installs is `rigor`. If you already have Ruby
|
|
62
|
-
4.0, `gem install rigortype` works too.
|
|
62
|
+
4.0, `gem install rigortype` works too. If the project's bundle lists `rbs`, the `rbs` that `gem:rigortype` puts on `PATH` can shadow it; see the [install guide's note on `rbs` shadowing](../install.md#case-a--mise-is-available-recommended).
|
|
63
63
|
|
|
64
64
|
For shell activation and shims, `asdf`, and developing inside a
|
|
65
65
|
container, see [Installing Rigor](../manual/01-installation.md);
|
data/docs/handbook/11-sig-gen.md
CHANGED
|
@@ -164,6 +164,32 @@ The `sig.skipped.*` reasons are:
|
|
|
164
164
|
inline and in `sig/`, and the two disagree. A refusal:
|
|
165
165
|
`--write` and `--check` exit `1`. See
|
|
166
166
|
[Methods declared inline](#methods-declared-inline).
|
|
167
|
+
- `sig.skipped.overridden-bot` — the method's body never
|
|
168
|
+
returns (its inferred return is `bot`), and the analysed
|
|
169
|
+
code defines the method again, with `def` or
|
|
170
|
+
`define_method`: in a subclass, signed or not, in a class
|
|
171
|
+
that includes the method's module, in a module included
|
|
172
|
+
later or prepended, or as an extending class's own
|
|
173
|
+
singleton method. `bot` would describe only the base body
|
|
174
|
+
the overrides replace. A class left with nothing to write
|
|
175
|
+
because of this is still written as an empty class, so its
|
|
176
|
+
subclasses keep their signatures, unless your `sig/` or a
|
|
177
|
+
gem's signatures already declare it.
|
|
178
|
+
- `sig.skipped.abstract-method` — the method's inferred return
|
|
179
|
+
is `bot` from an abstract-style raise: `NotImplementedError`,
|
|
180
|
+
an error class named `Abstract…` or `NotImplemented…`, or a
|
|
181
|
+
message that asks for the method to be implemented or
|
|
182
|
+
overridden, or to define it by name ("please define
|
|
183
|
+
about"; not "you must define a block"). The
|
|
184
|
+
implementations may live outside the analysed code, as in a
|
|
185
|
+
plugin gem, so no `bot` is proposed.
|
|
186
|
+
- `sig.skipped.template-method` — the method's inferred return
|
|
187
|
+
is `bot`, its body does not end in a direct `raise`, `fail`,
|
|
188
|
+
`throw`, `exit` or `abort`, and it calls a method the
|
|
189
|
+
analysed code overrides or declares abstract, directly or
|
|
190
|
+
through self-dispatched calls. The call is matched by name,
|
|
191
|
+
whatever the receiver. A `bot` that ends in a direct
|
|
192
|
+
`throw` or a raise nothing overrides is still proposed.
|
|
167
193
|
- `sig.skipped.top-level-def` — a plain top-level `def`, which
|
|
168
194
|
defines a private `Object` method. sig-gen lists it (file,
|
|
169
195
|
method name and this reason in `--format=json`) but writes no
|
|
@@ -185,6 +211,15 @@ The `sig.skipped.*` reasons are:
|
|
|
185
211
|
down with it. The rest of the signatures are unaffected;
|
|
186
212
|
the skipped method is reported on stderr, and it is worth
|
|
187
213
|
reporting to us.
|
|
214
|
+
- `sig.skipped.platform-guarded` — the method is defined in
|
|
215
|
+
a file Ruby loads only under a `RUBY_ENGINE`,
|
|
216
|
+
`RUBY_PLATFORM` or `defined?(…)` require guard (the
|
|
217
|
+
`if RUBY_ENGINE == 'truffleruby'` → `require
|
|
218
|
+
"stackprof/truffleruby"` shape), so it is not an ordinary
|
|
219
|
+
definition for every platform. sig-gen withholds the
|
|
220
|
+
proposal when another scanned file also defines the
|
|
221
|
+
method, or when the inferred return is `bot` — the shape
|
|
222
|
+
a raising stub takes (#3035).
|
|
188
223
|
|
|
189
224
|
### Tighter returns keep the declared parameters
|
|
190
225
|
|
data/docs/install.md
CHANGED
|
@@ -109,6 +109,26 @@ A user-wide `~/.config/mise/config.toml` entry for `gem:rigortype`
|
|
|
109
109
|
keeps applying outside this project. Mention it if it names an older
|
|
110
110
|
version, but do not edit global config without the user's consent.
|
|
111
111
|
|
|
112
|
+
`gem:rigortype` also puts an `rbs` on `PATH`: mise wraps every
|
|
113
|
+
executable the gem's dependencies install, and that wrapper runs with
|
|
114
|
+
rigortype's private `GEM_HOME`. When `rbs` is in the project's bundle
|
|
115
|
+
(`Gemfile.lock` lists it, directly or through Steep or `rbs_rails`)
|
|
116
|
+
and the bundle uses the default path, `bundle exec rbs` runs the
|
|
117
|
+
wrapper instead of the project's `rbs`. A git-sourced gem then fails
|
|
118
|
+
with `is not yet checked out` under rigortype's `GEM_HOME`. A bundle
|
|
119
|
+
installed under a configured path such as `vendor/bundle` is not
|
|
120
|
+
affected, because `bundle exec` puts that path's `bin` first. Only
|
|
121
|
+
when `Gemfile.lock` lists `rbs`, run `mise exec -- bundle exec which
|
|
122
|
+
rbs` (the shell you are in has not picked up the new tool yet, so a
|
|
123
|
+
bare `bundle exec which rbs` can miss it). If it prints a path under
|
|
124
|
+
`installs/gem-rigortype/`, tell the user, and tell them the fix is
|
|
125
|
+
local to this checkout: `bundle config set --local path vendor/bundle`
|
|
126
|
+
followed by `bundle install` writes an untracked `.bundle/config`
|
|
127
|
+
(teammates and CI keep the default path), puts the bundle in
|
|
128
|
+
`vendor/`, and makes Rigor read each bundled gem's shipped `sig/`
|
|
129
|
+
(ADR-27). Offer it; do not change the bundle path without their
|
|
130
|
+
consent.
|
|
131
|
+
|
|
112
132
|
Then verify:
|
|
113
133
|
|
|
114
134
|
```sh
|
|
@@ -28,6 +28,14 @@ so nothing is lost by installing it separately.
|
|
|
28
28
|
> [Rails quickstart](14-rails-quickstart.md)). The channels below
|
|
29
29
|
> are the manual route.
|
|
30
30
|
|
|
31
|
+
> **Only trying Rigor in VS Code?** When the
|
|
32
|
+
> [Rigor extension](../../editors/vscode/README.md) finds no `rigor`,
|
|
33
|
+
> it offers to install one into its own storage, using a Ruby 4.0
|
|
34
|
+
> already on the machine (or one `mise install ruby@4.0` provides).
|
|
35
|
+
> That install serves the editor only and is never used for a project
|
|
36
|
+
> that pins `rigortype`; for the command line and CI, use a channel
|
|
37
|
+
> below.
|
|
38
|
+
|
|
31
39
|
### Set up in your language
|
|
32
40
|
|
|
33
41
|
The prompt above is plain natural language — your agent follows the
|
|
@@ -269,6 +277,8 @@ A few things worth knowing if you have not used mise before:
|
|
|
269
277
|
The gem is `rigortype`; the executable it installs (and the only
|
|
270
278
|
command you run) is `rigor`.
|
|
271
279
|
|
|
280
|
+
If the project's bundle lists `rbs`, the `rbs` that `gem:rigortype` puts on `PATH` can shadow the project's own; see the [install guide's note on `rbs` shadowing](../install.md#case-a--mise-is-available-recommended).
|
|
281
|
+
|
|
272
282
|
### Putting `rigor` on your PATH
|
|
273
283
|
|
|
274
284
|
Installing the tool is not enough on its own — `rigor` reaches your
|
|
@@ -356,8 +366,63 @@ gem install rigortype
|
|
|
356
366
|
`asdf` has no general-purpose gem backend, so the gem itself is
|
|
357
367
|
installed with `gem install` rather than an `asdf` command. `mise`
|
|
358
368
|
(above) is the more integrated option because its `gem:` backend
|
|
359
|
-
records the gem in the same config that records Ruby, and — as
|
|
360
|
-
|
|
369
|
+
records the gem in the same config that records Ruby, and — as
|
|
370
|
+
[Simple alternative](#simple-alternative--gem-install) explains —
|
|
371
|
+
keeps the two from interfering.
|
|
372
|
+
|
|
373
|
+
## Secondary — a pinned bundle
|
|
374
|
+
|
|
375
|
+
The rule at the top of this chapter is about your *application's*
|
|
376
|
+
`Gemfile` — the one Bundler resolves against your app's gems, and whose
|
|
377
|
+
entries `Bundler.require` loads at boot. It is not a rule against
|
|
378
|
+
Bundler. A `Gemfile` holding nothing but Rigor, resolved separately and
|
|
379
|
+
selected with `BUNDLE_GEMFILE`, keeps every property the prohibition
|
|
380
|
+
exists to protect: your application's dependency graph never meets
|
|
381
|
+
Rigor's, and your application's Ruby is never constrained by Rigor's.
|
|
382
|
+
|
|
383
|
+
Commit it, with its `Gemfile.lock`, at `.github/rigor/`, the path Rigor's
|
|
384
|
+
CI template uses. The VS Code extension runs it (discovery kind
|
|
385
|
+
`pinned-bundle`, under a Ruby it finds the way it does for its managed
|
|
386
|
+
Rigor, preferring one that matches the lockfile's `RUBY VERSION` or
|
|
387
|
+
the Gemfile's `ruby` line; `rigor.server.bundleGemfile` names another
|
|
388
|
+
location), and never a different Rigor while it pins one.
|
|
389
|
+
`rigor doctor` does not recognise it yet
|
|
390
|
+
([#2751](https://github.com/rigortype/rigor/issues/2751)):
|
|
391
|
+
|
|
392
|
+
```ruby
|
|
393
|
+
# .github/rigor/Gemfile
|
|
394
|
+
source "https://rubygems.org"
|
|
395
|
+
ruby ">= 4.0.0", "< 4.1"
|
|
396
|
+
gem "rigortype", "~> 0.4"
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
Each command has to run under a Ruby 4.0, which is usually not your
|
|
400
|
+
project's Ruby, so select it on the command line:
|
|
401
|
+
|
|
402
|
+
```sh
|
|
403
|
+
# with mise
|
|
404
|
+
BUNDLE_GEMFILE=.github/rigor/Gemfile mise exec ruby@4.0 -- bundle install
|
|
405
|
+
BUNDLE_GEMFILE=.github/rigor/Gemfile mise exec ruby@4.0 -- bundle exec rigor check
|
|
406
|
+
# with rbenv
|
|
407
|
+
BUNDLE_GEMFILE=.github/rigor/Gemfile RBENV_VERSION=4.0.5 bundle exec rigor check
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
A `.ruby-version` inside `.github/rigor/` does not select it, because
|
|
411
|
+
Rigor runs from the project root, and neither does a Bundler binstub,
|
|
412
|
+
whose `#!/usr/bin/env ruby` runs the project's Ruby.
|
|
413
|
+
|
|
414
|
+
The same pin then serves local runs and CI, Dependabot can keep it
|
|
415
|
+
current (see [Pinning Rigor's version](11-ci.md#pinning-rigors-version)
|
|
416
|
+
in the CI chapter), and it is where a third-party Rigor plugin gem
|
|
417
|
+
goes. What it does **not** do is provide Ruby: every `bundle exec`
|
|
418
|
+
must already run under a Ruby 4.0, which the `ruby` line checks. Only
|
|
419
|
+
`rigortype` is pinned exactly; the lockfile records the dependency
|
|
420
|
+
versions Bundler resolved when you installed.
|
|
421
|
+
|
|
422
|
+
It is more moving parts than `mise use --pin gem:rigortype`, which
|
|
423
|
+
records the version and the Ruby in one place and needs no `bundle
|
|
424
|
+
exec`. Reach for it when your team already runs everything through
|
|
425
|
+
Bundler, or needs a plugin gem — not as a first choice.
|
|
361
426
|
|
|
362
427
|
## Simple alternative — gem install
|
|
363
428
|
|
|
@@ -386,30 +451,6 @@ reach it. A `gem install` under a Ruby 4.0 you never switch away from
|
|
|
386
451
|
is perfectly fine; one that shares a Ruby with projects you switch
|
|
387
452
|
between is a footgun.
|
|
388
453
|
|
|
389
|
-
## If you want Bundler to manage the version
|
|
390
|
-
|
|
391
|
-
The rule at the top of this chapter is about your *application's*
|
|
392
|
-
`Gemfile` — the one Bundler resolves against your app's gems, and whose
|
|
393
|
-
entries `Bundler.require` loads at boot. It is not a rule against
|
|
394
|
-
Bundler. A `Gemfile` holding nothing but Rigor, resolved separately and
|
|
395
|
-
selected with `BUNDLE_GEMFILE`, keeps every property the prohibition
|
|
396
|
-
exists to protect: your application's dependency graph never meets
|
|
397
|
-
Rigor's, and your application's Ruby is never constrained by Rigor's.
|
|
398
|
-
|
|
399
|
-
That arrangement — a `Gemfile` under `.github/rigor/`, plus the
|
|
400
|
-
Dependabot config that keeps it current — is written up under
|
|
401
|
-
[Pinning Rigor's version](11-ci.md#pinning-rigors-version) in the CI
|
|
402
|
-
chapter. Nothing about it is CI-specific:
|
|
403
|
-
|
|
404
|
-
```sh
|
|
405
|
-
BUNDLE_GEMFILE=.github/rigor/Gemfile bundle exec rigor check
|
|
406
|
-
```
|
|
407
|
-
|
|
408
|
-
It is more moving parts than `mise use --pin gem:rigortype`, which
|
|
409
|
-
records the same version in one line and needs no `bundle exec`. Reach
|
|
410
|
-
for it when your team already runs everything through Bundler and wants
|
|
411
|
-
Rigor on the same footing — not as a first choice.
|
|
412
|
-
|
|
413
454
|
## Nix
|
|
414
455
|
|
|
415
456
|
If you use Nix, Rigor's flake exposes the executable as a package,
|