sorbet-runtime 0.5.11266 → 0.5.11353

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: 62a1d832c6ab11c77c2604ee4f41e90ce19504ceb77e26a2ac1a1946316c5850
4
- data.tar.gz: ef76ff59edbc69784d52817720f36fc38d3705849b4eea653f40b52bf7c4b1dd
3
+ metadata.gz: b3029658bedb67b2a71eed26086d9f9e3bd5c35aca9676546caf1614abe8b97f
4
+ data.tar.gz: db96a9580cca32acac3b64b9a0629911c332204f5d121a4490f438f0ef2a7003
5
5
  SHA512:
6
- metadata.gz: e666a6f08ec47051bcd8a7b92320089d1841544c526be65c3cdb17d0a0cea3fd4e2e921e7b389ea52b836c2a076e18346215d2c484b7efbda372cd6dd232dc58
7
- data.tar.gz: e44d0e46981e86bd7c5f124ea1a1592d64a44955f9f405e0dcb6a61f02fb03ac4021d13bb9e01f1ac6599d94c9f7521d3164cd98f0b7efe3cc687fcb799fa6cf
6
+ metadata.gz: b640a1b394492bc9bd52f61d449c85af709a6554c81fbdbde223f202c60f5af77fc74195058ceb5ce2ff54d8a5e3f6017d163262d830920a841ed560df02da30
7
+ data.tar.gz: 6ad634e562834c3227cd1d756d07224551664ecf0834e39c9bbfc8475865545685e26ebde2935d7f9d05fe5276e9ef9b6c49c8414806927f516d7692933f6627
@@ -536,6 +536,7 @@ module T::Configuration
536
536
 
537
537
  @legacy_t_enum_migration_mode = false
538
538
  def self.enable_legacy_t_enum_migration_mode
539
+ T::Enum.include(T::Enum::LegacyMigrationMode)
539
540
  @legacy_t_enum_migration_mode = true
540
541
  end
541
542
  def self.disable_legacy_t_enum_migration_mode
data/lib/types/enum.rb CHANGED
@@ -185,69 +185,90 @@ class T::Enum
185
185
  end
186
186
  end
187
187
 
188
- # NB: Do not call this method. This exists to allow for a safe migration path in places where enum
189
- # values are compared directly against string values.
190
- #
191
- # Ruby's string has a weird quirk where `'my_string' == obj` calls obj.==('my_string') if obj
192
- # responds to the `to_str` method. It does not actually call `to_str` however.
193
- #
194
- # See https://ruby-doc.org/core-2.4.0/String.html#method-i-3D-3D
195
- sig {returns(String)}
196
- def to_str
197
- msg = 'Implicit conversion of Enum instances to strings is not allowed. Call #serialize instead.'
198
- if T::Configuration.legacy_t_enum_migration_mode?
199
- T::Configuration.soft_assert_handler(
200
- msg,
201
- storytime: {class: self.class.name},
202
- )
203
- serialize.to_s
204
- else
205
- raise NoMethodError.new(msg)
188
+ module LegacyMigrationMode
189
+ include Kernel
190
+ extend T::Helpers
191
+ abstract!
192
+
193
+ if T.unsafe(false)
194
+ # Declare to the type system that the `serialize` method for sure exists
195
+ # on whatever we mix this into.
196
+ T::Sig::WithoutRuntime.sig {abstract.returns(T.untyped)}
197
+ def serialize; end
206
198
  end
207
- end
208
199
 
209
- sig {params(other: BasicObject).returns(T::Boolean).checked(:never)}
210
- def ==(other)
211
- case other
212
- when String
200
+ # NB: Do not call this method. This exists to allow for a safe migration path in places where enum
201
+ # values are compared directly against string values.
202
+ #
203
+ # Ruby's string has a weird quirk where `'my_string' == obj` calls obj.==('my_string') if obj
204
+ # responds to the `to_str` method. It does not actually call `to_str` however.
205
+ #
206
+ # See https://ruby-doc.org/core-2.4.0/String.html#method-i-3D-3D
207
+ T::Sig::WithoutRuntime.sig {returns(String)}
208
+ def to_str
209
+ msg = 'Implicit conversion of Enum instances to strings is not allowed. Call #serialize instead.'
213
210
  if T::Configuration.legacy_t_enum_migration_mode?
214
- comparison_assertion_failed(:==, other)
215
- self.serialize == other
211
+ T::Configuration.soft_assert_handler(
212
+ msg,
213
+ storytime: {
214
+ class: self.class.name,
215
+ caller_location: Kernel.caller_locations(1..1)&.[](0)&.then {"#{_1.path}:#{_1.lineno}"},
216
+ },
217
+ )
218
+ serialize.to_s
216
219
  else
217
- false
220
+ Kernel.raise NoMethodError.new(msg)
218
221
  end
219
- else
220
- super(other)
221
222
  end
222
- end
223
223
 
