rigortype 0.2.0 → 0.2.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 +82 -20
- 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/docs/handbook/01-getting-started.md +311 -0
- data/docs/handbook/02-everyday-types.md +337 -0
- data/docs/handbook/03-narrowing.md +359 -0
- data/docs/handbook/04-tuples-and-shapes.md +321 -0
- data/docs/handbook/05-methods-and-blocks.md +339 -0
- data/docs/handbook/06-classes.md +305 -0
- data/docs/handbook/07-rbs-and-extended.md +427 -0
- data/docs/handbook/08-understanding-errors.md +373 -0
- data/docs/handbook/09-plugins.md +241 -0
- data/docs/handbook/10-sorbet.md +347 -0
- data/docs/handbook/11-sig-gen.md +312 -0
- data/docs/handbook/12-lightweight-hkt.md +333 -0
- data/docs/handbook/README.md +275 -0
- data/docs/handbook/appendix-elixir.md +370 -0
- data/docs/handbook/appendix-go.md +399 -0
- data/docs/handbook/appendix-java-csharp.md +470 -0
- data/docs/handbook/appendix-liskov.md +580 -0
- data/docs/handbook/appendix-mypy.md +370 -0
- data/docs/handbook/appendix-phpstan.md +338 -0
- data/docs/handbook/appendix-protocols-and-structural-typing.md +292 -0
- data/docs/handbook/appendix-rust.md +446 -0
- data/docs/handbook/appendix-steep.md +336 -0
- data/docs/handbook/appendix-type-theory.md +1662 -0
- data/docs/handbook/appendix-typeprof.md +416 -0
- data/docs/handbook/appendix-typescript.md +332 -0
- data/docs/install.md +189 -0
- data/docs/llms.txt +72 -0
- data/docs/manual/01-installation.md +342 -0
- data/docs/manual/02-cli-reference.md +557 -0
- data/docs/manual/03-configuration.md +152 -0
- data/docs/manual/04-diagnostics.md +206 -0
- data/docs/manual/05-inspecting-types.md +109 -0
- data/docs/manual/06-baseline.md +104 -0
- data/docs/manual/07-plugins.md +92 -0
- data/docs/manual/08-skills.md +143 -0
- data/docs/manual/09-editor-integration.md +245 -0
- data/docs/manual/10-mcp-server.md +532 -0
- data/docs/manual/11-ci.md +274 -0
- data/docs/manual/12-caching.md +116 -0
- data/docs/manual/13-troubleshooting.md +120 -0
- data/docs/manual/14-rails-quickstart.md +332 -0
- data/docs/manual/15-type-protection-coverage.md +204 -0
- data/docs/manual/16-rbs-extended-annotations.md +190 -0
- data/docs/manual/17-driving-improvement.md +160 -0
- data/docs/manual/README.md +87 -0
- data/docs/manual/ci-templates/README.md +58 -0
- data/docs/manual/plugins/README.md +86 -0
- data/docs/manual/plugins/rigor-actioncable.md +78 -0
- data/docs/manual/plugins/rigor-actionmailer.md +74 -0
- data/docs/manual/plugins/rigor-actionpack.md +80 -0
- data/docs/manual/plugins/rigor-activejob.md +58 -0
- data/docs/manual/plugins/rigor-activerecord.md +102 -0
- data/docs/manual/plugins/rigor-activestorage.md +74 -0
- data/docs/manual/plugins/rigor-activesupport-core-ext.md +86 -0
- data/docs/manual/plugins/rigor-devise.md +70 -0
- data/docs/manual/plugins/rigor-dry-schema.md +56 -0
- data/docs/manual/plugins/rigor-dry-struct.md +60 -0
- data/docs/manual/plugins/rigor-dry-types.md +59 -0
- data/docs/manual/plugins/rigor-dry-validation.md +62 -0
- data/docs/manual/plugins/rigor-factorybot.md +76 -0
- data/docs/manual/plugins/rigor-graphql.md +89 -0
- data/docs/manual/plugins/rigor-hanami.md +83 -0
- data/docs/manual/plugins/rigor-mangrove.md +73 -0
- data/docs/manual/plugins/rigor-minitest.md +86 -0
- data/docs/manual/plugins/rigor-pundit.md +72 -0
- data/docs/manual/plugins/rigor-rails-i18n.md +92 -0
- data/docs/manual/plugins/rigor-rails-routes.md +94 -0
- data/docs/manual/plugins/rigor-rails.md +44 -0
- data/docs/manual/plugins/rigor-rbs-inline.md +83 -0
- data/docs/manual/plugins/rigor-rspec-rails.md +72 -0
- data/docs/manual/plugins/rigor-rspec.md +86 -0
- data/docs/manual/plugins/rigor-shoulda-matchers.md +78 -0
- data/docs/manual/plugins/rigor-sidekiq.md +78 -0
- data/docs/manual/plugins/rigor-sinatra.md +61 -0
- data/docs/manual/plugins/rigor-sorbet.md +63 -0
- data/docs/manual/plugins/rigor-statesman.md +75 -0
- data/docs/manual/plugins/rigor-typescript-utility-types.md +71 -0
- data/exe/rigor +1 -1
- data/lib/rigor/analysis/incremental_session.rb +4 -2
- data/lib/rigor/analysis/run_stats.rb +13 -1
- data/lib/rigor/analysis/runner.rb +54 -12
- data/lib/rigor/cli/check_command.rb +26 -3
- data/lib/rigor/cli/coverage_command.rb +67 -92
- data/lib/rigor/cli/coverage_mutation.rb +149 -0
- data/lib/rigor/cli/docs_command.rb +248 -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/skill_command.rb +103 -41
- data/lib/rigor/cli/skill_describe.rb +346 -0
- data/lib/rigor/cli.rb +25 -3
- data/lib/rigor/config_audit.rb +152 -0
- data/lib/rigor/configuration.rb +12 -0
- data/lib/rigor/environment/rbs_loader.rb +27 -0
- data/lib/rigor/environment.rb +49 -1
- data/lib/rigor/inference/method_dispatcher/constant_folding.rb +140 -38
- data/lib/rigor/inference/method_dispatcher/shape_dispatch.rb +37 -6
- data/lib/rigor/inference/scope_indexer.rb +87 -89
- data/lib/rigor/inference/statement_evaluator.rb +27 -0
- data/lib/rigor/plugin/isolation.rb +5 -5
- data/lib/rigor/plugin/loader.rb +4 -2
- data/lib/rigor/protection/diagnostic_oracle.rb +51 -0
- data/lib/rigor/protection/mutation_scanner.rb +98 -38
- data/lib/rigor/protection/mutator.rb +21 -0
- data/lib/rigor/protection/test_suite_oracle.rb +68 -0
- data/lib/rigor/signature_path_audit.rb +92 -0
- data/lib/rigor/version.rb +1 -1
- data/skills/rigor-ask/SKILL.md +172 -0
- data/skills/rigor-doctor/SKILL.md +87 -0
- data/skills/rigor-editor-setup/SKILL.md +114 -0
- data/skills/rigor-mcp-setup/SKILL.md +117 -0
- data/skills/rigor-monkeypatch-resolve/SKILL.md +79 -0
- data/skills/rigor-next-steps/SKILL.md +113 -0
- data/skills/rigor-plugin-tune/SKILL.md +79 -0
- data/skills/rigor-protection-uplift/SKILL.md +133 -0
- data/skills/rigor-rbs-setup/SKILL.md +128 -0
- data/skills/rigor-upgrade/SKILL.md +79 -0
- metadata +120 -1
|
@@ -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
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
# Hand-authored by Rigor maintainers. See LICENSE.upstream.
|
|
2
|
+
#
|
|
3
|
+
# Covers AST::Node, AST::Processor::Mixin, AST::Processor, and
|
|
4
|
+
# AST::Sexp from the `ast` gem (whitequark/ast v2.4.3).
|
|
5
|
+
#
|
|
6
|
+
# Design notes (ADR-5 robustness principle):
|
|
7
|
+
# - `children` is `Array[untyped]` — AST node children are
|
|
8
|
+
# heterogeneous (other Nodes, Symbols, Integers, Strings, nils).
|
|
9
|
+
# - `#==` / `#eql?` accept `untyped` — `#==` calls `to_ast` on the
|
|
10
|
+
# argument and `#eql?` does a class + field equality check.
|
|
11
|
+
# - `#updated` returns `AST::Node`, not `instance`, because concrete
|
|
12
|
+
# subclasses (Parser::AST::Node) override `initialize` via
|
|
13
|
+
# `original_dup` + `send(:initialize, ...)`, so the return type is
|
|
14
|
+
# always an instance of `self.class` at runtime — widening to
|
|
15
|
+
# `AST::Node` is the safe upper bound Rigor can check against.
|
|
16
|
+
# - `AST::Processor::Mixin#process` returns `AST::Node?` — the method
|
|
17
|
+
# returns `nil` when given `nil`, and handlers may return `nil` to
|
|
18
|
+
# preserve the original node (then `process` returns the original).
|
|
19
|
+
|
|
20
|
+
module AST
|
|
21
|
+
# Immutable AST node. The type and children are set at construction
|
|
22
|
+
# and the object is frozen. Subclasses add metadata (e.g. source
|
|
23
|
+
# location) via `#assign_properties`.
|
|
24
|
+
class Node
|
|
25
|
+
# Returns the node type (e.g. `:send`, `:begin`, `:int`).
|
|
26
|
+
attr_reader type: Symbol
|
|
27
|
+
|
|
28
|
+
# Returns the (frozen) children array. Elements are heterogeneous:
|
|
29
|
+
# either other AST::Node instances or plain Ruby values (Symbol,
|
|
30
|
+
# Integer, String, nil, …).
|
|
31
|
+
attr_reader children: Array[untyped]
|
|
32
|
+
|
|
33
|
+
# Precomputed hash based on type, children, and class.
|
|
34
|
+
attr_reader hash: Integer
|
|
35
|
+
|
|
36
|
+
# Constructs a new Node. `type` is coerced with `to_sym`;
|
|
37
|
+
# `children` is coerced with `to_a` and then frozen.
|
|
38
|
+
def initialize: (untyped type, ?untyped children, ?untyped properties) -> void
|
|
39
|
+
|
|
40
|
+
# Equality ignores metadata; only type and children are compared.
|
|
41
|
+
def ==: (untyped other) -> bool
|
|
42
|
+
|
|
43
|
+
# Structural equality (type, children, and class must match).
|
|
44
|
+
def eql?: (untyped other) -> bool
|
|
45
|
+
|
|
46
|
+
# Returns a new Node with non-nil arguments replacing the
|
|
47
|
+
# corresponding fields. If the result would be identical to self,
|
|
48
|
+
# returns self unchanged.
|
|
49
|
+
def updated: (?Symbol? type, ?Array[untyped]? children, ?Hash[Symbol, untyped]? properties) -> AST::Node
|
|
50
|
+
|
|
51
|
+
# Concatenates `array` with children and returns a new node.
|
|
52
|
+
def concat: (Array[untyped] array) -> AST::Node
|
|
53
|
+
|
|
54
|
+
# Alias for `concat`.
|
|
55
|
+
def +: (Array[untyped] array) -> AST::Node
|
|
56
|
+
|
|
57
|
+
# Appends `element` to children and returns a new node.
|
|
58
|
+
def append: (untyped element) -> AST::Node
|
|
59
|
+
|
|
60
|
+
# Alias for `append`.
|
|
61
|
+
def <<: (untyped element) -> AST::Node
|
|
62
|
+
|
|
63
|
+
# Alias for `children`.
|
|
64
|
+
def to_a: () -> Array[untyped]
|
|
65
|
+
|
|
66
|
+
# Returns self — nodes are already frozen.
|
|
67
|
+
def dup: () -> AST::Node
|
|
68
|
+
|
|
69
|
+
# Alias for `dup`.
|
|
70
|
+
def clone: () -> AST::Node
|
|
71
|
+
|
|
72
|
+
# Returns self — satisfies the `to_ast` protocol.
|
|
73
|
+
def to_ast: () -> AST::Node
|
|
74
|
+
|
|
75
|
+
# Pretty-printed s-expression string.
|
|
76
|
+
def to_sexp: (?Integer indent) -> String
|
|
77
|
+
|
|
78
|
+
# Alias for `to_sexp`.
|
|
79
|
+
def to_s: (?Integer indent) -> String
|
|
80
|
+
|
|
81
|
+
# Ruby-source s-expression string (uses `s(:type, ...)` notation).
|
|
82
|
+
def inspect: (?Integer indent) -> String
|
|
83
|
+
|
|
84
|
+
# Converts to `[type, *children_as_sexp_arrays]` recursively.
|
|
85
|
+
def to_sexp_array: () -> Array[untyped]
|
|
86
|
+
|
|
87
|
+
# Pattern-match support: `[type, *children]`.
|
|
88
|
+
def deconstruct: () -> Array[untyped]
|
|
89
|
+
|
|
90
|
+
# Assigns entries from `properties` as instance variables.
|
|
91
|
+
# Protected in Ruby; declared here without visibility for RBS
|
|
92
|
+
# compatibility (RBS does not support `protected` on class members).
|
|
93
|
+
def assign_properties: (Hash[Symbol, untyped] properties) -> nil
|
|
94
|
+
|
|
95
|
+
# Returns the type with underscores replaced by dashes.
|
|
96
|
+
def fancy_type: () -> String
|
|
97
|
+
|
|
98
|
+
# The original unfrozen `dup` kept for use in `#updated`.
|
|
99
|
+
private def original_dup: () -> AST::Node
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# The processor mixin provides a node-dispatch framework. Mix into a
|
|
103
|
+
# class and define `on_<type>` handlers; unhandled nodes fall through
|
|
104
|
+
# to `#handler_missing`.
|
|
105
|
+
module Processor::Mixin
|
|
106
|
+
# Dispatches `node` to the appropriate `on_<type>` handler.
|
|
107
|
+
# Returns the handler's return value if non-nil, otherwise the
|
|
108
|
+
# original `node`. Returns `nil` when `node` is `nil`.
|
|
109
|
+
def process: (AST::Node? node) -> AST::Node?
|
|
110
|
+
|
|
111
|
+
# Processes each node in `nodes` and returns the array of results.
|
|
112
|
+
def process_all: (Array[AST::Node?] nodes) -> Array[AST::Node?]
|
|
113
|
+
|
|
114
|
+
# Default handler for unrecognised node types. Does nothing and
|
|
115
|
+
# returns `nil`, which causes `#process` to return the node unchanged.
|
|
116
|
+
def handler_missing: (AST::Node node) -> nil
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
# Deprecated superclass. Prefer `include AST::Processor::Mixin`.
|
|
120
|
+
class Processor
|
|
121
|
+
include AST::Processor::Mixin
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
# Mixin providing the `s(type, *children)` shorthand for building
|
|
125
|
+
# nodes in tests or DSLs.
|
|
126
|
+
module Sexp
|
|
127
|
+
# Creates an AST::Node with the given type and children.
|
|
128
|
+
def s: (Symbol type, *untyped children) -> AST::Node
|
|
129
|
+
end
|
|
130
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
module BCrypt
|
|
2
|
+
class Password < String
|
|
3
|
+
attr_reader checksum: String
|
|
4
|
+
attr_reader salt: String
|
|
5
|
+
attr_reader version: String
|
|
6
|
+
attr_reader cost: Integer
|
|
7
|
+
def self.create: (_ToS secret, {cost: _ToI} options) -> BCrypt::Password
|
|
8
|
+
def self.valid_hash?: (String h) -> bool
|
|
9
|
+
def initialize: (String raw_hash) -> void
|
|
10
|
+
def ==: (_ToS secret) -> bool
|
|
11
|
+
alias is_password? ==
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
class Engine
|
|
15
|
+
DEFAULT_COST: Integer
|
|
16
|
+
MIN_COST: Integer
|
|
17
|
+
MAX_COST: Integer
|
|
18
|
+
MAX_SECRET_BYTESIZE: Integer
|
|
19
|
+
MAX_SALT_LENGTH: Integer
|
|
20
|
+
|
|
21
|
+
def self.cost: () -> Integer
|
|
22
|
+
def self.cost=: (Integer cost) -> Integer
|
|
23
|
+
def self.hash_secret: (_ToS secret, String salt, ?untyped _) -> String
|
|
24
|
+
def self.generate_salt: (?_ToI cost) -> String
|
|
25
|
+
def self.valid_salt?: (String salt) -> bool
|
|
26
|
+
def self.valid_secret?: (Object secret) -> bool
|
|
27
|
+
def self.calibrate: (Numeric upper_time_limit_in_ms) -> Integer
|
|
28
|
+
def self.autodetect_cost: (String salt) -> Integer
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
class Error < StandardError
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
module Errors
|
|
35
|
+
class InvalidSalt < Error
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
class InvalidHash < Error
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
class InvalidCost < Error
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
class InvalidSecret < Error
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|