sorbet-runtime 0.5.6295 → 0.5.6483

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.
@@ -2,7 +2,7 @@
2
2
  # typed: true
3
3
 
4
4
  module T::Private::Methods
5
- Declaration = Struct.new(:mod, :params, :returns, :bind, :mode, :checked, :finalized, :on_failure, :override_allow_incompatible, :type_parameters)
5
+ Declaration = Struct.new(:mod, :params, :returns, :bind, :mode, :checked, :finalized, :on_failure, :override_allow_incompatible, :type_parameters, :raw)
6
6
 
7
7
  class DeclBuilder
8
8
  attr_reader :decl
@@ -15,7 +15,7 @@ module T::Private::Methods
15
15
  end
16
16
  end
17
17
 
18
- def initialize(mod)
18
+ def initialize(mod, raw)
19
19
  # TODO RUBYPLAT-1278 - with ruby 2.5, use kwargs here
20
20
  @decl = Declaration.new(
21
21
  mod,
@@ -28,6 +28,7 @@ module T::Private::Methods
28
28
  ARG_NOT_PROVIDED, # on_failure
29
29
  nil, # override_allow_incompatible
30
30
  ARG_NOT_PROVIDED, # type_parameters
31
+ raw
31
32
  )
32
33
  end
33
34
 
@@ -5,7 +5,8 @@ class T::Private::Methods::Signature
5
5
  attr_reader :method, :method_name, :arg_types, :kwarg_types, :block_type, :block_name,
6
6
  :rest_type, :rest_name, :keyrest_type, :keyrest_name, :bind,
7
7
  :return_type, :mode, :req_arg_count, :req_kwarg_names, :has_rest, :has_keyrest,
8
- :check_level, :parameters, :on_failure, :override_allow_incompatible
8
+ :check_level, :parameters, :on_failure, :override_allow_incompatible,
9
+ :defined_raw
9
10
 
10
11
  def self.new_untyped(method:, mode: T::Private::Methods::Modes.untyped, parameters: method.parameters)
11
12
  # Using `Untyped` ensures we'll get an error if we ever try validation on these.
@@ -32,7 +33,7 @@ class T::Private::Methods::Signature
32
33
  )
33
34
  end
34
35
 
35
- def initialize(method:, method_name:, raw_arg_types:, raw_return_type:, bind:, mode:, check_level:, on_failure:, parameters: method.parameters, override_allow_incompatible: false)
36
+ def initialize(method:, method_name:, raw_arg_types:, raw_return_type:, bind:, mode:, check_level:, on_failure:, parameters: method.parameters, override_allow_incompatible: false, defined_raw: false)
36
37
  @method = method
37
38
  @method_name = method_name
38
39
  @arg_types = []
@@ -54,6 +55,7 @@ class T::Private::Methods::Signature
54
55
  @parameters = parameters
55
56
  @on_failure = on_failure
56
57
  @override_allow_incompatible = override_allow_incompatible
58
+ @defined_raw = defined_raw
57
59
 
58
60
  declared_param_names = raw_arg_types.keys
59
61
  # If sig params are declared but there is a single parameter with a missing name
@@ -181,7 +181,7 @@ module T::Private::Methods::SignatureValidation
181
181
  # arg types must be contravariant
182
182
  super_signature.arg_types.zip(signature.arg_types).each_with_index do |((_super_name, super_type), (name, type)), index|
183
183
  if !super_type.subtype_of?(type)
184
- raise "Incompatible type for arg ##{index + 1} (`#{name}`) in #{mode_noun} of method " \
184
+ raise "Incompatible type for arg ##{index + 1} (`#{name}`) in signature for #{mode_noun} of method " \
185
185
  "`#{signature.method_name}`:\n" \
186
186
  "* Base: `#{super_type}` (in #{method_loc_str(super_signature.method)})\n" \
187
187
  "* #{mode_noun.capitalize}: `#{type}` (in #{method_loc_str(signature.method)})\n" \
@@ -193,7 +193,7 @@ module T::Private::Methods::SignatureValidation
193
193
  super_signature.kwarg_types.each do |name, super_type|
194
194
  type = signature.kwarg_types[name]
195
195
  if !super_type.subtype_of?(type)
