sorbet-runtime 0.4.4301 → 0.5.5794

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 (66) hide show
  1. checksums.yaml +5 -5
  2. data/lib/sorbet-runtime.rb +17 -1
  3. data/lib/types/_types.rb +68 -28
  4. data/lib/types/boolean.rb +2 -2
  5. data/lib/types/compatibility_patches.rb +66 -8
  6. data/lib/types/configuration.rb +128 -68
  7. data/lib/types/enum.rb +349 -0
  8. data/lib/types/generic.rb +2 -2
  9. data/lib/types/helpers.rb +8 -0
  10. data/lib/types/non_forcing_constants.rb +51 -0
  11. data/lib/types/private/abstract/declare.rb +10 -5
  12. data/lib/types/private/abstract/validate.rb +1 -1
  13. data/lib/types/private/casts.rb +1 -1
  14. data/lib/types/private/class_utils.rb +11 -2
  15. data/lib/types/private/decl_state.rb +12 -0
  16. data/lib/types/private/final.rb +51 -0
  17. data/lib/types/private/methods/_methods.rb +165 -49
  18. data/lib/types/private/methods/call_validation.rb +27 -55
  19. data/lib/types/private/methods/decl_builder.rb +36 -83
  20. data/lib/types/private/methods/modes.rb +5 -7
  21. data/lib/types/private/methods/signature.rb +11 -11
  22. data/lib/types/private/methods/signature_validation.rb +19 -22
  23. data/lib/types/private/retry.rb +10 -0
  24. data/lib/types/private/runtime_levels.rb +15 -0
  25. data/lib/types/private/sealed.rb +65 -0
  26. data/lib/types/private/types/type_alias.rb +26 -0
  27. data/lib/types/private/types/void.rb +4 -3
  28. data/lib/types/props/_props.rb +3 -7
  29. data/lib/types/props/constructor.rb +24 -10
  30. data/lib/types/props/custom_type.rb +51 -27
  31. data/lib/types/props/decorator.rb +232 -386
  32. data/lib/types/props/errors.rb +1 -1
  33. data/lib/types/props/generated_code_validation.rb +268 -0
  34. data/lib/types/props/has_lazily_specialized_methods.rb +92 -0
  35. data/lib/types/props/optional.rb +43 -35
  36. data/lib/types/props/plugin.rb +23 -1
  37. data/lib/types/props/pretty_printable.rb +4 -3
  38. data/lib/types/props/private/apply_default.rb +170 -0
  39. data/lib/types/props/private/deserializer_generator.rb +165 -0
  40. data/lib/types/props/private/parser.rb +32 -0
  41. data/lib/types/props/private/serde_transform.rb +192 -0
  42. data/lib/types/props/private/serializer_generator.rb +77 -0
  43. data/lib/types/props/private/setter_factory.rb +134 -0
  44. data/lib/types/props/serializable.rb +133 -179
  45. data/lib/types/props/type_validation.rb +18 -5
  46. data/lib/types/props/utils.rb +18 -8
  47. data/lib/types/props/weak_constructor.rb +47 -15
  48. data/lib/types/runtime_profiled.rb +12 -24
  49. data/lib/types/sig.rb +12 -10
  50. data/lib/types/types/attached_class.rb +33 -0
  51. data/lib/types/types/base.rb +11 -1
  52. data/lib/types/types/intersection.rb +1 -0
  53. data/lib/types/types/t_enum.rb +38 -0
  54. data/lib/types/types/type_member.rb +1 -1
  55. data/lib/types/types/type_parameter.rb +1 -1
  56. data/lib/types/types/type_template.rb +1 -1
  57. data/lib/types/types/typed_array.rb +14 -0
  58. data/lib/types/types/typed_enumerable.rb +29 -9
  59. data/lib/types/types/typed_enumerator.rb +14 -0
  60. data/lib/types/types/typed_hash.rb +14 -0
  61. data/lib/types/types/typed_range.rb +4 -0
  62. data/lib/types/types/typed_set.rb +14 -0
  63. data/lib/types/types/union.rb +1 -0
  64. data/lib/types/utils.rb +29 -35
  65. metadata +77 -9
  66. data/lib/types/private/error_handler.rb +0 -37
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 4caba5123cd2598c381ec8aee684b3ec9d836e82
4
- data.tar.gz: 6a9bbf51e25f0228c8cec2f98565af5721227953
2
+ SHA256:
3
+ metadata.gz: ac9a48252c9529d0ca91f96108b141c85388c88180281e5c8a682b16c11a9d5a
4
+ data.tar.gz: 31dc95eabc00327b1672a8fc142da7dc47f0ee0699fd4112358042248628675b
5
5
  SHA512:
