rigortype 0.3.0 → 0.3.2

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 (145) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +10 -10
  3. data/data/builtins/ruby_core/array.yml +416 -392
  4. data/data/builtins/ruby_core/file.yml +42 -42
  5. data/data/builtins/ruby_core/hash.yml +302 -302
  6. data/data/builtins/ruby_core/io.yml +191 -191
  7. data/data/builtins/ruby_core/numeric.yml +321 -366
  8. data/data/builtins/ruby_core/proc.yml +124 -124
  9. data/data/builtins/ruby_core/range.yml +21 -21
  10. data/data/builtins/ruby_core/rational.yml +39 -39
  11. data/data/builtins/ruby_core/re.yml +65 -65
  12. data/data/builtins/ruby_core/set.yml +106 -106
  13. data/data/builtins/ruby_core/struct.yml +14 -14
  14. data/data/core_overlay/pathname.rbs +5 -0
  15. data/data/core_overlay/resolv.rbs +31 -0
  16. data/data/core_overlay/string_scanner.rbs +11 -5
  17. data/data/gem_overlay/activesupport/core_ext.rbs +10 -6
  18. data/data/vendored_gem_sigs/bundler/bundler.rbs +39 -27
  19. data/data/vendored_gem_sigs/cgi/cgi_extras.rbs +6 -0
  20. data/data/vendored_gem_sigs/prism/prism_supplement.rbs +7 -0
  21. data/data/vendored_gem_sigs/racc/racc.rbs +67 -0
  22. data/data/vendored_gem_sigs/rubygems/rubygems_extras.rbs +20 -9
  23. data/docs/handbook/01-getting-started.md +22 -34
  24. data/docs/handbook/06-classes.md +1 -1
  25. data/docs/handbook/07-rbs-and-extended.md +76 -101
  26. data/docs/handbook/08-understanding-errors.md +114 -247
  27. data/docs/handbook/09-plugins.md +54 -144
  28. data/docs/handbook/README.md +5 -3
  29. data/docs/handbook/appendix-liskov.md +4 -2
  30. data/docs/handbook/appendix-phpstan.md +14 -7
  31. data/docs/handbook/appendix-steep.md +4 -2
  32. data/docs/handbook/appendix-type-theory.md +3 -1
  33. data/docs/manual/02-cli-reference.md +103 -11
  34. data/docs/manual/03-configuration.md +16 -1
  35. data/docs/manual/04-diagnostics.md +36 -4
  36. data/docs/manual/06-baseline.md +35 -1
  37. data/docs/manual/08-skills.md +6 -1
  38. data/docs/manual/09-editor-integration.md +3 -2
  39. data/docs/manual/12-caching.md +17 -5
  40. data/docs/manual/15-type-protection-coverage.md +122 -1
  41. data/docs/manual/plugins/rigor-actioncable.md +32 -0
  42. data/docs/manual/plugins/rigor-devise.md +4 -2
  43. data/docs/manual/plugins/rigor-rbs-inline.md +22 -0
  44. data/lib/rigor/analysis/check_rules/rule_ids.rb +1 -0
  45. data/lib/rigor/analysis/check_rules/void_value_use_collector.rb +21 -2
  46. data/lib/rigor/analysis/check_rules.rb +79 -19
  47. data/lib/rigor/analysis/incremental_session.rb +156 -11
  48. data/lib/rigor/analysis/plugin_fact_fingerprint.rb +14 -0
  49. data/lib/rigor/analysis/run_cache_key.rb +27 -1
  50. data/lib/rigor/analysis/runner/buffer_pool_dispatcher.rb +201 -0
  51. data/lib/rigor/analysis/runner/diagnostic_aggregator.rb +28 -10
  52. data/lib/rigor/analysis/runner/pool_coordinator.rb +7 -10
  53. data/lib/rigor/analysis/runner/project_pre_passes.rb +3 -1
  54. data/lib/rigor/analysis/runner.rb +80 -8
  55. data/lib/rigor/bleeding_edge.rb +132 -7
  56. data/lib/rigor/cache/descriptor.rb +6 -1
  57. data/lib/rigor/cache/engine_source.rb +162 -0
  58. data/lib/rigor/cache/incremental_snapshot.rb +87 -18
  59. data/lib/rigor/cache/rbs_cache_producer.rb +11 -1
  60. data/lib/rigor/cache/rbs_environment_marshal_patch.rb +38 -0
  61. data/lib/rigor/cache/store.rb +99 -24
  62. data/lib/rigor/cli/check_command.rb +61 -34
  63. data/lib/rigor/cli/check_invocation.rb +84 -0
  64. data/lib/rigor/cli/coverage_command.rb +15 -2
  65. data/lib/rigor/cli/coverage_mutation.rb +242 -11
  66. data/lib/rigor/cli/doctor_command.rb +6 -8
  67. data/lib/rigor/cli/fused_protection_renderer.rb +10 -0
  68. data/lib/rigor/cli/fused_protection_report.rb +12 -3
  69. data/lib/rigor/cli/mutation_fork_scan.rb +64 -0
  70. data/lib/rigor/cli/mutation_protection_renderer.rb +12 -0
  71. data/lib/rigor/cli/mutation_protection_report.rb +26 -5
  72. data/lib/rigor/cli/protection_renderer.rb +13 -0
  73. data/lib/rigor/cli/protection_report.rb +11 -3
  74. data/lib/rigor/cli/show_bleedingedge_command.rb +17 -4
  75. data/lib/rigor/cli/sig_gen_command.rb +5 -4
  76. data/lib/rigor/cli/skill_command.rb +21 -1
  77. data/lib/rigor/cli/skill_deep_probe.rb +172 -0
  78. data/lib/rigor/cli/skill_describe.rb +75 -9
  79. data/lib/rigor/configuration.rb +45 -6
  80. data/lib/rigor/environment/bundle_sig_discovery.rb +2 -1
  81. data/lib/rigor/environment/default_libraries.rb +5 -4
  82. data/lib/rigor/environment/rbs_coverage_report.rb +1 -1
  83. data/lib/rigor/environment/rbs_loader.rb +434 -75
  84. data/lib/rigor/environment.rb +38 -14
  85. data/lib/rigor/inference/expression_typer.rb +15 -0
  86. data/lib/rigor/inference/fork_map.rb +9 -0
  87. data/lib/rigor/inference/method_dispatcher/constant_folding.rb +50 -2
  88. data/lib/rigor/inference/method_dispatcher/data_folding.rb +1 -1
  89. data/lib/rigor/inference/method_dispatcher/member_shape_projection.rb +35 -1
  90. data/lib/rigor/inference/method_dispatcher/overload_selector.rb +6 -1
  91. data/lib/rigor/inference/method_dispatcher/rbs_dispatch.rb +16 -0
  92. data/lib/rigor/inference/method_dispatcher/regexp_folding.rb +64 -5
  93. data/lib/rigor/inference/method_dispatcher/shape_dispatch.rb +137 -9
  94. data/lib/rigor/inference/method_dispatcher/struct_folding.rb +3 -2
  95. data/lib/rigor/inference/method_dispatcher/uri_folding.rb +124 -1
  96. data/lib/rigor/inference/mutation_widening.rb +30 -25
  97. data/lib/rigor/inference/narrowing.rb +3 -1
  98. data/lib/rigor/inference/optimistic_origin.rb +58 -0
  99. data/lib/rigor/inference/protection_scanner.rb +18 -2
  100. data/lib/rigor/inference/receiver_alias.rb +57 -0
  101. data/lib/rigor/inference/scope_indexer.rb +78 -27
  102. data/lib/rigor/inference/statement_evaluator.rb +40 -2
  103. data/lib/rigor/language_server/buffer_resolution.rb +6 -3
  104. data/lib/rigor/language_server/buffer_table.rb +68 -6
  105. data/lib/rigor/language_server/diagnostic_publisher.rb +207 -4
  106. data/lib/rigor/language_server/incremental_sync.rb +159 -0
  107. data/lib/rigor/language_server/project_context.rb +45 -0
  108. data/lib/rigor/language_server/publish_batcher.rb +82 -0
  109. data/lib/rigor/language_server/server.rb +38 -9
  110. data/lib/rigor/language_server.rb +2 -0
  111. data/lib/rigor/plugin/base.rb +29 -2
  112. data/lib/rigor/plugin/source_rbs_synthesis_reporter.rb +9 -3
  113. data/lib/rigor/protection/closure_kill_oracle.rb +171 -0
  114. data/lib/rigor/protection/dependency_closure.rb +59 -0
  115. data/lib/rigor/protection/diagnostic_oracle.rb +12 -8
  116. data/lib/rigor/protection/discovery_seed.rb +116 -0
  117. data/lib/rigor/protection/kill_signature.rb +31 -0
  118. data/lib/rigor/protection/mutation_cache.rb +355 -0
  119. data/lib/rigor/protection/mutation_scanner.rb +55 -11
  120. data/lib/rigor/protection/mutator.rb +26 -4
  121. data/lib/rigor/runtime/jit.rb +63 -1
  122. data/lib/rigor/scope/discovery_index.rb +9 -0
  123. data/lib/rigor/scope.rb +52 -8
  124. data/lib/rigor/sig_gen/generator.rb +130 -31
  125. data/lib/rigor/sig_gen/layout_index.rb +6 -0
  126. data/lib/rigor/sig_gen/meta_class_shape.rb +84 -0
  127. data/lib/rigor/sig_gen/renderer.rb +20 -1
  128. data/lib/rigor/sig_gen/write_result.rb +6 -4
  129. data/lib/rigor/sig_gen/writer.rb +195 -47
  130. data/lib/rigor/sig_gen.rb +1 -0
  131. data/lib/rigor/version.rb +1 -1
  132. data/plugins/rigor-actioncable/lib/rigor/plugin/actioncable.rb +51 -1
  133. data/plugins/rigor-activesupport-core-ext/sig/active_support/core_ext.rbs +6 -6
  134. data/plugins/rigor-dry-schema/lib/rigor/plugin/dry_schema/result_shape.rb +146 -0
  135. data/plugins/rigor-dry-schema/lib/rigor/plugin/dry_schema/schema_scanner.rb +177 -12
  136. data/plugins/rigor-dry-schema/lib/rigor/plugin/dry_schema.rb +74 -7
  137. data/plugins/rigor-dry-validation/lib/rigor/plugin/dry_validation/contract_scanner.rb +257 -0
  138. data/plugins/rigor-dry-validation/lib/rigor/plugin/dry_validation/params_shape.rb +69 -0
  139. data/plugins/rigor-dry-validation/lib/rigor/plugin/dry_validation.rb +87 -11
  140. data/plugins/rigor-rbs-inline/lib/rigor/plugin/rbs_inline.rb +34 -4
  141. data/sig/rigor/cache.rbs +6 -0
  142. data/sig/rigor/inference/void_origin.rbs +21 -0
  143. data/sig/rigor/plugin/base.rbs +4 -3
  144. data/sig/rigor/scope.rbs +8 -0
  145. metadata +23 -3