196
- raise "Incompatible type for arg `#{name}` in #{mode_noun} of method `#{signature.method_name}`:\n" \
196
+ raise "Incompatible type for arg `#{name}` in signature for #{mode_noun} of method `#{signature.method_name}`:\n" \
197
197
  "* Base: `#{super_type}` (in #{method_loc_str(super_signature.method)})\n" \
198
198
  "* #{mode_noun.capitalize}: `#{type}` (in #{method_loc_str(signature.method)})\n" \
199
199
  "(The types must be contravariant.)"
@@ -202,7 +202,7 @@ module T::Private::Methods::SignatureValidation
202
202
 
203
203
  # return types must be covariant
204
204
  if !signature.return_type.subtype_of?(super_signature.return_type)
205
- raise "Incompatible return type in #{mode_noun} of method `#{signature.method_name}`:\n" \
205
+ raise "Incompatible return type in signature for #{mode_noun} of method `#{signature.method_name}`:\n" \
206
206
  "* Base: `#{super_signature.return_type}` (in #{method_loc_str(super_signature.method)})\n" \
207
207
  "* #{mode_noun.capitalize}: `#{signature.return_type}` (in #{method_loc_str(signature.method)})\n" \
208
208
  "(The types must be covariant.)"
@@ -449,8 +449,11 @@ class T::Props::Decorator
449
449
 
450
450
  @class.send(:define_method, redacted_method) do
451
451
  value = self.public_send(prop_name)
452
- Chalk::Tools::RedactionUtils.redact_with_directive(
453
- value, redaction)
452
+ handler = T::Configuration.redaction_handler
453
+ if !handler
454
+ raise "Using `redaction:` on a prop requires specifying `T::Configuration.redaction_handler`"
455
+ end
456
+ handler.call(value, redaction)
454
457
  end
455
458
  end
456
459
 
@@ -162,7 +162,16 @@ module T::Props
162
162
  exceptions.children.each {|c| assert_equal(:const, c.type)}
163
163
  assert_equal(:lvasgn, assignment.type)
164
164
  assert_equal([:e], assignment.children)
165
- validate_lack_of_side_effects(handler, whitelisted_methods_for_deserialize)
165
+
166
+ deserialization_error, val_return = handler.children
167
+
168
+ assert_equal(:send, deserialization_error.type)
169
+ receiver, method, *args = deserialization_error.children
170
+ assert_equal(nil, receiver)
171
+ assert_equal(:raise_deserialization_error, method)
172
+ args.each {|a| validate_lack_of_side_effects(a, whitelisted_methods_for_deserialize)}
173
+
174
+ validate_lack_of_side_effects(val_return, whitelisted_methods_for_deserialize)
166
175
  else
167
176
  validate_lack_of_side_effects(else_body, whitelisted_methods_for_deserialize)
168
177
  end
@@ -261,7 +270,7 @@ module T::Props
261
270
  private_class_method def self.whitelisted_methods_for_deserialize
262
271
  @whitelisted_methods_for_deserialize ||= {
263
272
  lvar: %i{dup map transform_values transform_keys each_with_object nil? []= to_f},
264
- const: %i[deserialize from_hash deep_clone_object soft_assert_handler],
273
+ const: %i[deserialize from_hash deep_clone_object],
265
274
  }
266
275
  end
267
276
  end
@@ -48,6 +48,11 @@ module T::Props
48
48
  @lazily_defined_methods ||= {}
49
49
  end
50
50
 
51
+ sig {returns(T::Hash[Symbol, T.untyped]).checked(:never)}
52
+ private def lazily_defined_vm_methods
53
+ @lazily_defined_vm_methods ||= {}
54
+ end
55
+
51
56
  sig {params(name: Symbol).void}
52
57
  private def eval_lazily_defined_method!(name)
53
58
  if !HasLazilySpecializedMethods.lazy_evaluation_enabled?
@@ -61,6 +66,18 @@ module T::Props
61
66
  cls.send(:private, name)
62
67
  end
63
68
 