224
- sig {params(other: BasicObject).returns(T::Boolean).checked(:never)}
225
- def ===(other)
226
- case other
227
- when String
228
- if T::Configuration.legacy_t_enum_migration_mode?
229
- comparison_assertion_failed(:===, other)
230
- self.serialize == other
224
+ # WithoutRuntime so that comparison_assertion_failed can assume a constant stack depth
225
+ T::Sig::WithoutRuntime.sig {params(other: BasicObject).returns(T::Boolean)}
226
+ def ==(other)
227
+ case other
228
+ when String
229
+ if T::Configuration.legacy_t_enum_migration_mode?
230
+ comparison_assertion_failed(:==, other)
231
+ self.serialize == other
232
+ else
233
+ false
234
+ end
231
235
  else
232
- false
236
+ super(other)
237
+ end
238
+ end
239
+
240
+ # WithoutRuntime so that comparison_assertion_failed can assume a constant stack depth
241
+ T::Sig::WithoutRuntime.sig {params(other: BasicObject).returns(T::Boolean)}
242
+ def ===(other)
243
+ case other
244
+ when String
245
+ if T::Configuration.legacy_t_enum_migration_mode?
246
+ comparison_assertion_failed(:===, other)
247
+ self.serialize == other
248
+ else
249
+ false
250
+ end
251
+ else
252
+ super(other)
233
253
  end
234
- else
235
- super(other)
236
254
  end
237
- end
238
255
 
239
- sig {params(method: Symbol, other: T.untyped).void}
240
- private def comparison_assertion_failed(method, other)
241
- T::Configuration.soft_assert_handler(
242
- 'Enum to string comparison not allowed. Compare to the Enum instance directly instead. See go/enum-migration',
243
- storytime: {
244
- class: self.class.name,
245
- self: self.inspect,
246
- other: other,
247
- other_class: other.class.name,
248
- method: method,
249
- }
250
- )
256
+ # WithoutRuntime so that caller_locations can assume a constant stack depth
257
+ # (Otherwise, the first call would be the method with the wrapping, which would have a different stack depth.)
258
+ T::Sig::WithoutRuntime.sig {params(method: Symbol, other: T.untyped).void}
259
+ private def comparison_assertion_failed(method, other)
260
+ T::Configuration.soft_assert_handler(
261
+ 'Enum to string comparison not allowed. Compare to the Enum instance directly instead. See go/enum-migration',
262
+ storytime: {
263
+ class: self.class.name,
264
+ self: self.inspect,
265
+ other: other,
266
+ other_class: other.class.name,
267
+ method: method,
268
+ caller_location: Kernel.caller_locations(2..2)&.[](0)&.then {"#{_1.path}:#{_1.lineno}"},
269
+ }
270
+ )
271
+ end
251
272
  end
252
273
 
253
274
  ### Private implementation ###
@@ -4,20 +4,13 @@
4
4
  module T::NonForcingConstants
5
5
  # NOTE: This method is documented on the RBI in Sorbet's payload, so that it
6
6
  # shows up in the hover/completion documentation via LSP.
7
- T::Sig::WithoutRuntime.sig {params(val: BasicObject, klass: String, package: T.nilable(String)).returns(T::Boolean)}
8
- def self.non_forcing_is_a?(val, klass, package: nil)
7
+ T::Sig::WithoutRuntime.sig {params(val: BasicObject, klass: String).returns(T::Boolean)}
8
+ def self.non_forcing_is_a?(val, klass)
9
9
  method_name = "T::NonForcingConstants.non_forcing_is_a?"
10
10
  if klass.empty?
11
11
  raise ArgumentError.new("The string given to `#{method_name}` must not be empty")
12
12
  end
13
13
 
14
- # We don't treat packages differently at runtime, but the static
15
- # type-checker still needs to have the package and constant
16
- # separated out. This just re-assembles the string as needed
17
- if !package.nil?
18
- klass = "::#{package}::#{klass}"
19
- end
20
-
21
14
  current_klass = T.let(nil, T.nilable(Module))
22
15
  current_prefix = T.let(nil, T.nilable(String))
23
16
 
@@ -25,10 +18,7 @@ module T::NonForcingConstants
25
18
  parts.each do |part|
26
19
  if current_klass.nil?
27
20
  # First iteration
28
- if part != "" && package.nil?
29
- # if we've supplied a package, we're probably running in
30
- # package mode, which means absolute references are
31
- # meaningless
21
+ if part != ""
32
22
  raise ArgumentError.new("The string given to `#{method_name}` must be an absolute constant reference that starts with `::`")
33
23
  end
34
24
 
@@ -37,7 +27,7 @@ module T::NonForcingConstants
37
27
 
38
28
  # if this had a :: prefix, then there's no more loading to
39
29
  # do---skip to the next one
40
- next if part == ""
30
+ next
41
31
  end
42
32
 
43
33
  if current_klass.autoload?(part)
@@ -4,7 +4,13 @@
4
4
  module T::Private::CallerUtils
5
5
  if Thread.respond_to?(:each_caller_location) # RUBY_VERSION >= "3.2"
6
6
  def self.find_caller
7
+ skiped_first = false
7
8
  Thread.each_caller_location do |loc|
9
+ unless skiped_first
10
+ skiped_first = true
11
+ next
12
+ end
13
+
8
14
  next if loc.path&.start_with?("<internal:")