@@ -0,0 +1,31 @@
1
+ # Rigor core overlay — supplemental core signatures.
2
+ #
3
+ # --- Resolv#initialize ---
4
+ #
5
+ # `rbs` before 4.1 declares `Resolv#initialize` as only:
6
+ #
7
+ # def initialize: (?Resolv::Hosts | Resolv::DNS resolvers) -> untyped
8
+ #
9
+ # But `Resolv.new` takes an *array* of resolvers — the runtime default is
10
+ # `[Hosts.new, DNS.new]`, and `each_address` iterates the argument — so the
11
+ # documented, idiomatic call passes an Array:
12
+ #
13
+ # Resolv.new([Resolv::Hosts.new, Resolv::DNS.new(nameserver: ...)])
14
+ #
15
+ # Against the pre-4.1 signature every overload rejects that Array and
16
+ # `call.argument-type-mismatch` false-fires (measured on Mastodon's
17
+ # `app/lib/request.rb`).
18
+ #
19
+ # `rbs` 4.1.0 fixed the signature upstream (ruby/rbs#2960); the overlay
20
+ # backports that overload for the older releases the gemspec still supports
21
+ # (`>= 3.0, < 5.0`). On 4.1 the appended overload duplicates the upstream
22
+ # one, which costs nothing. Drop this file when the rbs floor reaches 4.1.
23
+ #
24
+ # Loaded ONLY when the `resolv` library resolves
25
+ # (`RbsLoader::LIBRARY_SUPPLEMENT_CORE_OVERLAYS`): the `| ...` overload
26
+ # continuation is invalid without the base declaration, and the resulting
27
+ # `InvalidOverloadMethodError` would take the whole class down.
28
+ class Resolv
29
+ def initialize: (?(Array[Resolv::Hosts | Resolv::DNS] | Hash[Symbol, untyped])? resolvers, ?use_ipv6: bool?) -> untyped
30
+ | ...
31
+ end
@@ -2,7 +2,7 @@
2
2
  #