69
+ sig {params(name: Symbol).void}
70
+ private def eval_lazily_defined_vm_method!(name)
71
+ if !HasLazilySpecializedMethods.lazy_evaluation_enabled?
72
+ raise SourceEvaluationDisabled.new
73
+ end
74
+
75
+ lazily_defined_vm_methods.fetch(name).call
76
+
77
+ cls = decorated_class
78
+ cls.send(:private, name)
79
+ end
80
+
64
81
  sig {params(name: Symbol, blk: T.proc.returns(String)).void}
65
82
  private def enqueue_lazy_method_definition!(name, &blk)
66
83
  lazily_defined_methods[name] = blk
@@ -76,6 +93,21 @@ module T::Props
76
93
  cls.send(:private, name)
77
94
  end
78
95
 
96
+ sig {params(name: Symbol, blk: T.untyped).void}
97
+ private def enqueue_lazy_vm_method_definition!(name, &blk)
98
+ lazily_defined_vm_methods[name] = blk
99
+
100
+ cls = decorated_class
101
+ cls.send(:define_method, name) do |*args|
102
+ self.class.decorator.send(:eval_lazily_defined_vm_method!, name)
103
+ send(name, *args)
104
+ end
105
+ if cls.respond_to?(:ruby2_keywords, true)
106
+ cls.send(:ruby2_keywords, name)
107
+ end
108
+ cls.send(:private, name)
109
+ end
110
+
79
111
  sig {void}
80
112
  def eagerly_define_lazy_methods!
81
113
  return if lazily_defined_methods.empty?
@@ -87,6 +119,17 @@ module T::Props
87
119
  lazily_defined_methods.each_key {|name| cls.send(:private, name)}
88
120
  lazily_defined_methods.clear
89
121
  end
122
+
123
+ sig {void}
124
+ def eagerly_define_lazy_vm_methods!
125
+ return if lazily_defined_vm_methods.empty?
126
+
127
+ lazily_defined_vm_methods.values.map(&:call)
128
+
129
+ cls = decorated_class
130
+ lazily_defined_vm_methods.each_key {|name| cls.send(:private, name)}
131
+ lazily_defined_vm_methods.clear
132
+ end
90
133
  end
91
134
  end
92
135
  end
@@ -57,15 +57,10 @@ module T::Props
57
57
  begin
58
58
  #{transformation}
59
59
  rescue NoMethodError => e
60
- T::Configuration.soft_assert_handler(
61
- 'Deserialization error (probably unexpected stored type)',
62
- storytime: {
63
- klass: self.class,
64
- prop: #{prop.inspect},
65
- value: val,
66
- error: e.message,
67
- notify: 'djudd'
68
- }
60
+ raise_deserialization_error(
61
+ #{prop.inspect},
62
+ val,
63
+ e,
69
64
  )
70
65
  val
71
66
  end
@@ -156,6 +156,19 @@ module T::Props::Serializable
156
156
  @_required_props_missing_from_deserialize << prop
157
157
  nil
158
158
  end
159
+
160
+ private def raise_deserialization_error(prop_name, value, orig_error)
161
+ T::Configuration.soft_assert_handler(
162
+ 'Deserialization error (probably unexpected stored type)',
163
+ storytime: {
164
+ klass: self.class,
165
+ prop: prop_name,
166
+ value: value,
167
+ error: orig_error.message,
168
+ notify: 'djudd'
169
+ }
170
+ )
171
+ end
159
172
  end
160
173
 
161
174
 
@@ -201,8 +214,13 @@ module T::Props::Serializable::DecoratorMethods
201
214
  rules[:serialized_form] = rules.fetch(:name, prop.to_s)
202
215
  res = super
203
216
  prop_by_serialized_forms[rules[:serialized_form]] = prop
204
- enqueue_lazy_method_definition!(:__t_props_generated_serialize) {generate_serialize_source}
205
- enqueue_lazy_method_definition!(:__t_props_generated_deserialize) {generate_deserialize_source}
217
+ if T::Configuration.use_vm_prop_serde?
218
+ enqueue_lazy_vm_method_definition!(:__t_props_generated_serialize) {generate_serialize2}
219
+ enqueue_lazy_vm_method_definition!(:__t_props_generated_deserialize) {generate_deserialize2}
220
+ else
221
+ enqueue_lazy_method_definition!(:__t_props_generated_serialize) {generate_serialize_source}
222
+ enqueue_lazy_method_definition!(:__t_props_generated_deserialize) {generate_deserialize_source}
223
+ end
206
224
  res
207
225
  end
208
226
 
@@ -217,6 +235,18 @@ module T::Props::Serializable::DecoratorMethods
217
235
  )