6
- metadata.gz: c57c3dca97c35bdb4b7bde004ad20e5a78d0e737f7f2a2a78e047d20feb9513fa5ed216ee083a61222c98616f4764e47b5eb16be096fb040630a666adb8d24a9
7
- data.tar.gz: e88711e3451d9b31013284f577390aa41a85e1f0ad57d639471a1cb2e83da4e7256ebe4c4a6bd4ca73698fc846058791c57364d39f19011438f065cda53b5c7f
6
+ metadata.gz: 21b1ef4ffdd76365effafe0c6a3eea4b15c1f9c36f2f402a1c8ba382d2f03d89f2202c1b8ac2aa82c315c7471f0989f7501d1888a49f67d401d33d26ac8e4d3a
7
+ data.tar.gz: 0f4c110725910ae452ea72fe6852538aa1c31cbb576dc242fe3631bd318e3b2bfda7b0fe3b05362584bd53885c9788a4f3eb2d5920d285c1c39ce727fb0ebd14
@@ -24,11 +24,12 @@ require_relative 'types/_types'
24
24
  require_relative 'types/private/decl_state'
25
25
  require_relative 'types/runtime_profiled'
26
26
  require_relative 'types/private/class_utils'
27
- require_relative 'types/private/error_handler'
28
27
  require_relative 'types/private/runtime_levels'
29
28
  require_relative 'types/private/methods/_methods'
30
29
  require_relative 'types/sig'
31
30
  require_relative 'types/helpers'
31
+ require_relative 'types/private/final'
32
+ require_relative 'types/private/sealed'
32
33
 
33
34
  # The types themselves. First base classes
34
35
  require_relative 'types/types/base'
@@ -41,8 +42,10 @@ require_relative 'types/types/fixed_hash'
41
42
  require_relative 'types/types/intersection'
42
43
  require_relative 'types/types/noreturn'
43
44
  require_relative 'types/types/proc'
45
+ require_relative 'types/types/attached_class'
44
46
  require_relative 'types/types/self_type'
45
47
  require_relative 'types/types/simple'
48
+ require_relative 'types/types/t_enum'
46
49
  require_relative 'types/types/type_parameter'
47
50
  require_relative 'types/types/typed_array'
48
51
  require_relative 'types/types/typed_enumerator'
@@ -54,6 +57,7 @@ require_relative 'types/types/untyped'
54
57
  require_relative 'types/private/types/not_typed'
55
58
  require_relative 'types/private/types/void'
56
59
  require_relative 'types/private/types/string_holder'
60
+ require_relative 'types/private/types/type_alias'
57
61
 
58
62
  require_relative 'types/types/type_variable'
59
63
  require_relative 'types/types/type_member'
@@ -76,6 +80,7 @@ require_relative 'types/private/abstract/hooks'
76
80
  require_relative 'types/private/casts'
77
81
  require_relative 'types/private/methods/decl_builder'
78
82
  require_relative 'types/private/methods/signature'
83
+ require_relative 'types/private/retry'
79
84
  require_relative 'types/utils'
80
85
  require_relative 'types/boolean'
