sorbet-runtime 0.0.1.pre.prealpha → 0.4.4253

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 (69) hide show
  1. checksums.yaml +5 -5
  2. data/lib/sorbet-runtime.rb +100 -0
  3. data/lib/types/_types.rb +245 -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 +37 -0
  7. data/lib/types/configuration.rb +368 -0
  8. data/lib/types/generic.rb +23 -0
  9. data/lib/types/helpers.rb +31 -0
  10. data/lib/types/interface_wrapper.rb +158 -0
  11. data/lib/types/private/abstract/data.rb +36 -0
  12. data/lib/types/private/abstract/declare.rb +39 -0
  13. data/lib/types/private/abstract/hooks.rb +43 -0
  14. data/lib/types/private/abstract/validate.rb +128 -0
  15. data/lib/types/private/casts.rb +22 -0
  16. data/lib/types/private/class_utils.rb +102 -0
  17. data/lib/types/private/decl_state.rb +18 -0
  18. data/lib/types/private/error_handler.rb +37 -0
  19. data/lib/types/private/methods/_methods.rb +344 -0
  20. data/lib/types/private/methods/call_validation.rb +1177 -0
  21. data/lib/types/private/methods/decl_builder.rb +275 -0
  22. data/lib/types/private/methods/modes.rb +18 -0
  23. data/lib/types/private/methods/signature.rb +196 -0
  24. data/lib/types/private/methods/signature_validation.rb +232 -0
  25. data/lib/types/private/mixins/mixins.rb +27 -0
  26. data/lib/types/private/runtime_levels.rb +41 -0
  27. data/lib/types/private/types/not_typed.rb +23 -0
  28. data/lib/types/private/types/string_holder.rb +26 -0
  29. data/lib/types/private/types/void.rb +33 -0
  30. data/lib/types/profile.rb +27 -0
  31. data/lib/types/props/_props.rb +165 -0
  32. data/lib/types/props/constructor.rb +20 -0
  33. data/lib/types/props/custom_type.rb +84 -0
  34. data/lib/types/props/decorator.rb +826 -0
  35. data/lib/types/props/errors.rb +8 -0
  36. data/lib/types/props/optional.rb +73 -0
  37. data/lib/types/props/plugin.rb +15 -0
  38. data/lib/types/props/pretty_printable.rb +106 -0
  39. data/lib/types/props/serializable.rb +376 -0
  40. data/lib/types/props/type_validation.rb +98 -0
  41. data/lib/types/props/utils.rb +49 -0
  42. data/lib/types/props/weak_constructor.rb +30 -0
  43. data/lib/types/runtime_profiled.rb +36 -0
  44. data/lib/types/sig.rb +28 -0
  45. data/lib/types/struct.rb +8 -0
  46. data/lib/types/types/base.rb +141 -0
  47. data/lib/types/types/class_of.rb +38 -0
  48. data/lib/types/types/enum.rb +42 -0
  49. data/lib/types/types/fixed_array.rb +60 -0
  50. data/lib/types/types/fixed_hash.rb +59 -0
  51. data/lib/types/types/intersection.rb +36 -0
  52. data/lib/types/types/noreturn.rb +25 -0
  53. data/lib/types/types/proc.rb +51 -0
  54. data/lib/types/types/self_type.rb +31 -0
  55. data/lib/types/types/simple.rb +33 -0
  56. data/lib/types/types/type_member.rb +7 -0
  57. data/lib/types/types/type_parameter.rb +23 -0
  58. data/lib/types/types/type_template.rb +7 -0
  59. data/lib/types/types/type_variable.rb +31 -0
  60. data/lib/types/types/typed_array.rb +20 -0
  61. data/lib/types/types/typed_enumerable.rb +141 -0
  62. data/lib/types/types/typed_enumerator.rb +22 -0
  63. data/lib/types/types/typed_hash.rb +29 -0
  64. data/lib/types/types/typed_range.rb +22 -0
  65. data/lib/types/types/typed_set.rb +22 -0
  66. data/lib/types/types/union.rb +59 -0
  67. data/lib/types/types/untyped.rb +25 -0
  68. data/lib/types/utils.rb +223 -0
  69. metadata +122 -15
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA256:
3
- metadata.gz: c4f49cb714c88c903514f17f163768e3bd1575acd6b0d03db35f75da70e16c1e
4
- data.tar.gz: 79d77212df76f815de71d6ece2887942d115944b70837bd292726091d43eec83
2
+ SHA1:
3
+ metadata.gz: de11dcda7e38c4977b8e8adb679d16e2e34b94df
4
+ data.tar.gz: 930cdf2804d7b8919dea38ccd474e261a654e03d
5
5
  SHA512:
