solargraph 0.21.1 → 0.22.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/solargraph.rb +0 -1
- data/lib/solargraph/api_map.rb +40 -23
- data/lib/solargraph/api_map/completion.rb +3 -0
- data/lib/solargraph/api_map/probe.rb +16 -19
- data/lib/solargraph/api_map/store.rb +6 -2
- data/lib/solargraph/diagnostics/rubocop.rb +6 -0
- data/lib/solargraph/language_server/host.rb +9 -1
- data/lib/solargraph/language_server/message.rb +3 -0
- data/lib/solargraph/language_server/message/extended.rb +1 -0
- data/lib/solargraph/language_server/message/extended/check_gem_version.rb +1 -1
- data/lib/solargraph/language_server/message/extended/download_core.rb +25 -0
- data/lib/solargraph/language_server/message/initialize.rb +3 -1
- data/lib/solargraph/language_server/message/text_document.rb +13 -11
- 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/uri_helpers.rb +2 -0
- data/lib/solargraph/library.rb +37 -0
- data/lib/solargraph/live_map.rb +8 -2
- data/lib/solargraph/live_map/cache.rb +7 -0
- data/lib/solargraph/pin.rb +1 -0
- 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/plugin/process.rb +1 -1
- data/lib/solargraph/plugin/runtime.rb +0 -1
- data/lib/solargraph/shell.rb +0 -1
- data/lib/solargraph/source.rb +31 -1
- data/lib/solargraph/source/fragment.rb +12 -15
- data/lib/solargraph/source/location.rb +3 -0
- data/lib/solargraph/source/mapper.rb +20 -10
- data/lib/solargraph/source/node_methods.rb +111 -0
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/workspace.rb +7 -1
- data/lib/solargraph/workspace/config.rb +6 -2
- data/lib/solargraph/yard_map.rb +12 -1
- metadata +25 -7
- data/lib/solargraph/node_methods.rb +0 -101
@@ -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
|
data/lib/solargraph/library.rb
CHANGED
@@ -141,6 +141,30 @@ module Solargraph
|
|
141
141
|
api_map.signify(fragment)
|
142
142
|
end
|
143
143
|
|
144
|
+
def references_from filename, line, column
|
145
|
+
source = read(filename)
|
146
|
+
api_map.virtualize source
|
147
|
+
fragment = source.fragment_at(line, column)
|
148
|
+
pins = api_map.define(fragment)
|
149
|
+
return [] if pins.empty?
|
150
|
+
result = []
|
151
|
+
# @param pin [Solargraph::Pin::Base]
|
152
|
+
pins.uniq.each do |pin|
|
153
|
+
if pin.kind != Solargraph::Pin::NAMESPACE and !pin.location.nil?
|
154
|
+
mn_loc = get_symbol_name_location(pin)
|
155
|
+
result.push mn_loc unless mn_loc.nil?
|
156
|
+
end
|
157
|
+
(workspace.sources + source_hash.values).uniq(&:filename).each do |source|
|
158
|
+
found = source.references(pin.name).select do |loc|
|
159
|
+
referenced = definitions_at(loc.filename, loc.range.ending.line, loc.range.ending.character).first
|
160
|
+
!referenced.nil? and referenced.path == pin.path
|
161
|
+
end
|
162
|
+
result.concat found.sort{|a, b| a.range.start.line <=> b.range.start.line}
|
163
|
+
end
|
164
|
+
end
|
165
|
+
result
|
166
|
+
end
|
167
|
+
|
144
168
|
# Get the pin at the specified location or nil if the pin does not exist.
|
145
169
|
#
|
146
170
|
# @return [Solargraph::Pin::Base]
|
@@ -270,5 +294,18 @@ module Solargraph
|
|
270
294
|
raise FileNotFoundError, "File not found: #{filename}" unless File.file?(filename)
|
271
295
|
Solargraph::Source.load(filename)
|
272
296
|
end
|
297
|
+
|
298
|
+
def get_symbol_name_location pin
|
299
|
+
decsrc = read(pin.location.filename)
|
300
|
+
offset = Solargraph::Source::Position.to_offset(decsrc.code, pin.location.range.start)
|
301
|
+
soff = decsrc.code.index(pin.name, offset)
|
302
|
+
eoff = soff + pin.name.length
|
303
|
+
Solargraph::Source::Location.new(
|
304
|
+
pin.location.filename, Solargraph::Source::Range.new(
|
305
|
+
Solargraph::Source::Position.from_offset(decsrc.code, soff),
|
306
|
+
Solargraph::Source::Position.from_offset(decsrc.code, eoff)
|
307
|
+
)
|
308
|
+
)
|
309
|
+
end
|
273
310
|
end
|
274
311
|
end
|
data/lib/solargraph/live_map.rb
CHANGED
@@ -9,11 +9,17 @@ module Solargraph
|
|
9
9
|
# @return [Solargraph::ApiMap]
|
10
10
|
attr_reader :api_map
|
11
11
|
|
12
|
+
# @param api_map [Solargraph::ApiMap]
|
12
13
|
def initialize api_map
|
13
14
|
@api_map = api_map
|
14
15
|
runners
|
15
16
|
end
|
16
17
|
|
18
|
+
def get_path_pin path
|
19
|
+
cache.get_path_pin(path)
|
20
|
+
end
|
21
|
+
|
22
|
+
# @return [Array<Solargraph::Pin::Base>]
|
17
23
|
def get_methods(namespace, root = '', scope = 'instance', with_private = false)
|
18
24
|
fqns = api_map.find_fully_qualified_namespace(namespace, root)
|
19
25
|
params = {
|
@@ -26,7 +32,7 @@ module Solargraph
|
|
26
32
|
runners.each do |p|
|
27
33
|
next if did_runtime and p.runtime?
|
28
34
|
p.get_methods(namespace: namespace, root: root, scope: scope, with_private: with_private).each do |m|
|
29
|
-
result.push
|
35
|
+
result.push Solargraph::Pin::Method.new(nil, namespace, m['name'], YARD::Docstring.new('(defined at runtime)'), scope.to_sym, nil, [])
|
30
36
|
end
|
31
37
|
did_runtime = true if p.runtime?
|
32
38
|
end
|
@@ -34,7 +40,7 @@ module Solargraph
|
|
34
40
|
result
|
35
41
|
end
|
36
42
|
|
37
|
-
# @return [Array<Solargraph::
|
43
|
+
# @return [Array<Solargraph::Pin::Base>]
|
38
44
|
def get_constants(namespace, root = '')
|
39
45
|
cached = cache.get_constants(namespace, root)
|
40
46
|
return cached unless cached.nil?
|
@@ -4,6 +4,7 @@ module Solargraph
|
|
4
4
|
def initialize
|
5
5
|
@method_cache = {}
|
6
6
|
@constant_cache = {}
|
7
|
+
@path_cache = {}
|
7
8
|
end
|
8
9
|
|
9
10
|
def get_methods options
|
@@ -12,6 +13,7 @@ module Solargraph
|
|
12
13
|
|
13
14
|
def set_methods options, values
|
14
15
|
@method_cache[options] = values
|
16
|
+
values.each { |pin| @path_cache[pin.path] = pin }
|
15
17
|
end
|
16
18
|
|
17
19
|
def get_constants namespace, root
|
@@ -22,9 +24,14 @@ module Solargraph
|
|
22
24
|
@constant_cache[[namespace, root]] = values
|
23
25
|
end
|
24
26
|
|
27
|
+
def get_path_pin path
|
28
|
+
@path_cache[path]
|
29
|
+
end
|
30
|
+
|
25
31
|
def clear
|
26
32
|
@method_cache.clear
|
27
33
|
@constant_cache.clear
|
34
|
+
@path_cache.clear
|
28
35
|
end
|
29
36
|
end
|
30
37
|
end
|
data/lib/solargraph/pin.rb
CHANGED
@@ -21,6 +21,7 @@ module Solargraph
|
|
21
21
|
autoload :Documenting, 'solargraph/pin/documenting'
|
22
22
|
autoload :Block, 'solargraph/pin/block'
|
23
23
|
autoload :Localized, 'solargraph/pin/localized'
|
24
|
+
autoload :ProxyMethod, 'solargraph/pin/proxy_method'
|
24
25
|
|
25
26
|
ATTRIBUTE = 1
|
26
27
|
CLASS_VARIABLE = 2
|
@@ -4,10 +4,14 @@ module Solargraph
|
|
4
4
|
# @return [Symbol] :reader or :writer
|
5
5
|
attr_reader :access
|
6
6
|
|
7
|
-
|
7
|
+
# @return [Symbol] :class or :instance
|
8
|
+
attr_reader :scope
|
9
|
+
|
10
|
+
def initialize location, namespace, name, docstring, access, scope
|
8
11
|
super(location, namespace, name, docstring)
|
9
12
|
@access = access
|
10
13
|
@docstring = docstring
|
14
|
+
@scope = scope
|
11
15
|
end
|
12
16
|
|
13
17
|
def kind
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Solargraph
|
2
|
+
module Pin
|
3
|
+
# ProxyMethod serves as a quick, disposable shortcut for providing context
|
4
|
+
# to type inference methods. ApiMap::Probe can treat it as an anonymous
|
5
|
+
# method while analyzing signatures.
|
6
|
+
#
|
7
|
+
class ProxyMethod
|
8
|
+
# @return [String]
|
9
|
+
attr_reader :return_type
|
10
|
+
|
11
|
+
def initialize return_type
|
12
|
+
@return_type = return_type
|
13
|
+
end
|
14
|
+
|
15
|
+
# @return [String]
|
16
|
+
def namespace
|
17
|
+
@namespace ||= ApiMap::TypeMethods.extract_namespace(@return_type)
|
18
|
+
end
|
19
|
+
|
20
|
+
# @return [Integer]
|
21
|
+
def kind
|
22
|
+
Pin::METHOD
|
23
|
+
end
|
24
|
+
|
25
|
+
# @return [Symbol]
|
26
|
+
def scope
|
27
|
+
:instance
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -33,7 +33,7 @@ module Solargraph
|
|
33
33
|
rescue JSON::ParserError => e
|
34
34
|
STDOUT.puts respond_err "Error parsing input: #{e.message}"
|
35
35
|
rescue Exception => e
|
36
|
-
STDOUT.puts respond_err "Error processing input: #{e.message}"
|
36
|
+
STDOUT.puts respond_err "Error processing input: #{e.message}\n#{e.backtrace}"
|
37
37
|
end
|
38
38
|
STDOUT.flush
|
39
39
|
end
|
data/lib/solargraph/shell.rb
CHANGED
data/lib/solargraph/source.rb
CHANGED
@@ -11,6 +11,7 @@ module Solargraph
|
|
11
11
|
autoload :Updater, 'solargraph/source/updater'
|
12
12
|
autoload :Change, 'solargraph/source/change'
|
13
13
|
autoload :Mapper, 'solargraph/source/mapper'
|
14
|
+
autoload :NodeMethods, 'solargraph/source/node_methods'
|
14
15
|
|
15
16
|
# @return [String]
|
16
17
|
attr_reader :code
|
@@ -40,6 +41,7 @@ module Solargraph
|
|
40
41
|
# @return [Time]
|
41
42
|
attr_reader :stime
|
42
43
|
|
44
|
+
# @return [Array<Solargraph::Pin::Base>]
|
43
45
|
attr_reader :pins
|
44
46
|
|
45
47
|
attr_reader :requires
|
@@ -132,6 +134,22 @@ module Solargraph
|
|
132
134
|
symbol_pins
|
133
135
|
end
|
134
136
|
|
137
|
+
# @return [Array<Source::Location>]
|
138
|
+
def references name
|
139
|
+
inner_node_references(name, node).map do |n|
|
140
|
+
offset = Position.to_offset(code, get_node_start_position(n))
|
141
|
+
soff = code.index(name, offset)
|
142
|
+
eoff = soff + name.length
|
143
|
+
Location.new(
|
144
|
+
filename,
|
145
|
+
Solargraph::Source::Range.new(
|
146
|
+
Position.from_offset(code, soff),
|
147
|
+
Position.from_offset(code, eoff)
|
148
|
+
)
|
149
|
+
)
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
135
153
|
def locate_named_path_pin line, character
|
136
154
|
_locate_pin line, character, Pin::NAMESPACE, Pin::METHOD
|
137
155
|
end
|
@@ -157,7 +175,8 @@ module Solargraph
|
|
157
175
|
|
158
176
|
# Get the nearest node that contains the specified index.
|
159
177
|
#
|
160
|
-
# @param
|
178
|
+
# @param line [Integer]
|
179
|
+
# @param column [Integer]
|
161
180
|
# @return [AST::Node]
|
162
181
|
def node_at(line, column)
|
163
182
|
tree_at(line, column).first
|
@@ -246,6 +265,17 @@ module Solargraph
|
|
246
265
|
|
247
266
|
private
|
248
267
|
|
268
|
+
def inner_node_references name, top
|
269
|
+
result = []
|
270
|
+
if top.kind_of?(AST::Node)
|
271
|
+
if (top.type == :const and top.children[1].to_s == name) or (top.type == :send and top.children[1].to_s == name)
|
272
|
+
result.push top
|
273
|
+
end
|
274
|
+
top.children.each { |c| result.concat inner_node_references(name, c) }
|
275
|
+
end
|
276
|
+
result
|
277
|
+
end
|
278
|
+
|
249
279
|
def parse
|
250
280
|
node, comments = inner_parse(@fixed, filename)
|
251
281
|
@node = node
|
@@ -3,12 +3,11 @@ module Solargraph
|
|
3
3
|
class Fragment
|
4
4
|
include NodeMethods
|
5
5
|
|
6
|
-
attr_reader :tree
|
7
|
-
|
8
6
|
attr_reader :line
|
9
7
|
|
10
8
|
attr_reader :column
|
11
9
|
|
10
|
+
# @return [Solargraph::Source]
|
12
11
|
attr_reader :source
|
13
12
|
|
14
13
|
# @param source [Solargraph::Source]
|
@@ -46,17 +45,6 @@ module Solargraph
|
|
46
45
|
@argument ||= !signature_position.nil?
|
47
46
|
end
|
48
47
|
|
49
|
-
def chained?
|
50
|
-
if @chained.nil?
|
51
|
-
@chained = false
|
52
|
-
@tree.each do |n|
|
53
|
-
@chained = true if n.type == :send
|
54
|
-
break
|
55
|
-
end
|
56
|
-
end
|
57
|
-
@chained
|
58
|
-
end
|
59
|
-
|
60
48
|
# @return [Fragment]
|
61
49
|
def recipient
|
62
50
|
return nil if signature_position.nil?
|
@@ -319,9 +307,18 @@ module Solargraph
|
|
319
307
|
@base_literal = 'Integer'
|
320
308
|
# @todo Smelly exceptional case for array literals
|
321
309
|
elsif signature.start_with?('.[]')
|
322
|
-
index +=
|
323
|
-
signature = signature[
|
310
|
+
index += 2
|
311
|
+
signature = signature[3..-1].to_s
|
324
312
|
@base_literal = 'Array'
|
313
|
+
elsif signature.start_with?('.')
|
314
|
+
pos = Position.from_offset(source.code, index)
|
315
|
+
node = source.node_at(pos.line, pos.character)
|
316
|
+
lit = infer_literal_node_type(node)
|
317
|
+
unless lit.nil?
|
318
|
+
signature = signature[1..-1].to_s
|
319
|
+
index += 1
|
320
|
+
@base_literal = lit
|
321
|
+
end
|
325
322
|
end
|
326
323
|
[index + 1, signature]
|
327
324
|
end
|
@@ -106,9 +106,17 @@ module Solargraph
|
|
106
106
|
u = c.updated(:ivasgn, c.children + ora.children[1..-1], nil)
|
107
107
|
@docstring_hash[u.loc] = docstring_for(ora)
|
108
108
|
pins.push Solargraph::Pin::InstanceVariable.new(get_node_location(u), fqn || '', c.children[0].to_s, docstring_for(u), resolve_node_signature(u.children[1]), infer_literal_node_type(u.children[1]), context)
|
109
|
+
if visibility == :module_function and context.kind == Pin::METHOD
|
110
|
+
other = pins.select{|pin| pin.path == "#{context.namespace}.#{context.name}"}.first
|
111
|
+
pins.push Solargraph::Pin::InstanceVariable.new(get_node_location(u), fqn || '', c.children[0].to_s, docstring_for(u), resolve_node_signature(u.children[1]), infer_literal_node_type(u.children[1]), other) unless other.nil?
|
112
|
+
end
|
109
113
|
end
|
110
114
|
else
|
111
115
|
pins.push Solargraph::Pin::InstanceVariable.new(get_node_location(c), fqn || '',c.children[0].to_s, docstring_for(c), resolve_node_signature(c.children[1]), infer_literal_node_type(c.children[1]), context)
|
116
|
+
if visibility == :module_function and context.kind == Pin::METHOD
|
117
|
+
other = pins.select{|pin| pin.path == "#{context.namespace}.#{context.name}"}.first
|
118
|
+
pins.push Solargraph::Pin::InstanceVariable.new(get_node_location(c), fqn || '',c.children[0].to_s, docstring_for(c), resolve_node_signature(c.children[1]), infer_literal_node_type(c.children[1]), other)
|
119
|
+
end
|
112
120
|
end
|
113
121
|
elsif c.type == :cvasgn
|
114
122
|
here = get_node_start_position(c)
|
@@ -212,8 +220,14 @@ module Solargraph
|
|
212
220
|
ref = pins.select{|p| p.namespace == (fqn || '') and p.name == cn}.first
|
213
221
|
unless ref.nil?
|
214
222
|
pins.delete ref
|
215
|
-
|
216
|
-
|
223
|
+
mm = Solargraph::Pin::Method.new(ref.location, ref.namespace, ref.name, ref.docstring, :class, :public, ref.parameters)
|
224
|
+
cm = Solargraph::Pin::Method.new(ref.location, ref.namespace, ref.name, ref.docstring, :instance, :private, ref.parameters)
|
225
|
+
pins.push mm, cm
|
226
|
+
pins.select{|pin| pin.kind == Pin::INSTANCE_VARIABLE and pin.context == ref}.each do |ivar|
|
227
|
+
pins.delete ivar
|
228
|
+
pins.push Solargraph::Pin::InstanceVariable.new(ivar.location, ivar.namespace, ivar.name, ivar.docstring, ivar.signature, ivar.instance_variable_get(:@literal), mm)
|
229
|
+
pins.push Solargraph::Pin::InstanceVariable.new(ivar.location, ivar.namespace, ivar.name, ivar.docstring, ivar.signature, ivar.instance_variable_get(:@literal), cm)
|
230
|
+
end
|
217
231
|
end
|
218
232
|
end
|
219
233
|
elsif c.children[2].type == :def
|
@@ -253,10 +267,10 @@ module Solargraph
|
|
253
267
|
elsif c.type == :send and [:attr_reader, :attr_writer, :attr_accessor].include?(c.children[1])
|
254
268
|
c.children[2..-1].each do |a|
|
255
269
|
if c.children[1] == :attr_reader or c.children[1] == :attr_accessor
|
256
|
-
pins.push Solargraph::Pin::Attribute.new(get_node_location(c), fqn || '', "#{a.children[0]}", docstring_for(c), :reader
|
270
|
+
pins.push Solargraph::Pin::Attribute.new(get_node_location(c), fqn || '', "#{a.children[0]}", docstring_for(c), :reader, scope)
|
257
271
|
end
|
258
272
|
if c.children[1] == :attr_writer or c.children[1] == :attr_accessor
|
259
|
-
pins.push Solargraph::Pin::Attribute.new(get_node_location(c), fqn || '', "#{a.children[0]}=", docstring_for(c), :writer
|
273
|
+
pins.push Solargraph::Pin::Attribute.new(get_node_location(c), fqn || '', "#{a.children[0]}=", docstring_for(c), :writer, scope)
|
260
274
|
end
|
261
275
|
end
|
262
276
|
elsif c.type == :sclass and c.children[0].type == :self
|
@@ -330,10 +344,6 @@ module Solargraph
|
|
330
344
|
nil
|
331
345
|
end
|
332
346
|
|
333
|
-
def get_node_start_position(node)
|
334
|
-
Position.new(node.loc.line - 1, node.loc.column)
|
335
|
-
end
|
336
|
-
|
337
347
|
def get_node_location(node)
|
338
348
|
if node.nil?
|
339
349
|
st = Position.new(0, 0)
|
@@ -392,10 +402,10 @@ module Solargraph
|
|
392
402
|
t = (d.tag.types.nil? || d.tag.types.empty?) ? nil : d.tag.types.flatten.join('')
|
393
403
|
if t.nil? or t.include?('r')
|
394
404
|
# location, namespace, name, docstring, access
|
395
|
-
pins.push Solargraph::Pin::Attribute.new(get_node_location(k.node), namespace_for(k.node).path, d.tag.name, docstring, :reader)
|
405
|
+
pins.push Solargraph::Pin::Attribute.new(get_node_location(k.node), namespace_for(k.node).path, d.tag.name, docstring, :reader, :instance)
|
396
406
|
end
|
397
407
|
if t.nil? or t.include?('w')
|
398
|
-
pins.push Solargraph::Pin::Attribute.new(get_node_location(k.node), namespace_for(k.node).path, "#{d.tag.name}=", docstring, :
|
408
|
+
pins.push Solargraph::Pin::Attribute.new(get_node_location(k.node), namespace_for(k.node).path, "#{d.tag.name}=", docstring, :writer, :instance)
|
399
409
|
end
|
400
410
|
elsif d.tag.tag_name == 'method'
|
401
411
|
gen_src = Source.new("def #{d.tag.name};end", filename)
|