sorbet-runtime 0.5.9103 → 0.5.9368

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 (46) hide show
  1. checksums.yaml +4 -4
  2. data/lib/sorbet-runtime.rb +2 -4
  3. data/lib/types/_types.rb +10 -7
  4. data/lib/types/configuration.rb +62 -52
  5. data/lib/types/enum.rb +3 -3
  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 -2
  10. data/lib/types/private/methods/_methods.rb +32 -27
  11. data/lib/types/private/methods/decl_builder.rb +103 -7
  12. data/lib/types/private/methods/signature.rb +1 -1
  13. data/lib/types/private/sealed.rb +26 -15
  14. data/lib/types/private/types/not_typed.rb +3 -3
  15. data/lib/types/private/types/string_holder.rb +3 -3
  16. data/lib/types/private/types/type_alias.rb +3 -3
  17. data/lib/types/private/types/void.rb +3 -3
  18. data/lib/types/props/_props.rb +6 -9
  19. data/lib/types/props/custom_type.rb +1 -1
  20. data/lib/types/props/decorator.rb +6 -48
  21. data/lib/types/props/has_lazily_specialized_methods.rb +5 -0
  22. data/lib/types/props/private/serde_transform.rb +3 -3
  23. data/lib/types/props/serializable.rb +1 -3
  24. data/lib/types/sig.rb +46 -3
  25. data/lib/types/types/attached_class.rb +3 -3
  26. data/lib/types/types/base.rb +6 -2
  27. data/lib/types/types/class_of.rb +4 -4
  28. data/lib/types/types/enum.rb +5 -7
  29. data/lib/types/types/fixed_array.rb +5 -5
  30. data/lib/types/types/fixed_hash.rb +7 -7
  31. data/lib/types/types/intersection.rb +4 -4
  32. data/lib/types/types/noreturn.rb +3 -3
  33. data/lib/types/types/proc.rb +3 -3
  34. data/lib/types/types/self_type.rb +3 -3
  35. data/lib/types/types/simple.rb +22 -5
  36. data/lib/types/types/t_enum.rb +3 -3
  37. data/lib/types/types/typed_array.rb +3 -3
  38. data/lib/types/types/typed_enumerable.rb +5 -5
  39. data/lib/types/types/typed_enumerator.rb +3 -3
  40. data/lib/types/types/typed_hash.rb +3 -3
  41. data/lib/types/types/typed_range.rb +3 -3
  42. data/lib/types/types/typed_set.rb +15 -3
  43. data/lib/types/types/union.rb +4 -4
  44. data/lib/types/types/untyped.rb +3 -3
  45. data/lib/types/utils.rb +1 -1
  46. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dd50aa97fa3835f75f05ddad407ced4062053e791cb9c246a4ac617cb6e4eeb5
4
- data.tar.gz: dd7a5031c72ae5ce3a09324d2b110c343e1409e350c12b1a8bf8a1bf21763c90
3
+ metadata.gz: c091500cbf7054e5603c1258b3295f49f151b0d40e5353d2f904d520f5f98da0
4
+ data.tar.gz: 61a637921e738a248610afe0a6281af23cbef7f337e01db379583c32c837eee1
5
5
  SHA512:
6
- metadata.gz: fa6efdc3b42d1b42322af825df44bf33c625cc24b2d93f5474887218f686604e8603db6c19afae00c29c6e32e1e1ecceb52a07de68471ec9cf18aea01ab98ef4
7
- data.tar.gz: a16780c9665e17e0666d2e2b04a5b60a04a7b02863f111d3a068e2b5c7b32b72334b246b00e76ddfa98d1a64fd78c79fa1467e03d19d80203c0bc5ccacf28b6c
6
+ metadata.gz: ab2e881510a729c50a1f75ae6326ed206c371233d9e61c43f479969889c47d2a93550ce6dc8b7dd84c5ebe87e622848074d41d31397cd690113aa353544cb6c8
7
+ data.tar.gz: 5f4c1f1a8dacfc9c1e987a6124acea43d52ccf8ef8999eec0d35cf3c126f588cf2dc2ae1c58b1ef0c513a9b8b7b2c97fbd34cf11870d5a516735551abbb8e0c3
@@ -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
 