218
236
  end
219
237
 
238
+ private def generate_serialize2
239
+ T::Props::Private::SerializerGenerator.generate2(decorated_class, props)
240
+ end
241
+
242
+ private def generate_deserialize2
243
+ T::Props::Private::DeserializerGenerator.generate2(
244
+ decorated_class,
245
+ props,
246
+ props_with_defaults || {},
247
+ )
248
+ end
249
+
220
250
  def message_with_generated_source_context(error, generated_method, generate_source_method)
221
251
  line_label = error.backtrace.find {|l| l.end_with?("in `#{generated_method}'")}
222
252
  return unless line_label
data/lib/types/sig.rb CHANGED
@@ -25,6 +25,6 @@ module T::Sig
25
25
  # {T::Helpers}
26
26
  T::Sig::WithoutRuntime.sig {params(arg0: T.nilable(Symbol), blk: T.proc.bind(T::Private::Methods::DeclBuilder).void).void}
27
27
  def sig(arg0=nil, &blk)
28
- T::Private::Methods.declare_sig(self, arg0, &blk)
28
+ T::Private::Methods.declare_sig(self, Kernel.caller_locations(1, 1)&.first, arg0, &blk)
29
29
  end
30
30
  end
@@ -2,7 +2,7 @@
2
2
  # typed: true
3
3
 
4
4
  module T::Types
5
- # Takes a hash of types. Validates each item in an hash using the type in the same position
5
+ # Takes a hash of types. Validates each item in a hash using the type in the same position
6
6
  # in the list.
7
7
  class FixedHash < Base
8
8
  attr_reader :types
@@ -13,7 +13,15 @@ module T::Types
13
13
 
14
14
  # @override Base
15
15
  def name
16
- "{#{@types.map {|(k, v)| "#{k}: #{v}"}.join(', ')}}"
16
+ entries = @types.map do |(k, v)|
17
+ if Symbol === k && ":#{k}" == k.inspect
18
+ "#{k}: #{v}"
19
+ else
20
+ "#{k.inspect} => #{v}"
21
+ end
22
+ end
23
+
24
+ "{#{entries.join(', ')}}"
17
25
  end
18
26
 
19
27
  # @override Base
@@ -41,11 +41,26 @@ module T::Types
41
41
  module Private
42
42
  module Pool
43
43
  def self.type_for_module(mod)
44
- cached = mod.instance_variable_get(:@__as_sorbet_simple_type)
44
+ cached = mod.instance_variable_get(:@__as_sorbet_type)
45
45
  return cached if cached
46
46
 
47
- type = Simple.new(mod)
48
- mod.instance_variable_set(:@__as_sorbet_simple_type, type) unless mod.frozen?
47
+ type = if mod == ::Array
48
+ T::Array[T.untyped]
49
+ elsif mod == ::Set
50
+ T::Set[T.untyped]
51
+ elsif mod == ::Hash
52
+ T::Hash[T.untyped, T.untyped]
53
+ elsif mod == ::Enumerable
54
+ T::Enumerable[T.untyped]
55
+ elsif mod == ::Enumerator
56
+ T::Enumerator[T.untyped]
57
+ elsif mod == ::Range
58
+ T::Range[T.untyped]
59
+ else
60
+ Simple.new(mod)
61
+ end
62
+
63
+ mod.instance_variable_set(:@__as_sorbet_type, type) unless mod.frozen?
49
64
  type
50
65
  end
51
66
  end
@@ -150,7 +150,11 @@ module T::Types
150
150
  obj.class
151
151
  else
152
152
  # This is a specialized enumerable type, just return the class.
153
- Object.instance_method(:class).bind(obj).call
153
+ if T::Configuration::AT_LEAST_RUBY_2_7
154
+ Object.instance_method(:class).bind_call(obj)
155
+ else
156
+ Object.instance_method(:class).bind(obj).call
157
+ end
154
158
  end
