rigortype 0.4.5 → 0.4.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (136) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/docs/handbook/11-sig-gen.md +11 -2
  4. data/docs/manual/02-cli-reference.md +46 -7
  5. data/docs/manual/03-configuration.md +2 -1
  6. data/docs/manual/04-diagnostics.md +1 -1
  7. data/docs/manual/10-mcp-server.md +9 -1
  8. data/docs/manual/12-caching.md +8 -1
  9. data/docs/manual/plugins/rigor-actionmailer.md +30 -0
  10. data/docs/manual/plugins/rigor-actionpack.md +30 -0
  11. data/docs/manual/plugins/rigor-devise.md +15 -0
  12. data/docs/manual/plugins/rigor-rspec.md +2 -1
  13. data/lib/rigor/analysis/buffer_binding.rb +14 -0
  14. data/lib/rigor/analysis/check_rules/inferred_param_guard.rb +30 -9
  15. data/lib/rigor/analysis/check_rules/ivar_write_collector.rb +142 -15
  16. data/lib/rigor/analysis/check_rules/lexical_method_sites.rb +4 -0
  17. data/lib/rigor/analysis/check_rules/rbs_receiver_surface.rb +66 -3
  18. data/lib/rigor/analysis/check_rules/rebinding_block_callees/dispatch.rb +112 -0
  19. data/lib/rigor/analysis/check_rules/rebinding_block_callees.rb +394 -0
  20. data/lib/rigor/analysis/check_rules/ruby_deprecations.rb +7 -0
  21. data/lib/rigor/analysis/check_rules/unreachable_clause_collector.rb +51 -0
  22. data/lib/rigor/analysis/check_rules.rb +93 -8
  23. data/lib/rigor/analysis/dependency_recorder.rb +11 -0
  24. data/lib/rigor/analysis/edit_replay.rb +67 -0
  25. data/lib/rigor/analysis/incremental.rb +37 -0
  26. data/lib/rigor/analysis/incremental_session.rb +175 -27
  27. data/lib/rigor/analysis/path_expansion.rb +41 -0
  28. data/lib/rigor/analysis/require_relative_closure.rb +100 -0
  29. data/lib/rigor/analysis/rule_catalog.rb +5 -1
  30. data/lib/rigor/analysis/run_disclosure_credit.rb +80 -0
  31. data/lib/rigor/analysis/run_disclosure_ledger.rb +155 -0
  32. data/lib/rigor/analysis/runner/buffer_pool_dispatcher.rb +6 -2
  33. data/lib/rigor/analysis/runner/diagnostic_aggregator.rb +11 -3
  34. data/lib/rigor/analysis/runner/pool_coordinator.rb +17 -4
  35. data/lib/rigor/analysis/runner/project_pre_passes.rb +45 -3
  36. data/lib/rigor/analysis/runner/scan_environment.rb +51 -0
  37. data/lib/rigor/analysis/runner.rb +156 -49
  38. data/lib/rigor/analysis/worker_session.rb +14 -2
  39. data/lib/rigor/cache/incremental_snapshot.rb +30 -7
  40. data/lib/rigor/cli/check_command.rb +93 -4
  41. data/lib/rigor/cli/diff_command.rb +2 -1
  42. data/lib/rigor/cli/lens_command.rb +5 -5
  43. data/lib/rigor/cli/mcp_command.rb +2 -1
  44. data/lib/rigor/cli/options.rb +20 -3
  45. data/lib/rigor/cli/plugins_command.rb +5 -0
  46. data/lib/rigor/cli/plugins_renderer.rb +24 -2
  47. data/lib/rigor/cli/show_bleedingedge_command.rb +2 -1
  48. data/lib/rigor/cli/sig_gen_command.rb +46 -7
  49. data/lib/rigor/cli/type_of_command.rb +2 -1
  50. data/lib/rigor/cli/type_of_project_scope.rb +27 -0
  51. data/lib/rigor/config_audit.rb +16 -5
  52. data/lib/rigor/configuration.rb +14 -4
  53. data/lib/rigor/environment/rbs_loader.rb +115 -6
  54. data/lib/rigor/environment/required_features.rb +136 -29
  55. data/lib/rigor/environment/ruby_library_roots.rb +122 -0
  56. data/lib/rigor/environment.rb +4 -2
  57. data/lib/rigor/inference/callee_mutation_chain.rb +115 -0
  58. data/lib/rigor/inference/deep_erasure.rb +138 -0
  59. data/lib/rigor/inference/def_return_typer.rb +159 -9
  60. data/lib/rigor/inference/definer_resolution.rb +17 -3
  61. data/lib/rigor/inference/error_info.rb +17 -3
  62. data/lib/rigor/inference/expression_typer.rb +62 -13
  63. data/lib/rigor/inference/global_write_census.rb +36 -1
  64. data/lib/rigor/inference/ivar_writer_census.rb +195 -0
  65. data/lib/rigor/inference/loop_value_record.rb +53 -0
  66. data/lib/rigor/inference/match_rebinding/frame.rb +19 -0
  67. data/lib/rigor/inference/method_dispatcher/constant_folding.rb +110 -9
  68. data/lib/rigor/inference/method_dispatcher/kernel_dispatch.rb +6 -2
  69. data/lib/rigor/inference/method_dispatcher/set_folding.rb +53 -20
  70. data/lib/rigor/inference/method_dispatcher.rb +46 -16
  71. data/lib/rigor/inference/module_function_state/spellings.rb +64 -0
  72. data/lib/rigor/inference/module_function_state.rb +12 -0
  73. data/lib/rigor/inference/mutation_widening.rb +5 -2
  74. data/lib/rigor/inference/narrowing.rb +66 -5
  75. data/lib/rigor/inference/object_mixins.rb +13 -1
  76. data/lib/rigor/inference/project_seed_tables.rb +2 -1
  77. data/lib/rigor/inference/project_yielder.rb +128 -0
  78. data/lib/rigor/inference/scope_indexer/certainty.rb +9 -0
  79. data/lib/rigor/inference/scope_indexer/declared_ivar_types.rb +64 -0
  80. data/lib/rigor/inference/scope_indexer/declared_param_writes.rb +162 -0
  81. data/lib/rigor/inference/scope_indexer/unseen_ivar_writers.rb +133 -0
  82. data/lib/rigor/inference/scope_indexer.rb +480 -103
  83. data/lib/rigor/inference/self_call_ivar_writes.rb +18 -6
  84. data/lib/rigor/inference/statement_evaluator.rb +658 -90
  85. data/lib/rigor/inference/synthetic_method_index.rb +23 -0
  86. data/lib/rigor/inference/synthetic_method_scanner/project_members.rb +130 -0
  87. data/lib/rigor/inference/synthetic_method_scanner.rb +72 -12
  88. data/lib/rigor/language_server/buffer_table.rb +6 -0
  89. data/lib/rigor/language_server/diagnostic_publisher.rb +20 -6
  90. data/lib/rigor/language_server/project_context.rb +59 -3
  91. data/lib/rigor/language_server/server.rb +5 -3
  92. data/lib/rigor/mcp/server.rb +9 -1
  93. data/lib/rigor/plugin/base.rb +26 -11
  94. data/lib/rigor/plugin/manifest.rb +29 -3
  95. data/lib/rigor/plugin/registry.rb +38 -0
  96. data/lib/rigor/protection/discovery_seed.rb +57 -2
  97. data/lib/rigor/rooted_glob.rb +10 -1
  98. data/lib/rigor/scope.rb +14 -5
  99. data/lib/rigor/sig_gen/generator.rb +308 -37
  100. data/lib/rigor/sig_gen/observation_collector.rb +4 -1
  101. data/lib/rigor/sig_gen/rbs_validity.rb +1 -1
  102. data/lib/rigor/sig_gen/renderer.rb +6 -3
  103. data/lib/rigor/sig_gen/type_elaborator.rb +21 -5
  104. data/lib/rigor/type/combinator.rb +4 -3
  105. data/lib/rigor/type/constant.rb +45 -3
  106. data/lib/rigor/type/hash_shape.rb +14 -9
  107. data/lib/rigor/type/struct_instance.rb +3 -2
  108. data/lib/rigor/version.rb +1 -1
  109. data/plugins/rigor-actionmailer/lib/rigor/plugin/actionmailer/mailer_discoverer.rb +60 -43
  110. data/plugins/rigor-actionmailer/lib/rigor/plugin/actionmailer.rb +20 -1
  111. data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack.rb +13 -0
  112. data/plugins/rigor-activejob/lib/rigor/plugin/activejob.rb +4 -2
  113. data/plugins/rigor-devise/lib/rigor/plugin/devise.rb +5 -3
  114. data/plugins/rigor-dry-types/lib/rigor/plugin/dry_types.rb +6 -5
  115. data/plugins/rigor-rspec/lib/rigor/plugin/rspec/matcher_analyzer.rb +102 -11
  116. data/plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq.rb +4 -2
  117. data/plugins/rigor-typelizer/lib/rigor/plugin/typelizer.rb +1 -1
  118. data/sig/rigor/analysis/baseline.rbs +3 -2
  119. data/sig/rigor/effects/file_collection.rbs +5 -6
  120. data/sig/rigor/effects/registry.rbs +8 -6
  121. data/sig/rigor/effects/summary.rbs +6 -5
  122. data/sig/rigor/environment.rbs +5 -3
  123. data/sig/rigor/inference/optimistic_origin.rbs +11 -0
  124. data/sig/rigor/inference.rbs +6 -0
  125. data/sig/rigor/plugin/additional_initializer.rbs +5 -5
  126. data/sig/rigor/plugin/effect_ancestry.rbs +6 -4
  127. data/sig/rigor/plugin/effect_attribution.rbs +25 -10
  128. data/sig/rigor/plugin/effect_edge.rbs +12 -5
  129. data/sig/rigor/plugin/effect_entry_points.rbs +8 -3
  130. data/sig/rigor/plugin/io_boundary.rbs +4 -4
  131. data/sig/rigor/plugin/manifest.rbs +16 -18
  132. data/sig/rigor/plugin/protocol_contract.rbs +10 -9
  133. data/sig/rigor/plugin/registry.rbs +1 -1
  134. data/sig/rigor/scope.rbs +31 -50
  135. data/sig/rigor/type.rbs +0 -6
  136. metadata +20 -1
