sorbet-runtime 0.5.6437 → 0.5.6453

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e8ecca92c44541d24bb04c5b793a62777aa9a72f927e417710dd170f6c5493f3
4
- data.tar.gz: 0116352dd8ee2baa548ffc479e0e7ef53f76242e0354e61f186d96ae781fa93b
3
+ metadata.gz: aa133acfa00111d8518fe6f2b7306e5f805644c3c89f7d98d865bfcb1544fc99
4
+ data.tar.gz: 8eb1604d0688b7b253762de525ba26d28db324ccf2320e8cac15acfb03b38cad
5
5
  SHA512:
6
- metadata.gz: 1a5d7124fba4d4342ed2bd1760f3e42b0c1a564b127ea13ba3688b967764886c3a922ba68598856c2f4f9442accdbc2b582bb6a22c896d18efaa922fe54506a5
7
- data.tar.gz: 6020c7561fb7c9df1a4b8de96a898adb477cf16f76e82e343d4436d40f8009e5e5dfed7e47250fa1a1ff3ade8fae61c59056e0dd98457491562f2004141af615
6
+ metadata.gz: 597c26f0960c654dd4cc8838428e1ab089773837f0a2514d36bd2f87340d212a205e75b70249667b1629db66c08979c0e1b7edc6ada2e3f676fd5a660c8e1967
7
+ data.tar.gz: fc5ae47c2fedfbe67831f66231a7d69c06f5ad63ba1ba7917e3228b6e392edd2d0fd24a0ae60ff1029f2524f432d72c60e8eef395300f6919e6353c87cc3aeb7
@@ -26,6 +26,8 @@ module T::Private::Methods
26
26
  # in installed_hooks.
27
27
  @old_hooks = nil
28
28
 
29
+ @declaring_final_method = false
30
+
29
31
  ARG_NOT_PROVIDED = Object.new
30
32
  PROC_TYPE = Object.new
31
33
 
@@ -180,6 +182,17 @@ module T::Private::Methods
180
182
  @modules_with_final[mod.singleton_class]
181
183
  end
182
184
 
185
+ # See tests for how to use this.
186
+ def self._with_declaring_final_method_INTERNAL(&blk)
187
+ begin
188
+ prev_value = @declaring_final_method
189
+ @declaring_final_method = true
190
+ yield
191
+ ensure
192
+ @declaring_final_method = prev_value
193
+ end
194
+ end
195
+
183
196
  # Only public because it needs to get called below inside the replace_method blocks below.
184
197
  def self._on_method_added(hook_mod, method_name, is_singleton_method: false)
185
198
  if T::Private::DeclState.current.skip_on_method_added
@@ -189,7 +202,9 @@ module T::Private::Methods
189
202
  current_declaration = T::Private::DeclState.current.active_declaration
190
203
  mod = is_singleton_method ? hook_mod.singleton_class : hook_mod
191
204
 
192
- if T::Private::Final.final_module?(mod) && (current_declaration.nil? || !current_declaration.final)
205
+ directly_declaring_final_method = @declaring_final_method
206
+ method_is_final = directly_declaring_final_method || current_declaration&.final
207
+ if T::Private::Final.final_module?(mod) && !method_is_final
193
208
  raise "#{mod} was declared as final but its method `#{method_name}` was not declared as final"
194
209
  end
195
210
  # Don't compute mod.ancestors if we don't need to bother checking final-ness.
@@ -212,46 +227,49 @@ module T::Private::Methods
212
227
  )
213
228
  end
214
229
 