3
3
  # --- StringScanner#[] ---
4
4
  #
5
- # The pinned `rbs` gem (4.0.2) declares `StringScanner#[]` as only:
5
+ # `rbs` 4.0.x declares `StringScanner#[]` as only:
6
6
  #
7
7
  # def []: (Integer) -> String?
8
8
  #
@@ -14,14 +14,20 @@
14
14
  # scanner.skip(/(?<key>\w+)=/)
15
15
  # scanner[:key] # => the captured String, or nil
16
16
  #
17
- # Newer `ruby/rbs` already widens the signature to
18
- # `(Integer | String | Symbol) -> String?`; the pinned 4.0.2 gem lags.
19
17
  # Without the wider overload, a named-capture access such as Mastodon's
20
18
  # `scanner[:key]` false-fires `call.argument-type-mismatch` (the lone
21
19
  # overload rejects a `Symbol`).
22
20
  #
23
- # The overlay supplies the runtime-accurate overload; drop it once the
24
- # pinned `rbs` gem carries the wider signature.
21
+ # `rbs` 4.1.0 widened the upstream signature to exactly this
22
+ # (ruby/rbs#2959), so the overlay is redundant on the pinned gem and only
23
+ # earns its keep for a consumer resolving an older `rbs` inside the
24
+ # gemspec's `>= 3.0, < 5.0` range. It stays until that floor moves;
25
+ # reopening with an identical overload costs nothing on 4.1.
26
+ #
27
+ # Loaded ONLY when the `strscan` library resolves
28
+ # (`RbsLoader::LIBRARY_SUPPLEMENT_CORE_OVERLAYS`): the `| ...` overload
29
+ # continuation is invalid without the base declaration, and the resulting
30
+ # `InvalidOverloadMethodError` would take the whole class down.
25
31
  class StringScanner