81
86
 
@@ -88,13 +93,24 @@ require_relative 'types/props/decorator'
88
93
  require_relative 'types/props/errors'
89
94
  require_relative 'types/props/plugin'
90
95
  require_relative 'types/props/utils'
96
+ require_relative 'types/enum'
91
97
  # Props that run sigs statically so have to be after all the others :(
98
+ require_relative 'types/props/private/setter_factory'
99
+ require_relative 'types/props/private/apply_default'
100
+ require_relative 'types/props/has_lazily_specialized_methods'
92
101
  require_relative 'types/props/optional'
93
102
  require_relative 'types/props/weak_constructor'
94
103
  require_relative 'types/props/constructor'
95
104
  require_relative 'types/props/pretty_printable'
105
+ require_relative 'types/props/private/serde_transform'
106
+ require_relative 'types/props/private/deserializer_generator'
107
+ require_relative 'types/props/private/serializer_generator'
96
108
  require_relative 'types/props/serializable'
97
109
  require_relative 'types/props/type_validation'
110
+ require_relative 'types/props/private/parser'
111
+ require_relative 'types/props/generated_code_validation'
112
+
98
113
  require_relative 'types/struct'
114
+ require_relative 'types/non_forcing_constants'
99
115
 
100
116
  require_relative 'types/compatibility_patches'
data/lib/types/_types.rb CHANGED
@@ -65,6 +65,11 @@ module T
65
65
  T::Types::SelfType.new
66
66
  end
67
67
 
68
+ # Matches the instance type in a singleton-class context
69
+ def self.attached_class
70
+ T::Types::AttachedClassType.new
71
+ end
72
+
68
73
  # Matches any class that subclasses or includes the provided class
69
74
  # or module
70
75
  def self.class_of(klass)
@@ -75,11 +80,11 @@ module T
75
80
  ## END OF THE METHODS TO PASS TO `sig`.
76
81
 
77
82
 
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:
83
+ # Constructs a type alias. Used to create a short name for a larger type. In Ruby this returns a
84
+ # wrapper that contains a proc that is evaluated to get the underlying type. This syntax however
85
+ # is needed for support by the static checker. Example usage:
81
86
  #
82
- # NilableString = T.type_alias(T.nilable(String))
87
+ # NilableString = T.type_alias {T.nilable(String)}
83
88
  #
84
89
  # sig {params(arg: NilableString, default: String).returns(String)}
85
90
  # def or_else(arg, default)
@@ -88,11 +93,17 @@ module T
88
93
  #
89
94
  # The name of the type alias is not preserved; Error messages will
90
95
  # be printed with reference to the underlying type.
91
- def self.type_alias(type)
92
- T::Utils.coerce(type)
96
+ #
97
+ # TODO Remove `type` parameter. This was left in to make life easier while migrating.
98
+ def self.type_alias(type=nil, &blk)
99
+ if blk
100
+ T::Private::Types::TypeAlias.new(blk)
101
+ else
102
+ T::Utils.coerce(type)
103
+ end
93
104
  end
94
105
 
95
- # References a type paramater which was previously defined with
106
+ # References a type parameter which was previously defined with
96
107
  # `type_parameters`.
97
108
  #
98
109
  # This is used for generic methods. Example usage:
@@ -176,21 +187,15 @@ module T
176
187
  # Intended to be used to promise sorbet that a given nilable value happens
177
188
  # to contain a non-nil value at this point.
178
189
  #
179
- # sig {params(arg: T.nilable(A), msg: T.nilable(String)).returns(A)}
180
- def self.must(arg, msg=nil)
190
+ # sig {params(arg: T.nilable(A)).returns(A)}
191
+ def self.must(arg)
192
+ return arg if arg
193
+ return arg if arg == false
194
+
181
195
  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
196
+ raise TypeError.new("Passed `nil` into T.must")
191
197
  rescue TypeError => e # raise into rescue to ensure e.backtrace is populated