215
- original_method = mod.instance_method(method_name)
216
- sig_block = lambda do
217
- T::Private::Methods.run_sig(hook_mod, method_name, original_method, current_declaration)
218
- end
219
-
220
- # Always replace the original method with this wrapper,
221
- # which is called only on the *first* invocation.
222
- # This wrapper is very slow, so it will subsequently re-wrap with a much faster wrapper
223
- # (or unwrap back to the original method).
224
- key = method_owner_and_name_to_key(mod, method_name)
225
- T::Private::ClassUtils.replace_method(mod, method_name) do |*args, &blk|
226
- method_sig = T::Private::Methods.maybe_run_sig_block_for_key(key)
227
- method_sig ||= T::Private::Methods._handle_missing_method_signature(
228
- self,
229
- original_method,
230
- __callee__,
231
- )
230
+ unless directly_declaring_final_method
231
+ original_method = mod.instance_method(method_name)
232
+ sig_block = lambda do
233
+ T::Private::Methods.run_sig(hook_mod, method_name, original_method, current_declaration)
234
+ end
232
235
 
233
- # Should be the same logic as CallValidation.wrap_method_if_needed but we
234
- # don't want that extra layer of indirection in the callstack
235
- if method_sig.mode == T::Private::Methods::Modes.abstract
236
- # We're in an interface method, keep going up the chain
237
- if defined?(super)
238
- super(*args, &blk)
236
+ # Always replace the original method with this wrapper,
237
+ # which is called only on the *first* invocation.
238
+ # This wrapper is very slow, so it will subsequently re-wrap with a much faster wrapper
239
+ # (or unwrap back to the original method).
240
+ key = method_owner_and_name_to_key(mod, method_name)
241
+ T::Private::ClassUtils.replace_method(mod, method_name) do |*args, &blk|
242
+ method_sig = T::Private::Methods.maybe_run_sig_block_for_key(key)
243
+ method_sig ||= T::Private::Methods._handle_missing_method_signature(
244
+ self,
245
+ original_method,
246
+ __callee__,
247
+ )
248
+
249
+ # Should be the same logic as CallValidation.wrap_method_if_needed but we
250
+ # don't want that extra layer of indirection in the callstack
251
+ if method_sig.mode == T::Private::Methods::Modes.abstract
252
+ # We're in an interface method, keep going up the chain
253
+ if defined?(super)
254
+ super(*args, &blk)
255
+ else
256
+ raise NotImplementedError.new("The method `#{method_sig.method_name}` on #{mod} is declared as `abstract`. It does not have an implementation.")
257
+ end
258
+ # Note, this logic is duplicated (intentionally, for micro-perf) at `CallValidation.wrap_method_if_needed`,
259
+ # make sure to keep changes in sync.
260
+ elsif method_sig.check_level == :always || (method_sig.check_level == :tests && T::Private::RuntimeLevels.check_tests?)
261
+ CallValidation.validate_call(self, original_method, method_sig, args, blk)
262
+ elsif T::Configuration::AT_LEAST_RUBY_2_7
263
+ original_method.bind_call(self, *args, &blk)
239
264
  else
240
- raise NotImplementedError.new("The method `#{method_sig.method_name}` on #{mod} is declared as `abstract`. It does not have an implementation.")
265
+ original_method.bind(self).call(*args, &blk)
241
266
  end
242
- # Note, this logic is duplicated (intentionally, for micro-perf) at `CallValidation.wrap_method_if_needed`,
243
- # make sure to keep changes in sync.
244
- elsif method_sig.check_level == :always || (method_sig.check_level == :tests && T::Private::RuntimeLevels.check_tests?)
245
- CallValidation.validate_call(self, original_method, method_sig, args, blk)
246
- elsif T::Configuration::AT_LEAST_RUBY_2_7
247
- original_method.bind_call(self, *args, &blk)
248
- else
249
- original_method.bind(self).call(*args, &blk)
250
267
  end
268
+
269
+ @sig_wrappers[key] = sig_block
251
270
  end
252
271
 
253
- @sig_wrappers[key] = sig_block
254
- if current_declaration.final
272
+ if method_is_final
255
273
  @was_ever_final_names.add(method_name)
256
274
  # use hook_mod, not mod, because for example, we want class C to be marked as having final if we def C.foo as
257
275
  # final. change this to mod to see some final_method tests fail.
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sorbet-runtime
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.6437
4
+ version: 0.5.6453
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stripe
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-06-10 00:00:00.000000000 Z
11
+ date: 2021-06-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: minitest