sorbet-runtime 0.4.4321 → 0.4.4322

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 55f2218bd8ea16d7c8390da6504451472425f6b0
4
- data.tar.gz: 150dde097f793876984025db081e6bbe5fca6e53
3
+ metadata.gz: f4467e9a187ef1afa84f78db3ee5771e61b6727f
4
+ data.tar.gz: b1b92e841097fecfffd2137e8bc572960c762ff6
5
5
  SHA512:
6
- metadata.gz: 859b2d4e8c767b2975188828bddf1fb8c1779f2dee1c5781742c8c012501266d2330a22d9ecb048e19f857b33294019b3faacc17b15d0df1575f6aea32a638d4
7
- data.tar.gz: 2821f3baf23d4bf62f2c5ea4b770f7bf385f802ba4d18fe95c69c07b10066f289c38499665f716ed59c227e0a57e3bab74e241e36f51808deb59aec4fa02dc70
6
+ metadata.gz: c840637529ae6864501dd9132d272b02fafb9d91366c487919ac9e307d467d6343af8d9816c6227140cf8cbe48c74cdb9a4582f29fece604258f7a37b72179fb
7
+ data.tar.gz: 4120461d62a00240114e6a146fc91dee43e108fac23d0f02db18dddd69cf103472429f043463253184aaf0ac4309ee46d947b6d8becd530bb907b142abad2794
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  # typed: ignore
2
3
 
3
4
  require_relative 'private/methods/_methods'
@@ -18,10 +18,6 @@ module T::Private::Abstract::Declare
18
18
  mod.extend(T::InterfaceWrapper::Helpers)
19
19
 
20
20
  if mod.is_a?(Class)
21
- if mod < T::Struct
22
- raise "#{mod.name} is a subclass of T::Struct and cannot be declared abstract"
23
- end
24
-
25
21
  if type == :interface
26
22
  # Since `interface!` is just `abstract!` with some extra validation, we could technically
27
23
  # allow this, but it's unclear there are good use cases, and it might be confusing.
@@ -11,7 +11,7 @@ module T::Private::Methods::SignatureValidation
11
11
  # but in practice, you never call them polymorphically. Conceptually, they're standard
12
12
  # methods (this is consistent with how they're treated in other languages, e.g. Java)
13
13
  if signature.mode != Modes.standard
14
- raise "Constructor methods should always be declared using `sig`."
14
+ raise "`initialize` should not use `.abstract` or `.implementation` or any other inheritance modifiers."
15
15
  end
16
16
  return
17
17
  end
@@ -10,7 +10,7 @@ module T::Props::Constructor
10
10
  decorator.props.each do |prop, rules|
11
11
  # It's important to explicitly compare against `true` here; the value can also be :existing or
12
12
  # :on_load (which are truthy) but we don't want to treat those as optional in this context.
13
- if T::Utils::Props.required_prop?(rules) && !decorator.has_default?(rules) && !hash.key?(prop)
13
+ if T::Props::Utils.required_prop?(rules) && !decorator.has_default?(rules) && !hash.key?(prop)
14
14
  raise ArgumentError.new("Missing required prop `#{prop}` for class `#{self.class}`")
15
15
  end
16
16
  end
@@ -149,7 +149,7 @@ class T::Props::Decorator
149
149
  # T::Props::CustomType is not a real object based class so that we can not run real type check call.
150
150
  # T::Props::CustomType.valid?() is only a helper function call.
151
151
  valid =
152
- if type.is_a?(T::Props::CustomType) && T::Utils::Props.optional_prop?(rules)
152
+ if type.is_a?(T::Props::CustomType) && T::Props::Utils.optional_prop?(rules)
153
153
  type.valid?(val)
154
154
  else
155
155
  type_object.valid?(val)
@@ -371,8 +371,8 @@ class T::Props::Decorator
371
371
  if T::Utils::Nilable.is_union_with_nilclass(cls)
372
372
  # :_tnilable is introduced internally for performance purpose so that clients do not need to call
373
373
  # T::Utils::Nilable.is_tnilable(cls) again.
374
- # It is strictly internal: clients should always use T::Utils::Props.required_prop?() or
375
- # T::Utils::Props.optional_prop?() for checking whether a field is required or optional.
374
+ # It is strictly internal: clients should always use T::Props::Utils.required_prop?() or
375
+ # T::Props::Utils.optional_prop?() for checking whether a field is required or optional.
376
376
  rules[:_tnilable] = true
377
377
  end
378
378
 
@@ -31,8 +31,20 @@ module T::Props::Optional::DecoratorMethods
31
31
 
32
32
  def prop_optional?(prop); prop_rules(prop)[:fully_optional]; end
33
33
 
34
- def add_prop_definition(prop, rules)
34
+ def mutate_prop_backdoor!(prop, key, value)
35
+ rules = props.fetch(prop)
36
+ rules = rules.merge(key => value)
37
+ compute_derived_rules(rules)
38
+ @props = props.merge(prop => rules.freeze).freeze
39
+ end
40
+
41
+ def compute_derived_rules(rules)
35
42
  rules[:fully_optional] = !T::Props::Utils.need_nil_write_check?(rules)