@@ -24,6 +22,8 @@ require_relative 'types/private/decl_state'
24
22
  require_relative 'types/private/class_utils'
25
23
  require_relative 'types/private/runtime_levels'
26
24
  require_relative 'types/private/methods/_methods'
25
+ require_relative 'types/private/methods/modes'
26
+ require_relative 'types/private/methods/decl_builder'
27
27
  require_relative 'types/sig'
28
28
  require_relative 'types/helpers'
29
29
  require_relative 'types/private/final'
@@ -62,7 +62,6 @@ require_relative 'types/types/type_member'
62
62
  require_relative 'types/types/type_template'
63
63
 
64
64
  # Call validation
65
- require_relative 'types/private/methods/modes'
66
65
  require_relative 'types/private/methods/call_validation'
67
66
 
68
67
  # Signature validation
@@ -76,7 +75,6 @@ require_relative 'types/interface_wrapper'
76
75
  require_relative 'types/private/abstract/declare'
77
76
  require_relative 'types/private/abstract/hooks'
78
77
  require_relative 'types/private/casts'
79
- require_relative 'types/private/methods/decl_builder'
80
78
  require_relative 'types/private/methods/signature'
81
79
  require_relative 'types/private/retry'
82
80
  require_relative 'types/utils'
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
 
@@ -82,8 +83,9 @@ module T
82
83
 
83
84
  # Constructs a type alias. Used to create a short name for a larger type. In Ruby this returns a
84
85
  # 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:
86
+ # is needed for support by the static checker.
86
87
  #
88
+ # @example
87
89
  # NilableString = T.type_alias {T.nilable(String)}
88
90
  #
89
91
  # sig {params(arg: NilableString, default: String).returns(String)}
@@ -106,8 +108,9 @@ module T
106
108
  # References a type parameter which was previously defined with
107
109
  # `type_parameters`.
108
110
  #
109
- # This is used for generic methods. Example usage:
111
+ # This is used for generic methods.
110
112
  #
113
+ # @example
111
114
  # sig
112
115
  # .type_parameters(:U)
113
116
  # .params(
@@ -185,7 +188,7 @@ module T
185
188
  # cycle. However, we also don't actually need to do so; An untyped
186
189
  # identity method works just as well here.
187
190
  #
188
- # sig {params(value: T.untyped).returns(T.untyped)}
191
+ # `sig {params(value: T.untyped).returns(T.untyped)}`
189
192
  def self.unsafe(value)
190
193
  value
191
194
  end
@@ -206,7 +209,7 @@ module T
206
209
  # Intended to be used to promise sorbet that a given nilable value happens
207
210
  # to contain a non-nil value at this point.
208
211
  #
209
- # sig {params(arg: T.nilable(A)).returns(A)}
212
+ # `sig {params(arg: T.nilable(A)).returns(A)}`
210
213
  def self.must(arg)
211
214
  return arg if arg
212
215
  return arg if arg == false
@@ -214,7 +217,7 @@ module T
214
217
  begin
215
218
  raise TypeError.new("Passed `nil` into T.must")
216
219
  rescue TypeError => e # raise into rescue to ensure e.backtrace is populated
217
- T::Configuration.inline_type_error_handler(e)
220
+ T::Configuration.inline_type_error_handler(e, {kind: 'T.must', value: arg, type: nil})
218
221
  end
219
222
  end
220
223
 
@@ -239,7 +242,7 @@ module T
239
242
  begin
240
243
  raise TypeError.new(msg)
241
244
  rescue TypeError => e # raise into rescue to ensure e.backtrace is populated
242
- T::Configuration.inline_type_error_handler(e)
245
+ T::Configuration.inline_type_error_handler(e, {kind: 'T.absurd', value: value, type: nil})
243
246
  end
244
247
  end
245
248
 
@@ -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
@@ -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
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,7 +134,7 @@ class T::Enum
134
134
  self.from_serialized(mongo_value)
135
135
  end
136
136
 
137
- ## Enum instance methods ##
137
+ ### Enum instance methods ###
138
138
 