192
- T::Private::ErrorHandler.handle_inline_type_error(e)
193
- arg
198
+ T::Configuration.inline_type_error_handler(e)
194
199
  end
195
200
  end
196
201
 
@@ -201,29 +206,63 @@ module T
201
206
  value
202
207
  end
203
208
 
209
+ # A way to ask Sorbet to prove that a certain branch of control flow never
210
+ # happens. Commonly used to assert that a case or if statement exhausts all
211
+ # possible cases.
212
+ def self.absurd(value)
213
+ msg = "Control flow reached T.absurd."
214
+
215
+ case value
216
+ when Kernel
217
+ msg += " Got value: #{value}"
218
+ end
219
+
220
+ begin
221
+ raise TypeError.new(msg)
222
+ rescue TypeError => e # raise into rescue to ensure e.backtrace is populated
223
+ T::Configuration.inline_type_error_handler(e)
224
+ end
225
+ end
226
+
204
227
  ### Generic classes ###
205
228
 
206
229
  module Array
207
230
  def self.[](type)
208
- T::Types::TypedArray.new(type)
231
+ if type.is_a?(T::Types::Untyped)
232
+ T::Types::TypedArray::Untyped.new
233
+ else
234
+ T::Types::TypedArray.new(type)
235
+ end
209
236
  end
210
237
  end
211
238
 
212
239
  module Hash
213
240
  def self.[](keys, values)
214
- T::Types::TypedHash.new(keys: keys, values: values)
241
+ if keys.is_a?(T::Types::Untyped) && values.is_a?(T::Types::Untyped)
242
+ T::Types::TypedHash::Untyped.new
243
+ else
244
+ T::Types::TypedHash.new(keys: keys, values: values)
245
+ end
215
246
  end
216
247
  end
217
248
 
218
249
  module Enumerable
219
250
  def self.[](type)
220
- T::Types::TypedEnumerable.new(type)
251
+ if type.is_a?(T::Types::Untyped)
252
+ T::Types::TypedEnumerable::Untyped.new
253
+ else
254
+ T::Types::TypedEnumerable.new(type)
255
+ end
221
256
  end
222
257
  end
223
258
 
224
259
  module Enumerator
225
260
  def self.[](type)
226
- T::Types::TypedEnumerator.new(type)
261
+ if type.is_a?(T::Types::Untyped)
262
+ T::Types::TypedEnumerator::Untyped.new
263
+ else
264
+ T::Types::TypedEnumerator.new(type)
265
+ end
227
266
  end
228
267
  end
229
268
 
@@ -235,11 +274,12 @@ module T
235
274
 
236
275
  module Set
237
276
  def self.[](type)
238
- T::Types::TypedSet.new(type)
277
+ if type.is_a?(T::Types::Untyped)
278
+ T::Types::TypedSet::Untyped.new
279
+ else
280
+ T::Types::TypedSet.new(type)
281
+ end
239
282
  end
240
283
  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
284
  end
245
285
  # rubocop:enable PrisonGuard/UseOpusTypesShortcut
data/lib/types/boolean.rb CHANGED
@@ -1,8 +1,8 @@
1
- # typed: true
1
+ # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module T
5
5
  # T::Boolean is a type alias helper for the common `T.any(TrueClass, FalseClass)`.
6
6
  # Defined separately from _types.rb because it has a dependency on T::Types::Union.
7
- Boolean = T.type_alias(T.any(TrueClass, FalseClass))
7
+ Boolean = T.type_alias {T.any(TrueClass, FalseClass)}
8
8
  end
@@ -1,9 +1,11 @@
1
+ # frozen_string_literal: true
1
2
  # typed: ignore
2
3
 
3
4
  require_relative 'private/methods/_methods'
4
5
 
5
6
  # Work around an interaction bug with sorbet-runtime and rspec-mocks,