43
+ rules[:need_nil_read_check] = T::Props::Utils.need_nil_read_check?(rules)
44
+ end
45
+
46
+ def add_prop_definition(prop, rules)
47
+ compute_derived_rules(rules)
36
48
  super
37
49
  end
38
50
 
@@ -19,13 +19,12 @@ module T::Props::Serializable
19
19
  decorator = self.class.decorator
20
20
  h = {}
21
21
 
22
- decorator.props.keys.each do |prop|
23
- rules = decorator.prop_rules(prop)
22
+ decorator.props.each do |prop, rules|
24
23
  hkey = rules[:serialized_form]
25
24
 
26
- val = decorator.get(self, prop)
25
+ val = decorator.get(self, prop, rules)
27
26
 
28
- if strict && val.nil? && T::Props::Utils.need_nil_write_check?(rules)
27
+ if val.nil? && strict && !rules[:fully_optional]
29
28
  # If the prop was already missing during deserialization, that means the application
30
29
  # code already had to deal with a nil value, which means we wouldn't be accomplishing
31
30
  # much by raising here (other than causing an unnecessary breakage).
@@ -42,40 +41,42 @@ module T::Props::Serializable
42
41
  # Don't serialize values that are nil to save space (both the
43
42
  # nil value itself and the field name in the serialized BSON
44
43
  # document)
45
- next if decorator.prop_dont_store?(prop) || val.nil?
46
-
47
- if rules[:type_is_serializable]
48
- val = val.serialize(strict)
49
- elsif rules[:type_is_array_of_serializable]
50
- if (subtype = rules[:serializable_subtype]).is_a?(T::Props::CustomType)
51
- val = val.map {|el| el && subtype.serialize(el)}
52
- else
53
- val = val.map {|el| el && el.serialize(strict)}
54
- end
55
- elsif rules[:type_is_hash_of_serializable_values] && rules[:type_is_hash_of_custom_type_keys]
56
- key_subtype = rules[:serializable_subtype][:keys]
57
- value_subtype = rules[:serializable_subtype][:values]
58
- if value_subtype.is_a?(T::Props::CustomType)
59
- val = val.each_with_object({}) do |(key, value), result|
60
- result[key_subtype.serialize(key)] = value && value_subtype.serialize(value)
44
+ next if rules[:dont_store] || val.nil?
45
+
46
+ if rules[:serializable_subtype]
47
+ if rules[:type_is_serializable]
48
+ val = val.serialize(strict)
49
+ elsif rules[:type_is_array_of_serializable]
50
+ if (subtype = rules[:serializable_subtype]).is_a?(T::Props::CustomType)
51
+ val = val.map {|el| el && subtype.serialize(el)}
52
+ else
53
+ val = val.map {|el| el && el.serialize(strict)}
61
54
  end
62
- else
55
+ elsif rules[:type_is_hash_of_serializable_values] && rules[:type_is_hash_of_custom_type_keys]
56
+ key_subtype = rules[:serializable_subtype][:keys]
57
+ value_subtype = rules[:serializable_subtype][:values]
58
+ if value_subtype.is_a?(T::Props::CustomType)
59
+ val = val.each_with_object({}) do |(key, value), result|
60
+ result[key_subtype.serialize(key)] = value && value_subtype.serialize(value)
61
+ end
62
+ else
63
+ val = val.each_with_object({}) do |(key, value), result|
64
+ result[key_subtype.serialize(key)] = value && value.serialize(strict)
65
+ end
66
+ end
67
+ elsif rules[:type_is_hash_of_serializable_values]
68
+ value_subtype = rules[:serializable_subtype]
69
+ if value_subtype.is_a?(T::Props::CustomType)
70
+ val = val.transform_values {|v| v && value_subtype.serialize(v)}
71
+ else
72
+ val = val.transform_values {|v| v && v.serialize(strict)}
73
+ end
74
+ elsif rules[:type_is_hash_of_custom_type_keys]
75
+ key_subtype = rules[:serializable_subtype]
63
76
  val = val.each_with_object({}) do |(key, value), result|
64
- result[key_subtype.serialize(key)] = value && value.serialize(strict)
77
+ result[key_subtype.serialize(key)] = value
65
78
  end
66
79
  end
67
- elsif rules[:type_is_hash_of_serializable_values]
68
- value_subtype = rules[:serializable_subtype]
69
- if value_subtype.is_a?(T::Props::CustomType)
70
- val = val.transform_values {|v| v && value_subtype.serialize(v)}
71
- else
72
- val = val.transform_values {|v| v && v.serialize(strict)}
73
- end
74
- elsif rules[:type_is_hash_of_custom_type_keys]
75
- key_subtype = rules[:serializable_subtype]
76
- val = val.each_with_object({}) do |(key, value), result|
77
- result[key_subtype.serialize(key)] = value
78
- end
79
80
  elsif rules[:type_is_custom_type]