26
32
  def []: (Integer | String | Symbol) -> String?
27
33
  | ...
@@ -245,10 +245,10 @@ class Time
245
245
  def self.zone: () -> untyped # ActiveSupport::TimeZone | nil
246
246
  def self.zone=: (String | Symbol | untyped) -> untyped
247
247
 
248
- # `core_ext/time/conversions` — also `Time.parse` from stdlib
249
- # `time`, which is already in core RBS.
250
- def self.httpdate: (String) -> Time
251
- def self.iso8601: (String) -> Time
248
+ # `core_ext/time/conversions` — nothing to declare. `Time.parse`, `Time.httpdate` and `Time.iso8601`
249
+ # all come from stdlib `time`, which rbs types; ActiveSupport only re-opens them. Declaring them
250
+ # here raised `RBS::DuplicatedMethodDefinitionError` and collapsed the whole `Time` definition to
251
+ # `Dynamic[top]`.
252
252
 
253
253
  # `core_ext/time/calculations`
254
254
  def yesterday: () -> Time
@@ -278,7 +278,10 @@ class Time
278
278
  def midday: () -> Time
279
279
  def midnight: () -> Time
280
280
  def noon: () -> Time
281
- def utc?: () -> bool
281
+ # NOTE: `Time#utc?` is NOT declared here — it is Ruby core, already typed by rbs's `core/time.rbs`.
282
+ # Re-declaring it raised `RBS::DuplicatedMethodDefinitionError` and took the WHOLE `Time` definition
283
+ # down with it (every `Time` call degraded to `Dynamic[top]`). This overlay only ADDS what
284
+ # ActiveSupport adds.
282
285
  def acts_like_time?: () -> true
283
286
  end
284
287
 
@@ -457,7 +460,8 @@ end
457
460
 
458
461
  class DateTime
459
462
  def utc: () -> Time
460
- def to_time: () -> Time
463
+ # NOTE: `DateTime#to_time` is NOT declared here — stdlib `date` already types it, and re-declaring it
464
+ # collapsed the whole `DateTime` definition (see the `Time#utc?` note above).
461
465
  def in_time_zone: (?String | Symbol zone) -> untyped
462
466
  def yesterday: () -> DateTime
463
467
  def tomorrow: () -> DateTime
@@ -2,14 +2,12 @@
2
2
  # Rigor-side vendored RBS stub for the `bundler` gem.
3
3
  #
4
4
  # The `bundler` gem does not ship its own `sig/` and is not
5
- # covered by `ruby/gem_rbs_collection`. The shim in
6
- # `references/rbs/sig/shims/bundler.rbs` (rbs gem upstream)
7
- # carries a tiny subset (`LockfileParser`, `LazySpecification`,
8
- # `Dependency`, `Definition`, `default_lockfile`, `definition`,
9
- # `Source::Gemspec`) but is only loaded when the user opts in via
10
- # `library "bundler"` — that's rare in Rigor `.rigor.yml` setups,
11
- # so most projects analyse bundler-using code with NO `Bundler`
12
- # RBS in scope.
5
+ # covered by `ruby/gem_rbs_collection`. The rbs gem's own
6
+ # `sig/shims/bundler.rbs` carries a tiny subset (`LockfileParser`,
7
+ # `LazySpecification`, `Dependency`, `Definition`,
8
+ # `default_lockfile`, `definition`, `Source::Gemspec`) — enough to
9
+ # type rbs's own use of bundler, not enough to analyse a project
10
+ # that uses it.
13
11
  #
14
12
  # This stub covers the Bundler module's top-25 singleton methods
15
13
  # surfaced by the `references/ruby/lib` survey
@@ -21,13 +19,23 @@
21
19
  # silence `call.undefined-method` rather than infer precise
22
20
  # returns.
23
21
  #