6
- # which occurs when using *_any_instance_of and and_call_original.
7
+ # which occurs when using message expectations (*_any_instance_of,
8
+ # expect, allow) and and_call_original.
7
9
  #
8
10
  # When a sig is defined, sorbet-runtime will replace the sigged method
9
11
  # with a wrapper that, upon first invocation, re-wraps the method with a faster
@@ -21,17 +23,73 @@ require_relative 'private/methods/_methods'
21
23
  #
22
24
  # We work around this by forcing re-wrapping before rspec stores a reference
23
25
  # to the method.
24
- if defined? ::RSpec::Mocks::AnyInstance
26
+ if defined? ::RSpec::Mocks
25
27
  module T
26
28
  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)
29
+ module RSpecCompatibility
30
+ module RecorderExtensions
31
+ def observe!(method_name)
32
+ method = @klass.instance_method(method_name.to_sym)
33
+ T::Private::Methods.maybe_run_sig_block_for_method(method)
34
+ super(method_name)
35
+ end
32
36
  end
37
+ ::RSpec::Mocks::AnyInstance::Recorder.prepend(RecorderExtensions) if defined?(::RSpec::Mocks::AnyInstance::Recorder)
38
+
39
+ module MethodDoubleExtensions
40
+ def initialize(object, method_name, proxy)
41
+ if ::Kernel.instance_method(:respond_to?).bind(object).call(method_name, true)
42
+ method = ::RSpec::Support.method_handle_for(object, method_name)
43
+ T::Private::Methods.maybe_run_sig_block_for_method(method)
44
+ end
45
+ super(object, method_name, proxy)
46
+ end
47
+ end
48
+ ::RSpec::Mocks::MethodDouble.prepend(MethodDoubleExtensions) if defined?(::RSpec::Mocks::MethodDouble)
49
+ end
50
+ end
51
+ end
52
+ end
53
+
54
+ # Work around for sorbet-runtime wrapped methods.
55
+ #
56
+ # When a sig is defined, sorbet-runtime will replace the sigged method
57
+ # with a wrapper. Those wrapper methods look like `foo(*args, &blk)`
58
+ # so that wrappers can handle and pass on all the arguments supplied.
59
+ #
60
+ # However, that creates a problem with runtime reflection on the methods,
61
+ # since when a sigged method is introspected, it will always return its
62
+ # `arity` as `-1`, its `parameters` as `[[:rest, :args], [:block, :blk]]`,
63
+ # and its `source_location` as `[<some_file_in_sorbet>, <some_line_number>]`.
64
+ #
65
+ # This might be a problem for some applications that rely on getting the
66
+ # correct information from these methods.
67
+ #
68
+ # This compatibility module, when prepended to the `Method` class, would fix
69
+ # the return values of `arity`, `parameters` and `source_location`.
70
+ #
71
+ # @example
72
+ # require 'sorbet-runtime'
73
+ # ::Method.prepend(T::CompatibilityPatches::MethodExtensions)
74
+ module T
75
+ module CompatibilityPatches
76
+ module MethodExtensions
77
+ def arity
78
+ arity = super
79
+ return arity if arity != -1 || self.is_a?(Proc)
80
+ sig = T::Private::Methods.signature_for_method(self)
81
+ sig ? sig.method.arity : arity
82
+ end
83
+
84
+ def source_location
85
+ sig = T::Private::Methods.signature_for_method(self)
86
+ sig ? sig.method.source_location : super
87
+ end
88
+
89
+ def parameters
90
+ sig = T::Private::Methods.signature_for_method(self)
91
+ sig ? sig.method.parameters : super
33
92
  end
34
- ::RSpec::Mocks::AnyInstance::Recorder.prepend(RecorderExtensions)
35
93
  end
36
94
  end
37
95
  end
