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
|
@@ -56,6 +56,8 @@ module Solargraph
|
|
|
56
56
|
register 'textDocument/formatting', TextDocument::Formatting
|
|
57
57
|
register 'textDocument/onTypeFormatting', TextDocument::OnTypeFormatting
|
|
58
58
|
register 'textDocument/documentSymbol', TextDocument::DocumentSymbol
|
|
59
|
+
register 'textDocument/references', TextDocument::References
|
|
60
|
+
register 'textDocument/rename', TextDocument::Rename
|
|
59
61
|
register 'workspace/didChangeWatchedFiles', Workspace::DidChangeWatchedFiles
|
|
60
62
|
register 'workspace/didChangeConfiguration', Workspace::DidChangeConfiguration
|
|
61
63
|
register 'workspace/symbol', Workspace::WorkspaceSymbol
|
|
@@ -64,6 +66,7 @@ module Solargraph
|
|
|
64
66
|
register '$/solargraph/search', Extended::Search
|
|
65
67
|
register '$/solargraph/checkGemVersion', Extended::CheckGemVersion
|
|
66
68
|
register '$/solargraph/documentGems', Extended::DocumentGems
|
|
69
|
+
register '$/solargraph/downloadCore', Extended::DownloadCore
|
|
67
70
|
register 'shutdown', Shutdown
|
|
68
71
|
register 'exit', ExitNotification
|
|
69
72
|
end
|
|
@@ -18,13 +18,13 @@ module Solargraph
|
|
|
18
18
|
start_timers
|
|
19
19
|
end
|
|
20
20
|
|
|
21
|
-
def process
|
|
21
|
+
def process request
|
|
22
22
|
Thread.new do
|
|
23
|
-
message = @host.start(
|
|
24
|
-
message.
|
|
23
|
+
message = @host.start(request)
|
|
24
|
+
message.send_response
|
|
25
25
|
tmp = @host.flush
|
|
26
26
|
send_data tmp unless tmp.empty?
|
|
27
|
-
GC.start unless
|
|
27
|
+
GC.start unless request['method'] == 'textDocument/didChange'
|
|
28
28
|
end
|
|
29
29
|
end
|
|
30
30
|
|
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
|
|
@@ -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/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,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
|
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
|
|
@@ -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
|
|
@@ -53,11 +53,14 @@ module Solargraph
|
|
|
53
53
|
end
|
|
54
54
|
end
|
|
55
55
|
|
|
56
|
+
def stop
|
|
57
|
+
@io.close
|
|
58
|
+
end
|
|
59
|
+
|
|
56
60
|
protected
|
|
57
61
|
|
|
58
62
|
def load_environment
|
|
59
63
|
return if api_map.nil?
|
|
60
|
-
STDERR.puts "Required paths given to Runtime: #{api_map.required}"
|
|
61
64
|
send_require api_map.required
|
|
62
65
|
@current_required = api_map.required.clone
|
|
63
66
|
end
|
|
@@ -66,8 +69,8 @@ module Solargraph
|
|
|
66
69
|
|
|
67
70
|
def start_process
|
|
68
71
|
dir = Dir.pwd
|
|
69
|
-
unless api_map.nil? or api_map.workspace.nil?
|
|
70
|
-
dir = api_map.workspace
|
|
72
|
+
unless api_map.nil? or api_map.workspace.nil? or api_map.workspace.directory.nil?
|
|
73
|
+
dir = api_map.workspace.directory
|
|
71
74
|
end
|
|
72
75
|
Dir.chdir(dir) do
|
|
73
76
|
@io = IO.popen(executable, 'r+')
|
data/lib/solargraph/shell.rb
CHANGED
|
@@ -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
|
|
@@ -1,11 +1,19 @@
|
|
|
1
1
|
module Solargraph
|
|
2
2
|
class Source
|
|
3
|
+
# The Mapper generates pins and other data for Sources.
|
|
4
|
+
#
|
|
5
|
+
# This class is used internally by the Source class on initialization,
|
|
6
|
+
# e.g., via Source.new or Source.load. Users should not normally need to
|
|
7
|
+
# call it directly.
|
|
8
|
+
#
|
|
3
9
|
class Mapper
|
|
4
10
|
include NodeMethods
|
|
5
11
|
|
|
6
12
|
private_class_method :new
|
|
7
13
|
|
|
8
|
-
#
|
|
14
|
+
# Generate the data.
|
|
15
|
+
#
|
|
16
|
+
# @return [Array]
|
|
9
17
|
def map filename, code, node, comments
|
|
10
18
|
@filename = filename
|
|
11
19
|
@code = code
|
|
@@ -37,7 +45,7 @@ module Solargraph
|
|
|
37
45
|
end
|
|
38
46
|
|
|
39
47
|
class << self
|
|
40
|
-
# @return [Array
|
|
48
|
+
# @return [Array]
|
|
41
49
|
def map filename, code, node, comments
|
|
42
50
|
new.map filename, code, node, comments
|
|
43
51
|
end
|
|
@@ -98,9 +106,17 @@ module Solargraph
|
|
|
98
106
|
u = c.updated(:ivasgn, c.children + ora.children[1..-1], nil)
|
|
99
107
|
@docstring_hash[u.loc] = docstring_for(ora)
|
|
100
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
|
|
101
113
|
end
|
|
102
114
|
else
|
|
103
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
|
|
104
120
|
end
|
|
105
121
|
elsif c.type == :cvasgn
|
|
106
122
|
here = get_node_start_position(c)
|
|
@@ -134,7 +150,6 @@ module Solargraph
|
|
|
134
150
|
pins.push Solargraph::Pin::GlobalVariable.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]), @pins.first)
|
|
135
151
|
elsif c.type == :sym
|
|
136
152
|
@symbols.push Solargraph::Pin::Symbol.new(get_node_location(c), ":#{c.children[0]}")
|
|
137
|
-
|
|
138
153
|
elsif c.type == :casgn
|
|
139
154
|
here = get_node_start_position(c)
|
|
140
155
|
block = get_block_pin(here)
|
|
@@ -146,12 +161,15 @@ module Solargraph
|
|
|
146
161
|
# @todo Smelly instance variable access.
|
|
147
162
|
pins.last.instance_variable_set(:@return_type, methpin.namespace)
|
|
148
163
|
pins.push Solargraph::Pin::Method.new(methpin.location, methpin.namespace, methpin.name, methpin.docstring, methpin.scope, :private, methpin.parameters)
|
|
164
|
+
elsif visibility == :module_function
|
|
165
|
+
pins.push Solargraph::Pin::Method.new(methpin.location, methpin.namespace, methpin.name, methpin.docstring, :class, :public, methpin.parameters)
|
|
166
|
+
pins.push Solargraph::Pin::Method.new(methpin.location, methpin.namespace, methpin.name, methpin.docstring, :instance, :private, methpin.parameters)
|
|
149
167
|
else
|
|
150
168
|
pins.push methpin
|
|
151
169
|
end
|
|
152
170
|
elsif c.type == :defs
|
|
153
171
|
s_visi = visibility
|
|
154
|
-
s_visi = :public if scope != :class
|
|
172
|
+
s_visi = :public if s_visi == :module_function or scope != :class
|
|
155
173
|
if c.children[0].is_a?(AST::Node) and c.children[0].type == :self
|
|
156
174
|
dfqn = fqn || ''
|
|
157
175
|
else
|
|
@@ -191,6 +209,32 @@ module Solargraph
|
|
|
191
209
|
end
|
|
192
210
|
end
|
|
193
211
|
next
|
|
212
|
+
elsif c.type == :send and c.children[1] == :module_function
|
|
213
|
+
# @todo Handle module_function
|
|
214
|
+
if c.children[2].nil?
|
|
215
|
+
visibility = :module_function
|
|
216
|
+
elsif c.children[2].type == :sym or c.children[2].type == :str
|
|
217
|
+
# @todo What to do about references?
|
|
218
|
+
c.children[2..-1].each do |x|
|
|
219
|
+
cn = x.children[0].to_s
|
|
220
|
+
ref = pins.select{|p| p.namespace == (fqn || '') and p.name == cn}.first
|
|
221
|
+
unless ref.nil?
|
|
222
|
+
pins.delete ref
|
|
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
|
|
231
|
+
end
|
|
232
|
+
end
|
|
233
|
+
elsif c.children[2].type == :def
|
|
234
|
+
# @todo A single function
|
|
235
|
+
process c, tree, :module_function, :class, fqn, stack
|
|
236
|
+
next
|
|
237
|
+
end
|
|
194
238
|
elsif c.type == :send and c.children[1] == :include and c.children[0].nil?
|
|
195
239
|
last_node = get_last_in_stack_not_begin(stack)
|
|
196
240
|
if last_node.nil? or last_node.type == :class or last_node.type == :module or last_node.type == :source
|
|
@@ -207,24 +251,26 @@ module Solargraph
|
|
|
207
251
|
elsif c.type == :send and c.children[1] == :extend and c.children[0].nil?
|
|
208
252
|
last_node = get_last_in_stack_not_begin(stack)
|
|
209
253
|
if last_node.nil? or last_node.type == :class or last_node.type == :module or last_node.type == :source
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
254
|
+
c.children[2..-1].each do |i|
|
|
255
|
+
nspin = @pins.select{|pin| pin.kind == Pin::NAMESPACE and pin.path == fqn}.last
|
|
256
|
+
unless nspin.nil?
|
|
257
|
+
ref = nil
|
|
258
|
+
if i.type == :self
|
|
259
|
+
ref = Pin::Reference.new(get_node_location(c), nspin.path, nspin.path)
|
|
260
|
+
elsif i.type == :const
|
|
215
261
|
ref = Pin::Reference.new(get_node_location(c), nspin.path, unpack_name(i))
|
|
216
|
-
nspin.extend_references.push(ref)
|
|
217
262
|
end
|
|
263
|
+
nspin.extend_references.push(ref) unless ref.nil?
|
|
218
264
|
end
|
|
219
265
|
end
|
|
220
266
|
end
|
|
221
267
|
elsif c.type == :send and [:attr_reader, :attr_writer, :attr_accessor].include?(c.children[1])
|
|
222
268
|
c.children[2..-1].each do |a|
|
|
223
269
|
if c.children[1] == :attr_reader or c.children[1] == :attr_accessor
|
|
224
|
-
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)
|
|
225
271
|
end
|
|
226
272
|
if c.children[1] == :attr_writer or c.children[1] == :attr_accessor
|
|
227
|
-
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)
|
|
228
274
|
end
|
|
229
275
|
end
|
|
230
276
|
elsif c.type == :sclass and c.children[0].type == :self
|
|
@@ -298,10 +344,6 @@ module Solargraph
|
|
|
298
344
|
nil
|
|
299
345
|
end
|
|
300
346
|
|
|
301
|
-
def get_node_start_position(node)
|
|
302
|
-
Position.new(node.loc.line - 1, node.loc.column)
|
|
303
|
-
end
|
|
304
|
-
|
|
305
347
|
def get_node_location(node)
|
|
306
348
|
if node.nil?
|
|
307
349
|
st = Position.new(0, 0)
|
|
@@ -360,10 +402,10 @@ module Solargraph
|
|
|
360
402
|
t = (d.tag.types.nil? || d.tag.types.empty?) ? nil : d.tag.types.flatten.join('')
|
|
361
403
|
if t.nil? or t.include?('r')
|
|
362
404
|
# location, namespace, name, docstring, access
|
|
363
|
-
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)
|
|
364
406
|
end
|
|
365
407
|
if t.nil? or t.include?('w')
|
|
366
|
-
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)
|
|
367
409
|
end
|
|
368
410
|
elsif d.tag.tag_name == 'method'
|
|
369
411
|
gen_src = Source.new("def #{d.tag.name};end", filename)
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
module Solargraph
|
|
2
|
+
class Source
|
|
3
|
+
module NodeMethods
|
|
4
|
+
module_function
|
|
5
|
+
|
|
6
|
+
# @return [String]
|
|
7
|
+
def unpack_name(node)
|
|
8
|
+
pack_name(node).join("::")
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# @return [Array<String>]
|
|
12
|
+
def pack_name(node)
|
|
13
|
+
parts = []
|
|
14
|
+
if node.kind_of?(AST::Node)
|
|
15
|
+
node.children.each { |n|
|
|
16
|
+
if n.kind_of?(AST::Node)
|
|
17
|
+
if n.type == :cbase
|
|
18
|
+
parts = pack_name(n)
|
|
19
|
+
else
|
|
20
|
+
parts += pack_name(n)
|
|
21
|
+
end
|
|
22
|
+
else
|
|
23
|
+
parts.push n unless n.nil?
|
|
24
|
+
end
|
|
25
|
+
}
|
|
26
|
+
end
|
|
27
|
+
parts
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# @return [String]
|
|
31
|
+
def const_from node
|
|
32
|
+
if node.kind_of?(AST::Node) and node.type == :const
|
|
33
|
+
result = ''
|
|
34
|
+
unless node.children[0].nil?
|
|
35
|
+
result = const_from(node.children[0])
|
|
36
|
+
end
|
|
37
|
+
if result == ''
|
|
38
|
+
result = node.children[1].to_s
|
|
39
|
+
else
|
|
40
|
+
result = result + '::' + node.children[1].to_s
|
|
41
|
+
end
|
|
42
|
+
result
|
|
43
|
+
else
|
|
44
|
+
nil
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# @return [String]
|
|
49
|
+
def infer_literal_node_type node
|
|
50
|
+
return nil unless node.kind_of?(AST::Node)
|
|
51
|
+
if node.type == :str or node.type == :dstr
|
|
52
|
+
return 'String'
|
|
53
|
+
elsif node.type == :array
|
|
54
|
+
return 'Array'
|
|
55
|
+
elsif node.type == :hash
|
|
56
|
+
return 'Hash'
|
|
57
|
+
elsif node.type == :int
|
|
58
|
+
return 'Integer'
|
|
59
|
+
elsif node.type == :float
|
|
60
|
+
return 'Float'
|
|
61
|
+
elsif node.type == :sym
|
|
62
|
+
return 'Symbol'
|
|
63
|
+
# @todo Maybe ignore nils
|
|
64
|
+
# elsif node.type == :nil
|
|
65
|
+
# return 'NilClass'
|
|
66
|
+
end
|
|
67
|
+
nil
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# Get a call signature from a node.
|
|
71
|
+
# The result should be a string in the form of a method path, e.g.,
|
|
72
|
+
# String.new or variable.method.
|
|
73
|
+
#
|
|
74
|
+
# @return [String]
|
|
75
|
+
def resolve_node_signature node
|
|
76
|
+
result = drill_signature node, ''
|
|
77
|
+
return nil if result.empty?
|
|
78
|
+
result
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def get_node_start_position(node)
|
|
82
|
+
Position.new(node.loc.line - 1, node.loc.column)
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def get_node_end_position(node)
|
|
86
|
+
Position.new(node.loc.last_line - 1, node.loc.last_column)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def drill_signature node, signature
|
|
90
|
+
return signature unless node.kind_of?(AST::Node)
|
|
91
|
+
if node.type == :const or node.type == :cbase
|
|
92
|
+
unless node.children[0].nil?
|
|
93
|
+
signature += drill_signature(node.children[0], signature)
|
|
94
|
+
end
|
|
95
|
+
signature += '::' unless signature.empty?
|
|
96
|
+
signature += node.children[1].to_s
|
|
97
|
+
elsif node.type == :lvar or node.type == :ivar or node.type == :cvar
|
|
98
|
+
signature += '.' unless signature.empty?
|
|
99
|
+
signature += node.children[0].to_s
|
|
100
|
+
elsif node.type == :send
|
|
101
|
+
unless node.children[0].nil?
|
|
102
|
+
signature += drill_signature(node.children[0], signature)
|
|
103
|
+
end
|
|
104
|
+
signature += '.' unless signature.empty?
|
|
105
|
+
signature += node.children[1].to_s
|
|
106
|
+
end
|
|
107
|
+
signature
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
end
|