sorbet-runtime 0.6.12984 → 0.6.13286
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.
- checksums.yaml +4 -4
- data/lib/sorbet-runtime.rb +1 -0
- data/lib/types/_types.rb +5 -1
- data/lib/types/compatibility_patches.rb +42 -0
- data/lib/types/configuration.rb +1 -1
- data/lib/types/helpers.rb +0 -2
- data/lib/types/private/abstract/hooks.rb +1 -1
- data/lib/types/private/abstract/validate.rb +4 -4
- data/lib/types/private/casts.rb +1 -1
- data/lib/types/private/class_utils.rb +30 -71
- data/lib/types/private/final.rb +4 -4
- data/lib/types/private/methods/_methods.rb +129 -147
- data/lib/types/private/methods/call_validation.rb +50 -28
- data/lib/types/private/methods/call_validation_2_7.rb +32 -32
- data/lib/types/private/methods/decl_builder.rb +15 -17
- data/lib/types/private/methods/signature.rb +41 -27
- data/lib/types/private/methods/signature_validation.rb +37 -46
- data/lib/types/private/runtime_levels.rb +1 -1
- data/lib/types/private/sealed.rb +3 -3
- data/lib/types/sig.rb +72 -1
- data/lib/types/struct.rb +4 -2
- data/lib/types/types/fixed_array.rb +3 -3
- data/lib/types/types/simple.rb +6 -6
- data/lib/types/types/typed_range.rb +10 -0
- data/lib/types/types/union.rb +1 -1
- data/lib/types/utils.rb +1 -1
- metadata +16 -16
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e2b15b12f019d99d0883d3987d7bd205a368b8646b8c998328967023be62d8a1
|
|
4
|
+
data.tar.gz: dbed6520ccd76a2ac122f63cfee589811b4ea570d72d994b0c6e1e2391640e8e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a30b5d79bb6b5ae5dd11b6a82bdec010bb00ba90d386db70a9fa8ff191180e2a264f89243f45674a7db2d6f7c17f6856d6b32e0795cacb6717852c1e2a902c1a
|
|
7
|
+
data.tar.gz: 69d156afa66059195cbc8cf6d5aad958cfc5132959fc18842716d8df563a4f08788e24fd9a43313ba7e667f4e81c30abed3e1aa03a90ee021d267d9061df9ba3
|
data/lib/sorbet-runtime.rb
CHANGED
data/lib/types/_types.rb
CHANGED
|
@@ -51,6 +51,48 @@ if defined? ::RSpec::Mocks
|
|
|
51
51
|
end
|
|
52
52
|
end
|
|
53
53
|
|
|
54
|
+
# Allow using `sig {...}` on top of a `let`-defined method in an RSpec example group
|
|
55
|
+
if defined? ::RSpec::Core::MemoizedHelpers::ClassMethods
|
|
56
|
+
module T
|
|
57
|
+
module CompatibilityPatches
|
|
58
|
+
module RSpecCompatibility
|
|
59
|
+
module MemoizedHelpers
|
|
60
|
+
# `let!`, `subject`, and `subject!` are implemented by dispatching to
|
|
61
|
+
# `let`, so this should cover those methods too.
|
|
62
|
+
def let(name, &block)
|
|
63
|
+
res = T::Private::DeclState.current.without_on_method_added do
|
|
64
|
+
# Allow the `let`-defined methods to be defined
|
|
65
|
+
super
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
return res unless T::Private::DeclState.current.active_declaration
|
|
69
|
+
|
|
70
|
+
# Force the `sig` to attach to the outer `let`-defined method,
|
|
71
|
+
# not the one inside the `LetDefinitions` module. Re-running
|
|
72
|
+
# `define_method` with the method we grab via reflection there
|
|
73
|
+
# triggers the `method_added`, which allows the active_declaration
|
|
74
|
+
# to be consumed.
|
|
75
|
+
#
|
|
76
|
+
# Unfortunately, this means that the runtime checks are not
|
|
77
|
+
# memoized (but they never were).
|
|
78
|
+
#
|
|
79
|
+
# (An alternative approach of pretending that the `sig` was actually
|
|
80
|
+
# written inside the `LetDefinitions` module didn't work, because
|
|
81
|
+
# things like `sig {override}` broke: the `LetDefinitions` module
|
|
82
|
+
# has no ancestors and thus does not override anything)
|
|
83
|
+
method = instance_method(name)
|
|
84
|
+
remove_method(name)
|
|
85
|
+
define_method(name, method)
|
|
86
|
+
|
|
87
|
+
res
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
::RSpec::Core::MemoizedHelpers::ClassMethods.prepend(MemoizedHelpers)
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
54
96
|
# Work around for sorbet-runtime wrapped methods.
|
|
55
97
|
#
|
|
56
98
|
# When a sig is defined, sorbet-runtime will replace the sigged method
|
data/lib/types/configuration.rb
CHANGED
data/lib/types/helpers.rb
CHANGED
|
@@ -27,7 +27,7 @@ module T::Private::Abstract::Hooks
|
|
|
27
27
|
# `self` may not actually be abstract -- it could be a concrete class that inherited from an
|
|
28
28
|
# abstract class. We only need to check this in `inherited` because, for modules being included
|
|
29
29
|
# or extended, the concrete ones won't have these hooks at all. This is just an optimization.
|
|
30
|
-
return if !T::AbstractUtils.abstract_module?(self)
|
|
30
|
+
return if !T::AbstractUtils.abstract_module?(T.unsafe(self))
|
|
31
31
|
|
|
32
32
|
T::Private::Abstract::Data.set(self, :last_used_by, other)
|
|
33
33
|
end
|
|
@@ -9,7 +9,7 @@ module T::Private::Abstract::Validate
|
|
|
9
9
|
|
|
10
10
|
def self.validate_abstract_module(mod)
|
|
11
11
|
type = Abstract::Data.get(mod, :abstract_type)
|
|
12
|
-
validate_interface(mod) if
|
|
12
|
+
validate_interface(mod) if :interface == type
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
# Validates a class/module with an abstract class/module as an ancestor. This must be called
|
|
@@ -56,7 +56,7 @@ module T::Private::Abstract::Validate
|
|
|
56
56
|
# signature and (b) methods from ancestors (note that these ancestors can come before or
|
|
57
57
|
# after the abstract module in the inheritance chain -- the former coming from
|
|
58
58
|
# walking `mod.ancestors` above).
|
|
59
|
-
abstract_signature = Methods.signature_for_method(abstract_method)
|
|
59
|
+
abstract_signature = Methods.signature_for_method(abstract_method) || raise("Method being abstract must imply it has a signature")
|
|
60
60
|
# We allow implementation methods to be defined without a signature.
|
|
61
61
|
# In that case, get its untyped signature.
|
|
62
62
|
implementation_signature ||= Methods::Signature.new_untyped(
|
|
@@ -111,8 +111,8 @@ module T::Private::Abstract::Validate
|
|
|
111
111
|
end
|
|
112
112
|
|
|
113
113
|
private_class_method def self.describe_method(method, show_owner: true)
|
|
114
|
-
loc = if method.source_location
|
|
115
|
-
|
|
114
|
+
loc = if (source_loc = method.source_location)
|
|
115
|
+
source_loc.join(':')
|
|
116
116
|
else
|
|
117
117
|
"<unknown location>"
|
|
118
118
|
end
|
data/lib/types/private/casts.rb
CHANGED
|
@@ -1,63 +1,16 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
-
# typed:
|
|
2
|
+
# typed: true
|
|
3
3
|
|
|
4
4
|
# Cut down version of Chalk::Tools::ClassUtils with only :replace_method functionality.
|
|
5
5
|
# Extracted to a separate namespace so the type system can be used standalone.
|
|
6
|
+
#
|
|
7
|
+
# Note: the functionality to "restore" a method was removed, because it is no
|
|
8
|
+
# longer being used by sorbet-runtime. Restoring a method requires care--if you
|
|
9
|
+
# need to reintroduce this functionality, consult the git history for how to do
|
|
10
|
+
# it safely.
|
|
6
11
|
module T::Private::ClassUtils
|
|
7
|
-
class ReplacedMethod
|
|
8
|
-
def initialize(mod, old_method, new_method, overwritten, visibility)
|
|
9
|
-
if old_method.name != new_method.name
|
|
10
|
-
raise "Method names must match. old=#{old_method.name} new=#{new_method.name}"
|
|
11
|
-
end
|
|
12
|
-
@mod = mod
|
|
13
|
-
@old_method = old_method
|
|
14
|
-
@new_method = new_method
|
|
15
|
-
@overwritten = overwritten
|
|
16
|
-
@name = old_method.name
|
|
17
|
-
@visibility = visibility
|
|
18
|
-
@restored = false
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
def restore
|
|
22
|
-
# The check below would also catch this, but this makes the failure mode much clearer
|
|
23
|
-
if @restored
|
|
24
|
-
raise "Method '#{@name}' on '#{@mod}' was already restored"
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
if @mod.instance_method(@name) != @new_method
|
|
28
|
-
raise "Trying to restore #{@mod}##{@name} but the method has changed since the call to replace_method"
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
@restored = true
|
|
32
|
-
|
|
33
|
-
if @overwritten
|
|
34
|
-
# The original method was overwritten. Overwrite again to restore it.
|
|
35
|
-
T::Configuration.without_ruby_warnings do
|
|
36
|
-
@mod.send(:define_method, @old_method.name, @old_method)
|
|
37
|
-
end
|
|
38
|
-
else
|
|
39
|
-
# The original method was in an ancestor. Restore it by removing the overriding method.
|
|
40
|
-
@mod.send(:remove_method, @old_method.name)
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
# Restore the visibility. Note that we need to do this even when we call remove_method
|
|
44
|
-
# above, because the module may have set custom visibility for a method it inherited.
|
|
45
|
-
@mod.send(@visibility, @old_method.name)
|
|
46
|
-
|
|
47
|
-
nil
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
def bind(obj)
|
|
51
|
-
@old_method.bind(obj)
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
def to_s
|
|
55
|
-
@old_method.to_s
|
|
56
|
-
end
|
|
57
|
-
end
|
|
58
|
-
|
|
59
12
|
# `name` must be an instance method (for class methods, pass in mod.singleton_class)
|
|
60
|
-
|
|
13
|
+
def self.visibility_method_name(mod, name)
|
|
61
14
|
if mod.public_method_defined?(name)
|
|
62
15
|
:public
|
|
63
16
|
elsif mod.protected_method_defined?(name)
|
|
@@ -65,7 +18,13 @@ module T::Private::ClassUtils
|
|
|
65
18
|
elsif mod.private_method_defined?(name)
|
|
66
19
|
:private
|
|
67
20
|
else
|
|
68
|
-
|
|
21
|
+
# Raises a NameError formatted like the Ruby VM would (the exact text formatting
|
|
22
|
+
# of these errors changed across Ruby VM versions, in ways that would sometimes
|
|
23
|
+
# cause tests to fail if they were dependent on hard coding errors).
|
|
24
|
+
mod.method(name)
|
|
25
|
+
# This is just to prove to Sorbet that this method raises.
|
|
26
|
+
# This line should be unreachable in practice due to the above call.
|
|
27
|
+
raise NameError.new("undefined method `#{name}' for class `#{mod}'")
|
|
69
28
|
end
|
|
70
29
|
end
|
|
71
30
|
|
|
@@ -85,20 +44,26 @@ module T::Private::ClassUtils
|
|
|
85
44
|
end
|
|
86
45
|
|
|
87
46
|
if block && block.arity < 0 && respond_to?(:ruby2_keywords, true)
|
|
88
|
-
|
|
47
|
+
m = instance_method(name)
|
|
48
|
+
has_rest = m.parameters.any? { |type, _| type == :rest }
|
|
49
|
+
has_keywords = m.parameters.any? { |type, _| %i[keyrest keyreq key].include?(type) }
|
|
50
|
+
ruby2_keywords(name) if has_rest && !has_keywords
|
|
89
51
|
end
|
|
90
52
|
end
|
|
91
53
|
end
|
|
92
54
|
|
|
93
|
-
# Replaces a method, either by overwriting it (if it is defined directly on
|
|
94
|
-
# overriding it (if it is defined by one of mod's ancestors).
|
|
95
|
-
#
|
|
96
|
-
#
|
|
97
|
-
#
|
|
55
|
+
# Replaces a method, either by overwriting it (if it is defined directly on
|
|
56
|
+
# `mod`) or by overriding it (if it is defined by one of mod's ancestors).
|
|
57
|
+
#
|
|
58
|
+
# Takes the `original_method` as a parameter, so it does not return anything.
|
|
59
|
+
#
|
|
60
|
+
# Can also avoid `T.let` pinning errors by letting the caller pre-compute the
|
|
61
|
+
# `original_method`, so it knows that it will always be defined (because it
|
|
62
|
+
# doesn't know that the block will always run once)
|
|
98
63
|
#
|
|
99
|
-
#
|
|
100
|
-
|
|
101
|
-
|
|
64
|
+
# Does not share code with `replace_method_with_handle`, for performance (do
|
|
65
|
+
# not want to increase the call stack, as this is a very sensitive code path).
|
|
66
|
+
def self.replace_method(original_method, mod, name, &blk)
|
|
102
67
|
original_visibility = visibility_method_name(mod, name)
|
|
103
68
|
original_owner = original_method.owner
|
|
104
69
|
|
|
@@ -117,18 +82,12 @@ module T::Private::ClassUtils
|
|
|
117
82
|
end
|
|
118
83
|
end
|
|
119
84
|
|
|
120
|
-
overwritten = original_owner == mod
|
|
121
85
|
T::Configuration.without_ruby_warnings do
|
|
122
86
|
T::Private::DeclState.current.without_on_method_added do
|
|
123
87
|
def_with_visibility(mod, name, original_visibility, &blk)
|
|
124
88
|
end
|
|
125
89
|
end
|
|
126
90
|
|
|
127
|
-
|
|
128
|
-
original_method
|
|
129
|
-
else
|
|
130
|
-
new_method = mod.instance_method(name)
|
|
131
|
-
ReplacedMethod.new(mod, original_method, new_method, overwritten, original_visibility)
|
|
132
|
-
end
|
|
91
|
+
nil
|
|
133
92
|
end
|
|
134
93
|
end
|
data/lib/types/private/final.rb
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
-
# typed:
|
|
2
|
+
# typed: true
|
|
3
3
|
|
|
4
4
|
module T::Private::Final
|
|
5
5
|
module NoInherit
|
|
6
6
|
def inherited(arg)
|
|
7
7
|
super(arg)
|
|
8
|
-
raise "#{self} was declared as final and cannot be inherited"
|
|
8
|
+
Kernel.raise "#{self} was declared as final and cannot be inherited"
|
|
9
9
|
end
|
|
10
10
|
end
|
|
11
11
|
|
|
12
12
|
module NoIncludeExtend
|
|
13
13
|
def included(arg)
|
|
14
14
|
super(arg)
|
|
15
|
-
raise "#{self} was declared as final and cannot be included"
|
|
15
|
+
Kernel.raise "#{self} was declared as final and cannot be included"
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
def extended(arg)
|
|
19
19
|
super(arg)
|
|
20
|
-
raise "#{self} was declared as final and cannot be extended"
|
|
20
|
+
Kernel.raise "#{self} was declared as final and cannot be extended"
|
|
21
21
|
end
|
|
22
22
|
end
|
|
23
23
|
|