data/sig/rigor/scope.rbs CHANGED
@@ -14,39 +14,32 @@ module Rigor
14
14
  attr_reader void_origins: Hash[untyped, Inference::VoidOrigin]
15
15
  attr_reader plugin_typed_calls: Hash[untyped, bool]
16
16
  attr_reader optimistic_origins: Hash[untyped, Symbol]
17
- # A marked binding whose miss answer is known stores an `Inference::OptimisticOrigin::BoundMark` (a `Data`)
18
- # in place of its bare cause (issue #1302).
19
- attr_reader optimistic_locals: Hash[Symbol, Symbol | Data]
20
- attr_reader optimistic_ivars: Hash[Symbol, Symbol | Data]
21
- # sig-gen gap: #1154 — an `attr_reader` over an ivar assigned in `initialize` from a parameter reaches `untyped`.
17
+ # A marked binding whose miss answer is known stores an `Inference::OptimisticOrigin::BoundMark` in place of
18
+ # its bare cause (issue #1302).
19
+ attr_reader optimistic_locals: Hash[Symbol, Symbol | Inference::OptimisticOrigin::BoundMark]
20
+ attr_reader optimistic_ivars: Hash[Symbol, Symbol | Inference::OptimisticOrigin::BoundMark]
22
21
  attr_reader repeated_or_writes: Hash[untyped, bool]