155
159
  end
156
160
 
@@ -8,12 +8,12 @@ module T::Types
8
8
 
9
9
  def initialize(types)
10
10
  @types = types.flat_map do |type|
11
- type = T::Utils.resolve_alias(type)
11
+ type = T::Utils.coerce(type)
12
12
  if type.is_a?(Union)
13
13
  # Simplify nested unions (mostly so `name` returns a nicer value)
14
14
  type.types
15
15
  else
16
- T::Utils.coerce(type)
16
+ type
17
17
  end
18
18
  end.uniq
19
19
  end
data/lib/types/utils.rb CHANGED
@@ -8,18 +8,6 @@ module T::Utils
8
8
  val.aliased_type
9
9
  elsif val.is_a?(T::Types::Base)
10
10
  val
11
- elsif val == ::Array
12
- T::Array[T.untyped]
13
- elsif val == ::Set
14
- T::Set[T.untyped]
15
- elsif val == ::Hash
16
- T::Hash[T.untyped, T.untyped]
17
- elsif val == ::Enumerable
18
- T::Enumerable[T.untyped]
19
- elsif val == ::Enumerator
20
- T::Enumerator[T.untyped]
21
- elsif val == ::Range
22
- T::Range[T.untyped]
23
11
  elsif val.is_a?(Module)
24
12
  T::Types::Simple::Private::Pool.type_for_module(val)
25
13
  elsif val.is_a?(::Array)
@@ -52,6 +40,13 @@ module T::Utils
52
40
  end.uniq
53
41
  end
54
42
 
43
+ # Returns the signature for the `UnboundMethod`, or nil if it's not sig'd
44
+ #
45
+ # @example T::Utils.signature_for_method(x.method(:foo))
46
+ def self.signature_for_method(method)
47
+ T::Private::Methods.signature_for_method(method)
48
+ end
49
+
55
50
  # Returns the signature for the instance method on the supplied module, or nil if it's not found or not typed.
56
51
  #
57
52
  # @example T::Utils.signature_for_instance_method(MyClass, :my_method)
@@ -84,10 +79,12 @@ module T::Utils
84
79
  case type
85
80
  when T::Types::Union
86
81
  non_nil_types = type.types.reject {|t| t == Nilable::NIL_TYPE}
87
- if non_nil_types.length == 1
88
- non_nil_types.first
82
+ return nil if type.types.length == non_nil_types.length
83
+ case non_nil_types.length
84
+ when 0 then nil
85
+ when 1 then non_nil_types.first
89
86
  else
90
- nil
87
+ T::Types::Union::Private::Pool.union_of_types(non_nil_types[0], non_nil_types[1], non_nil_types[2..-1])
91
88
  end
92
89
  else
93
90
  nil
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.6295
4
+ version: 0.5.6483
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stripe
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-02-23 00:00:00.000000000 Z
11
+ date: 2021-07-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: minitest
@@ -177,6 +177,8 @@ files:
177
177
  - lib/types/private/final.rb
178
178
  - lib/types/private/methods/_methods.rb
179
179
  - lib/types/private/methods/call_validation.rb
180
+ - lib/types/private/methods/call_validation_2_6.rb
181
+ - lib/types/private/methods/call_validation_2_7.rb
180
182
  - lib/types/private/methods/decl_builder.rb
181
183
  - lib/types/private/methods/modes.rb
182
184
  - lib/types/private/methods/signature.rb
@@ -189,7 +191,6 @@ files:
189
191
  - lib/types/private/types/string_holder.rb
190
192
  - lib/types/private/types/type_alias.rb
191
193
  - lib/types/private/types/void.rb
192
- - lib/types/profile.rb
193
194
  - lib/types/props/_props.rb
194
195
  - lib/types/props/constructor.rb
195
196
  - lib/types/props/custom_type.rb
@@ -257,7 +258,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
257
258
  - !ruby/object:Gem::Version
258
259
  version: '0'
259
260
  requirements: []
260
- rubygems_version: 3.0.3
261
+ rubygems_version: 3.1.4
261
262
  signing_key:
262
263
  specification_version: 4
263
264
  summary: Sorbet runtime