solargraph 0.39.0 → 0.40.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/.travis.yml +2 -7
- data/CHANGELOG.md +984 -0
- data/Rakefile +12 -1
- data/SPONSORS.md +6 -0
- data/lib/.rubocop.yml +21 -0
- data/lib/solargraph/api_map/cache.rb +4 -0
- data/lib/solargraph/api_map/store.rb +35 -51
- data/lib/solargraph/api_map.rb +94 -87
- data/lib/solargraph/{bundle.rb → bench.rb} +6 -2
- data/lib/solargraph/compat.rb +23 -0
- data/lib/solargraph/complex_type.rb +2 -2
- data/lib/solargraph/convention/base.rb +16 -8
- data/lib/solargraph/convention/gemfile.rb +2 -5
- data/lib/solargraph/convention/gemspec.rb +3 -6
- data/lib/solargraph/convention/rspec.rb +3 -6
- data/lib/solargraph/convention.rb +14 -5
- data/lib/solargraph/diagnostics/rubocop.rb +2 -1
- data/lib/solargraph/diagnostics/rubocop_helpers.rb +4 -1
- data/lib/solargraph/documentor.rb +4 -0
- data/lib/solargraph/environ.rb +11 -6
- data/lib/solargraph/language_server/host.rb +1 -1
- data/lib/solargraph/language_server/message/extended/check_gem_version.rb +6 -1
- data/lib/solargraph/language_server/message/text_document/definition.rb +1 -1
- data/lib/solargraph/language_server/message/text_document/formatting.rb +7 -3
- data/lib/solargraph/language_server/uri_helpers.rb +23 -3
- data/lib/solargraph/library.rb +22 -8
- data/lib/solargraph/parser/legacy/class_methods.rb +4 -0
- data/lib/solargraph/parser/legacy/node_chainer.rb +10 -7
- data/lib/solargraph/parser/legacy/node_methods.rb +16 -3
- data/lib/solargraph/parser/legacy/node_processors/ivasgn_node.rb +1 -1
- data/lib/solargraph/parser/legacy/node_processors/send_node.rb +48 -23
- data/lib/solargraph/parser/node_processor/base.rb +3 -0
- data/lib/solargraph/parser/rubyvm/class_methods.rb +6 -2
- data/lib/solargraph/parser/rubyvm/node_chainer.rb +11 -9
- data/lib/solargraph/parser/rubyvm/node_methods.rb +6 -1
- data/lib/solargraph/parser/rubyvm/node_processors/args_node.rb +35 -11
- data/lib/solargraph/parser/rubyvm/node_processors/ivasgn_node.rb +1 -1
- data/lib/solargraph/parser/rubyvm/node_processors/kw_arg_node.rb +6 -1
- data/lib/solargraph/parser/rubyvm/node_processors/opt_arg_node.rb +6 -1
- data/lib/solargraph/parser/rubyvm/node_processors/send_node.rb +52 -67
- data/lib/solargraph/parser/rubyvm/node_processors.rb +2 -0
- data/lib/solargraph/pin/base.rb +2 -2
- data/lib/solargraph/pin/base_variable.rb +1 -1
- data/lib/solargraph/pin/block.rb +28 -14
- data/lib/solargraph/pin/closure.rb +1 -1
- data/lib/solargraph/pin/common.rb +1 -1
- data/lib/solargraph/pin/constant.rb +1 -1
- data/lib/solargraph/pin/conversions.rb +3 -4
- data/lib/solargraph/pin/documenting.rb +6 -11
- data/lib/solargraph/pin/local_variable.rb +1 -1
- data/lib/solargraph/pin/method.rb +143 -9
- data/lib/solargraph/pin/method_alias.rb +2 -2
- data/lib/solargraph/pin/namespace.rb +1 -1
- data/lib/solargraph/pin/parameter.rb +2 -2
- data/lib/solargraph/pin/proxy_type.rb +1 -1
- data/lib/solargraph/pin.rb +0 -3
- data/lib/solargraph/position.rb +2 -14
- data/lib/solargraph/shell.rb +2 -1
- data/lib/solargraph/source/chain/call.rb +9 -0
- data/lib/solargraph/source/chain/head.rb +14 -8
- data/lib/solargraph/source/chain/z_super.rb +30 -0
- data/lib/solargraph/source/chain.rb +19 -36
- data/lib/solargraph/source/source_chainer.rb +2 -1
- data/lib/solargraph/source.rb +24 -9
- data/lib/solargraph/source_map/clip.rb +78 -44
- data/lib/solargraph/source_map/mapper.rb +41 -21
- data/lib/solargraph/source_map.rb +20 -2
- data/lib/solargraph/type_checker/param_def.rb +1 -1
- data/lib/solargraph/type_checker.rb +61 -42
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/views/_name_type_tag.erb +1 -1
- data/lib/solargraph/workspace.rb +1 -1
- data/lib/solargraph/yard_map/core_fills.rb +185 -0
- data/lib/solargraph/yard_map/helpers.rb +16 -0
- data/lib/solargraph/{pin/yard_pin/constant.rb → yard_map/mapper/to_constant.rb} +6 -6
- data/lib/solargraph/yard_map/mapper/to_method.rb +78 -0
- data/lib/solargraph/{pin/yard_pin/namespace.rb → yard_map/mapper/to_namespace.rb} +6 -6
- data/lib/solargraph/yard_map/mapper.rb +17 -8
- data/lib/solargraph/yard_map/rdoc_to_yard.rb +26 -15
- data/lib/solargraph/yard_map/stdlib_fills.rb +43 -0
- data/lib/solargraph/yard_map/to_method.rb +79 -0
- data/lib/solargraph/yard_map.rb +140 -92
- data/lib/solargraph.rb +5 -4
- data/solargraph.gemspec +5 -5
- data/yardoc/2.2.2.tar.gz +0 -0
- metadata +29 -41
- data/.rubocop.yml +0 -6
- data/lib/solargraph/core_fills.rb +0 -159
- data/lib/solargraph/pin/attribute.rb +0 -49
- data/lib/solargraph/pin/base_method.rb +0 -141
- data/lib/solargraph/pin/yard_pin/method.rb +0 -65
- data/lib/solargraph/pin/yard_pin/yard_mixin.rb +0 -26
- data/lib/solargraph/pin/yard_pin.rb +0 -12
- data/lib/solargraph/stdlib_fills.rb +0 -32
- data/travis-bundler.rb +0 -11
|
@@ -73,15 +73,15 @@ module Solargraph
|
|
|
73
73
|
# @return [Array<Problem>]
|
|
74
74
|
def method_tag_problems
|
|
75
75
|
result = []
|
|
76
|
-
# @param pin [Pin::
|
|
77
|
-
source_map.
|
|
76
|
+
# @param pin [Pin::Method]
|
|
77
|
+
source_map.pins_by_class(Pin::Method).each do |pin|
|
|
78
78
|
result.concat method_return_type_problems_for(pin)
|
|
79
79
|
result.concat method_param_type_problems_for(pin)
|
|
80
80
|
end
|
|
81
81
|
result
|
|
82
82
|
end
|
|
83
83
|
|
|
84
|
-
# @param pin [Pin::
|
|
84
|
+
# @param pin [Pin::Method]
|
|
85
85
|
# @return [Array<Problem>]
|
|
86
86
|
def method_return_type_problems_for pin
|
|
87
87
|
result = []
|
|
@@ -115,7 +115,7 @@ module Solargraph
|
|
|
115
115
|
pin.location && source_map.source.comment_at?(pin.location.range.ending)
|
|
116
116
|
end
|
|
117
117
|
|
|
118
|
-
# @param pin [Pin::
|
|
118
|
+
# @param pin [Pin::Method]
|
|
119
119
|
# @return [Array<Problem>]
|
|
120
120
|
def method_param_type_problems_for pin
|
|
121
121
|
stack = api_map.get_method_stack(pin.namespace, pin.name, scope: pin.scope)
|
|
@@ -147,14 +147,12 @@ module Solargraph
|
|
|
147
147
|
result = []
|
|
148
148
|
all_variables.each do |pin|
|
|
149
149
|
if pin.return_type.defined?
|
|
150
|
-
# @todo Somwhere in here we still need to determine if the variable is defined by an external call
|
|
151
150
|
declared = pin.typify(api_map)
|
|
152
151
|
if declared.defined?
|
|
153
152
|
if rules.validate_tags?
|
|
154
153
|
inferred = pin.probe(api_map)
|
|
155
154
|
if inferred.undefined?
|
|
156
155
|
next if rules.ignore_all_undefined?
|
|
157
|
-
# next unless internal?(pin) # @todo This might be redundant for variables
|
|
158
156
|
if declared_externally?(pin)
|
|
159
157
|
ignored_pins.push pin
|
|
160
158
|
else
|
|
@@ -172,7 +170,6 @@ module Solargraph
|
|
|
172
170
|
result.push Problem.new(pin.location, "Unresolved type #{pin.return_type} for variable #{pin.name}", pin: pin)
|
|
173
171
|
end
|
|
174
172
|
else
|
|
175
|
-
# @todo Check if the variable is defined by an external call
|
|
176
173
|
inferred = pin.probe(api_map)
|
|
177
174
|
if inferred.undefined? && declared_externally?(pin)
|
|
178
175
|
ignored_pins.push pin
|
|
@@ -184,8 +181,7 @@ module Solargraph
|
|
|
184
181
|
|
|
185
182
|
# @return [Array<Pin::BaseVariable>]
|
|
186
183
|
def all_variables
|
|
187
|
-
source_map.
|
|
188
|
-
source_map.locals.select { |pin| pin.is_a?(Pin::LocalVariable) }
|
|
184
|
+
source_map.pins_by_class(Pin::BaseVariable) + source_map.locals.select { |pin| pin.is_a?(Pin::LocalVariable) }
|
|
189
185
|
end
|
|
190
186
|
|
|
191
187
|
def const_problems
|
|
@@ -228,7 +224,7 @@ module Solargraph
|
|
|
228
224
|
base = base.base
|
|
229
225
|
end
|
|
230
226
|
closest = found.typify(api_map) if found
|
|
231
|
-
if !found || closest.defined?
|
|
227
|
+
if !found || (closest.defined? && internal_or_core?(found))
|
|
232
228
|
unless ignored_pins.include?(found)
|
|
233
229
|
result.push Problem.new(location, "Unresolved call to #{missing.links.last.word}")
|
|
234
230
|
@marked_ranges.push rng
|
|
@@ -245,10 +241,14 @@ module Solargraph
|
|
|
245
241
|
base = chain
|
|
246
242
|
until base.links.length == 1 && base.undefined?
|
|
247
243
|
pins = base.define(api_map, block_pin, locals)
|
|
248
|
-
if pins.first.is_a?(Pin::
|
|
249
|
-
# @type [Pin::
|
|
244
|
+
if pins.first.is_a?(Pin::Method)
|
|
245
|
+
# @type [Pin::Method]
|
|
250
246
|
pin = pins.first
|
|
251
|
-
ap =
|
|
247
|
+
ap = if base.links.last.is_a?(Solargraph::Source::Chain::ZSuper)
|
|
248
|
+
arity_problems_for(pin, fake_args_for(block_pin), location)
|
|
249
|
+
else
|
|
250
|
+
arity_problems_for(pin, base.links.last.arguments, location)
|
|
251
|
+
end
|
|
252
252
|
unless ap.empty?
|
|
253
253
|
result.concat ap
|
|
254
254
|
break
|
|
@@ -310,7 +310,6 @@ module Solargraph
|
|
|
310
310
|
end
|
|
311
311
|
else
|
|
312
312
|
if par.decl == :kwarg
|
|
313
|
-
# @todo Problem: missing required keyword argument
|
|
314
313
|
result.push Problem.new(location, "Call to #{pin.path} is missing keyword argument #{par.name}")
|
|
315
314
|
end
|
|
316
315
|
end
|
|
@@ -357,9 +356,14 @@ module Solargraph
|
|
|
357
356
|
|
|
358
357
|
# @param pin [Pin::Base]
|
|
359
358
|
def internal? pin
|
|
359
|
+
return false if pin.nil?
|
|
360
360
|
pin.location && api_map.bundled?(pin.location.filename)
|
|
361
361
|
end
|
|
362
362
|
|
|
363
|
+
def internal_or_core? pin
|
|
364
|
+
internal?(pin) || api_map.yard_map.core_pins.include?(pin) || api_map.yard_map.stdlib_pins.include?(pin)
|
|
365
|
+
end
|
|
366
|
+
|
|
363
367
|
# @param pin [Pin::Base]
|
|
364
368
|
def external? pin
|
|
365
369
|
!internal? pin
|
|
@@ -392,7 +396,7 @@ module Solargraph
|
|
|
392
396
|
true
|
|
393
397
|
end
|
|
394
398
|
|
|
395
|
-
# @param pin [Pin::
|
|
399
|
+
# @param pin [Pin::Method]
|
|
396
400
|
def arity_problems_for(pin, arguments, location)
|
|
397
401
|
return [] unless pin.explicit?
|
|
398
402
|
return [] if pin.parameters.empty? && arguments.empty?
|
|
@@ -407,29 +411,29 @@ module Solargraph
|
|
|
407
411
|
if unchecked.empty? && pin.parameters.any? { |param| param.decl == :kwarg }
|
|
408
412
|
return [Problem.new(location, "Missing keyword arguments to #{pin.path}")]
|
|
409
413
|
end
|
|
414
|
+
settled_kwargs = 0
|
|
410
415
|
unless unchecked.empty?
|
|
411
416
|
kwargs = convert_hash(unchecked.last.node)
|
|
412
|
-
|
|
413
|
-
if
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
end
|
|
425
|
-
end
|
|
426
|
-
kwargs.clear if pin.parameters.any?(&:kwrestarg?)
|
|
427
|
-
unless kwargs.empty?
|
|
428
|
-
return [Problem.new(location, "Unrecognized keyword argument #{kwargs.keys.first} to #{pin.path}")]
|
|
417
|
+
if pin.parameters.any? { |param| [:kwarg, :kwoptarg].include?(param.decl) || param.kwrestarg? }
|
|
418
|
+
if kwargs.empty?
|
|
419
|
+
add_params += 1
|
|
420
|
+
else
|
|
421
|
+
unchecked.pop
|
|
422
|
+
pin.parameters.each do |param|
|
|
423
|
+
next unless param.keyword?
|
|
424
|
+
if kwargs.key?(param.name.to_sym)
|
|
425
|
+
kwargs.delete param.name.to_sym
|
|
426
|
+
settled_kwargs += 1
|
|
427
|
+
elsif param.decl == :kwarg
|
|
428
|
+
return [Problem.new(location, "Missing keyword argument #{param.name} to #{pin.path}")]
|
|
429
429
|
end
|
|
430
430
|
end
|
|
431
|
+
kwargs.clear if pin.parameters.any?(&:kwrestarg?)
|
|
432
|
+
unless kwargs.empty?
|
|
433
|
+
return [Problem.new(location, "Unrecognized keyword argument #{kwargs.keys.first} to #{pin.path}")]
|
|
434
|
+
end
|
|
431
435
|
end
|
|
432
|
-
|
|
436
|
+
end
|
|
433
437
|
end
|
|
434
438
|
req = required_param_count(pin)
|
|
435
439
|
if req + add_params < unchecked.length
|
|
@@ -440,23 +444,18 @@ module Solargraph
|
|
|
440
444
|
return []
|
|
441
445
|
end
|
|
442
446
|
return [Problem.new(location, "Too many arguments to #{pin.path}")]
|
|
443
|
-
elsif unchecked.length < req && (arguments.empty? || !arguments.last.splat?)
|
|
447
|
+
elsif unchecked.length < req - settled_kwargs && (arguments.empty? || !arguments.last.splat?)
|
|
444
448
|
return [Problem.new(location, "Not enough arguments to #{pin.path}")]
|
|
445
449
|
end
|
|
446
450
|
[]
|
|
447
451
|
end
|
|
448
452
|
|
|
449
|
-
# @param pin [Pin::
|
|
453
|
+
# @param pin [Pin::Method]
|
|
450
454
|
def required_param_count(pin)
|
|
451
|
-
|
|
452
|
-
pin.parameters.each do |param|
|
|
453
|
-
break unless param.decl == :arg
|
|
454
|
-
count += 1
|
|
455
|
-
end
|
|
456
|
-
count
|
|
455
|
+
pin.parameters.sum { |param| %i[arg kwarg].include?(param.decl) ? 1 : 0 }
|
|
457
456
|
end
|
|
458
457
|
|
|
459
|
-
# @param pin [Pin::
|
|
458
|
+
# @param pin [Pin::Method]
|
|
460
459
|
def optional_param_count(pin)
|
|
461
460
|
count = 0
|
|
462
461
|
pin.parameters.each do |param|
|
|
@@ -470,5 +469,25 @@ module Solargraph
|
|
|
470
469
|
pin.docstring.has_tag?(:abstract) ||
|
|
471
470
|
(pin.closure && pin.closure.docstring.has_tag?(:abstract))
|
|
472
471
|
end
|
|
472
|
+
|
|
473
|
+
def fake_args_for(pin)
|
|
474
|
+
args = []
|
|
475
|
+
with_opts = false
|
|
476
|
+
with_block = false
|
|
477
|
+
pin.parameters.each do |pin|
|
|
478
|
+
if [:kwarg, :kwoptarg, :kwrestarg].include?(pin.decl)
|
|
479
|
+
with_opts = true
|
|
480
|
+
elsif pin.decl == :block
|
|
481
|
+
with_block = true
|
|
482
|
+
elsif pin.decl == :restarg
|
|
483
|
+
args.push Solargraph::Source::Chain.new([Solargraph::Source::Chain::Variable.new(pin.name)], nil, true)
|
|
484
|
+
else
|
|
485
|
+
args.push Solargraph::Source::Chain.new([Solargraph::Source::Chain::Variable.new(pin.name)])
|
|
486
|
+
end
|
|
487
|
+
end
|
|
488
|
+
args.push Solargraph::Parser.chain_string('{}') if with_opts
|
|
489
|
+
args.push Solargraph::Parser.chain_string('&') if with_block
|
|
490
|
+
args
|
|
491
|
+
end
|
|
473
492
|
end
|
|
474
493
|
end
|
data/lib/solargraph/version.rb
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
<% unless tag.types.nil? or tag.types.empty? %>
|
|
3
3
|
[<%= escape(tag.types.join(', ')) %>]
|
|
4
4
|
<% end %>
|
|
5
|
-
<% unless tag.text.empty? %>
|
|
5
|
+
<% unless tag.text.nil? || tag.text.empty? %>
|
|
6
6
|
<% unless (tag.name.nil? or tag.name.empty?) and (tag.types.nil? or tag.types.empty?) %>
|
|
7
7
|
-
|
|
8
8
|
<% end %>
|
data/lib/solargraph/workspace.rb
CHANGED
|
@@ -170,7 +170,7 @@ module Solargraph
|
|
|
170
170
|
Dir.chdir base do
|
|
171
171
|
begin
|
|
172
172
|
# @type [Gem::Specification]
|
|
173
|
-
spec = eval(File.read(file),
|
|
173
|
+
spec = eval(File.read(file), TOPLEVEL_BINDING, file)
|
|
174
174
|
next unless Gem::Specification === spec
|
|
175
175
|
@gemnames.push spec.name
|
|
176
176
|
result.concat(spec.require_paths.map { |path| File.join(base, path) })
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
module Solargraph
|
|
2
|
+
class YardMap
|
|
3
|
+
module CoreFills
|
|
4
|
+
Override = Pin::Reference::Override
|
|
5
|
+
|
|
6
|
+
KEYWORDS = [
|
|
7
|
+
'__ENCODING__', '__LINE__', '__FILE__', 'BEGIN', 'END', 'alias', 'and',
|
|
8
|
+
'begin', 'break', 'case', 'class', 'def', 'defined?', 'do', 'else',
|
|
9
|
+
'elsif', 'end', 'ensure', 'false', 'for', 'if', 'in', 'module', 'next',
|
|
10
|
+
'nil', 'not', 'or', 'redo', 'rescue', 'retry', 'return', 'self', 'super',
|
|
11
|
+
'then', 'true', 'undef', 'unless', 'until', 'when', 'while', 'yield'
|
|
12
|
+
].map { |k| Pin::Keyword.new(k) }
|
|
13
|
+
|
|
14
|
+
methods_with_yieldparam_subtypes = %w[
|
|
15
|
+
Array#each Array#map Array#map! Array#any? Array#all? Array#index
|
|
16
|
+
Array#keep_if Array#delete_if
|
|
17
|
+
Enumerable#each_entry Enumerable#map Enumerable#any? Enumerable#all?
|
|
18
|
+
Enumerable#select Enumerable#reject
|
|
19
|
+
Set#each
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
OVERRIDES = [
|
|
23
|
+
Override.method_return('Array#concat', 'Array'),
|
|
24
|
+
Override.method_return('Array#keep_if', 'self'),
|
|
25
|
+
Override.method_return('Array#delete_if', 'self'),
|
|
26
|
+
Override.from_comment('Array#map', %(
|
|
27
|
+
@overload map(&block)
|
|
28
|
+
@return [Array]
|
|
29
|
+
@overload map()
|
|
30
|
+
@return [Enumerator]
|
|
31
|
+
)),
|
|
32
|
+
Override.from_comment('Array#reject', %(
|
|
33
|
+
@overload reject(&block)
|
|
34
|
+
@return [self]
|
|
35
|
+
@overload reject()
|
|
36
|
+
@return [Enumerator]
|
|
37
|
+
)),
|
|
38
|
+
Override.method_return('Array#reverse', 'self', delete: ['overload']),
|
|
39
|
+
Override.from_comment('Array#select', %(
|
|
40
|
+
@overload select(&block)
|
|
41
|
+
@return [self]
|
|
42
|
+
@overload select()
|
|
43
|
+
@return [Enumerator]
|
|
44
|
+
)),
|
|
45
|
+
Override.from_comment('Array#[]', %(
|
|
46
|
+
@overload [](range)
|
|
47
|
+
@param range [Range]
|
|
48
|
+
@return [self]
|
|
49
|
+
@overload [](num1, num2)
|
|
50
|
+
@param num1 [Integer]
|
|
51
|
+
@param num2 [Integer]
|
|
52
|
+
@return [self]
|
|
53
|
+
@overload [](num)
|
|
54
|
+
@param num [Integer]
|
|
55
|
+
@return_single_parameter
|
|
56
|
+
@return_single_parameter
|
|
57
|
+
)),
|
|
58
|
+
Override.from_comment('Array#first', %(
|
|
59
|
+
@overload first(num)
|
|
60
|
+
@param num [Integer]
|
|
61
|
+
@return [self]
|
|
62
|
+
@return_single_parameter
|
|
63
|
+
)),
|
|
64
|
+
Override.from_comment('Array#last', %(
|
|
65
|
+
@overload last(num)
|
|
66
|
+
@param num [Integer]
|
|
67
|
+
@return [self]
|
|
68
|
+
@return_single_parameter
|
|
69
|
+
)),
|
|
70
|
+
Override.method_return('Array#map', 'Array'),
|
|
71
|
+
Override.method_return('Array#uniq', 'self'),
|
|
72
|
+
Override.method_return('Array#zip', 'Array, nil'),
|
|
73
|
+
|
|
74
|
+
Override.from_comment('BasicObject#==', %(
|
|
75
|
+
@param other [BasicObject]
|
|
76
|
+
@return [Boolean]
|
|
77
|
+
)),
|
|
78
|
+
Override.method_return('BasicObject#initialize', 'void'),
|
|
79
|
+
|
|
80
|
+
Override.method_return('Class#new', 'self'),
|
|
81
|
+
Override.method_return('Class.new', 'Class<Object>'),
|
|
82
|
+
Override.method_return('Class#allocate', 'self'),
|
|
83
|
+
Override.method_return('Class.allocate', 'Class<Object>'),
|
|
84
|
+
|
|
85
|
+
Override.method_return('Enumerable#select', 'self'),
|
|
86
|
+
|
|
87
|
+
Override.method_return('File.absolute_path', 'String'),
|
|
88
|
+
Override.method_return('File.basename', 'String'),
|
|
89
|
+
Override.method_return('File.dirname', 'String'),
|
|
90
|
+
Override.method_return('File.extname', 'String'),
|
|
91
|
+
Override.method_return('File.join', 'String'),
|
|
92
|
+
|
|
93
|
+
Override.from_comment('Float#+', %(
|
|
94
|
+
@param y [Numeric]
|
|
95
|
+
@return [Numeric]
|
|
96
|
+
)),
|
|
97
|
+
|
|
98
|
+
Override.from_comment('Hash#[]', %(
|
|
99
|
+
@return_value_parameter
|
|
100
|
+
)),
|
|
101
|
+
|
|
102
|
+
# @todo This override isn't robust enough. It needs to allow for
|
|
103
|
+
# parameterized Hash types, e.g., [Hash{Symbol => String}].
|
|
104
|
+
Override.from_comment('Hash#[]=', %(
|
|
105
|
+
@param_tuple
|
|
106
|
+
)),
|
|
107
|
+
|
|
108
|
+
Override.method_return('Hash#merge', 'Hash'),
|
|
109
|
+
|
|
110
|
+
Override.from_comment('Integer#+', %(
|
|
111
|
+
@param y [Numeric]
|
|
112
|
+
@return [Numeric]
|
|
113
|
+
)),
|
|
114
|
+
|
|
115
|
+
Override.method_return('Kernel#puts', 'nil'),
|
|
116
|
+
|
|
117
|
+
Override.from_comment('Numeric#+', %(
|
|
118
|
+
@param y [Numeric]
|
|
119
|
+
@return [Numeric]
|
|
120
|
+
)),
|
|
121
|
+
|
|
122
|
+
Override.method_return('Object#!', 'Boolean'),
|
|
123
|
+
Override.method_return('Object#clone', 'self', delete: [:overload]),
|
|
124
|
+
Override.method_return('Object#dup', 'self', delete: [:overload]),
|
|
125
|
+
Override.method_return('Object#freeze', 'self', delete: [:overload]),
|
|
126
|
+
Override.method_return('Object#inspect', 'String'),
|
|
127
|
+
Override.method_return('Object#taint', 'self'),
|
|
128
|
+
Override.method_return('Object#to_s', 'String'),
|
|
129
|
+
Override.method_return('Object#untaint', 'self'),
|
|
130
|
+
Override.from_comment('Object#tap', %(
|
|
131
|
+
@return [self]
|
|
132
|
+
@yieldparam [self]
|
|
133
|
+
)),
|
|
134
|
+
|
|
135
|
+
Override.from_comment('STDERR', %(
|
|
136
|
+
@type [IO]
|
|
137
|
+
)),
|
|
138
|
+
|
|
139
|
+
Override.from_comment('STDIN', %(
|
|
140
|
+
@type [IO]
|
|
141
|
+
)),
|
|
142
|
+
|
|
143
|
+
Override.from_comment('STDOUT', %(
|
|
144
|
+
@type [IO]
|
|
145
|
+
)),
|
|
146
|
+
|
|
147
|
+
Override.method_return('String#freeze', 'self'),
|
|
148
|
+
Override.method_return('String#split', 'Array<String>'),
|
|
149
|
+
Override.method_return('String#lines', 'Array<String>'),
|
|
150
|
+
Override.from_comment('String#each_line', %(
|
|
151
|
+
@yieldparam [String]
|
|
152
|
+
)),
|
|
153
|
+
Override.from_comment('String.new', %(
|
|
154
|
+
@overload new(*)
|
|
155
|
+
@return [self]
|
|
156
|
+
))
|
|
157
|
+
].concat(
|
|
158
|
+
methods_with_yieldparam_subtypes.map do |path|
|
|
159
|
+
Override.from_comment(path, %(
|
|
160
|
+
@yieldparam_single_parameter
|
|
161
|
+
))
|
|
162
|
+
end
|
|
163
|
+
)
|
|
164
|
+
|
|
165
|
+
PINS = [
|
|
166
|
+
Pin::Reference::Superclass.new(closure: Pin::Namespace.new(name: 'File'), name: 'IO'),
|
|
167
|
+
Pin::Reference::Superclass.new(closure: Pin::Namespace.new(name: 'Integer'), name: 'Numeric'),
|
|
168
|
+
Pin::Reference::Superclass.new(closure: Pin::Namespace.new(name: 'Float'), name: 'Numeric')
|
|
169
|
+
].concat(
|
|
170
|
+
# HACK: Add Errno exception classes
|
|
171
|
+
begin
|
|
172
|
+
errno = Solargraph::Pin::Namespace.new(name: 'Errno')
|
|
173
|
+
result = []
|
|
174
|
+
Errno.constants.each do |const|
|
|
175
|
+
result.push Solargraph::Pin::Namespace.new(type: :class, name: const.to_s, closure: errno)
|
|
176
|
+
result.push Solargraph::Pin::Reference::Superclass.new(closure: result.last, name: 'SystemCallError')
|
|
177
|
+
end
|
|
178
|
+
result
|
|
179
|
+
end
|
|
180
|
+
)
|
|
181
|
+
|
|
182
|
+
ALL = KEYWORDS + PINS + OVERRIDES
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module Solargraph
|
|
2
|
+
class YardMap
|
|
3
|
+
module Helpers
|
|
4
|
+
module_function
|
|
5
|
+
|
|
6
|
+
# @param code_object [YARD::CodeObjects::Base]
|
|
7
|
+
# @param spec [Gem::Specification]
|
|
8
|
+
# @return [Solargraph::Location, nil]
|
|
9
|
+
def object_location code_object, spec
|
|
10
|
+
return nil if spec.nil? || code_object.nil? || code_object.file.nil? || code_object.line.nil?
|
|
11
|
+
file = File.join(spec.full_gem_path, code_object.file)
|
|
12
|
+
Solargraph::Location.new(file, Solargraph::Range.from_to(code_object.line - 1, 0, code_object.line - 1, 0))
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Solargraph
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
class YardMap
|
|
5
|
+
class Mapper
|
|
6
|
+
module ToConstant
|
|
7
|
+
extend YardMap::Helpers
|
|
8
8
|
|
|
9
|
-
def
|
|
9
|
+
def self.make code_object, closure = nil, spec = nil
|
|
10
10
|
closure ||= Solargraph::Pin::Namespace.new(
|
|
11
11
|
name: code_object.namespace.to_s,
|
|
12
12
|
gates: [code_object.namespace.to_s]
|
|
13
13
|
)
|
|
14
|
-
|
|
14
|
+
Pin::Constant.new(
|
|
15
15
|
location: object_location(code_object, spec),
|
|
16
16
|
closure: closure,
|
|
17
17
|
name: code_object.name.to_s,
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Solargraph
|
|
4
|
+
class YardMap
|
|
5
|
+
class Mapper
|
|
6
|
+
module ToMethod
|
|
7
|
+
extend YardMap::Helpers
|
|
8
|
+
|
|
9
|
+
def self.make code_object, name = nil, scope = nil, visibility = nil, closure = nil, spec = nil
|
|
10
|
+
closure ||= Solargraph::Pin::Namespace.new(
|
|
11
|
+
name: code_object.namespace.to_s,
|
|
12
|
+
gates: [code_object.namespace.to_s]
|
|
13
|
+
)
|
|
14
|
+
location = object_location(code_object, spec)
|
|
15
|
+
comments = code_object.docstring ? code_object.docstring.all.to_s : ''
|
|
16
|
+
Pin::Method.new(
|
|
17
|
+
location: location,
|
|
18
|
+
closure: closure,
|
|
19
|
+
name: name || code_object.name.to_s,
|
|
20
|
+
comments: comments,
|
|
21
|
+
scope: scope || code_object.scope,
|
|
22
|
+
visibility: visibility || code_object.visibility,
|
|
23
|
+
parameters: get_parameters(code_object, location, comments),
|
|
24
|
+
explicit: code_object.is_explicit?
|
|
25
|
+
)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
class << self
|
|
29
|
+
private
|
|
30
|
+
|
|
31
|
+
# @param code_object [YARD::CodeObjects::Base]
|
|
32
|
+
# @return [Array<Solargraph::Pin::Parameter>]
|
|
33
|
+
def get_parameters code_object, location, comments
|
|
34
|
+
return [] unless code_object.is_a?(YARD::CodeObjects::MethodObject)
|
|
35
|
+
# HACK: Skip `nil` and `self` parameters that are sometimes emitted
|
|
36
|
+
# for methods defined in C
|
|
37
|
+
# See https://github.com/castwide/solargraph/issues/345
|
|
38
|
+
code_object.parameters.select { |a| a[0] && a[0] != 'self' }.map do |a|
|
|
39
|
+
Solargraph::Pin::Parameter.new(
|
|
40
|
+
location: location,
|
|
41
|
+
closure: self,
|
|
42
|
+
comments: comments,
|
|
43
|
+
name: arg_name(a),
|
|
44
|
+
presence: nil,
|
|
45
|
+
decl: arg_type(a),
|
|
46
|
+
asgn_code: a[1]
|
|
47
|
+
)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# @param a [Array]
|
|
52
|
+
# @return [String]
|
|
53
|
+
def arg_name a
|
|
54
|
+
a[0].gsub(/[^a-z0-9_]/i, '')
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# @param a [Array]
|
|
58
|
+
# @return [::Symbol]
|
|
59
|
+
def arg_type a
|
|
60
|
+
if a[0].start_with?('**')
|
|
61
|
+
:kwrestarg
|
|
62
|
+
elsif a[0].start_with?('*')
|
|
63
|
+
:restarg
|
|
64
|
+
elsif a[0].start_with?('&')
|
|
65
|
+
:blockarg
|
|
66
|
+
elsif a[0].end_with?(':')
|
|
67
|
+
a[1] ? :kwoptarg : :kwarg
|
|
68
|
+
elsif a[1]
|
|
69
|
+
:optarg
|
|
70
|
+
else
|
|
71
|
+
:arg
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Solargraph
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
class YardMap
|
|
5
|
+
class Mapper
|
|
6
|
+
module ToNamespace
|
|
7
|
+
extend YardMap::Helpers
|
|
8
8
|
|
|
9
|
-
def
|
|
9
|
+
def self.make code_object, spec, closure = nil
|
|
10
10
|
closure ||= Solargraph::Pin::Namespace.new(
|
|
11
11
|
name: code_object.namespace.to_s,
|
|
12
12
|
closure: Pin::ROOT_PIN,
|
|
13
13
|
gates: [code_object.namespace.to_s]
|
|
14
14
|
)
|
|
15
|
-
|
|
15
|
+
Pin::Namespace.new(
|
|
16
16
|
location: object_location(code_object, spec),
|
|
17
17
|
name: code_object.name.to_s,
|
|
18
18
|
comments: code_object.docstring ? code_object.docstring.all.to_s : '',
|
|
@@ -3,6 +3,10 @@
|
|
|
3
3
|
module Solargraph
|
|
4
4
|
class YardMap
|
|
5
5
|
class Mapper
|
|
6
|
+
autoload :ToMethod, 'solargraph/yard_map/mapper/to_method'
|
|
7
|
+
autoload :ToNamespace, 'solargraph/yard_map/mapper/to_namespace'
|
|
8
|
+
autoload :ToConstant, 'solargraph/yard_map/mapper/to_constant'
|
|
9
|
+
|
|
6
10
|
# @param code_objects [Array<YARD::CodeObjects::Base>]
|
|
7
11
|
# @param spec [Gem::Specification]
|
|
8
12
|
def initialize code_objects, spec = nil
|
|
@@ -17,25 +21,30 @@ module Solargraph
|
|
|
17
21
|
@code_objects.each do |co|
|
|
18
22
|
@pins.concat generate_pins co
|
|
19
23
|
end
|
|
24
|
+
# Some yardocs contain documentation for dependencies that can be
|
|
25
|
+
# ignored here. The YardMap will load dependencies separately.
|
|
26
|
+
@pins.keep_if { |pin| pin.location.nil? || File.file?(pin.location.filename) } if @spec
|
|
20
27
|
@pins
|
|
21
28
|
end
|
|
22
29
|
|
|
30
|
+
private
|
|
31
|
+
|
|
23
32
|
# @param code_object [YARD::CodeObjects::Base]
|
|
24
33
|
# @return [Array<Pin::Base>]
|
|
25
34
|
def generate_pins code_object
|
|
26
35
|
result = []
|
|
27
36
|
if code_object.is_a?(YARD::CodeObjects::NamespaceObject)
|
|
28
|
-
nspin =
|
|
37
|
+
nspin = ToNamespace.make(code_object, @spec, @namespace_pins[code_object.namespace.to_s])
|
|
29
38
|
@namespace_pins[code_object.path] = nspin
|
|
30
39
|
result.push nspin
|
|
31
40
|
if code_object.is_a?(YARD::CodeObjects::ClassObject) and !code_object.superclass.nil?
|
|
32
41
|
# This method of superclass detection is a bit of a hack. If
|
|
33
42
|
# the superclass is a Proxy, it is assumed to be undefined in its
|
|
34
43
|
# yardoc and converted to a fully qualified namespace.
|
|
35
|
-
if code_object.superclass.is_a?(YARD::CodeObjects::Proxy)
|
|
36
|
-
|
|
44
|
+
superclass = if code_object.superclass.is_a?(YARD::CodeObjects::Proxy)
|
|
45
|
+
"::#{code_object.superclass}"
|
|
37
46
|
else
|
|
38
|
-
|
|
47
|
+
code_object.superclass.to_s
|
|
39
48
|
end
|
|
40
49
|
result.push Solargraph::Pin::Reference::Superclass.new(name: superclass, closure: nspin)
|
|
41
50
|
end
|
|
@@ -52,14 +61,14 @@ module Solargraph
|
|
|
52
61
|
closure = @namespace_pins[code_object.namespace.to_s]
|
|
53
62
|
if code_object.name == :initialize && code_object.scope == :instance
|
|
54
63
|
# @todo Check the visibility of <Class>.new
|
|
55
|
-
result.push
|
|
56
|
-
result.push
|
|
64
|
+
result.push ToMethod.make(code_object, 'new', :class, :public, closure, @spec)
|
|
65
|
+
result.push ToMethod.make(code_object, 'initialize', :instance, :private, closure, @spec)
|
|
57
66
|
else
|
|
58
|
-
result.push
|
|
67
|
+
result.push ToMethod.make(code_object, nil, nil, nil, closure, @spec)
|
|
59
68
|
end
|
|
60
69
|
elsif code_object.is_a?(YARD::CodeObjects::ConstantObject)
|
|
61
70
|
closure = @namespace_pins[code_object.namespace]
|
|
62
|
-
result.push
|
|
71
|
+
result.push ToConstant.make(code_object, closure, @spec)
|
|
63
72
|
end
|
|
64
73
|
result
|
|
65
74
|
end
|