23
- # sig-gen gap: #1154 — the same reader shape; `Inference::MatchRebinding::Frame` carries no signature.
22
+ # sig-gen gap: #2323 — the same reader shape; `Inference::MatchRebinding::Frame` carries no signature.
24
23
  attr_reader match_frame: untyped
25
24
  attr_reader indexed_narrowings: Hash[IndexedKey, Type::t]
26
25
  attr_reader method_chain_narrowings: Hash[ChainKey, Type::t]
27
26
  attr_reader source_path: String?
27
+ # authored: the element is a `Symbol` by contract; a Set's element type stays `untyped` in sig-gen (#2177, #2317), so the generator
28
+ # would never propose it.
28
29
  attr_reader struct_fold_safe_locals: Set[Symbol]
29
30
  attr_reader opaque_block_self: bool
30
- # sig-gen gap: #1154 — sig-gen skips the reader (sig.skipped.untyped-return): an `attr_reader`
31
- # over an ivar assigned in `initialize` from a parameter, so inference reaches `untyped`.
32
31
  # Issue #1759 — `:refinement` (REFINEMENT_BLOCK_SELF) directly in a `refine X do … end` block body.
33
32
  attr_reader block_self_unknown: bool | :refinement
34
- # sig-gen gap: #1154 — sig-gen skips the reader (sig.skipped.untyped-return): an `attr_reader`
35
- # over an ivar assigned in `initialize` from a parameter, so inference reaches `untyped`.
36
33
  attr_reader singleton_class_body: bool
37
34
  attr_reader lexical_nesting: Array[String]?
38
35
  # Issue #1429 — a guard's narrowing of a constant reference, keyed by its spelling.
39
- # sig-gen gap: #1154 — a reader over an ivar `initialize` assigns from a parameter.
40
36
  attr_reader constant_narrowings: Hash[String, Type::t]
41
37
  # Issue #1429 — the pre-guard type of each global or constant a guard narrowed.
42
- # sig-gen gap: #1154 — a reader over an ivar `initialize` assigns from a parameter.
43
38
  attr_reader guard_records: Hash[[Symbol, Symbol | String], Type::t]
44
39
  # Issue #1446 — the classes a class guard narrowed a `bot` receiver to.
45
- # sig-gen gap: #1154 — a reader over an ivar `initialize` assigns from a parameter.
46
40
  attr_reader bot_guard_classes: Hash[[Symbol, Symbol | String], Array[String]]
47
41
  # Issue #1667 — the modules a plugin-declared refined block runs under, in declaration order.
48
- # sig-gen gap: #1154 — a reader over an ivar `initialize` assigns from a parameter.
49
- attr_reader declared_refinements: Array[String]
42
+ attr_reader declared_refinements: Array[String | Symbol]
50
43
 
51
44
  # ADR-53 Track A — the seed-time discovery tables live on the
52
45
  # DiscoveryIndex; Scope keeps per-table readers as delegates.
@@ -62,27 +55,19 @@ module Rigor
62
55
  def discovered_def_sources: () -> Hash[String, Hash[Symbol, String]]
63
56
  def discovered_singleton_def_sources: () -> Hash[String, Hash[Symbol, String]]
64
57
  def discovered_method_visibilities: () -> Hash[String, Hash[Symbol | [:singleton, Symbol], Symbol]]
65
- # sig-gen gap: #1148 — sig-gen skips an endless-def reader (untyped return); the row is hand-written.
66
58
  def discovered_parameter_envelopes: () -> Hash[String, Hash[untyped, untyped]]
67
- # sig-gen gap: #1149 — sig-gen skips the `||` fallback reader (untyped return); the row is hand-written.
68
59
  def parameter_envelopes_of: (String class_name) -> Hash[untyped, untyped]
69
60
  def discovered_superclasses: () -> Hash[String, String]
70
- # sig-gen gap: #1148 — sig-gen skips the endless-def reader (untyped return), so the per-file
71
- # deferred-range table's row shape is hand-written.
72
61
  def discovered_deferred_ranges: () -> Hash[String, Array[[Integer, Integer, Symbol?, Symbol?, String?]]]
73
- # sig-gen gap: #1148 — sig-gen skips the endless-def reader (untyped return), so the refinement table's
74
- # shape is hand-written. A method key is a Symbol or the `"*"` wildcard (ADR-121 WD7).
62
+ # A method key is a Symbol or the `"*"` wildcard (ADR-121 WD7).
75
63
  def discovered_refinements: () -> Hash[String, Hash[Symbol | String, Array[String]]]
76
64
  # authored: the list holds module names and the `InEffectRefinements::UNKNOWN` Symbol; sig-gen reads the delegated
77
65
  # return through an unsigned class as untyped.
78
66
  def in_effect_refinements: (untyped node, ?Array[String] declared) -> Array[String | Symbol]
79
- # sig-gen gap: #1148 — sig-gen skips the endless-def reader (untyped return), so the census shape is
80
- # hand-written.
81
67
  def discovered_global_write_census: () -> Set[Array[untyped]]
82
68
  def discovered_includes: () -> Hash[String, Array[String]]
83
69
  # Issue #1123 — the instance-ancestor-ORDER table beside the include one.
84
70
  def discovered_prepends: () -> Hash[String, Array[String]]
85
- # sig-gen gap: #1148 — sig-gen skips the endless-def reader (untyped return), so the table shape is hand-written.
86
71
  def discovered_extends: () -> Hash[String, Array[String]]