9
15
 
10
16
  return loc if yield(loc)
@@ -65,7 +65,7 @@ module T::Private::ClassUtils
65
65
  elsif mod.private_method_defined?(name)
66
66
  :private
67
67
  else
68
- raise NameError.new("undefined method `#{name}` for `#{mod}`")
68
+ mod.method(name) # Raises
69
69
  end
70
70
  end
71
71
 
@@ -318,7 +318,7 @@ module T::Private::Methods::CallValidation
318
318
  elsif mod.private_method_defined?(name)
319
319
  :private
320
320
  else
321
- raise NameError.new("undefined method `#{name}` for `#{mod}`")
321
+ mod.method(name) # Raises
322
322
  end
323
323
  end
324
324
  end
@@ -5,8 +5,8 @@ module T::Private::Sealed
5
5
  module NoInherit
6
6
  def inherited(child)
7
7
  super
8
- caller_loc = T::Private::CallerUtils.find_caller {|loc| !loc.to_s.match(/in `inherited'$/)}
9
- T::Private::Sealed.validate_inheritance(caller_loc&.to_s, self, child, 'inherited')
8
+ caller_loc = T::Private::CallerUtils.find_caller {|loc| loc.base_label != 'inherited'}
9
+ T::Private::Sealed.validate_inheritance(caller_loc, self, child, 'inherited')
10
10
  @sorbet_sealed_module_all_subclasses << child
11
11
  end
12
12
 
@@ -23,14 +23,14 @@ module T::Private::Sealed
23
23
  def included(child)
24
24
  super
25
25
  caller_loc = T::Private::CallerUtils.find_caller {|loc| !loc.to_s.match(/in `included'$/)}
26
- T::Private::Sealed.validate_inheritance(caller_loc&.to_s, self, child, 'included')
26
+ T::Private::Sealed.validate_inheritance(caller_loc, self, child, 'included')
27
27
  @sorbet_sealed_module_all_subclasses << child
28
28
  end
29
29
 
30
30
  def extended(child)
31
31
  super
32
32
  caller_loc = T::Private::CallerUtils.find_caller {|loc| !loc.to_s.match(/in `extended'$/)}
33
- T::Private::Sealed.validate_inheritance(caller_loc&.to_s, self, child, 'extended')
33
+ T::Private::Sealed.validate_inheritance(caller_loc, self, child, 'extended')
34
34
  @sorbet_sealed_module_all_subclasses << child
35
35
  end
36
36
 
@@ -68,8 +68,8 @@ module T::Private::Sealed
68
68
  mod.instance_variable_defined?(:@sorbet_sealed_module_decl_file)
69
69
  end
70
70
 
71
- def self.validate_inheritance(this_line, parent, child, verb)
72
- this_file = this_line&.split(':')&.first
71
+ def self.validate_inheritance(caller_loc, parent, child, verb)
72
+ this_file = caller_loc&.path
73
73
  decl_file = parent.instance_variable_get(:@sorbet_sealed_module_decl_file) if sealed_module?(parent)
74
74
 
75
75
  if !this_file
@@ -7,13 +7,13 @@ module T::Props::PrettyPrintable
7
7
 
8
8
  # Override the PP gem with something that's similar, but gives us a hook to do redaction and customization
9
9
  def pretty_print(pp)
10
- clazz = T.unsafe(T.cast(self, Object).class).decorator
10
+ klass = T.unsafe(T.cast(self, Object).class).decorator
11
11
  multiline = pp.is_a?(PP)
12
- pp.group(1, "<#{clazz.inspect_class_with_decoration(self)}", ">") do
13
- clazz.all_props.sort.each do |prop|
12
+ pp.group(1, "<#{klass.inspect_class_with_decoration(self)}", ">") do
13
+ klass.all_props.sort.each do |prop|
14
14
  pp.breakable
15
- val = clazz.get(self, prop)
16
- rules = clazz.prop_rules(prop)
15
+ val = klass.get(self, prop)
16
+ rules = klass.prop_rules(prop)
17
17
  pp.text("#{prop}=")
18
18
  if (custom_inspect = rules[:inspect])
19
19
  inspected = if T::Utils.arity(custom_inspect) == 1
@@ -28,7 +28,7 @@ module T::Props::PrettyPrintable
28
28
  val.pretty_print(pp)
29
29
  end
30
30
  end
31
- clazz.pretty_print_extra(self, pp)
31
+ klass.pretty_print_extra(self, pp)
32
32
  end
33
33
  end
34
34
 
@@ -33,7 +33,7 @@ module T::Types
33
33
 
34
34
  # overrides Base
35
35
  def name
36
- @name ||= "T.deprecated_enum([#{@values.map(&:inspect).join(', ')}])"
36
+ @name ||= "T.deprecated_enum([#{@values.map(&:inspect).sort.join(', ')}])"
37
37
  end
38
38
 
39
39
  # overrides Base
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.11266
4
+ version: 0.5.11353
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stripe
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-02-23 00:00:00.000000000 Z
11
+ date: 2024-04-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: minitest