139
139
  sig {returns(T.self_type)}
140
140
  def dup
@@ -243,7 +243,7 @@ class T::Enum
243
243
  )
244
244
  end
245
245
 
246
- ## Private implementation ##
246
+ ### Private implementation ###
247
247
 
248
248
  sig {params(serialized_val: SerializedVal).void}
249
249
  def initialize(serialized_val=nil)
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
@@ -14,7 +14,7 @@ module T::Private
14
14
 
15
15
  raise TypeError.new("#{cast_method}: #{error}\n#{suffix}")
16
16
  rescue TypeError => e # raise into rescue to ensure e.backtrace is populated
17
- T::Configuration.inline_type_error_handler(e)
17
+ T::Configuration.inline_type_error_handler(e, {kind: cast_method, value: value, type: type})
18
18
  value
19
19
  end
20
20
  end
@@ -33,7 +33,7 @@ module T::Private
33
33
 
34
34
  raise TypeError.new("#{cast_method}: #{error}\n#{suffix}")
35
35
  rescue TypeError => e # raise into rescue to ensure e.backtrace is populated
36
- T::Configuration.inline_type_error_handler(e)
36
+ T::Configuration.inline_type_error_handler(e, {kind: cast_method, value: value, type: type})
37
37
  value
38
38
  end
39
39
  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.
@@ -29,12 +29,13 @@ module T::Private::Methods
29
29
  ARG_NOT_PROVIDED = Object.new
30
30
  PROC_TYPE = Object.new
31
31
 
32
- DeclarationBlock = Struct.new(:mod, :loc, :blk, :final, :raw)
32
+ DeclarationBlock = Struct.new(:mod, :loc, :blk, :raw, :decl_builder)
33
33
 
34
34
  def self.declare_sig(mod, loc, arg, &blk)
35
- T::Private::DeclState.current.active_declaration = _declare_sig_internal(mod, loc, arg, &blk)
35
+ declaration = _declare_sig_internal(mod, loc, arg, &blk)
36
+ T::Private::DeclState.current.active_declaration = declaration
36
37
 
37
- nil
38
+ declaration.decl_builder
38
39
  end
39
40
 
40
41
  # See tests for how to use this. But you shouldn't be using this.
@@ -54,7 +55,10 @@ module T::Private::Methods
54
55
  raise "Invalid argument to `sig`: #{arg}"
55
56
  end
56
57
 
57
- DeclarationBlock.new(mod, loc, blk, arg == :final, raw)
58
+ decl_builder = DeclBuilder.new(mod, raw)
59
+ decl_builder.final if arg == :final # needed for backwards compatibility with sig(:final) {...}
60
+
61
+ DeclarationBlock.new(mod, loc, blk, raw, decl_builder)
58
62
  end
59
63
 
60
64
  def self._with_declared_signature(mod, declblock, &blk)
@@ -127,7 +131,7 @@ module T::Private::Methods
127
131
  source_ancestors = nil
128
132
  # use reverse_each to check farther-up ancestors first, for better error messages.
129
133
  target_ancestors.reverse_each do |ancestor|
130
- final_methods = @modules_with_final.fetch(ancestor, nil)
134
+ final_methods = @modules_with_final.fetch(ancestor.object_id, nil)
131
135
  # In this case, either ancestor didn't have any final methods anywhere in its
132
136
  # ancestor chain, or ancestor did have final methods somewhere in its ancestor
133
137
  # chain, but no final methods defined in ancestor itself. Either way, there
@@ -145,13 +149,13 @@ module T::Private::Methods
145
149
  # filter out things without actual final methods just to make sure that
146
150
  # the below checks (which should be uncommon) go as quickly as possible.
147
151
  source_ancestors.select! do |a|
148
- @modules_with_final.fetch(a, nil)
152
+ @modules_with_final.fetch(a.object_id, nil)
149
153
  end
150
154
  end
151
155
  # final-ness means that there should be no more than one index for which
152
156
  # the below block returns true.
153
157
  defining_ancestor_idx = source_ancestors.index do |a|
154
- @modules_with_final.fetch(a).include?(method_name)
158
+ @modules_with_final.fetch(a.object_id).include?(method_name)
155
159
  end
