sorbet-runtime 0.5.10470 → 0.5.10473
Sign up to get free protection for your applications and to get access to all the features.
- 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
|