87
72
  def discovered_class_sources: () -> Hash[String, Set[String]]
88
73
  def constant_sources: () -> Hash[String, Set[String]]
@@ -92,7 +77,8 @@ module Rigor
92
77
  def bound_constant_names: (String name) -> Array[String]
93
78
  # sig-gen gap: #1150 — the `Data.define` table it reads carries no type, so sig-gen skips the return; the shape is hand-written.
94
79
  def shadowing_constant_names: (String name) -> Array[String]
95
- # sig-gen gap: #1149 — sig-gen types the `||` fallback `untyped`, so the element type is hand-written.
80
+ # sig-gen gap: #2309 — the `|| Set.new.freeze` fallback arm types `Set[untyped]` beside the table's `Set[Symbol]`, so the
81
+ # element type is hand-written.
96
82
  def published_constant_ivars_for: (String class_name) -> Set[Symbol]
97
83
  def published_constant?: (String name) -> bool
98
84
  def record_constant_dependency: (String name) -> void
@@ -110,10 +96,14 @@ module Rigor
110
96
  def plugin_typed_call?: (untyped node) -> bool
111
97
 
112
98
  def with_repeated_or_writes: (untyped nodes) -> Rigor::Scope
113
- # sig-gen gap: #1154 — `Hash#key?` over that reader reaches `untyped`, so the `bool` is hand-written.
114
99
  def repeated_or_write?: (untyped node) -> bool
115
100
 
116
101
  class DiscoveryIndex
102
+ # #1557 — the def-nesting table is a Hash, or an `Inference::ScopeIndexer::LayeredDefNestings` that answers only
103
+ # `[]` and `empty?`, so that `each` or `key?` over one layer raises instead of reading half the table. A union
104
+ # rather than an interface: the engine reads an RBS interface as `untyped`, which would check nothing.
105
+ type def_nestings = Hash[untyped, Array[String]] | Inference::ScopeIndexer::LayeredDefNestings
106
+
117
107
  attr_reader declared_types: Hash[untyped, Type::t]
118
108
  attr_reader class_ivars: Hash[String, Hash[Symbol, Type::t]]
119
109
  attr_reader class_cvars: Hash[String, Hash[Symbol, Type::t]]
@@ -124,7 +114,7 @@ module Rigor
124
114
  attr_reader in_source_constants: Hash[String, Type::t]
125
115
  attr_reader discovered_methods: Hash[String, Hash[Symbol, Symbol]]
126
116
  attr_reader discovered_def_nodes: Hash[String, Hash[Symbol, untyped]]
127
- attr_reader discovered_def_nestings: Hash[untyped, Array[String]]
117
+ attr_reader discovered_def_nestings: def_nestings
128
118
  attr_reader discovered_singleton_def_nodes: Hash[String, Hash[Symbol, untyped]]
129
119
  attr_reader discovered_def_sources: Hash[String, Hash[Symbol, String]]
130
120
  attr_reader discovered_singleton_def_sources: Hash[String, Hash[Symbol, String]]
@@ -201,7 +191,7 @@ module Rigor
201
191
  # authored: ADR-119 WD1 sibling pairing; no inferred signature exists for it (#1150).
202
192
  def sibling_tables: () -> Hash[Symbol, untyped]
203
193
 
204
- 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], ?program_global_seeds: 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_nestings: Hash[untyped, Array[String]], ?discovered_singleton_def_nodes: Hash[String, Hash[Symbol, untyped]], ?discovered_def_sources: Hash[String, Hash[Symbol, String]], ?discovered_singleton_def_sources: Hash[String, Hash[Symbol, String]], ?discovered_method_visibilities: Hash[String, Hash[Symbol | [:singleton, Symbol], Symbol]], ?discovered_parameter_envelopes: Hash[String, Hash[untyped, untyped]], ?discovered_superclasses: Hash[String, String], ?discovered_includes: Hash[String, Array[String]], ?discovered_prepends: Hash[String, Array[String]], ?discovered_extends: Hash[String, Array[String]], ?discovered_class_sources: Hash[String, Set[String]], ?constant_sources: Hash[String, Set[String]], ?constant_writers: Hash[String, Array[String]], ?constant_shadowers: Hash[String, Array[String]], ?published_constant_names: Set[String], ?local_constant_names: Set[String], ?published_constant_alias_names: Set[String], ?published_constant_ivars: Hash[String, Set[Symbol]], ?data_member_layouts: Hash[String, Array[Symbol]], ?struct_member_layouts: Hash[String, { members: Array[Symbol], keyword_init: bool }], ?param_inferred_types: Hash[[String, Symbol, Symbol], Hash[Symbol, Type::t]], ?discovered_deferred_ranges: Hash[String, Array[[Integer, Integer, Symbol?, Symbol?, String?]]], ?discovered_refinements: Hash[String, Hash[Symbol | String, Array[String]]], ?discovered_global_write_census: Set[Array[untyped]], ?run_generation: Object?, ?patched_line_readers: Set[Symbol], ?clears_last_status: bool, ?defines_case_equality: bool, ?implicit_self_evidence: untyped, ?in_effect_refinements: untyped, ?possible_discovered_methods: Hash[String, Hash[Symbol, Symbol]], ?possible_discovered_deferred_ranges: Hash[String, Array[[Integer, Integer, Symbol?, Symbol?, String?]]], ?contested_discovered_def_nodes: Set[Array[untyped]], ?contested_discovered_singleton_def_nodes: Set[Array[untyped]], ?contested_discovered_method_visibilities: Set[Array[untyped]], ?contested_discovered_parameter_envelopes: Set[Array[untyped]]) -> DiscoveryIndex
194
+ 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], ?program_global_seeds: 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_nestings: def_nestings, ?discovered_singleton_def_nodes: Hash[String, Hash[Symbol, untyped]], ?discovered_def_sources: Hash[String, Hash[Symbol, String]], ?discovered_singleton_def_sources: Hash[String, Hash[Symbol, String]], ?discovered_method_visibilities: Hash[String, Hash[Symbol | [:singleton, Symbol], Symbol]], ?discovered_parameter_envelopes: Hash[String, Hash[untyped, untyped]], ?discovered_superclasses: Hash[String, String], ?discovered_includes: Hash[String, Array[String]], ?discovered_prepends: Hash[String, Array[String]], ?discovered_extends: Hash[String, Array[String]], ?discovered_class_sources: Hash[String, Set[String]], ?constant_sources: Hash[String, Set[String]], ?constant_writers: Hash[String, Array[String]], ?constant_shadowers: Hash[String, Array[String]], ?published_constant_names: Set[String], ?local_constant_names: Set[String], ?published_constant_alias_names: Set[String], ?published_constant_ivars: Hash[String, Set[Symbol]], ?data_member_layouts: Hash[String, Array[Symbol]], ?struct_member_layouts: Hash[String, { members: Array[Symbol], keyword_init: bool }], ?param_inferred_types: Hash[[String, Symbol, Symbol], Hash[Symbol, Type::t]], ?discovered_deferred_ranges: Hash[String, Array[[Integer, Integer, Symbol?, Symbol?, String?]]], ?discovered_refinements: Hash[String, Hash[Symbol | String, Array[String]]], ?discovered_global_write_census: Set[Array[untyped]], ?run_generation: Object?, ?patched_line_readers: Set[Symbol], ?clears_last_status: bool, ?defines_case_equality: bool, ?implicit_self_evidence: untyped, ?in_effect_refinements: untyped, ?possible_discovered_methods: Hash[String, Hash[Symbol, Symbol]], ?possible_discovered_deferred_ranges: Hash[String, Array[[Integer, Integer, Symbol?, Symbol?, String?]]], ?contested_discovered_def_nodes: Set[Array[untyped]], ?contested_discovered_singleton_def_nodes: Set[Array[untyped]], ?contested_discovered_method_visibilities: Set[Array[untyped]], ?contested_discovered_parameter_envelopes: Set[Array[untyped]]) -> DiscoveryIndex
205
195
  end
