solargraph 0.14.3 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +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
|