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.
Files changed (84) hide show
  1. checksums.yaml +7 -0
  2. data/lib/sorbet-runtime.rb +116 -0
  3. data/lib/types/_types.rb +285 -0
  4. data/lib/types/abstract_utils.rb +50 -0
  5. data/lib/types/boolean.rb +8 -0
  6. data/lib/types/compatibility_patches.rb +95 -0
  7. data/lib/types/configuration.rb +428 -0
  8. data/lib/types/enum.rb +349 -0
  9. data/lib/types/generic.rb +23 -0
  10. data/lib/types/helpers.rb +39 -0
  11. data/lib/types/interface_wrapper.rb +158 -0
  12. data/lib/types/non_forcing_constants.rb +51 -0
  13. data/lib/types/private/abstract/data.rb +36 -0
  14. data/lib/types/private/abstract/declare.rb +48 -0
  15. data/lib/types/private/abstract/hooks.rb +43 -0
  16. data/lib/types/private/abstract/validate.rb +128 -0
  17. data/lib/types/private/casts.rb +22 -0
  18. data/lib/types/private/class_utils.rb +111 -0
  19. data/lib/types/private/decl_state.rb +30 -0
  20. data/lib/types/private/final.rb +51 -0
  21. data/lib/types/private/methods/_methods.rb +460 -0
  22. data/lib/types/private/methods/call_validation.rb +1149 -0
  23. data/lib/types/private/methods/decl_builder.rb +228 -0
  24. data/lib/types/private/methods/modes.rb +16 -0
  25. data/lib/types/private/methods/signature.rb +196 -0
  26. data/lib/types/private/methods/signature_validation.rb +229 -0
  27. data/lib/types/private/mixins/mixins.rb +27 -0
  28. data/lib/types/private/retry.rb +10 -0
  29. data/lib/types/private/runtime_levels.rb +56 -0
  30. data/lib/types/private/sealed.rb +65 -0
  31. data/lib/types/private/types/not_typed.rb +23 -0
  32. data/lib/types/private/types/string_holder.rb +26 -0
  33. data/lib/types/private/types/type_alias.rb +26 -0
  34. data/lib/types/private/types/void.rb +34 -0
  35. data/lib/types/profile.rb +31 -0
  36. data/lib/types/props/_props.rb +161 -0
  37. data/lib/types/props/constructor.rb +40 -0
  38. data/lib/types/props/custom_type.rb +108 -0
  39. data/lib/types/props/decorator.rb +672 -0
  40. data/lib/types/props/errors.rb +8 -0
  41. data/lib/types/props/generated_code_validation.rb +268 -0
  42. data/lib/types/props/has_lazily_specialized_methods.rb +92 -0
  43. data/lib/types/props/optional.rb +81 -0
  44. data/lib/types/props/plugin.rb +37 -0
  45. data/lib/types/props/pretty_printable.rb +107 -0
  46. data/lib/types/props/private/apply_default.rb +170 -0
  47. data/lib/types/props/private/deserializer_generator.rb +165 -0
  48. data/lib/types/props/private/parser.rb +32 -0
  49. data/lib/types/props/private/serde_transform.rb +192 -0
  50. data/lib/types/props/private/serializer_generator.rb +77 -0
  51. data/lib/types/props/private/setter_factory.rb +134 -0
  52. data/lib/types/props/serializable.rb +330 -0
  53. data/lib/types/props/type_validation.rb +111 -0
  54. data/lib/types/props/utils.rb +59 -0
  55. data/lib/types/props/weak_constructor.rb +67 -0
  56. data/lib/types/runtime_profiled.rb +24 -0
  57. data/lib/types/sig.rb +30 -0
  58. data/lib/types/struct.rb +18 -0
  59. data/lib/types/types/attached_class.rb +37 -0
  60. data/lib/types/types/base.rb +151 -0
  61. data/lib/types/types/class_of.rb +38 -0
  62. data/lib/types/types/enum.rb +42 -0
  63. data/lib/types/types/fixed_array.rb +60 -0
  64. data/lib/types/types/fixed_hash.rb +59 -0
  65. data/lib/types/types/intersection.rb +37 -0
  66. data/lib/types/types/noreturn.rb +29 -0
  67. data/lib/types/types/proc.rb +51 -0
  68. data/lib/types/types/self_type.rb +35 -0
  69. data/lib/types/types/simple.rb +33 -0
  70. data/lib/types/types/t_enum.rb +38 -0
  71. data/lib/types/types/type_member.rb +7 -0
  72. data/lib/types/types/type_parameter.rb +23 -0
  73. data/lib/types/types/type_template.rb +7 -0
  74. data/lib/types/types/type_variable.rb +31 -0
  75. data/lib/types/types/typed_array.rb +34 -0
  76. data/lib/types/types/typed_enumerable.rb +161 -0
  77. data/lib/types/types/typed_enumerator.rb +36 -0
  78. data/lib/types/types/typed_hash.rb +43 -0
  79. data/lib/types/types/typed_range.rb +26 -0
  80. data/lib/types/types/typed_set.rb +36 -0
  81. data/lib/types/types/union.rb +56 -0
  82. data/lib/types/types/untyped.rb +29 -0
  83. data/lib/types/utils.rb +217 -0
  84. metadata +223 -0
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+ # typed: strict
3
+
4
+ module T::Types
5
+ class TypeTemplate < TypeVariable
6
+ end
7
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+ # typed: true
3
+
4
+ module T::Types
5
+ # Since we do type erasure at runtime, this just validates the variance and
6
+ # provides some syntax for the static type checker
7
+ class TypeVariable < Base
8
+ attr_reader :variance
9
+
10
+ VALID_VARIANCES = [:in, :out, :invariant]
11
+
12
+ def initialize(variance)
13
+ if !VALID_VARIANCES.include?(variance)
14
+ raise TypeError.new("invalid variance #{variance}")
15
+ end
16
+ @variance = variance
17
+ end
18
+
19
+ def valid?(obj)
20
+ true
21
+ end
22
+
23
+ def subtype_of_single?(type)
24
+ true
25
+ end
26
+
27
+ def name
28
+ Untyped.new.name
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+ # typed: true
3
+
4
+ module T::Types
5
+ class TypedArray < TypedEnumerable
6
+ # @override Base
7
+ def name
8
+ "T::Array[#{@type.name}]"
9
+ end
10
+
11
+ def underlying_class
12
+ Array
13
+ end
14
+
15
+ # @override Base
16
+ def valid?(obj)
17
+ obj.is_a?(Array) && super
18
+ end
19
+
20
+ def new(*args) # rubocop:disable PrisonGuard/BanBuiltinMethodOverride
21
+ Array.new(*T.unsafe(args))
22
+ end
23
+
24
+ class Untyped < TypedArray
25
+ def initialize
26
+ super(T.untyped)
27
+ end
28
+
29
+ def valid?(obj)
30
+ obj.is_a?(Array)
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,161 @@
1
+ # frozen_string_literal: true
2
+ # typed: true
3
+
4
+ module T::Types
5
+ # Note: All subclasses of Enumerable should add themselves to the
6
+ # `case` statement below in `describe_obj` in order to get better
7
+ # error messages.
8
+ class TypedEnumerable < Base
9
+ attr_reader :type
10
+
11
+ def initialize(type)
12
+ @type = T::Utils.coerce(type)
13
+ end
14
+
15
+ def underlying_class
16
+ Enumerable
17
+ end
18
+
19
+ # @override Base
20
+ def name
21
+ "T::Enumerable[#{@type.name}]"
22
+ end
23
+
24
+ # @override Base
25
+ def valid?(obj)
26
+ return false unless obj.is_a?(Enumerable)
27
+ case obj
28
+ when Array
29
+ begin
30
+ it = 0
31
+ while it < obj.count
32
+ return false unless @type.valid?(obj[it])
33
+ it += 1
34
+ end
35
+ return true
36
+ end
37
+ when Hash
38
+ return false unless @type.is_a?(FixedArray)
39
+ types = @type.types
40
+ return false if types.count != 2
41
+ key_type = types[0]
42
+ value_type = types[1]
43
+ obj.each_pair do |key, val|
44
+ # Some objects (I'm looking at you Rack::Utils::HeaderHash) don't
45
+ # iterate over a [key, value] array, so we can't juse use the @type.valid?(v)
46
+ return false if !key_type.valid?(key) || !value_type.valid?(val)
47
+ end
48
+ return true
49
+ when Enumerator
50
+ # Enumerators can be unbounded: see `[:foo, :bar].cycle`
51
+ return true
52
+ when Range
53
+ # A nil beginning or a nil end does not provide any type information. That is, nil in a range represents
54
+ # boundlessness, it does not express a type. For example `(nil...nil)` is not a T::Range[NilClass], its a range
55
+ # of unknown types (T::Range[T.untyped]).
56
+ # Similarly, `(nil...1)` is not a `T::Range[T.nilable(Integer)]`, it's a boundless range of Integer.
57
+ (obj.begin.nil? || @type.valid?(obj.begin)) && (obj.end.nil? || @type.valid?(obj.end))
58
+ when Set
59
+ obj.each do |item|
60
+ return false unless @type.valid?(item)
61
+ end
62
+
63
+ return true
64
+ else
65
+ # We don't check the enumerable since it isn't guaranteed to be
66
+ # rewindable (e.g. STDIN) and it may be expensive to enumerate
67
+ # (e.g. an enumerator that makes an HTTP request)"
68
+ true
69
+ end
70
+ end
71
+
72
+ # @override Base
73
+ private def subtype_of_single?(other)
74
+ if other.class <= TypedEnumerable &&
75
+ underlying_class <= other.underlying_class
76
+ # Enumerables are covariant because they are read only
77
+ #
78
+ # Properly speaking, many Enumerable subtypes (e.g. Set)
79
+ # should be invariant because they are mutable and support
80
+ # both reading and writing. However, Sorbet treats *all*
81
+ # Enumerable subclasses as covariant for ease of adoption.
82
+ @type.subtype_of?(other.type)
83
+ else
84
+ false
85
+ end
86
+ end
87
+
88
+ # @override Base
89
+ def describe_obj(obj)
90
+ return super unless obj.is_a?(Enumerable)
91
+ type_from_instance(obj).name
92
+ end
93
+
94
+ private def type_from_instances(objs)
95
+ return objs.class unless objs.is_a?(Enumerable)
96
+ obtained_types = []
97
+ begin
98
+ objs.each do |x|
99
+ obtained_types << type_from_instance(x)
100
+ end
101
+ rescue
102
+ return T.untyped # all we can do is go with the types we have so far
103
+ end
104
+ if obtained_types.count > 1
105
+ # Multiple kinds of bad types showed up, we'll suggest a union
106
+ # type you might want.
107
+ Union.new(obtained_types)
108
+ elsif obtained_types.empty?
109
+ T.noreturn
110
+ else
111
+ # Everything was the same bad type, lets just show that
112
+ obtained_types.first
113
+ end
114
+ end
115
+
116
+ private def type_from_instance(obj)
117
+ if [true, false].include?(obj)
118
+ return T::Boolean
119
+ elsif !obj.is_a?(Enumerable)
120
+ return obj.class
121
+ end
122
+
123
+ case obj
124
+ when Array
125
+ T::Array[type_from_instances(obj)]
126
+ when Hash
127
+ inferred_key = type_from_instances(obj.keys)
128
+ inferred_val = type_from_instances(obj.values)
129
+ T::Hash[inferred_key, inferred_val]
130
+ when Range
131
+ # We can't get any information from `NilClass` in ranges (since nil is used to represent boundlessness).
132
+ typeable_objects = [obj.begin, obj.end].compact
133
+ if typeable_objects.empty?
134
+ T::Range[T.untyped]
135
+ else
136
+ T::Range[type_from_instances(typeable_objects)]
137
+ end
138
+ when Enumerator
139
+ T::Enumerator[type_from_instances(obj)]
140
+ when Set
141
+ T::Set[type_from_instances(obj)]
142
+ when IO
143
+ # Short circuit for anything IO-like (File, etc.). In these cases,
144
+ # enumerating the object is a destructive operation and might hang.
145
+ obj.class
146
+ else
147
+ self.class.new(type_from_instances(obj))
148
+ end
149
+ end
150
+
151
+ class Untyped < TypedEnumerable
152
+ def initialize
153
+ super(T.untyped)
154
+ end
155
+
156
+ def valid?(obj)
157
+ obj.is_a?(Enumerable)
158
+ end
159
+ end
160
+ end
161
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+ # typed: true
3
+
4
+ module T::Types
5
+ class TypedEnumerator < TypedEnumerable
6
+ attr_reader :type
7
+
8
+ def underlying_class
9
+ Enumerator
10
+ end
11
+
12
+ # @override Base
13
+ def name
14
+ "T::Enumerator[#{@type.name}]"
15
+ end
16
+
17
+ # @override Base
18
+ def valid?(obj)
19
+ obj.is_a?(Enumerator) && super
20
+ end
21
+
22
+ def new(*args, &blk) # rubocop:disable PrisonGuard/BanBuiltinMethodOverride
23
+ T.unsafe(Enumerator).new(*args, &blk)
24
+ end
25
+
26
+ class Untyped < TypedEnumerator
27
+ def initialize
28
+ super(T.untyped)
29
+ end
30
+
31
+ def valid?(obj)
32
+ obj.is_a?(Enumerator)
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+ # typed: true
3
+
4
+ module T::Types
5
+ class TypedHash < TypedEnumerable
6
+ # Technically we don't need these, but they are a nice api
7
+ attr_reader :keys, :values
8
+
9
+ def underlying_class
10
+ Hash
11
+ end
12
+
13
+ def initialize(keys:, values:)
14
+ @keys = T::Utils.coerce(keys)
15
+ @values = T::Utils.coerce(values)
16
+ @type = T::Utils.coerce([keys, values])
17
+ end
18
+
19
+ # @override Base
20
+ def name
21
+ "T::Hash[#{@keys.name}, #{@values.name}]"
22
+ end
23
+
24
+ # @override Base
25
+ def valid?(obj)
26
+ obj.is_a?(Hash) && super
27
+ end
28
+
29
+ def new(*args, &blk) # rubocop:disable PrisonGuard/BanBuiltinMethodOverride
30
+ Hash.new(*T.unsafe(args), &blk) # rubocop:disable PrisonGuard/RestrictHashDefaults
31
+ end
32
+
33
+ class Untyped < TypedHash
34
+ def initialize
35
+ super(keys: T.untyped, values: T.untyped)
36
+ end
37
+
38
+ def valid?(obj)
39
+ obj.is_a?(Hash)
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+ # typed: true
3
+
4
+ module T::Types
5
+ class TypedRange < TypedEnumerable
6
+ attr_reader :type
7
+
8
+ def underlying_class
9
+ Hash
10
+ end
11
+
12
+ # @override Base
13
+ def name
14
+ "T::Range[#{@type.name}]"
15
+ end
16
+
17
+ # @override Base
18
+ def valid?(obj)
19
+ obj.is_a?(Range) && super
20
+ end
21
+
22
+ def new(*args) # rubocop:disable PrisonGuard/BanBuiltinMethodOverride
23
+ T.unsafe(Range).new(*args)
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+ # typed: true
3
+
4
+ module T::Types
5
+ class TypedSet < TypedEnumerable
6
+ attr_reader :type
7
+
8
+ def underlying_class
9
+ Hash
10
+ end
11
+
12
+ # @override Base
13
+ def name
14
+ "T::Set[#{@type.name}]"
15
+ end
16
+
17
+ # @override Base
18
+ def valid?(obj)
19
+ obj.is_a?(Set) && super
20
+ end
21
+
22
+ def new(*args) # rubocop:disable PrisonGuard/BanBuiltinMethodOverride
23
+ Set.new(*T.unsafe(args))
24
+ end
25
+
26
+ class Untyped < TypedSet
27
+ def initialize
28
+ super(T.untyped)
29
+ end
30
+
31
+ def valid?(obj)
32
+ obj.is_a?(Set)
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+ # typed: true
3
+
4
+ module T::Types
5
+ # Takes a list of types. Validates that an object matches at least one of the types.
6
+ class Union < 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?(Union)
13
+ # Simplify nested unions (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
+ type_shortcuts(@types)
24
+ end
25
+
26
+ private def type_shortcuts(types)
27
+ if types.size == 1
28
+ return types[0].name
29
+ end
30
+ nilable = T::Utils.coerce(NilClass)
31
+ trueclass = T::Utils.coerce(TrueClass)
32
+ falseclass = T::Utils.coerce(FalseClass)
33
+ if types.any? {|t| t == nilable}
34
+ remaining_types = types.reject {|t| t == nilable}
35
+ "T.nilable(#{type_shortcuts(remaining_types)})"
36
+ elsif types.any? {|t| t == trueclass} && types.any? {|t| t == falseclass}
37
+ remaining_types = types.reject {|t| t == trueclass || t == falseclass}
38
+ type_shortcuts([T::Private::Types::StringHolder.new("T::Boolean")] + remaining_types)
39
+ else
40
+ names = types.map(&:name).compact.sort
41
+ "T.any(#{names.join(', ')})"
42
+ end
43
+ end
44
+
45
+ # @override Base
46
+ def valid?(obj)
47
+ @types.any? {|type| type.valid?(obj)}
48
+ end
49
+
50
+ # @override Base
51
+ private def subtype_of_single?(other)
52
+ raise "This should never be reached if you're going through `subtype_of?` (and you should be)"
53
+ end
54
+
55
+ end
56
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+ # typed: true
3
+
4
+ module T::Types
5
+ # A dynamic type, which permits whatever
6
+ class Untyped < Base
7
+
8
+ def initialize; end
9
+
10
+ # @override Base
11
+ def name
12
+ "T.untyped"
13
+ end
14
+
15
+ # @override Base
16
+ def valid?(obj)
17
+ true
18
+ end
19
+
20
+ # @override Base
21
+ private def subtype_of_single?(other)
22
+ true
23
+ end
24
+
25
+ module Private
26
+ INSTANCE = Untyped.new.freeze
27
+ end
28
+ end
29
+ end