206
196
 
207
197
  class IndexedKey
@@ -218,22 +208,19 @@ module Rigor
218
208
 
219
209
  def self.empty: (?environment: Environment, ?source_path: String?) -> Scope
220
210
 
221
- 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?, ?dynamic_origins: Hash[untyped, Symbol]) -> void
211
+ 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?, ?opaque_block_self: bool, ?block_self_unknown: bool | :refinement, ?singleton_class_body: bool, ?dynamic_origins: Hash[untyped, Symbol], ?indexed_narrowings: Hash[IndexedKey, Type::t], ?method_chain_narrowings: Hash[ChainKey, Type::t], ?declaration_sourced: Set[[Symbol, Symbol] | [Symbol, Symbol, Symbol]], ?published_constant_sourced: Set[[Symbol, Symbol]], ?struct_fold_safe_locals: Set[Symbol], ?lexical_nesting: Array[String]?, ?local_origins: Hash[Symbol, Symbol], ?ivar_origins: Hash[Symbol, Symbol], ?void_origins: Hash[untyped, Inference::VoidOrigin], ?plugin_typed_calls: Hash[untyped, bool], ?optimistic_origins: Hash[untyped, Symbol], ?optimistic_locals: Hash[Symbol, Symbol | Inference::OptimisticOrigin::BoundMark], ?optimistic_ivars: Hash[Symbol, Symbol | Inference::OptimisticOrigin::BoundMark], ?repeated_or_writes: Hash[untyped, bool], ?match_frame: untyped, ?constant_narrowings: Hash[String, Type::t], ?guard_records: Hash[[Symbol, Symbol | String], Type::t], ?bot_guard_classes: Hash[[Symbol, Symbol | String], Array[String]], ?declared_refinements: Array[String | Symbol]) -> void
222
212
  def with_source_path: (String? path) -> Scope
223
213
  def with_struct_fold_safe: (Set[Symbol] locals) -> Scope
224
214
  def with_lexical_nesting: (Array[String]? chain) -> Scope
225
215
  def struct_fold_safe?: (String | Symbol name) -> bool
226
216
  def entering_opaque_block: () -> Scope
227
- # sig-gen gap: #1148 — sig-gen skips the endless-def reader (sig.skipped.untyped-return); the row is hand-written.
228
217
  def block_self_unknown?: () -> bool
229
218
  REFINEMENT_BLOCK_SELF: :refinement
230
- # sig-gen gap: #1148 — sig-gen skips the endless-def predicate (sig.skipped.untyped-return); the row is hand-written.
231
219
  def refinement_block_self?: () -> bool
232
220
  def with_block_self_unknown: (bool flag) -> Scope
233
221
  def opaque_block_self?: () -> bool
234
222
  def with_singleton_class_body: (bool) -> Scope
235
223
  def with_declared_refinements: (Array[String] names) -> Scope
236
- # sig-gen gap: #1148 — sig-gen skips the endless-def reader (sig.skipped.untyped-return); the row is hand-written.
237
224
  def singleton_class_body?: () -> bool
238
225
  def with_discovery: (DiscoveryIndex index) -> Scope
239
226
  def local: (String | Symbol name) -> Type::t?
@@ -261,33 +248,31 @@ module Rigor
261
248
  # Issue #1446 — `rigor sig-gen` output.
262
249
  def with_guarded_ivar: (untyped name, untyped type, untyped pre_guard) -> Scope
263
250
  def without_ivar_guard: (untyped name) -> Scope
