solargraph 0.13.2 → 0.13.3
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/config.rb +23 -12
- data/lib/solargraph/api_map/source.rb +45 -8
- data/lib/solargraph/api_map.rb +51 -6
- data/lib/solargraph/code_map.rb +7 -0
- data/lib/solargraph/live_map/cache.rb +31 -0
- data/lib/solargraph/live_map.rb +96 -0
- data/lib/solargraph/pin/directed/attribute.rb +16 -0
- data/lib/solargraph/pin/directed/method.rb +17 -0
- data/lib/solargraph/pin/directed.rb +9 -0
- data/lib/solargraph/pin.rb +1 -0
- data/lib/solargraph/plugin/base.rb +38 -0
- data/lib/solargraph/plugin/response.rb +19 -0
- data/lib/solargraph/plugin/runtime.rb +15 -0
- data/lib/solargraph/plugin.rb +7 -0
- data/lib/solargraph/server.rb +1 -1
- data/lib/solargraph/server_methods.rb +11 -0
- data/lib/solargraph/shell.rb +21 -15
- data/lib/solargraph/suggestion.rb +9 -5
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/yard_map.rb +29 -12
- data/lib/solargraph.rb +15 -12
- metadata +21 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 613c6ae706229464a6f918aef5f093a97e0ff569
|
4
|
+
data.tar.gz: b68e4d8abbf2b884d78f9af364e34e5cbcde6f2f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 843ff75f0ccf680f311a3e42ba4e5ff18810ff1beb048638503c3e7b794883b1bd419c2dd2b6bb3d56bc17a3a06e8e5a7d392f9abf458c57affe0f219ae2ad7a
|
7
|
+
data.tar.gz: a3b5f6d57c62b1d35e940e29b6c8e9b70594a73f1f6f37021a31cfee11eefc3495cb1d09f13de70b1722a9d42bfde9ce827682df898198c6dad5b59918c76419
|
@@ -4,33 +4,44 @@ module Solargraph
|
|
4
4
|
class ApiMap
|
5
5
|
class Config
|
6
6
|
attr_reader :workspace
|
7
|
-
attr_reader :
|
8
|
-
attr_reader :excluded
|
7
|
+
attr_reader :raw_data
|
9
8
|
|
10
9
|
def initialize workspace = nil
|
11
10
|
@workspace = workspace
|
12
|
-
@included = []
|
13
|
-
@excluded = []
|
14
11
|
include_globs = ['**/*.rb']
|
15
12
|
exclude_globs = ['spec/**/*', 'test/**/*']
|
16
13
|
unless @workspace.nil?
|
17
14
|
sfile = File.join(@workspace, '.solargraph.yml')
|
18
15
|
if File.file?(sfile)
|
19
|
-
|
20
|
-
include_globs = conf['include'] || include_globs
|
21
|
-
exclude_globs = conf['exclude'] || []
|
16
|
+
@raw_data = YAML.load(File.read(sfile))
|
22
17
|
end
|
23
18
|
end
|
24
|
-
|
25
|
-
|
19
|
+
@raw_data ||= {}
|
20
|
+
@raw_data['include'] = @raw_data['include'] || include_globs
|
21
|
+
@raw_data['exclude'] = @raw_data['exclude'] || exclude_globs
|
22
|
+
@raw_data['extensions'] = @raw_data['extensions'] || []
|
23
|
+
end
|
24
|
+
|
25
|
+
def included
|
26
|
+
process_globs @raw_data['include']
|
27
|
+
end
|
28
|
+
|
29
|
+
def excluded
|
30
|
+
process_globs @raw_data['exclude']
|
31
|
+
end
|
32
|
+
|
33
|
+
def extensions
|
34
|
+
@raw_data['extensions']
|
26
35
|
end
|
27
36
|
|
28
37
|
private
|
29
38
|
|
30
|
-
def
|
39
|
+
def process_globs globs
|
31
40
|
result = []
|
32
|
-
|
33
|
-
|
41
|
+
globs.each do |glob|
|
42
|
+
Dir[File.join workspace, glob].each do |f|
|
43
|
+
result.push File.realdirpath(f)
|
44
|
+
end
|
34
45
|
end
|
35
46
|
result
|
36
47
|
end
|
@@ -23,6 +23,7 @@ module Solargraph
|
|
23
23
|
root = root.append node
|
24
24
|
@node = root
|
25
25
|
@comments = comments
|
26
|
+
@directives = {}
|
26
27
|
@docstring_hash = associate_comments(node, comments)
|
27
28
|
@filename = filename
|
28
29
|
@namespace_nodes = {}
|
@@ -30,6 +31,27 @@ module Solargraph
|
|
30
31
|
@node_stack = []
|
31
32
|
@node_tree = {}
|
32
33
|
inner_map_node @node
|
34
|
+
@directives.each_pair do |k, v|
|
35
|
+
v.each do |d|
|
36
|
+
ns = namespace_for(k.node)
|
37
|
+
docstring = YARD::Docstring.parser.parse(d.tag.text).to_docstring
|
38
|
+
if d.tag.tag_name == 'attribute'
|
39
|
+
t = (d.tag.types.nil? || d.tag.types.empty?) ? nil : d.tag.types.flatten.join('')
|
40
|
+
if t.nil? or t.include?('r')
|
41
|
+
attribute_pins.push Solargraph::Pin::Directed::Attribute.new(self, k.node, ns, :reader, docstring, d.tag.name)
|
42
|
+
end
|
43
|
+
if t.nil? or t.include?('w')
|
44
|
+
attribute_pins.push Solargraph::Pin::Directed::Attribute.new(self, k.node, ns, :writer, docstring, "#{d.tag.name}=")
|
45
|
+
end
|
46
|
+
elsif d.tag.tag_name == 'method'
|
47
|
+
gen_src = Source.virtual(filename, "def #{d.tag.name};end")
|
48
|
+
gen_pin = gen_src.method_pins.first
|
49
|
+
method_pins.push Solargraph::Pin::Directed::Method.new(gen_src, gen_pin.node, ns, :instance, :public, docstring, gen_pin.name)
|
50
|
+
else
|
51
|
+
STDERR.puts "Nothing to do for directive: #{d}"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
33
55
|
end
|
34
56
|
|
35
57
|
def namespaces
|
@@ -99,6 +121,16 @@ module Solargraph
|
|
99
121
|
@node_tree[node] || []
|
100
122
|
end
|
101
123
|
|
124
|
+
def namespace_for node
|
125
|
+
parts = []
|
126
|
+
([node] + (@node_tree[node] || [])).each do |n|
|
127
|
+
if n.type == :class or n.type == :module
|
128
|
+
parts.unshift unpack_name(n.children[0])
|
129
|
+
end
|
130
|
+
end
|
131
|
+
parts.join('::')
|
132
|
+
end
|
133
|
+
|
102
134
|
def include? node
|
103
135
|
@all_nodes.include? node
|
104
136
|
end
|
@@ -126,7 +158,12 @@ module Solargraph
|
|
126
158
|
ctxt += "#{p[num..-1]}\n"
|
127
159
|
end
|
128
160
|
}
|
129
|
-
|
161
|
+
parse = YARD::Docstring.parser.parse(ctxt)
|
162
|
+
unless parse.directives.empty?
|
163
|
+
@directives[k] ||= []
|
164
|
+
@directives[k].concat parse.directives
|
165
|
+
end
|
166
|
+
yard_hash[k] = parse.to_docstring
|
130
167
|
}
|
131
168
|
yard_hash
|
132
169
|
end
|
@@ -204,14 +241,14 @@ module Solargraph
|
|
204
241
|
elsif c.type == :casgn
|
205
242
|
constant_pins.push Solargraph::Pin::Constant.new(self, c, fqn)
|
206
243
|
else
|
207
|
-
unless fqn.nil?
|
244
|
+
#unless fqn.nil?
|
208
245
|
if c.kind_of?(AST::Node)
|
209
246
|
if c.type == :def and c.children[0].to_s[0].match(/[a-z]/i)
|
210
|
-
method_pins.push Solargraph::Pin::Method.new(source, c, fqn, scope, visibility)
|
247
|
+
method_pins.push Solargraph::Pin::Method.new(source, c, fqn || '', scope, visibility)
|
211
248
|
#inner_map_node c, tree, visibility, scope, fqn, stack
|
212
249
|
#next
|
213
250
|
elsif c.type == :defs
|
214
|
-
method_pins.push Solargraph::Pin::Method.new(source, c, fqn, :class, :public)
|
251
|
+
method_pins.push Solargraph::Pin::Method.new(source, c, fqn || '', :class, :public)
|
215
252
|
inner_map_node c, tree, :public, :class, fqn, stack
|
216
253
|
next
|
217
254
|
elsif c.type == :send and [:public, :protected, :private].include?(c.children[1])
|
@@ -224,18 +261,18 @@ module Solargraph
|
|
224
261
|
elsif c.type == :send and [:attr_reader, :attr_writer, :attr_accessor].include?(c.children[1])
|
225
262
|
c.children[2..-1].each do |a|
|
226
263
|
if c.children[1] == :attr_reader or c.children[1] == :attr_accessor
|
227
|
-
attribute_pins.push Solargraph::Pin::Attribute.new(self, a, fqn, :reader, docstring_for(c)) #AttrPin.new(c)
|
264
|
+
attribute_pins.push Solargraph::Pin::Attribute.new(self, a, fqn || '', :reader, docstring_for(c)) #AttrPin.new(c)
|
228
265
|
end
|
229
266
|
if c.children[1] == :attr_writer or c.children[1] == :attr_accessor
|
230
|
-
attribute_pins.push Solargraph::Pin::Attribute.new(self, a, fqn, :writer, docstring_for(c)) #AttrPin.new(c)
|
267
|
+
attribute_pins.push Solargraph::Pin::Attribute.new(self, a, fqn || '', :writer, docstring_for(c)) #AttrPin.new(c)
|
231
268
|
end
|
232
269
|
end
|
233
270
|
elsif c.type == :sclass and c.children[0].type == :self
|
234
|
-
inner_map_node c, tree, :public, :class, fqn, stack
|
271
|
+
inner_map_node c, tree, :public, :class, fqn || '', stack
|
235
272
|
next
|
236
273
|
end
|
237
274
|
end
|
238
|
-
end
|
275
|
+
#end
|
239
276
|
if c.type == :send and c.children[1] == :require
|
240
277
|
if c.children[2].kind_of?(AST::Node) and c.children[2].type == :str
|
241
278
|
required.push c.children[2].children[0].to_s
|
data/lib/solargraph/api_map.rb
CHANGED
@@ -38,10 +38,15 @@ module Solargraph
|
|
38
38
|
def initialize workspace = nil
|
39
39
|
@workspace = workspace.gsub(/\\/, '/') unless workspace.nil?
|
40
40
|
clear
|
41
|
+
# @todo Instead of requiring extensions to be listed in the config,
|
42
|
+
# we're experimenting with automatically loading them.
|
43
|
+
#self.config.extensions.each do |ext|
|
44
|
+
# require ext
|
45
|
+
#end
|
46
|
+
require_extensions
|
41
47
|
@workspace_files = []
|
42
48
|
unless @workspace.nil?
|
43
|
-
config
|
44
|
-
@workspace_files.concat (config.included - config.excluded)
|
49
|
+
@workspace_files.concat (self.config.included - self.config.excluded)
|
45
50
|
@workspace_files.each do |wf|
|
46
51
|
begin
|
47
52
|
@@source_cache[wf] ||= Source.load(wf)
|
@@ -54,9 +59,14 @@ module Solargraph
|
|
54
59
|
@virtual_source = nil
|
55
60
|
@virtual_filename = nil
|
56
61
|
@stale = true
|
62
|
+
live_map
|
57
63
|
refresh
|
58
64
|
end
|
59
65
|
|
66
|
+
def config
|
67
|
+
@config ||= ApiMap::Config.new(@workspace)
|
68
|
+
end
|
69
|
+
|
60
70
|
# @return [Solargraph::YardMap]
|
61
71
|
def yard_map
|
62
72
|
refresh
|
@@ -66,6 +76,11 @@ module Solargraph
|
|
66
76
|
@yard_map
|
67
77
|
end
|
68
78
|
|
79
|
+
# @return [Solargraph::LiveMap]
|
80
|
+
def live_map
|
81
|
+
@live_map ||= Solargraph::LiveMap.new(workspace)
|
82
|
+
end
|
83
|
+
|
69
84
|
# @return [Solargraph::ApiMap::Source]
|
70
85
|
def virtualize filename, code, cursor = nil
|
71
86
|
unless @virtual_source.nil? or @virtual_filename == filename or @workspace_files.include?(@virtual_filename)
|
@@ -356,6 +371,7 @@ module Solargraph
|
|
356
371
|
def get_methods(namespace, root = '', visibility: [:public])
|
357
372
|
refresh
|
358
373
|
namespace = clean_namespace_string(namespace)
|
374
|
+
fqns = find_fully_qualified_namespace(namespace, root)
|
359
375
|
meths = []
|
360
376
|
meths.concat inner_get_methods(namespace, root, []) #unless has_yardoc?
|
361
377
|
yard_meths = yard_map.get_methods(namespace, root, visibility: visibility)
|
@@ -371,7 +387,6 @@ module Solargraph
|
|
371
387
|
end
|
372
388
|
news = meths.select{|s| s.label == 'new'}
|
373
389
|
unless news.empty?
|
374
|
-
fqns = find_fully_qualified_namespace(namespace, root)
|
375
390
|
if @method_pins[fqns]
|
376
391
|
inits = @method_pins[fqns].select{|p| p.name == 'initialize'}
|
377
392
|
meths -= news unless inits.empty?
|
@@ -380,7 +395,12 @@ module Solargraph
|
|
380
395
|
end
|
381
396
|
end
|
382
397
|
end
|
383
|
-
meths
|
398
|
+
strings = meths.map(&:to_s)
|
399
|
+
live_map.get_methods(namespace, root, visibility.include?(:private)).each do |m|
|
400
|
+
next if strings.include?(m) or !m.match(/^[a-z]/i)
|
401
|
+
meths.push Suggestion.new(m, kind: Suggestion::METHOD, docstring: YARD::Docstring.new('(defined at runtime)'))
|
402
|
+
end
|
403
|
+
meths
|
384
404
|
end
|
385
405
|
|
386
406
|
# Get an array of instance methods that are available in the specified
|
@@ -407,6 +427,11 @@ module Solargraph
|
|
407
427
|
meths += yard_map.get_instance_methods('Module')
|
408
428
|
end
|
409
429
|
end
|
430
|
+
strings = meths.map(&:to_s)
|
431
|
+
live_map.get_instance_methods(namespace, root, visibility.include?(:private)).each do |m|
|
432
|
+
next if strings.include?(m) or !m.match(/^[a-z]/i)
|
433
|
+
meths.push Suggestion.new(m, kind: Suggestion::METHOD)
|
434
|
+
end
|
410
435
|
meths
|
411
436
|
end
|
412
437
|
|
@@ -424,7 +449,8 @@ module Solargraph
|
|
424
449
|
|
425
450
|
def update filename
|
426
451
|
@@source_cache[filename] ||= Source.load(filename)
|
427
|
-
cache.clear
|
452
|
+
#cache.clear
|
453
|
+
@stale = true
|
428
454
|
end
|
429
455
|
|
430
456
|
def sources
|
@@ -511,6 +537,8 @@ module Solargraph
|
|
511
537
|
map_source s
|
512
538
|
}
|
513
539
|
@required.uniq!
|
540
|
+
#live_map.update self
|
541
|
+
live_map.reload
|
514
542
|
@stale = false
|
515
543
|
end
|
516
544
|
|
@@ -600,6 +628,11 @@ module Solargraph
|
|
600
628
|
unless sc.nil?
|
601
629
|
meths.concat inner_get_methods(sc, fqns, skip, visibility - [:private])
|
602
630
|
meths.concat yard_map.get_methods(sc, fqns, visibility: visibility - [:private])
|
631
|
+
strings = meths.map(&:to_s)
|
632
|
+
live_map.get_methods(sc, fqns, false).each do |m|
|
633
|
+
next if strings.include?(m) or !m.match(/^[a-z]/i)
|
634
|
+
meths.push Suggestion.new(m, kind: Suggestion::METHOD, docstring: YARD::Docstring.new('(defined at runtime)'))
|
635
|
+
end
|
603
636
|
end
|
604
637
|
end
|
605
638
|
meths.uniq
|
@@ -627,6 +660,11 @@ module Solargraph
|
|
627
660
|
unless sc.nil?
|
628
661
|
meths.concat inner_get_instance_methods(sc, fqns, skip, visibility - [:private])
|
629
662
|
meths.concat yard_map.get_instance_methods(sc, fqns, visibility: visibility - [:private])
|
663
|
+
strings = meths.map(&:to_s)
|
664
|
+
live_map.get_instance_methods(sc, fqns, false).each do |m|
|
665
|
+
next if strings.include?(m) or !m.match(/^[a-z]/i)
|
666
|
+
meths.push Suggestion.new(m, kind: Suggestion::METHOD, docstring: YARD::Docstring.new('(defined at runtime)'))
|
667
|
+
end
|
630
668
|
end
|
631
669
|
end
|
632
670
|
im = @namespace_includes[fqns]
|
@@ -716,7 +754,7 @@ module Solargraph
|
|
716
754
|
elsif !METHODS_RETURNING_SELF.include?(part)
|
717
755
|
visibility = [:public]
|
718
756
|
visibility.concat [:private, :protected] if top
|
719
|
-
if scope == :instance
|
757
|
+
if scope == :instance || namespace == ''
|
720
758
|
meth = get_instance_methods(namespace, visibility: visibility).select{|s| s.label == part}.first
|
721
759
|
else
|
722
760
|
meth = get_methods(namespace, visibility: visibility).select{|s| s.label == part}.first
|
@@ -759,5 +797,12 @@ module Solargraph
|
|
759
797
|
def pin_to_suggestion pin
|
760
798
|
@pin_suggestions[pin] ||= Suggestion.pull(pin)
|
761
799
|
end
|
800
|
+
|
801
|
+
def require_extensions
|
802
|
+
Gem::Specification.all_names.select{|n| n.match(/^solargraph\-[a-z0-9_\-]*?\-ext\-[0-9\.]*$/)}.each do |n|
|
803
|
+
STDERR.puts "Loading extension #{n}"
|
804
|
+
require n.match(/^(solargraph\-[a-z0-9_\-]*?\-ext)\-[0-9\.]*$/)[1]
|
805
|
+
end
|
806
|
+
end
|
762
807
|
end
|
763
808
|
end
|
data/lib/solargraph/code_map.rb
CHANGED
@@ -13,6 +13,11 @@ module Solargraph
|
|
13
13
|
# @return [String]
|
14
14
|
attr_reader :code
|
15
15
|
|
16
|
+
# The source object generated from the code.
|
17
|
+
#
|
18
|
+
# @return [Solargraph::ApiMap::Source]
|
19
|
+
attr_reader :source
|
20
|
+
|
16
21
|
# The filename for the source code.
|
17
22
|
#
|
18
23
|
# @return [String]
|
@@ -236,6 +241,8 @@ module Solargraph
|
|
236
241
|
end
|
237
242
|
result += api_map.namespaces_in('')
|
238
243
|
result += api_map.get_instance_methods('Kernel')
|
244
|
+
result += api_map.get_methods('')
|
245
|
+
result += api_map.get_instance_methods('')
|
239
246
|
else
|
240
247
|
result.concat api_map.get_instance_methods(type)
|
241
248
|
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Solargraph
|
2
|
+
class LiveMap
|
3
|
+
class Cache
|
4
|
+
def initialize
|
5
|
+
@method_cache = {}
|
6
|
+
@instance_method_cache = {}
|
7
|
+
end
|
8
|
+
|
9
|
+
def get_methods options
|
10
|
+
@method_cache[options]
|
11
|
+
end
|
12
|
+
|
13
|
+
def set_methods options, values
|
14
|
+
@method_cache[options] = values
|
15
|
+
end
|
16
|
+
|
17
|
+
def get_instance_methods options
|
18
|
+
@instance_method_cache[options]
|
19
|
+
end
|
20
|
+
|
21
|
+
def set_instance_methods options, values
|
22
|
+
@instance_method_cache[options] = values
|
23
|
+
end
|
24
|
+
|
25
|
+
def clear
|
26
|
+
@method_cache.clear
|
27
|
+
@instance_method_cache.clear
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
module Solargraph
|
2
|
+
# The LiveMap allows extensions to add their own completion suggestions.
|
3
|
+
#
|
4
|
+
class LiveMap
|
5
|
+
@@plugins = []
|
6
|
+
|
7
|
+
attr_reader :workspace
|
8
|
+
|
9
|
+
def initialize workspace
|
10
|
+
@workspace = workspace
|
11
|
+
@runners = []
|
12
|
+
at_exit { stop }
|
13
|
+
end
|
14
|
+
|
15
|
+
def start
|
16
|
+
unless workspace.nil?
|
17
|
+
@@plugins.each do |p|
|
18
|
+
r = p.new(workspace)
|
19
|
+
r.start
|
20
|
+
@runners.push r
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def reload
|
26
|
+
restart
|
27
|
+
end
|
28
|
+
|
29
|
+
def restart
|
30
|
+
stop
|
31
|
+
start
|
32
|
+
end
|
33
|
+
|
34
|
+
def stop
|
35
|
+
@runners.each do |p|
|
36
|
+
p.stop
|
37
|
+
end
|
38
|
+
@runners.clear
|
39
|
+
end
|
40
|
+
|
41
|
+
def get_instance_methods(namespace, root = '', with_private = false)
|
42
|
+
result = []
|
43
|
+
@runners.each do |p|
|
44
|
+
resp = p.get_methods(namespace: namespace, root: root, scope: 'instance', with_private: with_private)
|
45
|
+
STDERR.puts resp.message unless resp.ok?
|
46
|
+
result.concat(resp.data)
|
47
|
+
end
|
48
|
+
result
|
49
|
+
end
|
50
|
+
|
51
|
+
def get_methods(namespace, root = '', with_private = false)
|
52
|
+
result = []
|
53
|
+
@runners.each do |p|
|
54
|
+
resp = p.get_methods(namespace: namespace, root: root, scope: 'class', with_private: with_private)
|
55
|
+
STDERR.puts resp.message unless resp.ok?
|
56
|
+
result.concat(resp.data)
|
57
|
+
end
|
58
|
+
result
|
59
|
+
end
|
60
|
+
|
61
|
+
def self.install cls
|
62
|
+
@@plugins.push cls
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
def find_constant(namespace, root)
|
68
|
+
result = nil
|
69
|
+
parts = root.split('::')
|
70
|
+
if parts.empty?
|
71
|
+
result = inner_find_constant(namespace)
|
72
|
+
else
|
73
|
+
until parts.empty?
|
74
|
+
result = inner_find_constant("#{parts.join('::')}::#{namespace}")
|
75
|
+
break unless result.nil?
|
76
|
+
parts.pop
|
77
|
+
end
|
78
|
+
end
|
79
|
+
result
|
80
|
+
end
|
81
|
+
|
82
|
+
def inner_find_constant(namespace)
|
83
|
+
cursor = Object
|
84
|
+
parts = namespace.split('::')
|
85
|
+
until parts.empty?
|
86
|
+
here = parts.shift
|
87
|
+
begin
|
88
|
+
cursor = cursor.const_get(here)
|
89
|
+
rescue NameError
|
90
|
+
return nil
|
91
|
+
end
|
92
|
+
end
|
93
|
+
cursor
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Solargraph
|
2
|
+
module Pin
|
3
|
+
module Directed
|
4
|
+
class Attribute < Solargraph::Pin::Attribute
|
5
|
+
def initialize source, node, namespace, access, docstring, name
|
6
|
+
super(source, node, namespace, access, docstring)
|
7
|
+
@name = name
|
8
|
+
end
|
9
|
+
|
10
|
+
def name
|
11
|
+
@name
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Solargraph
|
2
|
+
module Pin
|
3
|
+
module Directed
|
4
|
+
class Method < Solargraph::Pin::Method
|
5
|
+
def initialize source, node, namespace, scope, visibility, docstring, name
|
6
|
+
super(source, node, namespace, scope, visibility)
|
7
|
+
@docstring = docstring
|
8
|
+
@name = name
|
9
|
+
end
|
10
|
+
|
11
|
+
def name
|
12
|
+
@name
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/solargraph/pin.rb
CHANGED
@@ -0,0 +1,38 @@
|
|
1
|
+
module Solargraph
|
2
|
+
module Plugin
|
3
|
+
class Base
|
4
|
+
|
5
|
+
def initialize workspace
|
6
|
+
# @!attribute [r] workspace
|
7
|
+
# @return [String]
|
8
|
+
define_singleton_method(:workspace) { workspace }
|
9
|
+
post_initialize
|
10
|
+
end
|
11
|
+
|
12
|
+
def post_initialize
|
13
|
+
end
|
14
|
+
|
15
|
+
def start
|
16
|
+
raise "#{self.class} needs to implement the start method"
|
17
|
+
end
|
18
|
+
|
19
|
+
def stop
|
20
|
+
raise "#{self.class} needs to implement the stop method"
|
21
|
+
end
|
22
|
+
|
23
|
+
def get_methods namespace:, root:, scope:, with_private: false
|
24
|
+
raise "#{self.class} needs to implement the get_methods method"
|
25
|
+
end
|
26
|
+
|
27
|
+
protected
|
28
|
+
|
29
|
+
def respond_ok data
|
30
|
+
Solargraph::Plugin::Response.new('ok', data)
|
31
|
+
end
|
32
|
+
|
33
|
+
def respond_err exception
|
34
|
+
Solargraph::Plugin::Response.new('err', [], exception.message)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Solargraph
|
2
|
+
module Plugin
|
3
|
+
class Response
|
4
|
+
attr_reader :status
|
5
|
+
attr_reader :data
|
6
|
+
attr_reader :message
|
7
|
+
|
8
|
+
def initialize status = 'ok', data = [], message = nil
|
9
|
+
@status = status
|
10
|
+
@data = data
|
11
|
+
@message = message
|
12
|
+
end
|
13
|
+
|
14
|
+
def ok?
|
15
|
+
status == 'ok'
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Solargraph
|
2
|
+
module Plugin
|
3
|
+
class Runtime < Base
|
4
|
+
def start
|
5
|
+
end
|
6
|
+
|
7
|
+
def stop
|
8
|
+
end
|
9
|
+
|
10
|
+
def get_methods namespace:, root:, scope:, with_private: false
|
11
|
+
raise "#{self.class} needs to implement the get_methods method"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/lib/solargraph/server.rb
CHANGED
@@ -50,7 +50,7 @@ module Solargraph
|
|
50
50
|
code_map = CodeMap.new(code: params['text'], filename: params['filename'], api_map: api_map, cursor: [params['line'].to_i, params['column'].to_i])
|
51
51
|
offset = code_map.get_offset(params['line'].to_i, params['column'].to_i)
|
52
52
|
sugg = code_map.suggest_at(offset, with_snippets: params['with_snippets'] == '1' ? true : false, filtered: true)
|
53
|
-
{ "status" => "ok", "suggestions" => sugg }
|
53
|
+
JSON.generate({ "status" => "ok", "suggestions" => sugg.map(&:as_json) })
|
54
54
|
rescue Exception => e
|
55
55
|
STDERR.puts e
|
56
56
|
STDERR.puts e.backtrace.join("\n")
|
data/lib/solargraph/shell.rb
CHANGED
@@ -5,9 +5,12 @@ require 'rubygems/package'
|
|
5
5
|
require 'zlib'
|
6
6
|
require 'net/http'
|
7
7
|
require 'socket'
|
8
|
+
require 'bundler'
|
8
9
|
|
9
10
|
module Solargraph
|
10
11
|
class Shell < Thor
|
12
|
+
include Solargraph::ServerMethods
|
13
|
+
|
11
14
|
map %w[--version -v] => :version
|
12
15
|
|
13
16
|
desc "--version, -v", "Print the version"
|
@@ -93,25 +96,28 @@ module Solargraph
|
|
93
96
|
end
|
94
97
|
|
95
98
|
desc 'config [DIRECTORY]', 'Create or overwrite a default configuration file'
|
99
|
+
option :extensions, type: :boolean, aliases: :e, desc: 'Add installed extensions', default: true
|
96
100
|
def config(directory = '.')
|
101
|
+
matches = []
|
102
|
+
if options[:extensions]
|
103
|
+
Gem::Specification.each do |g|
|
104
|
+
puts g.name
|
105
|
+
if g.name.match(/^solargraph\-[A-Za-z0-9_\-]*?\-ext/)
|
106
|
+
require g.name
|
107
|
+
matches.push g.name
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
conf = Solargraph::ApiMap::Config.new.raw_data
|
112
|
+
unless matches.empty?
|
113
|
+
matches.each do |m|
|
114
|
+
conf['extensions'].push m
|
115
|
+
end
|
116
|
+
end
|
97
117
|
File.open(File.join(directory, '.solargraph.yml'), 'w') do |file|
|
98
|
-
file.puts
|
99
|
-
" - ./**/*.rb",
|
100
|
-
"exclude:",
|
101
|
-
" - spec/**/*",
|
102
|
-
" - test/**/*"
|
118
|
+
file.puts conf.to_yaml
|
103
119
|
end
|
104
120
|
STDOUT.puts "Configuration file initialized."
|
105
121
|
end
|
106
|
-
|
107
|
-
private
|
108
|
-
|
109
|
-
def available_port
|
110
|
-
socket = Socket.new(:INET, :STREAM, 0)
|
111
|
-
socket.bind(Addrinfo.tcp("127.0.0.1", 0))
|
112
|
-
port = socket.local_address.ip_port
|
113
|
-
socket.close
|
114
|
-
port
|
115
|
-
end
|
116
122
|
end
|
117
123
|
end
|
@@ -61,7 +61,8 @@ module Solargraph
|
|
61
61
|
# @return [String]
|
62
62
|
def return_type
|
63
63
|
if @return_type.nil? and !docstring.nil?
|
64
|
-
|
64
|
+
ol = docstring.tag(:overload)
|
65
|
+
t = ol.nil? ? docstring.tag(:return) : ol.tag(:return)
|
65
66
|
@return_type = t.types[0] unless t.nil? or t.types.nil?
|
66
67
|
end
|
67
68
|
@return_type
|
@@ -69,7 +70,7 @@ module Solargraph
|
|
69
70
|
|
70
71
|
# @return [YARD::Docstring]
|
71
72
|
def docstring
|
72
|
-
@docstring ||= @code_object
|
73
|
+
@docstring ||= @code_object.nil? ? nil : @code_object.docstring
|
73
74
|
end
|
74
75
|
|
75
76
|
# @return [String]
|
@@ -95,8 +96,8 @@ module Solargraph
|
|
95
96
|
@params
|
96
97
|
end
|
97
98
|
|
98
|
-
def
|
99
|
-
|
99
|
+
def as_json args = {}
|
100
|
+
{
|
100
101
|
label: @label,
|
101
102
|
kind: @kind,
|
102
103
|
insert: @insert,
|
@@ -108,7 +109,10 @@ module Solargraph
|
|
108
109
|
return_type: return_type,
|
109
110
|
documentation: documentation
|
110
111
|
}
|
111
|
-
|
112
|
+
end
|
113
|
+
|
114
|
+
def to_json args = {}
|
115
|
+
as_json.to_json(args)
|
112
116
|
end
|
113
117
|
|
114
118
|
def self.pull pin, return_type = nil
|
data/lib/solargraph/version.rb
CHANGED
data/lib/solargraph/yard_map.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
require 'parser/current'
|
2
2
|
require 'yard'
|
3
|
-
require 'bundler'
|
4
3
|
|
5
4
|
module Solargraph
|
6
5
|
|
@@ -27,7 +26,7 @@ module Solargraph
|
|
27
26
|
if gy.nil?
|
28
27
|
STDERR.puts "Required path not found: #{r}"
|
29
28
|
else
|
30
|
-
STDERR.puts "Adding #{gy}"
|
29
|
+
#STDERR.puts "Adding #{gy}"
|
31
30
|
yardocs.unshift gy
|
32
31
|
add_gem_dependencies g
|
33
32
|
end
|
@@ -47,6 +46,11 @@ module Solargraph
|
|
47
46
|
#cache_core
|
48
47
|
end
|
49
48
|
|
49
|
+
# @return [Solargraph::LiveMap]
|
50
|
+
def live_map
|
51
|
+
@live_map ||= Solargraph::LiveMap.new
|
52
|
+
end
|
53
|
+
|
50
54
|
# @return [Array<String>]
|
51
55
|
def yardocs
|
52
56
|
@yardocs ||= []
|
@@ -255,15 +259,28 @@ module Solargraph
|
|
255
259
|
def bundled_gem_yardocs
|
256
260
|
result = []
|
257
261
|
unless workspace.nil?
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
262
|
+
Bundler.with_clean_env do
|
263
|
+
Bundler.environment.chdir(workspace) do
|
264
|
+
glfn = File.join(workspace, 'Gemfile.lock')
|
265
|
+
spec_versions = {}
|
266
|
+
if File.file?(glfn)
|
267
|
+
lockfile = Bundler::LockfileParser.new(Bundler.read_file(glfn))
|
268
|
+
lockfile.specs.each do |s|
|
269
|
+
spec_versions[s.name] = s.version.to_s
|
270
|
+
end
|
271
|
+
end
|
272
|
+
Bundler.environment.dependencies.each do |s|
|
273
|
+
if s.type == :runtime
|
274
|
+
ver = spec_versions[s.name]
|
275
|
+
y = YARD::Registry.yardoc_file_for_gem(s.name, ver)
|
276
|
+
if y.nil?
|
277
|
+
STDERR.puts "Bundled gem not found: #{s.name}, #{ver}"
|
278
|
+
else
|
279
|
+
#STDERR.puts "Adding #{y}"
|
280
|
+
result.push y
|
281
|
+
add_gem_dependencies(s.name)
|
282
|
+
end
|
283
|
+
end
|
267
284
|
end
|
268
285
|
end
|
269
286
|
end
|
@@ -325,7 +342,7 @@ module Solargraph
|
|
325
342
|
if gy.nil?
|
326
343
|
STDERR.puts "Required path not found: #{r}"
|
327
344
|
else
|
328
|
-
STDERR.puts "Adding #{gy}"
|
345
|
+
#STDERR.puts "Adding #{gy}"
|
329
346
|
yardocs.unshift gy
|
330
347
|
end
|
331
348
|
end
|
data/lib/solargraph.rb
CHANGED
@@ -3,18 +3,21 @@ require 'rubygems/package'
|
|
3
3
|
require 'yard-solargraph'
|
4
4
|
|
5
5
|
module Solargraph
|
6
|
-
autoload :Analyzer,
|
7
|
-
autoload :Shell,
|
8
|
-
autoload :LiveParser,
|
9
|
-
autoload :ApiMap,
|
10
|
-
autoload :CodeMap,
|
11
|
-
autoload :NodeMethods,
|
12
|
-
autoload :Suggestion,
|
13
|
-
autoload :Snippets,
|
14
|
-
autoload :Server,
|
15
|
-
autoload :YardMap,
|
16
|
-
autoload :YardMethods,
|
17
|
-
autoload :Pin,
|
6
|
+
autoload :Analyzer, 'solargraph/analyzer'
|
7
|
+
autoload :Shell, 'solargraph/shell'
|
8
|
+
autoload :LiveParser, 'solargraph/live_parser'
|
9
|
+
autoload :ApiMap, 'solargraph/api_map'
|
10
|
+
autoload :CodeMap, 'solargraph/code_map'
|
11
|
+
autoload :NodeMethods, 'solargraph/node_methods'
|
12
|
+
autoload :Suggestion, 'solargraph/suggestion'
|
13
|
+
autoload :Snippets, 'solargraph/snippets'
|
14
|
+
autoload :Server, 'solargraph/server'
|
15
|
+
autoload :YardMap, 'solargraph/yard_map'
|
16
|
+
autoload :YardMethods, 'solargraph/yard_methods'
|
17
|
+
autoload :Pin, 'solargraph/pin'
|
18
|
+
autoload :LiveMap, 'solargraph/live_map'
|
19
|
+
autoload :ServerMethods, 'solargraph/server_methods'
|
20
|
+
autoload :Plugin, 'solargraph/plugin'
|
18
21
|
|
19
22
|
YARDOC_PATH = File.join(File.realpath(File.dirname(__FILE__)), '..', 'yardoc')
|
20
23
|
YARD_EXTENSION_FILE = File.join(File.realpath(File.dirname(__FILE__)), 'yard-solargraph.rb')
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: solargraph
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.13.
|
4
|
+
version: 0.13.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Fred Snyder
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-11-
|
11
|
+
date: 2017-11-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: parser
|
@@ -76,30 +76,30 @@ dependencies:
|
|
76
76
|
name: bundler
|
77
77
|
requirement: !ruby/object:Gem::Requirement
|
78
78
|
requirements:
|
79
|
-
- - "
|
79
|
+
- - "~>"
|
80
80
|
- !ruby/object:Gem::Version
|
81
|
-
version: '
|
81
|
+
version: '1.14'
|
82
82
|
type: :runtime
|
83
83
|
prerelease: false
|
84
84
|
version_requirements: !ruby/object:Gem::Requirement
|
85
85
|
requirements:
|
86
|
-
- - "
|
86
|
+
- - "~>"
|
87
87
|
- !ruby/object:Gem::Version
|
88
|
-
version: '
|
88
|
+
version: '1.14'
|
89
89
|
- !ruby/object:Gem::Dependency
|
90
90
|
name: puma
|
91
91
|
requirement: !ruby/object:Gem::Requirement
|
92
92
|
requirements:
|
93
|
-
- - "
|
93
|
+
- - "~>"
|
94
94
|
- !ruby/object:Gem::Version
|
95
|
-
version: '
|
95
|
+
version: '3.8'
|
96
96
|
type: :runtime
|
97
97
|
prerelease: false
|
98
98
|
version_requirements: !ruby/object:Gem::Requirement
|
99
99
|
requirements:
|
100
|
-
- - "
|
100
|
+
- - "~>"
|
101
101
|
- !ruby/object:Gem::Version
|
102
|
-
version: '
|
102
|
+
version: '3.8'
|
103
103
|
- !ruby/object:Gem::Dependency
|
104
104
|
name: rspec
|
105
105
|
requirement: !ruby/object:Gem::Requirement
|
@@ -190,6 +190,8 @@ files:
|
|
190
190
|
- lib/solargraph/api_map/config.rb
|
191
191
|
- lib/solargraph/api_map/source.rb
|
192
192
|
- lib/solargraph/code_map.rb
|
193
|
+
- lib/solargraph/live_map.rb
|
194
|
+
- lib/solargraph/live_map/cache.rb
|
193
195
|
- lib/solargraph/node_methods.rb
|
194
196
|
- lib/solargraph/pin.rb
|
195
197
|
- lib/solargraph/pin/attribute.rb
|
@@ -197,12 +199,20 @@ files:
|
|
197
199
|
- lib/solargraph/pin/base_variable.rb
|
198
200
|
- lib/solargraph/pin/class_variable.rb
|
199
201
|
- lib/solargraph/pin/constant.rb
|
202
|
+
- lib/solargraph/pin/directed.rb
|
203
|
+
- lib/solargraph/pin/directed/attribute.rb
|
204
|
+
- lib/solargraph/pin/directed/method.rb
|
200
205
|
- lib/solargraph/pin/global_variable.rb
|
201
206
|
- lib/solargraph/pin/instance_variable.rb
|
202
207
|
- lib/solargraph/pin/local_variable.rb
|
203
208
|
- lib/solargraph/pin/method.rb
|
204
209
|
- lib/solargraph/pin/symbol.rb
|
210
|
+
- lib/solargraph/plugin.rb
|
211
|
+
- lib/solargraph/plugin/base.rb
|
212
|
+
- lib/solargraph/plugin/response.rb
|
213
|
+
- lib/solargraph/plugin/runtime.rb
|
205
214
|
- lib/solargraph/server.rb
|
215
|
+
- lib/solargraph/server_methods.rb
|
206
216
|
- lib/solargraph/shell.rb
|
207
217
|
- lib/solargraph/snippets.rb
|
208
218
|
- lib/solargraph/suggestion.rb
|
@@ -237,7 +247,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
237
247
|
version: '0'
|
238
248
|
requirements: []
|
239
249
|
rubyforge_project:
|
240
|
-
rubygems_version: 2.5
|
250
|
+
rubygems_version: 2.4.5
|
241
251
|
signing_key:
|
242
252
|
specification_version: 4
|
243
253
|
summary: Solargraph for Ruby
|