6
- metadata.gz: 0d4f30e545125cbb41591bb593ceb96460a8fb67deeafa2c9f37d7ec314998c53e26afa21c0af280633840a37ef1a06068c83f12cf330a24ef2bdb0a567dc024
7
- data.tar.gz: be94a5f46d1e95b4ce2f8d767587e84271111bc026706210806349afab18fc327a2acd65295a85098241f13f3c313665b79da3cff0ac4efabeea9178f60f3df4
6
+ metadata.gz: 77caf2c55b6c999939a4860e8be38088854a4530cac75bee1c9cca68ed2d8b8c9ef6182061a15c73d0e5cf343ef6e2caaa7f3e5c45690b79ed41af18ebe1d2b4
7
+ data.tar.gz: 76a0990ca32cd691b58ae71ff7a34e6e63f0c674da3945718d6a5060f91bc08e50ec55972aafb8cf87930fba2220da3a336b557c8ad9121475e0a97445539a78
@@ -0,0 +1,100 @@
1
+ # frozen_string_literal: true
2
+ # typed: true
3
+
4
+ # This file is hand-crafted to encode the dependencies. They load the whole type
5
+ # system since there is such a high chance of it being used, using an autoloader
6
+ # wouldn't buy us any startup time saving.
7
+
8
+ # Namespaces without any implementation
9
+ module T; end
10
+ module T::Helpers; end
11
+ module T::Private; end
12
+ module T::Private::Abstract; end
13
+ module T::Private::Types; end
14
+
15
+ require 'set'
16
+
17
+ # Each section is a group that I believe need a fixed ordering. There is also
18
+ # an ordering between groups.
19
+
20
+ # These are pre-reqs for almost everything in here.
21
+ require_relative 'types/configuration'
22
+ require_relative 'types/profile'
23
+ require_relative 'types/_types'
24
+ require_relative 'types/private/decl_state'
25
+ require_relative 'types/runtime_profiled'
26
+ require_relative 'types/private/class_utils'
27
+ require_relative 'types/private/error_handler'
28
+ require_relative 'types/private/runtime_levels'
29
+ require_relative 'types/private/methods/_methods'
30
+ require_relative 'types/sig'
31
+ require_relative 'types/helpers'
32
+
33
+ # The types themselves. First base classes
34
+ require_relative 'types/types/base'
35
+ require_relative 'types/types/typed_enumerable'
36
+ # Everything else
37
+ require_relative 'types/types/class_of'
38
+ require_relative 'types/types/enum'
39
+ require_relative 'types/types/fixed_array'
40
+ require_relative 'types/types/fixed_hash'
41
+ require_relative 'types/types/intersection'
42
+ require_relative 'types/types/noreturn'
43
+ require_relative 'types/types/proc'
44
+ require_relative 'types/types/self_type'
45
+ require_relative 'types/types/simple'
46
+ require_relative 'types/types/type_parameter'
47
+ require_relative 'types/types/typed_array'
48
+ require_relative 'types/types/typed_enumerator'
49
+ require_relative 'types/types/typed_hash'
50
+ require_relative 'types/types/typed_range'
51
+ require_relative 'types/types/typed_set'
52
+ require_relative 'types/types/union'
53
+ require_relative 'types/types/untyped'
54
+ require_relative 'types/private/types/not_typed'
55
+ require_relative 'types/private/types/void'
56
+ require_relative 'types/private/types/string_holder'
57
+
58
+ require_relative 'types/types/type_variable'
59
+ require_relative 'types/types/type_member'
60
+ require_relative 'types/types/type_template'
61
+
62
+ # Call validation
63
+ require_relative 'types/private/methods/modes'
64
+ require_relative 'types/private/methods/call_validation'
65
+
66
+ # Signature validation
67
+ require_relative 'types/private/methods/signature_validation'
68
+ require_relative 'types/abstract_utils'
69
+ require_relative 'types/private/abstract/validate'
70
+
71
+ # Catch all. Sort of built by `cd extn; find types -type f | grep -v test | sort`
72
+ require_relative 'types/generic'
73
+ require_relative 'types/interface_wrapper'
74
+ require_relative 'types/private/abstract/declare'
75
+ require_relative 'types/private/abstract/hooks'
76
+ require_relative 'types/private/casts'
77
+ require_relative 'types/private/methods/decl_builder'
78
+ require_relative 'types/private/methods/signature'
79
+ require_relative 'types/utils'
80
+ require_relative 'types/boolean'
81
+
82
+ # Props dependencies
83
+ require_relative 'types/private/abstract/data'
84
+ require_relative 'types/private/mixins/mixins'
85
+ require_relative 'types/props/_props'
86
+ require_relative 'types/props/custom_type'
87
+ require_relative 'types/props/decorator'
88
+ require_relative 'types/props/errors'
89
+ require_relative 'types/props/plugin'
90
+ require_relative 'types/props/utils'
91
+ # Props that run sigs statically so have to be after all the others :(
92
+ require_relative 'types/props/optional'
93
+ require_relative 'types/props/weak_constructor'
94
+ require_relative 'types/props/constructor'
95
+ require_relative 'types/props/pretty_printable'
96
+ require_relative 'types/props/serializable'
97
+ require_relative 'types/props/type_validation'
98
+ require_relative 'types/struct'
99
+
100
+ require_relative 'types/compatibility_patches'
@@ -0,0 +1,245 @@
1
+ # frozen_string_literal: true
2
+ # typed: true
3
+ # This is where we define the shortcuts, so we can't use them here
4
+ # rubocop:disable PrisonGuard/UseOpusTypesShortcut
5
+
6
+ # _____
7
+ # |_ _| _ _ __ ___ ___
8
+ # | || | | | '_ \ / _ \/ __|
9
+ # | || |_| | |_) | __/\__ \
10
+ # |_| \__, | .__/ \___||___/
11
+ # |___/|_|
12
+ #
13
+ # Docs at http://go/types.
14
+ #
15
+ # Types that you can pass to `sig`:
16
+ #
17
+ # - a Ruby class
18
+ #
19
+ # - [<Type>, <Type>, ...] -- to specify a "tuple"; a fixed-size array with known types for each member
20
+ #
21
+ # - {key: <Type>, key2: <Type>, ...} -- to speicfy a "shape"; a fixed-size hash
22
+ # with known keys and type values
23
+ #
24
+ # - Any of the `T.foo` methods below
25
+
26
+ module T
27
+ # T.any(<Type>, <Type>, ...) -- matches any of the types listed
28
+ def self.any(type_a, type_b, *types)
29
+ T::Types::Union.new([type_a, type_b] + types)
30
+ end
31
+
32
+ # Shorthand for T.any(type, NilClass)
33
+ def self.nilable(type)
34
+ T::Types::Union.new([type, NilClass])
35
+ end
36
+
37
+ # Matches any object. In the static checker, T.untyped allows any
38
+ # method calls or operations.
39
+ def self.untyped
40
+ T::Types::Untyped.new
41
+ end
42
+
43
+ # Indicates a function never returns (e.g. "Kernel#raise")
44
+ def self.noreturn
45
+ T::Types::NoReturn.new
46
+ end
47
+
48
+ # T.all(<Type>, <Type>, ...) -- matches an object that has all of the types listed
49
+ def self.all(type_a, type_b, *types)
50
+ T::Types::Intersection.new([type_a, type_b] + types)
51
+ end
52
+
53
+ # Matches any of the listed values
54
+ def self.enum(values)
55
+ T::Types::Enum.new(values)
56
+ end
57
+
58
+ # Creates a proc type
59
+ def self.proc
60
+ T::Private::Methods.start_proc
61
+ end
62
+
63
+ # Matches `self`:
64
+ def self.self_type
65
+ T::Types::SelfType.new
66
+ end
67
+
68
+ # Matches any class that subclasses or includes the provided class
69
+ # or module
70
+ def self.class_of(klass)
71
+ T::Types::ClassOf.new(klass)
72
+ end
73
+
74
+
75
+ ## END OF THE METHODS TO PASS TO `sig`.
76
+
77
+
78
+ # Constructs a type alias. Used to create a short name for a larger
79
+ # type. In Ruby this is just equivalent to assignment, but this is
80
+ # needed for support by the static checker. Example usage:
81
+ #
82
+ # NilableString = T.type_alias(T.nilable(String))
83
+ #
84
+ # sig {params(arg: NilableString, default: String).returns(String)}
85
+ # def or_else(arg, default)
86
+ # arg || default
87
+ # end
88
+ #
89
+ # The name of the type alias is not preserved; Error messages will
90
+ # be printed with reference to the underlying type.
91
+ def self.type_alias(type)
92
+ T::Utils.coerce(type)
93
+ end
94
+
95
+ # References a type paramater which was previously defined with
96
+ # `type_parameters`.
97
+ #
98
+ # This is used for generic methods. Example usage:
99
+ #
100
+ # sig
101
+ # .type_parameters(:U)
102
+ # .params(
103
+ # blk: T.proc.params(arg0: Elem).returns(T.type_parameter(:U)),
104
+ # )
105
+ # .returns(T::Array[T.type_parameter(:U)])
106
+ # def map(&blk); end
107
+ def self.type_parameter(name)
108
+ T::Types::TypeParameter.new(name)
109
+ end
110
+
111
+ # Tells the typechecker that `value` is of type `type`. Use this to get additional checking after
112
+ # an expression that the typechecker is unable to analyze. If `checked` is true, raises an
113
+ # exception at runtime if the value doesn't match the type.
114
+ #
115
+ # Compared to `T.let`, `T.cast` is _trusted_ by static system.
116
+ def self.cast(value, type, checked: true)
117
+ return value unless checked
118
+
119
+ Private::Casts.cast(value, type, cast_method: "T.cast")
120
+ end
121
+
122
+ # Tells the typechecker to declare a variable of type `type`. Use
123
+ # like:
124
+ #
125
+ # seconds = T.let(0.0, Float)
126
+ #
127
+ # Compared to `T.cast`, `T.let` is _checked_ by static system.
128
+ #
129
+ # If `checked` is true, raises an exception at runtime if the value
130
+ # doesn't match the type.
131
+ def self.let(value, type, checked: true)
132
+ return value unless checked
133
+
134
+ Private::Casts.cast(value, type, cast_method: "T.let")
135
+ end
136
+
137
+ # Tells the typechecker to ensure that `value` is of type `type` (if not, the typechecker will
138
+ # fail). Use this for debugging typechecking errors, or to ensure that type information is
139
+ # statically known and being checked appropriately. If `checked` is true, raises an exception at
140
+ # runtime if the value doesn't match the type.
141
+ def self.assert_type!(value, type, checked: true)
142
+ return value unless checked
143
+
144
+ Private::Casts.cast(value, type, cast_method: "T.assert_type!")
145
+ end
146
+
147
+ # For the static type checker, strips all type information from a value
148
+ # and returns the same value, but statically-typed as `T.untyped`.
149
+ # Can be used to tell the static checker to "trust you" by discarding type information
150
+ # you know to be incorrect. Use with care!
151
+ # (This has no effect at runtime.)
152
+ #
153
+ # We can't actually write this sig because we ourselves are inside
154
+ # the `T::` module and doing this would create a bootstrapping
155
+ # cycle. However, we also don't actually need to do so; An untyped
156
+ # identity method works just as well here.
157
+ #
158
+ # sig {params(value: T.untyped).returns(T.untyped)}
159
+ def self.unsafe(value)
160
+ value
161
+ end
162
+
163
+ # A convenience method to `raise` when the argument is `nil` and return it
164
+ # otherwise.
165
+ #
166
+ # Intended to be used as:
167
+ #
168
+ # needs_foo(T.must(maybe_gives_foo))
169
+ #
170
+ # Equivalent to:
171
+ #
172
+ # foo = maybe_gives_foo
173
+ # raise "nil" if foo.nil?
174
+ # needs_foo(foo)
175
+ #
176
+ # Intended to be used to promise sorbet that a given nilable value happens
177
+ # to contain a non-nil value at this point.
178
+ #
179
+ # sig {params(arg: T.nilable(A), msg: T.nilable(String)).returns(A)}
180
+ def self.must(arg, msg=nil)
181
+ begin
182
+ if msg
183
+ if !T.unsafe(msg).is_a?(String)
184
+ raise TypeError.new("T.must expects a string as second argument")
185
+ end
186
+ else
187
+ msg = "Passed `nil` into T.must"
188
+ end
189
+ raise TypeError.new(msg) if arg.nil?
190
+ arg
191
+ rescue TypeError => e # raise into rescue to ensure e.backtrace is populated
192
+ T::Private::ErrorHandler.handle_inline_type_error(e)
193
+ arg
194
+ end
195
+ end
196
+
197
+ # A way to ask Sorbet to show what type it thinks an expression has.
198
+ # This can be useful for debugging and checking assumptions.
199
+ # In the runtime, merely returns the value passed in.
200
+ def self.reveal_type(value)
201
+ value
202
+ end
203
+
204
+ ### Generic classes ###
205
+
206
+ module Array
207
+ def self.[](type)
208
+ T::Types::TypedArray.new(type)
209
+ end
210
+ end
211
+
212
+ module Hash
213
+ def self.[](keys, values)
214
+ T::Types::TypedHash.new(keys: keys, values: values)
215
+ end
216
+ end
217
+
218
+ module Enumerable
219
+ def self.[](type)
220
+ T::Types::TypedEnumerable.new(type)
221
+ end
222
+ end
223
+
224
+ module Enumerator
225
+ def self.[](type)
226
+ T::Types::TypedEnumerator.new(type)
227
+ end
228
+ end
229
+
230
+ module Range
231
+ def self.[](type)
232
+ T::Types::TypedRange.new(type)
233
+ end
234
+ end
235
+
236
+ module Set
237
+ def self.[](type)
238
+ T::Types::TypedSet.new(type)
239
+ end
240
+ end
241
+
242
+ # When mixed into a module, indicates that Sorbet may export the CFG for methods in that module
243
+ module CFGExport; end
244
+ end
245
+ # rubocop:enable PrisonGuard/UseOpusTypesShortcut
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+ # typed: true
3
+
4
+ module T::AbstractUtils
5
+ Methods = T::Private::Methods
6
+
7
+ # Returns whether a module is declared as abstract. After the module is finished being declared,
8
+ # this is equivalent to whether it has any abstract methods that haven't been implemented
9
+ # (because we validate that and raise an error otherwise).
10
+ #
11
+ # Note that checking `mod.is_a?(Abstract::Hooks)` is not a safe substitute for this method; when
12
+ # a class extends `Abstract::Hooks`, all of its subclasses, including the eventual concrete
13
+ # ones, will still have `Abstract::Hooks` as an ancestor.
14
+ def self.abstract_module?(mod)
15
+ !T::Private::Abstract::Data.get(mod, :abstract_type).nil?
16
+ end
17
+
18
+ def self.abstract_method?(method)
19
+ signature = Methods.signature_for_method(method)
20
+ signature&.mode == Methods::Modes.abstract
21
+ end
22
+
23
+ # Given a module, returns the set of methods declared as abstract (in itself or ancestors)
24
+ # that have not been implemented.
25
+ def self.abstract_methods_for(mod)
26
+ declared_methods = declared_abstract_methods_for(mod)
27
+ declared_methods.select do |declared_method|
28
+ actual_method = mod.instance_method(declared_method.name)
29
+ # Note that in the case where an abstract method is overridden by another abstract method,
30
+ # this method will return them both. This is intentional to ensure we validate the final
31
+ # implementation against all declarations of an abstract method (they might not all have the
32
+ # same signature).
33
+ abstract_method?(actual_method)
34
+ end
35
+ end
36
+
37
+ # Given a module, returns the set of methods declared as abstract (in itself or ancestors)
38
+ # regardless of whether they have been implemented.
39
+ def self.declared_abstract_methods_for(mod)
40
+ methods = []
41
+ mod.ancestors.each do |ancestor|
42
+ ancestor_methods = ancestor.private_instance_methods(false) + ancestor.instance_methods(false)
43
+ ancestor_methods.each do |method_name|
44
+ method = ancestor.instance_method(method_name)
45
+ methods << method if abstract_method?(method)
46
+ end
47
+ end
48
+ methods
49
+ end
50
+ end
@@ -0,0 +1,8 @@
1
+ # typed: true
2
+ # frozen_string_literal: true
3
+
4
+ module T
5
+ # T::Boolean is a type alias helper for the common `T.any(TrueClass, FalseClass)`.
6
+ # Defined separately from _types.rb because it has a dependency on T::Types::Union.
7
+ Boolean = T.type_alias(T.any(TrueClass, FalseClass))
8
+ end
@@ -0,0 +1,37 @@
1
+ # typed: ignore
2
+
3
+ require_relative 'private/methods/_methods'
4
+
5
+ # Work around an interaction bug with sorbet-runtime and rspec-mocks,
6
+ # which occurs when using *_any_instance_of and and_call_original.
7
+ #
8
+ # When a sig is defined, sorbet-runtime will replace the sigged method
9
+ # with a wrapper that, upon first invocation, re-wraps the method with a faster
10
+ # implementation.
11
+ #
12
+ # When expect_any_instance_of is used, rspec stores a reference to the first wrapper,
13
+ # to be restored later.
14
+ #
15
+ # The first wrapper is invoked as part of the test and sorbet-runtime replaces
16
+ # the method definition with the second wrapper.
17
+ #
18
+ # But when mocks are cleaned up, rspec restores back to the first wrapper.
19
+ # Upon subsequent invocations, the first wrapper is called, and sorbet-runtime
20
+ # throws a runtime error, since this is an unexpected state.
21
+ #
22
+ # We work around this by forcing re-wrapping before rspec stores a reference
23
+ # to the method.
24
+ if defined? ::RSpec::Mocks::AnyInstance
25
+ module T
26
+ module CompatibilityPatches
27
+ module RecorderExtensions
28
+ def observe!(method_name)
29
+ method = @klass.instance_method(method_name.to_sym)
30
+ T::Private::Methods.maybe_run_sig_block_for_method(method)
31
+ super(method_name)
32
+ end
33
+ end
34
+ ::RSpec::Mocks::AnyInstance::Recorder.prepend(RecorderExtensions)
35
+ end
36
+ end
37
+ end