rigortype 0.1.19 → 0.2.1
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 +41 -6
- data/data/core_overlay/numeric.rbs +33 -0
- data/data/core_overlay/pathname.rbs +25 -0
- data/data/core_overlay/string_scanner.rbs +28 -0
- data/data/gem_overlay/activesupport/core_ext.rbs +473 -0
- data/data/vendored_gem_sigs/ast/ast.rbs +130 -0
- data/data/vendored_gem_sigs/bcrypt/bcrypt.rbs +47 -0
- data/data/vendored_gem_sigs/bundler/bundler.rbs +238 -0
- data/data/vendored_gem_sigs/cgi/cgi_extras.rbs +34 -0
- data/data/vendored_gem_sigs/did_you_mean/did_you_mean_extras.rbs +34 -0
- data/data/vendored_gem_sigs/idn-ruby/idn.rbs +54 -0
- data/data/vendored_gem_sigs/mysql2/client.rbs +55 -0
- data/data/vendored_gem_sigs/mysql2/error.rbs +5 -0
- data/data/vendored_gem_sigs/mysql2/result.rbs +31 -0
- data/data/vendored_gem_sigs/mysql2/statement.rbs +5 -0
- data/data/vendored_gem_sigs/nokogiri/nokogiri.rbs +2332 -0
- data/data/vendored_gem_sigs/nokogiri/nokogiri_html5.rbs +47 -0
- data/data/vendored_gem_sigs/pg/pg.rbs +212 -0
- data/data/vendored_gem_sigs/prism/prism_supplement.rbs +44 -0
- data/data/vendored_gem_sigs/redis/errors.rbs +50 -0
- data/data/vendored_gem_sigs/redis/future.rbs +5 -0
- data/data/vendored_gem_sigs/redis/redis.rbs +348 -0
- data/data/vendored_gem_sigs/redis/redis_extras.rbs +130 -0
- data/data/vendored_gem_sigs/rubygems/rubygems_extras.rbs +226 -0
- data/lib/rigor/analysis/check_rules/ivar_write_collector.rb +3 -23
- data/lib/rigor/analysis/check_rules/rule_walk.rb +3 -21
- data/lib/rigor/analysis/check_rules/self_closedness_scanner.rb +24 -15
- data/lib/rigor/analysis/check_rules.rb +492 -71
- data/lib/rigor/analysis/dependency_source_inference/index.rb +4 -7
- data/lib/rigor/analysis/dependency_source_inference/walker.rb +2 -18
- data/lib/rigor/analysis/dependency_source_inference.rb +3 -12
- data/lib/rigor/analysis/fact_store.rb +5 -4
- data/lib/rigor/analysis/rule_catalog.rb +153 -6
- data/lib/rigor/analysis/runner/diagnostic_aggregator.rb +17 -17
- data/lib/rigor/analysis/runner/project_pre_passes.rb +9 -8
- data/lib/rigor/analysis/runner.rb +17 -6
- data/lib/rigor/analysis/self_call_resolution_recorder.rb +3 -4
- data/lib/rigor/analysis/worker_session.rb +10 -14
- data/lib/rigor/builtins/predefined_constant_refinements.rb +151 -0
- data/lib/rigor/cache/store.rb +5 -3
- data/lib/rigor/cli/annotate_command.rb +28 -7
- data/lib/rigor/cli/baseline_command.rb +4 -3
- data/lib/rigor/cli/check_command.rb +138 -16
- data/lib/rigor/cli/coverage_command.rb +138 -31
- data/lib/rigor/cli/coverage_mutation.rb +149 -0
- data/lib/rigor/cli/coverage_scan.rb +57 -0
- data/lib/rigor/cli/explain_command.rb +2 -0
- data/lib/rigor/cli/fused_protection_renderer.rb +67 -0
- data/lib/rigor/cli/fused_protection_report.rb +76 -0
- data/lib/rigor/cli/lsp_command.rb +3 -7
- data/lib/rigor/cli/mutation_protection_renderer.rb +63 -0
- data/lib/rigor/cli/mutation_protection_report.rb +73 -0
- data/lib/rigor/cli/options.rb +9 -0
- data/lib/rigor/cli/plugins_command.rb +2 -1
- data/lib/rigor/cli/protection_renderer.rb +63 -0
- data/lib/rigor/cli/protection_report.rb +68 -0
- data/lib/rigor/cli/sig_gen_command.rb +2 -1
- data/lib/rigor/cli/trace_command.rb +2 -1
- data/lib/rigor/cli/triage_command.rb +2 -1
- data/lib/rigor/cli/type_of_command.rb +1 -1
- data/lib/rigor/cli/type_scan_command.rb +2 -1
- data/lib/rigor/cli.rb +3 -2
- data/lib/rigor/config_audit.rb +152 -0
- data/lib/rigor/configuration/dependencies.rb +2 -4
- data/lib/rigor/configuration.rb +57 -7
- data/lib/rigor/environment/bundle_sig_discovery.rb +61 -13
- data/lib/rigor/environment/class_registry.rb +4 -3
- data/lib/rigor/environment/constant_type_cache_holder.rb +43 -0
- data/lib/rigor/environment/lockfile_resolver.rb +1 -1
- data/lib/rigor/environment/rbs_collection_discovery.rb +1 -2
- data/lib/rigor/environment/rbs_coverage_report.rb +2 -1
- data/lib/rigor/environment/rbs_loader.rb +76 -5
- data/lib/rigor/environment.rb +66 -8
- data/lib/rigor/flow_contribution/fact.rb +1 -1
- data/lib/rigor/flow_contribution.rb +3 -5
- data/lib/rigor/inference/acceptance.rb +17 -9
- data/lib/rigor/inference/block_parameter_binder.rb +2 -3
- data/lib/rigor/inference/builtins/comparable_catalog.rb +2 -2
- data/lib/rigor/inference/builtins/enumerable_catalog.rb +2 -2
- data/lib/rigor/inference/builtins/method_catalog.rb +19 -0
- data/lib/rigor/inference/builtins/string_catalog.rb +9 -1
- data/lib/rigor/inference/expression_typer.rb +20 -28
- data/lib/rigor/inference/hkt_body.rb +8 -11
- data/lib/rigor/inference/hkt_body_parser.rb +10 -12
- data/lib/rigor/inference/hkt_registry.rb +10 -11
- data/lib/rigor/inference/method_dispatcher/call_context.rb +1 -4
- data/lib/rigor/inference/method_dispatcher/constant_folding.rb +169 -24
- data/lib/rigor/inference/method_dispatcher/data_folding.rb +9 -73
- data/lib/rigor/inference/method_dispatcher/file_folding.rb +6 -7
- data/lib/rigor/inference/method_dispatcher/iterator_dispatch.rb +10 -16
- data/lib/rigor/inference/method_dispatcher/kernel_dispatch.rb +25 -13
- data/lib/rigor/inference/method_dispatcher/member_shape_projection.rb +93 -0
- data/lib/rigor/inference/method_dispatcher/overload_selector.rb +1 -3
- data/lib/rigor/inference/method_dispatcher/rbs_dispatch.rb +24 -22
- data/lib/rigor/inference/method_dispatcher/shape_dispatch.rb +90 -15
- data/lib/rigor/inference/method_dispatcher/struct_folding.rb +303 -0
- data/lib/rigor/inference/method_dispatcher.rb +40 -48
- data/lib/rigor/inference/mutation_widening.rb +5 -11
- data/lib/rigor/inference/narrowing.rb +14 -16
- data/lib/rigor/inference/parameter_inference_collector.rb +367 -0
- data/lib/rigor/inference/project_patched_methods.rb +4 -7
- data/lib/rigor/inference/project_patched_scanner.rb +2 -13
- data/lib/rigor/inference/protection_scanner.rb +86 -0
- data/lib/rigor/inference/scope_indexer.rb +129 -55
- data/lib/rigor/inference/statement_evaluator.rb +271 -114
- data/lib/rigor/inference/struct_fold_safety.rb +181 -0
- data/lib/rigor/inference/synthetic_method.rb +7 -7
- data/lib/rigor/language_server/completion_provider.rb +6 -12
- data/lib/rigor/language_server/diagnostic_publisher.rb +4 -4
- data/lib/rigor/language_server/document_symbol_provider.rb +3 -3
- data/lib/rigor/language_server/hover_provider.rb +2 -3
- data/lib/rigor/language_server/hover_renderer.rb +2 -11
- data/lib/rigor/language_server/server.rb +9 -17
- data/lib/rigor/language_server.rb +4 -5
- data/lib/rigor/plugin/base.rb +10 -8
- data/lib/rigor/plugin/macro/block_as_method.rb +3 -4
- data/lib/rigor/plugin/macro/heredoc_template.rb +4 -7
- data/lib/rigor/plugin/macro/trait_registry.rb +3 -6
- data/lib/rigor/plugin/macro.rb +4 -5
- data/lib/rigor/plugin/manifest.rb +45 -66
- data/lib/rigor/plugin/registry.rb +6 -7
- data/lib/rigor/plugin/type_node_resolver.rb +6 -8
- data/lib/rigor/protection/diagnostic_oracle.rb +51 -0
- data/lib/rigor/protection/mutation_scanner.rb +180 -0
- data/lib/rigor/protection/mutator.rb +267 -0
- data/lib/rigor/protection/test_suite_oracle.rb +68 -0
- data/lib/rigor/rbs_extended.rb +24 -36
- data/lib/rigor/reflection.rb +4 -7
- data/lib/rigor/scope/discovery_index.rb +14 -2
- data/lib/rigor/scope.rb +54 -11
- data/lib/rigor/sig_gen/observed_call.rb +3 -3
- data/lib/rigor/sig_gen/writer.rb +40 -2
- data/lib/rigor/signature_path_audit.rb +92 -0
- data/lib/rigor/source/constant_path.rb +62 -0
- data/lib/rigor/source.rb +1 -0
- data/lib/rigor/type/bound_method.rb +2 -11
- data/lib/rigor/type/combinator.rb +16 -3
- data/lib/rigor/type/constant.rb +2 -11
- data/lib/rigor/type/data_class.rb +2 -11
- data/lib/rigor/type/data_instance.rb +2 -11
- data/lib/rigor/type/hash_shape.rb +2 -11
- data/lib/rigor/type/integer_range.rb +2 -11
- data/lib/rigor/type/intersection.rb +2 -11
- data/lib/rigor/type/nominal.rb +2 -11
- data/lib/rigor/type/plain_lattice.rb +37 -0
- data/lib/rigor/type/refined.rb +72 -13
- data/lib/rigor/type/singleton.rb +2 -11
- data/lib/rigor/type/struct_class.rb +75 -0
- data/lib/rigor/type/struct_instance.rb +93 -0
- data/lib/rigor/type/tuple.rb +5 -15
- data/lib/rigor/type.rb +2 -0
- data/lib/rigor/version.rb +1 -1
- data/plugins/rigor-actioncable/lib/rigor/plugin/actioncable/channel_discoverer.rb +1 -1
- data/plugins/rigor-actioncable/lib/rigor/plugin/actioncable/channel_index.rb +3 -3
- data/plugins/rigor-actioncable/lib/rigor/plugin/actioncable.rb +3 -3
- data/plugins/rigor-actionmailer/lib/rigor/plugin/actionmailer/mailer_discoverer.rb +5 -13
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/analyzer.rb +11 -17
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack.rb +7 -10
- data/plugins/rigor-activejob/lib/rigor/plugin/activejob/job_index.rb +3 -2
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/model_discoverer.rb +4 -4
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord.rb +6 -8
- data/plugins/rigor-activestorage/lib/rigor/plugin/activestorage/analyzer.rb +5 -7
- data/plugins/rigor-activestorage/lib/rigor/plugin/activestorage.rb +1 -2
- data/plugins/rigor-devise/lib/rigor/plugin/devise.rb +9 -11
- data/plugins/rigor-dry-struct/lib/rigor/plugin/dry_struct.rb +8 -9
- data/plugins/rigor-dry-types/lib/rigor/plugin/dry_types.rb +13 -12
- data/plugins/rigor-dry-validation/lib/rigor/plugin/dry_validation.rb +3 -4
- data/plugins/rigor-factorybot/lib/rigor/plugin/factorybot/analyzer.rb +8 -8
- data/plugins/rigor-factorybot/lib/rigor/plugin/factorybot/factory_discoverer.rb +9 -11
- data/plugins/rigor-factorybot/lib/rigor/plugin/factorybot/factory_index.rb +7 -8
- data/plugins/rigor-factorybot/lib/rigor/plugin/factorybot.rb +7 -9
- data/plugins/rigor-graphql/lib/rigor/plugin/graphql/type_scanner.rb +12 -13
- data/plugins/rigor-graphql/lib/rigor/plugin/graphql.rb +15 -23
- data/plugins/rigor-mangrove/lib/rigor/plugin/mangrove.rb +3 -3
- data/plugins/rigor-minitest/lib/rigor/plugin/minitest.rb +3 -3
- data/plugins/rigor-rails-i18n/lib/rigor/plugin/rails_i18n/analyzer.rb +2 -4
- data/plugins/rigor-rails-i18n/lib/rigor/plugin/rails_i18n/locale_loader.rb +27 -11
- data/plugins/rigor-rails-i18n/lib/rigor/plugin/rails_i18n.rb +1 -1
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/devise_routes.rb +4 -6
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/routes_parser.rb +12 -18
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes.rb +5 -5
- data/plugins/rigor-rspec/lib/rigor/plugin/rspec/let_scope_index.rb +3 -4
- data/plugins/rigor-rspec/lib/rigor/plugin/rspec/let_type_resolver.rb +1 -1
- data/plugins/rigor-rspec/lib/rigor/plugin/rspec/matcher_analyzer.rb +1 -1
- data/plugins/rigor-rspec/lib/rigor/plugin/rspec.rb +19 -14
- data/plugins/rigor-shoulda-matchers/lib/rigor/plugin/shoulda_matchers/analyzer.rb +0 -1
- data/plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq/worker_index.rb +5 -4
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/assertion_recognizer.rb +2 -3
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/method_signature.rb +7 -11
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/sig_parser.rb +4 -5
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/sigil_detector.rb +6 -9
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/type_translator.rb +5 -15
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet.rb +28 -41
- data/sig/rigor/scope.rbs +9 -1
- data/sig/rigor/type.rbs +36 -1
- metadata +49 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 11db7e9c0140dbb303b0644587e80cc683e5a9ee32791c007234dd12e37ecb21
|
|
4
|
+
data.tar.gz: 375cbd7387b2f8cac6d668db993b34e627d19ebacf74e5092c17c8717191b401
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 42a9121e67acbf27afc287c586c7b3cd9fbd271a0de9e0a7f28a1e57703ffb578572213402e37f57b7327572c944f799a186ccc0a13dbe1fba49eca02c39df6b
|
|
7
|
+
data.tar.gz: d5b333586309d0b25b17880608797e005a2083bad60d91e2a20163265cb31b948a08363ef4f37920862dc7ee5da3fb0cd1d7c67a7af6f64b1bc37d8721469f6c
|
data/README.md
CHANGED
|
@@ -204,12 +204,15 @@ the reference companions.
|
|
|
204
204
|
|
|
205
205
|
## Status
|
|
206
206
|
|
|
207
|
-
Current release: **`v0.
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
207
|
+
Current release: **`v0.2.0`** (2026-06-17) — the first
|
|
208
|
+
publicly-announced (general / evaluation) release. It publishes an
|
|
209
|
+
enumerated [compatibility surface](docs/compatibility.md) as a
|
|
210
|
+
minor-non-break trial, rehearsing the contract that hard-freezes at
|
|
211
|
+
`v1.0.0`. Rigor analyses real Ruby today: it has been hardened against
|
|
212
|
+
Mastodon, Redmine, and GitLab FOSS, and the deliberately conservative
|
|
213
|
+
rule catalogue grows only as fast as the zero-false-positive bar
|
|
214
|
+
allows. Release history: [`CHANGELOG.md`](CHANGELOG.md) ·
|
|
215
|
+
forward-looking commitments:
|
|
213
216
|
[Roadmap](https://rigor.typedduck.fail/reference/roadmap/).
|
|
214
217
|
|
|
215
218
|
## Contributing
|
|
@@ -221,3 +224,35 @@ contributors should read.
|
|
|
221
224
|
## License
|
|
222
225
|
|
|
223
226
|
Mozilla Public License Version 2.0. See [`LICENSE`](LICENSE).
|
|
227
|
+
|
|
228
|
+
## Sponsors
|
|
229
|
+
|
|
230
|
+
Rigor is built and maintained by one person, who has spent the better
|
|
231
|
+
part of the last month — nearly every spare hour of personal time — on
|
|
232
|
+
this project. Sustainable development depends on sustainable funding.
|
|
233
|
+
|
|
234
|
+
**The current monthly budget is well short of the $200 minimum needed
|
|
235
|
+
to keep this pace going; $600 or more would let me work on it
|
|
236
|
+
properly.** If Rigor is saving you time or catching real bugs, please
|
|
237
|
+
consider contributing:
|
|
238
|
+
|
|
239
|
+
- **GitHub Sponsors**: [github.com/sponsors/zonuexe](https://github.com/sponsors/zonuexe)
|
|
240
|
+
- **FANBOX** (credit-card / PayPal): [tadsan.fanbox.cc](https://tadsan.fanbox.cc/)
|
|
241
|
+
|
|
242
|
+
**For individuals** — any amount is welcome and genuinely appreciated.
|
|
243
|
+
Even a small recurring pledge (think of it as buying me one coffee a
|
|
244
|
+
month) makes a difference when it adds up across many users.
|
|
245
|
+
|
|
246
|
+
**For companies** using Rigor in production — please consider a
|
|
247
|
+
contribution that reflects the engineering hours Rigor is saving you.
|
|
248
|
+
A modest business sponsorship goes a long way toward keeping this
|
|
249
|
+
project alive and actively maintained.
|
|
250
|
+
|
|
251
|
+
**Sponsors at $50/month or more** are listed here with a banner.
|
|
252
|
+
*(This threshold will likely move to $100/month at some point — early
|
|
253
|
+
sponsors lock in the lower bar.)*
|
|
254
|
+
|
|
255
|
+
To the sponsors who have already contributed: **thank you sincerely.**
|
|
256
|
+
Your support makes the difference between a project that stalls and
|
|
257
|
+
one that ships.
|
|
258
|
+
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Rigor core overlay — supplemental core signatures.
|
|
2
|
+
#
|
|
3
|
+
# This directory holds Rigor-owned reopenings of Ruby core classes that
|
|
4
|
+
# add methods upstream `ruby/rbs` does not declare on a class but which
|
|
5
|
+
# every concrete value of that class answers at runtime. It is loaded
|
|
6
|
+
# LAST into the RBS environment (after core + stdlib + vendored gem
|
|
7
|
+
# sigs), so an upstream declaration always wins on conflict — these
|
|
8
|
+
# entries only fill genuine holes.
|
|
9
|
+
#
|
|
10
|
+
# Provenance: hand-authored against the documented CRuby behaviour, not
|
|
11
|
+
# extracted. Keep each addition justified by an observed false positive.
|
|
12
|
+
#
|
|
13
|
+
# --- Numeric coercion methods ---
|
|
14
|
+
#
|
|
15
|
+
# `ruby/rbs`'s `Numeric` declares only `to_c` and `to_int`; the three
|
|
16
|
+
# value-coercion selectors `to_f` / `to_i` / `to_r` are declared solely
|
|
17
|
+
# on the concrete subclasses (`Integer`, `Float`, `Rational`, `Complex`).
|
|
18
|
+
# But Rigor routinely *widens* an arithmetic chain to the abstract
|
|
19
|
+
# `Numeric` nominal — `Complex#abs -> Numeric`, or an overload join over
|
|
20
|
+
# `Integer | Float` — and the instant a widened value is asked for
|
|
21
|
+
# `.to_f`, dispatch misses and `call.undefined-method` fires on plain,
|
|
22
|
+
# correct arithmetic (observed four times across actionview's
|
|
23
|
+
# `date_helper`: `(distance_in_minutes.to_f / 60.0)`).
|
|
24
|
+
#
|
|
25
|
+
# Every concrete `Numeric` responds to all three, so the widening must
|
|
26
|
+
# not strip the capability. Returns mirror the concrete subclass
|
|
27
|
+
# signatures. `to_int` is already upstream and intentionally not
|
|
28
|
+
# duplicated here.
|
|
29
|
+
class Numeric
|
|
30
|
+
def to_f: () -> Float
|
|
31
|
+
def to_i: () -> Integer
|
|
32
|
+
def to_r: () -> Rational
|
|
33
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Rigor core overlay — supplemental core signatures.
|
|
2
|
+
#
|
|
3
|
+
# --- Pathname#expand_path ---
|
|
4
|
+
#
|
|
5
|
+
# Upstream `ruby/rbs` declares `Pathname#expand_path` as:
|
|
6
|
+
#
|
|
7
|
+
# def expand_path: (?String dir) -> Pathname
|
|
8
|
+
#
|
|
9
|
+
# But `Pathname#expand_path` delegates to `File.expand_path`, whose `dir`
|
|
10
|
+
# parameter is typed as `path` (= `string | _ToPath`). Passing a `Pathname`
|
|
11
|
+
# as the base directory is the idiomatic Bundler pattern:
|
|
12
|
+
#
|
|
13
|
+
# Pathname.new(path).expand_path(Bundler.root) # root → Pathname
|
|
14
|
+
#
|
|
15
|
+
# With the ADR-57 self-call adoption gate now resolving `Bundler.root` to
|
|
16
|
+
# `Pathname`, all five call sites in bundler.rb / bundler/source/git.rb fire
|
|
17
|
+
# `argument type mismatch at parameter 'dir'`. The upstream sig is simply
|
|
18
|
+
# under-typed: the runtime accepts any `to_path`-bearing object.
|
|
19
|
+
#
|
|
20
|
+
# The overlay widens `dir` to `String | Pathname`, matching the runtime
|
|
21
|
+
# delegation and the `File.expand_path` `path` alias used elsewhere in RBS.
|
|
22
|
+
class Pathname
|
|
23
|
+
def expand_path: (?String | Pathname dir) -> Pathname
|
|
24
|
+
| ...
|
|
25
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Rigor core overlay — supplemental core signatures.
|
|
2
|
+
#
|
|
3
|
+
# --- StringScanner#[] ---
|
|
4
|
+
#
|
|
5
|
+
# The pinned `rbs` gem (4.0.2) declares `StringScanner#[]` as only:
|
|
6
|
+
#
|
|
7
|
+
# def []: (Integer) -> String?
|
|
8
|
+
#
|
|
9
|
+
# But `StringScanner#[]` also accepts a capture-group *name* — a `String`
|
|
10
|
+
# or `Symbol` — and returns the named capture from the most recent match.
|
|
11
|
+
# Named-capture access (`scanner[:key]`) is the idiomatic form when the
|
|
12
|
+
# scan pattern uses named groups:
|
|
13
|
+
#
|
|
14
|
+
# scanner.skip(/(?<key>\w+)=/)
|
|
15
|
+
# scanner[:key] # => the captured String, or nil
|
|
16
|
+
#
|
|
17
|
+
# Newer `ruby/rbs` already widens the signature to
|
|
18
|
+
# `(Integer | String | Symbol) -> String?`; the pinned 4.0.2 gem lags.
|
|
19
|
+
# Without the wider overload, a named-capture access such as Mastodon's
|
|
20
|
+
# `scanner[:key]` false-fires `call.argument-type-mismatch` (the lone
|
|
21
|
+
# overload rejects a `Symbol`).
|
|
22
|
+
#
|
|
23
|
+
# The overlay supplies the runtime-accurate overload; drop it once the
|
|
24
|
+
# pinned `rbs` gem carries the wider signature.
|
|
25
|
+
class StringScanner
|
|
26
|
+
def []: (Integer | String | Symbol) -> String?
|
|
27
|
+
| ...
|
|
28
|
+
end
|
|
@@ -0,0 +1,473 @@
|
|
|
1
|
+
# ActiveSupport core_ext — Gemfile.lock-gated bundled RBS overlay (ADR-72).
|
|
2
|
+
#
|
|
3
|
+
# Rigor loads this overlay AUTOMATICALLY when `activesupport` is locked
|
|
4
|
+
# in the project's Gemfile.lock but ships no RBS through any resolution
|
|
5
|
+
# path (the `:missing` coverage class — no `rbs collection`, no bundled
|
|
6
|
+
# `sig/`, not a default library). It turns the systematic false
|
|
7
|
+
# `call.undefined-method` on Rails core-ext call sites (`3.minutes`,
|
|
8
|
+
# `"x".underscore`, `hash.symbolize_keys`, …) into a no-op, while a
|
|
9
|
+
# project WITHOUT activesupport still sees the genuine diagnostic.
|
|
10
|
+
#
|
|
11
|
+
# This is the auto-applied twin of the opt-in, hand-curated
|
|
12
|
+
# `rigor-activesupport-core-ext` plugin (`plugins/rigor-activesupport-
|
|
13
|
+
# core-ext/sig/active_support/core_ext.rbs`). The two files carry the
|
|
14
|
+
# same surface on purpose; the plugin remains the authoring home and
|
|
15
|
+
# may grow more exhaustive, and when its plugin id is loaded this
|
|
16
|
+
# overlay stands down (Environment.for_project) to avoid a duplicate
|
|
17
|
+
# declaration. Keep the two in sync when extending coverage.
|
|
18
|
+
#
|
|
19
|
+
# Scope: the most-frequently-flagged ActiveSupport extension methods
|
|
20
|
+
# from a four-project Rails survey (Redmine, Discourse, Mastodon,
|
|
21
|
+
# GitLab FOSS — see `docs/notes/20260515-real-world-rails-survey.md`),
|
|
22
|
+
# roughly the top ~40 selectors by `call.undefined-method` frequency.
|
|
23
|
+
# Not exhaustive.
|
|
24
|
+
|
|
25
|
+
# ---------------------------------------------------------------
|
|
26
|
+
# Object — universal predicates and helpers
|
|
27
|
+
# ---------------------------------------------------------------
|
|
28
|
+
|
|
29
|
+
class Object
|
|
30
|
+
# @return [bool]
|
|
31
|
+
def blank?: () -> bool
|
|
32
|
+
|
|
33
|
+
# @return [bool]
|
|
34
|
+
def present?: () -> bool
|
|
35
|
+
|
|
36
|
+
# @return [self?]
|
|
37
|
+
def presence: () -> self?
|
|
38
|
+
|
|
39
|
+
# `active_support/core_ext/object/json` monkey-patches
|
|
40
|
+
# `as_json` onto Object (default returns the object's
|
|
41
|
+
# `instance_values` hash) plus per-class overrides on
|
|
42
|
+
# NilClass / TrueClass / FalseClass / Numeric / String /
|
|
43
|
+
# Symbol / Time / Date / Array / Hash / Range / Regexp /
|
|
44
|
+
# Struct / Enumerable. Most call-site code uses the
|
|
45
|
+
# universal `obj.as_json` shape so a single Object row
|
|
46
|
+
# restores type coverage at the Mastodon-derived
|
|
47
|
+
# `as_json` call sites (`fan_out_on_write_service.rb`,
|
|
48
|
+
# `push_update_worker.rb`, `media_component_helper.rb`).
|
|
49
|
+
# `options` is the standard `only:` / `except:` / `methods:`
|
|
50
|
+
# / `include:` hash — left as untyped because the surface
|
|
51
|
+
# is large and per-call-site precision is rarely useful.
|
|
52
|
+
def as_json: (?untyped options) -> untyped
|
|
53
|
+
|
|
54
|
+
# `try` swallows NoMethodError; declared return is `untyped`
|
|
55
|
+
# because the called method's signature is not known to RBS
|
|
56
|
+
# at this call site.
|
|
57
|
+
def try: (Symbol | String) -> untyped
|
|
58
|
+
| (Symbol | String, *untyped) -> untyped
|
|
59
|
+
| (Symbol | String, *untyped) { (?) -> untyped } -> untyped
|
|
60
|
+
|
|
61
|
+
def try!: (Symbol | String) -> untyped
|
|
62
|
+
| (Symbol | String, *untyped) -> untyped
|
|
63
|
+
| (Symbol | String, *untyped) { (?) -> untyped } -> untyped
|
|
64
|
+
|
|
65
|
+
# `acts_like?(:string)` / `acts_like?(:date)` / `acts_like?(:time)`
|
|
66
|
+
# is ActiveSupport's "duck-typing helper" predicate.
|
|
67
|
+
def acts_like?: (Symbol | String) -> bool
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# `nil.blank?` / `nil.present?` / `nil.try` are the most frequent
|
|
71
|
+
# call sites the survey turned up.
|
|
72
|
+
class NilClass
|
|
73
|
+
def blank?: () -> true
|
|
74
|
+
def present?: () -> false
|
|
75
|
+
def presence: () -> nil
|
|
76
|
+
def try: (*untyped) -> nil
|
|
77
|
+
def try!: (*untyped) -> nil
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
class TrueClass
|
|
81
|
+
def blank?: () -> false
|
|
82
|
+
def present?: () -> true
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
class FalseClass
|
|
86
|
+
def blank?: () -> true
|
|
87
|
+
def present?: () -> false
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# ---------------------------------------------------------------
|
|
91
|
+
# String — ActiveSupport `core_ext/string/*`
|
|
92
|
+
# ---------------------------------------------------------------
|
|
93
|
+
|
|
94
|
+
class String
|
|
95
|
+
# `core_ext/string/inflections`
|
|
96
|
+
def underscore: () -> String
|
|
97
|
+
def camelize: (?Symbol upper_case_first) -> String
|
|
98
|
+
def camelcase: (?Symbol upper_case_first) -> String
|
|
99
|
+
def classify: () -> String
|
|
100
|
+
def constantize: () -> untyped
|
|
101
|
+
def safe_constantize: () -> untyped
|
|
102
|
+
def demodulize: () -> String
|
|
103
|
+
def deconstantize: () -> String
|
|
104
|
+
def titleize: () -> String
|
|
105
|
+
def parameterize: (?separator: String, ?preserve_case: bool, ?locale: Symbol?) -> String
|
|
106
|
+
def tableize: () -> String
|
|
107
|
+
def foreign_key: (?bool separate_class_name_and_id_with_underscore) -> String
|
|
108
|
+
def pluralize: (?Integer count, ?Symbol locale) -> String
|
|
109
|
+
def singularize: (?Symbol locale) -> String
|
|
110
|
+
def humanize: (?capitalize: bool, ?keep_id_suffix: bool) -> String
|
|
111
|
+
|
|
112
|
+
# `core_ext/string/filters`
|
|
113
|
+
def squish: () -> String
|
|
114
|
+
def squish!: () -> String
|
|
115
|
+
def truncate: (Integer truncate_at, ?omission: String, ?separator: String | Regexp | nil) -> String
|
|
116
|
+
def truncate_bytes: (Integer truncate_at, ?omission: String) -> String
|
|
117
|
+
def truncate_words: (Integer words_count, ?omission: String, ?separator: String | Regexp | nil) -> String
|
|
118
|
+
|
|
119
|
+
# `core_ext/string/output_safety` — `html_safe` returns an
|
|
120
|
+
# `ActiveSupport::SafeBuffer` (a String subclass). The closest
|
|
121
|
+
# RBS-canonical carrier is plain `String`; precision lost is the
|
|
122
|
+
# `html_safe?` predicate value.
|
|
123
|
+
def html_safe: () -> String
|
|
124
|
+
def html_safe?: () -> bool
|
|
125
|
+
|
|
126
|
+
# `core_ext/string/indent`
|
|
127
|
+
def indent: (Integer amount, ?String indent_string, ?bool indent_empty_lines) -> String
|
|
128
|
+
def indent!: (Integer amount, ?String indent_string, ?bool indent_empty_lines) -> String?
|
|
129
|
+
|
|
130
|
+
# `core_ext/string/starts_ends_with` — also covered by core
|
|
131
|
+
# `start_with?` / `end_with?`; these are the ActiveSupport aliases.
|
|
132
|
+
def starts_with?: (*String prefixes) -> bool
|
|
133
|
+
def ends_with?: (*String suffixes) -> bool
|
|
134
|
+
|
|
135
|
+
# `core_ext/string/conversions` — `to_time` / `to_date` /
|
|
136
|
+
# `to_datetime` return Time / Date / DateTime.
|
|
137
|
+
def to_time: (?Symbol form) -> Time?
|
|
138
|
+
def to_date: () -> Date?
|
|
139
|
+
def to_datetime: () -> DateTime
|
|
140
|
+
def to_hours: () -> Float
|
|
141
|
+
|
|
142
|
+
# `core_ext/string/access`
|
|
143
|
+
def at: (Integer | Range[Integer] | Regexp position) -> String?
|
|
144
|
+
def from: (Integer position) -> String
|
|
145
|
+
def to: (Integer position) -> String
|
|
146
|
+
def first: (?Integer limit) -> String
|
|
147
|
+
def last: (?Integer limit) -> String
|
|
148
|
+
|
|
149
|
+
# `core_ext/string/strip` — leading-blank strip with shared margin.
|
|
150
|
+
def strip_heredoc: () -> String
|
|
151
|
+
|
|
152
|
+
# `core_ext/string/multibyte`
|
|
153
|
+
def mb_chars: () -> untyped
|
|
154
|
+
|
|
155
|
+
# `core_ext/string/inquiry`
|
|
156
|
+
def inquiry: () -> untyped # ActiveSupport::StringInquirer
|
|
157
|
+
|
|
158
|
+
# `core_ext/string/exclude` (an ActiveSupport addition)
|
|
159
|
+
def exclude?: (String) -> bool
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
# ---------------------------------------------------------------
|
|
163
|
+
# Integer — `core_ext/integer/*`
|
|
164
|
+
# ---------------------------------------------------------------
|
|
165
|
+
|
|
166
|
+
class Integer
|
|
167
|
+
# `core_ext/numeric/time` — Duration multipliers.
|
|
168
|
+
def second: () -> untyped # ActiveSupport::Duration
|
|
169
|
+
def seconds: () -> untyped
|
|
170
|
+
def minute: () -> untyped
|
|
171
|
+
def minutes: () -> untyped
|
|
172
|
+
def hour: () -> untyped
|
|
173
|
+
def hours: () -> untyped
|
|
174
|
+
def day: () -> untyped
|
|
175
|
+
def days: () -> untyped
|
|
176
|
+
def week: () -> untyped
|
|
177
|
+
def weeks: () -> untyped
|
|
178
|
+
def fortnight: () -> untyped
|
|
179
|
+
def fortnights: () -> untyped
|
|
180
|
+
def month: () -> untyped
|
|
181
|
+
def months: () -> untyped
|
|
182
|
+
def year: () -> untyped
|
|
183
|
+
def years: () -> untyped
|
|
184
|
+
|
|
185
|
+
# `core_ext/numeric/bytes`
|
|
186
|
+
def byte: () -> Integer
|
|
187
|
+
def bytes: () -> Integer
|
|
188
|
+
def kilobyte: () -> Integer
|
|
189
|
+
def kilobytes: () -> Integer
|
|
190
|
+
def megabyte: () -> Integer
|
|
191
|
+
def megabytes: () -> Integer
|
|
192
|
+
def gigabyte: () -> Integer
|
|
193
|
+
def gigabytes: () -> Integer
|
|
194
|
+
def terabyte: () -> Integer
|
|
195
|
+
def terabytes: () -> Integer
|
|
196
|
+
def petabyte: () -> Integer
|
|
197
|
+
def petabytes: () -> Integer
|
|
198
|
+
def exabyte: () -> Integer
|
|
199
|
+
def exabytes: () -> Integer
|
|
200
|
+
|
|
201
|
+
# `core_ext/integer/multiple`
|
|
202
|
+
def multiple_of?: (Integer) -> bool
|
|
203
|
+
|
|
204
|
+
# `core_ext/integer/inflections`
|
|
205
|
+
def ordinal: () -> String
|
|
206
|
+
def ordinalize: () -> String
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
# ---------------------------------------------------------------
|
|
210
|
+
# Float — same Duration / Bytes pattern as Integer
|
|
211
|
+
# ---------------------------------------------------------------
|
|
212
|
+
|
|
213
|
+
class Float
|
|
214
|
+
def second: () -> untyped
|
|
215
|
+
def seconds: () -> untyped
|
|
216
|
+
def minute: () -> untyped
|
|
217
|
+
def minutes: () -> untyped
|
|
218
|
+
def hour: () -> untyped
|
|
219
|
+
def hours: () -> untyped
|
|
220
|
+
def day: () -> untyped
|
|
221
|
+
def days: () -> untyped
|
|
222
|
+
def week: () -> untyped
|
|
223
|
+
def weeks: () -> untyped
|
|
224
|
+
def month: () -> untyped
|
|
225
|
+
def months: () -> untyped
|
|
226
|
+
def year: () -> untyped
|
|
227
|
+
def years: () -> untyped
|
|
228
|
+
|
|
229
|
+
def byte: () -> Float
|
|
230
|
+
def bytes: () -> Float
|
|
231
|
+
def kilobyte: () -> Float
|
|
232
|
+
def kilobytes: () -> Float
|
|
233
|
+
def megabyte: () -> Float
|
|
234
|
+
def megabytes: () -> Float
|
|
235
|
+
def gigabyte: () -> Float
|
|
236
|
+
def gigabytes: () -> Float
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
# ---------------------------------------------------------------
|
|
240
|
+
# Time — singleton + instance extensions
|
|
241
|
+
# ---------------------------------------------------------------
|
|
242
|
+
|
|
243
|
+
class Time
|
|
244
|
+
def self.current: () -> Time
|
|
245
|
+
def self.zone: () -> untyped # ActiveSupport::TimeZone | nil
|
|
246
|
+
def self.zone=: (String | Symbol | untyped) -> untyped
|
|
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
|
|
252
|
+
|
|
253
|
+
# `core_ext/time/calculations`
|
|
254
|
+
def yesterday: () -> Time
|
|
255
|
+
def tomorrow: () -> Time
|
|
256
|
+
def beginning_of_day: () -> Time
|
|
257
|
+
def end_of_day: () -> Time
|
|
258
|
+
def beginning_of_hour: () -> Time
|
|
259
|
+
def end_of_hour: () -> Time
|
|
260
|
+
def beginning_of_minute: () -> Time
|
|
261
|
+
def end_of_minute: () -> Time
|
|
262
|
+
def beginning_of_week: (?Symbol start_day) -> Time
|
|
263
|
+
def end_of_week: (?Symbol start_day) -> Time
|
|
264
|
+
def beginning_of_month: () -> Time
|
|
265
|
+
def end_of_month: () -> Time
|
|
266
|
+
def beginning_of_year: () -> Time
|
|
267
|
+
def end_of_year: () -> Time
|
|
268
|
+
def ago: (Numeric seconds) -> Time
|
|
269
|
+
def since: (Numeric seconds) -> Time
|
|
270
|
+
def in: (Numeric seconds) -> Time
|
|
271
|
+
def change: (**untyped) -> Time
|
|
272
|
+
def at_beginning_of_day: () -> Time
|
|
273
|
+
def at_end_of_day: () -> Time
|
|
274
|
+
def at_beginning_of_week: () -> Time
|
|
275
|
+
def at_end_of_week: () -> Time
|
|
276
|
+
def at_midnight: () -> Time
|
|
277
|
+
def at_noon: () -> Time
|
|
278
|
+
def midday: () -> Time
|
|
279
|
+
def midnight: () -> Time
|
|
280
|
+
def noon: () -> Time
|
|
281
|
+
def utc?: () -> bool
|
|
282
|
+
def acts_like_time?: () -> true
|
|
283
|
+
end
|
|
284
|
+
|
|
285
|
+
# ---------------------------------------------------------------
|
|
286
|
+
# Date — `core_ext/date/*`
|
|
287
|
+
# ---------------------------------------------------------------
|
|
288
|
+
|
|
289
|
+
class Date
|
|
290
|
+
def self.current: () -> Date
|
|
291
|
+
def self.yesterday: () -> Date
|
|
292
|
+
def self.tomorrow: () -> Date
|
|
293
|
+
def self.beginning_of_week: () -> Date
|
|
294
|
+
def self.end_of_week: () -> Date
|
|
295
|
+
def self.beginning_of_month: () -> Date
|
|
296
|
+
def self.end_of_month: () -> Date
|
|
297
|
+
def self.beginning_of_year: () -> Date
|
|
298
|
+
def self.end_of_year: () -> Date
|
|
299
|
+
|
|
300
|
+
def yesterday: () -> Date
|
|
301
|
+
def tomorrow: () -> Date
|
|
302
|
+
def beginning_of_week: (?Symbol start_day) -> Date
|
|
303
|
+
def end_of_week: (?Symbol start_day) -> Date
|
|
304
|
+
def beginning_of_month: () -> Date
|
|
305
|
+
def end_of_month: () -> Date
|
|
306
|
+
def beginning_of_year: () -> Date
|
|
307
|
+
def end_of_year: () -> Date
|
|
308
|
+
def ago: (Numeric seconds) -> Time
|
|
309
|
+
def since: (Numeric seconds) -> Time
|
|
310
|
+
def acts_like_date?: () -> true
|
|
311
|
+
|
|
312
|
+
# `core_ext/date/calculations` — `Date#midnight` /
|
|
313
|
+
# `Date#at_midnight` are aliases for `beginning_of_day`.
|
|
314
|
+
# Rails' `beginning_of_day` on Date returns a Time at
|
|
315
|
+
# midnight of that day (not a Date). Mastodon's
|
|
316
|
+
# `Date.current.at_midnight` shape relies on this.
|
|
317
|
+
def beginning_of_day: () -> Time
|
|
318
|
+
def midnight: () -> Time
|
|
319
|
+
def at_midnight: () -> Time
|
|
320
|
+
def at_beginning_of_day: () -> Time
|
|
321
|
+
def end_of_day: () -> Time
|
|
322
|
+
def at_end_of_day: () -> Time
|
|
323
|
+
end
|
|
324
|
+
|
|
325
|
+
# ---------------------------------------------------------------
|
|
326
|
+
# Array — singleton wrapper + instance extensions
|
|
327
|
+
# ---------------------------------------------------------------
|
|
328
|
+
|
|
329
|
+
class Array[unchecked out Elem]
|
|
330
|
+
# `Array.wrap(x)` is the dominant Rails idiom: `nil → []`,
|
|
331
|
+
# `Array x → x`, `else → [x]`.
|
|
332
|
+
def self.wrap: (untyped) -> Array[untyped]
|
|
333
|
+
|
|
334
|
+
# `core_ext/array/access`
|
|
335
|
+
def from: (Integer position) -> Array[Elem]
|
|
336
|
+
def to: (Integer position) -> Array[Elem]
|
|
337
|
+
def second: () -> Elem?
|
|
338
|
+
def third: () -> Elem?
|
|
339
|
+
def fourth: () -> Elem?
|
|
340
|
+
def fifth: () -> Elem?
|
|
341
|
+
def forty_two: () -> Elem?
|
|
342
|
+
|
|
343
|
+
# `core_ext/array/grouping`
|
|
344
|
+
def in_groups_of: (Integer number, ?untyped fill_with) -> Array[Array[Elem]]
|
|
345
|
+
| (Integer number, ?untyped fill_with) { (Array[Elem]) -> void } -> Array[Elem]
|
|
346
|
+
def in_groups: (Integer number, ?untyped fill_with) -> Array[Array[Elem]]
|
|
347
|
+
| (Integer number, ?untyped fill_with) { (Array[Elem]) -> void } -> Array[Elem]
|
|
348
|
+
def split: (?untyped value) -> Array[Array[Elem]]
|
|
349
|
+
| () { (Elem) -> bool } -> Array[Array[Elem]]
|
|
350
|
+
|
|
351
|
+
# `core_ext/array/conversions`
|
|
352
|
+
def to_sentence: (?two_words_connector: String, ?last_word_connector: String, ?words_connector: String, ?locale: Symbol?) -> String
|
|
353
|
+
def to_formatted_s: (?Symbol format) -> String
|
|
354
|
+
def to_fs: (?Symbol format) -> String
|
|
355
|
+
def to_xml: (**untyped) -> String
|
|
356
|
+
|
|
357
|
+
# `core_ext/array/inquiry`
|
|
358
|
+
def inquiry: () -> untyped # ActiveSupport::ArrayInquirer
|
|
359
|
+
|
|
360
|
+
# `core_ext/array/extract`
|
|
361
|
+
def extract!: () { (Elem) -> bool } -> Array[Elem]
|
|
362
|
+
|
|
363
|
+
# `core_ext/object/blank` / `core_ext/enumerable` — both
|
|
364
|
+
# ActiveSupport additions, shipped on Array specifically.
|
|
365
|
+
def compact_blank: () -> Array[Elem]
|
|
366
|
+
def compact_blank!: () -> self
|
|
367
|
+
def exclude?: (Elem) -> bool
|
|
368
|
+
end
|
|
369
|
+
|
|
370
|
+
# ---------------------------------------------------------------
|
|
371
|
+
# Enumerable — `core_ext/enumerable`
|
|
372
|
+
# ---------------------------------------------------------------
|
|
373
|
+
|
|
374
|
+
module Enumerable[unchecked out Elem]
|
|
375
|
+
def index_by: () { (Elem) -> untyped } -> Hash[untyped, Elem]
|
|
376
|
+
def index_with: (?untyped default) { (Elem) -> untyped } -> Hash[Elem, untyped]
|
|
377
|
+
| (untyped default) -> Hash[Elem, untyped]
|
|
378
|
+
def exclude?: (Elem) -> bool
|
|
379
|
+
def including: (*Elem) -> Array[Elem]
|
|
380
|
+
def excluding: (*Elem) -> Array[Elem]
|
|
381
|
+
def without: (*Elem) -> Array[Elem]
|
|
382
|
+
def pluck: (Symbol | String) -> Array[untyped]
|
|
383
|
+
| (*Symbol | String) -> Array[Array[untyped]]
|
|
384
|
+
def pick: (Symbol | String) -> untyped
|
|
385
|
+
| (*Symbol | String) -> Array[untyped]?
|
|
386
|
+
def maximum: (Symbol | String) -> untyped
|
|
387
|
+
def minimum: (Symbol | String) -> untyped
|
|
388
|
+
def sole: () -> Elem
|
|
389
|
+
def compact_blank: () -> Array[Elem]
|
|
390
|
+
end
|
|
391
|
+
|
|
392
|
+
# ---------------------------------------------------------------
|
|
393
|
+
# Hash — `core_ext/hash/*`
|
|
394
|
+
# ---------------------------------------------------------------
|
|
395
|
+
|
|
396
|
+
class Hash[unchecked out K, unchecked out V]
|
|
397
|
+
# `core_ext/hash/keys`
|
|
398
|
+
def symbolize_keys: () -> Hash[Symbol, V]
|
|
399
|
+
def symbolize_keys!: () -> self
|
|
400
|
+
def deep_symbolize_keys: () -> Hash[untyped, untyped]
|
|
401
|
+
def deep_symbolize_keys!: () -> self
|
|
402
|
+
def stringify_keys: () -> Hash[String, V]
|
|
403
|
+
def stringify_keys!: () -> self
|
|
404
|
+
def deep_stringify_keys: () -> Hash[untyped, untyped]
|
|
405
|
+
def deep_stringify_keys!: () -> self
|
|
406
|
+
def assert_valid_keys: (*K | Array[K]) -> self
|
|
407
|
+
def deep_transform_keys: () { (K) -> K } -> Hash[K, untyped]
|
|
408
|
+
def deep_transform_keys!: () { (K) -> K } -> self
|
|
409
|
+
def deep_transform_values: () { (V) -> untyped } -> Hash[K, untyped]
|
|
410
|
+
def deep_transform_values!: () { (V) -> untyped } -> self
|
|
411
|
+
|
|
412
|
+
# `core_ext/hash/deep_dup`
|
|
413
|
+
def deep_dup: () -> Hash[K, V]
|
|
414
|
+
|
|
415
|
+
# `core_ext/hash/deep_merge`
|
|
416
|
+
def deep_merge: (Hash[K, V]) -> Hash[K, V]
|
|
417
|
+
| (Hash[K, V]) { (K, V, V) -> V } -> Hash[K, V]
|
|
418
|
+
def deep_merge!: (Hash[K, V]) -> self
|
|
419
|
+
| (Hash[K, V]) { (K, V, V) -> V } -> self
|
|
420
|
+
|
|
421
|
+
# `core_ext/hash/except` — `Hash#except` is in core RBS as of
|
|
422
|
+
# Ruby 3.0+; `except!` is ActiveSupport-only. ActiveSupport
|
|
423
|
+
# also aliases `Hash#without` to `Hash#except`, used by
|
|
424
|
+
# `Mastodon`-shaped `options.without('type').merge(...)` chains.
|
|
425
|
+
def except!: (*K) -> self
|
|
426
|
+
def without: (*K) -> Hash[K, V]
|
|
427
|
+
|
|
428
|
+
# `core_ext/hash/conversions`
|
|
429
|
+
def to_query: (?String namespace) -> String
|
|
430
|
+
def to_param: (?String namespace) -> String
|
|
431
|
+
def to_xml: (**untyped) -> String
|
|
432
|
+
|
|
433
|
+
# `core_ext/hash/indifferent_access`
|
|
434
|
+
def with_indifferent_access: () -> untyped
|
|
435
|
+
|
|
436
|
+
# `core_ext/hash/conversions`
|
|
437
|
+
def self.from_xml: (String, ?Symbol disallowed_types) -> Hash[String, untyped]
|
|
438
|
+
def self.from_trusted_xml: (String) -> Hash[String, untyped]
|
|
439
|
+
|
|
440
|
+
# `core_ext/object/blank` / `core_ext/hash`
|
|
441
|
+
def compact_blank: () -> Hash[K, V]
|
|
442
|
+
def compact_blank!: () -> self
|
|
443
|
+
|
|
444
|
+
# `core_ext/hash/reverse_merge`
|
|
445
|
+
def reverse_merge: (Hash[K, V]) -> Hash[K, V]
|
|
446
|
+
def reverse_merge!: (Hash[K, V]) -> self
|
|
447
|
+
|
|
448
|
+
# `core_ext/hash/slice` — `Hash#except` is in core RBS (Ruby 3.0+);
|
|
449
|
+
# `Hash#slice` is in core RBS (Ruby 2.5+); the bang variants are
|
|
450
|
+
# ActiveSupport-only.
|
|
451
|
+
def slice!: (*K) -> Hash[K, V]
|
|
452
|
+
end
|
|
453
|
+
|
|
454
|
+
# ---------------------------------------------------------------
|
|
455
|
+
# DateTime — `core_ext/date_time/*`
|
|
456
|
+
# ---------------------------------------------------------------
|
|
457
|
+
|
|
458
|
+
class DateTime
|
|
459
|
+
def utc: () -> Time
|
|
460
|
+
def to_time: () -> Time
|
|
461
|
+
def in_time_zone: (?String | Symbol zone) -> untyped
|
|
462
|
+
def yesterday: () -> DateTime
|
|
463
|
+
def tomorrow: () -> DateTime
|
|
464
|
+
def ago: (Numeric seconds) -> DateTime
|
|
465
|
+
def since: (Numeric seconds) -> DateTime
|
|
466
|
+
def beginning_of_day: () -> DateTime
|
|
467
|
+
def end_of_day: () -> DateTime
|
|
468
|
+
def beginning_of_hour: () -> DateTime
|
|
469
|
+
def end_of_hour: () -> DateTime
|
|
470
|
+
def beginning_of_minute: () -> DateTime
|
|
471
|
+
def end_of_minute: () -> DateTime
|
|
472
|
+
def acts_like_time?: () -> true
|
|
473
|
+
end
|