sorbet-runtime 0.5.10470 → 0.5.10473
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/private/types/simple_pair_union.rb +42 -0
- data/lib/types/types/base.rb +5 -1
- data/lib/types/types/simple.rb +4 -1
- data/lib/types/types/union.rb +39 -14
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b189a0adf5472e2cae48a050abe2697c03c44048fd3c59b1f104928ed09771d2
|
|
4
|
+
data.tar.gz: 7aa59c471cf94a8539c610c96b11f36884da152d2b6e37e6f8fb630c781b51fb
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8cfcd118c9529eb878a9838deb129d246c7594030553a448116b6f6c30250476367aa2a19ff3b555ba58398b25827fbb7d3d82c45ef267d01076f6810bdcf95d
|
|
7
|
+
data.tar.gz: 8848028f5f9dd560ce4600a8ff8ead2bf9eb05dc969897bc714f6a6868e5f73fbb36ed3c73979da0f01ead482d1f4a5c4bb0b1d04edde09190f5ba26f6ed1af8
|
data/lib/sorbet-runtime.rb
CHANGED
|
@@ -55,6 +55,7 @@ require_relative 'types/private/types/not_typed'
|
|
|
55
55
|
require_relative 'types/private/types/void'
|
|
56
56
|
require_relative 'types/private/types/string_holder'
|
|
57
57
|
require_relative 'types/private/types/type_alias'
|
|
58
|
+
require_relative 'types/private/types/simple_pair_union'
|
|
58
59
|
|
|
59
60
|
require_relative 'types/types/type_variable'
|
|
60
61
|
require_relative 'types/types/type_member'
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# typed: true
|
|
3
|
+
|
|
4
|
+
# Specialization of Union for the common case of the union of two simple types.
|
|
5
|
+
#
|
|
6
|
+
# This covers e.g. T.nilable(SomeModule), T.any(Integer, Float), and T::Boolean.
|
|
7
|
+
class T::Private::Types::SimplePairUnion < T::Types::Union
|
|
8
|
+
class DuplicateType < RuntimeError; end
|
|
9
|
+
|
|
10
|
+
# @param type_a [T::Types::Simple]
|
|
11
|
+
# @param type_b [T::Types::Simple]
|
|
12
|
+
def initialize(type_a, type_b)
|
|
13
|
+
if type_a == type_b
|
|
14
|
+
raise DuplicateType.new("#{type_a} == #{type_b}")
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
@raw_a = type_a.raw_type
|
|
18
|
+
@raw_b = type_b.raw_type
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# @override Union
|
|
22
|
+
def recursively_valid?(obj)
|
|
23
|
+
obj.is_a?(@raw_a) || obj.is_a?(@raw_b)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# @override Union
|
|
27
|
+
def valid?(obj)
|
|
28
|
+
obj.is_a?(@raw_a) || obj.is_a?(@raw_b)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# @override Union
|
|
32
|
+
def types
|
|
33
|
+
# We reconstruct the simple types rather than just storing them because
|
|
34
|
+
# (1) this is normally not a hot path and (2) we want to keep the instance
|
|
35
|
+
# variable count <= 3 so that we can fit in a 40 byte heap entry along
|
|
36
|
+
# with object headers.
|
|
37
|
+
@types ||= [
|
|
38
|
+
T::Types::Simple::Private::Pool.type_for_module(@raw_a),
|
|
39
|
+
T::Types::Simple::Private::Pool.type_for_module(@raw_b),
|
|
40
|
+
]
|
|
41
|
+
end
|
|
42
|
+
end
|
data/lib/types/types/base.rb
CHANGED
|
@@ -163,8 +163,12 @@ module T::Types
|
|
|
163
163
|
# Type equivalence, defined by serializing the type to a string (with
|
|
164
164
|
# `#name`) and comparing the resulting strings for equality.
|
|
165
165
|
def ==(other)
|
|
166
|
-
|
|
166
|
+
case other
|
|
167
|
+
when T::Types::Base
|
|
167
168
|
other.name == self.name
|
|
169
|
+
else
|
|
170
|
+
false
|
|
171
|
+
end
|
|
168
172
|
end
|
|
169
173
|
|
|
170
174
|
alias_method :eql?, :==
|
data/lib/types/types/simple.rb
CHANGED
data/lib/types/types/union.rb
CHANGED
|
@@ -6,6 +6,8 @@ module T::Types
|
|
|
6
6
|
class Union < Base
|
|
7
7
|
attr_reader :types
|
|
8
8
|
|
|
9
|
+
# Don't use Union.new directly, use `Private::Pool.union_of_types`
|
|
10
|
+
# inside sorbet-runtime and `T.any` elsewhere.
|
|
9
11
|
def initialize(types)
|
|
10
12
|
@types = types.flat_map do |type|
|
|
11
13
|
type = T::Utils.coerce(type)
|
|
@@ -20,11 +22,16 @@ module T::Types
|
|
|
20
22
|
|
|
21
23
|
# overrides Base
|
|
22
24
|
def name
|
|
23
|
-
|
|
25
|
+
# Use the attr_reader here so we can override it in SimplePairUnion
|
|
26
|
+
type_shortcuts(types)
|
|
24
27
|
end
|
|
25
28
|
|
|
26
29
|
private def type_shortcuts(types)
|
|
27
30
|
if types.size == 1
|
|
31
|
+
# We shouldn't generally get here but it's possible if initializing the type
|
|
32
|
+
# evades Sorbet's static check and we end up on the slow path, or if someone
|
|
33
|
+
# is using the T:Types::Union constructor directly (the latter possibility
|
|
34
|
+
# is why we don't just move the `uniq` into `Private::Pool.union_of_types`).
|
|
28
35
|
return types[0].name
|
|
29
36
|
end
|
|
30
37
|
nilable = T::Utils.coerce(NilClass)
|
|
@@ -62,27 +69,45 @@ module T::Types
|
|
|
62
69
|
EMPTY_ARRAY = [].freeze
|
|
63
70
|
private_constant :EMPTY_ARRAY
|
|
64
71
|
|
|
72
|
+
# Try to use `to_nilable` on a type to get memoization, or failing that
|
|
73
|
+
# try to at least use SimplePairUnion to get faster init and typechecking.
|
|
74
|
+
#
|
|
75
|
+
# We aren't guaranteed to detect a simple `T.nilable(<Module>)` type here
|
|
76
|
+
# in cases where there are duplicate types, nested unions, etc.
|
|
77
|
+
#
|
|
78
|
+
# That's ok, because returning is SimplePairUnion an optimization which
|
|
79
|
+
# isn't necessary for correctness.
|
|
80
|
+
#
|
|
65
81
|
# @param type_a [T::Types::Base]
|
|
66
82
|
# @param type_b [T::Types::Base]
|
|
67
83
|
# @param types [Array] optional array of additional T::Types::Base instances
|
|
68
84
|
def self.union_of_types(type_a, type_b, types=EMPTY_ARRAY)
|
|
69
|
-
if types.empty?
|
|
70
|
-
#
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
#
|
|
74
|
-
|
|
75
|
-
|
|
85
|
+
if !types.empty?
|
|
86
|
+
# Slow path
|
|
87
|
+
return Union.new([type_a, type_b] + types)
|
|
88
|
+
elsif !type_a.is_a?(T::Types::Simple) || !type_b.is_a?(T::Types::Simple)
|
|
89
|
+
# Slow path
|
|
90
|
+
return Union.new([type_a, type_b])
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
begin
|
|
94
|
+
if type_b == T::Utils::Nilable::NIL_TYPE
|
|
76
95
|
type_a.to_nilable
|
|
77
|
-
elsif type_a == T::Utils::Nilable::NIL_TYPE
|
|
96
|
+
elsif type_a == T::Utils::Nilable::NIL_TYPE
|
|
78
97
|
type_b.to_nilable
|
|
79
98
|
else
|
|
80
|
-
|
|
99
|
+
T::Private::Types::SimplePairUnion.new(type_a, type_b)
|
|
81
100
|
end
|
|
82
|
-
|
|
83
|
-
#
|
|
84
|
-
#
|
|
85
|
-
|
|
101
|
+
rescue T::Private::Types::SimplePairUnion::DuplicateType
|
|
102
|
+
# Slow path
|
|
103
|
+
#
|
|
104
|
+
# This shouldn't normally be possible due to static checks,
|
|
105
|
+
# but we can get here if we're constructing a type dynamically.
|
|
106
|
+
#
|
|
107
|
+
# Relying on the duplicate check in the constructor has the
|
|
108
|
+
# advantage that we avoid it when we hit the memoized case
|
|
109
|
+
# of `to_nilable`.
|
|
110
|
+
type_a
|
|
86
111
|
end
|
|
87
112
|
end
|
|
88
113
|
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.10473
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Stripe
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2022-
|
|
11
|
+
date: 2022-10-01 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: minitest
|
|
@@ -189,6 +189,7 @@ files:
|
|
|
189
189
|
- lib/types/private/runtime_levels.rb
|
|
190
190
|
- lib/types/private/sealed.rb
|
|
191
191
|
- lib/types/private/types/not_typed.rb
|
|
192
|
+
- lib/types/private/types/simple_pair_union.rb
|
|
192
193
|
- lib/types/private/types/string_holder.rb
|
|
193
194
|
- lib/types/private/types/type_alias.rb
|
|
194
195
|
- lib/types/private/types/void.rb
|