264
- # sig-gen gap: #1154 — the table reader over an ivar `initialize` assigns from a parameter reaches `untyped`.
265
251
  def guard_narrowed_ivar?: (untyped name) -> bool
266
252
  # Issue #1446 — `rigor sig-gen` output.
267
253
  def with_bot_guard_classes: (untyped kind, untyped name, untyped class_names) -> Scope
268
- # sig-gen gap: #1154 — the table reader over an ivar `initialize` assigns from a parameter reaches `untyped`.
269
254
  def bot_guard_classes_for: (untyped kind, untyped name) -> Array[String]?
270
255
  def without_constant_narrowing: (untyped key) -> Scope
271
256
  def guard_narrowed?: () -> bool
272
257
  def forget_guard_narrowings: () -> Scope
273
258
  def forget_guard_narrowing_of: (untyped kind, untyped name) -> Scope
274
259
  def without_constant_narrowings_named: (untyped name) -> Scope
275
- # sig-gen gap: #1154 — the table reader over an ivar `initialize` assigns from a parameter reaches `untyped`.
276
260
  def constant_narrowing: (String key) -> Type::t?
277
- # sig-gen gap: #1151 — an `attr_reader` over a frozen Set literal types `untyped`, as the sibling
278
- # `declaration_sourced` row does.
261
+ # authored: the element is `[Symbol, Symbol]` by contract; a Set's element type stays `untyped` in sig-gen (#2177, #2317), so the generator
262
+ # would never propose it.
279
263
  def published_constant_sourced: () -> Set[[Symbol, Symbol]]
280
- # sig-gen gap: #1152 — `Set#include?` over a tuple key types `untyped`, so the `bool` is hand-written.
281
264
  def published_constant_sourced?: (Symbol kind, String | Symbol name) -> bool
282
265
  def with_published_constant_mark: (Symbol kind, String | Symbol name) -> Scope
283
266
  # Issue #1362 — a `[:global_copy, local, global]` record rides beside the `(kind, name)` refs.
267
+ # authored: the element is a `[Symbol, Symbol]` or `[Symbol, Symbol, Symbol]` tuple by contract; a Set's element type stays `untyped` in sig-gen (#2177, #2317), so the generator
268
+ # would never propose it.
284
269
  def declaration_sourced: () -> Set[[Symbol, Symbol] | [Symbol, Symbol, Symbol]]
285
270
  def seed_declaration_sourced_ivar: (String | Symbol name, Type::t type) -> Scope
286
271
  def seed_declaration_sourced_global: (String | Symbol name, Type::t type) -> Scope
287
272
  def with_global_copy_marks: (String | Symbol name, Array[String | Symbol] globals) -> Scope
288
273
  def without_local_declaration_marks: (String | Symbol name) -> Scope
289
- # sig-gen gap: #1154 — the records come out of `@declaration_sourced`, an ivar assigned in `initialize` from a
290
- # parameter, which reaches `untyped`.
274
+ # sig-gen gap: #2322 — the records come out of `@declaration_sourced`, whose set now types; `ref[2]` reads as
275
+ # `Symbol?`, but the `filter_map` over it answers `Array[untyped]`.
291
276
  def declaration_sourced_global_copies: (String | Symbol name) -> Array[Symbol]
292
277
  def with_declaration_sourced_local: (String | Symbol name, Type::t type) -> Scope
293
278
  def with_local_declaration_mark: (String | Symbol name) -> Scope
@@ -300,19 +285,15 @@ module Rigor
300
285
  def inferred_param?: (String | Symbol name) -> bool
301
286
  def forget_match_globals: () -> Scope
302
287
  def untyped_match_globals: () -> Scope
303
- # sig-gen gap: #1154 — the reader over the `@globals` ivar `initialize` assigns from a parameter reaches
304
- # `untyped`, so the `bool` is hand-written.
305
288
  def match_globals_bound?: () -> bool
306
289
  def with_match_frame: (untyped body, ?untyped parameters) -> Scope
307
- # sig-gen gap: #1154 — the frame reader over an ivar assigned in `initialize` from a parameter reaches
290
+ # sig-gen gap: #2323 — the frame reader over an ivar assigned in `initialize` from a parameter reaches
308
291
  # `untyped`, so the `bool` is hand-written.
309
292
  def match_rebinding_closure?: () -> bool
310
293
  def forget_last_line: () -> Scope
311
294
  def untyped_last_line: () -> Scope
312
- # sig-gen gap: #1154 — the reader over the `@globals` ivar `initialize` assigns from a parameter reaches
313
- # `untyped`, so the `bool` is hand-written.
314
295
  def last_line_bound?: () -> bool
315
- # sig-gen gap: #1154 — the frame reader over the `@match_frame` ivar `initialize` assigns from a parameter
296
+ # sig-gen gap: #2323 — the frame reader over the `@match_frame` ivar `initialize` assigns from a parameter
316
297
  # reaches `untyped`, so the `bool` is hand-written.
317
298
  def last_line_closure?: () -> bool
318
299
  def forget_error_info: () -> Scope
@@ -331,8 +312,8 @@ module Rigor
331
312
  def enqueue_ancestors: (String current, Array[String] queue, Hash[untyped, untyped] name_memo, ?mixins: bool) -> void
332
313
  def ancestor_name_candidates: (String | Symbol subclass_qualified, String | Symbol raw_ancestor) -> Array[String]
333
314
 
334
- # sig-gen gap: #1148 — sig-gen skips the method (sig.skipped.untyped-return: every decline returns the
335
- # frozen EMPTY_HEADER_NESTING constant); the row is hand-written.
315
+ # sig-gen gap: #2312 — sig-gen skips the method (sig.skipped.untyped-return): its non-decline arm is the result of
316
+ # the private helper `ambiguous_ancestor_resolutions_of`, whose parameters are untyped, so the arm is `untyped`.
336
317
  def ambiguous_ancestor_resolutions: (String | Symbol subclass_qualified, String | Symbol raw_ancestor) -> Array[String]
