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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 34676c45c9ee3121fd2bef3ccd7748843cb9720be11d18d730eefa648ad17fc4
4
- data.tar.gz: 59f462975d25a7f566fae4bb3e2ff75b16d348c392b725567ca9bec41cfca997
3
+ metadata.gz: e2b15b12f019d99d0883d3987d7bd205a368b8646b8c998328967023be62d8a1
4
+ data.tar.gz: dbed6520ccd76a2ac122f63cfee589811b4ea570d72d994b0c6e1e2391640e8e
5
5
  SHA512:
6
- metadata.gz: b30613cca7cf091f67f6725fdd878acec5d17d83a2e0beb0ee81c3e8e3d8781c8e5a413d4969ad0fe1dc2dd5f579d87d3cee9c370914f72fb9f68fd972d0d37f
7
- data.tar.gz: 4cdb21494e6f932beec12c4c27a872a4301181d3044065e4ce4f725bba7db3bd9f9c83eacdf2b1bc71898a302d1d552144533bb36bfd96b85b03e9529f3e7298
6
+ metadata.gz: a30b5d79bb6b5ae5dd11b6a82bdec010bb00ba90d386db70a9fa8ff191180e2a264f89243f45674a7db2d6f7c17f6856d6b32e0795cacb6717852c1e2a902c1a
7
+ data.tar.gz: 69d156afa66059195cbc8cf6d5aad958cfc5132959fc18842716d8df563a4f08788e24fd9a43313ba7e667f4e81c30abed3e1aa03a90ee021d267d9061df9ba3
@@ -9,6 +9,7 @@
9
9
  module T; end
10
10
  module T::Helpers; end
11
11
  module T::Private; end
12
+ T::Private::IS_TYPECHECKING = false
12
13
  module T::Private::Abstract; end
13
14
  module T::Private::Types; end
14
15
 
data/lib/types/_types.rb CHANGED
@@ -342,7 +342,11 @@ module T
342
342
 
343
343
  module Range
344
344
  def self.[](type)
345
- T::Types::TypedRange.new(type)
345
+ if type.is_a?(T::Types::Untyped)
346
+ T::Types::TypedRange::Untyped.new
347
+ else
348
+ T::Types::TypedRange.new(type)
349
+ end
346
350
  end
347
351
  end
348
352
 
@@ -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
@@ -1,5 +1,5 @@
1
- # typed: true
2
1
  # frozen_string_literal: true
2
+ # typed: true
3
3
 
4
4
  module T::Configuration
5
5
  # Announces to Sorbet that we are currently in a test environment, so it
data/lib/types/helpers.rb CHANGED
@@ -4,8 +4,6 @@
4
4
  # Use as a mixin with extend (`extend T::Helpers`).
5
5
  # Docs at https://sorbet.org/docs/
6
6
  module T::Helpers
7
- extend T::Sig
8
-
9
7
  Private = T::Private
10
8
 
11
9
  ### Class/Module Helpers ###
@@ -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 type == :interface
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
- method.source_location.join(':')
114
+ loc = if (source_loc = method.source_location)
115
+ source_loc.join(':')
116
116
  else
117
117
  "<unknown location>"
118
118
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
- # typed: false
2
+ # typed: true
3
3
 
4
4
  module T::Private
5
5
  module Casts
@@ -1,63 +1,16 @@
1
1
  # frozen_string_literal: true
2
- # typed: false
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
- private_class_method def self.visibility_method_name(mod, name)
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
- mod.method(name) # Raises
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
- ruby2_keywords(name)
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 `mod`) or by
94
- # overriding it (if it is defined by one of mod's ancestors). If `original_only` is
95
- # false, returns a ReplacedMethod instance on which you can call `bind(...).call(...)`
96
- # to call the original method, or `restore` to restore the original method (by
97
- # overwriting or removing the override).
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
- # If `original_only` is true, return the `UnboundMethod` representing the original method.
100
- def self.replace_method(mod, name, original_only=false, &blk)
101
- original_method = mod.instance_method(name)
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
- if original_only
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
@@ -1,23 +1,23 @@
1
1
  # frozen_string_literal: true
2
- # typed: false
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