solargraph 0.55.4 → 0.56.0
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/.github/workflows/plugins.yml +2 -0
- data/.github/workflows/typecheck.yml +2 -0
- data/.gitignore +2 -0
- data/CHANGELOG.md +17 -0
- data/README.md +13 -3
- data/lib/solargraph/api_map/index.rb +23 -15
- data/lib/solargraph/api_map/store.rb +2 -1
- data/lib/solargraph/api_map.rb +53 -27
- data/lib/solargraph/complex_type/type_methods.rb +5 -1
- data/lib/solargraph/complex_type/unique_type.rb +7 -0
- data/lib/solargraph/convention/base.rb +3 -3
- data/lib/solargraph/convention.rb +3 -3
- data/lib/solargraph/doc_map.rb +200 -43
- data/lib/solargraph/gem_pins.rb +53 -38
- data/lib/solargraph/language_server/host.rb +9 -1
- data/lib/solargraph/language_server/message/extended/check_gem_version.rb +1 -0
- data/lib/solargraph/language_server/message/extended/document.rb +5 -2
- data/lib/solargraph/language_server/message/extended/document_gems.rb +3 -3
- data/lib/solargraph/library.rb +6 -3
- data/lib/solargraph/location.rb +13 -0
- data/lib/solargraph/parser/parser_gem/class_methods.rb +5 -8
- data/lib/solargraph/parser/parser_gem/node_processors/casgn_node.rb +2 -2
- data/lib/solargraph/parser/parser_gem/node_processors/namespace_node.rb +2 -2
- data/lib/solargraph/pin/base.rb +268 -24
- data/lib/solargraph/pin/base_variable.rb +9 -8
- data/lib/solargraph/pin/callable.rb +69 -0
- data/lib/solargraph/pin/closure.rb +12 -0
- data/lib/solargraph/pin/local_variable.rb +8 -5
- data/lib/solargraph/pin/method.rb +134 -17
- data/lib/solargraph/pin/parameter.rb +43 -6
- data/lib/solargraph/pin/signature.rb +38 -0
- data/lib/solargraph/pin_cache.rb +185 -0
- data/lib/solargraph/position.rb +9 -0
- data/lib/solargraph/range.rb +9 -0
- data/lib/solargraph/rbs_map/conversions.rb +19 -8
- data/lib/solargraph/rbs_map/core_map.rb +31 -9
- data/lib/solargraph/rbs_map/stdlib_map.rb +15 -5
- data/lib/solargraph/rbs_map.rb +74 -17
- data/lib/solargraph/shell.rb +16 -18
- data/lib/solargraph/source_map.rb +0 -17
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/views/_method.erb +10 -10
- data/lib/solargraph/views/_namespace.erb +3 -3
- data/lib/solargraph/views/document.erb +10 -10
- data/lib/solargraph/workspace.rb +15 -5
- data/lib/solargraph/yardoc.rb +6 -9
- data/lib/solargraph.rb +10 -12
- data/rbs_collection.yaml +19 -0
- data/solargraph.gemspec +1 -0
- metadata +19 -7
- data/lib/solargraph/cache.rb +0 -77
data/lib/solargraph/pin/base.rb
CHANGED
@@ -8,6 +8,7 @@ module Solargraph
|
|
8
8
|
include Common
|
9
9
|
include Conversions
|
10
10
|
include Documenting
|
11
|
+
include Logging
|
11
12
|
|
12
13
|
# @return [YARD::CodeObjects::Base]
|
13
14
|
attr_reader :code_object
|
@@ -36,16 +37,273 @@ module Solargraph
|
|
36
37
|
# @param closure [Solargraph::Pin::Closure, nil]
|
37
38
|
# @param name [String]
|
38
39
|
# @param comments [String]
|
39
|
-
|
40
|
+
# @param source [Symbol, nil]
|
41
|
+
# @param docstring [YARD::Docstring, nil]
|
42
|
+
# @param directives [::Array<YARD::Tags::Directive>, nil]
|
43
|
+
def initialize location: nil, type_location: nil, closure: nil, source: nil, name: '', comments: '', docstring: nil, directives: nil
|
40
44
|
@location = location
|
41
45
|
@type_location = type_location
|
42
46
|
@closure = closure
|
43
47
|
@name = name
|
44
48
|
@comments = comments
|
45
49
|
@source = source
|
50
|
+
@identity = nil
|
51
|
+
@docstring = docstring
|
52
|
+
@directives = directives
|
46
53
|
assert_source_provided
|
47
54
|
end
|
48
55
|
|
56
|
+
# @param other [self]
|
57
|
+
# @param attrs [Hash{Symbol => Object}]
|
58
|
+
#
|
59
|
+
# @return [self]
|
60
|
+
def combine_with(other, attrs={})
|
61
|
+
raise "tried to combine #{other.class} with #{self.class}" unless other.class == self.class
|
62
|
+
type_location = choose(other, :type_location)
|
63
|
+
location = choose(other, :location)
|
64
|
+
combined_name = combine_name(other)
|
65
|
+
new_attrs = {
|
66
|
+
location: location,
|
67
|
+
type_location: type_location,
|
68
|
+
name: combined_name,
|
69
|
+
closure: choose_pin_attr_with_same_name(other, :closure),
|
70
|
+
comments: choose_longer(other, :comments),
|
71
|
+
source: :combined,
|
72
|
+
docstring: choose(other, :docstring),
|
73
|
+
directives: combine_directives(other),
|
74
|
+
}.merge(attrs)
|
75
|
+
assert_same_macros(other)
|
76
|
+
logger.debug { "Base#combine_with(path=#{path}) - other.comments=#{other.comments.inspect}, self.comments = #{self.comments}" }
|
77
|
+
out = self.class.new(**new_attrs)
|
78
|
+
out.reset_generated!
|
79
|
+
out
|
80
|
+
end
|
81
|
+
|
82
|
+
# @param other [self]
|
83
|
+
# @param attr [::Symbol]
|
84
|
+
# @sg-ignore
|
85
|
+
# @return [undefined]
|
86
|
+
def choose_longer(other, attr)
|
87
|
+
# @type [undefined]
|
88
|
+
val1 = send(attr)
|
89
|
+
# @type [undefined]
|
90
|
+
val2 = other.send(attr)
|
91
|
+
return val1 if val1 == val2
|
92
|
+
return val2 if val1.nil?
|
93
|
+
# @sg-ignore
|
94
|
+
val1.length > val2.length ? val1 : val2
|
95
|
+
end
|
96
|
+
|
97
|
+
# @param other [self]
|
98
|
+
# @return [::Array<YARD::Tags::Directive>, nil]
|
99
|
+
def combine_directives(other)
|
100
|
+
return self.directives if other.directives.empty?
|
101
|
+
return other.directives if directives.empty?
|
102
|
+
[directives + other.directives].uniq
|
103
|
+
end
|
104
|
+
|
105
|
+
# @param other [self]
|
106
|
+
# @return [String]
|
107
|
+
def combine_name(other)
|
108
|
+
if needs_consistent_name? || other.needs_consistent_name?
|
109
|
+
assert_same(other, :name)
|
110
|
+
else
|
111
|
+
choose(other, :name)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
# @return [void]
|
116
|
+
def reset_generated!
|
117
|
+
# @return_type doesn't go here as subclasses tend to assign it
|
118
|
+
# themselves in constructors, and they will deal with setting
|
119
|
+
# it in any methods that call this
|
120
|
+
#
|
121
|
+
# @docstring also doesn't go here, as there is code which
|
122
|
+
# directly manipulates docstring without editing comments
|
123
|
+
# (e.g., Api::Map::Store#index processes overrides that way
|
124
|
+
#
|
125
|
+
# Same with @directives, @macros, @maybe_directives, which
|
126
|
+
# regenerate docstring
|
127
|
+
@deprecated = nil
|
128
|
+
reset_conversions
|
129
|
+
end
|
130
|
+
|
131
|
+
def needs_consistent_name?
|
132
|
+
true
|
133
|
+
end
|
134
|
+
|
135
|
+
# @sg-ignore def should infer as symbol - "Not enough arguments to Module#protected"
|
136
|
+
protected def equality_fields
|
137
|
+
[name, location, type_location, closure, source]
|
138
|
+
end
|
139
|
+
|
140
|
+
# @param other [self]
|
141
|
+
# @return [ComplexType]
|
142
|
+
def combine_return_type(other)
|
143
|
+
if return_type.undefined?
|
144
|
+
other.return_type
|
145
|
+
elsif other.return_type.undefined?
|
146
|
+
return_type
|
147
|
+
elsif dodgy_return_type_source? && !other.dodgy_return_type_source?
|
148
|
+
other.return_type
|
149
|
+
elsif other.dodgy_return_type_source? && !dodgy_return_type_source?
|
150
|
+
return_type
|
151
|
+
else
|
152
|
+
all_items = return_type.items + other.return_type.items
|
153
|
+
if all_items.any? { |item| item.selfy? } && all_items.any? { |item| item.rooted_tag == context.rooted_tag }
|
154
|
+
# assume this was a declaration that should have said 'self'
|
155
|
+
all_items.delete_if { |item| item.rooted_tag == context.rooted_tag }
|
156
|
+
end
|
157
|
+
ComplexType.new(all_items)
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
def dodgy_return_type_source?
|
162
|
+
# uses a lot of 'Object' instead of 'self'
|
163
|
+
location&.filename&.include?('core_ext/object/')
|
164
|
+
end
|
165
|
+
|
166
|
+
# when choices are arbitrary, make sure the choice is consistent
|
167
|
+
#
|
168
|
+
# @param other [Pin::Base]
|
169
|
+
# @param attr [::Symbol]
|
170
|
+
#
|
171
|
+
# @return [Object, nil]
|
172
|
+
def choose(other, attr)
|
173
|
+
results = [self, other].map(&attr).compact
|
174
|
+
# true and false are different classes and can't be sorted
|
175
|
+
return true if results.any? { |r| r == true || r == false }
|
176
|
+
results.min
|
177
|
+
rescue
|
178
|
+
STDERR.puts("Problem handling #{attr} for \n#{self.inspect}\n and \n#{other.inspect}\n\n#{self.send(attr).inspect} vs #{other.send(attr).inspect}")
|
179
|
+
raise
|
180
|
+
end
|
181
|
+
|
182
|
+
# @param other [self]
|
183
|
+
# @param attr [Symbol]
|
184
|
+
# @sg-ignore
|
185
|
+
# @return [undefined]
|
186
|
+
def choose_node(other, attr)
|
187
|
+
if other.object_id < attr.object_id
|
188
|
+
other.send(attr)
|
189
|
+
else
|
190
|
+
send(attr)
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
# @param other [self]
|
195
|
+
# @param attr [::Symbol]
|
196
|
+
# @sg-ignore
|
197
|
+
# @return [undefined]
|
198
|
+
def prefer_rbs_location(other, attr)
|
199
|
+
if rbs_location? && !other.rbs_location?
|
200
|
+
self.send(attr)
|
201
|
+
elsif !rbs_location? && other.rbs_location?
|
202
|
+
other.send(attr)
|
203
|
+
else
|
204
|
+
choose(other, attr)
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
def rbs_location?
|
209
|
+
type_location&.rbs?
|
210
|
+
end
|
211
|
+
|
212
|
+
# @param other [self]
|
213
|
+
# @return [void]
|
214
|
+
def assert_same_macros(other)
|
215
|
+
return unless self.source == :yardoc && other.source == :yardoc
|
216
|
+
assert_same_count(other, :macros)
|
217
|
+
assert_same_array_content(other, :macros) { |macro| macro.tag.name }
|
218
|
+
end
|
219
|
+
|
220
|
+
# @param other [self]
|
221
|
+
# @param attr [::Symbol]
|
222
|
+
# @return [void]
|
223
|
+
# @todo strong typechecking should complain when there are no block-related tags
|
224
|
+
def assert_same_array_content(other, attr, &block)
|
225
|
+
arr1 = send(attr)
|
226
|
+
raise "Expected #{attr} on #{self} to be an Enumerable, got #{arr1.class}" unless arr1.is_a?(::Enumerable)
|
227
|
+
# @type arr1 [::Enumerable]
|
228
|
+
arr2 = other.send(attr)
|
229
|
+
raise "Expected #{attr} on #{other} to be an Enumerable, got #{arr2.class}" unless arr2.is_a?(::Enumerable)
|
230
|
+
# @type arr2 [::Enumerable]
|
231
|
+
|
232
|
+
# @sg-ignore
|
233
|
+
# @type [undefined]
|
234
|
+
values1 = arr1.map(&block)
|
235
|
+
# @type [undefined]
|
236
|
+
values2 = arr2.map(&block)
|
237
|
+
# @sg-ignore
|
238
|
+
return arr1 if values1 == values2
|
239
|
+
Solargraph.assert_or_log("combine_with_#{attr}".to_sym,
|
240
|
+
"Inconsistent #{attr.inspect} values between \nself =#{inspect} and \nother=#{other.inspect}:\n\n self values = #{values1}\nother values =#{attr} = #{values2}")
|
241
|
+
arr1
|
242
|
+
end
|
243
|
+
|
244
|
+
# @param other [self]
|
245
|
+
# @param attr [::Symbol]
|
246
|
+
#
|
247
|
+
# @return [::Enumerable]
|
248
|
+
def assert_same_count(other, attr)
|
249
|
+
# @type [::Enumerable]
|
250
|
+
arr1 = self.send(attr)
|
251
|
+
raise "Expected #{attr} on #{self} to be an Enumerable, got #{arr1.class}" unless arr1.is_a?(::Enumerable)
|
252
|
+
# @type [::Enumerable]
|
253
|
+
arr2 = other.send(attr)
|
254
|
+
raise "Expected #{attr} on #{other} to be an Enumerable, got #{arr2.class}" unless arr2.is_a?(::Enumerable)
|
255
|
+
return arr1 if arr1.count == arr2.count
|
256
|
+
Solargraph.assert_or_log("combine_with_#{attr}".to_sym,
|
257
|
+
"Inconsistent #{attr.inspect} count value between \nself =#{inspect} and \nother=#{other.inspect}:\n\n self.#{attr} = #{arr1.inspect}\nother.#{attr} = #{arr2.inspect}")
|
258
|
+
arr1
|
259
|
+
end
|
260
|
+
|
261
|
+
# @param other [self]
|
262
|
+
# @param attr [::Symbol]
|
263
|
+
#
|
264
|
+
# @return [Object, nil]
|
265
|
+
def assert_same(other, attr)
|
266
|
+
return false if other.nil?
|
267
|
+
val1 = send(attr)
|
268
|
+
val2 = other.send(attr)
|
269
|
+
return val1 if val1 == val2
|
270
|
+
Solargraph.assert_or_log("combine_with_#{attr}".to_sym,
|
271
|
+
"Inconsistent #{attr.inspect} values between \nself =#{inspect} and \nother=#{other.inspect}:\n\n self.#{attr} = #{val1.inspect}\nother.#{attr} = #{val2.inspect}")
|
272
|
+
val1
|
273
|
+
end
|
274
|
+
|
275
|
+
# @param other [self]
|
276
|
+
# @param attr [::Symbol]
|
277
|
+
# @sg-ignore
|
278
|
+
# @return [undefined]
|
279
|
+
def choose_pin_attr_with_same_name(other, attr)
|
280
|
+
# @type [Pin::Base, nil]
|
281
|
+
val1 = send(attr)
|
282
|
+
# @type [Pin::Base, nil]
|
283
|
+
val2 = other.send(attr)
|
284
|
+
raise "Expected pin for #{attr} on\n#{self.inspect},\ngot #{val1.inspect}" unless val1.nil? || val1.is_a?(Pin::Base)
|
285
|
+
raise "Expected pin for #{attr} on\n#{other.inspect},\ngot #{val2.inspect}" unless val2.nil? || val2.is_a?(Pin::Base)
|
286
|
+
if val1&.name != val2&.name
|
287
|
+
Solargraph.assert_or_log("combine_with_#{attr}_name".to_sym,
|
288
|
+
"Inconsistent #{attr.inspect} name values between \nself =#{inspect} and \nother=#{other.inspect}:\n\n self.#{attr} = #{val1.inspect}\nother.#{attr} = #{val2.inspect}")
|
289
|
+
end
|
290
|
+
choose_pin_attr(other, attr)
|
291
|
+
end
|
292
|
+
|
293
|
+
def choose_pin_attr(other, attr)
|
294
|
+
# @type [Pin::Base, nil]
|
295
|
+
val1 = send(attr)
|
296
|
+
# @type [Pin::Base, nil]
|
297
|
+
val2 = other.send(attr)
|
298
|
+
if val1.class != val2.class
|
299
|
+
Solargraph.assert_or_log("combine_with_#{attr}_class".to_sym,
|
300
|
+
"Inconsistent #{attr.inspect} class values between \nself =#{inspect} and \nother=#{other.inspect}:\n\n self.#{attr} = #{val1.inspect}\nother.#{attr} = #{val2.inspect}")
|
301
|
+
return val1
|
302
|
+
end
|
303
|
+
# arbitrary way of choosing a pin
|
304
|
+
[val1, val2].compact.min_by { _1.best_location.to_s }
|
305
|
+
end
|
306
|
+
|
49
307
|
def assert_source_provided
|
50
308
|
Solargraph.assert_or_log(:source, "source not provided - #{@path} #{@source} #{self.class}") if source.nil?
|
51
309
|
end
|
@@ -144,6 +402,7 @@ module Solargraph
|
|
144
402
|
# Pin equality is determined using the #nearly? method and also
|
145
403
|
# requiring both pins to have the same location.
|
146
404
|
#
|
405
|
+
# @param other [self]
|
147
406
|
def == other
|
148
407
|
return false unless nearly? other
|
149
408
|
comments == other.comments && location == other.location
|
@@ -158,13 +417,13 @@ module Solargraph
|
|
158
417
|
|
159
418
|
# @return [YARD::Docstring]
|
160
419
|
def docstring
|
161
|
-
parse_comments unless
|
420
|
+
parse_comments unless @docstring
|
162
421
|
@docstring ||= Solargraph::Source.parse_docstring('').to_docstring
|
163
422
|
end
|
164
423
|
|
165
424
|
# @return [::Array<YARD::Tags::Directive>]
|
166
425
|
def directives
|
167
|
-
parse_comments unless
|
426
|
+
parse_comments unless @directives
|
168
427
|
@directives
|
169
428
|
end
|
170
429
|
|
@@ -182,7 +441,7 @@ module Solargraph
|
|
182
441
|
#
|
183
442
|
# @return [Boolean]
|
184
443
|
def maybe_directives?
|
185
|
-
return !@directives.empty? if defined?(@directives)
|
444
|
+
return !@directives.empty? if defined?(@directives) && @directives
|
186
445
|
@maybe_directives ||= comments.include?('@!')
|
187
446
|
end
|
188
447
|
|
@@ -221,26 +480,6 @@ module Solargraph
|
|
221
480
|
probe api_map
|
222
481
|
end
|
223
482
|
|
224
|
-
# Try to merge data from another pin. Merges are only possible if the
|
225
|
-
# pins are near matches (see the #nearly? method). The changes should
|
226
|
-
# not have any side effects on the API surface.
|
227
|
-
#
|
228
|
-
# @param pin [Pin::Base] The pin to merge into this one
|
229
|
-
# @return [Boolean] True if the pins were merged
|
230
|
-
def try_merge! pin
|
231
|
-
return false unless nearly?(pin)
|
232
|
-
@location = pin.location
|
233
|
-
@closure = pin.closure
|
234
|
-
return true if comments == pin.comments
|
235
|
-
@comments = pin.comments
|
236
|
-
@docstring = pin.docstring
|
237
|
-
@return_type = pin.return_type
|
238
|
-
@documentation = nil
|
239
|
-
@deprecated = nil
|
240
|
-
reset_conversions
|
241
|
-
true
|
242
|
-
end
|
243
|
-
|
244
483
|
def proxied?
|
245
484
|
@proxied ||= false
|
246
485
|
end
|
@@ -313,6 +552,7 @@ module Solargraph
|
|
313
552
|
"[#{inner_desc}]"
|
314
553
|
end
|
315
554
|
|
555
|
+
# @return [String]
|
316
556
|
def inspect
|
317
557
|
"#<#{self.class} `#{self.inner_desc}`#{all_location_text} via #{source.inspect}>"
|
318
558
|
end
|
@@ -343,6 +583,10 @@ module Solargraph
|
|
343
583
|
# @return [ComplexType]
|
344
584
|
attr_writer :return_type
|
345
585
|
|
586
|
+
attr_writer :docstring
|
587
|
+
|
588
|
+
attr_writer :directives
|
589
|
+
|
346
590
|
private
|
347
591
|
|
348
592
|
# @return [void]
|
@@ -21,6 +21,15 @@ module Solargraph
|
|
21
21
|
@return_type = return_type
|
22
22
|
end
|
23
23
|
|
24
|
+
def combine_with(other, attrs={})
|
25
|
+
attrs.merge({
|
26
|
+
assignment: assert_same(other, :assignment),
|
27
|
+
mass_assignment: assert_same(other, :mass_assignment),
|
28
|
+
return_type: combine_return_type(other),
|
29
|
+
})
|
30
|
+
super(other, attrs)
|
31
|
+
end
|
32
|
+
|
24
33
|
def completion_item_kind
|
25
34
|
Solargraph::LanguageServer::CompletionItemKinds::VARIABLE
|
26
35
|
end
|
@@ -99,14 +108,6 @@ module Solargraph
|
|
99
108
|
assignment == other.assignment
|
100
109
|
end
|
101
110
|
|
102
|
-
# @param pin [self]
|
103
|
-
def try_merge! pin
|
104
|
-
return false unless super
|
105
|
-
@assignment = pin.assignment
|
106
|
-
@return_type = pin.return_type
|
107
|
-
true
|
108
|
-
end
|
109
|
-
|
110
111
|
def type_desc
|
111
112
|
"#{super} = #{assignment&.type.inspect}"
|
112
113
|
end
|
@@ -25,11 +25,63 @@ module Solargraph
|
|
25
25
|
closure.namespace
|
26
26
|
end
|
27
27
|
|
28
|
+
def combine_blocks(other)
|
29
|
+
if block.nil?
|
30
|
+
other.block
|
31
|
+
elsif other.block.nil?
|
32
|
+
block
|
33
|
+
else
|
34
|
+
choose_pin_attr(other, :block)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# @param other [self]
|
39
|
+
# @param attrs [Hash{Symbol => Object}]
|
40
|
+
#
|
41
|
+
# @return [self]
|
42
|
+
def combine_with(other, attrs={})
|
43
|
+
new_attrs = {
|
44
|
+
block: combine_blocks(other),
|
45
|
+
return_type: combine_return_type(other),
|
46
|
+
}.merge(attrs)
|
47
|
+
new_attrs[:parameters] = choose_parameters(other).clone.freeze unless new_attrs.key?(:parameters)
|
48
|
+
super(other, new_attrs)
|
49
|
+
end
|
50
|
+
|
28
51
|
# @return [::Array<String>]
|
29
52
|
def parameter_names
|
30
53
|
@parameter_names ||= parameters.map(&:name)
|
31
54
|
end
|
32
55
|
|
56
|
+
def generics
|
57
|
+
[]
|
58
|
+
end
|
59
|
+
|
60
|
+
def choose_parameters(other)
|
61
|
+
raise "Trying to combine two pins with different arities - \nself =#{inspect}, \nother=#{other.inspect}, \n\n self.arity=#{self.arity}, \nother.arity=#{other.arity}" if other.arity != arity
|
62
|
+
parameters.zip(other.parameters).map do |param, other_param|
|
63
|
+
if param.nil? && other_param.block?
|
64
|
+
other_param
|
65
|
+
elsif other_param.nil? && param.block?
|
66
|
+
param
|
67
|
+
else
|
68
|
+
param.combine_with(other_param)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def blockless_parameters
|
74
|
+
if parameters.last&.block?
|
75
|
+
parameters[0..-2]
|
76
|
+
else
|
77
|
+
parameters
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def arity
|
82
|
+
[generics, blockless_parameters.map(&:arity_decl), block&.arity]
|
83
|
+
end
|
84
|
+
|
33
85
|
# @param generics_to_resolve [Enumerable<String>]
|
34
86
|
# @param arg_types [Array<ComplexType>, nil]
|
35
87
|
# @param return_type_context [ComplexType, nil]
|
@@ -61,6 +113,23 @@ module Solargraph
|
|
61
113
|
callable
|
62
114
|
end
|
63
115
|
|
116
|
+
def typify api_map
|
117
|
+
type = super
|
118
|
+
return type if type.defined?
|
119
|
+
if method_name.end_with?('?')
|
120
|
+
logger.debug { "Callable#typify(self=#{self}) => Boolean (? suffix)" }
|
121
|
+
ComplexType::BOOLEAN
|
122
|
+
else
|
123
|
+
logger.debug { "Callable#typify(self=#{self}) => undefined" }
|
124
|
+
ComplexType::UNDEFINED
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def method_name
|
129
|
+
raise "closure was nil in #{self.inspect}" if closure.nil?
|
130
|
+
@method_name ||= closure.name
|
131
|
+
end
|
132
|
+
|
64
133
|
# @param generics_to_resolve [::Array<String>]
|
65
134
|
# @param arg_types [Array<ComplexType>, nil]
|
66
135
|
# @param return_type_context [ComplexType, nil]
|
@@ -19,6 +19,18 @@ module Solargraph
|
|
19
19
|
@generic_defaults ||= {}
|
20
20
|
end
|
21
21
|
|
22
|
+
# @param other [self]
|
23
|
+
# @param attrs [Hash{Symbol => Object}]
|
24
|
+
#
|
25
|
+
# @return [self]
|
26
|
+
def combine_with(other, attrs={})
|
27
|
+
new_attrs = {
|
28
|
+
scope: assert_same(other, :scope),
|
29
|
+
generics: generics.empty? ? other.generics : generics,
|
30
|
+
}.merge(attrs)
|
31
|
+
super(other, new_attrs)
|
32
|
+
end
|
33
|
+
|
22
34
|
def context
|
23
35
|
@context ||= begin
|
24
36
|
result = super
|
@@ -21,11 +21,14 @@ module Solargraph
|
|
21
21
|
@presence_certain = presence_certain
|
22
22
|
end
|
23
23
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
24
|
+
def combine_with(other, attrs={})
|
25
|
+
new_attrs = {
|
26
|
+
assignment: assert_same(other, :assignment),
|
27
|
+
presence_certain: assert_same(other, :presence_certain?),
|
28
|
+
}.merge(attrs)
|
29
|
+
new_attrs[:presence] = assert_same(other, :presence) unless attrs.key?(:presence)
|
30
|
+
|
31
|
+
super(other, new_attrs)
|
29
32
|
end
|
30
33
|
|
31
34
|
# @param other_closure [Pin::Closure]
|