@@ -2,6 +2,59 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module T::Configuration
5
+ # Announces to Sorbet that we are currently in a test environment, so it
6
+ # should treat any sigs which are marked `.checked(:tests)` as if they were
7
+ # just a normal sig.
8
+ #
9
+ # If this method is not called, sigs marked `.checked(:tests)` will not be
10
+ # checked. In fact, such methods won't even be wrapped--the runtime will put
11
+ # back the original method.
12
+ #
13
+ # Note: Due to the way sigs are evaluated and methods are wrapped, this
14
+ # method MUST be called before any code calls `sig`. This method raises if
15
+ # it has been called too late.
16
+ def self.enable_checking_for_sigs_marked_checked_tests
17
+ T::Private::RuntimeLevels.enable_checking_in_tests
18
+ end
19
+
20
+ # Announce to Sorbet that we would like the final checks to be enabled when
21
+ # including and extending modules. Iff this is not called, then the following
22
+ # example will not raise an error.
23
+ #
24
+ # ```ruby
25
+ # module M
26
+ # extend T::Sig
27
+ # sig(:final) {void}
28
+ # def foo; end
29
+ # end
30
+ # class C
31
+ # include M
32
+ # def foo; end
33
+ # end
34
+ # ```
35
+ def self.enable_final_checks_on_hooks
36
+ T::Private::Methods.set_final_checks_on_hooks(true)
37
+ end
38
+
39
+ # Undo the effects of a previous call to
40
+ # `enable_final_checks_on_hooks`.
41
+ def self.reset_final_checks_on_hooks
42
+ T::Private::Methods.set_final_checks_on_hooks(false)
43
+ end
44
+
45
+ # Configure the default checked level for a sig with no explicit `.checked`
46
+ # builder. When unset, the default checked level is `:always`.
47
+ #
48
+ # Note: setting this option is potentially dangerous! Sorbet can't check all
49
+ # code statically. The runtime checks complement the checks that Sorbet does
50
+ # statically, so that methods don't have to guard themselves from being
51
+ # called incorrectly by untyped code.
52
+ #
53
+ # @param [:never, :tests, :always] default_checked_level
54
+ def self.default_checked_level=(default_checked_level)
55
+ T::Private::RuntimeLevels.default_checked_level = default_checked_level
56
+ end
57
+
5
58
  # Set a handler to handle `TypeError`s raised by any in-line type assertions,
6
59
  # including `T.must`, `T.let`, `T.cast`, and `T.assert_type!`.
7
60
  #
@@ -36,6 +89,7 @@ module T::Configuration
36
89
  else
37
90
  inline_type_error_handler_default(error)
38
91
  end
92
+ nil
39
93
  end
40
94
 
41
95
  # Set a handler to handle errors that occur when the builder methods in the
@@ -66,7 +120,7 @@ module T::Configuration
66
120
  end
67
121
 
68
122
  private_class_method def self.sig_builder_error_handler_default(error, location)
69
- T::Private::Methods.sig_error(location, error.message)
123
+ raise ArgumentError.new("#{location.path}:#{location.lineno}: Error interpreting `sig`:\n #{error.message}\n\n")
70
124
  end
71
125
 
72
126
  def self.sig_builder_error_handler(error, location)
@@ -75,6 +129,7 @@ module T::Configuration
75
129
  else
76
130
  sig_builder_error_handler_default(error, location)
77
131
  end
132
+ nil
78
133
  end
79
134
 
80
135
  # Set a handler to handle sig validation errors.
@@ -84,11 +139,10 @@ module T::Configuration
84
139
  # successfully built, but the built sig is incompatible with other sigs in
85
140
  # some way.
86
141
  #
87
- # By default, sig validation errors cause an exception to be raised. One
88
- # exception is for `generated` sigs, for which a message will be logged
89
- # instead of raising. Setting sig_validation_error_handler to an object that
90
- # implements :call (e.g. proc or lambda) allows users to customize the
91
- # behavior when a method signature's build fails.
142
+ # By default, sig validation errors cause an exception to be raised.
143
+ # Setting sig_validation_error_handler to an object that implements :call
144
+ # (e.g. proc or lambda) allows users to customize the behavior when a method
145
+ # signature's build fails.
92
146
  #