337
318
 
338
319
  # Issue #530 — public so the external-gem ancestry probe asks the same question the walk does.
@@ -356,8 +337,8 @@ module Rigor
356
337
  def data_member_layout: (String | Symbol class_name) -> Array[Symbol]?
357
338
  def struct_member_layout: (String | Symbol class_name) -> { members: Array[Symbol], keyword_init: bool }?
358
339
  def includes_of: (String | Symbol class_name) -> Array[String]
359
- # sig-gen gap: #1153 — sig-gen proposes `Array[untyped] | []` off the empty-table early return, so the
360
- # element type is hand-written, matching {#includes_of}.
340
+ # sig-gen gap: #2302 — `names = []` grown by `concat` reads `Array[untyped]`, so the element type is
341
+ # hand-written, matching {#includes_of}.
361
342
  def singleton_extends_of: (String | Symbol class_name) -> Array[String]
362
343
  def indexed_narrowing: (Symbol receiver_kind, String | Symbol receiver_name, untyped key) -> Type::t?
363
344
  def with_indexed_narrowing: (Symbol receiver_kind, String | Symbol receiver_name, untyped key, Type::t type) -> Scope
data/sig/rigor/type.rbs CHANGED
@@ -429,14 +429,8 @@ module Rigor
429
429
  attr_reader trinary: Trinary
430
430
  attr_reader mode: accepts_mode
431
431
  attr_reader reasons: Array[String]
432
- # sig-gen gap: #1155 — the memoized `||=` return is an honest union with an
433
- # untyped arm (the slot read cannot prove the memoized value), so sig-gen
434
- # skips it (sig.skipped.untyped-return); the runtime result is always
435
- # AcceptsResult and the row is hand-written.
436
432
  def self.yes: (?mode: accepts_mode, ?reasons: (Array[String] | String)?) -> AcceptsResult
437
- # sig-gen gap: #1155 — same memoized `||=` untyped-return gap as `self.yes`.
438
433
  def self.no: (?mode: accepts_mode, ?reasons: (Array[String] | String)?) -> AcceptsResult
439
- # sig-gen gap: #1155 — same memoized `||=` untyped-return gap as `self.yes`.
440
434
  def self.maybe: (?mode: accepts_mode, ?reasons: (Array[String] | String)?) -> AcceptsResult
441
435
  def initialize: (Trinary trinary, ?mode: accepts_mode, ?reasons: (Array[String] | String)?) -> void
442
436
  def yes?: () -> bool
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rigortype
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.5
4
+ version: 0.4.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rigor contributors
@@ -457,6 +457,8 @@ files:
457
457
  - lib/rigor/analysis/check_rules/main_pass_collector.rb
458
458
  - lib/rigor/analysis/check_rules/published_constant_guard.rb
459
459
  - lib/rigor/analysis/check_rules/rbs_receiver_surface.rb
460
+ - lib/rigor/analysis/check_rules/rebinding_block_callees.rb
461
+ - lib/rigor/analysis/check_rules/rebinding_block_callees/dispatch.rb
460
462
  - lib/rigor/analysis/check_rules/return_in_ensure_collector.rb
461
463
  - lib/rigor/analysis/check_rules/ruby_deprecations.rb
462
464
  - lib/rigor/analysis/check_rules/rule_ids.rb
@@ -477,6 +479,7 @@ files:
477
479
  - lib/rigor/analysis/dependency_source_inference/return_type_heuristic.rb
478
480
  - lib/rigor/analysis/dependency_source_inference/walker.rb
479
481
  - lib/rigor/analysis/diagnostic.rb
482
+ - lib/rigor/analysis/edit_replay.rb
480
483
  - lib/rigor/analysis/effects_cache_probe.rb
481
484
  - lib/rigor/analysis/erb_template_detector.rb
482
485
  - lib/rigor/analysis/fact_store.rb
@@ -493,10 +496,13 @@ files:
493
496
  - lib/rigor/analysis/reachability/scan.rb
494
497
  - lib/rigor/analysis/reachability/scan_cache.rb
495
498
  - lib/rigor/analysis/reachability/signature_scan.rb
499
+ - lib/rigor/analysis/require_relative_closure.rb
496
500
  - lib/rigor/analysis/result.rb
497
501
  - lib/rigor/analysis/rule_catalog.rb
498
502
  - lib/rigor/analysis/run_cache_key.rb
499
503
  - lib/rigor/analysis/run_cache_probe.rb
504
+ - lib/rigor/analysis/run_disclosure_credit.rb
505
+ - lib/rigor/analysis/run_disclosure_ledger.rb
500
506
  - lib/rigor/analysis/run_stats.rb
501
507
  - lib/rigor/analysis/runner.rb
502
508
  - lib/rigor/analysis/runner/buffer_pool_dispatcher.rb
@@ -508,6 +514,7 @@ files:
508
514
  - lib/rigor/analysis/runner/pool_coordinator.rb
509
515
  - lib/rigor/analysis/runner/project_pre_passes.rb
510
516
  - lib/rigor/analysis/runner/run_snapshots.rb
517
+ - lib/rigor/analysis/runner/scan_environment.rb
511
518
  - lib/rigor/analysis/self_call_resolution_recorder.rb
512
519
  - lib/rigor/analysis/severity_stamp.rb
513
520
  - lib/rigor/analysis/shadow_harness.rb
@@ -593,6 +600,7 @@ files:
593
600
  - lib/rigor/cli/triage_command.rb
594
601
  - lib/rigor/cli/triage_renderer.rb