80
81
  val = rules[:type].serialize(val)
81
82
 
@@ -88,11 +89,19 @@ module T::Props::Serializable
88
89
  end
89
90
  end
90
91
 
91
- h[hkey] = T::Props::Utils.deep_clone_object(val)
92
+ needs_clone = rules[:type_needs_clone]
93
+ if needs_clone
94
+ if needs_clone == :shallow
95
+ val = val.dup
96
+ else
97
+ val = T::Props::Utils.deep_clone_object(val)
98
+ end
99
+ end
100
+
101
+ h[hkey] = val
92
102
  end
93
103
 
94
- extra_props = decorator.extra_props(self)
95
- h.merge!(extra_props) if extra_props
104
+ h.merge!(@_extra_props) if @_extra_props
96
105
 
97
106
  h
98
107
  end
@@ -116,7 +125,7 @@ module T::Props::Serializable
116
125
  hkey = rules[:serialized_form]
117
126
  val = hash[hkey]
118
127
  if val.nil?
119
- if T::Utils::Props.required_prop?(rules)
128
+ if T::Props::Utils.required_prop?(rules)
120
129
  val = decorator.get_default(rules, self.class)
121
130
  if val.nil?
122
131
  msg = "Tried to deserialize a required prop from a nil value. It's "\
@@ -140,7 +149,7 @@ module T::Props::Serializable
140
149
  T::Configuration.hard_assert_handler(msg, storytime: storytime)
141
150
  end
142
151
  end
143
- elsif T::Props::Utils.need_nil_read_check?(rules)
152
+ elsif rules[:need_nil_read_check]
144
153
  self.required_prop_missing_from_deserialize(p)
145
154
  end
146
155
 
@@ -274,7 +283,7 @@ module T::Props::Serializable::DecoratorMethods
274
283
  end
275
284
 
276
285
  def required_props
277
- @class.props.select {|_, v| T::Utils::Props.required_prop?(v)}.keys
286
+ @class.props.select {|_, v| T::Props::Utils.required_prop?(v)}.keys
278
287
  end
279
288
 
280
289
  def prop_dont_store?(prop); prop_rules(prop)[:dont_store]; end
@@ -44,6 +44,20 @@ module T::Props::Utils
44
44
 
45
45
  # The prop_rules indicate whether we should check for writing a nil value for the prop/field.
46
46
  def self.need_nil_write_check?(prop_rules)
47
- need_nil_read_check?(prop_rules) || T::Utils::Props.required_prop?(prop_rules)
47
+ need_nil_read_check?(prop_rules) || T::Props::Utils.required_prop?(prop_rules)
48
+ end
49
+
50
+ def self.required_prop?(prop_rules)
51
+ # Clients should never reference :_tnilable as the implementation can change.
52
+ !prop_rules[:_tnilable]
53
+ end
54
+
55
+ def self.optional_prop?(prop_rules)
56
+ # Clients should never reference :_tnilable as the implementation can change.
57
+ !!prop_rules[:_tnilable]
58
+ end
59
+
60
+ def self.merge_serialized_optional_rule(prop_rules)
61
+ {'_tnilable' => true}.merge(prop_rules.merge('_tnilable' => true))
48
62
  end
49
63
  end
data/lib/types/sig.rb CHANGED
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
  # typed: true
3
- # rubocop:disable PrisonGuard/NoTopLevelDeclarations, PrisonGuard/PackageMatchesDirectory
4
3
 
5
4
  # Used as a mixin to any class so that you can call `sig`.
6
5
  # Docs at https://sorbet.org/docs/sigs
@@ -24,5 +23,3 @@ module T::Sig
24
23
  T::Private::Methods.declare_sig(self, &blk)
25
24
  end
26
25
  end
27
-
28
- # rubocop:enable PrisonGuard/NoTopLevelDeclarations, PrisonGuard/PackageMatchesDirectory
data/lib/types/utils.rb CHANGED
@@ -154,22 +154,6 @@ module T::Utils
154
154
  "#{start_part}#{ellipsis}#{end_part}"
155
155
  end
156
156
 
157
- module Props
158
- def self.required_prop?(prop_rules)
159
- # Clients should never reference :_tnilable as the implementation can change.
160
- !prop_rules[:_tnilable]
161
- end
162
-
163
- def self.optional_prop?(prop_rules)
164
- # Clients should never reference :_tnilable as the implementation can change.
165
- !!prop_rules[:_tnilable]
166
- end
167
-
168
- def self.merge_serialized_optional_rule(prop_rules)
169
- {'_tnilable' => true}.merge(prop_rules.merge('_tnilable' => true))
170
- end
171
- end
172
-
173
157
  module Nilable
174
158
  # :is_union_type, T::Boolean: whether the type is an T::Types::Union type
175
159
  # :non_nilable_type, Class: if it is an T.nilable type, the corresponding underlying type; otherwise, nil.
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sorbet-runtime
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.4321
4
+ version: 0.4.4322
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stripe