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.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/lib/sorbet-runtime.rb +3 -2
  3. data/lib/types/_types.rb +10 -9
  4. data/lib/types/configuration.rb +76 -56
  5. data/lib/types/enum.rb +4 -9
  6. data/lib/types/helpers.rb +4 -2
  7. data/lib/types/non_forcing_constants.rb +5 -9
  8. data/lib/types/private/abstract/declare.rb +5 -0
  9. data/lib/types/private/casts.rb +2 -10
  10. data/lib/types/private/compiler.rb +24 -0
  11. data/lib/types/private/methods/_methods.rb +25 -19
  12. data/lib/types/private/methods/decl_builder.rb +5 -5
  13. data/lib/types/private/methods/modes.rb +18 -6
  14. data/lib/types/private/methods/signature.rb +1 -1
  15. data/lib/types/private/methods/signature_validation.rb +1 -2
  16. data/lib/types/private/runtime_levels.rb +7 -1
  17. data/lib/types/private/sealed.rb +26 -15
  18. data/lib/types/private/types/not_typed.rb +3 -3
  19. data/lib/types/private/types/string_holder.rb +3 -3
  20. data/lib/types/private/types/type_alias.rb +3 -3
  21. data/lib/types/private/types/void.rb +3 -3
  22. data/lib/types/props/_props.rb +21 -14
  23. data/lib/types/props/custom_type.rb +1 -1
  24. data/lib/types/props/decorator.rb +34 -52
  25. data/lib/types/props/generated_code_validation.rb +1 -1
  26. data/lib/types/props/has_lazily_specialized_methods.rb +5 -0
  27. data/lib/types/props/optional.rb +3 -3
  28. data/lib/types/props/private/serde_transform.rb +3 -3
  29. data/lib/types/props/private/serializer_generator.rb +0 -1
  30. data/lib/types/props/serializable.rb +16 -15
  31. data/lib/types/types/attached_class.rb +3 -3
  32. data/lib/types/types/base.rb +6 -2
  33. data/lib/types/types/class_of.rb +6 -4
  34. data/lib/types/types/enum.rb +5 -7
  35. data/lib/types/types/fixed_array.rb +5 -5
  36. data/lib/types/types/fixed_hash.rb +23 -17
  37. data/lib/types/types/intersection.rb +4 -4
  38. data/lib/types/types/noreturn.rb +3 -3
  39. data/lib/types/types/proc.rb +3 -3
  40. data/lib/types/types/self_type.rb +6 -6
  41. data/lib/types/types/simple.rb +32 -7
  42. data/lib/types/types/t_enum.rb +3 -3
  43. data/lib/types/types/typed_array.rb +3 -3
  44. data/lib/types/types/typed_enumerable.rb +5 -5
  45. data/lib/types/types/typed_enumerator.rb +3 -3
  46. data/lib/types/types/typed_hash.rb +3 -3
  47. data/lib/types/types/typed_range.rb +3 -3
  48. data/lib/types/types/typed_set.rb +15 -3
  49. data/lib/types/types/union.rb +4 -4
  50. data/lib/types/types/untyped.rb +3 -3
  51. data/lib/types/utils.rb +9 -1
  52. metadata +4 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c9b153e0e894eb0a81121fd2c9a2f52cccf1654a78b6fc72d75eacc10d6ee288
4
- data.tar.gz: c09b72a6a28a96d35e9076b206d9019df999659145842f6c2b5ec7d3481e4850
3
+ metadata.gz: 1e5023e6be54c34aae9eaa90bd256fc8e9f15b56d54490f21530fb6ebac519fe
4
+ data.tar.gz: 43e21db8ed3660374e82d0017fcbca9768e3b8ce15ffe85997aa854e2338d47c
5
5
  SHA512:
6
- metadata.gz: 948194b8718dd728ecaa0668421480103ce052587c6ceebee0ec01818ecf529d0a62715f0c66409ff07594c6ad4c8c0f22a05921129c66cb405f2fe143b46705
7
- data.tar.gz: a788eea54fe2321d6060a79ef31ab784b21a6a4e9e15b299600abbe9699e4cc8095eaa69bedbfc07fa5f2a3e3ef959e002562db705050f8882878dbb15b6a14e
6
+ metadata.gz: c2d2348cd0cf77820a3e3b5a5f935cf9bebc481dd2e85c4af01c642601d95215f3fe00f8c3145ccaf98626d4bc8815013e74b8d4c80c9f6b8159ec6f443e739a
7
+ data.tar.gz: ff45d3aa7343c2874d369d422b9690342c91c7a1f650229b108fef3bc9f7a92e68a06ca5fe38391a40aa6163a6839e63bc02dbcded7ea26d635338b359b514c5
@@ -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
- def self.enum(values)
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. Example usage:
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. Example usage:
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
 
@@ -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
- # @param [TypeError] error TypeError that was raised
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
- @inline_type_error_handler.call(error)
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
- # @param [StandardError] error The error that was raised
173
- # @param [Thread::Backtrace::Location] location Location of the error
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
- # @param [StandardError] error The error that was raised
215
- # @param [Hash] opts A hash containing contextual information on the error:
216
- # @option opts [Method, UnboundMethod] :method Method on which the signature build failed
217
- # @option opts [T::Private::Methods::Declaration] :declaration Method
218
- # signature declaration struct
219
- # @option opts [T::Private::Methods::Signature, nil] :signature Signature
220
- # that failed (nil if sig build failed before Signature initialization)
221
- # @option opts [T::Private::Methods::Signature, nil] :super_signature Super
222
- # method's signature (nil if method is not an override or super method
223
- # does not have a method signature)
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
- # @param [T::Private::Methods::Signature] signature Signature that failed
260
- # @param [Hash] opts A hash containing contextual information on the error:
261
- # @option opts [String] :message Error message
262
- # @option opts [String] :kind One of:
263
- # ['Parameter', 'Block parameter', 'Return value']
264
- # @option opts [Symbol] :name Param or block param name (nil for return
265
- # value)
266
- # @option opts [Object] :type Expected param/return value type
267
- # @option opts [Object] :value Actual param/return value
268
- # @option opts [Thread::Backtrace::Location] :location Location of the
269
- # caller
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
- # @param [String] str Message to be logged
301
- # @param [Hash] extra A hash containing additional parameters to be passed along to the logger.
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
- # @param [String] str Assertion message
335
- # @param [Hash] extra A hash containing additional parameters to be passed along to the handler.
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
- # @param [String] str Assertion message
369
- # @param [Hash] extra A hash containing additional parameters to be passed along to the handler.
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] value Class name.
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 = Set.new(values).freeze
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 = Set.new(%w[
413
- NilClass
414
- TrueClass
415
- FalseClass
416
- Integer
417
- Float
418
- String
419
- Symbol
420
- Time
421
- T::Enum
422
- ]).freeze
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
- @default_module_name_mangler = ->(type) {MODULE_NAME.bind_call(type)}
442
+ @default_module_name_mangler = if T::Configuration::AT_LEAST_RUBY_2_7
443
+ ->(type) {MODULE_NAME.bind_call(type)}
434
444
  else
435
- @default_module_name_mangler = ->(type) {MODULE_NAME.bind(type).call}
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] value Proc that converts a type (Class/Module)
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] value Proc that takes a hash mapping symbols to the
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] value Proc that converts a value into its
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] value Proc that takes a class and
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
- ## Enum class methods ##
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(mod, *mods); end
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
- # TODO(gdritter): this might not be want we want in a multipackage
20
- # world; revisit this implementation we move on from the monopackage
21
- if stripe_packages_enabled?
22
- klass = "PkgRegistry::#{package}::#{klass}"
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
@@ -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 = Set.new
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 = Set.new
12
- # maps from modules to the set of final methods declared in that module.
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 { |hash, key| hash[key] = nil }
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
- methods = @modules_with_final[m]
191
+ mid = m.object_id
192
+ methods = @modules_with_final[mid]
192
193
  if methods.nil?
193
- methods = Set.new
194
- @modules_with_final[m] = methods
194
+ methods = {}
195
+ @modules_with_final[mid] = methods
195
196
  end
196
- methods.add(method_name)
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.add(method_name)
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 << mod
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