156
160
  next if defining_ancestor_idx && source_ancestors[defining_ancestor_idx] == ancestor
157
161
  end
@@ -188,18 +192,20 @@ module T::Private::Methods
188
192
 
189
193
  def self.add_module_with_final_method(mod, method_name, is_singleton_method)
190
194
  m = is_singleton_method ? mod.singleton_class : mod
191
- methods = @modules_with_final[m]
195
+ mid = m.object_id
196
+ methods = @modules_with_final[mid]
192
197
  if methods.nil?
193
- methods = Set.new
194
- @modules_with_final[m] = methods
198
+ methods = {}
199
+ @modules_with_final[mid] = methods
195
200
  end
196
- methods.add(method_name)
201
+ methods[method_name] = true
202
+ nil
197
203
  end
198
204
 
199
205
  def self.note_module_deals_with_final(mod)
200
206
  # Side-effectfully initialize the value if it's not already there
201
- @modules_with_final[mod]
202
- @modules_with_final[mod.singleton_class]
207
+ @modules_with_final[mod.object_id]
208
+ @modules_with_final[mod.singleton_class.object_id]
203
209
  end
204
210
 
205
211
  # Only public because it needs to get called below inside the replace_method blocks below.
@@ -211,11 +217,11 @@ module T::Private::Methods
211
217
  current_declaration = T::Private::DeclState.current.active_declaration
212
218
  mod = is_singleton_method ? hook_mod.singleton_class : hook_mod
213
219
 
214
- if T::Private::Final.final_module?(mod) && (current_declaration.nil? || !current_declaration.final)
220
+ if T::Private::Final.final_module?(mod) && (current_declaration.nil? || !current_declaration.decl_builder.final?)
215
221
  raise "#{mod} was declared as final but its method `#{method_name}` was not declared as final"
216
222
  end
217
223
  # 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)
224
+ if @was_ever_final_names.include?(method_name) && @modules_with_final.include?(mod.object_id)
219
225
  _check_final_ancestors(mod, mod.ancestors, [method_name], nil)
220
226
  # We need to fetch the active declaration again, as _check_final_ancestors
221
227
  # may have reset it (see the comment in that method for details).
@@ -275,8 +281,8 @@ module T::Private::Methods
275
281
  end
276
282
 
277
283
  @sig_wrappers[key] = sig_block
278
- if current_declaration.final
279
- @was_ever_final_names.add(method_name)
284
+ if current_declaration.decl_builder.final?
285
+ @was_ever_final_names[method_name] = true
280
286
  # 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
287
  # final. change this to mod to see some final_method tests fail.
282
288
  note_module_deals_with_final(hook_mod)
@@ -344,10 +350,9 @@ module T::Private::Methods
344
350
  end
345
351
 
346
352
  def self.run_builder(declaration_block)
347
- builder = DeclBuilder.new(declaration_block.mod, declaration_block.raw)
348
- builder
349
- .instance_exec(&declaration_block.blk)
350
- .finalize!
353
+ declaration_block
354
+ .decl_builder
355
+ .run!(&declaration_block.blk)
351
356
  .decl
352
357
  end
353
358
 
@@ -465,8 +470,8 @@ module T::Private::Methods
465
470
  def self._hook_impl(target, singleton_class, source)
466
471
  # we do not need to call add_was_ever_final here, because we have already marked
467
472
  # any such methods when source was originally defined.
468
- if !@modules_with_final.include?(target)
469
- if !@modules_with_final.include?(source)
473
+ if !@modules_with_final.include?(target.object_id)
474
+ if !@modules_with_final.include?(source.object_id)
470
475
  return
471
476
  end
472
477
  note_module_deals_with_final(target)
@@ -527,7 +532,7 @@ module T::Private::Methods
527
532
 
528
533
  def self.install_hooks(mod)
529
534
  return if @installed_hooks.include?(mod)
530
- @installed_hooks << mod
535
+ @installed_hooks[mod] = true
531
536
 
532
537
  if mod == TOP_SELF
533
538
  # self at the top-level of a file is weirdly special in Ruby