solargraph 0.14.3 → 0.15.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 +1 -21
- data/lib/solargraph/api_map.rb +74 -23
- data/lib/solargraph/api_map/config.rb +5 -0
- data/lib/solargraph/api_map/source.rb +44 -45
- data/lib/solargraph/api_map/source_to_yard.rb +66 -0
- data/lib/solargraph/code_map.rb +71 -32
- data/lib/solargraph/live_map.rb +18 -10
- data/lib/solargraph/plugin/process.rb +12 -16
- data/lib/solargraph/plugin/runtime.rb +3 -1
- data/lib/solargraph/server.rb +4 -14
- data/lib/solargraph/shell.rb +23 -47
- data/lib/solargraph/suggestion.rb +4 -1
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/yard_map.rb +31 -33
- data/lib/solargraph/yard_map/core_docs.rb +111 -0
- data/yardoc/2.2.2.tar.gz +0 -0
- metadata +5 -3
- data/yardoc/2.0.0.tar.gz +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a4f454b9e7f567d76ddc0b8902986eedbaa954be
|
4
|
+
data.tar.gz: 6c6717978be4f958dce42035ba8640cf332c9fe2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5db48477da0eb98a11a52b9f456d6bb693a79eb8efda1689b2b7cb1402c1011a84d099f4c29ffb6c35489a1937ed54da074ba2c07f198919f0534b06f555ed7f
|
7
|
+
data.tar.gz: 512f69ecf4dcd355e55cb5a5a9f44aa9af792273f3fb99e0fcf17944b0b7006bb338e4560795ca4cf33a0526b29c06b60ad8a0fd740ded92c906499dd371d8ed
|
data/lib/solargraph.rb
CHANGED
@@ -20,24 +20,4 @@ module Solargraph
|
|
20
20
|
YARD_EXTENSION_FILE = File.join(File.realpath(File.dirname(__FILE__)), 'yard-solargraph.rb')
|
21
21
|
end
|
22
22
|
|
23
|
-
|
24
|
-
cache_dir = File.join(Dir.home, '.solargraph', 'cache')
|
25
|
-
version_dir = File.join(cache_dir, '2.0.0')
|
26
|
-
unless File.exist?(version_dir)
|
27
|
-
FileUtils.mkdir_p cache_dir
|
28
|
-
FileUtils.cp File.join(Solargraph::YARDOC_PATH, '2.0.0.tar.gz'), cache_dir
|
29
|
-
tar_extract = Gem::Package::TarReader.new(Zlib::GzipReader.open(File.join(cache_dir, '2.0.0.tar.gz')))
|
30
|
-
tar_extract.rewind
|
31
|
-
tar_extract.each do |entry|
|
32
|
-
if entry.directory?
|
33
|
-
FileUtils.mkdir_p File.join(cache_dir, entry.full_name)
|
34
|
-
else
|
35
|
-
FileUtils.mkdir_p File.join(cache_dir, File.dirname(entry.full_name))
|
36
|
-
File.open(File.join(cache_dir, entry.full_name), 'wb') do |f|
|
37
|
-
f << entry.read
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
|
-
tar_extract.close
|
42
|
-
#FileUtils.rm File.join(cache_dir, '2.0.0.tar.gz')
|
43
|
-
end
|
23
|
+
Solargraph::YardMap::CoreDocs.require_minimum
|
data/lib/solargraph/api_map.rb
CHANGED
@@ -4,10 +4,10 @@ require 'thread'
|
|
4
4
|
|
5
5
|
module Solargraph
|
6
6
|
class ApiMap
|
7
|
-
autoload :Config,
|
8
|
-
autoload :Source,
|
9
|
-
autoload :Cache,
|
10
|
-
|
7
|
+
autoload :Config, 'solargraph/api_map/config'
|
8
|
+
autoload :Source, 'solargraph/api_map/source'
|
9
|
+
autoload :Cache, 'solargraph/api_map/cache'
|
10
|
+
autoload :SourceToYard, 'solargraph/api_map/source_to_yard'
|
11
11
|
@@source_cache = {}
|
12
12
|
|
13
13
|
KEYWORDS = [
|
@@ -23,6 +23,7 @@ module Solargraph
|
|
23
23
|
].freeze
|
24
24
|
|
25
25
|
include NodeMethods
|
26
|
+
include Solargraph::ApiMap::SourceToYard
|
26
27
|
|
27
28
|
# The root directory of the project. The ApiMap will search here for
|
28
29
|
# additional files to parse and analyze.
|
@@ -40,7 +41,7 @@ module Solargraph
|
|
40
41
|
workspace_files.each do |wf|
|
41
42
|
begin
|
42
43
|
@@source_cache[wf] ||= Source.load(wf)
|
43
|
-
rescue
|
44
|
+
rescue Parser::SyntaxError => e
|
44
45
|
STDERR.puts "Failed to load #{wf}: #{e.message}"
|
45
46
|
end
|
46
47
|
end
|
@@ -49,6 +50,7 @@ module Solargraph
|
|
49
50
|
@virtual_source = nil
|
50
51
|
@virtual_filename = nil
|
51
52
|
@stale = true
|
53
|
+
@yard_stale = true
|
52
54
|
refresh
|
53
55
|
yard_map
|
54
56
|
end
|
@@ -333,6 +335,14 @@ module Solargraph
|
|
333
335
|
suggest_unique_variables globals
|
334
336
|
end
|
335
337
|
|
338
|
+
def get_global_variable_pins
|
339
|
+
globals = []
|
340
|
+
@sources.values.each do |s|
|
341
|
+
globals.concat s.global_variable_pins
|
342
|
+
end
|
343
|
+
globals
|
344
|
+
end
|
345
|
+
|
336
346
|
# @return [String]
|
337
347
|
def infer_assignment_node_type node, namespace
|
338
348
|
type = cache.get_assignment_node_type(node, namespace)
|
@@ -369,6 +379,13 @@ module Solargraph
|
|
369
379
|
return cache.get_signature_type(signature, namespace, scope)
|
370
380
|
end
|
371
381
|
return nil if signature.nil? or signature.empty?
|
382
|
+
if !signature.include?('.')
|
383
|
+
fqns = find_fully_qualified_namespace(signature, namespace)
|
384
|
+
unless fqns.nil? or fqns.empty?
|
385
|
+
type = (get_namespace_type(fqns) == :class ? 'Class' : 'Module')
|
386
|
+
return "#{type}<#{fqns}>"
|
387
|
+
end
|
388
|
+
end
|
372
389
|
result = nil
|
373
390
|
if namespace.end_with?('#class')
|
374
391
|
result = infer_signature_type signature, namespace[0..-7], scope: (scope == :class ? :instance : :class)
|
@@ -439,7 +456,7 @@ module Solargraph
|
|
439
456
|
if type == :class
|
440
457
|
meths.concat yard_map.get_instance_methods('Class')
|
441
458
|
else
|
442
|
-
meths.concat yard_map.
|
459
|
+
meths.concat yard_map.get_instance_methods('Module')
|
443
460
|
end
|
444
461
|
end
|
445
462
|
news = meths.select{|s| s.label == 'new'}
|
@@ -474,6 +491,8 @@ module Solargraph
|
|
474
491
|
namespace = clean_namespace_string(namespace)
|
475
492
|
if namespace.end_with?('#class')
|
476
493
|
return get_methods(namespace.split('#').first, root, visibility: visibility)
|
494
|
+
elsif namespace.end_with?('#module')
|
495
|
+
return get_methods(namespace.split('#').first, root, visibility: visibility)
|
477
496
|
end
|
478
497
|
meths = []
|
479
498
|
meths += inner_get_instance_methods(namespace, root, [], visibility) #unless has_yardoc?
|
@@ -489,6 +508,11 @@ module Solargraph
|
|
489
508
|
meths += yard_map.get_instance_methods('Module')
|
490
509
|
end
|
491
510
|
end
|
511
|
+
if namespace == '' and root == ''
|
512
|
+
config.domains.each do |d|
|
513
|
+
meths.concat get_instance_methods(d)
|
514
|
+
end
|
515
|
+
end
|
492
516
|
strings = meths.map(&:to_s)
|
493
517
|
live_map.get_methods(namespace, root, 'instance', visibility.include?(:private)).each do |m|
|
494
518
|
next if strings.include?(m) or !m.match(/^[a-z]/i)
|
@@ -513,6 +537,10 @@ module Solargraph
|
|
513
537
|
def update filename
|
514
538
|
filename.gsub!(/\\/, '/')
|
515
539
|
if filename.end_with?('.rb')
|
540
|
+
if @virtual_filename == filename
|
541
|
+
@virtual_filename = nil
|
542
|
+
@virtual_source = nil
|
543
|
+
end
|
516
544
|
if @workspace_files.include?(filename)
|
517
545
|
eliminate filename
|
518
546
|
@@source_cache[filename] = Source.load(filename)
|
@@ -556,6 +584,30 @@ module Solargraph
|
|
556
584
|
result
|
557
585
|
end
|
558
586
|
|
587
|
+
def search query
|
588
|
+
refresh
|
589
|
+
rake_yard(@sources.values) if @yard_stale
|
590
|
+
@yard_stale = false
|
591
|
+
found = []
|
592
|
+
code_object_paths.each do |k|
|
593
|
+
if found.empty? or (query.include?('.') or query.include?('#')) or !(k.include?('.') or k.include?('#'))
|
594
|
+
found.push k if k.downcase.include?(query.downcase)
|
595
|
+
end
|
596
|
+
end
|
597
|
+
found.concat(yard_map.search(query)).uniq.sort
|
598
|
+
end
|
599
|
+
|
600
|
+
# @return [Array<YARD::CodeObject::Base>]
|
601
|
+
def document path
|
602
|
+
refresh
|
603
|
+
rake_yard(@sources.values) if @yard_stale
|
604
|
+
@yard_stale = false
|
605
|
+
docs = []
|
606
|
+
docs.push code_object_at(path) unless code_object_at(path).nil?
|
607
|
+
docs.concat yard_map.document(path)
|
608
|
+
docs
|
609
|
+
end
|
610
|
+
|
559
611
|
private
|
560
612
|
|
561
613
|
# @return [Hash]
|
@@ -599,6 +651,7 @@ module Solargraph
|
|
599
651
|
@required.uniq!
|
600
652
|
live_map.refresh
|
601
653
|
@stale = false
|
654
|
+
@yard_stale = true
|
602
655
|
end
|
603
656
|
|
604
657
|
def rebuild_local_yardoc
|
@@ -707,13 +760,9 @@ module Solargraph
|
|
707
760
|
if visibility.include?(:public) or visibility.include?(:protected)
|
708
761
|
sc = @superclasses[fqns]
|
709
762
|
unless sc.nil?
|
710
|
-
|
711
|
-
|
712
|
-
|
713
|
-
live_map.get_methods(sc, fqns, 'class', false).each do |m|
|
714
|
-
next if strings.include?(m) or !m.match(/^[a-z]/i)
|
715
|
-
meths.push Suggestion.new(m, kind: Suggestion::METHOD, docstring: YARD::Docstring.new('(defined at runtime)'), path: "#{fqns}##{m}")
|
716
|
-
end
|
763
|
+
sc_visi = [:public]
|
764
|
+
sc_visi.push :protected if root == fqns
|
765
|
+
meths.concat get_methods(sc, fqns, visibility: sc_visi)
|
717
766
|
end
|
718
767
|
end
|
719
768
|
meths.uniq
|
@@ -739,13 +788,9 @@ module Solargraph
|
|
739
788
|
if visibility.include?(:public) or visibility.include?(:protected)
|
740
789
|
sc = @superclasses[fqns]
|
741
790
|
unless sc.nil?
|
742
|
-
|
743
|
-
|
744
|
-
|
745
|
-
live_map.get_methods(sc, fqns, 'instance', false).each do |m|
|
746
|
-
next if strings.include?(m) or !m.match(/^[a-z]/i)
|
747
|
-
meths.push Suggestion.new(m, kind: Suggestion::METHOD, docstring: YARD::Docstring.new('(defined at runtime)'))
|
748
|
-
end
|
791
|
+
sc_visi = [:public]
|
792
|
+
sc_visi.push :protected if sc == fqns
|
793
|
+
meths.concat get_instance_methods(sc, fqns, visibility: sc_visi)
|
749
794
|
end
|
750
795
|
end
|
751
796
|
im = @namespace_includes[fqns]
|
@@ -768,9 +813,12 @@ module Solargraph
|
|
768
813
|
signature.gsub!(/\.$/, '')
|
769
814
|
if signature.empty?
|
770
815
|
if scope == :class
|
771
|
-
|
772
|
-
|
773
|
-
|
816
|
+
type = get_namespace_type(namespace)
|
817
|
+
if type == :class
|
818
|
+
return "Class<#{namespace}>"
|
819
|
+
else
|
820
|
+
return "Module<#{namespace}>"
|
821
|
+
end
|
774
822
|
end
|
775
823
|
end
|
776
824
|
parts = signature.split('.')
|
@@ -846,6 +894,9 @@ module Solargraph
|
|
846
894
|
if result == 'Class' and namespace.include?('<')
|
847
895
|
subtype = namespace.match(/<([a-z0-9:_]*)/i)[1]
|
848
896
|
result = "#{subtype}#class"
|
897
|
+
elsif result == 'Module' and namespace.include?('<')
|
898
|
+
subtype = namespace.match(/<([a-z0-9:_]*)/i)[1]
|
899
|
+
result = "#{subtype}#module"
|
849
900
|
end
|
850
901
|
result
|
851
902
|
end
|
@@ -32,6 +32,7 @@ module Solargraph
|
|
32
32
|
@raw_data['exclude'] ||= exclude_globs
|
33
33
|
@raw_data['domains'] ||= []
|
34
34
|
@raw_data['required'] ||= []
|
35
|
+
@raw_data['plugins'] ||= []
|
35
36
|
end
|
36
37
|
|
37
38
|
# An array of files included in the workspace (before calculating excluded files).
|
@@ -66,6 +67,10 @@ module Solargraph
|
|
66
67
|
raw_data['required']
|
67
68
|
end
|
68
69
|
|
70
|
+
def plugins
|
71
|
+
raw_data['plugins']
|
72
|
+
end
|
73
|
+
|
69
74
|
private
|
70
75
|
|
71
76
|
def process_globs globs
|
@@ -15,9 +15,12 @@ module Solargraph
|
|
15
15
|
# @return [String]
|
16
16
|
attr_reader :filename
|
17
17
|
|
18
|
+
# @return [Array<Integer>]
|
19
|
+
attr_reader :stubbed_lines
|
20
|
+
|
18
21
|
include NodeMethods
|
19
22
|
|
20
|
-
def initialize code, node, comments, filename
|
23
|
+
def initialize code, node, comments, filename, stubbed_lines = []
|
21
24
|
@code = code
|
22
25
|
root = AST::Node.new(:source, [filename])
|
23
26
|
root = root.append node
|
@@ -30,6 +33,7 @@ module Solargraph
|
|
30
33
|
@all_nodes = []
|
31
34
|
@node_stack = []
|
32
35
|
@node_tree = {}
|
36
|
+
@stubbed_lines = stubbed_lines
|
33
37
|
inner_map_node @node
|
34
38
|
@directives.each_pair do |k, v|
|
35
39
|
v.each do |d|
|
@@ -324,67 +328,62 @@ module Solargraph
|
|
324
328
|
Source.new(code, node, comments, filename)
|
325
329
|
end
|
326
330
|
|
327
|
-
|
328
|
-
|
331
|
+
def get_position_at(code, offset)
|
332
|
+
cursor = 0
|
333
|
+
line = 0
|
334
|
+
col = nil
|
335
|
+
code.each_line do |l|
|
336
|
+
if cursor + l.length >= offset
|
337
|
+
col = offset - cursor
|
338
|
+
break
|
339
|
+
end
|
340
|
+
cursor += l.length
|
341
|
+
line += 1
|
342
|
+
end
|
343
|
+
raise "Invalid offset" if col.nil?
|
344
|
+
[line, col]
|
345
|
+
end
|
346
|
+
|
347
|
+
def fix code, filename = nil, offset = nil
|
329
348
|
tries = 0
|
330
349
|
code.gsub!(/\r/, '')
|
350
|
+
offset = CodeMap.get_offset(code, offset[0], offset[1]) if offset.kind_of?(Array)
|
351
|
+
pos = nil
|
352
|
+
pos = get_position_at(code, offset) unless offset.nil?
|
353
|
+
stubs = []
|
354
|
+
fixed_position = false
|
331
355
|
tmp = code
|
332
|
-
cursor = CodeMap.get_offset(code, cursor[0], cursor[1]) if cursor.kind_of?(Array)
|
333
|
-
fixed_cursor = false
|
334
356
|
begin
|
335
|
-
|
336
|
-
|
337
|
-
# variable assignment).
|
338
|
-
node, comments = Parser::CurrentRuby.parse_with_comments(tmp + "\n_")
|
339
|
-
Source.new(code, node, comments, filename)
|
357
|
+
node, comments = Parser::CurrentRuby.parse_with_comments(tmp)
|
358
|
+
Source.new(code, node, comments, filename, stubs)
|
340
359
|
rescue Parser::SyntaxError => e
|
341
360
|
if tries < 10
|
342
361
|
tries += 1
|
343
|
-
|
362
|
+
# Stub periods before the offset to retain the expected node tree
|
363
|
+
if !offset.nil? and tmp[offset-1] == '.'
|
364
|
+
tmp = tmp[0, offset-1] + '_' + tmp[offset..-1]
|
365
|
+
elsif !fixed_position and !offset.nil?
|
366
|
+
fixed_position = true
|
367
|
+
beg = beginning_of_line_from(tmp, offset)
|
368
|
+
tmp = tmp[0, beg] + '#' + tmp[beg+1..-1]
|
369
|
+
stubs.push(pos[0])
|
370
|
+
elsif e.message.include?('token $end')
|
344
371
|
tmp += "\nend"
|
345
|
-
|
346
|
-
|
347
|
-
fixed_cursor = true
|
348
|
-
spot = cursor - 2
|
349
|
-
if tmp[cursor - 1] == '.' or tmp[cursor - 1] == '$'
|
350
|
-
repl = ';'
|
351
|
-
else
|
352
|
-
repl = '#'
|
353
|
-
end
|
354
|
-
else
|
355
|
-
spot = e.diagnostic.location.begin_pos
|
356
|
-
repl = '_'
|
357
|
-
if tmp[spot] == '@' or tmp[spot] == ':'
|
358
|
-
# Stub unfinished instance variables and symbols
|
359
|
-
spot -= 1
|
360
|
-
elsif tmp[spot - 1] == '.'
|
361
|
-
# Stub unfinished method calls
|
362
|
-
repl = '#' if spot == tmp.length or tmp[spot] == '\n'
|
363
|
-
spot -= 2
|
364
|
-
else
|
365
|
-
# Stub the whole line
|
366
|
-
spot = beginning_of_line_from(tmp, spot)
|
367
|
-
repl = '#'
|
368
|
-
if tmp[spot+1..-1].rstrip == 'end'
|
369
|
-
repl= 'end;end'
|
370
|
-
end
|
371
|
-
end
|
372
|
-
end
|
373
|
-
tmp = tmp[0..spot] + repl + tmp[spot+repl.length+1..-1].to_s
|
372
|
+
elsif e.message.include?("unexpected `@'")
|
373
|
+
tmp = tmp[0, e.diagnostic.location.begin_pos] + '_' + tmp[e.diagnostic.location.begin_pos+1..-1]
|
374
374
|
end
|
375
375
|
retry
|
376
376
|
end
|
377
|
-
|
377
|
+
STDERR.puts "Unable to parse code: #{e.message}"
|
378
|
+
virt = Source.virtual('', filename)
|
379
|
+
Source.new(code, virt.node, virt.comments, filename)
|
378
380
|
end
|
379
381
|
end
|
380
382
|
|
381
383
|
def beginning_of_line_from str, i
|
382
|
-
while i > 0 and str[i] != "\n"
|
384
|
+
while i > 0 and str[i-1] != "\n"
|
383
385
|
i -= 1
|
384
386
|
end
|
385
|
-
if i > 0 and str[i..-1].strip == ''
|
386
|
-
i = beginning_of_line_from str, i -1
|
387
|
-
end
|
388
387
|
i
|
389
388
|
end
|
390
389
|
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
module Solargraph
|
2
|
+
class ApiMap
|
3
|
+
module SourceToYard
|
4
|
+
|
5
|
+
# Get the YARD CodeObject at the specified path.
|
6
|
+
#
|
7
|
+
# @return [YARD::CodeObjects::Base]
|
8
|
+
def code_object_at path
|
9
|
+
code_object_map[path]
|
10
|
+
end
|
11
|
+
|
12
|
+
def code_object_paths
|
13
|
+
code_object_map.keys
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def code_object_map
|
19
|
+
@code_object_map ||= {}
|
20
|
+
end
|
21
|
+
|
22
|
+
def rake_yard sources
|
23
|
+
code_object_map.clear
|
24
|
+
sources.each do |s|
|
25
|
+
s.namespace_pins.each do |pin|
|
26
|
+
if pin.kind == :class
|
27
|
+
code_object_map[pin.path] ||= YARD::CodeObjects::ClassObject.new(code_object_at(pin.namespace), pin.name)
|
28
|
+
else
|
29
|
+
code_object_map[pin.path] ||= YARD::CodeObjects::ModuleObject.new(code_object_at(pin.namespace), pin.name)
|
30
|
+
end
|
31
|
+
code_object_map[pin.path].docstring = pin.docstring unless pin.docstring.nil?
|
32
|
+
end
|
33
|
+
s.namespace_includes.each_pair do |n, i|
|
34
|
+
code_object_map[n].mixins.push code_object_map[i] unless code_object_map[i].nil?
|
35
|
+
end
|
36
|
+
s.attribute_pins.each do |pin|
|
37
|
+
STDERR.puts "Adding #{pin.name} attribute to #{pin.namespace}"
|
38
|
+
code_object_map[pin.path] ||= YARD::CodeObjects::MethodObject.new(code_object_at(pin.namespace), pin.name, :instance)
|
39
|
+
code_object_map[pin.path].docstring = pin.docstring unless pin.docstring.nil?
|
40
|
+
code_object_map[pin.parameters] = []
|
41
|
+
#code_object_map[pin.path].parameters = pin.parameters.map do |p|
|
42
|
+
# n = p.match(/^[a-z0-9\-]*?:?/i)[0]
|
43
|
+
# v = nil
|
44
|
+
# if p.length > n.length
|
45
|
+
# v = p[n.length..-1].gsub(/^ = /, '')
|
46
|
+
# end
|
47
|
+
# [n, v]
|
48
|
+
#end
|
49
|
+
end
|
50
|
+
s.method_pins.each do |pin|
|
51
|
+
code_object_map[pin.path] ||= YARD::CodeObjects::MethodObject.new(code_object_at(pin.namespace), pin.name, pin.scope)
|
52
|
+
code_object_map[pin.path].docstring = pin.docstring unless pin.docstring.nil?
|
53
|
+
code_object_map[pin.path].parameters = pin.parameters.map do |p|
|
54
|
+
n = p.match(/^[a-z0-9\-]*?:?/i)[0]
|
55
|
+
v = nil
|
56
|
+
if p.length > n.length
|
57
|
+
v = p[n.length..-1].gsub(/^ = /, '')
|
58
|
+
end
|
59
|
+
[n, v]
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
data/lib/solargraph/code_map.rb
CHANGED
@@ -23,18 +23,9 @@ module Solargraph
|
|
23
23
|
# @return [String]
|
24
24
|
attr_reader :filename
|
25
25
|
|
26
|
-
# The root directory of the project. The ApiMap will search here for
|
27
|
-
# additional files to parse and analyze.
|
28
|
-
# @deprecated CodeMap will be server-agnostic in a future version.
|
29
|
-
#
|
30
|
-
# @return [String]
|
31
|
-
attr_reader :workspace
|
32
|
-
|
33
26
|
include NodeMethods
|
34
27
|
|
35
|
-
def initialize code: '', filename: nil,
|
36
|
-
STDERR.puts "WARNING: the `workspace` parameter in Solargraph::CodeMap#new is deprecated and will be removed in a future version." unless workspace.nil?
|
37
|
-
@workspace = workspace
|
28
|
+
def initialize code: '', filename: nil, api_map: nil, cursor: nil
|
38
29
|
# HACK: Adjust incoming filename's path separator for yardoc file comparisons
|
39
30
|
filename = filename.gsub(File::ALT_SEPARATOR, File::SEPARATOR) unless filename.nil? or File::ALT_SEPARATOR.nil?
|
40
31
|
@filename = filename
|
@@ -50,7 +41,7 @@ module Solargraph
|
|
50
41
|
#
|
51
42
|
# @return [Solargraph::ApiMap]
|
52
43
|
def api_map
|
53
|
-
@api_map ||= ApiMap.new(
|
44
|
+
@api_map ||= ApiMap.new(nil)
|
54
45
|
end
|
55
46
|
|
56
47
|
# Get the offset of the specified line and column.
|
@@ -107,6 +98,8 @@ module Solargraph
|
|
107
98
|
#
|
108
99
|
# @return [Boolean]
|
109
100
|
def comment_at?(index)
|
101
|
+
line, col = Solargraph::ApiMap::Source.get_position_at(source.code, index)
|
102
|
+
return false if source.stubbed_lines.include?(line)
|
110
103
|
@comments.each do |c|
|
111
104
|
return true if index > c.location.expression.begin_pos and index <= c.location.expression.end_pos
|
112
105
|
end
|
@@ -241,9 +234,9 @@ module Solargraph
|
|
241
234
|
parts.pop
|
242
235
|
end
|
243
236
|
result += api_map.get_constants('')
|
244
|
-
result += api_map.get_instance_methods('Kernel')
|
245
|
-
result += api_map.get_methods('')
|
246
|
-
result += api_map.get_instance_methods('')
|
237
|
+
result += api_map.get_instance_methods('Kernel', namespace)
|
238
|
+
result += api_map.get_methods('', namespace)
|
239
|
+
#result += api_map.get_instance_methods('', namespace)
|
247
240
|
else
|
248
241
|
result.concat api_map.get_instance_methods(type)
|
249
242
|
end
|
@@ -333,7 +326,7 @@ module Solargraph
|
|
333
326
|
end
|
334
327
|
type = infer_literal_node_type(literal)
|
335
328
|
if type.nil?
|
336
|
-
node = parent_node_from(index, :class, :module, :def, :defs) || @node
|
329
|
+
node = parent_node_from(index, :class, :module, :def, :defs, :block) || @node
|
337
330
|
result = infer_signature_from_node signature, node
|
338
331
|
if result.nil? or result.empty?
|
339
332
|
# The rest of this routine is dedicated to method and block parameters
|
@@ -428,6 +421,9 @@ module Solargraph
|
|
428
421
|
scope = (node.type == :def ? :instance : :class)
|
429
422
|
iv = api_map.get_instance_variable_pins(ns_here, scope).select{|s| s.name == start}.first
|
430
423
|
return (iv.return_type || api_map.infer_assignment_node_type(iv.node, iv.namespace)) unless iv.nil?
|
424
|
+
elsif start.start_with?('$')
|
425
|
+
gv = api_map.get_global_variable_pins.select{|s| s.name == start}.first
|
426
|
+
return (gv.return_type || api_map.infer_assignment_node_type(gv.node, gv.namespace)) unless gv.nil?
|
431
427
|
end
|
432
428
|
var = find_local_variable_node(start, node)
|
433
429
|
if var.nil?
|
@@ -458,6 +454,19 @@ module Solargraph
|
|
458
454
|
inferred = api_map.infer_signature_type(remainder.join('.'), type, scope: :instance)
|
459
455
|
end
|
460
456
|
end
|
457
|
+
if inferred.nil? and node.respond_to?(:loc)
|
458
|
+
index = node.loc.expression.begin_pos
|
459
|
+
block_node = parent_node_from(index, :block, :class, :module, :sclass, :def, :defs)
|
460
|
+
unless block_node.nil? or block_node.type != :block or block_node.children[0].nil?
|
461
|
+
scope_node = parent_node_from(index, :class, :module, :def, :defs) || @node
|
462
|
+
meth = get_yielding_method_with_yieldself(block_node, scope_node)
|
463
|
+
unless meth.nil?
|
464
|
+
match = meth.docstring.all.match(/@yieldself \[([a-z0-9:_]*)/i)
|
465
|
+
self_yield = match[1]
|
466
|
+
inferred = api_map.infer_signature_type(signature, self_yield, scope: :instance)
|
467
|
+
end
|
468
|
+
end
|
469
|
+
end
|
461
470
|
inferred
|
462
471
|
end
|
463
472
|
|
@@ -516,9 +525,7 @@ module Solargraph
|
|
516
525
|
if local.type == :def or local.type == :defs
|
517
526
|
result += get_method_arguments_from local
|
518
527
|
end
|
519
|
-
result
|
520
|
-
# @todo This might not be necessary.
|
521
|
-
#result += api_map.get_methods('Kernel')
|
528
|
+
result.concat get_yieldparams_at(index)
|
522
529
|
result
|
523
530
|
end
|
524
531
|
|
@@ -590,7 +597,8 @@ module Solargraph
|
|
590
597
|
end
|
591
598
|
|
592
599
|
def get_yieldparams_at index
|
593
|
-
block_node = parent_node_from(index, :block)
|
600
|
+
block_node = parent_node_from(index, :block, :class, :module, :def, :defs)
|
601
|
+
return [] if block_node.nil? or block_node.type != :block
|
594
602
|
scope_node = parent_node_from(index, :class, :module, :def, :defs) || @node
|
595
603
|
return [] if block_node.nil?
|
596
604
|
get_yieldparams_from block_node, scope_node
|
@@ -600,32 +608,63 @@ module Solargraph
|
|
600
608
|
return [] unless block_node.kind_of?(AST::Node) and block_node.type == :block
|
601
609
|
result = []
|
602
610
|
unless block_node.nil? or block_node.children[1].nil?
|
603
|
-
|
604
|
-
fqns = namespace_from(block_node)
|
605
|
-
lvarnode = find_local_variable_node(recv, scope_node)
|
606
|
-
if lvarnode.nil?
|
607
|
-
sig = api_map.infer_signature_type(recv, fqns)
|
608
|
-
else
|
609
|
-
tmp = resolve_node_signature(lvarnode.children[1])
|
610
|
-
sig = infer_signature_from_node tmp, scope_node
|
611
|
-
end
|
612
|
-
meths = api_map.get_instance_methods(sig, fqns)
|
613
|
-
meths += api_map.get_methods('')
|
614
|
-
meth = meths.keep_if{ |s| s.to_s == block_node.children[0].children[1].to_s }.first
|
611
|
+
meth = get_yielding_method(block_node, scope_node)
|
615
612
|
yps = []
|
616
613
|
unless meth.nil? or meth.docstring.nil?
|
617
614
|
yps = meth.docstring.tags(:yieldparam) || []
|
618
615
|
end
|
616
|
+
self_yield = nil
|
617
|
+
meth = get_yielding_method_with_yieldself(block_node, scope_node)
|
618
|
+
unless meth.nil?
|
619
|
+
match = meth.docstring.all.match(/@yieldself \[([a-z0-9:_]*)/i)
|
620
|
+
self_yield = match[1]
|
621
|
+
end
|
619
622
|
i = 0
|
620
623
|
block_node.children[1].children.each do |a|
|
621
624
|
rt = (yps[i].nil? ? nil : yps[i].types[0])
|
622
625
|
result.push Suggestion.new(a.children[0], kind: Suggestion::PROPERTY, return_type: rt)
|
623
626
|
i += 1
|
624
627
|
end
|
628
|
+
result.concat api_map.get_instance_methods(self_yield, namespace_from(scope_node)) unless self_yield.nil?
|
625
629
|
end
|
626
630
|
result
|
627
631
|
end
|
628
632
|
|
633
|
+
def get_yielding_method block_node, scope_node
|
634
|
+
recv = resolve_node_signature(block_node.children[0].children[0])
|
635
|
+
fqns = namespace_from(block_node)
|
636
|
+
lvarnode = find_local_variable_node(recv, scope_node)
|
637
|
+
if lvarnode.nil?
|
638
|
+
sig = api_map.infer_signature_type(recv, fqns)
|
639
|
+
else
|
640
|
+
tmp = resolve_node_signature(lvarnode.children[1])
|
641
|
+
sig = infer_signature_from_node tmp, scope_node
|
642
|
+
end
|
643
|
+
if sig.nil?
|
644
|
+
meths = api_map.get_methods(fqns, fqns)
|
645
|
+
else
|
646
|
+
meths = api_map.get_instance_methods(sig, fqns)
|
647
|
+
end
|
648
|
+
meths += api_map.get_methods('')
|
649
|
+
meth = meths.keep_if{ |s| s.to_s == block_node.children[0].children[1].to_s }.first
|
650
|
+
meth
|
651
|
+
end
|
652
|
+
|
653
|
+
def get_yielding_method_with_yieldself block_node, scope_node
|
654
|
+
meth = get_yielding_method block_node, scope_node
|
655
|
+
if meth.nil? or meth.docstring.nil? or !meth.docstring.all.include?('@yieldself')
|
656
|
+
meth = nil
|
657
|
+
tree = @source.tree_for(block_node)
|
658
|
+
unless tree.nil?
|
659
|
+
tree.each do |p|
|
660
|
+
break if [:def, :defs, :class, :module, :sclass].include?(p.type)
|
661
|
+
return get_yielding_method_with_yieldself(p, scope_node) if p.type == :block
|
662
|
+
end
|
663
|
+
end
|
664
|
+
end
|
665
|
+
meth
|
666
|
+
end
|
667
|
+
|
629
668
|
# @param suggestions [Array<Solargraph::Suggestion>]
|
630
669
|
# @param word [String]
|
631
670
|
def reduce_starting_with(suggestions, word)
|
@@ -661,7 +700,7 @@ module Solargraph
|
|
661
700
|
|
662
701
|
def inner_node_at(index, node, arr)
|
663
702
|
node.children.each do |c|
|
664
|
-
if c.kind_of?(AST::Node)
|
703
|
+
if c.kind_of?(AST::Node) and c.respond_to?(:loc)
|
665
704
|
unless c.loc.expression.nil?
|
666
705
|
if index >= c.loc.expression.begin_pos
|
667
706
|
if c.respond_to?(:end)
|
data/lib/solargraph/live_map.rb
CHANGED
@@ -4,7 +4,7 @@ module Solargraph
|
|
4
4
|
class LiveMap
|
5
5
|
autoload :Cache, 'solargraph/live_map/cache'
|
6
6
|
|
7
|
-
@@
|
7
|
+
@@plugin_registry = {}
|
8
8
|
|
9
9
|
# @return [Solargraph::ApiMap]
|
10
10
|
attr_reader :api_map
|
@@ -68,19 +68,28 @@ module Solargraph
|
|
68
68
|
nil
|
69
69
|
end
|
70
70
|
|
71
|
+
def self.register name, klass
|
72
|
+
raise ArgumentError.new("A Solargraph plugin named #{name} already exists") if @@plugin_registry.has_key?(name)
|
73
|
+
@@plugin_registry[name] = klass
|
74
|
+
end
|
75
|
+
|
71
76
|
# Register a plugin for LiveMap to use when generating suggestions.
|
77
|
+
# @deprecated See Solargraph::LiveMap.register instead
|
72
78
|
#
|
73
79
|
# @param cls [Class<Solargraph::Plugin::Base>]
|
74
80
|
def self.install cls
|
75
|
-
|
81
|
+
STDERR.puts "WARNING: The Solargraph::LiveMap.install procedure for installing plugins is no longer used. This operation will be ignored."
|
76
82
|
end
|
77
83
|
|
84
|
+
# @deprecated
|
78
85
|
def self.uninstall cls
|
79
|
-
|
86
|
+
STDERR.puts "WARNING: The Solargraph::LiveMap.uninstall procedure for uninstalling plugins is no longer used. This operation will be ignored."
|
80
87
|
end
|
81
88
|
|
89
|
+
# @deprecated
|
82
90
|
def self.plugins
|
83
|
-
|
91
|
+
STDERR.puts "WARNING: Plugins have changed. The Solargraph::LiveMap.plugins attribute is no longer used."
|
92
|
+
[]
|
84
93
|
end
|
85
94
|
|
86
95
|
def refresh
|
@@ -114,14 +123,13 @@ module Solargraph
|
|
114
123
|
# @return [Array<Solargraph::Plugin::Base>]
|
115
124
|
def load_runners
|
116
125
|
result = []
|
117
|
-
|
118
|
-
|
119
|
-
r
|
120
|
-
result.push r if !has_runtime or !r.runtime?
|
121
|
-
has_runtime = true if r.runtime?
|
126
|
+
api_map.config.plugins.each do |name|
|
127
|
+
r = @@plugin_registry[name].new(api_map)
|
128
|
+
result.push r
|
122
129
|
end
|
123
|
-
#result.push Solargraph::Plugin::Runtime.new(api_map) unless has_runtime
|
124
130
|
result
|
125
131
|
end
|
126
132
|
end
|
127
133
|
end
|
134
|
+
|
135
|
+
Solargraph::LiveMap.register 'runtime', Solargraph::Plugin::Runtime
|
@@ -64,20 +64,14 @@ module Solargraph
|
|
64
64
|
con = find_constant(args['namespace'], args['root'])
|
65
65
|
unless con.nil?
|
66
66
|
if (args['scope'] == 'class')
|
67
|
-
if args['with_private']
|
68
|
-
|
69
|
-
else
|
70
|
-
result.concat con.public_methods(false)
|
71
|
-
end
|
67
|
+
result.concat con.methods(false) if args['with_private']
|
68
|
+
result.concat con.public_methods(false)
|
72
69
|
elsif (args['scope'] == 'instance')
|
73
|
-
if args['with_private']
|
74
|
-
|
75
|
-
else
|
76
|
-
result.concat con.public_instance_methods(false)
|
77
|
-
end
|
70
|
+
result.concat con.instance_methods(false) if args['with_private']
|
71
|
+
result.concat con.public_instance_methods(false)
|
78
72
|
end
|
79
73
|
end
|
80
|
-
respond_ok result
|
74
|
+
respond_ok result.uniq
|
81
75
|
end
|
82
76
|
|
83
77
|
def get_constants args
|
@@ -103,11 +97,13 @@ module Solargraph
|
|
103
97
|
|
104
98
|
def find_constant(namespace, root)
|
105
99
|
result = nil
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
100
|
+
unless root.empty?
|
101
|
+
parts = root.split('::')
|
102
|
+
until parts.empty?
|
103
|
+
result = inner_find_constant("#{parts.join('::')}::#{namespace}")
|
104
|
+
parts.pop
|
105
|
+
break unless result.nil?
|
106
|
+
end
|
111
107
|
end
|
112
108
|
result = inner_find_constant(namespace) if result.nil?
|
113
109
|
result
|
data/lib/solargraph/server.rb
CHANGED
@@ -121,25 +121,15 @@ module Solargraph
|
|
121
121
|
|
122
122
|
get '/search' do
|
123
123
|
workspace = params['workspace']
|
124
|
-
api_map = get_api_map(workspace)
|
125
|
-
|
126
|
-
unless api_map.nil?
|
127
|
-
required.concat api_map.required
|
128
|
-
end
|
129
|
-
yard = YardMap.new(required: required, workspace: workspace)
|
130
|
-
@results = yard.search(params['query'])
|
124
|
+
api_map = get_api_map(workspace) || Solargraph::ApiMap.new
|
125
|
+
@results = api_map.search(params['query'])
|
131
126
|
erb :search
|
132
127
|
end
|
133
128
|
|
134
129
|
get '/document' do
|
135
130
|
workspace = params['workspace']
|
136
|
-
api_map = get_api_map(workspace)
|
137
|
-
|
138
|
-
unless api_map.nil?
|
139
|
-
required.concat api_map.required
|
140
|
-
end
|
141
|
-
yard = YardMap.new(required: required, workspace: workspace)
|
142
|
-
@objects = yard.document(params['query'])
|
131
|
+
api_map = get_api_map(workspace) || Solargraph::ApiMap.new
|
132
|
+
@objects = api_map.document(params['query'])
|
143
133
|
erb :document
|
144
134
|
end
|
145
135
|
|
data/lib/solargraph/shell.rb
CHANGED
@@ -15,41 +15,6 @@ module Solargraph
|
|
15
15
|
puts Solargraph::VERSION
|
16
16
|
end
|
17
17
|
|
18
|
-
desc 'prepare', 'Cache YARD files for the current environment'
|
19
|
-
option :force, type: :boolean, aliases: :f, desc: 'Force download of YARDOC files if they already exist'
|
20
|
-
option :host, type: :string, aliases: :h, desc: 'The host that provides YARDOC files for download', default: 'yardoc.solargraph.org'
|
21
|
-
def prepare
|
22
|
-
cache_dir = File.join(Dir.home, '.solargraph', 'cache')
|
23
|
-
version_dir = File.join(cache_dir, '2.0.0')
|
24
|
-
unless File.exist?(version_dir) or options[:force]
|
25
|
-
FileUtils.mkdir_p cache_dir
|
26
|
-
puts 'Downloading 2.0.0...'
|
27
|
-
Net::HTTP.start(options[:host]) do |http|
|
28
|
-
resp = http.get("/2.0.0.tar.gz")
|
29
|
-
open(File.join(cache_dir, '2.0.0.tar.gz'), "wb") do |file|
|
30
|
-
file.write(resp.body)
|
31
|
-
end
|
32
|
-
puts 'Uncompressing archives...'
|
33
|
-
FileUtils.rm_rf version_dir if File.exist?(version_dir)
|
34
|
-
tar_extract = Gem::Package::TarReader.new(Zlib::GzipReader.open(File.join(cache_dir, '2.0.0.tar.gz')))
|
35
|
-
tar_extract.rewind
|
36
|
-
tar_extract.each do |entry|
|
37
|
-
if entry.directory?
|
38
|
-
FileUtils.mkdir_p File.join(cache_dir, entry.full_name)
|
39
|
-
else
|
40
|
-
FileUtils.mkdir_p File.join(cache_dir, File.dirname(entry.full_name))
|
41
|
-
File.open(File.join(cache_dir, entry.full_name), 'wb') do |f|
|
42
|
-
f << entry.read
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
46
|
-
tar_extract.close
|
47
|
-
FileUtils.rm File.join(cache_dir, '2.0.0.tar.gz')
|
48
|
-
puts 'Done.'
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
18
|
desc 'server', 'Start a Solargraph server'
|
54
19
|
option :port, type: :numeric, aliases: :p, desc: 'The server port', default: 7657
|
55
20
|
option :views, type: :string, aliases: :v, desc: 'The view template directory', default: nil
|
@@ -74,18 +39,6 @@ module Solargraph
|
|
74
39
|
end
|
75
40
|
end
|
76
41
|
end
|
77
|
-
|
78
|
-
|
79
|
-
desc 'plugin PLUGIN_NAME', 'Run a Solargraph runtime plugin'
|
80
|
-
option :workspace, type: :string, aliases: :w, desc: 'The workspace'
|
81
|
-
option :port, type: :numeric, aliases: :p, desc: 'The server port', required: true
|
82
|
-
option :ppid, type: :numeric, desc: 'ppid'
|
83
|
-
def plugin plugin_name
|
84
|
-
# @todo Find the correct plugin based on the provided name
|
85
|
-
cls = Solargraph::Plugin::Runtime
|
86
|
-
#SolargraphRailsExt::Server.new(options[:workspace], options[:port]).run
|
87
|
-
cls.serve options[:workspace], options[:port], options[:ppid]
|
88
|
-
end
|
89
42
|
|
90
43
|
desc 'suggest', 'Get code suggestions for the provided input'
|
91
44
|
long_desc <<-LONGDESC
|
@@ -95,6 +48,7 @@ module Solargraph
|
|
95
48
|
option :column, type: :numeric, aliases: [:c, :col], desc: 'Zero-based column number', required: true
|
96
49
|
option :filename, type: :string, aliases: :f, desc: 'File name', required: false
|
97
50
|
def suggest(*filenames)
|
51
|
+
STDERR.puts "WARNING: The `solargraph suggest` command is a candidate for deprecation. It will either change drastically or not exist in a future version."
|
98
52
|
# HACK: The ARGV array needs to be manipulated for ARGF.read to work
|
99
53
|
ARGV.clear
|
100
54
|
ARGV.concat filenames
|
@@ -138,5 +92,27 @@ module Solargraph
|
|
138
92
|
end
|
139
93
|
STDOUT.puts "Configuration file initialized."
|
140
94
|
end
|
95
|
+
|
96
|
+
desc 'download-core [VERSION]', 'Download core documentation'
|
97
|
+
def download_core version = nil
|
98
|
+
ver = version || Solargraph::YardMap::CoreDocs.best_download
|
99
|
+
puts "Downloading docs for #{ver}..."
|
100
|
+
Solargraph::YardMap::CoreDocs.download ver
|
101
|
+
end
|
102
|
+
|
103
|
+
desc 'list-cores', 'List the local documentation versions'
|
104
|
+
def list_cores
|
105
|
+
puts Solargraph::YardMap::CoreDocs.versions.join("\n")
|
106
|
+
end
|
107
|
+
|
108
|
+
desc 'available-cores', 'List available documentation versions'
|
109
|
+
def available_cores
|
110
|
+
puts Solargraph::YardMap::CoreDocs.available.join("\n")
|
111
|
+
end
|
112
|
+
|
113
|
+
desc 'clear-cores', 'Clear the cached core documentation'
|
114
|
+
def clear_cores
|
115
|
+
Solargraph::YardMap::CoreDocs.clear
|
116
|
+
end
|
141
117
|
end
|
142
118
|
end
|
@@ -26,7 +26,7 @@ module Solargraph
|
|
26
26
|
attr_reader :detail
|
27
27
|
|
28
28
|
# @return [YARD::CodeObjects::Base]
|
29
|
-
attr_reader :code_object
|
29
|
+
#attr_reader :code_object
|
30
30
|
|
31
31
|
# @return [String]
|
32
32
|
attr_reader :location
|
@@ -34,6 +34,9 @@ module Solargraph
|
|
34
34
|
# @return [Array<String>]
|
35
35
|
attr_reader :arguments
|
36
36
|
|
37
|
+
# @return [YARD::CodeObjects::Base]
|
38
|
+
attr_reader :code_object
|
39
|
+
|
37
40
|
def initialize label, kind: KEYWORD, insert: nil, detail: nil, docstring: nil, code_object: nil, location: nil, arguments: [], return_type: nil, path: nil
|
38
41
|
@helper = Server::Helpers.new
|
39
42
|
@label = label.to_s
|
data/lib/solargraph/version.rb
CHANGED
data/lib/solargraph/yard_map.rb
CHANGED
@@ -1,17 +1,17 @@
|
|
1
|
-
require 'parser/current'
|
2
1
|
require 'yard'
|
3
2
|
|
4
3
|
module Solargraph
|
5
4
|
class YardMap
|
6
|
-
|
5
|
+
autoload :Cache, 'solargraph/yard_map/cache'
|
6
|
+
autoload :CoreDocs, 'solargraph/yard_map/core_docs'
|
7
|
+
|
8
|
+
@@stdlib_yardoc = CoreDocs.yard_stdlib_file
|
7
9
|
@@stdlib_namespaces = []
|
8
10
|
YARD::Registry.load! @@stdlib_yardoc
|
9
11
|
YARD::Registry.all(:class, :module).each do |ns|
|
10
12
|
@@stdlib_namespaces.push ns.path
|
11
13
|
end
|
12
14
|
|
13
|
-
autoload :Cache, 'solargraph/yard_map/cache'
|
14
|
-
|
15
15
|
attr_reader :workspace
|
16
16
|
attr_reader :required
|
17
17
|
|
@@ -20,28 +20,22 @@ module Solargraph
|
|
20
20
|
used = []
|
21
21
|
@required = required
|
22
22
|
@namespace_yardocs = {}
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
else
|
35
|
-
#STDERR.puts "Adding #{gy}"
|
36
|
-
yardocs.unshift gy
|
37
|
-
add_gem_dependencies g
|
38
|
-
end
|
23
|
+
@required.each do |r|
|
24
|
+
if workspace.nil? or !File.exist?(File.join workspace, 'lib', "#{r}.rb")
|
25
|
+
g = r.split('/').first
|
26
|
+
unless used.include?(g)
|
27
|
+
used.push g
|
28
|
+
gy = YARD::Registry.yardoc_file_for_gem(g)
|
29
|
+
if gy.nil?
|
30
|
+
STDERR.puts "Required path not found: #{r}"
|
31
|
+
else
|
32
|
+
yardocs.unshift gy
|
33
|
+
add_gem_dependencies g
|
39
34
|
end
|
40
35
|
end
|
41
36
|
end
|
42
|
-
|
43
|
-
yardocs.push
|
44
|
-
#yardocs.push File.join(Dir.home, '.solargraph', 'cache', '2.0.0', 'yardoc-stdlib')
|
37
|
+
end
|
38
|
+
yardocs.push CoreDocs.yardoc_file
|
45
39
|
yardocs.uniq!
|
46
40
|
yardocs.each do |y|
|
47
41
|
load_yardoc y
|
@@ -83,12 +77,14 @@ module Solargraph
|
|
83
77
|
(yardocs + [@@stdlib_yardoc]).each { |y|
|
84
78
|
yard = load_yardoc(y)
|
85
79
|
unless yard.nil?
|
86
|
-
yard.paths.each
|
87
|
-
found.
|
88
|
-
|
80
|
+
yard.paths.each do |p|
|
81
|
+
if found.empty? or (query.include?('.') or query.include?('#')) or !(p.include?('.') or p.include?('#'))
|
82
|
+
found.push p if p.downcase.include?(query.downcase)
|
83
|
+
end
|
84
|
+
end
|
89
85
|
end
|
90
86
|
}
|
91
|
-
found.
|
87
|
+
found.uniq
|
92
88
|
end
|
93
89
|
|
94
90
|
# @param query [String]
|
@@ -227,13 +223,15 @@ module Solargraph
|
|
227
223
|
end
|
228
224
|
|
229
225
|
def find_fully_qualified_namespace namespace, scope
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
return
|
226
|
+
unless scope.empty?
|
227
|
+
parts = scope.split('::')
|
228
|
+
while parts.length > 0
|
229
|
+
here = "#{parts.join('::')}::#{namespace}"
|
230
|
+
return here unless yardocs_documenting(here).empty?
|
231
|
+
parts.pop
|
235
232
|
end
|
236
|
-
|
233
|
+
end
|
234
|
+
return namespace unless yardocs_documenting(namespace).empty?
|
237
235
|
nil
|
238
236
|
end
|
239
237
|
|
@@ -0,0 +1,111 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'uri'
|
3
|
+
require 'json'
|
4
|
+
require 'fileutils'
|
5
|
+
|
6
|
+
module Solargraph
|
7
|
+
class YardMap
|
8
|
+
module CoreDocs
|
9
|
+
class SourceNotAvailableError < StandardError;end
|
10
|
+
|
11
|
+
SOURCE = 'http://solargraph.org/download'
|
12
|
+
|
13
|
+
class << self
|
14
|
+
def cache_dir
|
15
|
+
@cache_dir ||= File.join(Dir.home, '.solargraph', 'cache')
|
16
|
+
end
|
17
|
+
|
18
|
+
# Solargraph installs Ruby 2.2.2 documentation to ensure minimum functionality.
|
19
|
+
def require_minimum
|
20
|
+
FileUtils.mkdir_p cache_dir
|
21
|
+
version_dir = File.join(cache_dir, '2.2.2')
|
22
|
+
unless File.exist?(version_dir)
|
23
|
+
FileUtils.cp File.join(Solargraph::YARDOC_PATH, '2.2.2.tar.gz'), cache_dir
|
24
|
+
install_archive File.join(cache_dir, '2.2.2.tar.gz')
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def valid?(ver)
|
29
|
+
dir = File.join(cache_dir, ver)
|
30
|
+
return false unless File.directory?(dir)
|
31
|
+
return false unless File.directory?(File.join(dir, 'yardoc'))
|
32
|
+
return false unless File.directory?(File.join(dir, 'yardoc-stdlib'))
|
33
|
+
true
|
34
|
+
end
|
35
|
+
|
36
|
+
def versions
|
37
|
+
dirs = Dir[File.join(cache_dir, '*')].map{|d| File.basename(d)}
|
38
|
+
dirs.keep_if{|d| valid?(d)}
|
39
|
+
dirs.sort!{|a, b| Gem::Version.new(b) <=> Gem::Version.new(a)}
|
40
|
+
dirs
|
41
|
+
end
|
42
|
+
|
43
|
+
def best_match
|
44
|
+
available = versions
|
45
|
+
available.each do |v|
|
46
|
+
return v if Gem::Version.new(v) <= Gem::Version.new(RUBY_VERSION)
|
47
|
+
end
|
48
|
+
return available.last
|
49
|
+
end
|
50
|
+
|
51
|
+
def available
|
52
|
+
uri = URI.parse("#{SOURCE}/versions.json")
|
53
|
+
response = Net::HTTP.get_response(uri)
|
54
|
+
obj = JSON.parse(response.body)
|
55
|
+
raise SourceNotAvailableError.new("Error connecting to #{SOURCE}") unless obj['status'] == 'ok'
|
56
|
+
obj['cores']
|
57
|
+
end
|
58
|
+
|
59
|
+
def best_download
|
60
|
+
rv = Gem::Version.new(RUBY_VERSION)
|
61
|
+
available.each do |ver|
|
62
|
+
return ver if Gem::Version.new(ver) <= rv
|
63
|
+
end
|
64
|
+
obj['cores'].last
|
65
|
+
end
|
66
|
+
|
67
|
+
def yardoc_file(ver = best_match)
|
68
|
+
raise ArgumentError.new("Invalid core yardoc version #{ver}") unless valid?(ver)
|
69
|
+
File.join(cache_dir, ver, 'yardoc')
|
70
|
+
end
|
71
|
+
|
72
|
+
def yard_stdlib_file(ver = best_match)
|
73
|
+
raise ArgumentError.new("Invalid core yardoc version #{ver}") unless valid?(ver)
|
74
|
+
File.join(cache_dir, ver, 'yardoc-stdlib')
|
75
|
+
end
|
76
|
+
|
77
|
+
def download version
|
78
|
+
FileUtils.mkdir_p cache_dir
|
79
|
+
uri = URI.parse("http://solargraph.org/download/#{version}.tar.gz")
|
80
|
+
response = Net::HTTP.get_response(uri)
|
81
|
+
zipfile = File.join(cache_dir, "#{version}.tar.gz")
|
82
|
+
File.binwrite zipfile, response.body
|
83
|
+
install_archive zipfile
|
84
|
+
end
|
85
|
+
|
86
|
+
def clear
|
87
|
+
FileUtils.rm_rf cache_dir, secure: true
|
88
|
+
require_minimum
|
89
|
+
end
|
90
|
+
|
91
|
+
private
|
92
|
+
|
93
|
+
def install_archive filename
|
94
|
+
tar_extract = Gem::Package::TarReader.new(Zlib::GzipReader.open(filename))
|
95
|
+
tar_extract.rewind
|
96
|
+
tar_extract.each do |entry|
|
97
|
+
if entry.directory?
|
98
|
+
FileUtils.mkdir_p File.join(cache_dir, entry.full_name)
|
99
|
+
else
|
100
|
+
FileUtils.mkdir_p File.join(cache_dir, File.dirname(entry.full_name))
|
101
|
+
File.open(File.join(cache_dir, entry.full_name), 'wb') do |f|
|
102
|
+
f << entry.read
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
tar_extract.close
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
data/yardoc/2.2.2.tar.gz
ADDED
Binary file
|
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.
|
4
|
+
version: 0.15.0
|
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
|
+
date: 2017-12-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: parser
|
@@ -177,6 +177,7 @@ files:
|
|
177
177
|
- lib/solargraph/api_map/cache.rb
|
178
178
|
- lib/solargraph/api_map/config.rb
|
179
179
|
- lib/solargraph/api_map/source.rb
|
180
|
+
- lib/solargraph/api_map/source_to_yard.rb
|
180
181
|
- lib/solargraph/code_map.rb
|
181
182
|
- lib/solargraph/live_map.rb
|
182
183
|
- lib/solargraph/live_map/cache.rb
|
@@ -215,8 +216,9 @@ files:
|
|
215
216
|
- lib/solargraph/views/search.erb
|
216
217
|
- lib/solargraph/yard_map.rb
|
217
218
|
- lib/solargraph/yard_map/cache.rb
|
219
|
+
- lib/solargraph/yard_map/core_docs.rb
|
218
220
|
- lib/yard-solargraph.rb
|
219
|
-
- yardoc/2.
|
221
|
+
- yardoc/2.2.2.tar.gz
|
220
222
|
homepage: http://solargraph.org
|
221
223
|
licenses:
|
222
224
|
- MIT
|
data/yardoc/2.0.0.tar.gz
DELETED
Binary file
|