93
147
  # @param [Lambda, Proc, Object, nil] value Proc that handles the error (pass
94
148
  # nil to reset to default behavior)
@@ -116,42 +170,24 @@ module T::Configuration
116
170
  end
117
171
 
118
172
  private_class_method def self.sig_validation_error_handler_default(error, opts)
119
- # if this method overrides a generated signature, report that one instead
120
- bad_method = opts[:method]
121
- if !opts[:declaration].generated
122
- super_signature = opts[:super_signature]
123
- raise error if !super_signature&.generated
124
- bad_method = super_signature.method
125
- end
126
-
127
- method_file, method_line = bad_method.source_location
128
- T::Configuration.log_info_handler(
129
- "SIG-DECLARE-FAILED",
130
- {
131
- definition_file: method_file,
132
- definition_line: method_line,
133
- kind: "Delete",
134
- message: error.message,
135
- },
136
- )
173
+ raise error
137
174
  end
138
175
 
139
- def self.sig_validation_error_handler(error, opts)
176
+ def self.sig_validation_error_handler(error, opts={})
140
177
  if @sig_validation_error_handler
141
178
  @sig_validation_error_handler.call(error, opts)
142
179
  else
143
180
  sig_validation_error_handler_default(error, opts)
144
181
  end
182
+ nil
145
183
  end
146
184
 
147
185
  # Set a handler for type errors that result from calling a method.
148
186
  #
149
187
  # By default, errors from calling a method cause an exception to be raised.
150
- # One exception is for `generated` sigs, for which a message will be logged
151
- # instead of raising. Setting call_validation_error_handler to an object that
152
- # implements :call (e.g. proc or lambda) allows users to customize the
153
- # behavior when a method is called with invalid parameters, or returns an
154
- # invalid value.
188
+ # Setting call_validation_error_handler to an object that implements :call
189
+ # (e.g. proc or lambda) allows users to customize the behavior when a method
190
+ # is called with invalid parameters, or returns an invalid value.
155
191
  #
156
192
  # @param [Lambda, Proc, Object, nil] value Proc that handles the error
157
193
  # report (pass nil to reset to default behavior)
@@ -180,49 +216,16 @@ module T::Configuration
180
216
  end
181
217
 
182
218
  private_class_method def self.call_validation_error_handler_default(signature, opts)
183
- method_file, method_line = signature.method.source_location
184
- location = opts[:location]
185
- suffix = "Caller: #{location.path}:#{location.lineno}\n" \
186
- "Definition: #{method_file}:#{method_line}"
187
-
188
- error_message = "#{opts[:kind]}#{opts[:name] ? " '#{opts[:name]}'" : ''}: #{opts[:message]}\n#{suffix}"
189
-
190
- if signature.generated
191
- got = opts[:value].class
192
- got = T.unsafe(T::Enumerable[T.untyped]).describe_obj(opts[:value]) if got < Enumerable
193
- T::Configuration.log_info_handler(
194
- "SIG-CHECK-FAILED",
195
- {
196
- caller_file: location.path,
197
- caller_line: location.lineno,
198
- definition_file: method_file,
199
- definition_line: method_line,
200
- kind: opts[:kind],
201
- name: opts[:name],
202
- expected: opts[:type].name,
203
- got: got,
204
- },
205
- )
206
- elsif signature.soft_notify
207
- T::Configuration.soft_assert_handler(
208
- "TypeError: #{error_message}",
209
- {notify: signature.soft_notify}
210
- )
211
- else
212
- begin
213
- raise TypeError.new(error_message)
214
- rescue TypeError => e # raise into rescue to ensure e.backtrace is populated
215
- T::Private::ErrorHandler.handle_inline_type_error(e)
216
- end
217
- end
219
+ raise TypeError.new(opts[:pretty_message])
218
220
  end
