sorbet-runtime 0.6.13293 → 0.6.13295
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/lib/sorbet-runtime.rb +2 -0
- data/lib/types/def_mods.rb +69 -0
- data/lib/types/private/methods/_methods.rb +120 -4
- data/lib/types/private/methods/decl_builder.rb +16 -1
- data/lib/types/syntax.rb +42 -0
- metadata +4 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1ba71f6fa762bdc985e7d0571384bdb516de33f4c9be69115cf1139975638da8
|
|
4
|
+
data.tar.gz: 557f176df1c801a3a1da3a9b7c28e112eada5cab30e23762b6d67ca1d1be6a8a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e7f17791a3f3e4c7dba12f932ae31f7c7e0a3379399d64037d89c78da0604472a64e55b3c6bad8d350304696f2ac8bc974e9ed1dd32e17542226d04b3e60734f
|
|
7
|
+
data.tar.gz: 82600633223a670039f18fa7cc0b857bb45a57210a8919a07e523181efdb66d416bf76f53f2c99b1473c5655d8fdfad964e364334f10c0471ad0aab132e99417
|
data/lib/sorbet-runtime.rb
CHANGED
|
@@ -25,7 +25,9 @@ require_relative 'types/private/class_utils'
|
|
|
25
25
|
require_relative 'types/private/runtime_levels'
|
|
26
26
|
require_relative 'types/private/methods/_methods'
|
|
27
27
|
require_relative 'types/sig'
|
|
28
|
+
require_relative 'types/def_mods'
|
|
28
29
|
require_relative 'types/helpers'
|
|
30
|
+
require_relative 'types/syntax'
|
|
29
31
|
require_relative 'types/private/final'
|
|
30
32
|
require_relative 'types/private/sealed'
|
|
31
33
|
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# typed: true
|
|
3
|
+
|
|
4
|
+
# Optional mixin providing `abstract`, `override`, `overridable`, and `final`
|
|
5
|
+
# as method-level DSL keywords. Use with `extend T::DefMods`.
|
|
6
|
+
#
|
|
7
|
+
# These are alternatives to writing modifiers inside a `sig { ... }` block:
|
|
8
|
+
#
|
|
9
|
+
# sig { void }
|
|
10
|
+
# abstract def foo; end
|
|
11
|
+
#
|
|
12
|
+
# is equivalent to:
|
|
13
|
+
#
|
|
14
|
+
# sig { abstract.void }
|
|
15
|
+
# def foo; end
|
|
16
|
+
#
|
|
17
|
+
# They all return the method name, so that they can be chained with methods
|
|
18
|
+
# like `private`. However, unlike those methods, these methods use the `sig`
|
|
19
|
+
# declaration to discover the most-recently-defined method, instead of needing
|
|
20
|
+
# `*_class_method` variants, like `private_class_method`.
|
|
21
|
+
module T::DefMods
|
|
22
|
+
def abstract(method_name)
|
|
23
|
+
Kernel.raise TypeError.new("abstract accepts a Symbol, got #{method_name.class}") unless method_name.is_a?(Symbol)
|
|
24
|
+
|
|
25
|
+
begin
|
|
26
|
+
T::Private::Methods.declare_abstract(T.unsafe(self), method_name)
|
|
27
|
+
rescue T::Private::Methods::DeclBuilder::BuilderError => e
|
|
28
|
+
T::Configuration.sig_builder_error_handler(e, Kernel.caller_locations(1, 1)&.first)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
method_name
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def override(method_name, allow_incompatible: false)
|
|
35
|
+
Kernel.raise TypeError.new("override accepts a Symbol, got #{method_name.class}") unless method_name.is_a?(Symbol)
|
|
36
|
+
|
|
37
|
+
begin
|
|
38
|
+
T::Private::Methods.declare_override(T.unsafe(self), method_name, allow_incompatible: allow_incompatible)
|
|
39
|
+
rescue T::Private::Methods::DeclBuilder::BuilderError => e
|
|
40
|
+
T::Configuration.sig_builder_error_handler(e, Kernel.caller_locations(1, 1)&.first)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
method_name
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def final(method_name)
|
|
47
|
+
Kernel.raise TypeError.new("final accepts a Symbol, got #{method_name.class}") unless method_name.is_a?(Symbol)
|
|
48
|
+
|
|
49
|
+
begin
|
|
50
|
+
T::Private::Methods.declare_final(T.unsafe(self), method_name)
|
|
51
|
+
rescue T::Private::Methods::DeclBuilder::BuilderError => e
|
|
52
|
+
T::Configuration.sig_builder_error_handler(e, Kernel.caller_locations(1, 1)&.first)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
method_name
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def overridable(method_name)
|
|
59
|
+
Kernel.raise TypeError.new("overridable accepts a Symbol, got #{method_name.class}") unless method_name.is_a?(Symbol)
|
|
60
|
+
|
|
61
|
+
begin
|
|
62
|
+
T::Private::Methods.declare_overridable(T.unsafe(self), method_name)
|
|
63
|
+
rescue T::Private::Methods::DeclBuilder::BuilderError => e
|
|
64
|
+
T::Configuration.sig_builder_error_handler(e, Kernel.caller_locations(1, 1)&.first)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
method_name
|
|
68
|
+
end
|
|
69
|
+
end
|
|
@@ -48,7 +48,7 @@ module T::Private::Methods
|
|
|
48
48
|
# (This can matter for circular load-time behavior, where a method is
|
|
49
49
|
# called while its Signature is being built)
|
|
50
50
|
# - It's `nil` if we've finished building the sig
|
|
51
|
-
DeclarationBlock = Struct.new(:mod, :loc, :blk_or_decl, :final)
|
|
51
|
+
DeclarationBlock = Struct.new(:mod, :method_name, :loc, :blk_or_decl, :final, :abstract, :override, :overridable)
|
|
52
52
|
|
|
53
53
|
def self.declare_sig(mod, loc, arg, &blk)
|
|
54
54
|
if T::Private::DeclState.current.active_declaration
|
|
@@ -60,13 +60,122 @@ module T::Private::Methods
|
|
|
60
60
|
raise "Invalid argument to `sig`: #{arg}"
|
|
61
61
|
end
|
|
62
62
|
|
|
63
|
-
|
|
63
|
+
method_name = nil # will be filled in once the next method is defined
|
|
64
|
+
abstract = nil
|
|
65
|
+
override = nil
|
|
66
|
+
overridable = nil
|
|
67
|
+
T::Private::DeclState.current.active_declaration = DeclarationBlock.new(mod, method_name, loc, blk, arg == :final, abstract, override, overridable)
|
|
68
|
+
|
|
69
|
+
nil
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
private_class_method def self.ensure_valid_declare_dsl!(mod, method_name, dsl_name)
|
|
73
|
+
previous_declaration = T::Private::DeclState.current.previous_declaration
|
|
74
|
+
if previous_declaration.nil?
|
|
75
|
+
# TODO(jez) Eventually, relax this and allow these DSLs without a preceding `sig`
|
|
76
|
+
raise DeclBuilder::BuilderError.new("You must declare a `sig` before using `#{dsl_name}` on the method `#{method_name}`")
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
if !previous_declaration.blk_or_decl.is_a?(Proc)
|
|
80
|
+
raise DeclBuilder::BuilderError.new("Cannot call `#{dsl_name} #{method_name.inspect}`, because the sig block has already run")
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# previous_declaration.mod is the method owner (which for `def self.foo`
|
|
84
|
+
# is the singleton class). The DSL caller's `self` is the class itself,
|
|
85
|
+
# so we also accept mod.singleton_class == previous_declaration.mod.
|
|
86
|
+
mod_matches = previous_declaration.mod == mod || previous_declaration.mod == mod.singleton_class
|
|
87
|
+
if !mod_matches || previous_declaration.method_name != method_name
|
|
88
|
+
raise DeclBuilder::BuilderError.new(
|
|
89
|
+
"Can only call `#{dsl_name} #{method_name.inspect}` for the previously sig'd method. " \
|
|
90
|
+
"Expected: #{previous_declaration.mod}##{previous_declaration.method_name}"
|
|
91
|
+
)
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
previous_declaration
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def self.declare_abstract(mod, method_name)
|
|
98
|
+
previous_declaration = ensure_valid_declare_dsl!(mod, method_name, :abstract)
|
|
99
|
+
return unless previous_declaration
|
|
100
|
+
|
|
101
|
+
if previous_declaration.abstract
|
|
102
|
+
raise DeclBuilder::BuilderError.new("Cannot call `abstract` twice for the method `#{method_name}`")
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
previous_declaration.abstract = true
|
|
106
|
+
|
|
107
|
+
# # TODO(jez) In the future, we will want some logic like this, but ONLY if
|
|
108
|
+
# # the method did not have a sig. The first-call sig wrapper is normally in
|
|
109
|
+
# # charge of running the sig block (even for abstract methods) If we know
|
|
110
|
+
# # for sure that we're not going to have a sig, but we want the runtime
|
|
111
|
+
# # `super` logic (possibly because there is an RBS method annotation), we
|
|
112
|
+
# # are safe to eagerly call `create_abstract_wrapper` to overwrite the
|
|
113
|
+
# # user's method.
|
|
114
|
+
# #
|
|
115
|
+
# # (Omitting this until we support DSL methods without runtime `sig`'s)
|
|
116
|
+
# original_visibility = T::Private::ClassUtils.visibility_method_name(mod, method_name)
|
|
117
|
+
# T::Private::Methods::CallValidation.create_abstract_wrapper(mod, method_name, original_visibility)
|
|
118
|
+
|
|
119
|
+
nil
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def self.declare_override(mod, method_name, allow_incompatible:)
|
|
123
|
+
previous_declaration = ensure_valid_declare_dsl!(mod, method_name, :override)
|
|
124
|
+
return unless previous_declaration
|
|
125
|
+
|
|
126
|
+
if previous_declaration.override
|
|
127
|
+
raise DeclBuilder::BuilderError.new("Cannot call `override` twice for the method `#{method_name}`")
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
method = mod.instance_method(method_name)
|
|
131
|
+
super_method = method.super_method
|
|
132
|
+
if super_method.nil?
|
|
133
|
+
source_loc = Kernel.caller_locations(2, 1)&.map { |loc| [loc.path || "<unknown>", loc.lineno] }&.first
|
|
134
|
+
T::Private::Methods::SignatureValidation.validate_non_override_mode(Modes.override, method_name, method, source_loc)
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
previous_declaration.override = {allow_incompatible: allow_incompatible}
|
|
138
|
+
|
|
139
|
+
nil
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
def self.declare_final(mod, method_name)
|
|
143
|
+
previous_declaration = ensure_valid_declare_dsl!(mod, method_name, :final)
|
|
144
|
+
return unless previous_declaration
|
|
145
|
+
|
|
146
|
+
if previous_declaration.final
|
|
147
|
+
raise DeclBuilder::BuilderError.new("Cannot declare `#{method_name}` final twice (from `sig(:final)` nor `final def`)")
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
previous_declaration.final = true
|
|
151
|
+
|
|
152
|
+
# Register final bookkeeping that _on_method_added would have done if it
|
|
153
|
+
# had seen final=true at that time. Use previous_declaration.mod (the actual
|
|
154
|
+
# method owner, which is the singleton_class for `def self.foo`).
|
|
155
|
+
add_module_with_final_method(previous_declaration.mod, method_name)
|
|
156
|
+
|
|
157
|
+
nil
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
def self.declare_overridable(mod, method_name)
|
|
161
|
+
previous_declaration = ensure_valid_declare_dsl!(mod, method_name, :overridable)
|
|
162
|
+
return unless previous_declaration
|
|
163
|
+
|
|
164
|
+
if previous_declaration.overridable
|
|
165
|
+
raise DeclBuilder::BuilderError.new("Cannot call `overridable` twice for the method `#{method_name}`")
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
previous_declaration.overridable = true
|
|
64
169
|
|
|
65
170
|
nil
|
|
66
171
|
end
|
|
67
172
|
|
|
68
173
|
def self.start_proc
|
|
69
|
-
|
|
174
|
+
# abstract/override/overridable don't make sense on procs
|
|
175
|
+
abstract = false
|
|
176
|
+
override = nil
|
|
177
|
+
overridable = false
|
|
178
|
+
DeclBuilder.new(PROC_TYPE, abstract, override, overridable)
|
|
70
179
|
end
|
|
71
180
|
|
|
72
181
|
def self.finalize_proc(decl)
|
|
@@ -211,6 +320,8 @@ module T::Private::Methods
|
|
|
211
320
|
return
|
|
212
321
|
end
|
|
213
322
|
|
|
323
|
+
current_declaration.method_name = method_name
|
|
324
|
+
|
|
214
325
|
if method_name == :method_added || method_name == :singleton_method_added
|
|
215
326
|
raise(
|
|
216
327
|
"Putting a `sig` on `#{method_name}` is not supported" \
|
|
@@ -350,7 +461,12 @@ module T::Private::Methods
|
|
|
350
461
|
raise "DeclarationBlock for #{declaration_block.mod} at #{declaration_block.loc} should have already been unwrapped"
|
|
351
462
|
end
|
|
352
463
|
|
|
353
|
-
builder = DeclBuilder.new(
|
|
464
|
+
builder = DeclBuilder.new(
|
|
465
|
+
declaration_block.mod,
|
|
466
|
+
declaration_block.abstract,
|
|
467
|
+
declaration_block.override,
|
|
468
|
+
declaration_block.overridable
|
|
469
|
+
)
|
|
354
470
|
decl = builder.instance_exec(&blk_or_decl).finalize!.decl
|
|
355
471
|
# Record that we've already run `blk` once and constructed a `Declaration`
|
|
356
472
|
declaration_block.blk_or_decl = decl
|
|
@@ -15,7 +15,7 @@ module T::Private::Methods
|
|
|
15
15
|
end
|
|
16
16
|
end
|
|
17
17
|
|
|
18
|
-
def initialize(mod)
|
|
18
|
+
def initialize(mod, abstract, override, overridable)
|
|
19
19
|
@decl = Declaration.new(
|
|
20
20
|
mod,
|
|
21
21
|
ARG_NOT_PROVIDED, # params
|
|
@@ -28,6 +28,21 @@ module T::Private::Methods
|
|
|
28
28
|
false, # override_allow_incompatible
|
|
29
29
|
ARG_NOT_PROVIDED, # type_parameters
|
|
30
30
|
)
|
|
31
|
+
|
|
32
|
+
# Call the methods after the fact (instead of setting them in the constructor)
|
|
33
|
+
# so we get the BuilderError's, if applicable
|
|
34
|
+
|
|
35
|
+
if abstract
|
|
36
|
+
self.abstract
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
if override
|
|
40
|
+
self.override(**override)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
if overridable
|
|
44
|
+
self.overridable
|
|
45
|
+
end
|
|
31
46
|
end
|
|
32
47
|
|
|
33
48
|
def params(*unused_positional_params, **params)
|
data/lib/types/syntax.rb
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# typed: strict
|
|
3
|
+
|
|
4
|
+
# Used as a shortcut for mixing in the three most common "syntax" extensions
|
|
5
|
+
# that Sorbet provides: `sig`, the various sig DSL methods like `abstract` and
|
|
6
|
+
# `override`, and the `final!`/`interface!` etc. syntax for class-level
|
|
7
|
+
# annotations
|
|
8
|
+
module T::Syntax
|
|
9
|
+
include T::Sig
|
|
10
|
+
include T::DefMods
|
|
11
|
+
include T::Helpers
|
|
12
|
+
|
|
13
|
+
# ===== NOTE: Must keep in sync with `T::Sig`! ==============================
|
|
14
|
+
#
|
|
15
|
+
# However, there are some slight differences:
|
|
16
|
+
#
|
|
17
|
+
# - We don't need the extra `include ... MethodHooks` lines, because those
|
|
18
|
+
# come from the `include T::Sig` (c.f. `T::DefMods` though, where those
|
|
19
|
+
# extra `include` *are* required because there is otherwise no inheritance
|
|
20
|
+
# relationship between `T::Sig` and `T::DefMods`)
|
|
21
|
+
#
|
|
22
|
+
# - We don't do the TOP_SELF things, because it's not clear that you ever
|
|
23
|
+
# really want this for TOP_SELF. e.g. what would it mean to write
|
|
24
|
+
# `interface!` there?
|
|
25
|
+
#
|
|
26
|
+
# Rather than encourage people to write `extend T::Syntax` in their script
|
|
27
|
+
# top-levels, let's encourage people to just write `extend T::Sig` to keep
|
|
28
|
+
# things simpler.
|
|
29
|
+
#
|
|
30
|
+
# (We could revisit this in the future if people do really want this.)
|
|
31
|
+
|
|
32
|
+
private_class_method def self.included(other)
|
|
33
|
+
return unless Module == other
|
|
34
|
+
other.prepend(T::Private::Methods::MethodHooks)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
private_class_method def self.extended(other)
|
|
38
|
+
return unless Module.===(other) && other.singleton_class?
|
|
39
|
+
other.include(T::Private::Methods::SingletonMethodHooks)
|
|
40
|
+
end
|
|
41
|
+
# ===========================================================================
|
|
42
|
+
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: sorbet-runtime
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.6.
|
|
4
|
+
version: 0.6.13295
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Stripe
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-06-
|
|
11
|
+
date: 2026-06-10 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: benchmark
|
|
@@ -162,6 +162,7 @@ files:
|
|
|
162
162
|
- lib/types/boolean.rb
|
|
163
163
|
- lib/types/compatibility_patches.rb
|
|
164
164
|
- lib/types/configuration.rb
|
|
165
|
+
- lib/types/def_mods.rb
|
|
165
166
|
- lib/types/enum.rb
|
|
166
167
|
- lib/types/generic.rb
|
|
167
168
|
- lib/types/helpers.rb
|
|
@@ -212,6 +213,7 @@ files:
|
|
|
212
213
|
- lib/types/props/weak_constructor.rb
|
|
213
214
|
- lib/types/sig.rb
|
|
214
215
|
- lib/types/struct.rb
|
|
216
|
+
- lib/types/syntax.rb
|
|
215
217
|
- lib/types/types/anything.rb
|
|
216
218
|
- lib/types/types/attached_class.rb
|
|
217
219
|
- lib/types/types/base.rb
|