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.
- checksums.yaml +4 -4
- data/README.md +10 -10
- data/data/builtins/ruby_core/array.yml +416 -392
- data/data/builtins/ruby_core/file.yml +42 -42
- data/data/builtins/ruby_core/hash.yml +302 -302
- data/data/builtins/ruby_core/io.yml +191 -191
- data/data/builtins/ruby_core/numeric.yml +321 -366
- data/data/builtins/ruby_core/proc.yml +124 -124
- data/data/builtins/ruby_core/range.yml +21 -21
- data/data/builtins/ruby_core/rational.yml +39 -39
- data/data/builtins/ruby_core/re.yml +65 -65
- data/data/builtins/ruby_core/set.yml +106 -106
- data/data/builtins/ruby_core/struct.yml +14 -14
- data/data/core_overlay/pathname.rbs +5 -0
- data/data/core_overlay/resolv.rbs +31 -0
- data/data/core_overlay/string_scanner.rbs +11 -5
- data/data/gem_overlay/activesupport/core_ext.rbs +10 -6
- data/data/vendored_gem_sigs/bundler/bundler.rbs +39 -27
- data/data/vendored_gem_sigs/cgi/cgi_extras.rbs +6 -0
- data/data/vendored_gem_sigs/prism/prism_supplement.rbs +7 -0
- data/data/vendored_gem_sigs/racc/racc.rbs +67 -0
- data/data/vendored_gem_sigs/rubygems/rubygems_extras.rbs +20 -9
- data/docs/handbook/01-getting-started.md +22 -34
- data/docs/handbook/06-classes.md +1 -1
- data/docs/handbook/07-rbs-and-extended.md +76 -101
- data/docs/handbook/08-understanding-errors.md +114 -247
- data/docs/handbook/09-plugins.md +54 -144
- data/docs/handbook/README.md +5 -3
- data/docs/handbook/appendix-liskov.md +4 -2
- data/docs/handbook/appendix-phpstan.md +14 -7
- data/docs/handbook/appendix-steep.md +4 -2
- data/docs/handbook/appendix-type-theory.md +3 -1
- data/docs/manual/02-cli-reference.md +103 -11
- data/docs/manual/03-configuration.md +16 -1
- data/docs/manual/04-diagnostics.md +36 -4
- data/docs/manual/06-baseline.md +35 -1
- data/docs/manual/08-skills.md +6 -1
- data/docs/manual/09-editor-integration.md +3 -2
- data/docs/manual/12-caching.md +17 -5
- data/docs/manual/15-type-protection-coverage.md +122 -1
- data/docs/manual/plugins/rigor-actioncable.md +32 -0
- data/docs/manual/plugins/rigor-devise.md +4 -2
- data/docs/manual/plugins/rigor-rbs-inline.md +22 -0
- data/lib/rigor/analysis/check_rules/rule_ids.rb +1 -0
- data/lib/rigor/analysis/check_rules/void_value_use_collector.rb +21 -2
- data/lib/rigor/analysis/check_rules.rb +79 -19
- data/lib/rigor/analysis/incremental_session.rb +156 -11
- data/lib/rigor/analysis/plugin_fact_fingerprint.rb +14 -0
- data/lib/rigor/analysis/run_cache_key.rb +27 -1
- data/lib/rigor/analysis/runner/buffer_pool_dispatcher.rb +201 -0
- data/lib/rigor/analysis/runner/diagnostic_aggregator.rb +28 -10
- data/lib/rigor/analysis/runner/pool_coordinator.rb +7 -10
- data/lib/rigor/analysis/runner/project_pre_passes.rb +3 -1
- data/lib/rigor/analysis/runner.rb +80 -8
- data/lib/rigor/bleeding_edge.rb +132 -7
- data/lib/rigor/cache/descriptor.rb +6 -1
- data/lib/rigor/cache/engine_source.rb +162 -0
- data/lib/rigor/cache/incremental_snapshot.rb +87 -18
- data/lib/rigor/cache/rbs_cache_producer.rb +11 -1
- data/lib/rigor/cache/rbs_environment_marshal_patch.rb +38 -0
- data/lib/rigor/cache/store.rb +99 -24
- data/lib/rigor/cli/check_command.rb +61 -34
- data/lib/rigor/cli/check_invocation.rb +84 -0
- data/lib/rigor/cli/coverage_command.rb +15 -2
- data/lib/rigor/cli/coverage_mutation.rb +242 -11
- data/lib/rigor/cli/doctor_command.rb +6 -8
- data/lib/rigor/cli/fused_protection_renderer.rb +10 -0
- data/lib/rigor/cli/fused_protection_report.rb +12 -3
- data/lib/rigor/cli/mutation_fork_scan.rb +64 -0
- data/lib/rigor/cli/mutation_protection_renderer.rb +12 -0
- data/lib/rigor/cli/mutation_protection_report.rb +26 -5
- data/lib/rigor/cli/protection_renderer.rb +13 -0
- data/lib/rigor/cli/protection_report.rb +11 -3
- data/lib/rigor/cli/show_bleedingedge_command.rb +17 -4
- data/lib/rigor/cli/sig_gen_command.rb +5 -4
- data/lib/rigor/cli/skill_command.rb +21 -1
- data/lib/rigor/cli/skill_deep_probe.rb +172 -0
- data/lib/rigor/cli/skill_describe.rb +75 -9
- data/lib/rigor/configuration.rb +45 -6
- data/lib/rigor/environment/bundle_sig_discovery.rb +2 -1
- data/lib/rigor/environment/default_libraries.rb +5 -4
- data/lib/rigor/environment/rbs_coverage_report.rb +1 -1
- data/lib/rigor/environment/rbs_loader.rb +434 -75
- data/lib/rigor/environment.rb +38 -14
- data/lib/rigor/inference/expression_typer.rb +15 -0
- data/lib/rigor/inference/fork_map.rb +9 -0
- data/lib/rigor/inference/method_dispatcher/constant_folding.rb +50 -2
- data/lib/rigor/inference/method_dispatcher/data_folding.rb +1 -1
- data/lib/rigor/inference/method_dispatcher/member_shape_projection.rb +35 -1
- data/lib/rigor/inference/method_dispatcher/overload_selector.rb +6 -1
- data/lib/rigor/inference/method_dispatcher/rbs_dispatch.rb +16 -0
- data/lib/rigor/inference/method_dispatcher/regexp_folding.rb +64 -5
- data/lib/rigor/inference/method_dispatcher/shape_dispatch.rb +137 -9
- data/lib/rigor/inference/method_dispatcher/struct_folding.rb +3 -2
- data/lib/rigor/inference/method_dispatcher/uri_folding.rb +124 -1
- data/lib/rigor/inference/mutation_widening.rb +30 -25
- data/lib/rigor/inference/narrowing.rb +3 -1
- data/lib/rigor/inference/optimistic_origin.rb +58 -0
- data/lib/rigor/inference/protection_scanner.rb +18 -2
- data/lib/rigor/inference/receiver_alias.rb +57 -0
- data/lib/rigor/inference/scope_indexer.rb +78 -27
- data/lib/rigor/inference/statement_evaluator.rb +40 -2
- data/lib/rigor/language_server/buffer_resolution.rb +6 -3
- data/lib/rigor/language_server/buffer_table.rb +68 -6
- data/lib/rigor/language_server/diagnostic_publisher.rb +207 -4
- data/lib/rigor/language_server/incremental_sync.rb +159 -0
- data/lib/rigor/language_server/project_context.rb +45 -0
- data/lib/rigor/language_server/publish_batcher.rb +82 -0
- data/lib/rigor/language_server/server.rb +38 -9
- data/lib/rigor/language_server.rb +2 -0
- data/lib/rigor/plugin/base.rb +29 -2
- data/lib/rigor/plugin/source_rbs_synthesis_reporter.rb +9 -3
- data/lib/rigor/protection/closure_kill_oracle.rb +171 -0
- data/lib/rigor/protection/dependency_closure.rb +59 -0
- data/lib/rigor/protection/diagnostic_oracle.rb +12 -8
- data/lib/rigor/protection/discovery_seed.rb +116 -0
- data/lib/rigor/protection/kill_signature.rb +31 -0
- data/lib/rigor/protection/mutation_cache.rb +355 -0
- data/lib/rigor/protection/mutation_scanner.rb +55 -11
- data/lib/rigor/protection/mutator.rb +26 -4
- data/lib/rigor/runtime/jit.rb +63 -1
- data/lib/rigor/scope/discovery_index.rb +9 -0
- data/lib/rigor/scope.rb +52 -8
- data/lib/rigor/sig_gen/generator.rb +130 -31
- data/lib/rigor/sig_gen/layout_index.rb +6 -0
- data/lib/rigor/sig_gen/meta_class_shape.rb +84 -0
- data/lib/rigor/sig_gen/renderer.rb +20 -1
- data/lib/rigor/sig_gen/write_result.rb +6 -4
- data/lib/rigor/sig_gen/writer.rb +195 -47
- data/lib/rigor/sig_gen.rb +1 -0
- data/lib/rigor/version.rb +1 -1
- data/plugins/rigor-actioncable/lib/rigor/plugin/actioncable.rb +51 -1
- data/plugins/rigor-activesupport-core-ext/sig/active_support/core_ext.rbs +6 -6
- data/plugins/rigor-dry-schema/lib/rigor/plugin/dry_schema/result_shape.rb +146 -0
- data/plugins/rigor-dry-schema/lib/rigor/plugin/dry_schema/schema_scanner.rb +177 -12
- data/plugins/rigor-dry-schema/lib/rigor/plugin/dry_schema.rb +74 -7
- data/plugins/rigor-dry-validation/lib/rigor/plugin/dry_validation/contract_scanner.rb +257 -0
- data/plugins/rigor-dry-validation/lib/rigor/plugin/dry_validation/params_shape.rb +69 -0
- data/plugins/rigor-dry-validation/lib/rigor/plugin/dry_validation.rb +87 -11
- data/plugins/rigor-rbs-inline/lib/rigor/plugin/rbs_inline.rb +34 -4
- data/sig/rigor/cache.rbs +6 -0
- data/sig/rigor/inference/void_origin.rbs +21 -0
- data/sig/rigor/plugin/base.rbs +4 -3
- data/sig/rigor/scope.rbs +8 -0
- 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
|
-
#
|
|
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
|
-
#
|
|
24
|
-
#
|
|
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` —
|
|
249
|
-
# `time`, which
|
|
250
|
-
|
|
251
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
6
|
-
# `
|
|
7
|
-
#
|
|
8
|
-
# `
|
|
9
|
-
#
|
|
10
|
-
#
|
|
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
|
-
#
|
|
25
|
-
# `
|
|
26
|
-
#
|
|
27
|
-
#
|
|
28
|
-
#
|
|
29
|
-
# `
|
|
30
|
-
#
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
148
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
174
|
-
|
|
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
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
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
|
|
data/docs/handbook/06-classes.md
CHANGED
|
@@ -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
|
-
[
|
|
100
|
+
[manual — Diagnostics](../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.
|