219
221
 
220
- def self.call_validation_error_handler(signature, opts)
222
+ def self.call_validation_error_handler(signature, opts={})
221
223
  if @call_validation_error_handler
222
224
  @call_validation_error_handler.call(signature, opts)
223
225
  else
224
226
  call_validation_error_handler_default(signature, opts)
225
227
  end
228
+ nil
226
229
  end
227
230
 
228
231
  # Set a handler for logging
@@ -316,7 +319,7 @@ module T::Configuration
316
319
  raise str
317
320
  end
318
321
 
319
- def self.hard_assert_handler(str, extra)
322
+ def self.hard_assert_handler(str, extra={})
320
323
  if @hard_assert_handler
321
324
  @hard_assert_handler.call(str, extra)
322
325
  else
@@ -333,7 +336,7 @@ module T::Configuration
333
336
  # T::Configuration.scalar_types = ["NilClass", "TrueClass", "FalseClass", ...]
334
337
  def self.scalar_types=(values)
335
338
  if values.nil?
336
- @scalar_tyeps = values
339
+ @scalar_types = values
337
340
  else
338
341
  bad_values = values.select {|v| v.class != String}
339
342
  unless bad_values.empty?
@@ -353,12 +356,69 @@ module T::Configuration
353
356
  String
354
357
  Symbol
355
358
  Time
359
+ T::Enum
356
360
  }).freeze
357
361
 
358
362
  def self.scalar_types
359
363
  @scalar_types || @default_scalar_types
360
364
  end
361
365
 
366
+ # Temporarily disable ruby warnings while executing the given block. This is
367
+ # useful when doing something that would normally cause a warning to be
368
+ # emitted in Ruby verbose mode ($VERBOSE = true).
369
+ #
370
+ # @yield
371
+ #
372
+ def self.without_ruby_warnings
373
+ if $VERBOSE
374
+ begin
375
+ original_verbose = $VERBOSE
376
+ $VERBOSE = false
377
+ yield
378
+ ensure
379
+ $VERBOSE = original_verbose
380
+ end
381
+ else
382
+ yield
383
+ end
384
+ end
385
+
386
+ def self.enable_legacy_t_enum_migration_mode
387
+ @legacy_t_enum_migration_mode = true
388
+ end
389
+ def self.disable_legacy_t_enum_migration_mode
390
+ @legacy_t_enum_migration_mode = false
391
+ end
392
+ def self.legacy_t_enum_migration_mode?
393
+ @legacy_t_enum_migration_mode || false
394
+ end
395
+
396
+ # @param [Array] sealed_violation_whitelist An array of Regexp to validate
397
+ # whether inheriting /including a sealed module outside the defining module
398
+ # should be allowed. Useful to whitelist benign violations, like shim files
399
+ # generated for an autoloader.
400
+ def self.sealed_violation_whitelist=(sealed_violation_whitelist)
401
+ if @sealed_violation_whitelist != nil
402
+ raise ArgumentError.new("Cannot overwrite sealed_violation_whitelist after setting it")
403
+ end
404
+
405
+ case sealed_violation_whitelist
406
+ when Array
407
+ sealed_violation_whitelist.each do |x|
408
+ case x
409
+ when Regexp then nil
410
+ else raise TypeError.new("sealed_violation_whitelist accepts an Array of Regexp")
411
+ end
412
+ end
413
+ else
414
+ raise TypeError.new("sealed_violation_whitelist= accepts an Array of Regexp")
415
+ end
416
+
417
+ @sealed_violation_whitelist = sealed_violation_whitelist
418
+ end
419
+ def self.sealed_violation_whitelist
420
+ @sealed_violation_whitelist
421
+ end
362
422
 
363
423
  private_class_method def self.validate_lambda_given!(value)
364
424
  if !value.nil? && !value.respond_to?(:call)