24
- # Declarations are intentionally a SUPERSET of the
25
- # `references/rbs/sig/shims/bundler.rbs` shim. When the user
26
- # opts into `library "bundler"`, the shim's typed declarations
27
- # (`LockfileParser#specs -> Array[LazySpecification]`, etc.)
28
- # would conflict; users who want both should drop the
29
- # `library "bundler"` entry from their config so this vendored
30
- # stub wins.
22
+ # The `rbs` gem's own `sig/shims/bundler.rbs` IS always in scope:
23
+ # `rbs` sits in `Environment::DEFAULT_LIBRARIES`, so its `sig/`
24
+ # tree shims included loads on every run. This file therefore
25
+ # declares only what the shim does NOT, and never re-declares a
26
+ # shim method: a duplicate raises
27
+ # `RBS::DuplicatedMethodDefinitionError` inside
28
+ # `RBS::DefinitionBuilder` and collapses the ENTIRE class to
29
+ # `Dynamic[top]` (issue #299). Where the shim's type is weaker
30
+ # than Rigor's would have been, the shim still wins: an RBS
31
+ # overload continuation (`| ...`) would append rather than
32
+ # collide, but it raises `InvalidOverloadMethodError` when the
33
+ # base declaration is absent, which breaks every environment
34
+ # built without the `rbs` library. Those spots are marked below.
35
+ #
36
+ # Keep this file and `sig/shims/bundler.rbs` in sync on an `rbs`
37
+ # bump — `spec/rigor/environment/bundled_rbs_definition_build_spec.rb`
38
+ # fails the suite if a new collision reappears.
31
39
  #
32
40
  module Bundler
33
41
  # `Bundler.<name>` — accessors / module-level entry points.
@@ -46,7 +54,13 @@ module Bundler
46
54
  def self.require: (*untyped groups) -> untyped
47
55
  def self.load: () -> untyped
48
56
  def self.environment: () -> untyped
49
- def self.definition: (?untyped unlock, ?untyped lockfile) -> Definition
57
+ # `self.definition` declared by `sig/shims/bundler.rbs`. Note that the shim types it `() ->
58
+ # Definition` while the real `Bundler.definition(unlock = nil, lockfile = default_lockfile)` takes
59
+ # two optional arguments; an `| ...` overload continuation here would restore that arity, but a
60
+ # continuation with no base declaration raises `RBS::InvalidOverloadMethodError` — so any
61
+ # environment built WITHOUT the `rbs` library would lose the whole `Bundler` module to
62
+ # `Dynamic[top]`. The narrower arity is the cheaper of the two failure modes; the fix belongs
63
+ # upstream in the shim.
50
64
  def self.frozen_bundle?: () -> bool
51
65
  def self.locked_gems: () -> untyped
52
66
  def self.ruby_scope: () -> String
@@ -78,7 +92,7 @@ module Bundler
78
92
  def self.local_platform: () -> untyped
79
93
  def self.generic_local_platform: () -> untyped
80
94
  def self.default_gemfile: () -> Pathname
81
- def self.default_lockfile: () -> Pathname
95
+ # `self.default_lockfile` declared by `sig/shims/bundler.rbs` with the same type.
82
96
  def self.default_bundle_dir: () -> Pathname?
83
97
  def self.system_bindir: () -> String?
84
98
  def self.preferred_gemfile_name: () -> String
@@ -104,10 +118,9 @@ module Bundler
104
118
 
105
119
  def initialize: (*untyped) -> void
106
120
  def gemfiles: () -> Array[Pathname]
107
- def lockfile: () -> Pathname
121
+ # `#lockfile`, `#locked_gems`, `#dependencies` — declared by `sig/shims/bundler.rbs` with the
122
+ # same types.
108
123
  def lockfile=: (untyped) -> untyped
109
- def locked_gems: () -> LockfileParser
110
- def dependencies: () -> Array[Dependency]
111
124
  def current_dependencies: () -> Array[Dependency]
112
125
  def requested_dependencies: () -> Array[Dependency]
113
126
  def dependencies_for: (untyped groups) -> Array[Dependency]
@@ -134,8 +147,7 @@ module Bundler
134
147
  end
135
148
 
136
149
  class LockfileParser
137
- def initialize: (String body) -> void
138
- def specs: () -> Array[LazySpecification]
150
+ # `#initialize`, `#specs` declared by `sig/shims/bundler.rbs` with the same types.
139
151
  def platforms: () -> Array[untyped]
140
152
  def sources: () -> Array[untyped]
141
153
  def dependencies: () -> Array[Dependency]
@@ -144,16 +156,16 @@ module Bundler
144
156
  end
145
157
 
146
158
  class LazySpecification
147
- def name: () -> String
148
- def version: () -> Gem::Version
159
+ # `#name`, `#version`, `#dependencies` — declared by `sig/shims/bundler.rbs`. The shim types
160
+ # `#version` as `() -> String` where bundler returns a `Gem::Version`; see the note on
161
+ # `Bundler.definition` above for why that is left alone rather than corrected with an `| ...`
162
+ # overload continuation.
149
163
  def platform: () -> untyped