595
602
  - lib/rigor/cli/type_of_command.rb
603
+ - lib/rigor/cli/type_of_project_scope.rb
596
604
  - lib/rigor/cli/type_of_renderer.rb
597
605
  - lib/rigor/cli/type_of_template_probe.rb
598
606
  - lib/rigor/cli/type_scan_command.rb
@@ -669,6 +677,7 @@ files:
669
677
  - lib/rigor/environment/reflection.rb
670
678
  - lib/rigor/environment/reporters.rb
671
679
  - lib/rigor/environment/required_features.rb
680
+ - lib/rigor/environment/ruby_library_roots.rb
672
681
  - lib/rigor/environment/source_rbs_synthesis.rb
673
682
  - lib/rigor/flow_contribution.rb
674
683
  - lib/rigor/flow_contribution/conflict.rb
@@ -706,6 +715,7 @@ files:
706
715
  - lib/rigor/inference/builtins/string_catalog.rb
707
716
  - lib/rigor/inference/builtins/struct_catalog.rb
708
717
  - lib/rigor/inference/builtins/time_catalog.rb
718
+ - lib/rigor/inference/callee_mutation_chain.rb
709
719
  - lib/rigor/inference/captured_locals.rb
710
720
  - lib/rigor/inference/clause_widening.rb
711
721
  - lib/rigor/inference/closure_escape_analyzer.rb
@@ -716,6 +726,7 @@ files:
716
726
  - lib/rigor/inference/declaration_walk/errors.rb
717
727
  - lib/rigor/inference/declaration_walk/shadow.rb
718
728
  - lib/rigor/inference/declaration_walk/traversal.rb
729
+ - lib/rigor/inference/deep_erasure.rb
719
730
  - lib/rigor/inference/def_handle.rb
720
731
  - lib/rigor/inference/def_node_resolver.rb
721
732
  - lib/rigor/inference/def_return_typer.rb
@@ -747,6 +758,7 @@ files:
747
758
  - lib/rigor/inference/index_write_widening.rb
748
759
  - lib/rigor/inference/indexed_narrowing.rb
749
760
  - lib/rigor/inference/intervening_ivar_reset.rb
761
+ - lib/rigor/inference/ivar_writer_census.rb
750
762
  - lib/rigor/inference/jump_targets.rb
751
763
  - lib/rigor/inference/key_presence_guard.rb
752
764
  - lib/rigor/inference/key_presence_guard/scan.rb
@@ -754,6 +766,7 @@ files:
754
766
  - lib/rigor/inference/last_line/implicit_self.rb
755
767
  - lib/rigor/inference/last_line/self_evidence.rb
756
768
  - lib/rigor/inference/last_status.rb
769
+ - lib/rigor/inference/loop_value_record.rb
757
770
  - lib/rigor/inference/macro_block_self_type.rb
758
771
  - lib/rigor/inference/match_rebinding.rb
759
772
  - lib/rigor/inference/match_rebinding/calls.rb
@@ -808,6 +821,7 @@ files:
808
821
  - lib/rigor/inference/method_dispatcher/uri_folding.rb
809
822
  - lib/rigor/inference/method_parameter_binder.rb
810
823
  - lib/rigor/inference/module_function_state.rb
824
+ - lib/rigor/inference/module_function_state/spellings.rb
811
825
  - lib/rigor/inference/multi_target_binder.rb
812
826
  - lib/rigor/inference/mutation_rejoin.rb
813
827
  - lib/rigor/inference/mutation_widening.rb
@@ -827,6 +841,7 @@ files:
827
841
  - lib/rigor/inference/project_patched_scanner.rb
828
842
  - lib/rigor/inference/project_patched_visibility.rb
829
843
  - lib/rigor/inference/project_seed_tables.rb
844
+ - lib/rigor/inference/project_yielder.rb
830
845
  - lib/rigor/inference/protection_scanner.rb
831
846
  - lib/rigor/inference/range_constant.rb
832
847
  - lib/rigor/inference/rbs_type_translator.rb
@@ -846,11 +861,14 @@ files:
846
861
  - lib/rigor/inference/scope_indexer.rb
847
862
  - lib/rigor/inference/scope_indexer/certainty.rb
848
863
  - lib/rigor/inference/scope_indexer/class_cvars_collector.rb
864
+ - lib/rigor/inference/scope_indexer/declared_ivar_types.rb
865
+ - lib/rigor/inference/scope_indexer/declared_param_writes.rb
849
866
  - lib/rigor/inference/scope_indexer/def_nestings_collector.rb
850
867
  - lib/rigor/inference/scope_indexer/layered_def_nestings.rb
851
868
  - lib/rigor/inference/scope_indexer/member_layouts_collector.rb
852
869
  - lib/rigor/inference/scope_indexer/mixin_accumulator.rb
853
870
  - lib/rigor/inference/scope_indexer/superclasses_collector.rb
871
+ - lib/rigor/inference/scope_indexer/unseen_ivar_writers.rb
854
872
  - lib/rigor/inference/self_call_ivar_writes.rb
855
873
  - lib/rigor/inference/singleton_external_ahead.rb
856
874
  - lib/rigor/inference/singleton_hook_decline.rb
@@ -862,6 +880,7 @@ files:
862
880
  - lib/rigor/inference/synthetic_method.rb
863
881
  - lib/rigor/inference/synthetic_method_index.rb
864
882
  - lib/rigor/inference/synthetic_method_scanner.rb
883
+ - lib/rigor/inference/synthetic_method_scanner/project_members.rb
865
884
  - lib/rigor/inference/unknown_store_widening.rb
866
885
  - lib/rigor/inference/unthreaded_rebinds.rb
867
886
  - lib/rigor/inference/untyped_rejoin.rb