solargraph 0.59.0.dev.1 → 0.59.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/linting.yml +3 -1
- data/.github/workflows/plugins.yml +12 -3
- data/.github/workflows/rspec.yml +9 -54
- data/.github/workflows/typecheck.yml +2 -1
- data/.gitignore +1 -0
- data/.rubocop.yml +38 -6
- data/.rubocop_todo.yml +40 -931
- data/CHANGELOG.md +22 -1
- data/Gemfile +3 -1
- data/Rakefile +25 -23
- data/bin/solargraph +2 -1
- data/lib/solargraph/api_map/constants.rb +0 -1
- data/lib/solargraph/api_map/index.rb +11 -11
- data/lib/solargraph/api_map/source_to_yard.rb +9 -8
- data/lib/solargraph/api_map/store.rb +28 -20
- data/lib/solargraph/api_map.rb +70 -41
- data/lib/solargraph/bench.rb +44 -45
- data/lib/solargraph/complex_type/type_methods.rb +14 -16
- data/lib/solargraph/complex_type/unique_type.rb +56 -47
- data/lib/solargraph/complex_type.rb +70 -62
- data/lib/solargraph/convention/data_definition/data_assignment_node.rb +61 -61
- data/lib/solargraph/convention/data_definition/data_definition_node.rb +4 -4
- data/lib/solargraph/convention/data_definition.rb +1 -1
- data/lib/solargraph/convention/gemfile.rb +15 -15
- data/lib/solargraph/convention/gemspec.rb +23 -23
- data/lib/solargraph/convention/rakefile.rb +17 -17
- data/lib/solargraph/convention/struct_definition/struct_assignment_node.rb +1 -1
- data/lib/solargraph/convention/struct_definition/struct_definition_node.rb +3 -3
- data/lib/solargraph/convention/struct_definition.rb +3 -3
- data/lib/solargraph/convention.rb +78 -78
- data/lib/solargraph/converters/dd.rb +19 -17
- data/lib/solargraph/converters/dl.rb +17 -15
- data/lib/solargraph/converters/dt.rb +17 -15
- data/lib/solargraph/converters/misc.rb +3 -1
- data/lib/solargraph/diagnostics/rubocop.rb +10 -10
- data/lib/solargraph/diagnostics/rubocop_helpers.rb +3 -3
- data/lib/solargraph/diagnostics/type_check.rb +10 -10
- data/lib/solargraph/diagnostics/update_errors.rb +37 -41
- data/lib/solargraph/doc_map.rb +370 -132
- data/lib/solargraph/equality.rb +3 -3
- data/lib/solargraph/gem_pins.rb +19 -18
- data/lib/solargraph/language_server/error_codes.rb +20 -20
- data/lib/solargraph/language_server/host/diagnoser.rb +89 -89
- data/lib/solargraph/language_server/host/dispatch.rb +2 -3
- data/lib/solargraph/language_server/host/message_worker.rb +2 -2
- data/lib/solargraph/language_server/host/sources.rb +1 -1
- data/lib/solargraph/language_server/host.rb +24 -21
- data/lib/solargraph/language_server/message/base.rb +97 -97
- data/lib/solargraph/language_server/message/client/register_capability.rb +13 -15
- data/lib/solargraph/language_server/message/completion_item/resolve.rb +58 -60
- data/lib/solargraph/language_server/message/extended/check_gem_version.rb +10 -11
- data/lib/solargraph/language_server/message/extended/document_gems.rb +32 -32
- data/lib/solargraph/language_server/message/extended/download_core.rb +20 -19
- data/lib/solargraph/language_server/message/extended/search.rb +20 -20
- data/lib/solargraph/language_server/message/initialize.rb +197 -191
- data/lib/solargraph/language_server/message/text_document/completion.rb +8 -8
- data/lib/solargraph/language_server/message/text_document/definition.rb +41 -34
- data/lib/solargraph/language_server/message/text_document/document_highlight.rb +23 -16
- data/lib/solargraph/language_server/message/text_document/document_symbol.rb +29 -21
- data/lib/solargraph/language_server/message/text_document/formatting.rb +6 -6
- data/lib/solargraph/language_server/message/text_document/hover.rb +3 -5
- data/lib/solargraph/language_server/message/text_document/prepare_rename.rb +18 -11
- data/lib/solargraph/language_server/message/text_document/references.rb +23 -16
- data/lib/solargraph/language_server/message/text_document/rename.rb +26 -19
- data/lib/solargraph/language_server/message/text_document/signature_help.rb +2 -2
- data/lib/solargraph/language_server/message/text_document/type_definition.rb +25 -19
- data/lib/solargraph/language_server/message/workspace/did_change_configuration.rb +41 -35
- data/lib/solargraph/language_server/message/workspace/did_change_watched_files.rb +48 -40
- data/lib/solargraph/language_server/message/workspace/did_change_workspace_folders.rb +32 -26
- data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +27 -19
- data/lib/solargraph/language_server/message.rb +94 -94
- data/lib/solargraph/language_server/request.rb +29 -27
- data/lib/solargraph/language_server/transport/data_reader.rb +72 -74
- data/lib/solargraph/language_server/uri_helpers.rb +49 -49
- data/lib/solargraph/library.rb +68 -95
- data/lib/solargraph/location.rb +10 -12
- data/lib/solargraph/logging.rb +4 -6
- data/lib/solargraph/page.rb +92 -92
- data/lib/solargraph/parser/comment_ripper.rb +12 -4
- data/lib/solargraph/parser/flow_sensitive_typing.rb +32 -44
- data/lib/solargraph/parser/node_processor/base.rb +4 -4
- data/lib/solargraph/parser/node_processor.rb +1 -1
- data/lib/solargraph/parser/parser_gem/class_methods.rb +4 -6
- data/lib/solargraph/parser/parser_gem/flawed_builder.rb +19 -19
- data/lib/solargraph/parser/parser_gem/node_chainer.rb +20 -20
- data/lib/solargraph/parser/parser_gem/node_methods.rb +66 -65
- data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +12 -12
- data/lib/solargraph/parser/parser_gem/node_processors/block_node.rb +1 -2
- data/lib/solargraph/parser/parser_gem/node_processors/def_node.rb +3 -3
- data/lib/solargraph/parser/parser_gem/node_processors/defs_node.rb +38 -37
- data/lib/solargraph/parser/parser_gem/node_processors/if_node.rb +3 -3
- data/lib/solargraph/parser/parser_gem/node_processors/ivasgn_node.rb +2 -1
- data/lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb +1 -1
- data/lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb +3 -5
- data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +118 -112
- data/lib/solargraph/parser/parser_gem/node_processors/until_node.rb +29 -29
- data/lib/solargraph/parser/parser_gem/node_processors/when_node.rb +1 -1
- data/lib/solargraph/parser/parser_gem/node_processors/while_node.rb +1 -1
- data/lib/solargraph/parser/parser_gem.rb +14 -12
- data/lib/solargraph/parser/snippet.rb +2 -0
- data/lib/solargraph/parser.rb +25 -23
- data/lib/solargraph/pin/base.rb +76 -64
- data/lib/solargraph/pin/base_variable.rb +28 -71
- data/lib/solargraph/pin/block.rb +3 -2
- data/lib/solargraph/pin/breakable.rb +2 -0
- data/lib/solargraph/pin/callable.rb +23 -26
- data/lib/solargraph/pin/closure.rb +5 -4
- data/lib/solargraph/pin/common.rb +5 -2
- data/lib/solargraph/pin/compound_statement.rb +3 -3
- data/lib/solargraph/pin/constant.rb +43 -45
- data/lib/solargraph/pin/conversions.rb +9 -4
- data/lib/solargraph/pin/delegated_method.rb +4 -4
- data/lib/solargraph/pin/documenting.rb +3 -2
- data/lib/solargraph/pin/local_variable.rb +4 -4
- data/lib/solargraph/pin/method.rb +74 -70
- data/lib/solargraph/pin/namespace.rb +13 -12
- data/lib/solargraph/pin/parameter.rb +28 -27
- data/lib/solargraph/pin/proxy_type.rb +2 -0
- data/lib/solargraph/pin/reference/type_alias.rb +16 -0
- data/lib/solargraph/pin/reference.rb +18 -0
- data/lib/solargraph/pin/search.rb +2 -2
- data/lib/solargraph/pin/signature.rb +9 -14
- data/lib/solargraph/pin/symbol.rb +1 -0
- data/lib/solargraph/pin/until.rb +1 -3
- data/lib/solargraph/pin/while.rb +1 -3
- data/lib/solargraph/pin_cache.rb +71 -488
- data/lib/solargraph/position.rb +38 -17
- data/lib/solargraph/range.rb +10 -9
- data/lib/solargraph/rbs_map/conversions.rb +327 -221
- data/lib/solargraph/rbs_map/core_fills.rb +91 -84
- data/lib/solargraph/rbs_map/stdlib_map.rb +0 -1
- data/lib/solargraph/rbs_map.rb +5 -15
- data/lib/solargraph/server_methods.rb +16 -16
- data/lib/solargraph/shell.rb +224 -66
- data/lib/solargraph/source/chain/array.rb +39 -37
- data/lib/solargraph/source/chain/call.rb +49 -44
- data/lib/solargraph/source/chain/class_variable.rb +13 -13
- data/lib/solargraph/source/chain/constant.rb +3 -1
- data/lib/solargraph/source/chain/global_variable.rb +13 -13
- data/lib/solargraph/source/chain/hash.rb +8 -6
- data/lib/solargraph/source/chain/if.rb +11 -10
- data/lib/solargraph/source/chain/instance_variable.rb +3 -1
- data/lib/solargraph/source/chain/link.rb +99 -109
- data/lib/solargraph/source/chain/literal.rb +4 -6
- data/lib/solargraph/source/chain/or.rb +2 -4
- data/lib/solargraph/source/chain/q_call.rb +13 -11
- data/lib/solargraph/source/chain/variable.rb +15 -13
- data/lib/solargraph/source/chain/z_super.rb +28 -30
- data/lib/solargraph/source/chain.rb +26 -16
- data/lib/solargraph/source/change.rb +3 -3
- data/lib/solargraph/source/cursor.rb +18 -18
- data/lib/solargraph/source/encoding_fixes.rb +6 -7
- data/lib/solargraph/source/source_chainer.rb +46 -32
- data/lib/solargraph/source/updater.rb +1 -1
- data/lib/solargraph/source.rb +27 -29
- data/lib/solargraph/source_map/clip.rb +38 -30
- data/lib/solargraph/source_map/mapper.rb +51 -47
- data/lib/solargraph/source_map.rb +8 -4
- data/lib/solargraph/type_checker/rules.rb +8 -8
- data/lib/solargraph/type_checker.rb +95 -102
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/workspace/config.rb +11 -10
- data/lib/solargraph/workspace/gemspecs.rb +3 -3
- data/lib/solargraph/workspace.rb +45 -165
- data/lib/solargraph/yard_map/helpers.rb +6 -2
- data/lib/solargraph/yard_map/mapper/to_method.rb +8 -6
- data/lib/solargraph/yard_map/mapper/to_namespace.rb +1 -1
- data/lib/solargraph/yard_map/mapper.rb +12 -12
- data/lib/solargraph/yard_map.rb +17 -18
- data/lib/solargraph/yard_tags.rb +20 -20
- data/lib/solargraph/yardoc.rb +26 -33
- data/lib/solargraph.rb +7 -5
- data/solargraph.gemspec +36 -35
- metadata +33 -38
|
@@ -52,26 +52,26 @@ module Solargraph
|
|
|
52
52
|
|
|
53
53
|
# @param inferred [ComplexType, ComplexType::UniqueType]
|
|
54
54
|
# @param expected [ComplexType, ComplexType::UniqueType]
|
|
55
|
-
def return_type_conforms_to?
|
|
55
|
+
def return_type_conforms_to? inferred, expected
|
|
56
56
|
conforms_to?(inferred, expected, :return_type)
|
|
57
57
|
end
|
|
58
58
|
|
|
59
59
|
# @param inferred [ComplexType, ComplexType::UniqueType]
|
|
60
60
|
# @param expected [ComplexType, ComplexType::UniqueType]
|
|
61
|
-
def arg_conforms_to?
|
|
61
|
+
def arg_conforms_to? inferred, expected
|
|
62
62
|
conforms_to?(inferred, expected, :method_call)
|
|
63
63
|
end
|
|
64
64
|
|
|
65
65
|
# @param inferred [ComplexType, ComplexType::UniqueType]
|
|
66
66
|
# @param expected [ComplexType, ComplexType::UniqueType]
|
|
67
|
-
def assignment_conforms_to?
|
|
67
|
+
def assignment_conforms_to? inferred, expected
|
|
68
68
|
conforms_to?(inferred, expected, :assignment)
|
|
69
69
|
end
|
|
70
70
|
|
|
71
71
|
# @param inferred [ComplexType, ComplexType::UniqueType]
|
|
72
72
|
# @param expected [ComplexType, ComplexType::UniqueType]
|
|
73
73
|
# @param scenario [Symbol]
|
|
74
|
-
def conforms_to?
|
|
74
|
+
def conforms_to? inferred, expected, scenario
|
|
75
75
|
rules_arr = []
|
|
76
76
|
rules_arr << :allow_empty_params unless rules.require_inferred_type_params?
|
|
77
77
|
rules_arr << :allow_any_match unless rules.require_all_unique_types_match_expected?
|
|
@@ -86,12 +86,12 @@ module Solargraph
|
|
|
86
86
|
# @return [Array<Problem>]
|
|
87
87
|
def problems
|
|
88
88
|
@problems ||= begin
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
89
|
+
all = method_tag_problems
|
|
90
|
+
.concat(variable_type_tag_problems)
|
|
91
|
+
.concat(const_problems)
|
|
92
|
+
.concat(call_problems)
|
|
93
|
+
unignored = without_ignored(all)
|
|
94
|
+
unignored.concat(unneeded_sgignore_problems)
|
|
95
95
|
end
|
|
96
96
|
end
|
|
97
97
|
|
|
@@ -148,7 +148,10 @@ module Solargraph
|
|
|
148
148
|
if pin.return_type.undefined? && rules.require_type_tags?
|
|
149
149
|
if pin.attribute?
|
|
150
150
|
inferred = pin.probe(api_map).self_to_type(pin.full_context)
|
|
151
|
-
|
|
151
|
+
unless inferred.defined?
|
|
152
|
+
result.push Problem.new(pin.location, "Missing @return tag for #{pin.path}",
|
|
153
|
+
pin: pin)
|
|
154
|
+
end
|
|
152
155
|
else
|
|
153
156
|
result.push Problem.new(pin.location, "Missing @return tag for #{pin.path}", pin: pin)
|
|
154
157
|
end
|
|
@@ -167,7 +170,8 @@ module Solargraph
|
|
|
167
170
|
end
|
|
168
171
|
else
|
|
169
172
|
unless return_type_conforms_to?(inferred, declared)
|
|
170
|
-
result.push Problem.new(pin.location,
|
|
173
|
+
result.push Problem.new(pin.location,
|
|
174
|
+
"Declared return type #{declared.rooted_tags} does not match inferred type #{inferred.rooted_tags} for #{pin.path}", pin: pin)
|
|
171
175
|
end
|
|
172
176
|
end
|
|
173
177
|
end
|
|
@@ -183,7 +187,7 @@ module Solargraph
|
|
|
183
187
|
def resolved_constant? pin
|
|
184
188
|
return true if pin.typify(api_map).defined?
|
|
185
189
|
constant_pins = api_map.get_constants('', *pin.closure.gates)
|
|
186
|
-
|
|
190
|
+
.select { |p| p.name == pin.return_type.namespace }
|
|
187
191
|
return true if constant_pins.find { |p| p.typify(api_map).defined? }
|
|
188
192
|
# will need to probe when a constant name is assigned to a
|
|
189
193
|
# class/module (alias)
|
|
@@ -205,19 +209,19 @@ module Solargraph
|
|
|
205
209
|
pin.signatures.each do |sig|
|
|
206
210
|
params = param_details_from_stack(sig, stack)
|
|
207
211
|
if rules.require_type_tags?
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
result.push Problem.new(pin.location, "Missing @param tag for #{par.name} on #{pin.path}", pin: pin)
|
|
215
|
-
end
|
|
216
|
-
else
|
|
212
|
+
sig.parameters.each do |par|
|
|
213
|
+
break if %i[restarg kwrestarg blockarg].include?(par.decl)
|
|
214
|
+
unless params[par.name]
|
|
215
|
+
if pin.attribute?
|
|
216
|
+
inferred = pin.probe(api_map).self_to_type(pin.full_context)
|
|
217
|
+
if inferred.undefined?
|
|
217
218
|
result.push Problem.new(pin.location, "Missing @param tag for #{par.name} on #{pin.path}", pin: pin)
|
|
218
219
|
end
|
|
220
|
+
else
|
|
221
|
+
result.push Problem.new(pin.location, "Missing @param tag for #{par.name} on #{pin.path}", pin: pin)
|
|
219
222
|
end
|
|
220
223
|
end
|
|
224
|
+
end
|
|
221
225
|
end
|
|
222
226
|
# @param name [String]
|
|
223
227
|
# @param data [Hash{Symbol => BasicObject}]
|
|
@@ -225,7 +229,8 @@ module Solargraph
|
|
|
225
229
|
# @type [ComplexType]
|
|
226
230
|
type = data[:qualified]
|
|
227
231
|
if type.undefined?
|
|
228
|
-
result.push Problem.new(pin.location, "Unresolved type #{data[:tagged]} for #{name} param on #{pin.path}",
|
|
232
|
+
result.push Problem.new(pin.location, "Unresolved type #{data[:tagged]} for #{name} param on #{pin.path}",
|
|
233
|
+
pin: pin)
|
|
229
234
|
end
|
|
230
235
|
end
|
|
231
236
|
end
|
|
@@ -257,20 +262,20 @@ module Solargraph
|
|
|
257
262
|
end
|
|
258
263
|
else
|
|
259
264
|
unless assignment_conforms_to?(inferred, declared)
|
|
260
|
-
result.push Problem.new(pin.location,
|
|
265
|
+
result.push Problem.new(pin.location,
|
|
266
|
+
"Declared type #{declared} does not match inferred type #{inferred} for variable #{pin.name}", pin: pin)
|
|
261
267
|
end
|
|
262
268
|
end
|
|
263
269
|
elsif declared_externally?(pin)
|
|
264
270
|
ignored_pins.push pin
|
|
265
271
|
end
|
|
266
272
|
elsif !pin.is_a?(Pin::Parameter) && !resolved_constant?(pin)
|
|
267
|
-
result.push Problem.new(pin.location, "Unresolved type #{pin.return_type} for variable #{pin.name}",
|
|
273
|
+
result.push Problem.new(pin.location, "Unresolved type #{pin.return_type} for variable #{pin.name}",
|
|
274
|
+
pin: pin)
|
|
268
275
|
end
|
|
269
276
|
elsif pin.assignment
|
|
270
277
|
inferred = pin.probe(api_map)
|
|
271
|
-
if inferred.undefined? && declared_externally?(pin)
|
|
272
|
-
ignored_pins.push pin
|
|
273
|
-
end
|
|
278
|
+
ignored_pins.push pin if inferred.undefined? && declared_externally?(pin)
|
|
274
279
|
end
|
|
275
280
|
end
|
|
276
281
|
result
|
|
@@ -313,7 +318,6 @@ module Solargraph
|
|
|
313
318
|
chain = Solargraph::Parser.chain(call, filename)
|
|
314
319
|
# @sg-ignore Need to add nil check here
|
|
315
320
|
closure_pin = source_map.locate_closure_pin(rng.start.line, rng.start.column)
|
|
316
|
-
namespace_pin = closure_pin
|
|
317
321
|
if call.type == :block
|
|
318
322
|
# blocks in the AST include the method call as well, so the
|
|
319
323
|
# node returned by #call_nodes_from needs to be backed out
|
|
@@ -336,7 +340,6 @@ module Solargraph
|
|
|
336
340
|
found = nil
|
|
337
341
|
# @type [Array<Solargraph::Pin::Base>]
|
|
338
342
|
all_found = []
|
|
339
|
-
closest = ComplexType::UNDEFINED
|
|
340
343
|
until base.links.first.undefined?
|
|
341
344
|
# @sg-ignore Need to add nil check here
|
|
342
345
|
all_found = base.define(api_map, closure_pin, locals)
|
|
@@ -348,16 +351,13 @@ module Solargraph
|
|
|
348
351
|
all_closest = all_found.map { |pin| pin.typify(api_map) }
|
|
349
352
|
closest = ComplexType.new(all_closest.flat_map(&:items).uniq)
|
|
350
353
|
# @todo remove the internal_or_core? check at a higher-than-strict level
|
|
351
|
-
if !found || found.is_a?(Pin::BaseVariable) || (closest.defined? && internal_or_core?(found))
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
else
|
|
357
|
-
result.push Problem.new(location, "Unresolved call to #{missing.links.last.word}")
|
|
358
|
-
end
|
|
359
|
-
@marked_ranges.push rng
|
|
354
|
+
if (!found || found.is_a?(Pin::BaseVariable) || (closest.defined? && internal_or_core?(found))) && !(closest.generic? || ignored_pins.include?(found))
|
|
355
|
+
if closest.defined?
|
|
356
|
+
result.push Problem.new(location, "Unresolved call to #{missing.links.last.word} on #{closest}")
|
|
357
|
+
else
|
|
358
|
+
result.push Problem.new(location, "Unresolved call to #{missing.links.last.word}")
|
|
360
359
|
end
|
|
360
|
+
@marked_ranges.push rng
|
|
361
361
|
end
|
|
362
362
|
end
|
|
363
363
|
# @sg-ignore Need to add nil check here
|
|
@@ -407,7 +407,7 @@ module Solargraph
|
|
|
407
407
|
return [] if !rules.validate_calls? || base.links.first.is_a?(Solargraph::Source::Chain::ZSuper)
|
|
408
408
|
|
|
409
409
|
all_errors = []
|
|
410
|
-
pin.signatures.
|
|
410
|
+
pin.signatures.sort_by { |sig| sig.parameters.length }.each do |sig|
|
|
411
411
|
params = param_details_from_stack(sig, pins)
|
|
412
412
|
|
|
413
413
|
signature_errors = signature_argument_problems_for location, locals, closure_pin, params, arguments, sig, pin
|
|
@@ -431,7 +431,6 @@ module Solargraph
|
|
|
431
431
|
# @param arguments [Array<Source::Chain>]
|
|
432
432
|
# @param sig [Pin::Signature]
|
|
433
433
|
# @param pin [Pin::Method]
|
|
434
|
-
# @param pins [Array<Pin::Method>]
|
|
435
434
|
#
|
|
436
435
|
# @return [Array<Problem>]
|
|
437
436
|
def signature_argument_problems_for location, locals, closure_pin, params, arguments, sig, pin
|
|
@@ -441,31 +440,25 @@ module Solargraph
|
|
|
441
440
|
# when possible, and when not, ensure provably
|
|
442
441
|
# incorrect situations are detected.
|
|
443
442
|
sig.parameters.each_with_index do |par, idx|
|
|
444
|
-
return errors if par.decl == :restarg
|
|
443
|
+
return errors if par.decl == :restarg # bail out and assume the rest is valid pending better arg processing
|
|
445
444
|
argchain = arguments[idx]
|
|
446
445
|
if argchain.nil?
|
|
446
|
+
final_arg = arguments.last
|
|
447
447
|
if par.decl == :arg
|
|
448
|
-
final_arg = arguments.last
|
|
449
448
|
if final_arg && final_arg.node.type == :splat
|
|
450
449
|
argchain = final_arg
|
|
451
450
|
return errors
|
|
452
451
|
else
|
|
453
452
|
errors.push Problem.new(location, "Not enough arguments to #{pin.path}")
|
|
454
453
|
end
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
argchain = final_arg if final_arg && [:kwsplat, :hash].include?(final_arg.node.type)
|
|
454
|
+
elsif final_arg && %i[kwsplat hash].include?(final_arg.node.type)
|
|
455
|
+
argchain = final_arg
|
|
458
456
|
end
|
|
459
457
|
end
|
|
460
458
|
if argchain
|
|
461
|
-
if par.decl
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
else
|
|
465
|
-
if argchain.node.type == :splat && argchain == arguments.last
|
|
466
|
-
final_arg = argchain
|
|
467
|
-
end
|
|
468
|
-
if (final_arg && final_arg.node.type == :splat)
|
|
459
|
+
if par.decl == :arg
|
|
460
|
+
final_arg = argchain if argchain.node.type == :splat && argchain == arguments.last
|
|
461
|
+
if final_arg && final_arg.node.type == :splat
|
|
469
462
|
# The final argument given has been seen and was a
|
|
470
463
|
# splat, which doesn't give us useful types or
|
|
471
464
|
# arities against positional parameters, so let's
|
|
@@ -485,15 +478,19 @@ module Solargraph
|
|
|
485
478
|
ptype = params.key?(par.name) ? params[par.name][:qualified] : ComplexType::UNDEFINED
|
|
486
479
|
ptype = ptype.self_to_type(par.context)
|
|
487
480
|
if ptype.nil?
|
|
488
|
-
|
|
481
|
+
# @todo Some level (strong, I guess) should require the param here
|
|
489
482
|
else
|
|
490
483
|
argtype = argchain.infer(api_map, closure_pin, locals)
|
|
491
484
|
argtype = argtype.self_to_type(closure_pin.context)
|
|
492
485
|
if argtype.defined? && ptype.defined? && !arg_conforms_to?(argtype, ptype)
|
|
493
|
-
errors.push Problem.new(location,
|
|
486
|
+
errors.push Problem.new(location,
|
|
487
|
+
"Wrong argument type for #{pin.path}: #{par.name} expected #{ptype}, received #{argtype}")
|
|
494
488
|
return errors
|
|
495
489
|
end
|
|
496
490
|
end
|
|
491
|
+
else
|
|
492
|
+
errors.concat kwarg_problems_for sig, argchain, api_map, closure_pin, locals, location, pin, params, idx
|
|
493
|
+
next
|
|
497
494
|
end
|
|
498
495
|
elsif par.decl == :kwarg
|
|
499
496
|
errors.push Problem.new(location, "Call to #{pin.path} is missing keyword argument #{par.name}")
|
|
@@ -522,27 +519,26 @@ module Solargraph
|
|
|
522
519
|
argchain = kwargs[par.name.to_sym]
|
|
523
520
|
if par.decl == :kwrestarg || (par.decl == :optarg && idx == pin.parameters.length - 1 && par.asgn_code == '{}')
|
|
524
521
|
result.concat kwrestarg_problems_for(api_map, closure_pin, locals, location, pin, params, kwargs)
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
end
|
|
522
|
+
elsif argchain
|
|
523
|
+
data = params[par.name]
|
|
524
|
+
if data.nil?
|
|
525
|
+
# @todo Some level (strong, I guess) should require the param here
|
|
526
|
+
else
|
|
527
|
+
# @type [ComplexType, ComplexType::UniqueType]
|
|
528
|
+
ptype = data[:qualified]
|
|
529
|
+
ptype = ptype.self_to_type(pin.context)
|
|
530
|
+
unless ptype.undefined?
|
|
531
|
+
# @type [ComplexType]
|
|
532
|
+
argtype = argchain.infer(api_map, closure_pin, locals).self_to_type(closure_pin.context)
|
|
533
|
+
# @todo Unresolved call to defined?
|
|
534
|
+
if argtype.defined? && ptype && !arg_conforms_to?(argtype, ptype)
|
|
535
|
+
result.push Problem.new(location,
|
|
536
|
+
"Wrong argument type for #{pin.path}: #{par.name} expected #{ptype}, received #{argtype}")
|
|
541
537
|
end
|
|
542
538
|
end
|
|
543
|
-
elsif par.decl == :kwarg
|
|
544
|
-
result.push Problem.new(location, "Call to #{pin.path} is missing keyword argument #{par.name}")
|
|
545
539
|
end
|
|
540
|
+
elsif par.decl == :kwarg
|
|
541
|
+
result.push Problem.new(location, "Call to #{pin.path} is missing keyword argument #{par.name}")
|
|
546
542
|
end
|
|
547
543
|
result
|
|
548
544
|
end
|
|
@@ -552,20 +548,22 @@ module Solargraph
|
|
|
552
548
|
# @param locals [Array<Pin::LocalVariable>]
|
|
553
549
|
# @param location [Location]
|
|
554
550
|
# @param pin [Pin::Method]
|
|
555
|
-
# @param params [Hash{String =>
|
|
551
|
+
# @param params [Hash{String => nil, Hash}]
|
|
556
552
|
# @param kwargs [Hash{Symbol => Source::Chain}]
|
|
557
553
|
# @return [Array<Problem>]
|
|
558
|
-
def kwrestarg_problems_for
|
|
554
|
+
def kwrestarg_problems_for api_map, closure_pin, locals, location, pin, params, kwargs
|
|
559
555
|
result = []
|
|
560
556
|
kwargs.each_pair do |pname, argchain|
|
|
561
557
|
next unless params.key?(pname.to_s)
|
|
558
|
+
# @sg-ignore
|
|
562
559
|
# @type [ComplexType]
|
|
563
|
-
|
|
564
|
-
ptype =
|
|
560
|
+
raw_ptype = params[pname.to_s][:qualified]
|
|
561
|
+
ptype = raw_ptype.self_to_type(pin.context)
|
|
565
562
|
argtype = argchain.infer(api_map, closure_pin, locals)
|
|
566
563
|
argtype = argtype.self_to_type(closure_pin.context)
|
|
567
564
|
if argtype.defined? && ptype && !arg_conforms_to?(argtype, ptype)
|
|
568
|
-
result.push Problem.new(location,
|
|
565
|
+
result.push Problem.new(location,
|
|
566
|
+
"Wrong argument type for #{pin.path}: #{pname} expected #{ptype}, received #{argtype}")
|
|
569
567
|
end
|
|
570
568
|
end
|
|
571
569
|
result
|
|
@@ -575,7 +573,7 @@ module Solargraph
|
|
|
575
573
|
# @param pin [Pin::Method, Pin::Signature]
|
|
576
574
|
# @param relevant_pin [Pin::Method, Pin::Signature] the pin which is under inspection
|
|
577
575
|
# @return [void]
|
|
578
|
-
def add_restkwarg_param_tag_details
|
|
576
|
+
def add_restkwarg_param_tag_details param_details, pin, relevant_pin
|
|
579
577
|
# see if we have additional tags to pay attention to from YARD -
|
|
580
578
|
# e.g., kwargs in a **restkwargs splat
|
|
581
579
|
tags = pin.docstring.tags(:param)
|
|
@@ -596,7 +594,7 @@ module Solargraph
|
|
|
596
594
|
|
|
597
595
|
# @param pin [Pin::Signature]
|
|
598
596
|
# @return [Hash{String => Hash{Symbol => String, ComplexType}}]
|
|
599
|
-
def signature_param_details
|
|
597
|
+
def signature_param_details pin
|
|
600
598
|
# @type [Hash{String => Hash{Symbol => String, ComplexType}}]
|
|
601
599
|
result = {}
|
|
602
600
|
pin.parameters.each do |param|
|
|
@@ -630,7 +628,7 @@ module Solargraph
|
|
|
630
628
|
# @param new_param_details [Hash{String => Hash{Symbol => String, ComplexType}}]
|
|
631
629
|
#
|
|
632
630
|
# @return [void]
|
|
633
|
-
def add_to_param_details
|
|
631
|
+
def add_to_param_details param_details, param_names, new_param_details
|
|
634
632
|
new_param_details.each do |param_name, details|
|
|
635
633
|
next unless param_names.include?(param_name)
|
|
636
634
|
|
|
@@ -643,7 +641,7 @@ module Solargraph
|
|
|
643
641
|
# @param signature [Pin::Signature]
|
|
644
642
|
# @param method_pin_stack [Array<Pin::Method>]
|
|
645
643
|
# @return [Hash{String => Hash{Symbol => String, ComplexType}}]
|
|
646
|
-
def param_details_from_stack
|
|
644
|
+
def param_details_from_stack signature, method_pin_stack
|
|
647
645
|
signature_type = signature.typify(api_map)
|
|
648
646
|
signature = signature.proxy signature_type
|
|
649
647
|
param_details = signature_param_details(signature)
|
|
@@ -683,7 +681,7 @@ module Solargraph
|
|
|
683
681
|
|
|
684
682
|
# @param pin [Pin::BaseVariable]
|
|
685
683
|
def declared_externally? pin
|
|
686
|
-
raise
|
|
684
|
+
raise 'No assignment found' if pin.assignment.nil?
|
|
687
685
|
|
|
688
686
|
chain = Solargraph::Parser.chain(pin.assignment, filename)
|
|
689
687
|
# @sg-ignore flow sensitive typing needs to handle attrs
|
|
@@ -696,24 +694,19 @@ module Solargraph
|
|
|
696
694
|
type = chain.infer(api_map, closure_pin, locals)
|
|
697
695
|
if type.undefined? && !rules.ignore_all_undefined?
|
|
698
696
|
base = chain
|
|
699
|
-
missing = chain
|
|
700
697
|
# @type [Solargraph::Pin::Base, nil]
|
|
701
698
|
found = nil
|
|
702
699
|
# @type [Array<Solargraph::Pin::Base>]
|
|
703
700
|
all_found = []
|
|
704
|
-
closest = ComplexType::UNDEFINED
|
|
705
701
|
until base.links.first.undefined?
|
|
706
702
|
all_found = base.define(api_map, closure_pin, locals)
|
|
707
703
|
found = all_found.first
|
|
708
704
|
break if found
|
|
709
|
-
missing = base
|
|
710
705
|
base = base.base
|
|
711
706
|
end
|
|
712
707
|
all_closest = all_found.map { |pin| pin.typify(api_map) }
|
|
713
708
|
closest = ComplexType.new(all_closest.flat_map(&:items).uniq)
|
|
714
|
-
if !found || closest.defined? || internal?(found)
|
|
715
|
-
return false
|
|
716
|
-
end
|
|
709
|
+
return false if !found || closest.defined? || internal?(found)
|
|
717
710
|
end
|
|
718
711
|
true
|
|
719
712
|
end
|
|
@@ -736,7 +729,7 @@ module Solargraph
|
|
|
736
729
|
# @param arguments [Array<Source::Chain>]
|
|
737
730
|
# @param location [Location]
|
|
738
731
|
# @return [Array<Problem>]
|
|
739
|
-
def parameterized_arity_problems_for
|
|
732
|
+
def parameterized_arity_problems_for pin, parameters, arguments, location
|
|
740
733
|
return [] unless pin.explicit?
|
|
741
734
|
return [] if parameters.empty? && arguments.empty?
|
|
742
735
|
return [] if pin.anon_splat?
|
|
@@ -751,7 +744,7 @@ module Solargraph
|
|
|
751
744
|
settled_kwargs = parameters.count(&:keyword?)
|
|
752
745
|
else
|
|
753
746
|
kwargs = convert_hash(unchecked.last.node)
|
|
754
|
-
if parameters.any? { |param| [
|
|
747
|
+
if parameters.any? { |param| %i[kwarg kwoptarg].include?(param.decl) || param.kwrestarg? }
|
|
755
748
|
if kwargs.empty?
|
|
756
749
|
add_params += 1
|
|
757
750
|
else
|
|
@@ -780,10 +773,12 @@ module Solargraph
|
|
|
780
773
|
return [] if parameters.any?(&:rest?)
|
|
781
774
|
opt = optional_param_count(parameters)
|
|
782
775
|
return [] if unchecked.length <= req + opt
|
|
783
|
-
if req + add_params + 1 == unchecked.length && any_splatted_call?(unchecked.map(&:node)) && (parameters.map(&:decl) & [
|
|
776
|
+
if req + add_params + 1 == unchecked.length && any_splatted_call?(unchecked.map(&:node)) && (parameters.map(&:decl) & %i[
|
|
777
|
+
kwarg kwoptarg kwrestarg
|
|
778
|
+
]).any?
|
|
784
779
|
return []
|
|
785
780
|
end
|
|
786
|
-
return [] if arguments.length - req == parameters.select { |p| [
|
|
781
|
+
return [] if arguments.length - req == parameters.select { |p| %i[optarg kwoptarg].include?(p.decl) }.length
|
|
787
782
|
return [Problem.new(location, "Too many arguments to #{pin.path}")]
|
|
788
783
|
elsif unchecked.length < req - settled_kwargs && (arguments.empty? || (!arguments.last.splat? && !arguments.last.links.last.is_a?(Solargraph::Source::Chain::Hash)))
|
|
789
784
|
# HACK: Kernel#raise signature is incorrect in Ruby 2.7 core docs.
|
|
@@ -799,35 +794,33 @@ module Solargraph
|
|
|
799
794
|
# @todo need to use generic types in method to choose correct
|
|
800
795
|
# signature and generate Integer as return type
|
|
801
796
|
# @return [Integer]
|
|
802
|
-
def required_param_count
|
|
797
|
+
def required_param_count parameters
|
|
803
798
|
parameters.sum { |param| %i[arg kwarg].include?(param.decl) ? 1 : 0 }
|
|
804
799
|
end
|
|
805
800
|
|
|
806
801
|
# @param parameters [Enumerable<Pin::Parameter>]
|
|
807
|
-
#
|
|
802
|
+
#
|
|
808
803
|
# @return [Integer]
|
|
809
|
-
def optional_param_count
|
|
804
|
+
def optional_param_count parameters
|
|
810
805
|
parameters.select { |p| p.decl == :optarg }.length
|
|
811
806
|
end
|
|
812
807
|
|
|
813
808
|
# @param pin [Pin::Method]
|
|
814
|
-
# @sg-ignore need boolish support for ? methods
|
|
815
809
|
def abstract? pin
|
|
816
810
|
pin.docstring.has_tag?('abstract') ||
|
|
817
|
-
|
|
818
|
-
(pin.closure && pin.closure.docstring.has_tag?('abstract'))
|
|
811
|
+
pin.closure&.docstring&.has_tag?('abstract')
|
|
819
812
|
end
|
|
820
813
|
|
|
821
814
|
# @param pin [Pin::Method]
|
|
822
815
|
# @return [Array<Source::Chain>]
|
|
823
|
-
def fake_args_for
|
|
816
|
+
def fake_args_for pin
|
|
824
817
|
args = []
|
|
825
818
|
with_opts = false
|
|
826
819
|
with_block = false
|
|
827
820
|
# @param pin [Pin::Parameter]
|
|
828
821
|
pin.parameters.each do |pin|
|
|
829
822
|
# @sg-ignore flow sensitive typing should be able to handle redefinition
|
|
830
|
-
if [
|
|
823
|
+
if %i[kwarg kwoptarg kwrestarg].include?(pin.decl)
|
|
831
824
|
with_opts = true
|
|
832
825
|
# @sg-ignore flow sensitive typing should be able to handle redefinition
|
|
833
826
|
elsif pin.decl == :block
|
data/lib/solargraph/version.rb
CHANGED
|
@@ -54,7 +54,9 @@ module Solargraph
|
|
|
54
54
|
#
|
|
55
55
|
# @return [Array<String>]
|
|
56
56
|
def calculated
|
|
57
|
-
|
|
57
|
+
unless @calculated || directory.empty? || directory == '*'
|
|
58
|
+
Solargraph.logger.info "Indexing workspace files in #{directory}"
|
|
59
|
+
end
|
|
58
60
|
@calculated ||= included - excluded
|
|
59
61
|
end
|
|
60
62
|
|
|
@@ -146,7 +148,7 @@ module Solargraph
|
|
|
146
148
|
global_config = read_config(global_config_path)
|
|
147
149
|
|
|
148
150
|
defaults = default_config
|
|
149
|
-
defaults.merge({'exclude' => []}) unless workspace_config.nil?
|
|
151
|
+
defaults.merge({ 'exclude' => [] }) unless workspace_config.nil?
|
|
150
152
|
|
|
151
153
|
defaults
|
|
152
154
|
.merge(global_config || {})
|
|
@@ -160,13 +162,13 @@ module Solargraph
|
|
|
160
162
|
def read_config config_path = ''
|
|
161
163
|
return nil if config_path.empty?
|
|
162
164
|
return nil unless File.file?(config_path)
|
|
163
|
-
YAML.
|
|
165
|
+
YAML.safe_load_file(config_path)
|
|
164
166
|
end
|
|
165
167
|
|
|
166
168
|
# @return [Hash{String => Array, Hash, Integer}]
|
|
167
169
|
def default_config
|
|
168
170
|
{
|
|
169
|
-
'include' => ['Rakefile', 'Gemfile', '*.gemspec', '
|
|
171
|
+
'include' => ['Rakefile', 'Gemfile', '*.gemspec', './**/*.rb'],
|
|
170
172
|
'exclude' => ['spec/**/*', 'test/**/*', 'vendor/**/*', '.bundle/**/*'],
|
|
171
173
|
'require' => [],
|
|
172
174
|
'domains' => [],
|
|
@@ -176,11 +178,11 @@ module Solargraph
|
|
|
176
178
|
'cops' => 'safe',
|
|
177
179
|
'except' => [],
|
|
178
180
|
'only' => [],
|
|
179
|
-
'extra_args' =>[]
|
|
181
|
+
'extra_args' => []
|
|
180
182
|
}
|
|
181
183
|
},
|
|
182
184
|
'type_checker' => {
|
|
183
|
-
'rules' => {
|
|
185
|
+
'rules' => {}
|
|
184
186
|
},
|
|
185
187
|
'require_paths' => [],
|
|
186
188
|
'plugins' => [],
|
|
@@ -193,12 +195,11 @@ module Solargraph
|
|
|
193
195
|
# @param globs [Array<String>]
|
|
194
196
|
# @return [Array<String>]
|
|
195
197
|
def process_globs globs
|
|
196
|
-
|
|
198
|
+
globs.flat_map do |glob|
|
|
197
199
|
Dir[File.absolute_path(glob, directory)]
|
|
198
|
-
.map{ |f| f.gsub(
|
|
200
|
+
.map { |f| f.gsub('\\', '/') }
|
|
199
201
|
.select { |f| File.file?(f) }
|
|
200
202
|
end
|
|
201
|
-
result
|
|
202
203
|
end
|
|
203
204
|
|
|
204
205
|
# Modify the included files based on excluded directories and get an
|
|
@@ -241,7 +242,7 @@ module Solargraph
|
|
|
241
242
|
# @param glob [String]
|
|
242
243
|
# @return [String]
|
|
243
244
|
def glob_to_directory glob
|
|
244
|
-
glob.gsub(
|
|
245
|
+
glob.gsub(%r{(/\*|/\*\*/\*\*?)$}, '')
|
|
245
246
|
end
|
|
246
247
|
|
|
247
248
|
# @return [Array<String>]
|
|
@@ -117,7 +117,7 @@ module Solargraph
|
|
|
117
117
|
#
|
|
118
118
|
# @return [Array<Gem::Specification>]
|
|
119
119
|
def fetch_dependencies gemspec, out: $stderr
|
|
120
|
-
|
|
120
|
+
all_gemspecs_from_bundle
|
|
121
121
|
|
|
122
122
|
# @type [Hash{String => Gem::Specification}]
|
|
123
123
|
deps_so_far = {}
|
|
@@ -190,7 +190,7 @@ module Solargraph
|
|
|
190
190
|
end
|
|
191
191
|
# @sg-ignore Unresolved constant Gem::StubSpecification
|
|
192
192
|
when Gem::StubSpecification
|
|
193
|
-
# @sg-ignore
|
|
193
|
+
# @sg-ignore Unresolved call to to_spec on Gem::Specification, Bundler::LazySpecification, Bundler::StubSpecification
|
|
194
194
|
specish.to_spec
|
|
195
195
|
else
|
|
196
196
|
raise "Unexpected type while resolving gem: #{specish.class}"
|
|
@@ -313,7 +313,7 @@ module Solargraph
|
|
|
313
313
|
end
|
|
314
314
|
end
|
|
315
315
|
|
|
316
|
-
# @sg-ignore
|
|
316
|
+
# @sg-ignore return type could not be inferred
|
|
317
317
|
# @return [Array<Gem::Specification>]
|
|
318
318
|
def all_gemspecs_from_external_bundle
|
|
319
319
|
@all_gemspecs_from_external_bundle ||=
|