Class: Solargraph::ComplexType
- Inherits:
-
Object
- Object
- Solargraph::ComplexType
show all
- Includes:
- Equality
- Defined in:
- lib/solargraph/complex_type.rb,
lib/solargraph/complex_type/unique_type.rb,
lib/solargraph/complex_type/type_methods.rb
Overview
A container for type data based on YARD type tags.
Defined Under Namespace
Modules: TypeMethods
Classes: UniqueType
Constant Summary
collapse
- GENERIC_TAG_NAME =
'generic'.freeze
Instance Attribute Summary collapse
Class Method Summary
collapse
Instance Method Summary
collapse
Methods included from Equality
#==, #eql?, #freeze, #hash
Constructor Details
#initialize(types = [UniqueType::UNDEFINED]) ⇒ ComplexType
Returns a new instance of ComplexType.
16
17
18
19
20
|
# File 'lib/solargraph/complex_type.rb', line 16
def initialize types = [UniqueType::UNDEFINED]
@items = types.flat_map(&:items).uniq(&:to_s)
end
|
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(name, *args, &block) ⇒ Object?
134
135
136
137
138
|
# File 'lib/solargraph/complex_type.rb', line 134
def method_missing name, *args, &block
return if @items.first.nil?
return @items.first.send(name, *args, &block) if respond_to_missing?(name)
super
end
|
Instance Attribute Details
#items ⇒ Object
Returns the value of attribute items.
233
234
235
|
# File 'lib/solargraph/complex_type.rb', line 233
def items
@items
end
|
Class Method Details
.parse(*strings, partial: false) ⇒ ComplexType
TODO:
To be able to select the right signature above, Chain::Call needs to know the decl type (:arg, :optarg, :kwarg, etc) of the arguments given, instead of just having an array of Chains as the arguments.
Note:
The ‘partial` parameter is used to indicate that the method is receiving a string that will be used inside another ComplexType. It returns arrays of ComplexTypes instead of a single cohesive one. Consumers should not need to use this parameter; it should only be used internally.
Parse type strings into a ComplexType.
# @overload parse(*strings, partial: false) # @todo Need ability to use a literal true as a type below # @param partial [Boolean] True if the string is part of a another type # @return [Array<UniqueType>] @sg-ignore
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
|
# File 'lib/solargraph/complex_type.rb', line 278
def parse *strings, partial: false
@cache ||= {}
unless partial
cached = @cache[strings]
return cached unless cached.nil?
end
types = []
key_types = nil
strings.each do |type_string|
point_stack = 0
curly_stack = 0
paren_stack = 0
base = String.new
subtype_string = String.new
type_string&.each_char do |char|
if char == '='
elsif char == '<'
point_stack += 1
elsif char == '>'
if subtype_string.end_with?('=') && curly_stack > 0
subtype_string += char
elsif base.end_with?('=')
raise ComplexTypeError, "Invalid hash thing" unless key_types.nil?
types.push UniqueType.parse(base[0..-2].strip, subtype_string)
key_types = types
types = []
base.clear
subtype_string.clear
next
else
raise ComplexTypeError, "Invalid close in type #{type_string}" if point_stack == 0
point_stack -= 1
subtype_string += char
end
next
elsif char == '{'
curly_stack += 1
elsif char == '}'
curly_stack -= 1
subtype_string += char
raise ComplexTypeError, "Invalid close in type #{type_string}" if curly_stack < 0
next
elsif char == '('
paren_stack += 1
elsif char == ')'
paren_stack -= 1
subtype_string += char
raise ComplexTypeError, "Invalid close in type #{type_string}" if paren_stack < 0
next
elsif char == ',' && point_stack == 0 && curly_stack == 0 && paren_stack == 0
types.push UniqueType.parse(base.strip, subtype_string.strip)
base.clear
subtype_string.clear
next
end
if point_stack == 0 && curly_stack == 0 && paren_stack == 0
base.concat char
else
subtype_string.concat char
end
end
raise ComplexTypeError, "Unclosed subtype in #{type_string}" if point_stack != 0 || curly_stack != 0 || paren_stack != 0
types.push UniqueType.parse(base.strip, subtype_string.strip)
end
unless key_types.nil?
raise ComplexTypeError, "Invalid use of key/value parameters" unless partial
return key_types if types.empty?
return [key_types, types]
end
result = partial ? types : ComplexType.new(types)
@cache[strings] = result unless partial
result
end
|
.try_parse(*strings) ⇒ ComplexType
362
363
364
365
366
367
|
# File 'lib/solargraph/complex_type.rb', line 362
def try_parse *strings
parse *strings
rescue ComplexTypeError => e
Solargraph.logger.info "Error parsing complex type `#{strings.join(', ')}`: #{e.message}"
ComplexType::UNDEFINED
end
|
Instance Method Details
112
113
114
|
# File 'lib/solargraph/complex_type.rb', line 112
def [](index)
@items[index]
end
|
#all? {|| ... } ⇒ Boolean
159
160
161
|
# File 'lib/solargraph/complex_type.rb', line 159
def all? &block
@items.all? &block
end
|
207
208
209
|
# File 'lib/solargraph/complex_type.rb', line 207
def all_params
@items.first.all_params || []
end
|
#all_rooted? ⇒ Boolean
every type and subtype in this union have been resolved to be fully qualified
223
224
225
|
# File 'lib/solargraph/complex_type.rb', line 223
def all_rooted?
all?(&:all_rooted?)
end
|
#any? {|| ... } ⇒ Boolean
166
167
168
|
# File 'lib/solargraph/complex_type.rb', line 166
def any? &block
@items.compact.any? &block
end
|
#desc ⇒ Object
150
151
152
|
# File 'lib/solargraph/complex_type.rb', line 150
def desc
rooted_tags
end
|
#each {|| ... } ⇒ Enumerable<UniqueType>
80
81
82
|
# File 'lib/solargraph/complex_type.rb', line 80
def each &block
@items.each &block
end
|
#each_unique_type ⇒ Enumerator<UniqueType>
This method returns an undefined value.
88
89
90
91
92
93
94
|
# File 'lib/solargraph/complex_type.rb', line 88
def each_unique_type &block
return enum_for(__method__) unless block_given?
@items.each do |item|
item.each_unique_type &block
end
end
|
51
52
53
|
# File 'lib/solargraph/complex_type.rb', line 51
def first
@items.first
end
|
#force_rooted ⇒ self
188
189
190
191
192
|
# File 'lib/solargraph/complex_type.rb', line 188
def force_rooted
transform do |t|
t.recreate(make_rooted: true)
end
end
|
#generic? ⇒ Boolean
174
175
176
|
# File 'lib/solargraph/complex_type.rb', line 174
def generic?
any?(&:generic?)
end
|
#length ⇒ Integer
97
98
99
|
# File 'lib/solargraph/complex_type.rb', line 97
def length
@items.length
end
|
#map {|| ... } ⇒ Array
74
75
76
|
# File 'lib/solargraph/complex_type.rb', line 74
def map &block
@items.map &block
end
|
#namespace ⇒ String
122
123
124
125
|
# File 'lib/solargraph/complex_type.rb', line 122
def namespace
@namespace ||= method_missing(:namespace).to_s
end
|
#namespaces ⇒ Array<String>
128
129
130
|
# File 'lib/solargraph/complex_type.rb', line 128
def namespaces
@items.map(&:namespace)
end
|
#nullable? ⇒ Boolean
202
203
204
|
# File 'lib/solargraph/complex_type.rb', line 202
def nullable?
@items.any?(&:nil_type?)
end
|
#qualify(api_map, context = '') ⇒ ComplexType
30
31
32
33
34
35
36
37
38
|
# File 'lib/solargraph/complex_type.rb', line 30
def qualify api_map, context = ''
red = reduce_object
types = red.items.map do |t|
next t if ['nil', 'void', 'undefined'].include?(t.name)
next t if ['::Boolean'].include?(t.rooted_name)
t.qualify api_map, context
end
ComplexType.new(types).reduce_object
end
|
212
213
214
215
216
217
218
219
|
# File 'lib/solargraph/complex_type.rb', line 212
def reduce_class_type
new_items = items.flat_map do |type|
next type unless ['Module', 'Class'].include?(type.name)
type.all_params
end
ComplexType.new(new_items)
end
|
#resolve_generics(definitions, context_type) ⇒ ComplexType
197
198
199
200
|
# File 'lib/solargraph/complex_type.rb', line 197
def resolve_generics definitions, context_type
result = @items.map { |i| i.resolve_generics(definitions, context_type) }
ComplexType.new(result)
end
|
#resolve_generics_from_context(generics_to_resolve, context_type, resolved_generic_values: {}) ⇒ self
44
45
46
47
48
|
# File 'lib/solargraph/complex_type.rb', line 44
def resolve_generics_from_context generics_to_resolve, context_type, resolved_generic_values: {}
return self unless generic?
ComplexType.new(@items.map { |i| i.resolve_generics_from_context(generics_to_resolve, context_type, resolved_generic_values: resolved_generic_values) })
end
|
#respond_to_missing?(name, include_private = false) ⇒ Boolean
142
143
144
|
# File 'lib/solargraph/complex_type.rb', line 142
def respond_to_missing?(name, include_private = false)
TypeMethods.public_instance_methods.include?(name) || super
end
|
#rooted? ⇒ Boolean
every top-level type has resolved to be fully qualified; see #all_rooted? to check their subtypes as well
229
230
231
|
# File 'lib/solargraph/complex_type.rb', line 229
def rooted?
all?(&:rooted?)
end
|
154
155
156
|
# File 'lib/solargraph/complex_type.rb', line 154
def rooted_tags
map(&:rooted_tag).join(', ')
end
|
#select(&block) ⇒ Array<UniqueType>
117
118
119
|
# File 'lib/solargraph/complex_type.rb', line 117
def select &block
@items.select &block
end
|
64
65
66
67
68
69
70
|
# File 'lib/solargraph/complex_type.rb', line 64
def self_to_type dst
object_type_dst = dst.reduce_class_type
transform do |t|
next t if t.name != 'self'
object_type_dst
end
end
|
#selfy? ⇒ Boolean
170
171
172
|
# File 'lib/solargraph/complex_type.rb', line 170
def selfy?
@items.any?(&:selfy?)
end
|
106
107
108
|
# File 'lib/solargraph/complex_type.rb', line 106
def tags
@items.map(&:tag).join(', ')
end
|
102
103
104
|
# File 'lib/solargraph/complex_type.rb', line 102
def to_a
@items
end
|
#to_rbs ⇒ String
56
57
58
59
60
|
# File 'lib/solargraph/complex_type.rb', line 56
def to_rbs
((@items.length > 1 ? '(' : '') +
@items.map(&:to_rbs).join(' | ') +
(@items.length > 1 ? ')' : ''))
end
|
#to_s ⇒ Object
146
147
148
|
# File 'lib/solargraph/complex_type.rb', line 146
def to_s
map(&:tag).join(', ')
end
|
182
183
184
185
|
# File 'lib/solargraph/complex_type.rb', line 182
def transform(new_name = nil, &transform_type)
raise "Please remove leading :: and set rooted with recreate() instead - #{new_name}" if new_name&.start_with?('::')
ComplexType.new(map { |ut| ut.transform(new_name, &transform_type) })
end
|