sorbet-runtime 0.5.8993 → 0.5.9566
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 +3 -2
- data/lib/types/_types.rb +10 -9
- data/lib/types/configuration.rb +76 -56
- data/lib/types/enum.rb +4 -9
- data/lib/types/helpers.rb +4 -2
- data/lib/types/non_forcing_constants.rb +5 -9
- data/lib/types/private/abstract/declare.rb +5 -0
- data/lib/types/private/casts.rb +2 -10
- data/lib/types/private/compiler.rb +24 -0
- data/lib/types/private/methods/_methods.rb +25 -19
- data/lib/types/private/methods/decl_builder.rb +5 -5
- data/lib/types/private/methods/modes.rb +18 -6
- data/lib/types/private/methods/signature.rb +1 -1
- data/lib/types/private/methods/signature_validation.rb +1 -2
- data/lib/types/private/runtime_levels.rb +7 -1
- data/lib/types/private/sealed.rb +26 -15
- data/lib/types/private/types/not_typed.rb +3 -3
- data/lib/types/private/types/string_holder.rb +3 -3
- data/lib/types/private/types/type_alias.rb +3 -3
- data/lib/types/private/types/void.rb +3 -3
- data/lib/types/props/_props.rb +21 -14
- data/lib/types/props/custom_type.rb +1 -1
- data/lib/types/props/decorator.rb +34 -52
- data/lib/types/props/generated_code_validation.rb +1 -1
- data/lib/types/props/has_lazily_specialized_methods.rb +5 -0
- data/lib/types/props/optional.rb +3 -3
- data/lib/types/props/private/serde_transform.rb +3 -3
- data/lib/types/props/private/serializer_generator.rb +0 -1
- data/lib/types/props/serializable.rb +16 -15
- data/lib/types/types/attached_class.rb +3 -3
- data/lib/types/types/base.rb +6 -2
- data/lib/types/types/class_of.rb +6 -4
- data/lib/types/types/enum.rb +5 -7
- data/lib/types/types/fixed_array.rb +5 -5
- data/lib/types/types/fixed_hash.rb +23 -17
- data/lib/types/types/intersection.rb +4 -4
- data/lib/types/types/noreturn.rb +3 -3
- data/lib/types/types/proc.rb +3 -3
- data/lib/types/types/self_type.rb +6 -6
- data/lib/types/types/simple.rb +32 -7
- data/lib/types/types/t_enum.rb +3 -3
- data/lib/types/types/typed_array.rb +3 -3
- data/lib/types/types/typed_enumerable.rb +5 -5
- data/lib/types/types/typed_enumerator.rb +3 -3
- data/lib/types/types/typed_hash.rb +3 -3
- data/lib/types/types/typed_range.rb +3 -3
- data/lib/types/types/typed_set.rb +15 -3
- data/lib/types/types/union.rb +4 -4
- data/lib/types/types/untyped.rb +3 -3
- data/lib/types/utils.rb +9 -1
- metadata +4 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1e5023e6be54c34aae9eaa90bd256fc8e9f15b56d54490f21530fb6ebac519fe
|
|
4
|
+
data.tar.gz: 43e21db8ed3660374e82d0017fcbca9768e3b8ce15ffe85997aa854e2338d47c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c2d2348cd0cf77820a3e3b5a5f935cf9bebc481dd2e85c4af01c642601d95215f3fe00f8c3145ccaf98626d4bc8815013e74b8d4c80c9f6b8159ec6f443e739a
|
|
7
|
+
data.tar.gz: ff45d3aa7343c2874d369d422b9690342c91c7a1f650229b108fef3bc9f7a92e68a06ca5fe38391a40aa6163a6839e63bc02dbcded7ea26d635338b359b514c5
|
data/lib/sorbet-runtime.rb
CHANGED
|
@@ -12,8 +12,6 @@ module T::Private; end
|
|
|
12
12
|
module T::Private::Abstract; end
|
|
13
13
|
module T::Private::Types; end
|
|
14
14
|
|
|
15
|
-
require 'set'
|
|
16
|
-
|
|
17
15
|
# Each section is a group that I believe need a fixed ordering. There is also
|
|
18
16
|
# an ordering between groups.
|
|
19
17
|
|
|
@@ -112,3 +110,6 @@ require_relative 'types/struct'
|
|
|
112
110
|
require_relative 'types/non_forcing_constants'
|
|
113
111
|
|
|
114
112
|
require_relative 'types/compatibility_patches'
|
|
113
|
+
|
|
114
|
+
# Sorbet Compiler support module
|
|
115
|
+
require_relative 'types/private/compiler'
|
data/lib/types/_types.rb
CHANGED
|
@@ -53,7 +53,8 @@ module T
|
|
|
53
53
|
end
|
|
54
54
|
|
|
55
55
|
# Matches any of the listed values
|
|
56
|
-
|
|
56
|
+
# @deprecated Use T::Enum instead.
|
|
57
|
+
def self.deprecated_enum(values)
|
|
57
58
|
T::Types::Enum.new(values)
|
|
58
59
|
end
|
|
59
60
|
|
|
@@ -78,14 +79,13 @@ module T
|
|
|
78
79
|
T::Types::ClassOf.new(klass)
|
|
79
80
|
end
|
|
80
81
|
|
|
81
|
-
|
|
82
82
|
## END OF THE METHODS TO PASS TO `sig`.
|
|
83
83
|
|
|
84
|
-
|
|
85
84
|
# Constructs a type alias. Used to create a short name for a larger type. In Ruby this returns a
|
|
86
85
|
# wrapper that contains a proc that is evaluated to get the underlying type. This syntax however
|
|
87
|
-
# is needed for support by the static checker.
|
|
86
|
+
# is needed for support by the static checker.
|
|
88
87
|
#
|
|
88
|
+
# @example
|
|
89
89
|
# NilableString = T.type_alias {T.nilable(String)}
|
|
90
90
|
#
|
|
91
91
|
# sig {params(arg: NilableString, default: String).returns(String)}
|
|
@@ -108,8 +108,9 @@ module T
|
|
|
108
108
|
# References a type parameter which was previously defined with
|
|
109
109
|
# `type_parameters`.
|
|
110
110
|
#
|
|
111
|
-
# This is used for generic methods.
|
|
111
|
+
# This is used for generic methods.
|
|
112
112
|
#
|
|
113
|
+
# @example
|
|
113
114
|
# sig
|
|
114
115
|
# .type_parameters(:U)
|
|
115
116
|
# .params(
|
|
@@ -187,7 +188,7 @@ module T
|
|
|
187
188
|
# cycle. However, we also don't actually need to do so; An untyped
|
|
188
189
|
# identity method works just as well here.
|
|
189
190
|
#
|
|
190
|
-
# sig {params(value: T.untyped).returns(T.untyped)}
|
|
191
|
+
# `sig {params(value: T.untyped).returns(T.untyped)}`
|
|
191
192
|
def self.unsafe(value)
|
|
192
193
|
value
|
|
193
194
|
end
|
|
@@ -208,7 +209,7 @@ module T
|
|
|
208
209
|
# Intended to be used to promise sorbet that a given nilable value happens
|
|
209
210
|
# to contain a non-nil value at this point.
|
|
210
211
|
#
|
|
211
|
-
# sig {params(arg: T.nilable(A)).returns(A)}
|
|
212
|
+
# `sig {params(arg: T.nilable(A)).returns(A)}`
|
|
212
213
|
def self.must(arg)
|
|
213
214
|
return arg if arg
|
|
214
215
|
return arg if arg == false
|
|
@@ -216,7 +217,7 @@ module T
|
|
|
216
217
|
begin
|
|
217
218
|
raise TypeError.new("Passed `nil` into T.must")
|
|
218
219
|
rescue TypeError => e # raise into rescue to ensure e.backtrace is populated
|
|
219
|
-
T::Configuration.inline_type_error_handler(e)
|
|
220
|
+
T::Configuration.inline_type_error_handler(e, {kind: 'T.must', value: arg, type: nil})
|
|
220
221
|
end
|
|
221
222
|
end
|
|
222
223
|
|
|
@@ -241,7 +242,7 @@ module T
|
|
|
241
242
|
begin
|
|
242
243
|
raise TypeError.new(msg)
|
|
243
244
|
rescue TypeError => e # raise into rescue to ensure e.backtrace is populated
|
|
244
|
-
T::Configuration.inline_type_error_handler(e)
|
|
245
|
+
T::Configuration.inline_type_error_handler(e, {kind: 'T.absurd', value: value, type: nil})
|
|
245
246
|
end
|
|
246
247
|
end
|
|
247
248
|
|
data/lib/types/configuration.rb
CHANGED
|
@@ -112,7 +112,7 @@ module T::Configuration
|
|
|
112
112
|
# statically, so that methods don't have to guard themselves from being
|
|
113
113
|
# called incorrectly by untyped code.
|
|
114
114
|
#
|
|
115
|
-
# @param [:never, :tests, :always] default_checked_level
|
|
115
|
+
# @param [:never, :compiled, :tests, :always] default_checked_level
|
|
116
116
|
def self.default_checked_level=(default_checked_level)
|
|
117
117
|
T::Private::RuntimeLevels.default_checked_level = default_checked_level
|
|
118
118
|
end
|
|
@@ -130,10 +130,15 @@ module T::Configuration
|
|
|
130
130
|
#
|
|
131
131
|
# Parameters passed to value.call:
|
|
132
132
|
#
|
|
133
|
-
#
|
|
133
|
+
# @param [TypeError] error TypeError that was raised
|
|
134
|
+
# @param [Hash] opts A hash containing contextual information on the error:
|
|
135
|
+
# @option opts [String] :kind One of:
|
|
136
|
+
# ['T.cast', 'T.let', 'T.bind', 'T.assert_type!', 'T.must', 'T.absurd']
|
|
137
|
+
# @option opts [Object, nil] :type Expected param/return value type
|
|
138
|
+
# @option opts [Object] :value Actual param/return value
|
|
134
139
|
#
|
|
135
140
|
# @example
|
|
136
|
-
# T::Configuration.inline_type_error_handler = lambda do |error|
|
|
141
|
+
# T::Configuration.inline_type_error_handler = lambda do |error, opts|
|
|
137
142
|
# puts error.message
|
|
138
143
|
# end
|
|
139
144
|
def self.inline_type_error_handler=(value)
|
|
@@ -141,15 +146,20 @@ module T::Configuration
|
|
|
141
146
|
@inline_type_error_handler = value
|
|
142
147
|
end
|
|
143
148
|
|
|
144
|
-
private_class_method def self.inline_type_error_handler_default(error)
|
|
149
|
+
private_class_method def self.inline_type_error_handler_default(error, opts)
|
|
145
150
|
raise error
|
|
146
151
|
end
|
|
147
152
|
|
|
148
|
-
def self.inline_type_error_handler(error)
|
|
153
|
+
def self.inline_type_error_handler(error, opts={})
|
|
149
154
|
if @inline_type_error_handler
|
|
150
|
-
|
|
155
|
+
# Backwards compatibility before `inline_type_error_handler` took a second arg
|
|
156
|
+
if @inline_type_error_handler.arity == 1
|
|
157
|
+
@inline_type_error_handler.call(error)
|
|
158
|
+
else
|
|
159
|
+
@inline_type_error_handler.call(error, opts)
|
|
160
|
+
end
|
|
151
161
|
else
|
|
152
|
-
inline_type_error_handler_default(error)
|
|
162
|
+
inline_type_error_handler_default(error, opts)
|
|
153
163
|
end
|
|
154
164
|
nil
|
|
155
165
|
end
|
|
@@ -169,8 +179,8 @@ module T::Configuration
|
|
|
169
179
|
#
|
|
170
180
|
# Parameters passed to value.call:
|
|
171
181
|
#
|
|
172
|
-
#
|
|
173
|
-
#
|
|
182
|
+
# @param [StandardError] error The error that was raised
|
|
183
|
+
# @param [Thread::Backtrace::Location] location Location of the error
|
|
174
184
|
#
|
|
175
185
|
# @example
|
|
176
186
|
# T::Configuration.sig_builder_error_handler = lambda do |error, location|
|
|
@@ -211,16 +221,16 @@ module T::Configuration
|
|
|
211
221
|
#
|
|
212
222
|
# Parameters passed to value.call:
|
|
213
223
|
#
|
|
214
|
-
#
|
|
215
|
-
#
|
|
216
|
-
#
|
|
217
|
-
#
|
|
218
|
-
#
|
|
219
|
-
#
|
|
220
|
-
#
|
|
221
|
-
#
|
|
222
|
-
#
|
|
223
|
-
#
|
|
224
|
+
# @param [StandardError] error The error that was raised
|
|
225
|
+
# @param [Hash] opts A hash containing contextual information on the error:
|
|
226
|
+
# @option opts [Method, UnboundMethod] :method Method on which the signature build failed
|
|
227
|
+
# @option opts [T::Private::Methods::Declaration] :declaration Method
|
|
228
|
+
# signature declaration struct
|
|
229
|
+
# @option opts [T::Private::Methods::Signature, nil] :signature Signature
|
|
230
|
+
# that failed (nil if sig build failed before Signature initialization)
|
|
231
|
+
# @option opts [T::Private::Methods::Signature, nil] :super_signature Super
|
|
232
|
+
# method's signature (nil if method is not an override or super method
|
|
233
|
+
# does not have a method signature)
|
|
224
234
|
#
|
|
225
235
|
# @example
|
|
226
236
|
# T::Configuration.sig_validation_error_handler = lambda do |error, opts|
|
|
@@ -256,17 +266,17 @@ module T::Configuration
|
|
|
256
266
|
#
|
|
257
267
|
# Parameters passed to value.call:
|
|
258
268
|
#
|
|
259
|
-
#
|
|
260
|
-
#
|
|
261
|
-
#
|
|
262
|
-
#
|
|
263
|
-
#
|
|
264
|
-
#
|
|
265
|
-
#
|
|
266
|
-
#
|
|
267
|
-
#
|
|
268
|
-
#
|
|
269
|
-
#
|
|
269
|
+
# @param [T::Private::Methods::Signature] signature Signature that failed
|
|
270
|
+
# @param [Hash] opts A hash containing contextual information on the error:
|
|
271
|
+
# @option opts [String] :message Error message
|
|
272
|
+
# @option opts [String] :kind One of:
|
|
273
|
+
# ['Parameter', 'Block parameter', 'Return value']
|
|
274
|
+
# @option opts [Symbol] :name Param or block param name (nil for return
|
|
275
|
+
# value)
|
|
276
|
+
# @option opts [Object] :type Expected param/return value type
|
|
277
|
+
# @option opts [Object] :value Actual param/return value
|
|
278
|
+
# @option opts [Thread::Backtrace::Location] :location Location of the
|
|
279
|
+
# caller
|
|
270
280
|
#
|
|
271
281
|
# @example
|
|
272
282
|
# T::Configuration.call_validation_error_handler = lambda do |signature, opts|
|
|
@@ -297,8 +307,8 @@ module T::Configuration
|
|
|
297
307
|
#
|
|
298
308
|
# Parameters passed to value.call:
|
|
299
309
|
#
|
|
300
|
-
#
|
|
301
|
-
#
|
|
310
|
+
# @param [String] str Message to be logged
|
|
311
|
+
# @param [Hash] extra A hash containing additional parameters to be passed along to the logger.
|
|
302
312
|
#
|
|
303
313
|
# @example
|
|
304
314
|
# T::Configuration.log_info_handler = lambda do |str, extra|
|
|
@@ -331,8 +341,8 @@ module T::Configuration
|
|
|
331
341
|
#
|
|
332
342
|
# Parameters passed to value.call:
|
|
333
343
|
#
|
|
334
|
-
#
|
|
335
|
-
#
|
|
344
|
+
# @param [String] str Assertion message
|
|
345
|
+
# @param [Hash] extra A hash containing additional parameters to be passed along to the handler.
|
|
336
346
|
#
|
|
337
347
|
# @example
|
|
338
348
|
# T::Configuration.soft_assert_handler = lambda do |str, extra|
|
|
@@ -365,8 +375,8 @@ module T::Configuration
|
|
|
365
375
|
#
|
|
366
376
|
# Parameters passed to value.call:
|
|
367
377
|
#
|
|
368
|
-
#
|
|
369
|
-
#
|
|
378
|
+
# @param [String] str Assertion message
|
|
379
|
+
# @param [Hash] extra A hash containing additional parameters to be passed along to the handler.
|
|
370
380
|
#
|
|
371
381
|
# @example
|
|
372
382
|
# T::Configuration.hard_assert_handler = lambda do |str, extra|
|
|
@@ -392,7 +402,7 @@ module T::Configuration
|
|
|
392
402
|
# Set a list of class strings that are to be considered scalar.
|
|
393
403
|
# (pass nil to reset to default behavior)
|
|
394
404
|
#
|
|
395
|
-
# @param [String]
|
|
405
|
+
# @param [String] values Class name.
|
|
396
406
|
#
|
|
397
407
|
# @example
|
|
398
408
|
# T::Configuration.scalar_types = ["NilClass", "TrueClass", "FalseClass", ...]
|
|
@@ -405,21 +415,21 @@ module T::Configuration
|
|
|
405
415
|
raise ArgumentError.new("Provided values must all be class name strings.")
|
|
406
416
|
end
|
|
407
417
|
|
|
408
|
-
@scalar_types =
|
|
418
|
+
@scalar_types = values.each_with_object({}) {|x, acc| acc[x] = true}.freeze
|
|
409
419
|
end
|
|
410
420
|
end
|
|
411
421
|
|
|
412
|
-
@default_scalar_types =
|
|
413
|
-
NilClass
|
|
414
|
-
TrueClass
|
|
415
|
-
FalseClass
|
|
416
|
-
Integer
|
|
417
|
-
Float
|
|
418
|
-
String
|
|
419
|
-
Symbol
|
|
420
|
-
Time
|
|
421
|
-
T::Enum
|
|
422
|
-
|
|
422
|
+
@default_scalar_types = {
|
|
423
|
+
"NilClass" => true,
|
|
424
|
+
"TrueClass" => true,
|
|
425
|
+
"FalseClass" => true,
|
|
426
|
+
"Integer" => true,
|
|
427
|
+
"Float" => true,
|
|
428
|
+
"String" => true,
|
|
429
|
+
"Symbol" => true,
|
|
430
|
+
"Time" => true,
|
|
431
|
+
"T::Enum" => true,
|
|
432
|
+
}.freeze
|
|
423
433
|
|
|
424
434
|
def self.scalar_types
|
|
425
435
|
@scalar_types || @default_scalar_types
|
|
@@ -429,10 +439,10 @@ module T::Configuration
|
|
|
429
439
|
MODULE_NAME = Module.instance_method(:name)
|
|
430
440
|
private_constant :MODULE_NAME
|
|
431
441
|
|
|
432
|
-
if T::Configuration::AT_LEAST_RUBY_2_7
|
|
433
|
-
|
|
442
|
+
@default_module_name_mangler = if T::Configuration::AT_LEAST_RUBY_2_7
|
|
443
|
+
->(type) {MODULE_NAME.bind_call(type)}
|
|
434
444
|
else
|
|
435
|
-
|
|
445
|
+
->(type) {MODULE_NAME.bind(type).call}
|
|
436
446
|
end
|
|
437
447
|
|
|
438
448
|
@module_name_mangler = nil
|
|
@@ -445,7 +455,7 @@ module T::Configuration
|
|
|
445
455
|
# to names in generated code. Used by the runtime implementation
|
|
446
456
|
# associated with `--stripe-packages` mode.
|
|
447
457
|
#
|
|
448
|
-
# @param [Lambda, Proc, nil]
|
|
458
|
+
# @param [Lambda, Proc, nil] handler Proc that converts a type (Class/Module)
|
|
449
459
|
# to a String (pass nil to reset to default behavior)
|
|
450
460
|
def self.module_name_mangler=(handler)
|
|
451
461
|
@module_name_mangler = handler
|
|
@@ -454,7 +464,7 @@ module T::Configuration
|
|
|
454
464
|
# Set to a PII handler function. This will be called with the `sensitivity:`
|
|
455
465
|
# annotations on things that use `T::Props` and can modify them ahead-of-time.
|
|
456
466
|
#
|
|
457
|
-
# @param [Lambda, Proc, nil]
|
|
467
|
+
# @param [Lambda, Proc, nil] handler Proc that takes a hash mapping symbols to the
|
|
458
468
|
# prop values. Pass nil to avoid changing `sensitivity:` annotations.
|
|
459
469
|
def self.normalize_sensitivity_and_pii_handler=(handler)
|
|
460
470
|
@sensitivity_and_pii_handler = handler
|
|
@@ -470,7 +480,7 @@ module T::Configuration
|
|
|
470
480
|
# `nil` and will raise an exception when the redacted version of a prop is
|
|
471
481
|
# accessed.
|
|
472
482
|
#
|
|
473
|
-
# @param [Lambda, Proc, nil]
|
|
483
|
+
# @param [Lambda, Proc, nil] handler Proc that converts a value into its
|
|
474
484
|
# redacted version according to the spec passed as the second argument.
|
|
475
485
|
def self.redaction_handler=(handler)
|
|
476
486
|
@redaction_handler = handler
|
|
@@ -483,7 +493,7 @@ module T::Configuration
|
|
|
483
493
|
# Set to a function which can get the 'owner' of a class. This is
|
|
484
494
|
# used in reporting deserialization errors
|
|
485
495
|
#
|
|
486
|
-
# @param [Lambda, Proc, nil]
|
|
496
|
+
# @param [Lambda, Proc, nil] handler Proc that takes a class and
|
|
487
497
|
# produces its owner, or `nil` if it does not have one.
|
|
488
498
|
def self.class_owner_finder=(handler)
|
|
489
499
|
@class_owner_finder = handler
|
|
@@ -523,6 +533,16 @@ module T::Configuration
|
|
|
523
533
|
@legacy_t_enum_migration_mode || false
|
|
524
534
|
end
|
|
525
535
|
|
|
536
|
+
@prop_freeze_handler = ->(instance, prop_name) {}
|
|
537
|
+
|
|
538
|
+
def self.prop_freeze_handler=(handler)
|
|
539
|
+
@prop_freeze_handler = handler
|
|
540
|
+
end
|
|
541
|
+
|
|
542
|
+
def self.prop_freeze_handler
|
|
543
|
+
@prop_freeze_handler
|
|
544
|
+
end
|
|
545
|
+
|
|
526
546
|
# @param [Array] sealed_violation_whitelist An array of Regexp to validate
|
|
527
547
|
# whether inheriting /including a sealed module outside the defining module
|
|
528
548
|
# should be allowed. Useful to whitelist benign violations, like shim files
|
data/lib/types/enum.rb
CHANGED
|
@@ -47,7 +47,7 @@ class T::Enum
|
|
|
47
47
|
SerializedVal = T.type_alias {T.untyped}
|
|
48
48
|
private_constant :SerializedVal
|
|
49
49
|
|
|
50
|
-
|
|
50
|
+
### Enum class methods ###
|
|
51
51
|
sig {returns(T::Array[T.attached_class])}
|
|
52
52
|
def self.values
|
|
53
53
|
if @values.nil?
|
|
@@ -134,9 +134,7 @@ class T::Enum
|
|
|
134
134
|
self.from_serialized(mongo_value)
|
|
135
135
|
end
|
|
136
136
|
|
|
137
|
-
|
|
138
|
-
## Enum instance methods ##
|
|
139
|
-
|
|
137
|
+
### Enum instance methods ###
|
|
140
138
|
|
|
141
139
|
sig {returns(T.self_type)}
|
|
142
140
|
def dup
|
|
@@ -180,7 +178,6 @@ class T::Enum
|
|
|
180
178
|
end
|
|
181
179
|
end
|
|
182
180
|
|
|
183
|
-
|
|
184
181
|
# NB: Do not call this method. This exists to allow for a safe migration path in places where enum
|
|
185
182
|
# values are compared directly against string values.
|
|
186
183
|
#
|
|
@@ -246,9 +243,7 @@ class T::Enum
|
|
|
246
243
|
)
|
|
247
244
|
end
|
|
248
245
|
|
|
249
|
-
|
|
250
|
-
## Private implementation ##
|
|
251
|
-
|
|
246
|
+
### Private implementation ###
|
|
252
247
|
|
|
253
248
|
sig {params(serialized_val: SerializedVal).void}
|
|
254
249
|
def initialize(serialized_val=nil)
|
|
@@ -366,6 +361,6 @@ class T::Enum
|
|
|
366
361
|
|
|
367
362
|
sig {params(args: String).returns(T.attached_class)}
|
|
368
363
|
def self._load(args)
|
|
369
|
-
deserialize(Marshal.load(args))
|
|
364
|
+
deserialize(Marshal.load(args)) # rubocop:disable Security/MarshalLoad
|
|
370
365
|
end
|
|
371
366
|
end
|
data/lib/types/helpers.rb
CHANGED
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
# Use as a mixin with extend (`extend T::Helpers`).
|
|
5
5
|
# Docs at https://confluence.corp.stripe.com/display/PRODINFRA/Ruby+Types
|
|
6
6
|
module T::Helpers
|
|
7
|
+
extend T::Sig
|
|
8
|
+
|
|
7
9
|
Private = T::Private
|
|
8
10
|
|
|
9
11
|
### Class/Module Helpers ###
|
|
@@ -44,7 +46,7 @@ module T::Helpers
|
|
|
44
46
|
# module MyHelper
|
|
45
47
|
# extend T::Helpers
|
|
46
48
|
#
|
|
47
|
-
# requires_ancestor Kernel
|
|
49
|
+
# requires_ancestor { Kernel }
|
|
48
50
|
# end
|
|
49
51
|
#
|
|
50
52
|
# class MyClass < BasicObject # error: `MyClass` must include `Kernel` (required by `MyHelper`)
|
|
@@ -52,5 +54,5 @@ module T::Helpers
|
|
|
52
54
|
# end
|
|
53
55
|
#
|
|
54
56
|
# TODO: implement the checks in sorbet-runtime.
|
|
55
|
-
def requires_ancestor(
|
|
57
|
+
def requires_ancestor(&block); end
|
|
56
58
|
end
|
|
@@ -2,11 +2,6 @@
|
|
|
2
2
|
# typed: strict
|
|
3
3
|
|
|
4
4
|
module T::NonForcingConstants
|
|
5
|
-
T::Sig::WithoutRuntime.sig {returns(T::Boolean)}
|
|
6
|
-
private_class_method def self.stripe_packages_enabled?
|
|
7
|
-
const_defined?('StripePackages') && const_get('StripePackages').enabled?
|
|
8
|
-
end
|
|
9
|
-
|
|
10
5
|
# NOTE: This method is documented on the RBI in Sorbet's payload, so that it
|
|
11
6
|
# shows up in the hover/completion documentation via LSP.
|
|
12
7
|
T::Sig::WithoutRuntime.sig {params(val: BasicObject, klass: String, package: T.nilable(String)).returns(T::Boolean)}
|
|
@@ -16,10 +11,11 @@ module T::NonForcingConstants
|
|
|
16
11
|
raise ArgumentError.new("The string given to `#{method_name}` must not be empty")
|
|
17
12
|
end
|
|
18
13
|
|
|
19
|
-
#
|
|
20
|
-
#
|
|
21
|
-
|
|
22
|
-
|
|
14
|
+
# We don't treat packages differently at runtime, but the static
|
|
15
|
+
# type-checker still needs to have the package and constant
|
|
16
|
+
# separated out. This just re-assembles the string as needed
|
|
17
|
+
if !package.nil?
|
|
18
|
+
klass = "::#{package}::#{klass}"
|
|
23
19
|
end
|
|
24
20
|
|
|
25
21
|
current_klass = T.let(nil, T.nilable(Module))
|
|
@@ -40,6 +40,11 @@ module T::Private::Abstract::Declare
|
|
|
40
40
|
end
|
|
41
41
|
super(*args, &blk)
|
|
42
42
|
end
|
|
43
|
+
|
|
44
|
+
# Ruby doesn not emit "method redefined" warnings for aliased methods
|
|
45
|
+
# (more robust than undef_method that would create a small window in which the method doesn't exist)
|
|
46
|
+
mod.send(:alias_method, :initialize, :initialize)
|
|
47
|
+
|
|
43
48
|
if mod.respond_to?(:ruby2_keywords, true)
|
|
44
49
|
mod.send(:ruby2_keywords, :initialize)
|
|
45
50
|
end
|
data/lib/types/private/casts.rb
CHANGED
|
@@ -2,14 +2,6 @@
|
|
|
2
2
|
# typed: false
|
|
3
3
|
|
|
4
4
|
module T::Private
|
|
5
|
-
# Dynamically confirm that `value` is recursively a valid value of
|
|
6
|
-
# type `type`, including recursively through collections. Note that
|
|
7
|
-
# in some cases this runtime check can be very expensive, especially
|
|
8
|
-
# with large collections of objects.
|
|
9
|
-
def self.check_type_recursive!(value, type)
|
|
10
|
-
T::Private::Casts.cast_recursive(value, type, cast_method: "T.check_type_recursive!")
|
|
11
|
-
end
|
|
12
|
-
|
|
13
5
|
module Casts
|
|
14
6
|
def self.cast(value, type, cast_method:)
|
|
15
7
|
begin
|
|
@@ -22,7 +14,7 @@ module T::Private
|
|
|
22
14
|
|
|
23
15
|
raise TypeError.new("#{cast_method}: #{error}\n#{suffix}")
|
|
24
16
|
rescue TypeError => e # raise into rescue to ensure e.backtrace is populated
|
|
25
|
-
T::Configuration.inline_type_error_handler(e)
|
|
17
|
+
T::Configuration.inline_type_error_handler(e, {kind: cast_method, value: value, type: type})
|
|
26
18
|
value
|
|
27
19
|
end
|
|
28
20
|
end
|
|
@@ -41,7 +33,7 @@ module T::Private
|
|
|
41
33
|
|
|
42
34
|
raise TypeError.new("#{cast_method}: #{error}\n#{suffix}")
|
|
43
35
|
rescue TypeError => e # raise into rescue to ensure e.backtrace is populated
|
|
44
|
-
T::Configuration.inline_type_error_handler(e)
|
|
36
|
+
T::Configuration.inline_type_error_handler(e, {kind: cast_method, value: value, type: type})
|
|
45
37
|
value
|
|
46
38
|
end
|
|
47
39
|
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# typed: true
|
|
3
|
+
|
|
4
|
+
module T::Private
|
|
5
|
+
module Compiler
|
|
6
|
+
# If this code ever runs, the caller is running interpreted (or the
|
|
7
|
+
# compiler didn't see the call to `running_compiled?` statically.)
|
|
8
|
+
#
|
|
9
|
+
# The Sorbet Compiler replaces calls to this method unconditionally (no
|
|
10
|
+
# runtime guards) to return `true` when compiling a file.
|
|
11
|
+
def self.running_compiled?
|
|
12
|
+
false
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# Returns `nil` because the compiler isn't running.
|
|
16
|
+
#
|
|
17
|
+
# The Sorbet Compiler replaces calls to this method unconditionally (no
|
|
18
|
+
# runtime guards) to return a String showing the Sorbet Compiler's version
|
|
19
|
+
# string.
|
|
20
|
+
def self.compiler_version
|
|
21
|
+
nil
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
# typed: false
|
|
3
3
|
|
|
4
4
|
module T::Private::Methods
|
|
5
|
-
@installed_hooks =
|
|
5
|
+
@installed_hooks = {}
|
|
6
6
|
@signatures_by_method = {}
|
|
7
7
|
@sig_wrappers = {}
|
|
8
8
|
@sigs_that_raised = {}
|
|
9
9
|
# stores method names that were declared final without regard for where.
|
|
10
10
|
# enables early rejection of names that we know can't induce final method violations.
|
|
11
|
-
@was_ever_final_names =
|
|
12
|
-
# maps from
|
|
11
|
+
@was_ever_final_names = {}
|
|
12
|
+
# maps from a module's object_id to the set of final methods declared in that module.
|
|
13
13
|
# we also overload entries slightly: if the value is nil, that means that the
|
|
14
14
|
# module has final methods somewhere along its ancestor chain, but does not itself
|
|
15
15
|
# have any final methods.
|
|
@@ -20,7 +20,7 @@ module T::Private::Methods
|
|
|
20
20
|
# twice is permitted). we could do this with two tables, but it seems slightly
|
|
21
21
|
# cleaner with a single table.
|
|
22
22
|
# Effectively T::Hash[Module, T.nilable(Set))]
|
|
23
|
-
@modules_with_final = Hash.new {
|
|
23
|
+
@modules_with_final = Hash.new {|hash, key| hash[key] = nil}
|
|
24
24
|
# this stores the old [included, extended] hooks for Module and inherited hook for Class that we override when
|
|
25
25
|
# enabling final checks for when those hooks are called. the 'hooks' here don't have anything to do with the 'hooks'
|
|
26
26
|
# in installed_hooks.
|
|
@@ -127,7 +127,7 @@ module T::Private::Methods
|
|
|
127
127
|
source_ancestors = nil
|
|
128
128
|
# use reverse_each to check farther-up ancestors first, for better error messages.
|
|
129
129
|
target_ancestors.reverse_each do |ancestor|
|
|
130
|
-
final_methods = @modules_with_final.fetch(ancestor, nil)
|
|
130
|
+
final_methods = @modules_with_final.fetch(ancestor.object_id, nil)
|
|
131
131
|
# In this case, either ancestor didn't have any final methods anywhere in its
|
|
132
132
|
# ancestor chain, or ancestor did have final methods somewhere in its ancestor
|
|
133
133
|
# chain, but no final methods defined in ancestor itself. Either way, there
|
|
@@ -145,20 +145,20 @@ module T::Private::Methods
|
|
|
145
145
|
# filter out things without actual final methods just to make sure that
|
|
146
146
|
# the below checks (which should be uncommon) go as quickly as possible.
|
|
147
147
|
source_ancestors.select! do |a|
|
|
148
|
-
@modules_with_final.fetch(a, nil)
|
|
148
|
+
@modules_with_final.fetch(a.object_id, nil)
|
|
149
149
|
end
|
|
150
150
|
end
|
|
151
151
|
# final-ness means that there should be no more than one index for which
|
|
152
152
|
# the below block returns true.
|
|
153
153
|
defining_ancestor_idx = source_ancestors.index do |a|
|
|
154
|
-
@modules_with_final.fetch(a).include?(method_name)
|
|
154
|
+
@modules_with_final.fetch(a.object_id).include?(method_name)
|
|
155
155
|
end
|
|
156
156
|
next if defining_ancestor_idx && source_ancestors[defining_ancestor_idx] == ancestor
|
|
157
157
|
end
|
|
158
158
|
|
|
159
159
|
definition_file, definition_line = T::Private::Methods.signature_for_method(ancestor.instance_method(method_name)).method.source_location
|
|
160
160
|
is_redefined = target == ancestor
|
|
161
|
-
caller_loc = caller_locations&.find {|l| !l.to_s.match?(%r{sorbet-runtime[^/]*/lib/})
|
|
161
|
+
caller_loc = caller_locations&.find {|l| !l.to_s.match?(%r{sorbet-runtime[^/]*/lib/})}
|
|
162
162
|
extra_info = "\n"
|
|
163
163
|
if caller_loc
|
|
164
164
|
extra_info = (is_redefined ? "Redefined" : "Overridden") + " here: #{caller_loc.path}:#{caller_loc.lineno}\n"
|
|
@@ -188,18 +188,20 @@ module T::Private::Methods
|
|
|
188
188
|
|
|
189
189
|
def self.add_module_with_final_method(mod, method_name, is_singleton_method)
|
|
190
190
|
m = is_singleton_method ? mod.singleton_class : mod
|
|
191
|
-
|
|
191
|
+
mid = m.object_id
|
|
192
|
+
methods = @modules_with_final[mid]
|
|
192
193
|
if methods.nil?
|
|
193
|
-
methods =
|
|
194
|
-
@modules_with_final[
|
|
194
|
+
methods = {}
|
|
195
|
+
@modules_with_final[mid] = methods
|
|
195
196
|
end
|
|
196
|
-
methods
|
|
197
|
+
methods[method_name] = true
|
|
198
|
+
nil
|
|
197
199
|
end
|
|
198
200
|
|
|
199
201
|
def self.note_module_deals_with_final(mod)
|
|
200
202
|
# Side-effectfully initialize the value if it's not already there
|
|
201
|
-
@modules_with_final[mod]
|
|
202
|
-
@modules_with_final[mod.singleton_class]
|
|
203
|
+
@modules_with_final[mod.object_id]
|
|
204
|
+
@modules_with_final[mod.singleton_class.object_id]
|
|
203
205
|
end
|
|
204
206
|
|
|
205
207
|
# Only public because it needs to get called below inside the replace_method blocks below.
|
|
@@ -215,7 +217,7 @@ module T::Private::Methods
|
|
|
215
217
|
raise "#{mod} was declared as final but its method `#{method_name}` was not declared as final"
|
|
216
218
|
end
|
|
217
219
|
# Don't compute mod.ancestors if we don't need to bother checking final-ness.
|
|
218
|
-
if @was_ever_final_names.include?(method_name) && @modules_with_final.include?(mod)
|
|
220
|
+
if @was_ever_final_names.include?(method_name) && @modules_with_final.include?(mod.object_id)
|
|
219
221
|
_check_final_ancestors(mod, mod.ancestors, [method_name], nil)
|
|
220
222
|
# We need to fetch the active declaration again, as _check_final_ancestors
|
|
221
223
|
# may have reset it (see the comment in that method for details).
|
|
@@ -276,7 +278,7 @@ module T::Private::Methods
|
|
|
276
278
|
|
|
277
279
|
@sig_wrappers[key] = sig_block
|
|
278
280
|
if current_declaration.final
|
|
279
|
-
@was_ever_final_names
|
|
281
|
+
@was_ever_final_names[method_name] = true
|
|
280
282
|
# use hook_mod, not mod, because for example, we want class C to be marked as having final if we def C.foo as
|
|
281
283
|
# final. change this to mod to see some final_method tests fail.
|
|
282
284
|
note_module_deals_with_final(hook_mod)
|
|
@@ -456,13 +458,17 @@ module T::Private::Methods
|
|
|
456
458
|
end
|
|
457
459
|
end
|
|
458
460
|
|
|
461
|
+
def self.all_checked_tests_sigs
|
|
462
|
+
@signatures_by_method.values.select {|sig| sig.check_level == :tests}
|
|
463
|
+
end
|
|
464
|
+
|
|
459
465
|
# the module target is adding the methods from the module source to itself. we need to check that for all instance
|
|
460
466
|
# methods M on source, M is not defined on any of target's ancestors.
|
|
461
467
|
def self._hook_impl(target, singleton_class, source)
|
|
462
468
|
# we do not need to call add_was_ever_final here, because we have already marked
|
|
463
469
|
# any such methods when source was originally defined.
|
|
464
|
-
if !@modules_with_final.include?(target)
|
|
465
|
-
if !@modules_with_final.include?(source)
|
|
470
|
+
if !@modules_with_final.include?(target.object_id)
|
|
471
|
+
if !@modules_with_final.include?(source.object_id)
|
|
466
472
|
return
|
|
467
473
|
end
|
|
468
474
|
note_module_deals_with_final(target)
|
|
@@ -523,7 +529,7 @@ module T::Private::Methods
|
|
|
523
529
|
|
|
524
530
|
def self.install_hooks(mod)
|
|
525
531
|
return if @installed_hooks.include?(mod)
|
|
526
|
-
@installed_hooks
|
|
532
|
+
@installed_hooks[mod] = true
|
|
527
533
|
|
|
528
534
|
if mod == TOP_SELF
|
|
529
535
|
# self at the top-level of a file is weirdly special in Ruby
|