sorbet-runtime 0.5.6322 → 0.5.6338
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/types/private/methods/_methods.rb +43 -10
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3671ed176f9cf1875148797095dcda29672ad803d5ede745ec3aac0e8ddacd31
|
4
|
+
data.tar.gz: '019c5545c3bdff3a7f1aad4c0eaefdc57f0172a13413aa59236b27da8609e89f'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 18c9836a43d62d5c73f8c7d4dd402496ed523e6beaa389eda774b207c4aaacb7499f83936f32a8d4efcf72559f0b2a06b341a89bd31aa41ca7168359ecf03462
|
7
|
+
data.tar.gz: da19c72bf63324a8f09ef63b811edba84f84c26bc545025c1ca354e03626c774bbf1fc3ada5051c7393678d056ad10106f73ffdb24a790d14564b9b7ebf10797
|
@@ -11,6 +11,9 @@ module T::Private::Methods
|
|
11
11
|
# - they are done possibly before any sig block has run.
|
12
12
|
# - they are done even if the method being defined doesn't have a sig.
|
13
13
|
@final_methods = Set.new
|
14
|
+
# stores method names that were declared final without regard for where.
|
15
|
+
# enables early rejection of names that we know can't induce final method violations.
|
16
|
+
@was_ever_final_names = Set.new
|
14
17
|
# a non-singleton is a module for which at least one of the following is true:
|
15
18
|
# - is declared final
|
16
19
|
# - defines a method that is declared final
|
@@ -96,13 +99,14 @@ module T::Private::Methods
|
|
96
99
|
# when target includes a module with instance methods source_method_names, ensure there is zero intersection between
|
97
100
|
# the final instance methods of target and source_method_names. so, for every m in source_method_names, check if there
|
98
101
|
# is already a method defined on one of target_ancestors with the same name that is final.
|
102
|
+
#
|
103
|
+
# we assume that source_method_names has already been filtered to only include method
|
104
|
+
# names that were declared final at one point.
|
99
105
|
def self._check_final_ancestors(target, target_ancestors, source_method_names)
|
100
|
-
if !module_with_final?(target)
|
101
|
-
return
|
102
|
-
end
|
103
106
|
# use reverse_each to check farther-up ancestors first, for better error messages. we could avoid this if we were on
|
104
107
|
# the version of ruby that adds the optional argument to method_defined? that allows you to exclude ancestors.
|
105
108
|
target_ancestors.reverse_each do |ancestor|
|
109
|
+
next if !module_with_final?(ancestor)
|
106
110
|
source_method_names.each do |method_name|
|
107
111
|
# the usage of method_owner_and_name_to_key(ancestor, method_name) instead of
|
108
112
|
# method_to_key(ancestor.instance_method(method_name)) is not (just) an optimization, but also required for
|
@@ -148,6 +152,14 @@ module T::Private::Methods
|
|
148
152
|
@final_methods.include?(method_key)
|
149
153
|
end
|
150
154
|
|
155
|
+
private_class_method def self.add_was_ever_final(method_name)
|
156
|
+
@was_ever_final_names.add(method_name)
|
157
|
+
end
|
158
|
+
|
159
|
+
private_class_method def self.was_ever_final?(method_name)
|
160
|
+
@was_ever_final_names.include?(method_name)
|
161
|
+
end
|
162
|
+
|
151
163
|
def self.add_module_with_final(mod)
|
152
164
|
@modules_with_final.add(mod)
|
153
165
|
@modules_with_final.add(mod.singleton_class)
|
@@ -169,7 +181,10 @@ module T::Private::Methods
|
|
169
181
|
if T::Private::Final.final_module?(mod) && (current_declaration.nil? || !current_declaration.final)
|
170
182
|
raise "#{mod} was declared as final but its method `#{method_name}` was not declared as final"
|
171
183
|
end
|
172
|
-
|
184
|
+
# Don't compute mod.ancestors if we don't need to bother checking final-ness.
|
185
|
+
if was_ever_final?(method_name) && module_with_final?(mod)
|
186
|
+
_check_final_ancestors(mod, mod.ancestors, [method_name])
|
187
|
+
end
|
173
188
|
|
174
189
|
# We need to fetch the active declaration again, as _check_final_ancestors
|
175
190
|
# may have reset it (see the comment in that method for details).
|
@@ -229,6 +244,7 @@ module T::Private::Methods
|
|
229
244
|
@sig_wrappers[key] = sig_block
|
230
245
|
if current_declaration.final
|
231
246
|
add_final_method(key)
|
247
|
+
add_was_ever_final(method_name)
|
232
248
|
# use hook_mod, not mod, because for example, we want class C to be marked as having final if we def C.foo as
|
233
249
|
# final. change this to mod to see some final_method tests fail.
|
234
250
|
add_module_with_final(hook_mod)
|
@@ -407,13 +423,30 @@ module T::Private::Methods
|
|
407
423
|
|
408
424
|
# the module target is adding the methods from the module source to itself. we need to check that for all instance
|
409
425
|
# methods M on source, M is not defined on any of target's ancestors.
|
410
|
-
def self._hook_impl(target,
|
411
|
-
|
426
|
+
def self._hook_impl(target, singleton_class, source)
|
427
|
+
target_was_final = module_with_final?(target)
|
428
|
+
if !target_was_final && !module_with_final?(source)
|
412
429
|
return
|
413
430
|
end
|
431
|
+
# we do not need to call add_was_ever_final here, because we have already marked
|
432
|
+
# any such methods when source was originally defined.
|
414
433
|
add_module_with_final(target)
|
415
434
|
install_hooks(target)
|
416
|
-
|
435
|
+
|
436
|
+
if !target_was_final
|
437
|
+
return
|
438
|
+
end
|
439
|
+
|
440
|
+
methods = source.instance_methods
|
441
|
+
methods.select! do |method_name|
|
442
|
+
was_ever_final?(method_name)
|
443
|
+
end
|
444
|
+
if methods.empty?
|
445
|
+
return
|
446
|
+
end
|
447
|
+
|
448
|
+
target_ancestors = singleton_class ? target.singleton_class.ancestors : target.ancestors
|
449
|
+
_check_final_ancestors(target, target_ancestors - source.ancestors, methods)
|
417
450
|
end
|
418
451
|
|
419
452
|
def self.set_final_checks_on_hooks(enable)
|
@@ -427,15 +460,15 @@ module T::Private::Methods
|
|
427
460
|
else
|
428
461
|
old_included = T::Private::ClassUtils.replace_method(Module, :included) do |arg|
|
429
462
|
old_included.bind(self).call(arg)
|
430
|
-
::T::Private::Methods._hook_impl(arg,
|
463
|
+
::T::Private::Methods._hook_impl(arg, false, self)
|
431
464
|
end
|
432
465
|
old_extended = T::Private::ClassUtils.replace_method(Module, :extended) do |arg|
|
433
466
|
old_extended.bind(self).call(arg)
|
434
|
-
::T::Private::Methods._hook_impl(arg,
|
467
|
+
::T::Private::Methods._hook_impl(arg, true, self)
|
435
468
|
end
|
436
469
|
old_inherited = T::Private::ClassUtils.replace_method(Class, :inherited) do |arg|
|
437
470
|
old_inherited.bind(self).call(arg)
|
438
|
-
::T::Private::Methods._hook_impl(arg,
|
471
|
+
::T::Private::Methods._hook_impl(arg, false, self)
|
439
472
|
end
|
440
473
|
@old_hooks = [old_included, old_extended, old_inherited]
|
441
474
|
end
|
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.
|
4
|
+
version: 0.5.6338
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Stripe
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-03-
|
11
|
+
date: 2021-03-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: minitest
|