solargraph 0.47.2 → 0.50.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/FUNDING.yml +1 -0
- data/.github/workflows/rspec.yml +1 -1
- data/CHANGELOG.md +40 -0
- data/LICENSE +1 -1
- data/README.md +9 -3
- data/SPONSORS.md +4 -4
- data/lib/solargraph/api_map/store.rb +13 -1
- data/lib/solargraph/api_map.rb +30 -12
- data/lib/solargraph/cache.rb +53 -0
- data/lib/solargraph/complex_type/type_methods.rb +10 -6
- data/lib/solargraph/complex_type/unique_type.rb +57 -0
- data/lib/solargraph/complex_type.rb +32 -3
- data/lib/solargraph/convention/rakefile.rb +17 -0
- data/lib/solargraph/convention.rb +2 -0
- data/lib/solargraph/diagnostics/rubocop.rb +17 -3
- data/lib/solargraph/diagnostics/rubocop_helpers.rb +3 -1
- data/lib/solargraph/language_server/host/cataloger.rb +1 -1
- data/lib/solargraph/language_server/host.rb +22 -18
- data/lib/solargraph/language_server/message/extended/download_core.rb +1 -5
- data/lib/solargraph/language_server/message/initialize.rb +2 -0
- data/lib/solargraph/language_server/message/text_document/formatting.rb +1 -1
- data/lib/solargraph/language_server/message/text_document/signature_help.rb +1 -6
- data/lib/solargraph/language_server/message/workspace/did_change_watched_files.rb +10 -3
- data/lib/solargraph/library.rb +25 -20
- data/lib/solargraph/parser/legacy/node_processors/casgn_node.rb +12 -2
- data/lib/solargraph/parser/legacy/node_processors/sclass_node.rb +24 -3
- data/lib/solargraph/parser/rubyvm/class_methods.rb +6 -1
- data/lib/solargraph/parser/rubyvm/node_processors/casgn_node.rb +13 -2
- data/lib/solargraph/parser/rubyvm/node_processors/def_node.rb +20 -8
- data/lib/solargraph/parser/rubyvm/node_processors/defs_node.rb +14 -3
- data/lib/solargraph/parser/rubyvm/node_processors/sclass_node.rb +14 -3
- data/lib/solargraph/parser/rubyvm/node_processors/send_node.rb +4 -2
- data/lib/solargraph/parser/rubyvm/node_wrapper.rb +47 -0
- data/lib/solargraph/pin/base.rb +5 -2
- data/lib/solargraph/pin/base_variable.rb +1 -1
- data/lib/solargraph/pin/conversions.rb +2 -6
- data/lib/solargraph/pin/method.rb +100 -10
- data/lib/solargraph/pin/namespace.rb +4 -1
- data/lib/solargraph/pin/parameter.rb +8 -3
- data/lib/solargraph/pin/signature.rb +23 -0
- data/lib/solargraph/pin.rb +1 -0
- data/lib/solargraph/rbs_map/conversions.rb +394 -0
- data/lib/solargraph/rbs_map/core_fills.rb +61 -0
- data/lib/solargraph/rbs_map/core_map.rb +38 -0
- data/lib/solargraph/rbs_map/core_signs.rb +33 -0
- data/lib/solargraph/rbs_map/stdlib_map.rb +36 -0
- data/lib/solargraph/rbs_map.rb +73 -0
- data/lib/solargraph/shell.rb +50 -32
- data/lib/solargraph/source/chain/call.rb +35 -24
- data/lib/solargraph/source/chain.rb +22 -7
- data/lib/solargraph/source_map/clip.rb +5 -0
- data/lib/solargraph/source_map/mapper.rb +8 -4
- data/lib/solargraph/type_checker.rb +71 -65
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/views/environment.erb +2 -2
- data/lib/solargraph/workspace.rb +11 -14
- data/lib/solargraph/yard_map/mapper/to_method.rb +7 -4
- data/lib/solargraph/yard_map.rb +35 -194
- data/lib/solargraph.rb +2 -2
- data/solargraph.gemspec +11 -6
- metadata +46 -37
- data/.travis.yml +0 -19
- data/lib/solargraph/compat.rb +0 -37
- data/lib/solargraph/yard_map/core_docs.rb +0 -170
- data/lib/solargraph/yard_map/core_fills.rb +0 -208
- data/lib/solargraph/yard_map/core_gen.rb +0 -76
- data/lib/solargraph/yard_map/rdoc_to_yard.rb +0 -140
- data/lib/solargraph/yard_map/stdlib_fills.rb +0 -43
- data/yardoc/2.2.2.tar.gz +0 -0
@@ -120,12 +120,10 @@ module Solargraph
|
|
120
120
|
# @param pin [Pin::Base]
|
121
121
|
# @return [Boolean]
|
122
122
|
def resolved_constant? pin
|
123
|
-
|
123
|
+
return true if pin.typify(api_map).defined?
|
124
|
+
api_map.get_constants('', *pin.closure.gates)
|
124
125
|
.select { |p| p.name == pin.return_type.namespace }
|
125
|
-
.any?
|
126
|
-
inferred = p.infer(api_map)
|
127
|
-
['Class', 'Module'].include?(inferred.name)
|
128
|
-
end
|
126
|
+
.any? { |p| p.infer(api_map).defined? }
|
129
127
|
end
|
130
128
|
|
131
129
|
def virtual_pin? pin
|
@@ -139,10 +137,12 @@ module Solargraph
|
|
139
137
|
params = first_param_hash(stack)
|
140
138
|
result = []
|
141
139
|
if rules.require_type_tags?
|
142
|
-
pin.
|
143
|
-
|
144
|
-
|
145
|
-
|
140
|
+
pin.signatures.each do |sig|
|
141
|
+
sig.parameters.each do |par|
|
142
|
+
break if par.decl == :restarg || par.decl == :kwrestarg || par.decl == :blockarg
|
143
|
+
unless params[par.name]
|
144
|
+
result.push Problem.new(pin.location, "Missing @param tag for #{par.name} on #{pin.path}", pin: pin)
|
145
|
+
end
|
146
146
|
end
|
147
147
|
end
|
148
148
|
end
|
@@ -184,7 +184,7 @@ module Solargraph
|
|
184
184
|
elsif declared_externally?(pin)
|
185
185
|
ignored_pins.push pin
|
186
186
|
end
|
187
|
-
elsif !pin.is_a?(Pin::Parameter)
|
187
|
+
elsif !pin.is_a?(Pin::Parameter) && !resolved_constant?(pin)
|
188
188
|
result.push Problem.new(pin.location, "Unresolved type #{pin.return_type} for variable #{pin.name}", pin: pin)
|
189
189
|
end
|
190
190
|
else
|
@@ -243,7 +243,7 @@ module Solargraph
|
|
243
243
|
end
|
244
244
|
closest = found.typify(api_map) if found
|
245
245
|
if !found || found.is_a?(Pin::BaseVariable) || (closest.defined? && internal_or_core?(found))
|
246
|
-
unless ignored_pins.include?(found)
|
246
|
+
unless closest.parameterized? || ignored_pins.include?(found)
|
247
247
|
result.push Problem.new(location, "Unresolved call to #{missing.links.last.word}")
|
248
248
|
@marked_ranges.push rng
|
249
249
|
end
|
@@ -273,34 +273,44 @@ module Solargraph
|
|
273
273
|
end
|
274
274
|
break unless rules.validate_calls?
|
275
275
|
params = first_param_hash(pins)
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
276
|
+
|
277
|
+
all_errors = []
|
278
|
+
pin.signatures.sort { |sig| sig.parameters.length }.each do |sig|
|
279
|
+
errors = []
|
280
|
+
sig.parameters.each_with_index do |par, idx|
|
281
|
+
argchain = base.links.last.arguments[idx]
|
282
|
+
if argchain.nil? && par.decl == :arg
|
283
|
+
errors.push Problem.new(location, "Not enough arguments to #{pin.path}")
|
284
|
+
next
|
285
|
+
end
|
286
|
+
if argchain
|
287
|
+
if par.decl != :arg
|
288
|
+
errors.concat kwarg_problems_for argchain, api_map, block_pin, locals, location, pin, params, idx
|
289
|
+
next
|
290
290
|
else
|
291
|
-
|
292
|
-
if
|
293
|
-
|
291
|
+
ptype = params.key?(par.name) ? params[par.name][:qualified] : ComplexType::UNDEFINED
|
292
|
+
if ptype.nil?
|
293
|
+
# @todo Some level (strong, I guess) should require the param here
|
294
|
+
else
|
295
|
+
argtype = argchain.infer(api_map, block_pin, locals)
|
296
|
+
if argtype.defined? && ptype.defined? && !any_types_match?(api_map, ptype, argtype)
|
297
|
+
errors.push Problem.new(location, "Wrong argument type for #{pin.path}: #{par.name} expected #{ptype}, received #{argtype}")
|
298
|
+
next
|
299
|
+
end
|
294
300
|
end
|
295
301
|
end
|
302
|
+
elsif par.decl == :kwarg
|
303
|
+
errors.push Problem.new(location, "Call to #{pin.path} is missing keyword argument #{par.name}")
|
304
|
+
next
|
296
305
|
end
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
result.push Problem.new(location, "Call to #{pin.path} is missing keyword argument #{par.name}")
|
306
|
+
end
|
307
|
+
if errors.empty?
|
308
|
+
all_errors.clear
|
301
309
|
break
|
302
310
|
end
|
311
|
+
all_errors.concat errors
|
303
312
|
end
|
313
|
+
result.concat all_errors
|
304
314
|
end
|
305
315
|
base = base.base
|
306
316
|
end
|
@@ -310,7 +320,7 @@ module Solargraph
|
|
310
320
|
def kwarg_problems_for argchain, api_map, block_pin, locals, location, pin, params, first
|
311
321
|
result = []
|
312
322
|
kwargs = convert_hash(argchain.node)
|
313
|
-
pin.parameters[first..-1].each_with_index do |par, cur|
|
323
|
+
pin.signatures.first.parameters[first..-1].each_with_index do |par, cur|
|
314
324
|
idx = first + cur
|
315
325
|
argchain = kwargs[par.name.to_sym]
|
316
326
|
if par.decl == :kwrestarg || (par.decl == :optarg && idx == pin.parameters.length - 1 && par.asgn_code == '{}')
|
@@ -381,8 +391,10 @@ module Solargraph
|
|
381
391
|
pin.location && api_map.bundled?(pin.location.filename)
|
382
392
|
end
|
383
393
|
|
394
|
+
# True if the pin is either internal (part of the workspace) or from the core/stdlib
|
384
395
|
def internal_or_core? pin
|
385
|
-
|
396
|
+
# @todo RBS pins are not necessarily core/stdlib pins
|
397
|
+
internal?(pin) || pin.source == :rbs
|
386
398
|
end
|
387
399
|
|
388
400
|
# @param pin [Pin::Base]
|
@@ -417,20 +429,20 @@ module Solargraph
|
|
417
429
|
true
|
418
430
|
end
|
419
431
|
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
432
|
+
def arity_problems_for pin, arguments, location
|
433
|
+
results = pin.signatures.map do |sig|
|
434
|
+
r = parameterized_arity_problems_for(pin, sig.parameters, arguments, location)
|
435
|
+
return [] if r.empty?
|
436
|
+
r
|
437
|
+
end
|
438
|
+
results.first
|
427
439
|
end
|
428
440
|
|
429
|
-
|
430
|
-
def pin_arity_problems_for(pin, arguments, location)
|
441
|
+
def parameterized_arity_problems_for(pin, parameters, arguments, location)
|
431
442
|
return [] unless pin.explicit?
|
432
|
-
return [] if
|
433
|
-
if pin.
|
443
|
+
return [] if parameters.empty? && arguments.empty?
|
444
|
+
return [] if pin.anon_splat?
|
445
|
+
if parameters.empty?
|
434
446
|
# Functions tagged param_tuple accepts two arguments (e.g., Hash#[]=)
|
435
447
|
return [] if pin.docstring.tag(:param_tuple) && arguments.length == 2
|
436
448
|
return [] if arguments.length == 1 && arguments.last.links.last.is_a?(Source::Chain::BlockVariable)
|
@@ -438,21 +450,21 @@ module Solargraph
|
|
438
450
|
end
|
439
451
|
unchecked = arguments.clone
|
440
452
|
add_params = 0
|
441
|
-
if unchecked.empty? &&
|
453
|
+
if unchecked.empty? && parameters.any? { |param| param.decl == :kwarg }
|
442
454
|
return [Problem.new(location, "Missing keyword arguments to #{pin.path}")]
|
443
455
|
end
|
444
456
|
settled_kwargs = 0
|
445
457
|
unless unchecked.empty?
|
446
458
|
if any_splatted_call?(unchecked.map(&:node))
|
447
|
-
settled_kwargs =
|
459
|
+
settled_kwargs = parameters.count(&:keyword?)
|
448
460
|
else
|
449
461
|
kwargs = convert_hash(unchecked.last.node)
|
450
|
-
if
|
462
|
+
if parameters.any? { |param| [:kwarg, :kwoptarg].include?(param.decl) || param.kwrestarg? }
|
451
463
|
if kwargs.empty?
|
452
464
|
add_params += 1
|
453
465
|
else
|
454
466
|
unchecked.pop
|
455
|
-
|
467
|
+
parameters.each do |param|
|
456
468
|
next unless param.keyword?
|
457
469
|
if kwargs.key?(param.name.to_sym)
|
458
470
|
kwargs.delete param.name.to_sym
|
@@ -462,7 +474,7 @@ module Solargraph
|
|
462
474
|
return [Problem.new(location, "Missing keyword argument #{param.name} to #{pin.path}")]
|
463
475
|
end
|
464
476
|
end
|
465
|
-
kwargs.clear if
|
477
|
+
kwargs.clear if parameters.any?(&:kwrestarg?)
|
466
478
|
unless kwargs.empty?
|
467
479
|
return [Problem.new(location, "Unrecognized keyword argument #{kwargs.keys.first} to #{pin.path}")]
|
468
480
|
end
|
@@ -470,18 +482,18 @@ module Solargraph
|
|
470
482
|
end
|
471
483
|
end
|
472
484
|
end
|
473
|
-
req = required_param_count(
|
485
|
+
req = required_param_count(parameters)
|
474
486
|
if req + add_params < unchecked.length
|
475
|
-
return [] if
|
476
|
-
opt = optional_param_count(
|
487
|
+
return [] if parameters.any?(&:rest?)
|
488
|
+
opt = optional_param_count(parameters)
|
477
489
|
return [] if unchecked.length <= req + opt
|
478
490
|
if unchecked.length == req + opt + 1 && unchecked.last.links.last.is_a?(Source::Chain::BlockVariable)
|
479
491
|
return []
|
480
492
|
end
|
481
|
-
if req + add_params + 1 == unchecked.length && any_splatted_call?(unchecked.map(&:node)) && (
|
493
|
+
if req + add_params + 1 == unchecked.length && any_splatted_call?(unchecked.map(&:node)) && (parameters.map(&:decl) & [:kwarg, :kwoptarg, :kwrestarg]).any?
|
482
494
|
return []
|
483
495
|
end
|
484
|
-
return [] if arguments.length - req ==
|
496
|
+
return [] if arguments.length - req == parameters.select { |p| [:optarg, :kwoptarg].include?(p.decl) }.length
|
485
497
|
return [Problem.new(location, "Too many arguments to #{pin.path}")]
|
486
498
|
elsif unchecked.length < req - settled_kwargs && (arguments.empty? || (!arguments.last.splat? && !arguments.last.links.last.is_a?(Solargraph::Source::Chain::Hash)))
|
487
499
|
# HACK: Kernel#raise signature is incorrect in Ruby 2.7 core docs.
|
@@ -493,19 +505,13 @@ module Solargraph
|
|
493
505
|
[]
|
494
506
|
end
|
495
507
|
|
496
|
-
|
497
|
-
|
498
|
-
pin.parameters.sum { |param| %i[arg kwarg].include?(param.decl) ? 1 : 0 }
|
508
|
+
def required_param_count(parameters)
|
509
|
+
parameters.sum { |param| %i[arg kwarg].include?(param.decl) ? 1 : 0 }
|
499
510
|
end
|
500
511
|
|
501
512
|
# @param pin [Pin::Method]
|
502
|
-
def optional_param_count(
|
503
|
-
|
504
|
-
pin.parameters.each do |param|
|
505
|
-
next unless param.decl == :optarg
|
506
|
-
count += 1
|
507
|
-
end
|
508
|
-
count
|
513
|
+
def optional_param_count(parameters)
|
514
|
+
parameters.select { |p| p.decl == :optarg }.length
|
509
515
|
end
|
510
516
|
|
511
517
|
def abstract? pin
|
data/lib/solargraph/version.rb
CHANGED
@@ -30,10 +30,10 @@
|
|
30
30
|
Solargraph Version: <%= Solargraph::VERSION %>
|
31
31
|
</li>
|
32
32
|
<li>
|
33
|
-
Core Documentation Version:
|
33
|
+
Core Documentation Version: N/A <%# @todo Fix %>
|
34
34
|
</li>
|
35
35
|
<li>
|
36
|
-
Core Cache Directory:
|
36
|
+
Core Cache Directory: N/A <%# @todo Fix %>
|
37
37
|
</li>
|
38
38
|
<% unless Solargraph::Parser.rubyvm? %>
|
39
39
|
<li>
|
data/lib/solargraph/workspace.rb
CHANGED
@@ -46,24 +46,21 @@ module Solargraph
|
|
46
46
|
#
|
47
47
|
# @param source [Solargraph::Source]
|
48
48
|
# @return [Boolean] True if the source was added to the workspace
|
49
|
-
def merge
|
50
|
-
unless directory == '*' || source_hash.key?(source.filename)
|
49
|
+
def merge *sources
|
50
|
+
unless directory == '*' || sources.all? { |source| source_hash.key?(source.filename) }
|
51
51
|
# Reload the config to determine if a new source should be included
|
52
52
|
@config = Solargraph::Workspace::Config.new(directory)
|
53
|
-
return false unless config.calculated.include?(source.filename)
|
54
53
|
end
|
55
|
-
source_hash[source.filename] = source
|
56
|
-
true
|
57
|
-
end
|
58
54
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
55
|
+
includes_any = false
|
56
|
+
sources.each do |source|
|
57
|
+
if directory == "*" || config.calculated.include?(source.filename)
|
58
|
+
source_hash[source.filename] = source
|
59
|
+
includes_any = true
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
includes_any
|
67
64
|
end
|
68
65
|
|
69
66
|
# Remove a source from the workspace. The source will not be removed if
|
@@ -13,16 +13,19 @@ module Solargraph
|
|
13
13
|
)
|
14
14
|
location = object_location(code_object, spec)
|
15
15
|
comments = code_object.docstring ? code_object.docstring.all.to_s : ''
|
16
|
-
Pin::Method.new(
|
16
|
+
pin = Pin::Method.new(
|
17
17
|
location: location,
|
18
18
|
closure: closure,
|
19
19
|
name: name || code_object.name.to_s,
|
20
20
|
comments: comments,
|
21
21
|
scope: scope || code_object.scope,
|
22
22
|
visibility: visibility || code_object.visibility,
|
23
|
-
|
23
|
+
# @todo Might need to convert overloads to signatures
|
24
|
+
parameters: [],
|
24
25
|
explicit: code_object.is_explicit?
|
25
26
|
)
|
27
|
+
pin.parameters.concat get_parameters(code_object, location, comments, pin)
|
28
|
+
pin
|
26
29
|
end
|
27
30
|
|
28
31
|
class << self
|
@@ -30,7 +33,7 @@ module Solargraph
|
|
30
33
|
|
31
34
|
# @param code_object [YARD::CodeObjects::Base]
|
32
35
|
# @return [Array<Solargraph::Pin::Parameter>]
|
33
|
-
def get_parameters code_object, location, comments
|
36
|
+
def get_parameters code_object, location, comments, pin
|
34
37
|
return [] unless code_object.is_a?(YARD::CodeObjects::MethodObject)
|
35
38
|
# HACK: Skip `nil` and `self` parameters that are sometimes emitted
|
36
39
|
# for methods defined in C
|
@@ -38,7 +41,7 @@ module Solargraph
|
|
38
41
|
code_object.parameters.select { |a| a[0] && a[0] != 'self' }.map do |a|
|
39
42
|
Solargraph::Pin::Parameter.new(
|
40
43
|
location: location,
|
41
|
-
closure:
|
44
|
+
closure: pin,
|
42
45
|
comments: comments,
|
43
46
|
name: arg_name(a),
|
44
47
|
presence: nil,
|