solargraph 0.29.4 → 0.29.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/solargraph/api_map.rb +5 -2
- data/lib/solargraph/api_map/source_to_yard.rb +32 -29
- data/lib/solargraph/api_map/store.rb +4 -6
- data/lib/solargraph/complex_type/type_methods.rb +5 -1
- data/lib/solargraph/diagnostics/type_not_defined.rb +1 -1
- data/lib/solargraph/language_server/message/extended/check_gem_version.rb +64 -32
- data/lib/solargraph/library.rb +28 -28
- data/lib/solargraph/pin.rb +1 -0
- data/lib/solargraph/pin/attribute.rb +1 -31
- data/lib/solargraph/pin/base.rb +38 -17
- data/lib/solargraph/pin/base_method.rb +64 -0
- data/lib/solargraph/pin/base_variable.rb +2 -4
- data/lib/solargraph/pin/block.rb +1 -3
- data/lib/solargraph/pin/block_parameter.rb +4 -3
- data/lib/solargraph/pin/keyword.rb +0 -4
- data/lib/solargraph/pin/localized.rb +2 -1
- data/lib/solargraph/pin/method.rb +24 -59
- data/lib/solargraph/pin/namespace.rb +1 -2
- data/lib/solargraph/range.rb +4 -2
- data/lib/solargraph/source.rb +18 -0
- data/lib/solargraph/source/chain.rb +5 -2
- data/lib/solargraph/source/chain/call.rb +3 -1
- data/lib/solargraph/source/change.rb +2 -2
- data/lib/solargraph/source/node_chainer.rb +2 -0
- data/lib/solargraph/source/node_methods.rb +15 -0
- data/lib/solargraph/source/source_chainer.rb +0 -22
- data/lib/solargraph/source_map.rb +11 -3
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/workspace.rb +3 -3
- metadata +10 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ef270f7fed3e6a6b8cae0214c0bcdd41e239bfe151951875895a5b6fa76b46f7
|
4
|
+
data.tar.gz: 5be38dd7aaee4533e5c60abe980176f30225e63393fb1858913c8fb4d9938802
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 67036eaaafe01c834b8ce7ca20b7ec00cf302653b4dcc45221d15e64121477c938f36027990d2eed1e206f1d037a69aa835c84882753b55fec43dab402ead4e5
|
7
|
+
data.tar.gz: d30834378eab843bee9b637dcfe0809189100bedce3c9c71f575da5a9a361153eedb9a1b15b48b4907d4b3776b67e3da12b12c9777ff75ac0ee46a7d147dd3d2
|
data/lib/solargraph/api_map.rb
CHANGED
@@ -117,9 +117,10 @@ module Solargraph
|
|
117
117
|
end
|
118
118
|
|
119
119
|
# @param filename [String]
|
120
|
-
# @param position [Position]
|
120
|
+
# @param position [Position, Array(Integer, Integer)]
|
121
121
|
# @return [Source::Cursor]
|
122
122
|
def cursor_at filename, position
|
123
|
+
position = Position.normalize(position)
|
123
124
|
raise "File not found: #{filename}" unless source_map_hash.has_key?(filename)
|
124
125
|
source_map_hash[filename].cursor_at(position)
|
125
126
|
end
|
@@ -127,9 +128,10 @@ module Solargraph
|
|
127
128
|
# Get a clip by filename and position.
|
128
129
|
#
|
129
130
|
# @param filename [String]
|
130
|
-
# @param position [Position]
|
131
|
+
# @param position [Position, Array(Integer, Integer)]
|
131
132
|
# @return [SourceMap::Clip]
|
132
133
|
def clip_at filename, position
|
134
|
+
position = Position.normalize(position)
|
133
135
|
SourceMap::Clip.new(self, cursor_at(filename, position))
|
134
136
|
end
|
135
137
|
|
@@ -509,6 +511,7 @@ module Solargraph
|
|
509
511
|
result.concat inner_get_methods(fqim, scope, visibility, deep, skip, true) unless fqim.nil?
|
510
512
|
end
|
511
513
|
result.concat inner_get_methods('Object', :instance, [:public], deep, skip, no_core)
|
514
|
+
result.concat inner_get_methods('BasicObject', :instance, [:public], deep, skip, no_core)
|
512
515
|
else
|
513
516
|
store.get_extends(fqns).reverse.each do |em|
|
514
517
|
fqem = qualify(em, fqns)
|
@@ -4,58 +4,61 @@ module Solargraph
|
|
4
4
|
|
5
5
|
# Get the YARD CodeObject at the specified path.
|
6
6
|
#
|
7
|
+
# @param path [String]
|
7
8
|
# @return [YARD::CodeObjects::Base]
|
8
9
|
def code_object_at path
|
9
10
|
code_object_map[path]
|
10
11
|
end
|
11
12
|
|
13
|
+
# @return [Array<String>]
|
12
14
|
def code_object_paths
|
13
15
|
code_object_map.keys
|
14
16
|
end
|
15
17
|
|
16
|
-
# @param
|
18
|
+
# @param store [Array<Store>] ApiMap pin store
|
19
|
+
# @return [void]
|
17
20
|
def rake_yard store
|
18
21
|
code_object_map.clear
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
code_object_map[pin.path] ||= YARD::CodeObjects::ModuleObject.new(root_code_object, pin.path)
|
26
|
-
end
|
27
|
-
code_object_map[pin.path].docstring = pin.docstring
|
28
|
-
code_object_map[pin.path].files.push pin.location.filename unless pin.location.nil?
|
22
|
+
store.namespace_pins.each do |pin|
|
23
|
+
next if pin.path.nil? or pin.path.empty?
|
24
|
+
if pin.type == :class
|
25
|
+
code_object_map[pin.path] ||= YARD::CodeObjects::ClassObject.new(root_code_object, pin.path)
|
26
|
+
else
|
27
|
+
code_object_map[pin.path] ||= YARD::CodeObjects::ModuleObject.new(root_code_object, pin.path)
|
29
28
|
end
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
29
|
+
code_object_map[pin.path].docstring = pin.docstring
|
30
|
+
code_object_map[pin.path].files.push pin.location.filename unless pin.location.nil?
|
31
|
+
end
|
32
|
+
store.namespace_pins.each do |pin|
|
33
|
+
# pin.include_references.each do |ref|
|
34
|
+
store.get_includes(pin.path).each do |ref|
|
35
|
+
code_object_map[pin.path].instance_mixins.push code_object_map[ref] unless code_object_map[ref].nil? or code_object_map[pin.path].nil?
|
35
36
|
end
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
[n, v]
|
37
|
+
end
|
38
|
+
store.method_pins.each do |pin|
|
39
|
+
code_object_map[pin.path] ||= YARD::CodeObjects::MethodObject.new(code_object_at(pin.namespace), pin.name, pin.scope)
|
40
|
+
code_object_map[pin.path].docstring = pin.docstring
|
41
|
+
code_object_map[pin.path].visibility = pin.visibility || :public
|
42
|
+
code_object_map[pin.path].files.push pin.location.filename unless pin.location.nil?
|
43
|
+
code_object_map[pin.path].parameters = pin.parameters.map do |p|
|
44
|
+
n = p.match(/^[a-z0-9_]*:?/i)[0]
|
45
|
+
v = nil
|
46
|
+
if p.length > n.length
|
47
|
+
v = p[n.length..-1].gsub(/^ = /, '')
|
48
48
|
end
|
49
|
+
[n, v]
|
49
50
|
end
|
50
|
-
|
51
|
+
end
|
51
52
|
end
|
52
53
|
|
53
54
|
private
|
54
55
|
|
56
|
+
# @return [Hash]
|
55
57
|
def code_object_map
|
56
58
|
@code_object_map ||= {}
|
57
59
|
end
|
58
60
|
|
61
|
+
# @return [YARD::CodeObjects::RootObject]
|
59
62
|
def root_code_object
|
60
63
|
@root_code_object ||= YARD::CodeObjects::RootObject.new(nil, 'root')
|
61
64
|
end
|
@@ -53,11 +53,8 @@ module Solargraph
|
|
53
53
|
# @param path [String]
|
54
54
|
# @return [Array<Solargraph::Pin::Base>]
|
55
55
|
def get_path_pins path
|
56
|
-
|
57
|
-
path
|
58
|
-
base = path.sub(/(#|\.|::)[a-z0-9_]*(\?|\!)?$/i, '')
|
59
|
-
base = '' if base == path
|
60
|
-
namespace_children(base).select{ |pin| pin.path == path }
|
56
|
+
return [] if path.nil? # @todo Should be '' instead?
|
57
|
+
pins.select { |pin| pin.path == path }
|
61
58
|
end
|
62
59
|
|
63
60
|
# @param fqns [String]
|
@@ -109,6 +106,7 @@ module Solargraph
|
|
109
106
|
result
|
110
107
|
end
|
111
108
|
|
109
|
+
# @return [Hash]
|
112
110
|
def named_macros
|
113
111
|
@named_macros ||= begin
|
114
112
|
result = {}
|
@@ -157,7 +155,7 @@ module Solargraph
|
|
157
155
|
end
|
158
156
|
|
159
157
|
# @param name [String]
|
160
|
-
# @return [Array<Solargraph::Pin::
|
158
|
+
# @return [Array<Solargraph::Pin::Base>]
|
161
159
|
def namespace_children name
|
162
160
|
namespace_map[name] || []
|
163
161
|
end
|
@@ -93,7 +93,11 @@ module Solargraph
|
|
93
93
|
def qualify api_map, context = ''
|
94
94
|
return ComplexType.parse(tag) if duck_type? or void? or undefined?
|
95
95
|
fqns = api_map.qualify(name, context)
|
96
|
-
return ComplexType::UNDEFINED if fqns.nil?
|
96
|
+
# return ComplexType::UNDEFINED if fqns.nil?
|
97
|
+
if fqns.nil?
|
98
|
+
return ComplexType.parse('Boolean') if tag == 'Boolean'
|
99
|
+
return ComplexType::UNDEFINED
|
100
|
+
end
|
97
101
|
ltypes = key_types.map do |t|
|
98
102
|
t.qualify api_map, context
|
99
103
|
end
|
@@ -18,7 +18,7 @@ module Solargraph
|
|
18
18
|
private
|
19
19
|
|
20
20
|
def check_return_type pin, api_map, source
|
21
|
-
return [] if (pin.name == 'initialize'
|
21
|
+
return [] if (pin.name == 'initialize' && pin.scope == :instance) || (pin.name == 'new' && pin.scope == :class)
|
22
22
|
result = []
|
23
23
|
unless defined_return_type?(pin, api_map)
|
24
24
|
result.push(
|
@@ -9,44 +9,76 @@ module Solargraph
|
|
9
9
|
# is true, notify the client when the gem is up to date.
|
10
10
|
#
|
11
11
|
class CheckGemVersion < Base
|
12
|
+
GEM_ZERO = Gem::Version.new('0.0.0')
|
13
|
+
|
14
|
+
def initialize host, request, current: Gem::Version.new(Solargraph::VERSION), available: nil
|
15
|
+
super(host, request)
|
16
|
+
@current = current
|
17
|
+
@available = available
|
18
|
+
end
|
19
|
+
|
12
20
|
def process
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
LanguageServer::MessageTypes::INFO,
|
26
|
-
['Update now'] do |result|
|
27
|
-
next unless result == 'Update now'
|
28
|
-
o, s = Open3.capture2("gem update solargraph")
|
29
|
-
if s == 0
|
30
|
-
host.show_message 'Successfully updated the Solargraph gem.', LanguageServer::MessageTypes::INFO
|
31
|
-
host.send_notification '$/solargraph/restart', {}
|
32
|
-
else
|
33
|
-
host.show_message 'An error occurred while updating the gem.', LanguageServer::MessageTypes::ERROR
|
34
|
-
end
|
21
|
+
if available > GEM_ZERO
|
22
|
+
if available > current
|
23
|
+
host.show_message_request "Solargraph gem version #{available} is available. (Current version: #{current})",
|
24
|
+
LanguageServer::MessageTypes::INFO,
|
25
|
+
['Update now'] do |result|
|
26
|
+
next unless result == 'Update now'
|
27
|
+
o, s = Open3.capture2("gem update solargraph")
|
28
|
+
if s == 0
|
29
|
+
host.show_message 'Successfully updated the Solargraph gem.', LanguageServer::MessageTypes::INFO
|
30
|
+
host.send_notification '$/solargraph/restart', {}
|
31
|
+
else
|
32
|
+
host.show_message 'An error occurred while updating the gem.', LanguageServer::MessageTypes::ERROR
|
35
33
|
end
|
36
|
-
|
37
|
-
|
34
|
+
end
|
35
|
+
elsif params['verbose']
|
36
|
+
host.show_message "The Solargraph gem is up to date (version #{Solargraph::VERSION})."
|
37
|
+
end
|
38
|
+
elsif fetched?
|
39
|
+
STDERR.puts error
|
40
|
+
host.show_message(error, MessageTypes::ERROR) if params['verbose']
|
41
|
+
end
|
42
|
+
set_result({
|
43
|
+
installed: current,
|
44
|
+
available: available
|
45
|
+
})
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
# @return [Gem::Version]
|
51
|
+
attr_reader :current
|
52
|
+
|
53
|
+
# @return [Gem::Version]
|
54
|
+
def available
|
55
|
+
if !@available && !@fetched
|
56
|
+
@fetched = true
|
57
|
+
begin
|
58
|
+
@available ||= begin
|
59
|
+
fetcher = Gem::SpecFetcher.new
|
60
|
+
tuple = fetcher.search_for_dependency(Gem::Dependency.new('solargraph')).flatten.first
|
61
|
+
if tuple.nil?
|
62
|
+
@error = 'An error occurred fetching the gem data'
|
63
|
+
GEM_ZERO
|
64
|
+
else
|
65
|
+
tuple.version
|
66
|
+
end
|
38
67
|
end
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
})
|
68
|
+
rescue Errno::EADDRNOTAVAIL => e
|
69
|
+
@error = "Unable to connect to gem source: #{e.message}"
|
70
|
+
GEM_ZERO
|
43
71
|
end
|
44
|
-
rescue Errno::EADDRNOTAVAIL => e
|
45
|
-
msg = "Unable to connect to gem source: #{e.message}"
|
46
|
-
STDERR.puts msg
|
47
|
-
host.show_message(msg, MessageTypes::ERROR) if params['verbose']
|
48
72
|
end
|
73
|
+
@available
|
49
74
|
end
|
75
|
+
|
76
|
+
def fetched?
|
77
|
+
@fetched ||= false
|
78
|
+
end
|
79
|
+
|
80
|
+
# @return [String, nil]
|
81
|
+
attr_reader :error
|
50
82
|
end
|
51
83
|
end
|
52
84
|
end
|
data/lib/solargraph/library.rb
CHANGED
@@ -2,9 +2,11 @@ module Solargraph
|
|
2
2
|
# A Library handles coordination between a Workspace and an ApiMap.
|
3
3
|
#
|
4
4
|
class Library
|
5
|
+
# @return [Solargraph::Workspace]
|
6
|
+
attr_reader :workspace
|
7
|
+
|
5
8
|
# @param workspace [Solargraph::Workspace]
|
6
9
|
def initialize workspace = Solargraph::Workspace.new
|
7
|
-
@mutex = Mutex.new
|
8
10
|
@workspace = workspace
|
9
11
|
api_map.catalog bundle
|
10
12
|
@synchronized = true
|
@@ -30,7 +32,8 @@ module Solargraph
|
|
30
32
|
source = Solargraph::Source.load_string(text, filename, version)
|
31
33
|
workspace.merge source
|
32
34
|
open_file_hash[filename] = source
|
33
|
-
|
35
|
+
checkout filename
|
36
|
+
catalog
|
34
37
|
end
|
35
38
|
end
|
36
39
|
|
@@ -51,8 +54,8 @@ module Solargraph
|
|
51
54
|
workspace.has_file?(filename)
|
52
55
|
end
|
53
56
|
|
54
|
-
# Create a source to be added to the workspace. The file is ignored if
|
55
|
-
#
|
57
|
+
# Create a source to be added to the workspace. The file is ignored if it is
|
58
|
+
# neither open in the library nor included in the workspace.
|
56
59
|
#
|
57
60
|
# @param filename [String]
|
58
61
|
# @param text [String] The contents of the file
|
@@ -60,28 +63,30 @@ module Solargraph
|
|
60
63
|
def create filename, text
|
61
64
|
result = false
|
62
65
|
mutex.synchronize do
|
63
|
-
next unless workspace.would_merge?(filename)
|
66
|
+
next unless contain?(filename) || open?(filename) || workspace.would_merge?(filename)
|
64
67
|
source = Solargraph::Source.load_string(text, filename)
|
65
68
|
workspace.merge(source)
|
66
|
-
catalog
|
69
|
+
catalog
|
67
70
|
result = true
|
68
71
|
end
|
69
72
|
result
|
70
73
|
end
|
71
74
|
|
72
|
-
# Create a file source from a file on disk. The file is ignored if
|
73
|
-
#
|
75
|
+
# Create a file source from a file on disk. The file is ignored if it is
|
76
|
+
# neither open in the library nor included in the workspace.
|
74
77
|
#
|
75
78
|
# @param filename [String]
|
76
79
|
# @return [Boolean] True if the file was added to the workspace.
|
77
80
|
def create_from_disk filename
|
78
81
|
result = false
|
79
82
|
mutex.synchronize do
|
80
|
-
next if File.directory?(filename)
|
81
|
-
next unless workspace.would_merge?(filename)
|
83
|
+
next if File.directory?(filename) || !File.exist?(filename)
|
84
|
+
next unless contain?(filename) || open?(filename) || workspace.would_merge?(filename)
|
82
85
|
source = Solargraph::Source.load_string(File.read(filename), filename)
|
83
86
|
workspace.merge(source)
|
84
|
-
|
87
|
+
open_file_hash[filename] = source if open_file_hash.key?(filename)
|
88
|
+
@current = source if @current && @current.filename == source.filename
|
89
|
+
catalog
|
85
90
|
result = true
|
86
91
|
end
|
87
92
|
result
|
@@ -179,9 +184,9 @@ module Solargraph
|
|
179
184
|
Solargraph::Location.new(loc.filename, Solargraph::Range.from_to(loc.range.start.line, loc.range.start.column + match[0].length, loc.range.ending.line, loc.range.ending.column))
|
180
185
|
end
|
181
186
|
end
|
182
|
-
result.concat(found.sort
|
187
|
+
result.concat(found.sort do |a, b|
|
183
188
|
a.range.start.line <=> b.range.start.line
|
184
|
-
|
189
|
+
end)
|
185
190
|
end
|
186
191
|
end
|
187
192
|
result
|
@@ -214,7 +219,9 @@ module Solargraph
|
|
214
219
|
# @param filename [String]
|
215
220
|
# @return [Source]
|
216
221
|
def checkout filename
|
217
|
-
read
|
222
|
+
@current = read(filename)
|
223
|
+
catalog
|
224
|
+
@current
|
218
225
|
end
|
219
226
|
|
220
227
|
# @param query [String]
|
@@ -246,7 +253,7 @@ module Solargraph
|
|
246
253
|
# @param filename [String]
|
247
254
|
# @return [Array<Solargraph::Pin::Base>]
|
248
255
|
def document_symbols filename
|
249
|
-
return [] unless open_file_hash.
|
256
|
+
return [] unless open_file_hash.key?(filename)
|
250
257
|
api_map.document_symbols(filename)
|
251
258
|
end
|
252
259
|
|
@@ -274,6 +281,7 @@ module Solargraph
|
|
274
281
|
raise FileNotFoundError, "Unable to update #{updater.filename}" unless open?(updater.filename)
|
275
282
|
open_file_hash[updater.filename] = open_file_hash[updater.filename].synchronize(updater)
|
276
283
|
end
|
284
|
+
@current = open_file_hash[updater.filename] if @current && @current.filename == updater.filename
|
277
285
|
@synchronized = false
|
278
286
|
end
|
279
287
|
end
|
@@ -325,31 +333,23 @@ module Solargraph
|
|
325
333
|
private
|
326
334
|
|
327
335
|
# @return [Mutex]
|
328
|
-
|
336
|
+
def mutex
|
337
|
+
@mutex ||= Mutex.new
|
338
|
+
end
|
329
339
|
|
330
340
|
# @return [ApiMap]
|
331
341
|
def api_map
|
332
342
|
@api_map ||= Solargraph::ApiMap.new
|
333
343
|
end
|
334
344
|
|
335
|
-
# @return [YardMap]
|
336
|
-
def yard_map
|
337
|
-
@yard_map ||= Solargraph::YardMap.new
|
338
|
-
end
|
339
|
-
|
340
345
|
# @return [Bundle]
|
341
346
|
def bundle
|
342
347
|
Bundle.new(
|
343
348
|
workspace: workspace,
|
344
|
-
opened:
|
349
|
+
opened: @current ? [@current] : []
|
345
350
|
)
|
346
351
|
end
|
347
352
|
|
348
|
-
# @return [Solargraph::Workspace]
|
349
|
-
def workspace
|
350
|
-
@workspace
|
351
|
-
end
|
352
|
-
|
353
353
|
# A collection of files that are currently open in the library. Open
|
354
354
|
# files do not need to be in the workspace.
|
355
355
|
#
|
@@ -367,7 +367,7 @@ module Solargraph
|
|
367
367
|
# @param filename [String]
|
368
368
|
# @return [Solargraph::Source]
|
369
369
|
def read filename
|
370
|
-
return open_file_hash[filename] if open_file_hash.
|
370
|
+
return open_file_hash[filename] if open_file_hash.key?(filename)
|
371
371
|
raise FileNotFoundError, "File not found: #{filename}" unless workspace.has_file?(filename)
|
372
372
|
workspace.source(filename)
|
373
373
|
end
|