150
- def dependencies: () -> Array[Gem::Dependency]
151
164
  def source: () -> untyped
152
165
  end
153
166
 
154
167
  class Dependency < Gem::Dependency
155
- attr_reader autorequire: Array[String]?
156
- attr_reader source: untyped
168
+ # `#autorequire`, `#source` — declared by `sig/shims/bundler.rbs` with the same types.
157
169
  attr_reader groups: Array[Symbol]
158
170
  attr_reader platforms: Array[Symbol]
159
171
  end
@@ -29,6 +29,12 @@
29
29
  # `include CGI::Util` + `extend CGI::Util`; adding a sibling
30
30
  # `include CGI::QueryExtension` is purely additive.
31
31
  #
32
+ # Loaded ONLY when the `cgi` stdlib library resolves
33
+ # (`RbsLoader::LIBRARY_SUPPLEMENT_VENDORED_DIRS`): without it the
34
+ # mixin target does not exist, `RBS::DefinitionBuilder` raises
35
+ # `NoMixinFoundError`, and the whole `CGI` class silently degrades
36
+ # to `Dynamic[top]`.
37
+ #
32
38
  class CGI
33
39
  include CGI::QueryExtension
34
40
  end
@@ -21,6 +21,13 @@
21
21
  # — bound as singleton methods by the C extension; the
22
22
  # gem's RBS only declares the matching instance methods.
23
23
  #
24
+ # Loaded ONLY when the `prism` library resolves
25
+ # (`RbsLoader::LIBRARY_SUPPLEMENT_VENDORED_DIRS`): the
26
+ # `ParseResult < Result` re-opening names a superclass only the
27
+ # gem's own RBS declares, so without it `RBS::DefinitionBuilder`
28
+ # raises `NoSuperclassFoundError` and the whole class silently
29
+ # degrades to `Dynamic[top]`.
30
+ #
24
31
  module Prism
25
32
  class ParseResult < Result
26
33
  # Walk the parse result's tree, attaching every comment to
@@ -0,0 +1,67 @@
1
+ #
2
+ # Rigor-side vendored RBS stub for the `racc` gem's runtime.
3
+ #
4
+ # Vendored for ONE structural reason: `data/vendored_gem_sigs/nokogiri/nokogiri.rbs` declares
5
+ # `class Nokogiri::CSS::Parser < Racc::Parser`, and `RBS::DefinitionBuilder` raises
6
+ # `RBS::NoSuperclassFoundError` when a declared superclass has no declaration anywhere in the
7
+ # environment — which took the whole `Nokogiri::CSS::Parser` definition down to `Dynamic[top]`
8
+ # (issue #299). Dropping the superclass from the nokogiri sig would have hidden the inheritance
9
+ # instead of typing it, and `Racc::Parser` is a real, small, stable class, so it is declared here.
10
+ #
11
+ # Scope is the documented runtime surface a racc-generated parser inherits, plus `Racc::ParseError`
12
+ # (which `Nokogiri::CSS::SyntaxError` and every generated parser raise). The `_racc_*` methods are
13
+ # private implementation detail of the generated parse loop and are deliberately NOT declared —
14
+ # nothing outside racc itself calls them.
15
+ #
16
+ # Returns are `untyped` wherever the value is a grammar-defined semantic value: racc has no way to
17
+ # know what a generated parser's actions produce, and guessing would cost false positives.
18
+ #
19
+ module Racc
20
+ # Raised by a generated parser on an unrecoverable syntax error.
21
+ class ParseError < StandardError
22
+ end
23
+
24
+ # The runtime base class every racc-generated parser inherits from.
25
+ class Parser
26
+ # Runs the parse loop, pulling tokens from the subclass's `#next_token`. Returns the grammar's
27
+ # start-rule value.
28
+ def do_parse: () -> untyped
29
+
30
+ # Token source: a generated parser's user code overrides this to return `[token_symbol, value]`,
31
+ # or `nil` / `[false, ...]` at end of input.
32
+ def next_token: () -> untyped
33
+
34
+ # Runs the parse loop pulling tokens by calling `recv.__send__(mid)` instead of `#next_token`.
35
+ def yyparse: (untyped recv, Symbol | String mid) -> untyped
36
+
37
+ # Error hook: called with the offending token id, its value, and the value stack. The default
38
+ # implementation raises `Racc::ParseError`; user code overrides it to report and recover.
39
+ def on_error: (untyped error_token_id, untyped error_value, untyped value_stack) -> void
40
+
41
+ # Explicitly signals a syntax error from inside a parser action.
42
+ def yyerror: () -> void
43
+
44
+ # Accepts the input from inside a parser action, ending the parse.
45
+ def yyaccept: () -> void
46
+
47
+ # Clears the error state after `#on_error`, resuming normal parsing.
48
+ def yyerrok: () -> void
49
+
50
+ # Human-readable name for a token id, or `nil` when the id is unknown.
51
+ def token_to_str: (untyped t) -> String?
52
+
53
+ # Debug-trace hooks. Enabled by a generated parser built with racc's `--debug`; harmless no-ops
54
+ # otherwise.
55
+ def racc_read_token: (untyped t, untyped tok, untyped val) -> void
56
+ def racc_shift: (untyped tok, untyped tstack, untyped vstack) -> void
57
+ def racc_reduce: (untyped toks, untyped sim, untyped tstack, untyped vstack) -> void
58
+ def racc_accept: () -> void
59
+ def racc_e_pop: (untyped state, untyped tstack, untyped vstack) -> void
60
+ def racc_next_state: (untyped curstate, untyped state) -> void
61
+ def racc_print_stacks: (untyped t, untyped v) -> void
62
+ def racc_print_states: (untyped s) -> void
63
+ def racc_token2str: (untyped tok) -> String
64
+
65
+ def self.racc_runtime_type: () -> String
66
+ end
67
+ end
@@ -8,6 +8,17 @@
8
8
  # the upstream RBS already covers, so the loader does not raise
