solargraph 0.54.1 → 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 +3 -1
- data/.gitignore +2 -0
- data/CHANGELOG.md +70 -0
- data/README.md +13 -3
- data/lib/solargraph/api_map/cache.rb +10 -1
- data/lib/solargraph/api_map/index.rb +175 -0
- data/lib/solargraph/api_map/store.rb +79 -126
- data/lib/solargraph/api_map.rb +247 -93
- data/lib/solargraph/bench.rb +17 -1
- data/lib/solargraph/complex_type/type_methods.rb +13 -1
- data/lib/solargraph/complex_type/unique_type.rb +118 -9
- data/lib/solargraph/complex_type.rb +48 -18
- data/lib/solargraph/convention/base.rb +3 -3
- data/lib/solargraph/convention/struct_definition/struct_assignment_node.rb +60 -0
- data/lib/solargraph/convention/struct_definition/struct_definition_node.rb +100 -0
- data/lib/solargraph/convention/struct_definition.rb +101 -0
- data/lib/solargraph/convention.rb +5 -3
- data/lib/solargraph/doc_map.rb +274 -56
- data/lib/solargraph/equality.rb +33 -0
- data/lib/solargraph/gem_pins.rb +53 -37
- data/lib/solargraph/language_server/host/message_worker.rb +31 -11
- data/lib/solargraph/language_server/host.rb +24 -13
- data/lib/solargraph/language_server/message/base.rb +19 -12
- data/lib/solargraph/language_server/message/extended/check_gem_version.rb +2 -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/language_server/message/initialize.rb +3 -1
- data/lib/solargraph/language_server/message/text_document/completion.rb +0 -3
- data/lib/solargraph/language_server/message/text_document/formatting.rb +4 -0
- data/lib/solargraph/library.rb +13 -11
- data/lib/solargraph/location.rb +28 -0
- data/lib/solargraph/logging.rb +1 -0
- data/lib/solargraph/parser/comment_ripper.rb +12 -6
- data/lib/solargraph/parser/flow_sensitive_typing.rb +227 -0
- data/lib/solargraph/parser/node_methods.rb +15 -1
- data/lib/solargraph/parser/node_processor.rb +3 -1
- data/lib/solargraph/parser/parser_gem/class_methods.rb +16 -14
- data/lib/solargraph/parser/parser_gem/node_chainer.rb +17 -23
- data/lib/solargraph/parser/parser_gem/node_methods.rb +5 -3
- data/lib/solargraph/parser/parser_gem/node_processors/alias_node.rb +2 -1
- data/lib/solargraph/parser/parser_gem/node_processors/and_node.rb +21 -0
- data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +4 -2
- data/lib/solargraph/parser/parser_gem/node_processors/block_node.rb +4 -2
- data/lib/solargraph/parser/parser_gem/node_processors/casgn_node.rb +23 -2
- data/lib/solargraph/parser/parser_gem/node_processors/cvasgn_node.rb +2 -1
- data/lib/solargraph/parser/parser_gem/node_processors/def_node.rb +6 -3
- data/lib/solargraph/parser/parser_gem/node_processors/defs_node.rb +2 -1
- data/lib/solargraph/parser/parser_gem/node_processors/gvasgn_node.rb +2 -1
- data/lib/solargraph/parser/parser_gem/node_processors/if_node.rb +21 -0
- data/lib/solargraph/parser/parser_gem/node_processors/ivasgn_node.rb +4 -2
- data/lib/solargraph/parser/parser_gem/node_processors/lvasgn_node.rb +4 -3
- data/lib/solargraph/parser/parser_gem/node_processors/namespace_node.rb +29 -6
- data/lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb +41 -0
- data/lib/solargraph/parser/parser_gem/node_processors/resbody_node.rb +2 -1
- data/lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb +4 -3
- data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +28 -16
- data/lib/solargraph/parser/parser_gem/node_processors/sym_node.rb +2 -1
- data/lib/solargraph/parser/parser_gem/node_processors/until_node.rb +29 -0
- data/lib/solargraph/parser/parser_gem/node_processors/while_node.rb +29 -0
- data/lib/solargraph/parser/parser_gem/node_processors.rb +10 -0
- data/lib/solargraph/parser/region.rb +1 -1
- data/lib/solargraph/parser.rb +1 -0
- data/lib/solargraph/pin/base.rb +326 -43
- data/lib/solargraph/pin/base_variable.rb +18 -10
- data/lib/solargraph/pin/block.rb +3 -3
- data/lib/solargraph/pin/breakable.rb +9 -0
- data/lib/solargraph/pin/callable.rb +77 -6
- data/lib/solargraph/pin/closure.rb +18 -1
- data/lib/solargraph/pin/common.rb +5 -0
- data/lib/solargraph/pin/delegated_method.rb +20 -1
- data/lib/solargraph/pin/documenting.rb +16 -0
- data/lib/solargraph/pin/keyword.rb +7 -2
- data/lib/solargraph/pin/local_variable.rb +15 -6
- data/lib/solargraph/pin/method.rb +172 -42
- data/lib/solargraph/pin/namespace.rb +17 -9
- data/lib/solargraph/pin/parameter.rb +61 -11
- data/lib/solargraph/pin/proxy_type.rb +12 -6
- data/lib/solargraph/pin/reference/override.rb +10 -6
- data/lib/solargraph/pin/reference/require.rb +2 -2
- data/lib/solargraph/pin/signature.rb +42 -0
- data/lib/solargraph/pin/singleton.rb +1 -1
- data/lib/solargraph/pin/symbol.rb +3 -2
- data/lib/solargraph/pin/until.rb +18 -0
- data/lib/solargraph/pin/while.rb +18 -0
- data/lib/solargraph/pin.rb +4 -1
- data/lib/solargraph/pin_cache.rb +185 -0
- data/lib/solargraph/position.rb +16 -0
- data/lib/solargraph/range.rb +16 -0
- data/lib/solargraph/rbs_map/conversions.rb +199 -66
- data/lib/solargraph/rbs_map/core_fills.rb +32 -16
- data/lib/solargraph/rbs_map/core_map.rb +34 -11
- data/lib/solargraph/rbs_map/stdlib_map.rb +15 -5
- data/lib/solargraph/rbs_map.rb +74 -16
- data/lib/solargraph/shell.rb +19 -18
- data/lib/solargraph/source/chain/array.rb +12 -8
- data/lib/solargraph/source/chain/block_symbol.rb +1 -1
- data/lib/solargraph/source/chain/block_variable.rb +1 -1
- data/lib/solargraph/source/chain/call.rb +62 -25
- data/lib/solargraph/source/chain/constant.rb +1 -1
- data/lib/solargraph/source/chain/hash.rb +9 -3
- data/lib/solargraph/source/chain/head.rb +1 -1
- data/lib/solargraph/source/chain/if.rb +6 -1
- data/lib/solargraph/source/chain/link.rb +19 -5
- data/lib/solargraph/source/chain/literal.rb +27 -2
- data/lib/solargraph/source/chain/or.rb +1 -1
- data/lib/solargraph/source/chain/z_super.rb +1 -1
- data/lib/solargraph/source/chain.rb +106 -62
- data/lib/solargraph/source/cursor.rb +1 -11
- data/lib/solargraph/source/source_chainer.rb +2 -2
- data/lib/solargraph/source.rb +2 -1
- data/lib/solargraph/source_map/clip.rb +4 -2
- data/lib/solargraph/source_map/mapper.rb +9 -5
- data/lib/solargraph/source_map.rb +0 -17
- data/lib/solargraph/type_checker/checks.rb +4 -0
- data/lib/solargraph/type_checker.rb +41 -14
- 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/config.rb +7 -3
- data/lib/solargraph/workspace.rb +16 -6
- data/lib/solargraph/yard_map/mapper/to_constant.rb +5 -2
- data/lib/solargraph/yard_map/mapper/to_method.rb +55 -15
- data/lib/solargraph/yard_map/mapper/to_namespace.rb +5 -2
- data/lib/solargraph/yard_map/mapper.rb +5 -3
- data/lib/solargraph/yard_map/to_method.rb +4 -2
- data/lib/solargraph/yardoc.rb +6 -9
- data/lib/solargraph.rb +20 -1
- data/rbs/fills/tuple.rbs +150 -0
- data/rbs_collection.yaml +19 -0
- data/solargraph.gemspec +6 -5
- metadata +56 -29
- 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
|
|
@@ -27,17 +28,284 @@ module Solargraph
|
|
|
27
28
|
# @return [::Symbol]
|
|
28
29
|
attr_accessor :source
|
|
29
30
|
|
|
31
|
+
def presence_certain?
|
|
32
|
+
true
|
|
33
|
+
end
|
|
34
|
+
|
|
30
35
|
# @param location [Solargraph::Location, nil]
|
|
31
36
|
# @param type_location [Solargraph::Location, nil]
|
|
32
37
|
# @param closure [Solargraph::Pin::Closure, nil]
|
|
33
38
|
# @param name [String]
|
|
34
39
|
# @param comments [String]
|
|
35
|
-
|
|
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
|
|
36
44
|
@location = location
|
|
37
45
|
@type_location = type_location
|
|
38
46
|
@closure = closure
|
|
39
47
|
@name = name
|
|
40
48
|
@comments = comments
|
|
49
|
+
@source = source
|
|
50
|
+
@identity = nil
|
|
51
|
+
@docstring = docstring
|
|
52
|
+
@directives = directives
|
|
53
|
+
assert_source_provided
|
|
54
|
+
end
|
|
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
|
+
|
|
307
|
+
def assert_source_provided
|
|
308
|
+
Solargraph.assert_or_log(:source, "source not provided - #{@path} #{@source} #{self.class}") if source.nil?
|
|
41
309
|
end
|
|
42
310
|
|
|
43
311
|
# @return [String]
|
|
@@ -71,15 +339,14 @@ module Solargraph
|
|
|
71
339
|
# @param context_type [ComplexType] The receiver type
|
|
72
340
|
# @return [self]
|
|
73
341
|
def resolve_generics definitions, context_type
|
|
74
|
-
|
|
75
|
-
transformed.erase_generics(definitions.generics)
|
|
342
|
+
transform_types { |t| t.resolve_generics(definitions, context_type) if t }
|
|
76
343
|
end
|
|
77
344
|
|
|
78
345
|
def all_rooted?
|
|
79
346
|
!return_type || return_type.all_rooted?
|
|
80
347
|
end
|
|
81
348
|
|
|
82
|
-
# @param generics_to_erase [
|
|
349
|
+
# @param generics_to_erase [::Array<String>]
|
|
83
350
|
# @return [self]
|
|
84
351
|
def erase_generics(generics_to_erase)
|
|
85
352
|
return self if generics_to_erase.empty?
|
|
@@ -103,7 +370,7 @@ module Solargraph
|
|
|
103
370
|
end
|
|
104
371
|
|
|
105
372
|
def to_s
|
|
106
|
-
|
|
373
|
+
desc
|
|
107
374
|
end
|
|
108
375
|
|
|
109
376
|
# @return [Boolean]
|
|
@@ -116,14 +383,6 @@ module Solargraph
|
|
|
116
383
|
location || type_location
|
|
117
384
|
end
|
|
118
385
|
|
|
119
|
-
# Pin equality is determined using the #nearly? method and also
|
|
120
|
-
# requiring both pins to have the same location.
|
|
121
|
-
#
|
|
122
|
-
def == other
|
|
123
|
-
return false unless nearly? other
|
|
124
|
-
comments == other.comments and location == other.location
|
|
125
|
-
end
|
|
126
|
-
|
|
127
386
|
# True if the specified pin is a near match to this one. A near match
|
|
128
387
|
# indicates that the pins contain mostly the same data. Any differences
|
|
129
388
|
# between them should not have an impact on the API surface.
|
|
@@ -140,6 +399,15 @@ module Solargraph
|
|
|
140
399
|
)
|
|
141
400
|
end
|
|
142
401
|
|
|
402
|
+
# Pin equality is determined using the #nearly? method and also
|
|
403
|
+
# requiring both pins to have the same location.
|
|
404
|
+
#
|
|
405
|
+
# @param other [self]
|
|
406
|
+
def == other
|
|
407
|
+
return false unless nearly? other
|
|
408
|
+
comments == other.comments && location == other.location
|
|
409
|
+
end
|
|
410
|
+
|
|
143
411
|
# The pin's return type.
|
|
144
412
|
#
|
|
145
413
|
# @return [ComplexType]
|
|
@@ -149,13 +417,13 @@ module Solargraph
|
|
|
149
417
|
|
|
150
418
|
# @return [YARD::Docstring]
|
|
151
419
|
def docstring
|
|
152
|
-
parse_comments unless
|
|
420
|
+
parse_comments unless @docstring
|
|
153
421
|
@docstring ||= Solargraph::Source.parse_docstring('').to_docstring
|
|
154
422
|
end
|
|
155
423
|
|
|
156
424
|
# @return [::Array<YARD::Tags::Directive>]
|
|
157
425
|
def directives
|
|
158
|
-
parse_comments unless
|
|
426
|
+
parse_comments unless @directives
|
|
159
427
|
@directives
|
|
160
428
|
end
|
|
161
429
|
|
|
@@ -173,7 +441,7 @@ module Solargraph
|
|
|
173
441
|
#
|
|
174
442
|
# @return [Boolean]
|
|
175
443
|
def maybe_directives?
|
|
176
|
-
return !@directives.empty? if defined?(@directives)
|
|
444
|
+
return !@directives.empty? if defined?(@directives) && @directives
|
|
177
445
|
@maybe_directives ||= comments.include?('@!')
|
|
178
446
|
end
|
|
179
447
|
|
|
@@ -212,26 +480,6 @@ module Solargraph
|
|
|
212
480
|
probe api_map
|
|
213
481
|
end
|
|
214
482
|
|
|
215
|
-
# Try to merge data from another pin. Merges are only possible if the
|
|
216
|
-
# pins are near matches (see the #nearly? method). The changes should
|
|
217
|
-
# not have any side effects on the API surface.
|
|
218
|
-
#
|
|
219
|
-
# @param pin [Pin::Base] The pin to merge into this one
|
|
220
|
-
# @return [Boolean] True if the pins were merged
|
|
221
|
-
def try_merge! pin
|
|
222
|
-
return false unless nearly?(pin)
|
|
223
|
-
@location = pin.location
|
|
224
|
-
@closure = pin.closure
|
|
225
|
-
return true if comments == pin.comments
|
|
226
|
-
@comments = pin.comments
|
|
227
|
-
@docstring = pin.docstring
|
|
228
|
-
@return_type = pin.return_type
|
|
229
|
-
@documentation = nil
|
|
230
|
-
@deprecated = nil
|
|
231
|
-
reset_conversions
|
|
232
|
-
true
|
|
233
|
-
end
|
|
234
|
-
|
|
235
483
|
def proxied?
|
|
236
484
|
@proxied ||= false
|
|
237
485
|
end
|
|
@@ -266,9 +514,10 @@ module Solargraph
|
|
|
266
514
|
result
|
|
267
515
|
end
|
|
268
516
|
|
|
517
|
+
# @deprecated
|
|
269
518
|
# @return [String]
|
|
270
519
|
def identity
|
|
271
|
-
@identity ||= "#{closure
|
|
520
|
+
@identity ||= "#{closure&.path}|#{name}|#{location}"
|
|
272
521
|
end
|
|
273
522
|
|
|
274
523
|
# @return [String, nil]
|
|
@@ -276,21 +525,51 @@ module Solargraph
|
|
|
276
525
|
return_type.to_rbs
|
|
277
526
|
end
|
|
278
527
|
|
|
279
|
-
# @return [String
|
|
280
|
-
def
|
|
528
|
+
# @return [String]
|
|
529
|
+
def type_desc
|
|
530
|
+
rbs = to_rbs
|
|
531
|
+
# RBS doesn't have a way to represent a Class<x> type
|
|
532
|
+
rbs = return_type.rooted_tags if return_type.name == 'Class'
|
|
281
533
|
if path
|
|
282
|
-
if
|
|
283
|
-
path + ' ' +
|
|
534
|
+
if rbs
|
|
535
|
+
path + ' ' + rbs
|
|
284
536
|
else
|
|
285
537
|
path
|
|
286
538
|
end
|
|
287
539
|
else
|
|
288
|
-
|
|
540
|
+
rbs
|
|
289
541
|
end
|
|
290
542
|
end
|
|
291
543
|
|
|
544
|
+
# @return [String]
|
|
545
|
+
def inner_desc
|
|
546
|
+
closure_info = closure&.desc
|
|
547
|
+
binder_info = binder&.desc
|
|
548
|
+
"name=#{name.inspect} return_type=#{type_desc}, context=#{context.rooted_tags}, closure=#{closure_info}, binder=#{binder_info}"
|
|
549
|
+
end
|
|
550
|
+
|
|
551
|
+
def desc
|
|
552
|
+
"[#{inner_desc}]"
|
|
553
|
+
end
|
|
554
|
+
|
|
555
|
+
# @return [String]
|
|
292
556
|
def inspect
|
|
293
|
-
"#<#{self.class} `#{self.
|
|
557
|
+
"#<#{self.class} `#{self.inner_desc}`#{all_location_text} via #{source.inspect}>"
|
|
558
|
+
end
|
|
559
|
+
|
|
560
|
+
def all_location_text
|
|
561
|
+
if location.nil? && type_location.nil?
|
|
562
|
+
''
|
|
563
|
+
elsif !location.nil? && type_location.nil?
|
|
564
|
+
" at #{location.inspect})"
|
|
565
|
+
elsif !type_location.nil? && location.nil?
|
|
566
|
+
" at #{type_location.inspect})"
|
|
567
|
+
else
|
|
568
|
+
" at (#{location.inspect} and #{type_location.inspect})"
|
|
569
|
+
end
|
|
570
|
+
end
|
|
571
|
+
|
|
572
|
+
def reset_generated!
|
|
294
573
|
end
|
|
295
574
|
|
|
296
575
|
protected
|
|
@@ -304,6 +583,10 @@ module Solargraph
|
|
|
304
583
|
# @return [ComplexType]
|
|
305
584
|
attr_writer :return_type
|
|
306
585
|
|
|
586
|
+
attr_writer :docstring
|
|
587
|
+
|
|
588
|
+
attr_writer :directives
|
|
589
|
+
|
|
307
590
|
private
|
|
308
591
|
|
|
309
592
|
# @return [void]
|
|
@@ -11,12 +11,23 @@ module Solargraph
|
|
|
11
11
|
|
|
12
12
|
attr_accessor :mass_assignment
|
|
13
13
|
|
|
14
|
+
# @param return_type [ComplexType, nil]
|
|
14
15
|
# @param assignment [Parser::AST::Node, nil]
|
|
15
|
-
def initialize assignment: nil, **splat
|
|
16
|
+
def initialize assignment: nil, return_type: nil, **splat
|
|
16
17
|
super(**splat)
|
|
17
18
|
@assignment = assignment
|
|
18
19
|
# @type [nil, ::Array(Parser::AST::Node, Integer)]
|
|
19
20
|
@mass_assignment = nil
|
|
21
|
+
@return_type = return_type
|
|
22
|
+
end
|
|
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)
|
|
20
31
|
end
|
|
21
32
|
|
|
22
33
|
def completion_item_kind
|
|
@@ -32,7 +43,10 @@ module Solargraph
|
|
|
32
43
|
@return_type ||= generate_complex_type
|
|
33
44
|
end
|
|
34
45
|
|
|
46
|
+
# @sg-ignore
|
|
35
47
|
def nil_assignment?
|
|
48
|
+
# this will always be false - should it be return_type ==
|
|
49
|
+
# ComplexType::NIL or somesuch?
|
|
36
50
|
return_type.nil?
|
|
37
51
|
end
|
|
38
52
|
|
|
@@ -88,20 +102,14 @@ module Solargraph
|
|
|
88
102
|
ComplexType::UNDEFINED
|
|
89
103
|
end
|
|
90
104
|
|
|
105
|
+
# @param other [Object]
|
|
91
106
|
def == other
|
|
92
107
|
return false unless super
|
|
93
108
|
assignment == other.assignment
|
|
94
109
|
end
|
|
95
110
|
|
|
96
|
-
def
|
|
97
|
-
|
|
98
|
-
@assignment = pin.assignment
|
|
99
|
-
@return_type = pin.return_type
|
|
100
|
-
true
|
|
101
|
-
end
|
|
102
|
-
|
|
103
|
-
def desc
|
|
104
|
-
"#{to_rbs} = #{assignment&.type.inspect}"
|
|
111
|
+
def type_desc
|
|
112
|
+
"#{super} = #{assignment&.type.inspect}"
|
|
105
113
|
end
|
|
106
114
|
|
|
107
115
|
private
|
data/lib/solargraph/pin/block.rb
CHANGED
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
module Solargraph
|
|
4
4
|
module Pin
|
|
5
5
|
class Block < Callable
|
|
6
|
+
include Breakable
|
|
7
|
+
|
|
6
8
|
# @return [Parser::AST::Node]
|
|
7
9
|
attr_reader :receiver
|
|
8
10
|
|
|
@@ -36,14 +38,12 @@ module Solargraph
|
|
|
36
38
|
#
|
|
37
39
|
# @return [::Array<ComplexType>]
|
|
38
40
|
def destructure_yield_types(yield_types, parameters)
|
|
39
|
-
return yield_types if yield_types.length == parameters.length
|
|
40
|
-
|
|
41
41
|
# yielding a tuple into a block will destructure the tuple
|
|
42
42
|
if yield_types.length == 1
|
|
43
43
|
yield_type = yield_types.first
|
|
44
44
|
return yield_type.all_params if yield_type.tuple? && yield_type.all_params.length == parameters.length
|
|
45
45
|
end
|
|
46
|
-
parameters.map { ComplexType::UNDEFINED }
|
|
46
|
+
parameters.map.with_index { |_, idx| yield_types[idx] || ComplexType::UNDEFINED }
|
|
47
47
|
end
|
|
48
48
|
|
|
49
49
|
# @param api_map [ApiMap]
|
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
module Solargraph
|
|
4
4
|
module Pin
|
|
5
5
|
class Callable < Closure
|
|
6
|
-
# @return [
|
|
6
|
+
# @return [Signature]
|
|
7
7
|
attr_reader :block
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
attr_accessor :parameters
|
|
10
10
|
|
|
11
11
|
# @return [ComplexType, nil]
|
|
12
12
|
attr_reader :return_type
|
|
@@ -21,11 +21,67 @@ module Solargraph
|
|
|
21
21
|
@parameters = parameters
|
|
22
22
|
end
|
|
23
23
|
|
|
24
|
+
def method_namespace
|
|
25
|
+
closure.namespace
|
|
26
|
+
end
|
|
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
|
+
|
|
24
51
|
# @return [::Array<String>]
|
|
25
52
|
def parameter_names
|
|
26
53
|
@parameter_names ||= parameters.map(&:name)
|
|
27
54
|
end
|
|
28
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
|
+
|
|
29
85
|
# @param generics_to_resolve [Enumerable<String>]
|
|
30
86
|
# @param arg_types [Array<ComplexType>, nil]
|
|
31
87
|
# @param return_type_context [ComplexType, nil]
|
|
@@ -57,7 +113,24 @@ module Solargraph
|
|
|
57
113
|
callable
|
|
58
114
|
end
|
|
59
115
|
|
|
60
|
-
|
|
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
|
+
|
|
133
|
+
# @param generics_to_resolve [::Array<String>]
|
|
61
134
|
# @param arg_types [Array<ComplexType>, nil]
|
|
62
135
|
# @param return_type_context [ComplexType, nil]
|
|
63
136
|
# @param yield_arg_types [Array<ComplexType>, nil]
|
|
@@ -113,7 +186,7 @@ module Solargraph
|
|
|
113
186
|
end
|
|
114
187
|
|
|
115
188
|
# @param arguments [::Array<Chain>]
|
|
116
|
-
# @param
|
|
189
|
+
# @param with_block [Boolean]
|
|
117
190
|
# @return [Boolean]
|
|
118
191
|
def arity_matches? arguments, with_block
|
|
119
192
|
argcount = arguments.length
|
|
@@ -140,8 +213,6 @@ module Solargraph
|
|
|
140
213
|
protected
|
|
141
214
|
|
|
142
215
|
attr_writer :block
|
|
143
|
-
|
|
144
|
-
attr_writer :parameters
|
|
145
216
|
end
|
|
146
217
|
end
|
|
147
218
|
end
|