solargraph 0.21.0 → 0.22.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 +5 -5
- data/lib/solargraph/api_map/completion.rb +3 -0
- data/lib/solargraph/api_map/probe.rb +21 -45
- data/lib/solargraph/api_map/store.rb +6 -2
- data/lib/solargraph/api_map/type_methods.rb +40 -0
- data/lib/solargraph/api_map.rb +45 -35
- data/lib/solargraph/diagnostics/require_not_found.rb +5 -0
- data/lib/solargraph/diagnostics/rubocop.rb +9 -0
- data/lib/solargraph/diagnostics.rb +5 -0
- data/lib/solargraph/language_server/host.rb +9 -1
- data/lib/solargraph/language_server/message/base.rb +1 -8
- data/lib/solargraph/language_server/message/extended/check_gem_version.rb +5 -1
- data/lib/solargraph/language_server/message/extended/download_core.rb +25 -0
- data/lib/solargraph/language_server/message/extended.rb +1 -0
- data/lib/solargraph/language_server/message/initialize.rb +3 -1
- data/lib/solargraph/language_server/message/text_document/definition.rb +1 -1
- data/lib/solargraph/language_server/message/text_document/hover.rb +1 -1
- data/lib/solargraph/language_server/message/text_document/references.rb +14 -0
- data/lib/solargraph/language_server/message/text_document/rename.rb +17 -0
- data/lib/solargraph/language_server/message/text_document.rb +13 -11
- data/lib/solargraph/language_server/message.rb +3 -0
- data/lib/solargraph/language_server/request.rb +4 -0
- data/lib/solargraph/language_server/transport/socket.rb +4 -4
- data/lib/solargraph/language_server/uri_helpers.rb +2 -0
- data/lib/solargraph/library.rb +37 -0
- data/lib/solargraph/live_map/cache.rb +7 -0
- data/lib/solargraph/live_map.rb +8 -2
- data/lib/solargraph/pin/attribute.rb +5 -1
- data/lib/solargraph/pin/namespace.rb +0 -2
- data/lib/solargraph/pin/proxy_method.rb +31 -0
- data/lib/solargraph/pin.rb +1 -0
- data/lib/solargraph/plugin/process.rb +1 -1
- data/lib/solargraph/plugin/runtime.rb +6 -3
- data/lib/solargraph/shell.rb +0 -1
- data/lib/solargraph/source/flawed_builder.rb +3 -0
- data/lib/solargraph/source/fragment.rb +12 -15
- data/lib/solargraph/source/location.rb +3 -0
- data/lib/solargraph/source/mapper.rb +60 -18
- data/lib/solargraph/source/node_methods.rb +111 -0
- data/lib/solargraph/source/position.rb +18 -0
- data/lib/solargraph/source/range.rb +5 -1
- data/lib/solargraph/source.rb +31 -1
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/workspace/config.rb +6 -2
- data/lib/solargraph/workspace.rb +7 -1
- data/lib/solargraph/yard_map/core_docs.rb +1 -1
- data/lib/solargraph/yard_map.rb +43 -5
- data/lib/solargraph.rb +0 -1
- metadata +27 -8
- data/lib/solargraph/node_methods.rb +0 -101
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: c647321bb57cb5ba859e1762032855324aa967e78a562c0e259508e5c24c22ee
|
|
4
|
+
data.tar.gz: 057c1a4298f9c4574c0773425cce496216ab60e22165871487d6d77e13733745
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ae8cb69f92e2f3ad78959bd8767b78dda5a7d4baa861fa59680be191b7c92944f0df15ff12ccad2ed4a93231afcc55db53bd40cf9b42473387491f4d168f1cef
|
|
7
|
+
data.tar.gz: 8d02f2a10b1a71579a0b48e9dae4268689cc0ec642c137b1adedf6fc99749ae5a1b04f46b4d9b30448d3316a71b65dfdf79b5066c0af499e2181fcc5a107201f
|
|
@@ -1,12 +1,7 @@
|
|
|
1
1
|
module Solargraph
|
|
2
2
|
class ApiMap
|
|
3
3
|
class Probe
|
|
4
|
-
|
|
5
|
-
attr_reader :return_type
|
|
6
|
-
def initialize return_type
|
|
7
|
-
@return_type = return_type
|
|
8
|
-
end
|
|
9
|
-
end
|
|
4
|
+
include TypeMethods
|
|
10
5
|
|
|
11
6
|
# @return [Solargraph::ApiMap]
|
|
12
7
|
attr_reader :api_map
|
|
@@ -24,8 +19,8 @@ module Solargraph
|
|
|
24
19
|
return infer_word_pins(base, context_pin, locals) if rest.nil?
|
|
25
20
|
pins = infer_word_pins(base, context_pin, locals).map do |pin|
|
|
26
21
|
next pin unless pin.return_type.nil?
|
|
27
|
-
type = resolve_pin_type(pin)
|
|
28
|
-
|
|
22
|
+
type = resolve_pin_type(pin, locals - [pin])
|
|
23
|
+
Pin::ProxyMethod.new(type)
|
|
29
24
|
end
|
|
30
25
|
return [] if pins.empty?
|
|
31
26
|
rest = rest.split('.')
|
|
@@ -53,7 +48,7 @@ module Solargraph
|
|
|
53
48
|
def infer_signature_type signature, context_pin, locals
|
|
54
49
|
pins = infer_signature_pins(signature, context_pin, locals)
|
|
55
50
|
pins.each do |pin|
|
|
56
|
-
type = resolve_pin_type(pin)
|
|
51
|
+
type = resolve_pin_type(pin, locals - [pin])
|
|
57
52
|
return qualify(type, pin.named_context) unless type.nil?
|
|
58
53
|
end
|
|
59
54
|
nil
|
|
@@ -70,15 +65,25 @@ module Solargraph
|
|
|
70
65
|
namespace, scope = extract_namespace_and_scope_from_pin(context_pin)
|
|
71
66
|
return api_map.pins.select{|pin| word_matches_context?(word, namespace, scope, pin)} if variable_name?(word)
|
|
72
67
|
result = []
|
|
73
|
-
|
|
68
|
+
cparts = namespace.split('::')
|
|
69
|
+
until cparts.empty?
|
|
70
|
+
break unless result.empty?
|
|
71
|
+
cur = cparts.join('::')
|
|
72
|
+
result.concat api_map.get_path_suggestions("#{cur}::#{word}")
|
|
73
|
+
cparts.pop
|
|
74
|
+
end
|
|
75
|
+
result.concat api_map.get_path_suggestions(word) if result.empty?
|
|
74
76
|
result.concat api_map.get_methods(namespace, scope: scope, visibility: [:public, :private, :protected]).select{|pin| pin.name == word} unless word.include?('::')
|
|
75
|
-
result.concat api_map.get_constants('', namespace).select{|pin| pin.name == word}
|
|
77
|
+
result.concat api_map.get_constants('', namespace).select{|pin| pin.name == word} if result.empty?
|
|
76
78
|
result
|
|
77
79
|
end
|
|
78
80
|
|
|
79
81
|
# Method name search is external by default
|
|
82
|
+
# @param method_name [String]
|
|
83
|
+
# @param context_pin [Solargraph::Pin::Base]
|
|
80
84
|
def infer_method_name_pins method_name, context_pin, internal = false
|
|
81
|
-
|
|
85
|
+
relname, scope = extract_namespace_and_scope(context_pin.return_type)
|
|
86
|
+
namespace = api_map.qualify(relname, context_pin.namespace)
|
|
82
87
|
visibility = [:public]
|
|
83
88
|
visibility.push :protected, :private if internal
|
|
84
89
|
result = api_map.get_methods(namespace, scope: scope, visibility: visibility).select{|pin| pin.name == method_name}
|
|
@@ -110,35 +115,6 @@ module Solargraph
|
|
|
110
115
|
type.sub(/<#{rns}>/, "<#{res}>")
|
|
111
116
|
end
|
|
112
117
|
|
|
113
|
-
# Extract a namespace from a type.
|
|
114
|
-
#
|
|
115
|
-
# @example
|
|
116
|
-
# extract_namespace('String') => 'String'
|
|
117
|
-
# extract_namespace('Class<String>') => 'String'
|
|
118
|
-
#
|
|
119
|
-
# @return [String]
|
|
120
|
-
def extract_namespace type
|
|
121
|
-
extract_namespace_and_scope(type)[0]
|
|
122
|
-
end
|
|
123
|
-
|
|
124
|
-
# Extract a namespace and a scope (:instance or :class) from a type.
|
|
125
|
-
#
|
|
126
|
-
# @example
|
|
127
|
-
# extract_namespace('String') #=> ['String', :instance]
|
|
128
|
-
# extract_namespace('Class<String>') #=> ['String', :class]
|
|
129
|
-
# extract_namespace('Module<Enumerable') #=> ['Enumberable', :class]
|
|
130
|
-
#
|
|
131
|
-
# @return [Array] The namespace (String) and scope (Symbol).
|
|
132
|
-
def extract_namespace_and_scope type
|
|
133
|
-
scope = :instance
|
|
134
|
-
result = type.to_s.gsub(/<.*$/, '')
|
|
135
|
-
if (result == 'Class' or result == 'Module') and type.include?('<')
|
|
136
|
-
result = type.match(/<([a-z0-9:_]*)/i)[1]
|
|
137
|
-
scope = :class
|
|
138
|
-
end
|
|
139
|
-
[result, scope]
|
|
140
|
-
end
|
|
141
|
-
|
|
142
118
|
# Extract a namespace and a scope from a pin. For now, the pin must
|
|
143
119
|
# be either a namespace, a method, or a block.
|
|
144
120
|
#
|
|
@@ -172,11 +148,11 @@ module Solargraph
|
|
|
172
148
|
pin
|
|
173
149
|
end
|
|
174
150
|
|
|
175
|
-
def resolve_pin_type pin
|
|
151
|
+
def resolve_pin_type pin, locals
|
|
176
152
|
pin.return_type
|
|
177
153
|
return pin.return_type unless pin.return_type.nil?
|
|
178
154
|
return resolve_block_parameter(pin) if pin.kind == Pin::BLOCK_PARAMETER
|
|
179
|
-
return resolve_variable(pin) if pin.variable?
|
|
155
|
+
return resolve_variable(pin, locals) if pin.variable?
|
|
180
156
|
nil
|
|
181
157
|
end
|
|
182
158
|
|
|
@@ -205,10 +181,10 @@ module Solargraph
|
|
|
205
181
|
nil
|
|
206
182
|
end
|
|
207
183
|
|
|
208
|
-
def resolve_variable(pin)
|
|
184
|
+
def resolve_variable(pin, locals)
|
|
209
185
|
return nil if pin.nil_assignment?
|
|
210
186
|
# @todo Do we need the locals here?
|
|
211
|
-
return infer_signature_type(pin.signature, pin.context,
|
|
187
|
+
return infer_signature_type(pin.signature, pin.context, locals)
|
|
212
188
|
end
|
|
213
189
|
|
|
214
190
|
def get_subtypes type
|
|
@@ -43,8 +43,8 @@ module Solargraph
|
|
|
43
43
|
}
|
|
44
44
|
end
|
|
45
45
|
|
|
46
|
-
def get_attrs fqns
|
|
47
|
-
namespace_pins(fqns).select{ |pin| pin.kind == Pin::ATTRIBUTE }
|
|
46
|
+
def get_attrs fqns, scope
|
|
47
|
+
namespace_pins(fqns).select{ |pin| pin.kind == Pin::ATTRIBUTE and pin.scope == scope }
|
|
48
48
|
end
|
|
49
49
|
|
|
50
50
|
def get_superclass fqns
|
|
@@ -80,6 +80,10 @@ module Solargraph
|
|
|
80
80
|
namespace_pins(fqns).select{|pin| pin.kind == Pin::INSTANCE_VARIABLE and pin.scope == scope}
|
|
81
81
|
end
|
|
82
82
|
|
|
83
|
+
def get_class_variables(fqns)
|
|
84
|
+
namespace_pins(fqns).select{|pin| pin.kind == Pin::CLASS_VARIABLE}
|
|
85
|
+
end
|
|
86
|
+
|
|
83
87
|
def get_symbols
|
|
84
88
|
symbols.uniq(&:name)
|
|
85
89
|
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
module Solargraph
|
|
2
|
+
class ApiMap
|
|
3
|
+
# Module functions for processing YARD types.
|
|
4
|
+
#
|
|
5
|
+
module TypeMethods
|
|
6
|
+
module_function
|
|
7
|
+
|
|
8
|
+
# Extract a namespace from a type.
|
|
9
|
+
#
|
|
10
|
+
# @example
|
|
11
|
+
# extract_namespace('String') => 'String'
|
|
12
|
+
# extract_namespace('Class<String>') => 'String'
|
|
13
|
+
#
|
|
14
|
+
# @param type [String]
|
|
15
|
+
# @return [String]
|
|
16
|
+
def extract_namespace type
|
|
17
|
+
extract_namespace_and_scope(type)[0]
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Extract a namespace and a scope (:instance or :class) from a type.
|
|
21
|
+
#
|
|
22
|
+
# @example
|
|
23
|
+
# extract_namespace('String') #=> ['String', :instance]
|
|
24
|
+
# extract_namespace('Class<String>') #=> ['String', :class]
|
|
25
|
+
# extract_namespace('Module<Enumerable') #=> ['Enumberable', :class]
|
|
26
|
+
#
|
|
27
|
+
# @param type [String]
|
|
28
|
+
# @return [Array] The namespace (String) and scope (Symbol).
|
|
29
|
+
def extract_namespace_and_scope type
|
|
30
|
+
scope = :instance
|
|
31
|
+
result = type.to_s.gsub(/<.*$/, '')
|
|
32
|
+
if (result == 'Class' or result == 'Module') and type.include?('<')
|
|
33
|
+
result = type.match(/<([a-z0-9:_]*)/i)[1]
|
|
34
|
+
scope = :class
|
|
35
|
+
end
|
|
36
|
+
[result, scope]
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
data/lib/solargraph/api_map.rb
CHANGED
|
@@ -9,15 +9,25 @@ module Solargraph
|
|
|
9
9
|
autoload :Completion, 'solargraph/api_map/completion'
|
|
10
10
|
autoload :Probe, 'solargraph/api_map/probe'
|
|
11
11
|
autoload :Store, 'solargraph/api_map/store'
|
|
12
|
+
autoload :TypeMethods, 'solargraph/api_map/type_methods'
|
|
12
13
|
|
|
13
14
|
include Solargraph::ApiMap::SourceToYard
|
|
14
15
|
include CoreFills
|
|
16
|
+
include TypeMethods
|
|
15
17
|
|
|
16
18
|
# The workspace to analyze and process.
|
|
17
19
|
#
|
|
18
20
|
# @return [Solargraph::Workspace]
|
|
19
21
|
attr_reader :workspace
|
|
20
22
|
|
|
23
|
+
# @return [ApiMap::Store]
|
|
24
|
+
attr_reader :store
|
|
25
|
+
|
|
26
|
+
# Get a LiveMap associated with the current workspace.
|
|
27
|
+
#
|
|
28
|
+
# @return [Solargraph::LiveMap]
|
|
29
|
+
attr_reader :live_map
|
|
30
|
+
|
|
21
31
|
# @param workspace [Solargraph::Workspace]
|
|
22
32
|
def initialize workspace = Solargraph::Workspace.new(nil)
|
|
23
33
|
@workspace = workspace
|
|
@@ -26,7 +36,7 @@ module Solargraph
|
|
|
26
36
|
@yard_stale = true
|
|
27
37
|
# process_maps
|
|
28
38
|
@sources = workspace.sources
|
|
29
|
-
|
|
39
|
+
refresh_store_and_maps
|
|
30
40
|
end
|
|
31
41
|
|
|
32
42
|
# Create an ApiMap with a workspace in the specified directory.
|
|
@@ -36,11 +46,6 @@ module Solargraph
|
|
|
36
46
|
self.new(Solargraph::Workspace.new(directory))
|
|
37
47
|
end
|
|
38
48
|
|
|
39
|
-
# @return [ApiMap::Store]
|
|
40
|
-
def store
|
|
41
|
-
@store ||= ApiMap::Store.new(@sources)
|
|
42
|
-
end
|
|
43
|
-
|
|
44
49
|
def pins
|
|
45
50
|
store.pins
|
|
46
51
|
end
|
|
@@ -66,19 +71,12 @@ module Solargraph
|
|
|
66
71
|
# @return [Solargraph::YardMap]
|
|
67
72
|
def yard_map
|
|
68
73
|
# refresh
|
|
69
|
-
if @yard_map.
|
|
74
|
+
if @yard_map.required.to_set != required.to_set
|
|
70
75
|
@yard_map = Solargraph::YardMap.new(required: required, workspace: workspace)
|
|
71
76
|
end
|
|
72
77
|
@yard_map
|
|
73
78
|
end
|
|
74
79
|
|
|
75
|
-
# Get a LiveMap associated with the current workspace.
|
|
76
|
-
#
|
|
77
|
-
# @return [Solargraph::LiveMap]
|
|
78
|
-
def live_map
|
|
79
|
-
@live_map ||= Solargraph::LiveMap.new(self)
|
|
80
|
-
end
|
|
81
|
-
|
|
82
80
|
# Declare a virtual source that will be included in the map regardless of
|
|
83
81
|
# whether it's in the workspace.
|
|
84
82
|
#
|
|
@@ -229,7 +227,7 @@ module Solargraph
|
|
|
229
227
|
# @param namespace [String] A fully qualified namespace
|
|
230
228
|
# @return [Array<Solargraph::Pin::ClassVariable>]
|
|
231
229
|
def get_class_variable_pins(namespace)
|
|
232
|
-
prefer_non_nil_variables(
|
|
230
|
+
prefer_non_nil_variables(store.get_class_variables(namespace))
|
|
233
231
|
end
|
|
234
232
|
|
|
235
233
|
# @return [Array<Solargraph::Pin::Base>]
|
|
@@ -260,6 +258,11 @@ module Solargraph
|
|
|
260
258
|
else
|
|
261
259
|
result.concat inner_get_methods(fqns, scope, visibility, deep, skip)
|
|
262
260
|
end
|
|
261
|
+
live = live_map.get_methods(fqns, '', scope.to_s, visibility.include?(:private))
|
|
262
|
+
unless live.empty?
|
|
263
|
+
exist = result.map(&:name)
|
|
264
|
+
result.concat live.reject{|p| exist.include?(p.name)}
|
|
265
|
+
end
|
|
263
266
|
result
|
|
264
267
|
end
|
|
265
268
|
|
|
@@ -293,7 +296,7 @@ module Solargraph
|
|
|
293
296
|
if fragment.base.empty?
|
|
294
297
|
result.concat get_methods(pin.path)
|
|
295
298
|
else
|
|
296
|
-
type = probe.infer_signature_type(fragment.base, pin, fragment.locals)
|
|
299
|
+
type = probe.infer_signature_type("#{pin.path}.new.#{fragment.base}", pin, fragment.locals)
|
|
297
300
|
unless type.nil?
|
|
298
301
|
namespace, scope = extract_namespace_and_scope(type)
|
|
299
302
|
result.concat get_methods(namespace, scope: scope)
|
|
@@ -310,7 +313,8 @@ module Solargraph
|
|
|
310
313
|
end
|
|
311
314
|
end
|
|
312
315
|
end
|
|
313
|
-
|
|
316
|
+
frag_start = fragment.word.to_s.downcase
|
|
317
|
+
filtered = result.uniq(&:identifier).select{|s| s.name.downcase.start_with?(frag_start) and (s.kind != Pin::METHOD or s.name.match(/^[a-z0-9_]*(\!|\?|=)?$/i))}.sort_by.with_index{ |x, idx| [x.name, idx] }
|
|
314
318
|
Completion.new(filtered, fragment.whole_word_range)
|
|
315
319
|
end
|
|
316
320
|
|
|
@@ -318,7 +322,11 @@ module Solargraph
|
|
|
318
322
|
# @return [Array<Solargraph::Pin::Base>]
|
|
319
323
|
def define fragment
|
|
320
324
|
return [] if fragment.string? or fragment.comment?
|
|
321
|
-
|
|
325
|
+
if fragment.base_literal?
|
|
326
|
+
probe.infer_signature_pins fragment.whole_signature, Pin::ProxyMethod.new(fragment.base_literal), fragment.locals
|
|
327
|
+
else
|
|
328
|
+
probe.infer_signature_pins fragment.whole_signature, fragment.named_path, fragment.locals
|
|
329
|
+
end
|
|
322
330
|
end
|
|
323
331
|
|
|
324
332
|
# Infer a return type from a fragment. This method will attempt to resolve
|
|
@@ -342,9 +350,13 @@ module Solargraph
|
|
|
342
350
|
def signify fragment
|
|
343
351
|
return [] unless fragment.argument?
|
|
344
352
|
return [] if fragment.recipient.whole_signature.nil? or fragment.recipient.whole_signature.empty?
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
353
|
+
result = []
|
|
354
|
+
if fragment.recipient.base_literal?
|
|
355
|
+
result.concat probe.infer_signature_pins(fragment.recipient.whole_signature, Pin::ProxyMethod.new(fragment.recipient.base_literal), fragment.locals)
|
|
356
|
+
else
|
|
357
|
+
result.concat probe.infer_signature_pins(fragment.recipient.whole_signature, fragment.named_path, fragment.locals)
|
|
358
|
+
end
|
|
359
|
+
result.select{ |pin| pin.kind == Pin::METHOD }
|
|
348
360
|
end
|
|
349
361
|
|
|
350
362
|
# Get an array of all suggestions that match the specified path.
|
|
@@ -356,6 +368,10 @@ module Solargraph
|
|
|
356
368
|
result = []
|
|
357
369
|
result.concat store.get_path_pins(path)
|
|
358
370
|
result.concat yard_map.objects(path)
|
|
371
|
+
if result.empty?
|
|
372
|
+
lp = live_map.get_path_pin(path)
|
|
373
|
+
result.push lp unless lp.nil?
|
|
374
|
+
end
|
|
359
375
|
result
|
|
360
376
|
end
|
|
361
377
|
|
|
@@ -423,6 +439,12 @@ module Solargraph
|
|
|
423
439
|
|
|
424
440
|
private
|
|
425
441
|
|
|
442
|
+
def refresh_store_and_maps
|
|
443
|
+
@store = ApiMap::Store.new(@sources)
|
|
444
|
+
@live_map = Solargraph::LiveMap.new(self)
|
|
445
|
+
@yard_map = Solargraph::YardMap.new(required: required, workspace: workspace)
|
|
446
|
+
end
|
|
447
|
+
|
|
426
448
|
def process_virtual
|
|
427
449
|
unless @virtual_source.nil?
|
|
428
450
|
map_source @virtual_source
|
|
@@ -448,9 +470,7 @@ module Solargraph
|
|
|
448
470
|
return [] if skip.include?(reqstr)
|
|
449
471
|
skip.push reqstr
|
|
450
472
|
result = []
|
|
451
|
-
|
|
452
|
-
result.concat store.get_attrs(fqns)
|
|
453
|
-
end
|
|
473
|
+
result.concat store.get_attrs(fqns, scope)
|
|
454
474
|
result.concat store.get_methods(fqns, scope: scope, visibility: visibility)
|
|
455
475
|
if deep
|
|
456
476
|
sc = store.get_superclass(fqns)
|
|
@@ -475,7 +495,7 @@ module Solargraph
|
|
|
475
495
|
result.concat yard_map.get_methods(fqns, '', visibility: visibility)
|
|
476
496
|
type = get_namespace_type(fqns)
|
|
477
497
|
result.concat inner_get_methods('Class', :instance, fqns == '' ? [:public] : visibility, deep, skip) if type == :class
|
|
478
|
-
result.concat inner_get_methods('Module', :instance, fqns == '' ? [:public] : visibility, deep, skip)
|
|
498
|
+
result.concat inner_get_methods('Module', :instance, fqns == '' ? [:public] : visibility, deep, skip) if type == :module
|
|
479
499
|
end
|
|
480
500
|
end
|
|
481
501
|
result
|
|
@@ -568,15 +588,5 @@ module Solargraph
|
|
|
568
588
|
return yard_map.get_namespace_type(fqns) if pin.nil?
|
|
569
589
|
pin.type
|
|
570
590
|
end
|
|
571
|
-
|
|
572
|
-
def extract_namespace_and_scope type
|
|
573
|
-
scope = :instance
|
|
574
|
-
result = type.to_s.gsub(/<.*$/, '')
|
|
575
|
-
if (result == 'Class' or result == 'Module') and type.include?('<')
|
|
576
|
-
result = type.match(/<([a-z0-9:_]*)/i)[1]
|
|
577
|
-
scope = :class
|
|
578
|
-
end
|
|
579
|
-
[result, scope]
|
|
580
|
-
end
|
|
581
591
|
end
|
|
582
592
|
end
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
module Solargraph
|
|
2
2
|
module Diagnostics
|
|
3
|
+
# RequireNotFound reports required paths that could not be resolved to
|
|
4
|
+
# either a file in the workspace or a gem.
|
|
5
|
+
#
|
|
6
|
+
# @todo Some stdlib paths can result in false positives.
|
|
7
|
+
#
|
|
3
8
|
class RequireNotFound < Base
|
|
4
9
|
def diagnose source, api_map
|
|
5
10
|
result = []
|
|
@@ -3,6 +3,8 @@ require 'shellwords'
|
|
|
3
3
|
|
|
4
4
|
module Solargraph
|
|
5
5
|
module Diagnostics
|
|
6
|
+
# This reporter provides linting through RuboCop.
|
|
7
|
+
#
|
|
6
8
|
class Rubocop < Base
|
|
7
9
|
# The rubocop command
|
|
8
10
|
#
|
|
@@ -13,6 +15,8 @@ module Solargraph
|
|
|
13
15
|
@command = command
|
|
14
16
|
end
|
|
15
17
|
|
|
18
|
+
# @param source [Solargraph::Source]
|
|
19
|
+
# @param api_map [Solargraph::ApiMap]
|
|
16
20
|
# @return [Array<Hash>]
|
|
17
21
|
def diagnose source, api_map
|
|
18
22
|
begin
|
|
@@ -20,7 +24,12 @@ module Solargraph
|
|
|
20
24
|
filename = source.filename
|
|
21
25
|
raise DiagnosticsError, 'No command specified' if command.nil? or command.empty?
|
|
22
26
|
cmd = "#{Shellwords.escape(command)} -f j -s #{Shellwords.escape(filename)}"
|
|
27
|
+
unless api_map.workspace.nil? or api_map.workspace.directory.nil?
|
|
28
|
+
rc = File.join(api_map.workspace.directory, '.rubocop.yml')
|
|
29
|
+
cmd += " -c #{Shellwords.escape(rc)}" if File.file?(rc)
|
|
30
|
+
end
|
|
23
31
|
o, e, s = Open3.capture3(cmd, stdin_data: text)
|
|
32
|
+
STDERR.puts e unless e.empty?
|
|
24
33
|
raise DiagnosticsError, "Command '#{command}' is not available (gem exception)" if e.include?('Gem::Exception')
|
|
25
34
|
raise DiagnosticsError, "RuboCop returned empty data" if o.empty?
|
|
26
35
|
make_array JSON.parse(o)
|
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
module Solargraph
|
|
2
|
+
# The Diagnostics library provides reporters for analyzing problems in code
|
|
3
|
+
# and providing the results to language server clients.
|
|
4
|
+
#
|
|
2
5
|
module Diagnostics
|
|
3
6
|
autoload :Base, 'solargraph/diagnostics/base'
|
|
4
7
|
autoload :Severities, 'solargraph/diagnostics/severities'
|
|
5
8
|
autoload :Rubocop, 'solargraph/diagnostics/rubocop'
|
|
6
9
|
autoload :RequireNotFound, 'solargraph/diagnostics/require_not_found'
|
|
7
10
|
|
|
11
|
+
# Reporters identified by name for activation in .solargraph.yml files.
|
|
12
|
+
#
|
|
8
13
|
REPORTERS = {
|
|
9
14
|
'rubocop' => Rubocop,
|
|
10
15
|
'require_not_found' => RequireNotFound
|
|
@@ -323,6 +323,14 @@ module Solargraph
|
|
|
323
323
|
result
|
|
324
324
|
end
|
|
325
325
|
|
|
326
|
+
def references_from filename, line, column
|
|
327
|
+
result = nil
|
|
328
|
+
@change_semaphore.synchronize do
|
|
329
|
+
result = library.references_from(filename, line, column)
|
|
330
|
+
end
|
|
331
|
+
result
|
|
332
|
+
end
|
|
333
|
+
|
|
326
334
|
def query_symbols query
|
|
327
335
|
result = nil
|
|
328
336
|
@change_semaphore.synchronize { result = library.query_symbols(query) }
|
|
@@ -446,7 +454,7 @@ module Solargraph
|
|
|
446
454
|
Thread.new do
|
|
447
455
|
diagnoser = Diagnostics::Rubocop.new
|
|
448
456
|
until stopped?
|
|
449
|
-
sleep 1
|
|
457
|
+
sleep 0.1
|
|
450
458
|
if !options['diagnostics']
|
|
451
459
|
@change_semaphore.synchronize { @diagnostics_queue.clear }
|
|
452
460
|
next
|
|
@@ -37,14 +37,7 @@ module Solargraph
|
|
|
37
37
|
}
|
|
38
38
|
end
|
|
39
39
|
|
|
40
|
-
def
|
|
41
|
-
response = {}
|
|
42
|
-
response[:result] = result
|
|
43
|
-
response[:error] = error unless error.nil?
|
|
44
|
-
response
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
def send
|
|
40
|
+
def send_response
|
|
48
41
|
unless id.nil? or host.cancel?(id)
|
|
49
42
|
response = {
|
|
50
43
|
jsonrpc: "2.0",
|
|
@@ -11,7 +11,7 @@ module Solargraph
|
|
|
11
11
|
class CheckGemVersion < Base
|
|
12
12
|
def process
|
|
13
13
|
o, s = Open3.capture2("gem search solargraph")
|
|
14
|
-
match = o.match(/solargraph \([
|
|
14
|
+
match = o.match(/solargraph \(([\d]*\.[\d]*\.[\d]*)\)/)
|
|
15
15
|
# @todo Error if no match or status code != 0
|
|
16
16
|
available = Gem::Version.new(match[1])
|
|
17
17
|
current = Gem::Version.new(Solargraph::VERSION)
|
|
@@ -30,6 +30,10 @@ module Solargraph
|
|
|
30
30
|
elsif params['verbose']
|
|
31
31
|
host.show_message "The Solargraph gem is up to date (version #{Solargraph::VERSION})."
|
|
32
32
|
end
|
|
33
|
+
set_result({
|
|
34
|
+
installed: current,
|
|
35
|
+
available: available
|
|
36
|
+
})
|
|
33
37
|
end
|
|
34
38
|
end
|
|
35
39
|
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
require 'open3'
|
|
2
|
+
|
|
3
|
+
module Solargraph
|
|
4
|
+
module LanguageServer
|
|
5
|
+
module Message
|
|
6
|
+
module Extended
|
|
7
|
+
# Update core Ruby documentation.
|
|
8
|
+
#
|
|
9
|
+
class DownloadCore < Base
|
|
10
|
+
def process
|
|
11
|
+
cmd = "solargraph download-core"
|
|
12
|
+
o, s = Open3.capture2(cmd)
|
|
13
|
+
if s != 0
|
|
14
|
+
host.show_message "An error occurred while downloading documentation.", LanguageServer::MessageTypes::ERROR
|
|
15
|
+
else
|
|
16
|
+
ver = o.match(/[\d]*\.[\d]*\.[\d]*/)[0]
|
|
17
|
+
host.show_message "Downloaded documentation for Ruby #{ver}.", LanguageServer::MessageTypes::INFO
|
|
18
|
+
# @todo YardMap should be refreshed
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -11,6 +11,7 @@ module Solargraph
|
|
|
11
11
|
autoload :Search, 'solargraph/language_server/message/extended/search'
|
|
12
12
|
autoload :CheckGemVersion, 'solargraph/language_server/message/extended/check_gem_version'
|
|
13
13
|
autoload :DocumentGems, 'solargraph/language_server/message/extended/document_gems'
|
|
14
|
+
autoload :DownloadCore, 'solargraph/language_server/message/extended/download_core'
|
|
14
15
|
end
|
|
15
16
|
end
|
|
16
17
|
end
|
|
@@ -11,12 +11,14 @@ module Solargraph
|
|
|
11
11
|
definitionProvider: true,
|
|
12
12
|
documentSymbolProvider: true,
|
|
13
13
|
workspaceSymbolProvider: true,
|
|
14
|
+
renameProvider: true,
|
|
14
15
|
workspace: {
|
|
15
16
|
workspaceFolders: {
|
|
16
17
|
supported: true,
|
|
17
18
|
changeNotifications: true
|
|
18
19
|
}
|
|
19
|
-
}
|
|
20
|
+
},
|
|
21
|
+
referencesProvider: true
|
|
20
22
|
}
|
|
21
23
|
}
|
|
22
24
|
result[:capabilities].merge! static_completion unless dynamic_completion?
|
|
@@ -11,7 +11,7 @@ module Solargraph::LanguageServer::Message::TextDocument
|
|
|
11
11
|
line = params['position']['line']
|
|
12
12
|
col = params['position']['character']
|
|
13
13
|
suggestions = host.definitions_at(filename, line, col)
|
|
14
|
-
locations = suggestions.map do |pin|
|
|
14
|
+
locations = suggestions.reject{|pin| pin.location.nil?}.map do |pin|
|
|
15
15
|
unless pin.location.nil?
|
|
16
16
|
{
|
|
17
17
|
uri: file_to_uri(pin.location.filename),
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
module Solargraph::LanguageServer::Message::TextDocument
|
|
2
|
+
class References < Base
|
|
3
|
+
def process
|
|
4
|
+
locs = host.references_from(uri_to_file(params['textDocument']['uri']), params['position']['line'], params['position']['character'])
|
|
5
|
+
result = locs.map do |loc|
|
|
6
|
+
{
|
|
7
|
+
uri: file_to_uri(loc.filename),
|
|
8
|
+
range: loc.range.to_hash
|
|
9
|
+
}
|
|
10
|
+
end
|
|
11
|
+
set_result result
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module Solargraph::LanguageServer::Message::TextDocument
|
|
2
|
+
class Rename < Base
|
|
3
|
+
def process
|
|
4
|
+
locs = host.references_from(uri_to_file(params['textDocument']['uri']), params['position']['line'], params['position']['character'])
|
|
5
|
+
changes = {}
|
|
6
|
+
locs.each do |loc|
|
|
7
|
+
uri = file_to_uri(loc.filename)
|
|
8
|
+
changes[uri] ||= []
|
|
9
|
+
changes[uri].push({
|
|
10
|
+
range: loc.range.to_hash,
|
|
11
|
+
newText: params['newName']
|
|
12
|
+
})
|
|
13
|
+
end
|
|
14
|
+
set_result changes: changes
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -2,19 +2,21 @@ module Solargraph
|
|
|
2
2
|
module LanguageServer
|
|
3
3
|
module Message
|
|
4
4
|
module TextDocument
|
|
5
|
-
autoload :Base,
|
|
6
|
-
autoload :Completion,
|
|
7
|
-
autoload :DidOpen,
|
|
8
|
-
autoload :DidChange,
|
|
9
|
-
autoload :DidClose,
|
|
10
|
-
autoload :DidSave,
|
|
11
|
-
autoload :Hover,
|
|
12
|
-
autoload :SignatureHelp,
|
|
5
|
+
autoload :Base, 'solargraph/language_server/message/text_document/base'
|
|
6
|
+
autoload :Completion, 'solargraph/language_server/message/text_document/completion'
|
|
7
|
+
autoload :DidOpen, 'solargraph/language_server/message/text_document/did_open'
|
|
8
|
+
autoload :DidChange, 'solargraph/language_server/message/text_document/did_change'
|
|
9
|
+
autoload :DidClose, 'solargraph/language_server/message/text_document/did_close'
|
|
10
|
+
autoload :DidSave, 'solargraph/language_server/message/text_document/did_save'
|
|
11
|
+
autoload :Hover, 'solargraph/language_server/message/text_document/hover'
|
|
12
|
+
autoload :SignatureHelp, 'solargraph/language_server/message/text_document/signature_help'
|
|
13
13
|
autoload :DiagnosticsQueue, 'solargraph/language_server/message/text_document/diagnostics_queue'
|
|
14
14
|
autoload :OnTypeFormatting, 'solargraph/language_server/message/text_document/on_type_formatting'
|
|
15
|
-
autoload :Definition,
|
|
16
|
-
autoload :DocumentSymbol,
|
|
17
|
-
autoload :Formatting,
|
|
15
|
+
autoload :Definition, 'solargraph/language_server/message/text_document/definition'
|
|
16
|
+
autoload :DocumentSymbol, 'solargraph/language_server/message/text_document/document_symbol'
|
|
17
|
+
autoload :Formatting, 'solargraph/language_server/message/text_document/formatting'
|
|
18
|
+
autoload :References, 'solargraph/language_server/message/text_document/references'
|
|
19
|
+
autoload :Rename, 'solargraph/language_server/message/text_document/rename'
|
|
18
20
|
end
|
|
19
21
|
end
|
|
20
22
|
end
|