9
9
  # `RBS::DuplicatedDeclarationError`.
10
10
  #
11
+ # "Upstream RBS" here means BOTH `core/rubygems/*.rbs` and the
12
+ # `rbs` gem's `sig/shims/rubygems.rbs`: `rbs` is in
13
+ # `Environment::DEFAULT_LIBRARIES`, so its whole `sig/` tree —
14
+ # shims included — is in scope on every run. A duplicate against
15
+ # either raises `RBS::DuplicatedMethodDefinitionError` inside
16
+ # `RBS::DefinitionBuilder` and collapses the ENTIRE class to
17
+ # `Dynamic[top]` (issue #299), so a shim-declared reader is left
18
+ # to the shim and only the writer half is declared here.
19
+ # `spec/rigor/environment/bundled_rbs_definition_build_spec.rb`
20
+ # fails the suite if a new collision reappears on an `rbs` bump.
21
+ #
11
22
  # Driven by the `references/ruby/lib` survey
12
23
  # (`docs/CURRENT_WORK.md` § "Queued engine items") which
13
24
  # clusters `undefined-method` on Gem-side selectors most-touched
@@ -62,7 +73,7 @@ class Gem::Platform
62
73
  def match_spec?: (untyped) -> bool
63
74
  def match_gem?: (untyped, untyped) -> bool
64
75
 
65
- def self.local: () -> Platform
76
+ def self.local: () -> Gem::Platform
66
77
  def self.match_spec?: (untyped) -> bool
67
78
  def self.match_gem?: (untyped, untyped) -> bool
68
79
  def self.installable?: (untyped) -> bool
@@ -75,7 +86,9 @@ class Gem::Dependency
75
86
  # permissive splat keeps the canonical and the
76
87
  # `(name, requirements, type)` invocation forms both silent.
77
88
  def initialize: (*untyped) -> void
78
- attr_accessor name: String
89
+ # `#name`'s READER is declared by `sig/shims/rubygems.rbs` (`() -> String`); only the writer is
90
+ # ours, so this is a `def name=` rather than the `attr_accessor` the other members use.
91
+ def name=: (String) -> String
79
92
  attr_accessor requirement: Gem::Requirement
80
93
  attr_accessor type: Symbol
81
94
  attr_accessor prerelease: bool
@@ -111,7 +124,9 @@ class Gem::Specification
111
124
  def required_ruby_version: () -> Gem::Requirement
112
125
  def require_paths: () -> Array[String]
113
126
  attr_accessor name: String
114
- attr_accessor version: Gem::Version
127
+ # `#version`'s READER is declared by `sig/shims/rubygems.rbs` (`attr_reader version (): Version`);
128
+ # only the writer is ours.
129
+ def version=: (Gem::Version) -> Gem::Version
115
130
  attr_accessor full_gem_path: String
116
131
  attr_accessor loaded_from: String?
117
132
  attr_accessor post_install_message: String?
@@ -131,7 +146,7 @@ end
131
146
 
132
147
  class Gem::Requirement
133
148
  def requirements: () -> Array[untyped]
134
- def self.create: (*untyped) -> Gem::Requirement
149
+ # `.create` declared by `core/rubygems/requirement.rbs`, and more precisely than this file did.
135
150
  end
136
151
 
137
152
  class Gem::ConfigFile
@@ -172,7 +187,7 @@ class Gem::SourceList
172
187
  def include?: (untyped) -> bool
173
188
  def each: () { (untyped) -> untyped } -> void
