sorbet-runtime 0.5.6330 → 0.5.6346
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 +42 -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: ccd35b0362921e31eb5c9a7bfbab5b33f337eca5e785175db007ce503deaf418
|
4
|
+
data.tar.gz: c44f1a563ea2a4bb6be35068957fcb0d08116745dc26f7ade284bf2dc66d2720
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f8b8cc96bc8ec2a866dd726a7828f5cab96251dbc391d03f29c6ffb5d4555a966a28c216df849d93c539993e19b37d4f73f04bc5244968dc4559705eff9f9a8f
|
7
|
+
data.tar.gz: 84d5da8c69776de610a6103166a8a756885c36fb2095c65d262f495696b06b71b7854dcba4662f50066f62d68c33bfc4ebcb82c15913e6559160740d56a315a1
|
@@ -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,10 +99,10 @@ 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|
|
@@ -149,6 +152,14 @@ module T::Private::Methods
|
|
149
152
|
@final_methods.include?(method_key)
|
150
153
|
end
|
151
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
|
+
|
152
163
|
def self.add_module_with_final(mod)
|
153
164
|
@modules_with_final.add(mod)
|
154
165
|
@modules_with_final.add(mod.singleton_class)
|
@@ -170,7 +181,10 @@ module T::Private::Methods
|
|
170
181
|
if T::Private::Final.final_module?(mod) && (current_declaration.nil? || !current_declaration.final)
|
171
182
|
raise "#{mod} was declared as final but its method `#{method_name}` was not declared as final"
|
172
183
|
end
|
173
|
-
|
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
|
174
188
|
|
175
189
|
# We need to fetch the active declaration again, as _check_final_ancestors
|
176
190
|
# may have reset it (see the comment in that method for details).
|
@@ -230,6 +244,7 @@ module T::Private::Methods
|
|
230
244
|
@sig_wrappers[key] = sig_block
|
231
245
|
if current_declaration.final
|
232
246
|
add_final_method(key)
|
247
|
+
add_was_ever_final(method_name)
|
233
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
|
234
249
|
# final. change this to mod to see some final_method tests fail.
|
235
250
|
add_module_with_final(hook_mod)
|
@@ -408,13 +423,30 @@ module T::Private::Methods
|
|
408
423
|
|
409
424
|
# the module target is adding the methods from the module source to itself. we need to check that for all instance
|
410
425
|
# methods M on source, M is not defined on any of target's ancestors.
|
411
|
-
def self._hook_impl(target,
|
412
|
-
|
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)
|
413
429
|
return
|
414
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.
|
415
433
|
add_module_with_final(target)
|
416
434
|
install_hooks(target)
|
417
|
-
|
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)
|
418
450
|
end
|
419
451
|
|
420
452
|
def self.set_final_checks_on_hooks(enable)
|
@@ -428,15 +460,15 @@ module T::Private::Methods
|
|
428
460
|
else
|
429
461
|
old_included = T::Private::ClassUtils.replace_method(Module, :included) do |arg|
|
430
462
|
old_included.bind(self).call(arg)
|
431
|
-
::T::Private::Methods._hook_impl(arg,
|
463
|
+
::T::Private::Methods._hook_impl(arg, false, self)
|
432
464
|
end
|
433
465
|
old_extended = T::Private::ClassUtils.replace_method(Module, :extended) do |arg|
|
434
466
|
old_extended.bind(self).call(arg)
|
435
|
-
::T::Private::Methods._hook_impl(arg,
|
467
|
+
::T::Private::Methods._hook_impl(arg, true, self)
|
436
468
|
end
|
437
469
|
old_inherited = T::Private::ClassUtils.replace_method(Class, :inherited) do |arg|
|
438
470
|
old_inherited.bind(self).call(arg)
|
439
|
-
::T::Private::Methods._hook_impl(arg,
|
471
|
+
::T::Private::Methods._hook_impl(arg, false, self)
|
440
472
|
end
|
441
473
|
@old_hooks = [old_included, old_extended, old_inherited]
|
442
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.6346
|
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-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: minitest
|