Class: Solargraph::ComplexType::UniqueType
- Inherits:
-
Object
- Object
- Solargraph::ComplexType::UniqueType
show all
- Includes:
- TypeMethods
- Defined in:
- lib/solargraph/complex_type/unique_type.rb
Overview
An individual type signature. A complex type can consist of multiple unique types.
Constant Summary
collapse
- UNDEFINED =
UniqueType.new('undefined', rooted: false)
- BOOLEAN =
UniqueType.new('Boolean', rooted: true)
Constants included
from TypeMethods
TypeMethods::PARAMETERS_TYPE_BY_STARTING_TAG
Instance Attribute Summary collapse
Attributes included from TypeMethods
#name, #parameters_type
Class Method Summary
collapse
Instance Method Summary
collapse
-
#force_rooted ⇒ self
-
#generic? ⇒ Boolean
-
#initialize(name, key_types = [], subtypes = [], rooted:, parameters_type: nil) ⇒ UniqueType
constructor
A new instance of UniqueType.
-
#items ⇒ Array<UniqueType>
-
#map {|t| ... } ⇒ Array<self>
-
#parameters? ⇒ Boolean
-
#parameters_as_rbs ⇒ String
-
#rbs_name ⇒ String
-
#rbs_union(types) ⇒ String
-
#recreate(new_name: nil, make_rooted: nil, new_key_types: nil, new_subtypes: nil) ⇒ self
-
#resolve_generics(definitions, context_type) ⇒ UniqueType, ComplexType
Probe the concrete type for each of the generic type parameters used in this type, and return a new type if possible.
-
#resolve_generics_from_context(generics_to_resolve, context_type, resolved_generic_values: {}) ⇒ UniqueType, ComplexType
-
#resolve_param_generics_from_context(generics_to_resolve, context_type, resolved_generic_values) ⇒ Array<ComplexType>
-
#rooted_tags ⇒ String
-
#self_to(dst) ⇒ UniqueType
Transform references to the ‘self’ type to the specified concrete namespace.
-
#selfy? ⇒ Boolean
-
#tags ⇒ String
-
#to_a ⇒ Array<UniqueType>
-
#to_rbs ⇒ String
-
#to_s ⇒ Object
-
#transform(new_name = nil) {|t| ... } ⇒ self
Apply the given transformation to each subtype and then finally to this type.
#==, #defined?, #duck_type?, #each_unique_type, #erase_generics, #fixed_parameters?, #generate_substring_from, #hash_parameters?, #list_parameters?, #namespace, #nil_type?, #qualify, #rooted?, #rooted_name, #rooted_namespace, #rooted_substring, #rooted_tag, #scope, #substring, #tag, #tuple?, #undefined?, #value_types, #void?
Constructor Details
#initialize(name, key_types = [], subtypes = [], rooted:, parameters_type: nil) ⇒ UniqueType
Returns a new instance of UniqueType.
62
63
64
65
66
67
68
69
70
71
72
73
74
75
|
# File 'lib/solargraph/complex_type/unique_type.rb', line 62
def initialize(name, key_types = [], subtypes = [], rooted:, parameters_type: nil)
if parameters_type.nil?
raise "You must supply parameters_type if you provide parameters" unless key_types.empty? && subtypes.empty?
end
raise "Please remove leading :: and set rooted instead - #{name}" if name.start_with?('::')
@name = name
@key_types = key_types
@subtypes = subtypes
@rooted = rooted
@all_params = []
@all_params.concat key_types
@all_params.concat subtypes
@parameters_type = parameters_type
end
|
Instance Attribute Details
#all_params ⇒ Object
Returns the value of attribute all_params.
11
12
13
|
# File 'lib/solargraph/complex_type/unique_type.rb', line 11
def all_params
@all_params
end
|
#key_types ⇒ Object
Returns the value of attribute key_types.
11
12
13
|
# File 'lib/solargraph/complex_type/unique_type.rb', line 11
def key_types
@key_types
end
|
#subtypes ⇒ Object
Returns the value of attribute subtypes.
11
12
13
|
# File 'lib/solargraph/complex_type/unique_type.rb', line 11
def subtypes
@subtypes
end
|
Class Method Details
.parse(name, substring = '', make_rooted: nil) ⇒ UniqueType
Create a UniqueType with the specified name and an optional substring. The substring is the parameter section of a parametrized type, e.g., for the type ‘Array<String>`, the name is `Array` and the substring is `<String>`.
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
# File 'lib/solargraph/complex_type/unique_type.rb', line 22
def self.parse name, substring = '', make_rooted: nil
if name.start_with?(':::')
raise "Illegal prefix: #{name}"
end
if name.start_with?('::')
name = name[2..-1]
rooted = true
else
rooted = false
end
rooted = make_rooted unless make_rooted.nil?
key_types = []
subtypes = []
parameters_type = nil
unless substring.empty?
subs = ComplexType.parse(substring[1..-2], partial: true)
parameters_type = PARAMETERS_TYPE_BY_STARTING_TAG.fetch(substring[0])
if parameters_type == :hash
raise ComplexTypeError, "Bad hash type" unless !subs.is_a?(ComplexType) and subs.length == 2 and !subs[0].is_a?(UniqueType) and !subs[1].is_a?(UniqueType)
key_types.concat(subs[0].map { |u| ComplexType.new([u]) })
subtypes.concat(subs[1].map { |u| ComplexType.new([u]) })
else
subtypes.concat subs
end
end
new(name, key_types, subtypes, rooted: rooted, parameters_type: parameters_type)
end
|
Instance Method Details
#force_rooted ⇒ self
259
260
261
262
263
|
# File 'lib/solargraph/complex_type/unique_type.rb', line 259
def force_rooted
transform do |t|
t.recreate(make_rooted: true)
end
end
|
#generic? ⇒ Boolean
148
149
150
|
# File 'lib/solargraph/complex_type/unique_type.rb', line 148
def generic?
name == GENERIC_TAG_NAME || all_params.any?(&:generic?)
end
|
82
83
84
|
# File 'lib/solargraph/complex_type/unique_type.rb', line 82
def items
[self]
end
|
#map {|t| ... } ⇒ Array<self>
224
225
226
|
# File 'lib/solargraph/complex_type/unique_type.rb', line 224
def map &block
[block.yield(self)]
end
|
#parameters? ⇒ Boolean
122
123
124
|
# File 'lib/solargraph/complex_type/unique_type.rb', line 122
def parameters?
!all_params.empty?
end
|
#parameters_as_rbs ⇒ String
137
138
139
140
141
142
143
144
145
146
|
# File 'lib/solargraph/complex_type/unique_type.rb', line 137
def parameters_as_rbs
return '' unless parameters?
return "[#{all_params.map(&:to_rbs).join(', ')}]" if key_types.empty?
key_types_str = rbs_union(key_types)
subtypes_str = rbs_union(subtypes)
"[#{key_types_str}, #{subtypes_str}]"
end
|
#rbs_name ⇒ String
87
88
89
90
91
92
93
|
# File 'lib/solargraph/complex_type/unique_type.rb', line 87
def rbs_name
if name == 'undefined'
'untyped'
else
rooted_name
end
end
|
#rbs_union(types) ⇒ String
128
129
130
131
132
133
134
|
# File 'lib/solargraph/complex_type/unique_type.rb', line 128
def rbs_union(types)
if types.length == 1
types.first.to_rbs
else
"(#{types.map(&:to_rbs).join(' | ')})"
end
end
|
#recreate(new_name: nil, make_rooted: nil, new_key_types: nil, new_subtypes: nil) ⇒ self
239
240
241
242
243
244
245
246
|
# File 'lib/solargraph/complex_type/unique_type.rb', line 239
def recreate(new_name: nil, make_rooted: nil, new_key_types: nil, new_subtypes: nil)
raise "Please remove leading :: and set rooted instead - #{new_name}" if new_name&.start_with?('::')
new_name ||= name
new_key_types ||= @key_types
new_subtypes ||= @subtypes
make_rooted = @rooted if make_rooted.nil?
UniqueType.new(new_name, new_key_types, new_subtypes, rooted: make_rooted, parameters_type: parameters_type)
end
|
#resolve_generics(definitions, context_type) ⇒ UniqueType, ComplexType
Probe the concrete type for each of the generic type parameters used in this type, and return a new type if possible.
207
208
209
210
211
212
213
214
215
216
217
218
219
|
# File 'lib/solargraph/complex_type/unique_type.rb', line 207
def resolve_generics definitions, context_type
return self if definitions.nil? || definitions.generics.empty?
transform(name) do |t|
if t.name == GENERIC_TAG_NAME
idx = definitions.generics.index(t.subtypes.first&.name)
next t if idx.nil?
context_type.all_params[idx] || ComplexType::UNDEFINED
else
t
end
end
end
|
#resolve_generics_from_context(generics_to_resolve, context_type, resolved_generic_values: {}) ⇒ UniqueType, ComplexType
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
|
# File 'lib/solargraph/complex_type/unique_type.rb', line 156
def resolve_generics_from_context generics_to_resolve, context_type, resolved_generic_values: {}
if name == ComplexType::GENERIC_TAG_NAME
type_param = subtypes.first&.name
return self unless generics_to_resolve.include? type_param
unless context_type.nil? || !resolved_generic_values[type_param].nil?
new_binding = true
resolved_generic_values[type_param] = context_type
end
if new_binding
resolved_generic_values.transform_values! do |complex_type|
complex_type.resolve_generics_from_context(generics_to_resolve, nil, resolved_generic_values: resolved_generic_values)
end
end
return resolved_generic_values[type_param] || self
end
new_key_types = resolve_param_generics_from_context(generics_to_resolve, context_type, resolved_generic_values, &:key_types)
new_subtypes = resolve_param_generics_from_context(generics_to_resolve, context_type, resolved_generic_values, &:subtypes)
recreate(new_key_types: new_key_types, new_subtypes: new_subtypes)
end
|
#resolve_param_generics_from_context(generics_to_resolve, context_type, resolved_generic_values) ⇒ Array<ComplexType>
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
|
# File 'lib/solargraph/complex_type/unique_type.rb', line 183
def resolve_param_generics_from_context(generics_to_resolve, context_type, resolved_generic_values)
types = yield self
types.each_with_index.flat_map do |ct, i|
ct.items.flat_map do |ut|
context_params = yield context_type if context_type
if context_params && context_params[i]
type_arg = context_params[i]
type_arg.map do |new_unique_context_type|
ut.resolve_generics_from_context generics_to_resolve, new_unique_context_type, resolved_generic_values: resolved_generic_values
end
else
ut.resolve_generics_from_context generics_to_resolve, nil, resolved_generic_values: resolved_generic_values
end
end
end
end
|
249
250
251
|
# File 'lib/solargraph/complex_type/unique_type.rb', line 249
def rooted_tags
rooted_tag
end
|
Transform references to the ‘self’ type to the specified concrete namespace
288
289
290
291
292
293
|
# File 'lib/solargraph/complex_type/unique_type.rb', line 288
def self_to dst
transform do |t|
next t if t.name != 'self'
t.recreate(new_name: dst, new_key_types: [], new_subtypes: [])
end
end
|
#selfy? ⇒ Boolean
295
296
297
|
# File 'lib/solargraph/complex_type/unique_type.rb', line 295
def selfy?
@name == 'self' || @key_types.any?(&:selfy?) || @subtypes.any?(&:selfy?)
end
|
254
255
256
|
# File 'lib/solargraph/complex_type/unique_type.rb', line 254
def tags
tag
end
|
229
230
231
|
# File 'lib/solargraph/complex_type/unique_type.rb', line 229
def to_a
[self]
end
|
#to_rbs ⇒ String
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
|
# File 'lib/solargraph/complex_type/unique_type.rb', line 96
def to_rbs
if duck_type?
'untyped'
elsif name == 'Boolean'
'bool'
elsif name.downcase == 'nil'
'nil'
elsif name == GENERIC_TAG_NAME
all_params.first.name
elsif ['Class', 'Module'].include?(name)
rbs_name
elsif ['Tuple', 'Array'].include?(name) && fixed_parameters?
if substring == '()'
'Array[]'
else
parameters_as_rbs
end
else
"#{rbs_name}#{parameters_as_rbs}"
end
end
|
#to_s ⇒ Object
77
78
79
|
# File 'lib/solargraph/complex_type/unique_type.rb', line 77
def to_s
tag
end
|
Apply the given transformation to each subtype and then finally to this type
271
272
273
274
275
276
277
278
279
280
281
282
283
|
# File 'lib/solargraph/complex_type/unique_type.rb', line 271
def transform(new_name = nil, &transform_type)
raise "Please remove leading :: and set rooted with recreate() instead - #{new_name}" if new_name&.start_with?('::')
if name == ComplexType::GENERIC_TAG_NAME
new_key_types = @key_types
new_subtypes = @subtypes
else
new_key_types = @key_types.flat_map { |ct| ct.items.map { |ut| ut.transform(&transform_type) } }
new_subtypes = @subtypes.flat_map { |ct| ct.items.map { |ut| ut.transform(&transform_type) } }
end
new_type = recreate(new_name: new_name || name, new_key_types: new_key_types, new_subtypes: new_subtypes)
yield new_type
end
|