sorbet-runtime 0.4.4301 → 0.5.5794
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 +5 -5
- data/lib/sorbet-runtime.rb +17 -1
- data/lib/types/_types.rb +68 -28
- data/lib/types/boolean.rb +2 -2
- data/lib/types/compatibility_patches.rb +66 -8
- data/lib/types/configuration.rb +128 -68
- data/lib/types/enum.rb +349 -0
- data/lib/types/generic.rb +2 -2
- data/lib/types/helpers.rb +8 -0
- data/lib/types/non_forcing_constants.rb +51 -0
- data/lib/types/private/abstract/declare.rb +10 -5
- data/lib/types/private/abstract/validate.rb +1 -1
- data/lib/types/private/casts.rb +1 -1
- data/lib/types/private/class_utils.rb +11 -2
- data/lib/types/private/decl_state.rb +12 -0
- data/lib/types/private/final.rb +51 -0
- data/lib/types/private/methods/_methods.rb +165 -49
- data/lib/types/private/methods/call_validation.rb +27 -55
- data/lib/types/private/methods/decl_builder.rb +36 -83
- data/lib/types/private/methods/modes.rb +5 -7
- data/lib/types/private/methods/signature.rb +11 -11
- data/lib/types/private/methods/signature_validation.rb +19 -22
- data/lib/types/private/retry.rb +10 -0
- data/lib/types/private/runtime_levels.rb +15 -0
- data/lib/types/private/sealed.rb +65 -0
- data/lib/types/private/types/type_alias.rb +26 -0
- data/lib/types/private/types/void.rb +4 -3
- data/lib/types/props/_props.rb +3 -7
- data/lib/types/props/constructor.rb +24 -10
- data/lib/types/props/custom_type.rb +51 -27
- data/lib/types/props/decorator.rb +232 -386
- data/lib/types/props/errors.rb +1 -1
- data/lib/types/props/generated_code_validation.rb +268 -0
- data/lib/types/props/has_lazily_specialized_methods.rb +92 -0
- data/lib/types/props/optional.rb +43 -35
- data/lib/types/props/plugin.rb +23 -1
- data/lib/types/props/pretty_printable.rb +4 -3
- data/lib/types/props/private/apply_default.rb +170 -0
- data/lib/types/props/private/deserializer_generator.rb +165 -0
- data/lib/types/props/private/parser.rb +32 -0
- data/lib/types/props/private/serde_transform.rb +192 -0
- data/lib/types/props/private/serializer_generator.rb +77 -0
- data/lib/types/props/private/setter_factory.rb +134 -0
- data/lib/types/props/serializable.rb +133 -179
- data/lib/types/props/type_validation.rb +18 -5
- data/lib/types/props/utils.rb +18 -8
- data/lib/types/props/weak_constructor.rb +47 -15
- data/lib/types/runtime_profiled.rb +12 -24
- data/lib/types/sig.rb +12 -10
- data/lib/types/types/attached_class.rb +33 -0
- data/lib/types/types/base.rb +11 -1
- data/lib/types/types/intersection.rb +1 -0
- data/lib/types/types/t_enum.rb +38 -0
- data/lib/types/types/type_member.rb +1 -1
- data/lib/types/types/type_parameter.rb +1 -1
- data/lib/types/types/type_template.rb +1 -1
- data/lib/types/types/typed_array.rb +14 -0
- data/lib/types/types/typed_enumerable.rb +29 -9
- data/lib/types/types/typed_enumerator.rb +14 -0
- data/lib/types/types/typed_hash.rb +14 -0
- data/lib/types/types/typed_range.rb +4 -0
- data/lib/types/types/typed_set.rb +14 -0
- data/lib/types/types/union.rb +1 -0
- data/lib/types/utils.rb +29 -35
- metadata +77 -9
- data/lib/types/private/error_handler.rb +0 -37
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: ac9a48252c9529d0ca91f96108b141c85388c88180281e5c8a682b16c11a9d5a
|
|
4
|
+
data.tar.gz: 31dc95eabc00327b1672a8fc142da7dc47f0ee0699fd4112358042248628675b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 21b1ef4ffdd76365effafe0c6a3eea4b15c1f9c36f2f402a1c8ba382d2f03d89f2202c1b8ac2aa82c315c7471f0989f7501d1888a49f67d401d33d26ac8e4d3a
|
|
7
|
+
data.tar.gz: 0f4c110725910ae452ea72fe6852538aa1c31cbb576dc242fe3631bd318e3b2bfda7b0fe3b05362584bd53885c9788a4f3eb2d5920d285c1c39ce727fb0ebd14
|
data/lib/sorbet-runtime.rb
CHANGED
|
@@ -24,11 +24,12 @@ require_relative 'types/_types'
|
|
|
24
24
|
require_relative 'types/private/decl_state'
|
|
25
25
|
require_relative 'types/runtime_profiled'
|
|
26
26
|
require_relative 'types/private/class_utils'
|
|
27
|
-
require_relative 'types/private/error_handler'
|
|
28
27
|
require_relative 'types/private/runtime_levels'
|
|
29
28
|
require_relative 'types/private/methods/_methods'
|
|
30
29
|
require_relative 'types/sig'
|
|
31
30
|
require_relative 'types/helpers'
|
|
31
|
+
require_relative 'types/private/final'
|
|
32
|
+
require_relative 'types/private/sealed'
|
|
32
33
|
|
|
33
34
|
# The types themselves. First base classes
|
|
34
35
|
require_relative 'types/types/base'
|
|
@@ -41,8 +42,10 @@ require_relative 'types/types/fixed_hash'
|
|
|
41
42
|
require_relative 'types/types/intersection'
|
|
42
43
|
require_relative 'types/types/noreturn'
|
|
43
44
|
require_relative 'types/types/proc'
|
|
45
|
+
require_relative 'types/types/attached_class'
|
|
44
46
|
require_relative 'types/types/self_type'
|
|
45
47
|
require_relative 'types/types/simple'
|
|
48
|
+
require_relative 'types/types/t_enum'
|
|
46
49
|
require_relative 'types/types/type_parameter'
|
|
47
50
|
require_relative 'types/types/typed_array'
|
|
48
51
|
require_relative 'types/types/typed_enumerator'
|
|
@@ -54,6 +57,7 @@ require_relative 'types/types/untyped'
|
|
|
54
57
|
require_relative 'types/private/types/not_typed'
|
|
55
58
|
require_relative 'types/private/types/void'
|
|
56
59
|
require_relative 'types/private/types/string_holder'
|
|
60
|
+
require_relative 'types/private/types/type_alias'
|
|
57
61
|
|
|
58
62
|
require_relative 'types/types/type_variable'
|
|
59
63
|
require_relative 'types/types/type_member'
|
|
@@ -76,6 +80,7 @@ require_relative 'types/private/abstract/hooks'
|
|
|
76
80
|
require_relative 'types/private/casts'
|
|
77
81
|
require_relative 'types/private/methods/decl_builder'
|
|
78
82
|
require_relative 'types/private/methods/signature'
|
|
83
|
+
require_relative 'types/private/retry'
|
|
79
84
|
require_relative 'types/utils'
|
|
80
85
|
require_relative 'types/boolean'
|
|
81
86
|
|
|
@@ -88,13 +93,24 @@ require_relative 'types/props/decorator'
|
|
|
88
93
|
require_relative 'types/props/errors'
|
|
89
94
|
require_relative 'types/props/plugin'
|
|
90
95
|
require_relative 'types/props/utils'
|
|
96
|
+
require_relative 'types/enum'
|
|
91
97
|
# Props that run sigs statically so have to be after all the others :(
|
|
98
|
+
require_relative 'types/props/private/setter_factory'
|
|
99
|
+
require_relative 'types/props/private/apply_default'
|
|
100
|
+
require_relative 'types/props/has_lazily_specialized_methods'
|
|
92
101
|
require_relative 'types/props/optional'
|
|
93
102
|
require_relative 'types/props/weak_constructor'
|
|
94
103
|
require_relative 'types/props/constructor'
|
|
95
104
|
require_relative 'types/props/pretty_printable'
|
|
105
|
+
require_relative 'types/props/private/serde_transform'
|
|
106
|
+
require_relative 'types/props/private/deserializer_generator'
|
|
107
|
+
require_relative 'types/props/private/serializer_generator'
|
|
96
108
|
require_relative 'types/props/serializable'
|
|
97
109
|
require_relative 'types/props/type_validation'
|
|
110
|
+
require_relative 'types/props/private/parser'
|
|
111
|
+
require_relative 'types/props/generated_code_validation'
|
|
112
|
+
|
|
98
113
|
require_relative 'types/struct'
|
|
114
|
+
require_relative 'types/non_forcing_constants'
|
|
99
115
|
|
|
100
116
|
require_relative 'types/compatibility_patches'
|
data/lib/types/_types.rb
CHANGED
|
@@ -65,6 +65,11 @@ module T
|
|
|
65
65
|
T::Types::SelfType.new
|
|
66
66
|
end
|
|
67
67
|
|
|
68
|
+
# Matches the instance type in a singleton-class context
|
|
69
|
+
def self.attached_class
|
|
70
|
+
T::Types::AttachedClassType.new
|
|
71
|
+
end
|
|
72
|
+
|
|
68
73
|
# Matches any class that subclasses or includes the provided class
|
|
69
74
|
# or module
|
|
70
75
|
def self.class_of(klass)
|
|
@@ -75,11 +80,11 @@ module T
|
|
|
75
80
|
## END OF THE METHODS TO PASS TO `sig`.
|
|
76
81
|
|
|
77
82
|
|
|
78
|
-
# Constructs a type alias. Used to create a short name for a larger
|
|
79
|
-
#
|
|
80
|
-
# needed for support by the static checker. Example usage:
|
|
83
|
+
# Constructs a type alias. Used to create a short name for a larger type. In Ruby this returns a
|
|
84
|
+
# wrapper that contains a proc that is evaluated to get the underlying type. This syntax however
|
|
85
|
+
# is needed for support by the static checker. Example usage:
|
|
81
86
|
#
|
|
82
|
-
# NilableString = T.type_alias
|
|
87
|
+
# NilableString = T.type_alias {T.nilable(String)}
|
|
83
88
|
#
|
|
84
89
|
# sig {params(arg: NilableString, default: String).returns(String)}
|
|
85
90
|
# def or_else(arg, default)
|
|
@@ -88,11 +93,17 @@ module T
|
|
|
88
93
|
#
|
|
89
94
|
# The name of the type alias is not preserved; Error messages will
|
|
90
95
|
# be printed with reference to the underlying type.
|
|
91
|
-
|
|
92
|
-
|
|
96
|
+
#
|
|
97
|
+
# TODO Remove `type` parameter. This was left in to make life easier while migrating.
|
|
98
|
+
def self.type_alias(type=nil, &blk)
|
|
99
|
+
if blk
|
|
100
|
+
T::Private::Types::TypeAlias.new(blk)
|
|
101
|
+
else
|
|
102
|
+
T::Utils.coerce(type)
|
|
103
|
+
end
|
|
93
104
|
end
|
|
94
105
|
|
|
95
|
-
# References a type
|
|
106
|
+
# References a type parameter which was previously defined with
|
|
96
107
|
# `type_parameters`.
|
|
97
108
|
#
|
|
98
109
|
# This is used for generic methods. Example usage:
|
|
@@ -176,21 +187,15 @@ module T
|
|
|
176
187
|
# Intended to be used to promise sorbet that a given nilable value happens
|
|
177
188
|
# to contain a non-nil value at this point.
|
|
178
189
|
#
|
|
179
|
-
# sig {params(arg: T.nilable(A)
|
|
180
|
-
def self.must(arg
|
|
190
|
+
# sig {params(arg: T.nilable(A)).returns(A)}
|
|
191
|
+
def self.must(arg)
|
|
192
|
+
return arg if arg
|
|
193
|
+
return arg if arg == false
|
|
194
|
+
|
|
181
195
|
begin
|
|
182
|
-
|
|
183
|
-
if !T.unsafe(msg).is_a?(String)
|
|
184
|
-
raise TypeError.new("T.must expects a string as second argument")
|
|
185
|
-
end
|
|
186
|
-
else
|
|
187
|
-
msg = "Passed `nil` into T.must"
|
|
188
|
-
end
|
|
189
|
-
raise TypeError.new(msg) if arg.nil?
|
|
190
|
-
arg
|
|
196
|
+
raise TypeError.new("Passed `nil` into T.must")
|
|
191
197
|
rescue TypeError => e # raise into rescue to ensure e.backtrace is populated
|
|
192
|
-
T::
|
|
193
|
-
arg
|
|
198
|
+
T::Configuration.inline_type_error_handler(e)
|
|
194
199
|
end
|
|
195
200
|
end
|
|
196
201
|
|
|
@@ -201,29 +206,63 @@ module T
|
|
|
201
206
|
value
|
|
202
207
|
end
|
|
203
208
|
|
|
209
|
+
# A way to ask Sorbet to prove that a certain branch of control flow never
|
|
210
|
+
# happens. Commonly used to assert that a case or if statement exhausts all
|
|
211
|
+
# possible cases.
|
|
212
|
+
def self.absurd(value)
|
|
213
|
+
msg = "Control flow reached T.absurd."
|
|
214
|
+
|
|
215
|
+
case value
|
|
216
|
+
when Kernel
|
|
217
|
+
msg += " Got value: #{value}"
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
begin
|
|
221
|
+
raise TypeError.new(msg)
|
|
222
|
+
rescue TypeError => e # raise into rescue to ensure e.backtrace is populated
|
|
223
|
+
T::Configuration.inline_type_error_handler(e)
|
|
224
|
+
end
|
|
225
|
+
end
|
|
226
|
+
|
|
204
227
|
### Generic classes ###
|
|
205
228
|
|
|
206
229
|
module Array
|
|
207
230
|
def self.[](type)
|
|
208
|
-
T::Types::
|
|
231
|
+
if type.is_a?(T::Types::Untyped)
|
|
232
|
+
T::Types::TypedArray::Untyped.new
|
|
233
|
+
else
|
|
234
|
+
T::Types::TypedArray.new(type)
|
|
235
|
+
end
|
|
209
236
|
end
|
|
210
237
|
end
|
|
211
238
|
|
|
212
239
|
module Hash
|
|
213
240
|
def self.[](keys, values)
|
|
214
|
-
T::Types::
|
|
241
|
+
if keys.is_a?(T::Types::Untyped) && values.is_a?(T::Types::Untyped)
|
|
242
|
+
T::Types::TypedHash::Untyped.new
|
|
243
|
+
else
|
|
244
|
+
T::Types::TypedHash.new(keys: keys, values: values)
|
|
245
|
+
end
|
|
215
246
|
end
|
|
216
247
|
end
|
|
217
248
|
|
|
218
249
|
module Enumerable
|
|
219
250
|
def self.[](type)
|
|
220
|
-
T::Types::
|
|
251
|
+
if type.is_a?(T::Types::Untyped)
|
|
252
|
+
T::Types::TypedEnumerable::Untyped.new
|
|
253
|
+
else
|
|
254
|
+
T::Types::TypedEnumerable.new(type)
|
|
255
|
+
end
|
|
221
256
|
end
|
|
222
257
|
end
|
|
223
258
|
|
|
224
259
|
module Enumerator
|
|
225
260
|
def self.[](type)
|
|
226
|
-
T::Types::
|
|
261
|
+
if type.is_a?(T::Types::Untyped)
|
|
262
|
+
T::Types::TypedEnumerator::Untyped.new
|
|
263
|
+
else
|
|
264
|
+
T::Types::TypedEnumerator.new(type)
|
|
265
|
+
end
|
|
227
266
|
end
|
|
228
267
|
end
|
|
229
268
|
|
|
@@ -235,11 +274,12 @@ module T
|
|
|
235
274
|
|
|
236
275
|
module Set
|
|
237
276
|
def self.[](type)
|
|
238
|
-
T::Types::
|
|
277
|
+
if type.is_a?(T::Types::Untyped)
|
|
278
|
+
T::Types::TypedSet::Untyped.new
|
|
279
|
+
else
|
|
280
|
+
T::Types::TypedSet.new(type)
|
|
281
|
+
end
|
|
239
282
|
end
|
|
240
283
|
end
|
|
241
|
-
|
|
242
|
-
# When mixed into a module, indicates that Sorbet may export the CFG for methods in that module
|
|
243
|
-
module CFGExport; end
|
|
244
284
|
end
|
|
245
285
|
# rubocop:enable PrisonGuard/UseOpusTypesShortcut
|
data/lib/types/boolean.rb
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
# typed:
|
|
1
|
+
# typed: strict
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
4
|
module T
|
|
5
5
|
# T::Boolean is a type alias helper for the common `T.any(TrueClass, FalseClass)`.
|
|
6
6
|
# Defined separately from _types.rb because it has a dependency on T::Types::Union.
|
|
7
|
-
Boolean = T.type_alias
|
|
7
|
+
Boolean = T.type_alias {T.any(TrueClass, FalseClass)}
|
|
8
8
|
end
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
1
2
|
# typed: ignore
|
|
2
3
|
|
|
3
4
|
require_relative 'private/methods/_methods'
|
|
4
5
|
|
|
5
6
|
# Work around an interaction bug with sorbet-runtime and rspec-mocks,
|
|
6
|
-
# which occurs when using *_any_instance_of
|
|
7
|
+
# which occurs when using message expectations (*_any_instance_of,
|
|
8
|
+
# expect, allow) and and_call_original.
|
|
7
9
|
#
|
|
8
10
|
# When a sig is defined, sorbet-runtime will replace the sigged method
|
|
9
11
|
# with a wrapper that, upon first invocation, re-wraps the method with a faster
|
|
@@ -21,17 +23,73 @@ require_relative 'private/methods/_methods'
|
|
|
21
23
|
#
|
|
22
24
|
# We work around this by forcing re-wrapping before rspec stores a reference
|
|
23
25
|
# to the method.
|
|
24
|
-
if defined? ::RSpec::Mocks
|
|
26
|
+
if defined? ::RSpec::Mocks
|
|
25
27
|
module T
|
|
26
28
|
module CompatibilityPatches
|
|
27
|
-
module
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
module RSpecCompatibility
|
|
30
|
+
module RecorderExtensions
|
|
31
|
+
def observe!(method_name)
|
|
32
|
+
method = @klass.instance_method(method_name.to_sym)
|
|
33
|
+
T::Private::Methods.maybe_run_sig_block_for_method(method)
|
|
34
|
+
super(method_name)
|
|
35
|
+
end
|
|
32
36
|
end
|
|
37
|
+
::RSpec::Mocks::AnyInstance::Recorder.prepend(RecorderExtensions) if defined?(::RSpec::Mocks::AnyInstance::Recorder)
|
|
38
|
+
|
|
39
|
+
module MethodDoubleExtensions
|
|
40
|
+
def initialize(object, method_name, proxy)
|
|
41
|
+
if ::Kernel.instance_method(:respond_to?).bind(object).call(method_name, true)
|
|
42
|
+
method = ::RSpec::Support.method_handle_for(object, method_name)
|
|
43
|
+
T::Private::Methods.maybe_run_sig_block_for_method(method)
|
|
44
|
+
end
|
|
45
|
+
super(object, method_name, proxy)
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
::RSpec::Mocks::MethodDouble.prepend(MethodDoubleExtensions) if defined?(::RSpec::Mocks::MethodDouble)
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Work around for sorbet-runtime wrapped methods.
|
|
55
|
+
#
|
|
56
|
+
# When a sig is defined, sorbet-runtime will replace the sigged method
|
|
57
|
+
# with a wrapper. Those wrapper methods look like `foo(*args, &blk)`
|
|
58
|
+
# so that wrappers can handle and pass on all the arguments supplied.
|
|
59
|
+
#
|
|
60
|
+
# However, that creates a problem with runtime reflection on the methods,
|
|
61
|
+
# since when a sigged method is introspected, it will always return its
|
|
62
|
+
# `arity` as `-1`, its `parameters` as `[[:rest, :args], [:block, :blk]]`,
|
|
63
|
+
# and its `source_location` as `[<some_file_in_sorbet>, <some_line_number>]`.
|
|
64
|
+
#
|
|
65
|
+
# This might be a problem for some applications that rely on getting the
|
|
66
|
+
# correct information from these methods.
|
|
67
|
+
#
|
|
68
|
+
# This compatibility module, when prepended to the `Method` class, would fix
|
|
69
|
+
# the return values of `arity`, `parameters` and `source_location`.
|
|
70
|
+
#
|
|
71
|
+
# @example
|
|
72
|
+
# require 'sorbet-runtime'
|
|
73
|
+
# ::Method.prepend(T::CompatibilityPatches::MethodExtensions)
|
|
74
|
+
module T
|
|
75
|
+
module CompatibilityPatches
|
|
76
|
+
module MethodExtensions
|
|
77
|
+
def arity
|
|
78
|
+
arity = super
|
|
79
|
+
return arity if arity != -1 || self.is_a?(Proc)
|
|
80
|
+
sig = T::Private::Methods.signature_for_method(self)
|
|
81
|
+
sig ? sig.method.arity : arity
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def source_location
|
|
85
|
+
sig = T::Private::Methods.signature_for_method(self)
|
|
86
|
+
sig ? sig.method.source_location : super
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def parameters
|
|
90
|
+
sig = T::Private::Methods.signature_for_method(self)
|
|
91
|
+
sig ? sig.method.parameters : super
|
|
33
92
|
end
|
|
34
|
-
::RSpec::Mocks::AnyInstance::Recorder.prepend(RecorderExtensions)
|
|
35
93
|
end
|
|
36
94
|
end
|
|
37
95
|
end
|
data/lib/types/configuration.rb
CHANGED
|
@@ -2,6 +2,59 @@
|
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
4
|
module T::Configuration
|
|
5
|
+
# Announces to Sorbet that we are currently in a test environment, so it
|
|
6
|
+
# should treat any sigs which are marked `.checked(:tests)` as if they were
|
|
7
|
+
# just a normal sig.
|
|
8
|
+
#
|
|
9
|
+
# If this method is not called, sigs marked `.checked(:tests)` will not be
|
|
10
|
+
# checked. In fact, such methods won't even be wrapped--the runtime will put
|
|
11
|
+
# back the original method.
|
|
12
|
+
#
|
|
13
|
+
# Note: Due to the way sigs are evaluated and methods are wrapped, this
|
|
14
|
+
# method MUST be called before any code calls `sig`. This method raises if
|
|
15
|
+
# it has been called too late.
|
|
16
|
+
def self.enable_checking_for_sigs_marked_checked_tests
|
|
17
|
+
T::Private::RuntimeLevels.enable_checking_in_tests
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Announce to Sorbet that we would like the final checks to be enabled when
|
|
21
|
+
# including and extending modules. Iff this is not called, then the following
|
|
22
|
+
# example will not raise an error.
|
|
23
|
+
#
|
|
24
|
+
# ```ruby
|
|
25
|
+
# module M
|
|
26
|
+
# extend T::Sig
|
|
27
|
+
# sig(:final) {void}
|
|
28
|
+
# def foo; end
|
|
29
|
+
# end
|
|
30
|
+
# class C
|
|
31
|
+
# include M
|
|
32
|
+
# def foo; end
|
|
33
|
+
# end
|
|
34
|
+
# ```
|
|
35
|
+
def self.enable_final_checks_on_hooks
|
|
36
|
+
T::Private::Methods.set_final_checks_on_hooks(true)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Undo the effects of a previous call to
|
|
40
|
+
# `enable_final_checks_on_hooks`.
|
|
41
|
+
def self.reset_final_checks_on_hooks
|
|
42
|
+
T::Private::Methods.set_final_checks_on_hooks(false)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Configure the default checked level for a sig with no explicit `.checked`
|
|
46
|
+
# builder. When unset, the default checked level is `:always`.
|
|
47
|
+
#
|
|
48
|
+
# Note: setting this option is potentially dangerous! Sorbet can't check all
|
|
49
|
+
# code statically. The runtime checks complement the checks that Sorbet does
|
|
50
|
+
# statically, so that methods don't have to guard themselves from being
|
|
51
|
+
# called incorrectly by untyped code.
|
|
52
|
+
#
|
|
53
|
+
# @param [:never, :tests, :always] default_checked_level
|
|
54
|
+
def self.default_checked_level=(default_checked_level)
|
|
55
|
+
T::Private::RuntimeLevels.default_checked_level = default_checked_level
|
|
56
|
+
end
|
|
57
|
+
|
|
5
58
|
# Set a handler to handle `TypeError`s raised by any in-line type assertions,
|
|
6
59
|
# including `T.must`, `T.let`, `T.cast`, and `T.assert_type!`.
|
|
7
60
|
#
|
|
@@ -36,6 +89,7 @@ module T::Configuration
|
|
|
36
89
|
else
|
|
37
90
|
inline_type_error_handler_default(error)
|
|
38
91
|
end
|
|
92
|
+
nil
|
|
39
93
|
end
|
|
40
94
|
|
|
41
95
|
# Set a handler to handle errors that occur when the builder methods in the
|
|
@@ -66,7 +120,7 @@ module T::Configuration
|
|
|
66
120
|
end
|
|
67
121
|
|
|
68
122
|
private_class_method def self.sig_builder_error_handler_default(error, location)
|
|
69
|
-
|
|
123
|
+
raise ArgumentError.new("#{location.path}:#{location.lineno}: Error interpreting `sig`:\n #{error.message}\n\n")
|
|
70
124
|
end
|
|
71
125
|
|
|
72
126
|
def self.sig_builder_error_handler(error, location)
|
|
@@ -75,6 +129,7 @@ module T::Configuration
|
|
|
75
129
|
else
|
|
76
130
|
sig_builder_error_handler_default(error, location)
|
|
77
131
|
end
|
|
132
|
+
nil
|
|
78
133
|
end
|
|
79
134
|
|
|
80
135
|
# Set a handler to handle sig validation errors.
|
|
@@ -84,11 +139,10 @@ module T::Configuration
|
|
|
84
139
|
# successfully built, but the built sig is incompatible with other sigs in
|
|
85
140
|
# some way.
|
|
86
141
|
#
|
|
87
|
-
# By default, sig validation errors cause an exception to be raised.
|
|
88
|
-
#
|
|
89
|
-
#
|
|
90
|
-
#
|
|
91
|
-
# behavior when a method signature's build fails.
|
|
142
|
+
# By default, sig validation errors cause an exception to be raised.
|
|
143
|
+
# Setting sig_validation_error_handler to an object that implements :call
|
|
144
|
+
# (e.g. proc or lambda) allows users to customize the behavior when a method
|
|
145
|
+
# signature's build fails.
|
|
92
146
|
#
|
|
93
147
|
# @param [Lambda, Proc, Object, nil] value Proc that handles the error (pass
|
|
94
148
|
# nil to reset to default behavior)
|
|
@@ -116,42 +170,24 @@ module T::Configuration
|
|
|
116
170
|
end
|
|
117
171
|
|
|
118
172
|
private_class_method def self.sig_validation_error_handler_default(error, opts)
|
|
119
|
-
|
|
120
|
-
bad_method = opts[:method]
|
|
121
|
-
if !opts[:declaration].generated
|
|
122
|
-
super_signature = opts[:super_signature]
|
|
123
|
-
raise error if !super_signature&.generated
|
|
124
|
-
bad_method = super_signature.method
|
|
125
|
-
end
|
|
126
|
-
|
|
127
|
-
method_file, method_line = bad_method.source_location
|
|
128
|
-
T::Configuration.log_info_handler(
|
|
129
|
-
"SIG-DECLARE-FAILED",
|
|
130
|
-
{
|
|
131
|
-
definition_file: method_file,
|
|
132
|
-
definition_line: method_line,
|
|
133
|
-
kind: "Delete",
|
|
134
|
-
message: error.message,
|
|
135
|
-
},
|
|
136
|
-
)
|
|
173
|
+
raise error
|
|
137
174
|
end
|
|
138
175
|
|
|
139
|
-
def self.sig_validation_error_handler(error, opts)
|
|
176
|
+
def self.sig_validation_error_handler(error, opts={})
|
|
140
177
|
if @sig_validation_error_handler
|
|
141
178
|
@sig_validation_error_handler.call(error, opts)
|
|
142
179
|
else
|
|
143
180
|
sig_validation_error_handler_default(error, opts)
|
|
144
181
|
end
|
|
182
|
+
nil
|
|
145
183
|
end
|
|
146
184
|
|
|
147
185
|
# Set a handler for type errors that result from calling a method.
|
|
148
186
|
#
|
|
149
187
|
# By default, errors from calling a method cause an exception to be raised.
|
|
150
|
-
#
|
|
151
|
-
#
|
|
152
|
-
#
|
|
153
|
-
# behavior when a method is called with invalid parameters, or returns an
|
|
154
|
-
# invalid value.
|
|
188
|
+
# Setting call_validation_error_handler to an object that implements :call
|
|
189
|
+
# (e.g. proc or lambda) allows users to customize the behavior when a method
|
|
190
|
+
# is called with invalid parameters, or returns an invalid value.
|
|
155
191
|
#
|
|
156
192
|
# @param [Lambda, Proc, Object, nil] value Proc that handles the error
|
|
157
193
|
# report (pass nil to reset to default behavior)
|
|
@@ -180,49 +216,16 @@ module T::Configuration
|
|
|
180
216
|
end
|
|
181
217
|
|
|
182
218
|
private_class_method def self.call_validation_error_handler_default(signature, opts)
|
|
183
|
-
|
|
184
|
-
location = opts[:location]
|
|
185
|
-
suffix = "Caller: #{location.path}:#{location.lineno}\n" \
|
|
186
|
-
"Definition: #{method_file}:#{method_line}"
|
|
187
|
-
|
|
188
|
-
error_message = "#{opts[:kind]}#{opts[:name] ? " '#{opts[:name]}'" : ''}: #{opts[:message]}\n#{suffix}"
|
|
189
|
-
|
|
190
|
-
if signature.generated
|
|
191
|
-
got = opts[:value].class
|
|
192
|
-
got = T.unsafe(T::Enumerable[T.untyped]).describe_obj(opts[:value]) if got < Enumerable
|
|
193
|
-
T::Configuration.log_info_handler(
|
|
194
|
-
"SIG-CHECK-FAILED",
|
|
195
|
-
{
|
|
196
|
-
caller_file: location.path,
|
|
197
|
-
caller_line: location.lineno,
|
|
198
|
-
definition_file: method_file,
|
|
199
|
-
definition_line: method_line,
|
|
200
|
-
kind: opts[:kind],
|
|
201
|
-
name: opts[:name],
|
|
202
|
-
expected: opts[:type].name,
|
|
203
|
-
got: got,
|
|
204
|
-
},
|
|
205
|
-
)
|
|
206
|
-
elsif signature.soft_notify
|
|
207
|
-
T::Configuration.soft_assert_handler(
|
|
208
|
-
"TypeError: #{error_message}",
|
|
209
|
-
{notify: signature.soft_notify}
|
|
210
|
-
)
|
|
211
|
-
else
|
|
212
|
-
begin
|
|
213
|
-
raise TypeError.new(error_message)
|
|
214
|
-
rescue TypeError => e # raise into rescue to ensure e.backtrace is populated
|
|
215
|
-
T::Private::ErrorHandler.handle_inline_type_error(e)
|
|
216
|
-
end
|
|
217
|
-
end
|
|
219
|
+
raise TypeError.new(opts[:pretty_message])
|
|
218
220
|
end
|
|
219
221
|
|
|
220
|
-
def self.call_validation_error_handler(signature, opts)
|
|
222
|
+
def self.call_validation_error_handler(signature, opts={})
|
|
221
223
|
if @call_validation_error_handler
|
|
222
224
|
@call_validation_error_handler.call(signature, opts)
|
|
223
225
|
else
|
|
224
226
|
call_validation_error_handler_default(signature, opts)
|
|
225
227
|
end
|
|
228
|
+
nil
|
|
226
229
|
end
|
|
227
230
|
|
|
228
231
|
# Set a handler for logging
|
|
@@ -316,7 +319,7 @@ module T::Configuration
|
|
|
316
319
|
raise str
|
|
317
320
|
end
|
|
318
321
|
|
|
319
|
-
def self.hard_assert_handler(str, extra)
|
|
322
|
+
def self.hard_assert_handler(str, extra={})
|
|
320
323
|
if @hard_assert_handler
|
|
321
324
|
@hard_assert_handler.call(str, extra)
|
|
322
325
|
else
|
|
@@ -333,7 +336,7 @@ module T::Configuration
|
|
|
333
336
|
# T::Configuration.scalar_types = ["NilClass", "TrueClass", "FalseClass", ...]
|
|
334
337
|
def self.scalar_types=(values)
|
|
335
338
|
if values.nil?
|
|
336
|
-
@
|
|
339
|
+
@scalar_types = values
|
|
337
340
|
else
|
|
338
341
|
bad_values = values.select {|v| v.class != String}
|
|
339
342
|
unless bad_values.empty?
|
|
@@ -353,12 +356,69 @@ module T::Configuration
|
|
|
353
356
|
String
|
|
354
357
|
Symbol
|
|
355
358
|
Time
|
|
359
|
+
T::Enum
|
|
356
360
|
}).freeze
|
|
357
361
|
|
|
358
362
|
def self.scalar_types
|
|
359
363
|
@scalar_types || @default_scalar_types
|
|
360
364
|
end
|
|
361
365
|
|
|
366
|
+
# Temporarily disable ruby warnings while executing the given block. This is
|
|
367
|
+
# useful when doing something that would normally cause a warning to be
|
|
368
|
+
# emitted in Ruby verbose mode ($VERBOSE = true).
|
|
369
|
+
#
|
|
370
|
+
# @yield
|
|
371
|
+
#
|
|
372
|
+
def self.without_ruby_warnings
|
|
373
|
+
if $VERBOSE
|
|
374
|
+
begin
|
|
375
|
+
original_verbose = $VERBOSE
|
|
376
|
+
$VERBOSE = false
|
|
377
|
+
yield
|
|
378
|
+
ensure
|
|
379
|
+
$VERBOSE = original_verbose
|
|
380
|
+
end
|
|
381
|
+
else
|
|
382
|
+
yield
|
|
383
|
+
end
|
|
384
|
+
end
|
|
385
|
+
|
|
386
|
+
def self.enable_legacy_t_enum_migration_mode
|
|
387
|
+
@legacy_t_enum_migration_mode = true
|
|
388
|
+
end
|
|
389
|
+
def self.disable_legacy_t_enum_migration_mode
|
|
390
|
+
@legacy_t_enum_migration_mode = false
|
|
391
|
+
end
|
|
392
|
+
def self.legacy_t_enum_migration_mode?
|
|
393
|
+
@legacy_t_enum_migration_mode || false
|
|
394
|
+
end
|
|
395
|
+
|
|
396
|
+
# @param [Array] sealed_violation_whitelist An array of Regexp to validate
|
|
397
|
+
# whether inheriting /including a sealed module outside the defining module
|
|
398
|
+
# should be allowed. Useful to whitelist benign violations, like shim files
|
|
399
|
+
# generated for an autoloader.
|
|
400
|
+
def self.sealed_violation_whitelist=(sealed_violation_whitelist)
|
|
401
|
+
if @sealed_violation_whitelist != nil
|
|
402
|
+
raise ArgumentError.new("Cannot overwrite sealed_violation_whitelist after setting it")
|
|
403
|
+
end
|
|
404
|
+
|
|
405
|
+
case sealed_violation_whitelist
|
|
406
|
+
when Array
|
|
407
|
+
sealed_violation_whitelist.each do |x|
|
|
408
|
+
case x
|
|
409
|
+
when Regexp then nil
|
|
410
|
+
else raise TypeError.new("sealed_violation_whitelist accepts an Array of Regexp")
|
|
411
|
+
end
|
|
412
|
+
end
|
|
413
|
+
else
|
|
414
|
+
raise TypeError.new("sealed_violation_whitelist= accepts an Array of Regexp")
|
|
415
|
+
end
|
|
416
|
+
|
|
417
|
+
@sealed_violation_whitelist = sealed_violation_whitelist
|
|
418
|
+
end
|
|
419
|
+
def self.sealed_violation_whitelist
|
|
420
|
+
@sealed_violation_whitelist
|
|
421
|
+
end
|
|
362
422
|
|
|
363
423
|
private_class_method def self.validate_lambda_given!(value)
|
|
364
424
|
if !value.nil? && !value.respond_to?(:call)
|