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 +4 -4
- data/lib/types/compatibility_patches.rb +1 -0
- data/lib/types/private/abstract/declare.rb +0 -4
- data/lib/types/private/methods/signature_validation.rb +1 -1
- data/lib/types/props/constructor.rb +1 -1
- data/lib/types/props/decorator.rb +3 -3
- data/lib/types/props/optional.rb +13 -1
- data/lib/types/props/serializable.rb +49 -40
- data/lib/types/props/utils.rb +15 -1
- data/lib/types/sig.rb +0 -3
- data/lib/types/utils.rb +0 -16
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f4467e9a187ef1afa84f78db3ee5771e61b6727f
|
4
|
+
data.tar.gz: b1b92e841097fecfffd2137e8bc572960c762ff6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c840637529ae6864501dd9132d272b02fafb9d91366c487919ac9e307d467d6343af8d9816c6227140cf8cbe48c74cdb9a4582f29fece604258f7a37b72179fb
|
7
|
+
data.tar.gz: 4120461d62a00240114e6a146fc91dee43e108fac23d0f02db18dddd69cf103472429f043463253184aaf0ac4309ee46d947b6d8becd530bb907b142abad2794
|
@@ -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 "
|
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
|
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
|
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
|
375
|
-
# T::Utils
|
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
|
|
data/lib/types/props/optional.rb
CHANGED
@@ -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
|
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.
|
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
|
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
|
46
|
-
|
47
|
-
if rules[:
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
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
|
-
|
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
|
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
|
-
|
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
|
-
|
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
|
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
|
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
|
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
|
data/lib/types/props/utils.rb
CHANGED
@@ -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
|
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.
|