solargraph 0.48.0 → 0.49.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 +9 -0
- data/LICENSE +1 -1
- data/SPONSORS.md +2 -4
- data/lib/solargraph/api_map/store.rb +13 -1
- data/lib/solargraph/api_map.rb +30 -12
- data/lib/solargraph/cache.rb +51 -0
- data/lib/solargraph/complex_type/type_methods.rb +3 -6
- data/lib/solargraph/complex_type/unique_type.rb +57 -0
- data/lib/solargraph/complex_type.rb +20 -1
- data/lib/solargraph/convention/rakefile.rb +17 -0
- data/lib/solargraph/convention.rb +2 -0
- data/lib/solargraph/diagnostics/rubocop.rb +15 -2
- data/lib/solargraph/diagnostics/rubocop_helpers.rb +3 -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 +21 -20
- data/lib/solargraph/parser/rubyvm/class_methods.rb +6 -1
- 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/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/conversions.rb +2 -6
- data/lib/solargraph/pin/method.rb +84 -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 +38 -30
- data/lib/solargraph/source/chain/call.rb +30 -22
- data/lib/solargraph/source/chain.rb +21 -6
- data/lib/solargraph/source_map/clip.rb +5 -0
- data/lib/solargraph/source_map/mapper.rb +2 -0
- 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 +7 -148
- data/lib/solargraph.rb +2 -2
- data/solargraph.gemspec +8 -6
- metadata +43 -36
- 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 -143
- data/lib/solargraph/yard_map/stdlib_fills.rb +0 -43
- data/yardoc/2.2.2.tar.gz +0 -0
data/lib/solargraph/shell.rb
CHANGED
@@ -71,43 +71,47 @@ module Solargraph
|
|
71
71
|
STDOUT.puts "Configuration file initialized."
|
72
72
|
end
|
73
73
|
|
74
|
-
desc 'download-core [VERSION]', 'Download core documentation'
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
FileUtils.rm_rf Dir.glob(File.join(Solargraph::YardMap::CoreDocs.cache_dir, ver, '*.ser'))
|
84
|
-
puts "Download complete."
|
85
|
-
rescue ArgumentError => e
|
86
|
-
STDERR.puts "ERROR: #{e.message}"
|
87
|
-
STDERR.puts "Run `solargraph available-cores` for a list."
|
88
|
-
exit 1
|
74
|
+
desc 'download-core [VERSION]', 'Download core documentation [deprecated]'
|
75
|
+
long_desc %(
|
76
|
+
The `download-core` command is deprecated. Current versions of Solargraph
|
77
|
+
use RBS for core and stdlib documentation.
|
78
|
+
)
|
79
|
+
# @deprecated
|
80
|
+
def download_core _version = nil
|
81
|
+
puts 'The `download-core` command is deprecated.'
|
82
|
+
puts 'Current versions of Solargraph use RBS for core and stdlib documentation.'
|
89
83
|
end
|
90
84
|
|
91
|
-
desc 'list-cores', 'List the local documentation versions'
|
85
|
+
desc 'list-cores', 'List the local documentation versions [deprecated]'
|
86
|
+
long_desc %(
|
87
|
+
The `list-cores` command is deprecated. Current versions of Solargraph use
|
88
|
+
RBS for core and stdlib documentation.
|
89
|
+
)
|
90
|
+
# @deprecated
|
92
91
|
def list_cores
|
93
|
-
puts
|
92
|
+
puts 'The `list-cores` command is deprecated.'
|
93
|
+
puts 'Current versions of Solargraph use RBS for core and stdlib documentation.'
|
94
94
|
end
|
95
95
|
|
96
|
-
desc 'available-cores', 'List available documentation versions'
|
96
|
+
desc 'available-cores', 'List available documentation versions [deprecated]'
|
97
|
+
long_desc %(
|
98
|
+
The `available-cores` command is deprecated. Current versions of Solargraph
|
99
|
+
use RBS for core and stdlib documentation.
|
100
|
+
)
|
101
|
+
# @deprecated
|
97
102
|
def available_cores
|
98
|
-
puts
|
103
|
+
puts 'The `available-cores` command is deprecated.'
|
104
|
+
puts 'Current versions of Solargraph use RBS for core and stdlib documentation.'
|
99
105
|
end
|
100
106
|
|
101
107
|
desc 'clear', 'Delete all cached documentation'
|
102
108
|
long_desc %(
|
103
109
|
This command will delete all core and gem documentation from the cache.
|
104
|
-
You can also delete specific gem caches with the `uncache` command or
|
105
|
-
update documentation for specific Ruby versions with the `download-core`
|
106
|
-
command.
|
107
110
|
)
|
111
|
+
# @deprecated
|
108
112
|
def clear
|
109
113
|
puts "Deleting the cached documentation"
|
110
|
-
Solargraph::
|
114
|
+
Solargraph::Cache.clear
|
111
115
|
end
|
112
116
|
map 'clear-cache' => :clear
|
113
117
|
map 'clear-cores' => :clear
|
@@ -191,18 +195,22 @@ module Solargraph
|
|
191
195
|
puts "Scanned #{directory} (#{api_map.pins.length} pins) in #{time.real} seconds."
|
192
196
|
end
|
193
197
|
|
194
|
-
desc 'bundle', 'Generate documentation for bundled gems'
|
198
|
+
desc 'bundle', 'Generate documentation for bundled gems [deprecated]'
|
199
|
+
long_desc %(
|
200
|
+
The `bundle` command is deprecated. Solargraph currently uses RBS instead.
|
201
|
+
)
|
195
202
|
option :directory, type: :string, aliases: :d, desc: 'The workspace directory', default: '.'
|
196
203
|
option :rebuild, type: :boolean, aliases: :r, desc: 'Rebuild existing documentation', default: false
|
197
204
|
def bundle
|
198
|
-
|
205
|
+
puts 'The `bundle` command is deprecated. Solargraph currently uses RBS instead.'
|
199
206
|
end
|
200
207
|
|
201
|
-
desc 'rdoc GEM [VERSION]', 'Use RDoc to cache documentation'
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
208
|
+
desc 'rdoc GEM [VERSION]', 'Use RDoc to cache documentation [deprecated]'
|
209
|
+
long_desc %(
|
210
|
+
The `rdoc` command is deprecated. Solargraph currently uses RBS instead.
|
211
|
+
)
|
212
|
+
def rdoc _gem, _version = '>= 0'
|
213
|
+
puts 'The `rdoc` command is deprecated. Solargraph currently uses RBS instead.'
|
206
214
|
end
|
207
215
|
|
208
216
|
private
|
@@ -52,36 +52,32 @@ module Solargraph
|
|
52
52
|
# @return [Array<Pin::Base>]
|
53
53
|
def inferred_pins pins, api_map, context, locals
|
54
54
|
result = pins.map do |p|
|
55
|
-
|
55
|
+
next p unless p.is_a?(Pin::Method)
|
56
|
+
overloads = p.signatures
|
56
57
|
# next p if overloads.empty?
|
57
58
|
type = ComplexType::UNDEFINED
|
58
|
-
# @param [YARD::Tags::OverloadTag]
|
59
59
|
overloads.each do |ol|
|
60
|
-
next unless arguments_match(arguments, ol
|
61
|
-
next if ol.parameters.last && ol.parameters.last.first.start_with?('&') && ol.parameters.last.last.nil? && !with_block?
|
60
|
+
next unless arguments_match(arguments, ol)
|
61
|
+
# next if ol.parameters.last && ol.parameters.last.first.start_with?('&') && ol.parameters.last.last.nil? && !with_block?
|
62
62
|
match = true
|
63
63
|
arguments.each_with_index do |arg, idx|
|
64
|
-
achain = arguments[idx]
|
65
|
-
next if achain.nil?
|
66
64
|
param = ol.parameters[idx]
|
67
65
|
if param.nil?
|
68
|
-
match = false unless ol.parameters.
|
66
|
+
match = false unless ol.parameters.any?(&:restarg?)
|
69
67
|
break
|
70
68
|
end
|
71
|
-
|
72
|
-
next if par.nil? || par.types.nil? || par.types.empty?
|
73
|
-
atype = achain.infer(api_map, Pin::ProxyType.anonymous(context), locals)
|
74
|
-
other = ComplexType.try_parse(*par.types)
|
69
|
+
atype = arg.infer(api_map, Pin::ProxyType.anonymous(context), locals)
|
75
70
|
# @todo Weak type comparison
|
76
|
-
unless atype.tag ==
|
71
|
+
# unless atype.tag == param.return_type.tag || api_map.super_and_sub?(param.return_type.tag, atype.tag)
|
72
|
+
unless param.return_type.undefined? || atype.name == param.return_type.name || api_map.super_and_sub?(param.return_type.name, atype.name)
|
77
73
|
match = false
|
78
74
|
break
|
79
75
|
end
|
80
76
|
end
|
81
77
|
if match
|
82
|
-
type = extra_return_type(
|
78
|
+
type = extra_return_type(p.docstring, context)
|
83
79
|
break if type
|
84
|
-
type =
|
80
|
+
type = with_params(ol.return_type.self_to(context.to_s), context).qualify(api_map, context.namespace) if ol.return_type.defined?
|
85
81
|
type ||= ComplexType::UNDEFINED
|
86
82
|
end
|
87
83
|
break if type.defined?
|
@@ -110,9 +106,13 @@ module Solargraph
|
|
110
106
|
p
|
111
107
|
end
|
112
108
|
result.map do |pin|
|
113
|
-
|
114
|
-
|
115
|
-
|
109
|
+
if pin.path == 'Class#new' && context.tag != 'Class'
|
110
|
+
pin.proxy(ComplexType.try_parse(context.namespace))
|
111
|
+
else
|
112
|
+
next pin if pin.return_type.undefined?
|
113
|
+
selfy = pin.return_type.self_to(context.tag)
|
114
|
+
selfy == pin.return_type ? pin : pin.proxy(selfy)
|
115
|
+
end
|
116
116
|
end
|
117
117
|
end
|
118
118
|
|
@@ -183,14 +183,15 @@ module Solargraph
|
|
183
183
|
end
|
184
184
|
|
185
185
|
# @param arguments [Array<Chain>]
|
186
|
-
# @param
|
186
|
+
# @param signature [Pin::Signature]
|
187
187
|
# @return [Boolean]
|
188
|
-
def arguments_match arguments,
|
188
|
+
def arguments_match arguments, signature
|
189
|
+
parameters = signature.parameters
|
189
190
|
argcount = arguments.length
|
190
|
-
# argcount -= 1 if !arguments.empty? && arguments.last.links.first.word.start_with?('&')
|
191
191
|
parcount = parameters.length
|
192
|
-
parcount -= 1 if !parameters.empty? && parameters.last.
|
193
|
-
return false if
|
192
|
+
parcount -= 1 if !parameters.empty? && parameters.last.block?
|
193
|
+
return false if signature.block? && !with_block?
|
194
|
+
return false if argcount < parcount && !(argcount == parcount - 1 && parameters.last.restarg?)
|
194
195
|
true
|
195
196
|
end
|
196
197
|
|
@@ -201,6 +202,13 @@ module Solargraph
|
|
201
202
|
pins = api_map.get_method_stack(name_pin.namespace, name_pin.name, scope: name_pin.scope)
|
202
203
|
pins.reject{|p| p.path == name_pin.path}
|
203
204
|
end
|
205
|
+
|
206
|
+
# @param type [ComplexType]
|
207
|
+
# @param context [ComplexType]
|
208
|
+
def with_params type, context
|
209
|
+
return type unless type.to_s.include?('$')
|
210
|
+
ComplexType.try_parse(type.to_s.gsub('$', context.value_types.map(&:tag).join(', ')).gsub('<>', ''))
|
211
|
+
end
|
204
212
|
end
|
205
213
|
end
|
206
214
|
end
|
@@ -63,11 +63,11 @@ module Solargraph
|
|
63
63
|
working_pin = name_pin
|
64
64
|
links[0..-2].each do |link|
|
65
65
|
pins = link.resolve(api_map, working_pin, locals)
|
66
|
-
type = infer_first_defined(pins, working_pin, api_map)
|
66
|
+
type = infer_first_defined(pins, working_pin, api_map, locals)
|
67
67
|
return [] if type.undefined?
|
68
68
|
working_pin = Pin::ProxyType.anonymous(type)
|
69
69
|
end
|
70
|
-
links.last.last_context =
|
70
|
+
links.last.last_context = name_pin
|
71
71
|
links.last.resolve(api_map, working_pin, locals)
|
72
72
|
end
|
73
73
|
|
@@ -76,8 +76,12 @@ module Solargraph
|
|
76
76
|
# @param locals [Array<Pin::Base>]
|
77
77
|
# @return [ComplexType]
|
78
78
|
def infer api_map, name_pin, locals
|
79
|
+
from_here = base.infer(api_map, name_pin, locals) unless links.length == 1
|
80
|
+
if from_here
|
81
|
+
name_pin = name_pin.proxy(from_here)
|
82
|
+
end
|
79
83
|
pins = define(api_map, name_pin, locals)
|
80
|
-
type = infer_first_defined(pins, links.last.last_context, api_map)
|
84
|
+
type = infer_first_defined(pins, links.last.last_context, api_map, locals)
|
81
85
|
maybe_nil(type)
|
82
86
|
end
|
83
87
|
|
@@ -110,9 +114,10 @@ module Solargraph
|
|
110
114
|
private
|
111
115
|
|
112
116
|
# @param pins [Array<Pin::Base>]
|
117
|
+
# @param context [Pin::Base]
|
113
118
|
# @param api_map [ApiMap]
|
114
119
|
# @return [ComplexType]
|
115
|
-
def infer_first_defined pins, context, api_map
|
120
|
+
def infer_first_defined pins, context, api_map, locals
|
116
121
|
possibles = []
|
117
122
|
pins.each do |pin|
|
118
123
|
# Avoid infinite recursion
|
@@ -121,8 +126,18 @@ module Solargraph
|
|
121
126
|
type = pin.typify(api_map)
|
122
127
|
@@inference_stack.pop
|
123
128
|
if type.defined?
|
124
|
-
|
125
|
-
|
129
|
+
if type.parameterized?
|
130
|
+
type = type.resolve_parameters(pin.closure, context)
|
131
|
+
# idx = pin.closure.parameters.index(type.subtypes.first.name)
|
132
|
+
# next if idx.nil?
|
133
|
+
# param_type = context.return_type.all_params[idx]
|
134
|
+
# next unless param_type
|
135
|
+
# type = ComplexType.try_parse(param_type.to_s)
|
136
|
+
end
|
137
|
+
if type.defined?
|
138
|
+
possibles.push type
|
139
|
+
break if pin.is_a?(Pin::Method)
|
140
|
+
end
|
126
141
|
end
|
127
142
|
end
|
128
143
|
if possibles.empty?
|
@@ -43,6 +43,11 @@ module Solargraph
|
|
43
43
|
# @return [ComplexType]
|
44
44
|
def infer
|
45
45
|
result = cursor.chain.infer(api_map, block, locals)
|
46
|
+
if result.tag == 'Class'
|
47
|
+
# HACK: Exception to return Object from Class#new
|
48
|
+
dfn = cursor.chain.define(api_map, block, locals).first
|
49
|
+
return ComplexType.try_parse('Object') if dfn && dfn.path == 'Class#new'
|
50
|
+
end
|
46
51
|
return result unless result.tag == 'self'
|
47
52
|
ComplexType.try_parse(cursor.chain.base.infer(api_map, block, locals).namespace)
|
48
53
|
end
|
@@ -24,6 +24,8 @@ module Solargraph
|
|
24
24
|
@code = source.code
|
25
25
|
@comments = source.comments
|
26
26
|
@pins, @locals = Parser.map(source)
|
27
|
+
@pins.each { |p| p.source = :code }
|
28
|
+
@locals.each { |l| l.source = :code }
|
27
29
|
process_comment_directives
|
28
30
|
[@pins, @locals]
|
29
31
|
# rescue Exception => e
|
@@ -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,
|