sorbet-runtime 0.5.5841
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 +7 -0
- data/lib/sorbet-runtime.rb +116 -0
- data/lib/types/_types.rb +285 -0
- data/lib/types/abstract_utils.rb +50 -0
- data/lib/types/boolean.rb +8 -0
- data/lib/types/compatibility_patches.rb +95 -0
- data/lib/types/configuration.rb +428 -0
- data/lib/types/enum.rb +349 -0
- data/lib/types/generic.rb +23 -0
- data/lib/types/helpers.rb +39 -0
- data/lib/types/interface_wrapper.rb +158 -0
- data/lib/types/non_forcing_constants.rb +51 -0
- data/lib/types/private/abstract/data.rb +36 -0
- data/lib/types/private/abstract/declare.rb +48 -0
- data/lib/types/private/abstract/hooks.rb +43 -0
- data/lib/types/private/abstract/validate.rb +128 -0
- data/lib/types/private/casts.rb +22 -0
- data/lib/types/private/class_utils.rb +111 -0
- data/lib/types/private/decl_state.rb +30 -0
- data/lib/types/private/final.rb +51 -0
- data/lib/types/private/methods/_methods.rb +460 -0
- data/lib/types/private/methods/call_validation.rb +1149 -0
- data/lib/types/private/methods/decl_builder.rb +228 -0
- data/lib/types/private/methods/modes.rb +16 -0
- data/lib/types/private/methods/signature.rb +196 -0
- data/lib/types/private/methods/signature_validation.rb +229 -0
- data/lib/types/private/mixins/mixins.rb +27 -0
- data/lib/types/private/retry.rb +10 -0
- data/lib/types/private/runtime_levels.rb +56 -0
- data/lib/types/private/sealed.rb +65 -0
- data/lib/types/private/types/not_typed.rb +23 -0
- data/lib/types/private/types/string_holder.rb +26 -0
- data/lib/types/private/types/type_alias.rb +26 -0
- data/lib/types/private/types/void.rb +34 -0
- data/lib/types/profile.rb +31 -0
- data/lib/types/props/_props.rb +161 -0
- data/lib/types/props/constructor.rb +40 -0
- data/lib/types/props/custom_type.rb +108 -0
- data/lib/types/props/decorator.rb +672 -0
- data/lib/types/props/errors.rb +8 -0
- data/lib/types/props/generated_code_validation.rb +268 -0
- data/lib/types/props/has_lazily_specialized_methods.rb +92 -0
- data/lib/types/props/optional.rb +81 -0
- data/lib/types/props/plugin.rb +37 -0
- data/lib/types/props/pretty_printable.rb +107 -0
- data/lib/types/props/private/apply_default.rb +170 -0
- data/lib/types/props/private/deserializer_generator.rb +165 -0
- data/lib/types/props/private/parser.rb +32 -0
- data/lib/types/props/private/serde_transform.rb +192 -0
- data/lib/types/props/private/serializer_generator.rb +77 -0
- data/lib/types/props/private/setter_factory.rb +134 -0
- data/lib/types/props/serializable.rb +330 -0
- data/lib/types/props/type_validation.rb +111 -0
- data/lib/types/props/utils.rb +59 -0
- data/lib/types/props/weak_constructor.rb +67 -0
- data/lib/types/runtime_profiled.rb +24 -0
- data/lib/types/sig.rb +30 -0
- data/lib/types/struct.rb +18 -0
- data/lib/types/types/attached_class.rb +37 -0
- data/lib/types/types/base.rb +151 -0
- data/lib/types/types/class_of.rb +38 -0
- data/lib/types/types/enum.rb +42 -0
- data/lib/types/types/fixed_array.rb +60 -0
- data/lib/types/types/fixed_hash.rb +59 -0
- data/lib/types/types/intersection.rb +37 -0
- data/lib/types/types/noreturn.rb +29 -0
- data/lib/types/types/proc.rb +51 -0
- data/lib/types/types/self_type.rb +35 -0
- data/lib/types/types/simple.rb +33 -0
- data/lib/types/types/t_enum.rb +38 -0
- data/lib/types/types/type_member.rb +7 -0
- data/lib/types/types/type_parameter.rb +23 -0
- data/lib/types/types/type_template.rb +7 -0
- data/lib/types/types/type_variable.rb +31 -0
- data/lib/types/types/typed_array.rb +34 -0
- data/lib/types/types/typed_enumerable.rb +161 -0
- data/lib/types/types/typed_enumerator.rb +36 -0
- data/lib/types/types/typed_hash.rb +43 -0
- data/lib/types/types/typed_range.rb +26 -0
- data/lib/types/types/typed_set.rb +36 -0
- data/lib/types/types/union.rb +56 -0
- data/lib/types/types/untyped.rb +29 -0
- data/lib/types/utils.rb +217 -0
- metadata +223 -0
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# typed: true
|
3
|
+
|
4
|
+
module T::Types
|
5
|
+
# Validates that an object belongs to the specified class.
|
6
|
+
class ClassOf < Base
|
7
|
+
attr_reader :type
|
8
|
+
|
9
|
+
def initialize(type)
|
10
|
+
@type = type
|
11
|
+
end
|
12
|
+
|
13
|
+
# @override Base
|
14
|
+
def name
|
15
|
+
"T.class_of(#{@type})"
|
16
|
+
end
|
17
|
+
|
18
|
+
# @override Base
|
19
|
+
def valid?(obj)
|
20
|
+
obj.is_a?(Module) && obj <= @type
|
21
|
+
end
|
22
|
+
|
23
|
+
# @override Base
|
24
|
+
def subtype_of_single?(other)
|
25
|
+
case other
|
26
|
+
when ClassOf
|
27
|
+
@type <= other.type
|
28
|
+
else
|
29
|
+
false
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# @override Base
|
34
|
+
def describe_obj(obj)
|
35
|
+
obj.inspect
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# typed: true
|
3
|
+
|
4
|
+
module T::Types
|
5
|
+
# validates that the provided value is within a given set/enum
|
6
|
+
class Enum < Base
|
7
|
+
extend T::Sig
|
8
|
+
|
9
|
+
attr_reader :values
|
10
|
+
|
11
|
+
# TODO Ideally Hash would not be accepted but there are a lot of uses with prop enum.
|
12
|
+
sig {params(values: T.any(Array, Set, Hash, T::Range[T.untyped])).void}
|
13
|
+
def initialize(values)
|
14
|
+
@values = values
|
15
|
+
end
|
16
|
+
|
17
|
+
# @override Base
|
18
|
+
def valid?(obj)
|
19
|
+
@values.member?(obj)
|
20
|
+
end
|
21
|
+
|
22
|
+
# @override Base
|
23
|
+
private def subtype_of_single?(other)
|
24
|
+
case other
|
25
|
+
when Enum
|
26
|
+
(other.values - @values).empty?
|
27
|
+
else
|
28
|
+
false
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# @override Base
|
33
|
+
def name
|
34
|
+
"T.enum([#{@values.map(&:inspect).join(', ')}])"
|
35
|
+
end
|
36
|
+
|
37
|
+
# @override Base
|
38
|
+
def describe_obj(obj)
|
39
|
+
obj.inspect
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# https://jira.corp.stripe.com/browse/RUBYPLAT-1107
|
3
|
+
# typed: false
|
4
|
+
|
5
|
+
module T::Types
|
6
|
+
# Takes a list of types. Validates each item in an array using the type in the same position
|
7
|
+
# in the list.
|
8
|
+
class FixedArray < Base
|
9
|
+
attr_reader :types
|
10
|
+
|
11
|
+
def initialize(types)
|
12
|
+
@types = types.map {|type| T::Utils.coerce(type)}
|
13
|
+
end
|
14
|
+
|
15
|
+
# @override Base
|
16
|
+
def name
|
17
|
+
"[#{@types.join(', ')}]"
|
18
|
+
end
|
19
|
+
|
20
|
+
# @override Base
|
21
|
+
def valid?(obj)
|
22
|
+
obj.is_a?(Array) && obj.length == @types.length &&
|
23
|
+
obj.zip(@types).all? {|item, type| type.valid?(item)}
|
24
|
+
end
|
25
|
+
|
26
|
+
# @override Base
|
27
|
+
private def subtype_of_single?(other)
|
28
|
+
case other
|
29
|
+
when FixedArray
|
30
|
+
# Properly speaking, covariance here is unsound since arrays
|
31
|
+
# can be mutated, but sorbet implements covariant tuples for
|
32
|
+
# ease of adoption.
|
33
|
+
@types.size == other.types.size && @types.zip(other.types).all? do |t1, t2|
|
34
|
+
t1.subtype_of?(t2)
|
35
|
+
end
|
36
|
+
else
|
37
|
+
false
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# This gives us better errors, e.g.:
|
42
|
+
# "Expected [String, Symbol], got [String, String]"
|
43
|
+
# instead of
|
44
|
+
# "Expected [String, Symbol], got Array".
|
45
|
+
#
|
46
|
+
# @override Base
|
47
|
+
def describe_obj(obj)
|
48
|
+
if obj.is_a?(Array)
|
49
|
+
if obj.length == @types.length
|
50
|
+
item_classes = obj.map(&:class).join(', ')
|
51
|
+
"type [#{item_classes}]"
|
52
|
+
else
|
53
|
+
"array of size #{obj.length}"
|
54
|
+
end
|
55
|
+
else
|
56
|
+
super
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# typed: true
|
3
|
+
|
4
|
+
module T::Types
|
5
|
+
# Takes a hash of types. Validates each item in an hash using the type in the same position
|
6
|
+
# in the list.
|
7
|
+
class FixedHash < Base
|
8
|
+
attr_reader :types
|
9
|
+
|
10
|
+
def initialize(types)
|
11
|
+
@types = types.each_with_object({}) {|(k, v), h| h[k] = T::Utils.coerce(v)}
|
12
|
+
end
|
13
|
+
|
14
|
+
# @override Base
|
15
|
+
def name
|
16
|
+
"{#{@types.map {|(k, v)| "#{k}: #{v}"}.join(', ')}}"
|
17
|
+
end
|
18
|
+
|
19
|
+
# @override Base
|
20
|
+
def valid?(obj)
|
21
|
+
return false unless obj.is_a?(Hash)
|
22
|
+
|
23
|
+
@types.each do |key, type|
|
24
|
+
return false unless type.valid?(obj[key])
|
25
|
+
end
|
26
|
+
|
27
|
+
obj.each_key do |key|
|
28
|
+
return false unless @types[key]
|
29
|
+
end
|
30
|
+
|
31
|
+
true
|
32
|
+
end
|
33
|
+
|
34
|
+
# @override Base
|
35
|
+
private def subtype_of_single?(other)
|
36
|
+
case other
|
37
|
+
when FixedHash
|
38
|
+
# Using `subtype_of?` here instead of == would be unsound
|
39
|
+
@types == other.types
|
40
|
+
else
|
41
|
+
false
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# This gives us better errors, e.g.:
|
46
|
+
# "Expected {a: String}, got {a: TrueClass}"
|
47
|
+
# instead of
|
48
|
+
# "Expected {a: String}, got Hash".
|
49
|
+
#
|
50
|
+
# @override Base
|
51
|
+
def describe_obj(obj)
|
52
|
+
if obj.is_a?(Hash)
|
53
|
+
"type {#{obj.map {|(k, v)| "#{k}: #{v.class}"}.join(', ')}}"
|
54
|
+
else
|
55
|
+
super
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# typed: true
|
3
|
+
|
4
|
+
module T::Types
|
5
|
+
# Takes a list of types. Validates that an object matches all of the types.
|
6
|
+
class Intersection < Base
|
7
|
+
attr_reader :types
|
8
|
+
|
9
|
+
def initialize(types)
|
10
|
+
@types = types.flat_map do |type|
|
11
|
+
type = T::Utils.resolve_alias(type)
|
12
|
+
if type.is_a?(Intersection)
|
13
|
+
# Simplify nested intersections (mostly so `name` returns a nicer value)
|
14
|
+
type.types
|
15
|
+
else
|
16
|
+
T::Utils.coerce(type)
|
17
|
+
end
|
18
|
+
end.uniq
|
19
|
+
end
|
20
|
+
|
21
|
+
# @override Base
|
22
|
+
def name
|
23
|
+
"T.all(#{@types.map(&:name).sort.join(', ')})"
|
24
|
+
end
|
25
|
+
|
26
|
+
# @override Base
|
27
|
+
def valid?(obj)
|
28
|
+
@types.all? {|type| type.valid?(obj)}
|
29
|
+
end
|
30
|
+
|
31
|
+
# @override Base
|
32
|
+
private def subtype_of_single?(other)
|
33
|
+
raise "This should never be reached if you're going through `subtype_of?` (and you should be)"
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# typed: true
|
3
|
+
|
4
|
+
module T::Types
|
5
|
+
# The bottom type
|
6
|
+
class NoReturn < Base
|
7
|
+
|
8
|
+
def initialize; end
|
9
|
+
|
10
|
+
# @override Base
|
11
|
+
def name
|
12
|
+
"T.noreturn"
|
13
|
+
end
|
14
|
+
|
15
|
+
# @override Base
|
16
|
+
def valid?(obj)
|
17
|
+
false
|
18
|
+
end
|
19
|
+
|
20
|
+
# @override Base
|
21
|
+
private def subtype_of_single?(other)
|
22
|
+
true
|
23
|
+
end
|
24
|
+
|
25
|
+
module Private
|
26
|
+
INSTANCE = NoReturn.new.freeze
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# typed: true
|
3
|
+
|
4
|
+
module T::Types
|
5
|
+
# Defines the type of a proc (a ruby callable). At runtime, only
|
6
|
+
# validates that the value is a `::Proc`.
|
7
|
+
#
|
8
|
+
# At present, we only support fixed-arity procs with no optional or
|
9
|
+
# keyword arguments.
|
10
|
+
class Proc < Base
|
11
|
+
attr_reader :arg_types
|
12
|
+
attr_reader :returns
|
13
|
+
|
14
|
+
def initialize(arg_types, returns)
|
15
|
+
@arg_types = {}
|
16
|
+
arg_types.each do |key, raw_type|
|
17
|
+
@arg_types[key] = T::Utils.coerce(raw_type)
|
18
|
+
end
|
19
|
+
@returns = T::Utils.coerce(returns)
|
20
|
+
end
|
21
|
+
|
22
|
+
# @override Base
|
23
|
+
def name
|
24
|
+
args = []
|
25
|
+
@arg_types.each do |k, v|
|
26
|
+
args << "#{k}: #{v.name}"
|
27
|
+
end
|
28
|
+
"T.proc.params(#{args.join(', ')}).returns(#{returns})"
|
29
|
+
end
|
30
|
+
|
31
|
+
# @override Base
|
32
|
+
def valid?(obj)
|
33
|
+
obj.is_a?(::Proc)
|
34
|
+
end
|
35
|
+
|
36
|
+
# @override Base
|
37
|
+
private def subtype_of_single?(other)
|
38
|
+
case other
|
39
|
+
when self.class
|
40
|
+
if arg_types.size != other.arg_types.size
|
41
|
+
return false
|
42
|
+
end
|
43
|
+
arg_types.values.zip(other.arg_types.values).all? do |a, b|
|
44
|
+
b.subtype_of?(a)
|
45
|
+
end && returns.subtype_of?(other.returns)
|
46
|
+
else
|
47
|
+
false
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# typed: true
|
3
|
+
|
4
|
+
module T::Types
|
5
|
+
# Modeling self-types properly at runtime would require additional tracking,
|
6
|
+
# so at runtime we permit all values and rely on the static checker.
|
7
|
+
class SelfType < Base
|
8
|
+
|
9
|
+
def initialize(); end
|
10
|
+
|
11
|
+
# @override Base
|
12
|
+
def name
|
13
|
+
"T.self_type"
|
14
|
+
end
|
15
|
+
|
16
|
+
# @override Base
|
17
|
+
def valid?(obj)
|
18
|
+
true
|
19
|
+
end
|
20
|
+
|
21
|
+
# @override Base
|
22
|
+
private def subtype_of_single?(other)
|
23
|
+
case other
|
24
|
+
when SelfType
|
25
|
+
true
|
26
|
+
else
|
27
|
+
false
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
module Private
|
32
|
+
INSTANCE = SelfType.new.freeze
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# typed: true
|
3
|
+
|
4
|
+
module T::Types
|
5
|
+
# Validates that an object belongs to the specified class.
|
6
|
+
class Simple < Base
|
7
|
+
attr_reader :raw_type
|
8
|
+
|
9
|
+
def initialize(raw_type)
|
10
|
+
@raw_type = raw_type
|
11
|
+
end
|
12
|
+
|
13
|
+
# @override Base
|
14
|
+
def name
|
15
|
+
@raw_type.name
|
16
|
+
end
|
17
|
+
|
18
|
+
# @override Base
|
19
|
+
def valid?(obj)
|
20
|
+
obj.is_a?(@raw_type)
|
21
|
+
end
|
22
|
+
|
23
|
+
# @override Base
|
24
|
+
private def subtype_of_single?(other)
|
25
|
+
case other
|
26
|
+
when Simple
|
27
|
+
@raw_type <= other.raw_type
|
28
|
+
else
|
29
|
+
false
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# typed: true
|
3
|
+
|
4
|
+
module T::Types
|
5
|
+
# Validates that an object is equal to another T::Enum singleton value.
|
6
|
+
class TEnum < Base
|
7
|
+
attr_reader :val
|
8
|
+
|
9
|
+
def initialize(val)
|
10
|
+
@val = val
|
11
|
+
end
|
12
|
+
|
13
|
+
# @override Base
|
14
|
+
def name
|
15
|
+
# Strips the #<...> off, just leaving the ...
|
16
|
+
# Reasoning: the user will have written something like
|
17
|
+
# T.any(MyEnum::A, MyEnum::B)
|
18
|
+
# in the type, so we should print what they wrote in errors, not:
|
19
|
+
# T.any(#<MyEnum::A>, #<MyEnum::B>)
|
20
|
+
@val.inspect[2..-2]
|
21
|
+
end
|
22
|
+
|
23
|
+
# @override Base
|
24
|
+
def valid?(obj)
|
25
|
+
@val == obj
|
26
|
+
end
|
27
|
+
|
28
|
+
# @override Base
|
29
|
+
private def subtype_of_single?(other)
|
30
|
+
case other
|
31
|
+
when TEnum
|
32
|
+
@val == other.val
|
33
|
+
else
|
34
|
+
false
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# typed: true
|
3
|
+
|
4
|
+
module T::Types
|
5
|
+
class TypeParameter < Base
|
6
|
+
def initialize(name)
|
7
|
+
raise ArgumentError.new("not a symbol: #{name}") unless name.is_a?(Symbol)
|
8
|
+
@name = name
|
9
|
+
end
|
10
|
+
|
11
|
+
def valid?(obj)
|
12
|
+
true
|
13
|
+
end
|
14
|
+
|
15
|
+
def subtype_of_single?(type)
|
16
|
+
true
|
17
|
+
end
|
18
|
+
|
19
|
+
def name
|
20
|
+
"T.type_parameter(:#{@name})"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|