174
189
  def to_a: () -> Array[untyped]
175
- def from: (untyped) -> SourceList
190
+ def from: (untyped) -> Gem::SourceList
176
191
  end
177
192
 
178
193
  class Gem::RequestSet
@@ -217,10 +232,6 @@ class Gem::Installer
217
232
  def initialize: (*untyped) -> void
218
233
  end
219
234
 
220
- class Gem::DependencyInstaller
221
- def initialize: (*untyped) -> void
222
- end
223
-
224
235
  class Gem::MissingSpecError < StandardError
225
236
  def initialize: (*untyped) -> void
226
237
  end
@@ -78,7 +78,9 @@ catalogue of bugs:
78
78
  - arithmetic that can be proved to raise (`5 / 0`);
79
79
  - arguments whose type does not satisfy a refined parameter
80
80
  contract;
81
- - a few more, all listed in
81
+ - a few more, all catalogued in
82
+ [manual — Diagnostics](../manual/04-diagnostics.md) and
83
+ explained in
82
84
  [Chapter 8 — Understanding errors](08-understanding-errors.md).
83
85
 
84
86
  Rigor does **not** ask you to write type annotations in
@@ -170,9 +172,11 @@ on the offending line:
170
172
  The same identifier also drives the `disable:` and
171
173
  `severity_overrides:` config keys, and family wildcards work
172
174
  (`# rigor:disable call` suppresses every `call.*` rule on that
173
- line). The full list of families and rules, and when to reach
174
- for each suppression mechanism, is in
175
- [Chapter 8 — Understanding errors](08-understanding-errors.md).
175
+ line). The full list of families and rules is in
176
+ [manual Diagnostics](../manual/04-diagnostics.md);
177
+ [Chapter 8 — Understanding errors](08-understanding-errors.md)
178
+ is where to read about choosing between the suppression
179
+ mechanisms.
176
180
 
177
181
  ## The "no annotations" stance
178
182
 
@@ -278,36 +282,20 @@ non-default behaviours: extra `paths`, an alternative
278
282
  If you used the [AI-assisted setup](#the-fast-path-let-an-ai-agent-set-it-up),
279
283
  the `rigor-project-init` skill already wrote one for you. To
280
284
  write a starter by hand, `rigor init` emits `.rigor.dist.yml`
281
- — the project default that gets committed:
282
-
283
- ```yaml
284
- target_ruby: "3.4" # your project's Ruby not Rigor's own 4.0
285
-
286
- paths:
287
- - lib
288
-
289
- # signature_paths: [sig] # auto-detected when omitted
290
-
291
- severity_profile: balanced
292
-
293
- # severity_overrides:
294
- # call.argument-type-mismatch: warning
295
-
296
- # disable: []
297
-
298
- # plugins: []
299
- ```
300
-
301
- That is all most projects need. The remaining mechanics —
302
- editor autocomplete from the bundled JSON schema, the
303
- `.rigor.yml` vs `.rigor.dist.yml` precedence rule, `includes:`
304
- composition, and how path-bearing keys resolve relative to the
305
- declaring file — are covered in
306
- [Configuration](../manual/03-configuration.md). The one rule
307
- worth knowing up front: when a developer keeps a local
308
- `.rigor.yml`, it is the *sole* source of config for their runs
309
- (the two files are never merged automatically), so to extend
310
- the shared default it must list it under `includes:`.
285
+ — the project default that gets committed, with `target_ruby`,
286
+ `paths`, and a `severity_profile` filled in and the rest
287
+ commented out. That is all most projects need; the key
288
+ reference, the JSON-schema editor integration, and `includes:`
289
+ composition are in
290
+ [Configuration](../manual/03-configuration.md).
291
+
292
+ Two things are worth knowing up front, because they surprise
293
+ people. `target_ruby` is *your project's* Ruby, not the 4.0
294
+ Rigor itself runs on — those are independent on purpose. And
295
+ when a developer keeps a local `.rigor.yml`, it is the *sole*
296
+ source of config for their runs (the two files are never merged
297
+ automatically), so to extend the shared default it must list it
298
+ under `includes:`.
311
299
 
312
300
  ## What's next
313
301
 
@@ -97,7 +97,7 @@ both. The setter's argument type is whatever the call site
97
97
  provides. The `def.ivar-write-mismatch` rule (v0.1.2) checks
98
98
  that two writes to the same ivar in the same class body
99
99
  agree on the concrete class — see
100
- [Chapter 8 Understanding errors](08-understanding-errors.md)
100
+ [manualDiagnostics](../manual/04-diagnostics.md)
101
101
  for the rule's exact contract; it lets you catch an
102
102
  accidental rebind from `String` to `Array` in the same class
103
103
  without authoring an explicit ivar type.