solargraph 0.7.5 → 0.8.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/api_map.rb +10 -17
- data/lib/solargraph/code_map.rb +128 -27
- data/lib/solargraph/node_methods.rb +40 -1
- data/lib/solargraph/server.rb +51 -20
- data/lib/solargraph/shell.rb +0 -1
- data/lib/solargraph/suggestion.rb +7 -5
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/yard_map.rb +51 -19
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a80ad72c101042120c5ec349dd3fb19a98e794e7
|
4
|
+
data.tar.gz: 99d562e48985d5fa6e3d8dbaf93edafd165490c4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ee8a6a7d1d7cc1ec77727a81e7cd4db7e3da8c0d03baee7424ac2063d281bbc1ceb1863c37c489219f65735cc3adbb64f78b05b7a1ed29a9dfc2b73eb776c6ee
|
7
|
+
data.tar.gz: 34a309dcdb41c54a99ced46a8c51fe3b4372d8dc51a2620647f0b7d3f4331662f7fd3a263f4a99d6e45f3bfe899b965212e38adfb1e578daa89667914be50b98
|
data/lib/solargraph/api_map.rb
CHANGED
@@ -15,7 +15,7 @@ module Solargraph
|
|
15
15
|
|
16
16
|
MAPPABLE_METHODS = [
|
17
17
|
:include, :extend, :require, :autoload, :attr_reader, :attr_writer, :attr_accessor, :private, :public, :protected
|
18
|
-
]
|
18
|
+
]
|
19
19
|
|
20
20
|
include NodeMethods
|
21
21
|
|
@@ -99,7 +99,7 @@ module Solargraph
|
|
99
99
|
|
100
100
|
def self.get_keywords
|
101
101
|
result = []
|
102
|
-
keywords = KEYWORDS +
|
102
|
+
keywords = KEYWORDS + ['attr_reader', 'attr_writer', 'attr_accessor', 'private', 'public', 'protected']
|
103
103
|
keywords.each { |k|
|
104
104
|
result.push Suggestion.new(k, kind: Suggestion::KEYWORD, detail: 'Keyword')
|
105
105
|
}
|
@@ -250,7 +250,6 @@ module Solargraph
|
|
250
250
|
if @yardoc_files.nil?
|
251
251
|
@yardoc_files = []
|
252
252
|
yard_options[:include].each { |glob|
|
253
|
-
#@yardoc_files.concat Dir[File.join workspace, glob]
|
254
253
|
Dir[File.join workspace, glob].each { |f|
|
255
254
|
@yardoc_files.push File.absolute_path(f)
|
256
255
|
}
|
@@ -349,7 +348,6 @@ module Solargraph
|
|
349
348
|
meths += get_methods('') if top or type.to_s == ''
|
350
349
|
else
|
351
350
|
meths = get_methods(type)
|
352
|
-
#meths += get_methods('') if top
|
353
351
|
end
|
354
352
|
meths.delete_if{ |m| m.insert != p }
|
355
353
|
return nil if meths.empty?
|
@@ -389,7 +387,7 @@ module Solargraph
|
|
389
387
|
meths
|
390
388
|
end
|
391
389
|
end
|
392
|
-
|
390
|
+
|
393
391
|
def get_method_args node
|
394
392
|
list = nil
|
395
393
|
args = []
|
@@ -466,12 +464,9 @@ module Solargraph
|
|
466
464
|
STDERR.puts "No workspace specified for yardoc update."
|
467
465
|
else
|
468
466
|
Dir.chdir(workspace) do
|
469
|
-
#YARD::Registry.load(yard_options[:include] - yard_options[:exclude], true)
|
470
|
-
#YARD::Registry.save
|
471
467
|
Thread.new {
|
472
468
|
STDERR.puts "Updating the yardoc..."
|
473
469
|
globs = yard_options[:include] - yard_options[:exclude]
|
474
|
-
#cmd = "yardoc #{globs.join(' ')} -e #{Solargraph::YARD_EXTENSION_FILE} #{yard_options[:flags].join(' ')}"
|
475
470
|
cmd = "yardoc -e #{Solargraph::YARD_EXTENSION_FILE}"
|
476
471
|
STDERR.puts "Update yardoc with #{cmd}"
|
477
472
|
STDERR.puts `#{cmd}`
|
@@ -514,16 +509,12 @@ module Solargraph
|
|
514
509
|
docstring = get_comment_for(c)
|
515
510
|
label = "#{c.children[1]}"
|
516
511
|
args = get_method_args(c)
|
517
|
-
label
|
518
|
-
meths.push Suggestion.new(label, insert: c.children[1].to_s.gsub(/=/, ' = '), kind: Suggestion::METHOD, detail: 'Method', documentation: docstring) if c.children[1].to_s[0].match(/[a-z_]/i) and c.children[1] != :def
|
512
|
+
meths.push Suggestion.new(label, insert: c.children[1].to_s.gsub(/=/, ' = '), kind: Suggestion::METHOD, detail: 'Method', documentation: docstring, arguments: args) if c.children[1].to_s[0].match(/[a-z_]/i) and c.children[1] != :def
|
519
513
|
elsif c.type == :send and c.children[1] == :include
|
520
514
|
# TODO: This might not be right. Should we be getting singleton methods
|
521
515
|
# from an include, or only from an extend?
|
522
516
|
i = unpack_name(c.children[2])
|
523
517
|
meths += inner_get_methods(i, root, skip) unless i == 'Kernel'
|
524
|
-
#elsif c.type == :send and c.children[1] == :solargraph_include_public_methods
|
525
|
-
# i = unpack_name(c.children[2])
|
526
|
-
# meths += get_instance_methods(i, root, visibility: [:public])
|
527
518
|
else
|
528
519
|
meths += inner_get_methods_from_node(c, root, skip)
|
529
520
|
end
|
@@ -559,8 +550,7 @@ module Solargraph
|
|
559
550
|
cmnt = get_comment_for(c)
|
560
551
|
label = "#{c.children[0]}"
|
561
552
|
args = get_method_args(c)
|
562
|
-
label
|
563
|
-
meths.push Suggestion.new(label, insert: c.children[0].to_s.gsub(/=/, ' = '), kind: Suggestion::METHOD, documentation: cmnt, detail: fqns) if c.children[0].to_s[0].match(/[a-z]/i)
|
553
|
+
meths.push Suggestion.new(label, insert: c.children[0].to_s.gsub(/=/, ' = '), kind: Suggestion::METHOD, documentation: cmnt, detail: fqns, arguments: args) if c.children[0].to_s[0].match(/[a-z]/i)
|
564
554
|
elsif c.kind_of?(AST::Node) and c.type == :send and c.children[1] == :attr_reader
|
565
555
|
c.children[2..-1].each { |x|
|
566
556
|
meths.push Suggestion.new(x.children[0], kind: Suggestion::METHOD) if x.type == :sym
|
@@ -590,7 +580,7 @@ module Solargraph
|
|
590
580
|
def mappable?(node)
|
591
581
|
return true if node.kind_of?(AST::Node) and [:array, :hash, :str, :int, :float].include?(node.type)
|
592
582
|
# TODO Add node.type :casgn (constant assignment)
|
593
|
-
if node.kind_of?(AST::Node) and (node.type == :class or node.type == :module or node.type == :def or node.type == :defs or node.type == :ivasgn or node.type == :gvasgn or node.type == :lvasgn or node.type == :or_asgn)
|
583
|
+
if node.kind_of?(AST::Node) and (node.type == :class or node.type == :module or node.type == :def or node.type == :defs or node.type == :ivasgn or node.type == :gvasgn or node.type == :lvasgn or node.type == :or_asgn or node.type == :const or node.type == :lvar)
|
594
584
|
true
|
595
585
|
elsif node.kind_of?(AST::Node) and node.type == :send and node.children[0] == nil and MAPPABLE_METHODS.include?(node.children[1])
|
596
586
|
true
|
@@ -627,6 +617,9 @@ module Solargraph
|
|
627
617
|
if node.type == :class
|
628
618
|
children += node.children[0, 2]
|
629
619
|
children += get_mappable_nodes(node.children[2..-1], comment_hash)
|
620
|
+
#children += get_mappable_nodes(node.children, comment_hash)
|
621
|
+
elsif node.type == :const
|
622
|
+
children += node.children
|
630
623
|
elsif node.type == :def
|
631
624
|
children += node.children[0, 2]
|
632
625
|
children += get_mappable_nodes(node.children[2..-1], comment_hash)
|
@@ -647,7 +640,7 @@ module Solargraph
|
|
647
640
|
@required.push(node.children[3].children[0]) if node.children[3].children[0].kind_of?(String)
|
648
641
|
type = :require
|
649
642
|
children += node.children[1, 3]
|
650
|
-
elsif node.type == :send
|
643
|
+
elsif node.type == :send or node.type == :lvar
|
651
644
|
children += node.children
|
652
645
|
elsif node.type == :or_asgn
|
653
646
|
# TODO: The api_map should ignore local variables.
|
data/lib/solargraph/code_map.rb
CHANGED
@@ -24,10 +24,6 @@ module Solargraph
|
|
24
24
|
end
|
25
25
|
@code = code.gsub(/\r/, '')
|
26
26
|
tries = 0
|
27
|
-
# Hide incomplete code to avoid syntax errors
|
28
|
-
# @todo This might not be necessary given the corrected character
|
29
|
-
# replacement in retries.
|
30
|
-
#tmp = "#{@code}\nX".gsub(/[\.@]([\s])/, '#\1').gsub(/([\A\s]?)def([\s]*?[\n\Z])/, '\1#ef\2')
|
31
27
|
tmp = @code
|
32
28
|
begin
|
33
29
|
node, comments = Parser::CurrentRuby.parse_with_comments(tmp)
|
@@ -41,10 +37,6 @@ module Solargraph
|
|
41
37
|
STDERR.puts "Retrying..."
|
42
38
|
tries += 1
|
43
39
|
spot = e.diagnostic.location.begin_pos
|
44
|
-
#STDERR.puts "CODE>>>>"
|
45
|
-
#STDERR.puts tmp
|
46
|
-
#STDERR.puts "<<<<CODE"
|
47
|
-
#STDERR.puts "Spot #{spot}: #{tmp[spot]}"
|
48
40
|
repl = '_'
|
49
41
|
if tmp[spot] == '@' or tmp[spot] == ':'
|
50
42
|
# Stub unfinished instance variables and symbols
|
@@ -61,14 +53,7 @@ module Solargraph
|
|
61
53
|
repl= 'end;end'
|
62
54
|
end
|
63
55
|
end
|
64
|
-
|
65
|
-
# tmp = '#' + tmp[1..-1]
|
66
|
-
#else
|
67
|
-
tmp = tmp[0..spot] + repl + tmp[spot+repl.length+1..-1].to_s
|
68
|
-
#end
|
69
|
-
#STDERR.puts "CHNG>>>>"
|
70
|
-
#STDERR.puts tmp
|
71
|
-
#STDERR.puts "<<<<CHNG"
|
56
|
+
tmp = tmp[0..spot] + repl + tmp[spot+repl.length+1..-1].to_s
|
72
57
|
retry
|
73
58
|
end
|
74
59
|
raise e
|
@@ -136,12 +121,12 @@ module Solargraph
|
|
136
121
|
def namespace_at(index)
|
137
122
|
tree = tree_at(index)
|
138
123
|
return nil if tree.length == 0
|
139
|
-
|
140
|
-
slice = tree[(tree.index(node) || 0)..-1]
|
124
|
+
slice = tree
|
141
125
|
parts = []
|
142
126
|
slice.reverse.each { |n|
|
143
127
|
if n.type == :class or n.type == :module
|
144
|
-
|
128
|
+
c = const_from(n.children[0])
|
129
|
+
parts.push c
|
145
130
|
end
|
146
131
|
}
|
147
132
|
parts.join("::")
|
@@ -179,7 +164,7 @@ module Solargraph
|
|
179
164
|
@api_map.get_instance_variables(ns, (node.type == :def ? :instance : :class))
|
180
165
|
end
|
181
166
|
|
182
|
-
def suggest_at index, filtered:
|
167
|
+
def suggest_at index, filtered: false, with_snippets: false
|
183
168
|
node = node_at(index - 2)
|
184
169
|
return [] if string_at?(index)
|
185
170
|
result = []
|
@@ -240,10 +225,88 @@ module Solargraph
|
|
240
225
|
end
|
241
226
|
end
|
242
227
|
end
|
243
|
-
|
228
|
+
result = reduce_starting_with(result, word_at(index)) if filtered
|
244
229
|
result.uniq{|s| s.path}
|
245
230
|
end
|
246
231
|
|
232
|
+
def signatures_at index
|
233
|
+
sig = signature_index_before(index)
|
234
|
+
return [] if sig.nil?
|
235
|
+
word = word_at(sig)
|
236
|
+
suggest_at(sig).reject{|s| s.label != word}
|
237
|
+
end
|
238
|
+
|
239
|
+
def resolve_object_at index
|
240
|
+
signature = get_signature_at(index)
|
241
|
+
cursor = index
|
242
|
+
while @code[cursor] =~ /[a-z0-9_\?]/i
|
243
|
+
signature += @code[cursor]
|
244
|
+
cursor += 1
|
245
|
+
break if cursor >= @code.length
|
246
|
+
end
|
247
|
+
return [] if signature.to_s == ''
|
248
|
+
ns_here = namespace_at(index)
|
249
|
+
scope = parent_node_from(index, :class, :module, :def, :defs) || @node
|
250
|
+
parts = signature.split('.')
|
251
|
+
if parts.length > 1
|
252
|
+
beginner = parts[0..-2].join('.')
|
253
|
+
ender = parts.last
|
254
|
+
else
|
255
|
+
beginner = signature
|
256
|
+
ender = nil
|
257
|
+
end
|
258
|
+
var = find_local_variable_node(parts[0], scope)
|
259
|
+
if var.nil?
|
260
|
+
# It's not a local variable
|
261
|
+
fqns = @api_map.find_fully_qualified_namespace(beginner, ns_here)
|
262
|
+
if fqns.nil?
|
263
|
+
# It's a method call
|
264
|
+
if ender.nil?
|
265
|
+
return @api_map.yard_map.objects(beginner, ns_here)
|
266
|
+
else
|
267
|
+
sig_scope = (scope.type == :def ? :instance : :class)
|
268
|
+
type = @api_map.infer_signature_type(beginner, ns_here, scope: sig_scope)
|
269
|
+
return [] if type.nil?
|
270
|
+
path = type
|
271
|
+
path += "##{ender}" unless ender.nil?
|
272
|
+
return @api_map.yard_map.objects(path, ns_here)
|
273
|
+
end
|
274
|
+
else
|
275
|
+
path = beginner
|
276
|
+
path += "##{ender}" unless ender.nil?
|
277
|
+
return @api_map.yard_map.objects(path, ns_here)
|
278
|
+
end
|
279
|
+
else
|
280
|
+
# It's a local variable. Get the type from the node
|
281
|
+
type = get_type_comment(var)
|
282
|
+
type = infer(var.children[1]) if type.nil?
|
283
|
+
if type.nil?
|
284
|
+
vsig = resolve_node_signature(var.children[1])
|
285
|
+
vparts = vsig.split('.')
|
286
|
+
fqns = @api_map.find_fully_qualified_namespace(vparts[0], ns_here)
|
287
|
+
if fqns.nil?
|
288
|
+
vtype = @api_map.infer_signature_type(vsig, ns_here, scope: :instance)
|
289
|
+
else
|
290
|
+
vtype = @api_map.infer_signature_type(vparts[1..-1].join('.'), fqns, scope: :class)
|
291
|
+
end
|
292
|
+
return [] if vtype.nil?
|
293
|
+
fqns = @api_map.find_fully_qualified_namespace(vtype, ns_here)
|
294
|
+
if ender.nil?
|
295
|
+
signature = parts[1..-1].join('.')
|
296
|
+
else
|
297
|
+
signature = parts[1..-2].join('.')
|
298
|
+
end
|
299
|
+
type = @api_map.infer_signature_type(signature, fqns, scope: :instance)
|
300
|
+
end
|
301
|
+
unless type.nil?
|
302
|
+
path = type
|
303
|
+
path += "##{ender}" unless ender.nil?
|
304
|
+
return @api_map.yard_map.objects(path, ns_here)
|
305
|
+
end
|
306
|
+
end
|
307
|
+
return []
|
308
|
+
end
|
309
|
+
|
247
310
|
# Find the signature at the specified index and get suggestions based
|
248
311
|
# on its inferred type.
|
249
312
|
#
|
@@ -274,23 +337,44 @@ module Solargraph
|
|
274
337
|
# It's a local variable. Get the type from the node
|
275
338
|
type = get_type_comment(var)
|
276
339
|
type = infer(var.children[1]) if type.nil?
|
340
|
+
skipdat = false
|
277
341
|
if type.nil?
|
278
342
|
vsig = resolve_node_signature(var.children[1])
|
279
343
|
vparts = vsig.split('.')
|
280
344
|
fqns = @api_map.find_fully_qualified_namespace(vparts[0], ns_here)
|
281
345
|
if fqns.nil?
|
282
|
-
|
346
|
+
lvar = find_local_variable_node(vparts[0], scope)
|
347
|
+
if lvar.nil?
|
348
|
+
vtype = @api_map.infer_signature_type(vsig, ns_here, scope: :instance)
|
349
|
+
else
|
350
|
+
type = get_type_comment(lvar)
|
351
|
+
type = infer(lvar.children[1]) if type.nil?
|
352
|
+
if type.nil?
|
353
|
+
type = @api_map.infer_signature_type(resolve_node_signature(lvar.children[1]), ns_here, scope: :class)
|
354
|
+
end
|
355
|
+
unless type.nil?
|
356
|
+
signature = "#{vparts[1..-1].join('.')}"
|
357
|
+
skipdat = true
|
358
|
+
end
|
359
|
+
end
|
283
360
|
else
|
284
361
|
vtype = @api_map.infer_signature_type(vparts[1..-1].join('.'), fqns, scope: :class)
|
362
|
+
type = fqns
|
363
|
+
signature = parts[1..-1].join('.')
|
364
|
+
skipdat = true
|
285
365
|
end
|
286
|
-
|
287
|
-
|
288
|
-
|
366
|
+
unless skipdat
|
367
|
+
fqns = @api_map.find_fully_qualified_namespace(vtype, ns_here)
|
368
|
+
signature = parts[1..-1].join('.')
|
369
|
+
type = @api_map.infer_signature_type(signature, fqns, scope: :instance)
|
370
|
+
end
|
371
|
+
else
|
372
|
+
signature = signature.split('.')[1..-1].join('.')
|
289
373
|
end
|
290
374
|
unless type.nil?
|
291
375
|
lparts = signature.split('.')
|
292
|
-
if lparts.length
|
293
|
-
lsig =
|
376
|
+
if lparts.length >= 1
|
377
|
+
lsig = signature
|
294
378
|
ltype = @api_map.infer_signature_type(lsig, type, scope: :instance)
|
295
379
|
result.concat @api_map.get_instance_methods(ltype) unless ltype.nil?
|
296
380
|
else
|
@@ -454,5 +538,22 @@ module Solargraph
|
|
454
538
|
end
|
455
539
|
i
|
456
540
|
end
|
541
|
+
|
542
|
+
def signature_index_before index
|
543
|
+
open_parens = 0
|
544
|
+
cursor = index - 1
|
545
|
+
while cursor >= 0
|
546
|
+
break if cursor < 0
|
547
|
+
if @code[cursor] == ')'
|
548
|
+
open_parens -= 1
|
549
|
+
elsif @code[cursor] == '('
|
550
|
+
open_parens += 1
|
551
|
+
end
|
552
|
+
break if open_parens == 1
|
553
|
+
cursor -= 1
|
554
|
+
end
|
555
|
+
cursor = nil if cursor < 0
|
556
|
+
cursor
|
557
|
+
end
|
457
558
|
end
|
458
559
|
end
|
@@ -22,6 +22,44 @@ module Solargraph
|
|
22
22
|
parts
|
23
23
|
end
|
24
24
|
|
25
|
+
def const_from node
|
26
|
+
if node.kind_of?(AST::Node) and node.type == :const
|
27
|
+
result = ''
|
28
|
+
unless node.children[0].nil?
|
29
|
+
result = const_from(node.children[0])
|
30
|
+
end
|
31
|
+
if result == ''
|
32
|
+
result = node.children[1].to_s
|
33
|
+
else
|
34
|
+
result = result + '::' + node.children[1].to_s
|
35
|
+
end
|
36
|
+
result
|
37
|
+
else
|
38
|
+
nil
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def drill_signature node, signature
|
43
|
+
return signature unless node.kind_of?(AST::Node)
|
44
|
+
if node.type == :const or node.type == :cbase
|
45
|
+
unless node.children[0].nil?
|
46
|
+
signature += drill_signature(node.children[0], signature)
|
47
|
+
end
|
48
|
+
signature += '::' unless signature.empty?
|
49
|
+
signature += node.children[1].to_s
|
50
|
+
elsif node.type == :lvar
|
51
|
+
signature += '.' unless signature.empty?
|
52
|
+
signature += node.children[0].to_s
|
53
|
+
elsif node.type == :send
|
54
|
+
unless node.children[0].nil?
|
55
|
+
signature += drill_signature(node.children[0], signature)
|
56
|
+
end
|
57
|
+
signature += '.' unless signature.empty?
|
58
|
+
signature += node.children[1].to_s
|
59
|
+
end
|
60
|
+
signature
|
61
|
+
end
|
62
|
+
|
25
63
|
def infer node
|
26
64
|
if node.type == :str
|
27
65
|
return 'String'
|
@@ -43,7 +81,8 @@ module Solargraph
|
|
43
81
|
#
|
44
82
|
# @return [String]
|
45
83
|
def resolve_node_signature node
|
46
|
-
stack_node_signature(node).join('.')
|
84
|
+
#stack_node_signature(node).join('.')
|
85
|
+
drill_signature node, ''
|
47
86
|
end
|
48
87
|
|
49
88
|
def stack_node_signature node
|
data/lib/solargraph/server.rb
CHANGED
@@ -24,7 +24,45 @@ module Solargraph
|
|
24
24
|
@@semaphore.synchronize {
|
25
25
|
code_map = CodeMap.new(code: params['text'], filename: params['filename'], api_map: @@api_hash[workspace])
|
26
26
|
offset = code_map.get_offset(params['line'].to_i, params['column'].to_i)
|
27
|
-
sugg = code_map.suggest_at(offset, with_snippets: params['with_snippets'] == '1' ? true : false
|
27
|
+
sugg = code_map.suggest_at(offset, with_snippets: params['with_snippets'] == '1' ? true : false)
|
28
|
+
}
|
29
|
+
{ "status" => "ok", "suggestions" => sugg }.to_json
|
30
|
+
rescue Exception => e
|
31
|
+
STDERR.puts e
|
32
|
+
STDERR.puts e.backtrace.join("\n")
|
33
|
+
{ "status" => "err", "message" => e.message + "\n" + e.backtrace.join("\n") }.to_json
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
post '/signify' do
|
38
|
+
content_type :json
|
39
|
+
begin
|
40
|
+
sugg = []
|
41
|
+
workspace = params['workspace'] || CodeMap.find_workspace(params['filename'])
|
42
|
+
Server.prepare_workspace workspace unless @@api_hash.has_key?(workspace)
|
43
|
+
@@semaphore.synchronize {
|
44
|
+
code_map = CodeMap.new(code: params['text'], filename: params['filename'], api_map: @@api_hash[workspace])
|
45
|
+
offset = code_map.get_offset(params['line'].to_i, params['column'].to_i)
|
46
|
+
sugg = code_map.signatures_at(offset)
|
47
|
+
}
|
48
|
+
{ "status" => "ok", "suggestions" => sugg }.to_json
|
49
|
+
rescue Exception => e
|
50
|
+
STDERR.puts e
|
51
|
+
STDERR.puts e.backtrace.join("\n")
|
52
|
+
{ "status" => "err", "message" => e.message + "\n" + e.backtrace.join("\n") }.to_json
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
post '/hover' do
|
57
|
+
content_type :json
|
58
|
+
begin
|
59
|
+
sugg = []
|
60
|
+
workspace = params['workspace'] || CodeMap.find_workspace(params['filename'])
|
61
|
+
Server.prepare_workspace workspace unless @@api_hash.has_key?(workspace)
|
62
|
+
@@semaphore.synchronize {
|
63
|
+
code_map = CodeMap.new(code: params['text'], filename: params['filename'], api_map: @@api_hash[workspace])
|
64
|
+
offset = code_map.get_offset(params['line'].to_i, params['column'].to_i)
|
65
|
+
sugg = code_map.resolve_object_at(offset)
|
28
66
|
}
|
29
67
|
{ "status" => "ok", "suggestions" => sugg }.to_json
|
30
68
|
rescue Exception => e
|
@@ -58,15 +96,22 @@ module Solargraph
|
|
58
96
|
erb :document
|
59
97
|
end
|
60
98
|
|
61
|
-
def htmlify
|
99
|
+
def htmlify text
|
100
|
+
rdoc_to_html text
|
101
|
+
end
|
102
|
+
|
103
|
+
def rdoc_to_html text
|
104
|
+
h = Helpers.new
|
105
|
+
h.html_markup_rdoc(text)
|
106
|
+
end
|
107
|
+
|
108
|
+
def ruby_to_html code
|
62
109
|
h = Helpers.new
|
63
|
-
h.
|
64
|
-
h.htmlify object.docstring.all, :rdoc
|
110
|
+
h.html_markup_ruby(code)
|
65
111
|
end
|
66
112
|
|
67
113
|
class << self
|
68
114
|
def run!
|
69
|
-
#constant_updates
|
70
115
|
super
|
71
116
|
end
|
72
117
|
|
@@ -75,22 +120,8 @@ module Solargraph
|
|
75
120
|
@@semaphore.synchronize {
|
76
121
|
@@api_hash[directory] = api_map
|
77
122
|
}
|
78
|
-
#Thread.new {
|
79
|
-
api_map.update_yardoc
|
80
|
-
#}
|
81
|
-
end
|
82
|
-
|
83
|
-
def constant_updates
|
84
123
|
Thread.new {
|
85
|
-
|
86
|
-
@@api_hash.keys.each { |k|
|
87
|
-
update = Solargraph::ApiMap.new(k)
|
88
|
-
@@semaphore.synchronize {
|
89
|
-
@@api_hash[k] = update
|
90
|
-
}
|
91
|
-
}
|
92
|
-
sleep 10
|
93
|
-
end
|
124
|
+
api_map.update_yardoc
|
94
125
|
}
|
95
126
|
end
|
96
127
|
end
|
data/lib/solargraph/shell.rb
CHANGED
@@ -75,7 +75,6 @@ module Solargraph
|
|
75
75
|
rescue Exception => e
|
76
76
|
STDERR.puts e
|
77
77
|
STDERR.puts e.backtrace.join("\n")
|
78
|
-
#result = { "status" => "err", "message" => e.message }.to_json
|
79
78
|
result = { "status" => "err", "message" => e.message + "\n" + e.backtrace.join("\n") }.to_json
|
80
79
|
STDOUT.puts result
|
81
80
|
end
|
@@ -10,9 +10,9 @@ module Solargraph
|
|
10
10
|
VARIABLE = 'Variable'
|
11
11
|
SNIPPET = 'Snippet'
|
12
12
|
|
13
|
-
attr_reader :label, :kind, :insert, :detail, :documentation, :code_object, :location
|
13
|
+
attr_reader :label, :kind, :insert, :detail, :documentation, :code_object, :location, :arguments
|
14
14
|
|
15
|
-
def initialize label, kind: KEYWORD, insert: nil, detail: nil, documentation: nil, code_object: nil, location: nil
|
15
|
+
def initialize label, kind: KEYWORD, insert: nil, detail: nil, documentation: nil, code_object: nil, location: nil, arguments: []
|
16
16
|
@label = label.to_s
|
17
17
|
@kind = kind
|
18
18
|
@insert = insert || @label
|
@@ -20,6 +20,7 @@ module Solargraph
|
|
20
20
|
@code_object = code_object
|
21
21
|
@documentation = documentation
|
22
22
|
@location = location
|
23
|
+
@arguments = arguments
|
23
24
|
end
|
24
25
|
|
25
26
|
def path
|
@@ -55,12 +56,13 @@ module Solargraph
|
|
55
56
|
insert: @insert,
|
56
57
|
detail: @detail,
|
57
58
|
path: path,
|
58
|
-
location: (@location.nil? ? nil : @location.to_s)
|
59
|
+
location: (@location.nil? ? nil : @location.to_s),
|
60
|
+
arguments: @arguments
|
59
61
|
}
|
60
62
|
if @code_object.nil?
|
61
|
-
obj[:documentation] = @documentation.
|
63
|
+
obj[:documentation] = @documentation.to_s unless @documentation.nil?
|
62
64
|
else
|
63
|
-
obj[:documentation] = @code_object.docstring.
|
65
|
+
obj[:documentation] = @code_object.docstring.to_s unless @code_object.docstring.nil?
|
64
66
|
end
|
65
67
|
obj.to_json(args)
|
66
68
|
end
|
data/lib/solargraph/version.rb
CHANGED
data/lib/solargraph/yard_map.rb
CHANGED
@@ -11,8 +11,6 @@ module Solargraph
|
|
11
11
|
unless workspace.nil?
|
12
12
|
wsy = File.join(workspace, '.yardoc')
|
13
13
|
yardocs.push wsy if File.exist?(wsy)
|
14
|
-
#wsy = Dir[File.join workspace, '**/*.rb']
|
15
|
-
#yardocs.push(wsy)
|
16
14
|
end
|
17
15
|
used = []
|
18
16
|
required.each { |r|
|
@@ -29,16 +27,7 @@ module Solargraph
|
|
29
27
|
end
|
30
28
|
end
|
31
29
|
}
|
32
|
-
# TODO: Experimental loading of all gems
|
33
|
-
#Bundler.load.specs.each { |s|
|
34
|
-
# unless used.include?(s.name)
|
35
|
-
# used.push s.name
|
36
|
-
# gy = YARD::Registry.yardoc_file_for_gem(s.name)
|
37
|
-
# yardocs.push gy unless gy.nil?
|
38
|
-
# end
|
39
|
-
#}
|
40
30
|
yardocs.push File.join(Dir.home, '.solargraph', 'cache', '2.0.0', 'yardoc')
|
41
|
-
#yardocs.push File.join(Dir.home, '.solargraph', 'cache', '2.0.0', 'yardoc-stdlib')
|
42
31
|
yardocs.uniq!
|
43
32
|
cache_core
|
44
33
|
end
|
@@ -159,8 +148,7 @@ module Solargraph
|
|
159
148
|
n = m.to_s.split(/[\.#]/).last.gsub(/=/, ' = ')
|
160
149
|
label = "#{n}"
|
161
150
|
args = get_method_args(m)
|
162
|
-
label
|
163
|
-
meths.push Suggestion.new(label, insert: "#{n.gsub(/=/, ' = ')}", kind: Suggestion::METHOD, documentation: m.docstring, code_object: m, detail: "#{ns}", location: "#{m.file}:#{m.line}")
|
151
|
+
meths.push Suggestion.new(label, insert: "#{n.gsub(/=/, ' = ')}", kind: Suggestion::METHOD, documentation: m.docstring, code_object: m, detail: "#{ns}", location: "#{m.file}:#{m.line}", arguments: args)
|
164
152
|
}
|
165
153
|
# Collect superclass methods
|
166
154
|
if ns.kind_of?(YARD::CodeObjects::ClassObject) and !ns.superclass.nil?
|
@@ -168,6 +156,14 @@ module Solargraph
|
|
168
156
|
end
|
169
157
|
if ns.kind_of?(YARD::CodeObjects::ClassObject) and namespace != 'Class'
|
170
158
|
meths += get_instance_methods('Class')
|
159
|
+
yard = load_yardoc(y)
|
160
|
+
i = yard.at("#{ns}#initialize")
|
161
|
+
unless i.nil?
|
162
|
+
meths.delete_if{|m| m.label == 'new'}
|
163
|
+
label = "#{i}"
|
164
|
+
args = get_method_args(i)
|
165
|
+
meths.push Suggestion.new('new', kind: Suggestion::METHOD, documentation: i.docstring, code_object: i, detail: "#{ns}", location: "#{i.file}:#{i.line}", arguments: args)
|
166
|
+
end
|
171
167
|
end
|
172
168
|
end
|
173
169
|
end
|
@@ -195,8 +191,7 @@ module Solargraph
|
|
195
191
|
if n.to_s.match(/^[a-z]/i) and (namespace == 'Kernel' or !m.to_s.start_with?('Kernel#')) and !m.docstring.to_s.include?(':nodoc:')
|
196
192
|
label = "#{n}"
|
197
193
|
args = get_method_args(m)
|
198
|
-
label
|
199
|
-
meths.push Suggestion.new(label, insert: "#{n.gsub(/=/, ' = ')}", kind: Suggestion::METHOD, documentation: m.docstring, code_object: m, detail: "#{ns}", location: "#{m.file}:#{m.line}")
|
194
|
+
meths.push Suggestion.new(label, insert: "#{n.gsub(/=/, ' = ')}", kind: Suggestion::METHOD, documentation: m.docstring, code_object: m, detail: m.namespace, location: "#{m.file}:#{m.line}", arguments: args)
|
200
195
|
end
|
201
196
|
}
|
202
197
|
if ns.kind_of?(YARD::CodeObjects::ClassObject) and namespace != 'Object'
|
@@ -226,6 +221,35 @@ module Solargraph
|
|
226
221
|
nil
|
227
222
|
end
|
228
223
|
|
224
|
+
def objects path, space = ''
|
225
|
+
result = []
|
226
|
+
yardocs.each { |y|
|
227
|
+
yard = load_yardoc(y)
|
228
|
+
unless yard.nil?
|
229
|
+
obj = find_first_resolved_namespace(yard, path, space)
|
230
|
+
if obj.nil? and path.include?('#')
|
231
|
+
parts = path.split('#')
|
232
|
+
obj = yard.at(parts[0])
|
233
|
+
unless obj.nil?
|
234
|
+
meths = obj.meths(scope: [:instance]).keep_if{|m| m.name.to_s == parts[1]}
|
235
|
+
meths.each { |m|
|
236
|
+
args = get_method_args(m)
|
237
|
+
result.push Solargraph::Suggestion.new(m.name, kind: 'Method', detail: m.path, code_object: m, arguments: args)
|
238
|
+
}
|
239
|
+
end
|
240
|
+
else
|
241
|
+
unless obj.nil?
|
242
|
+
args = []
|
243
|
+
args = get_method_args(obj) if obj.kind_of?(YARD::CodeObjects::MethodObject)
|
244
|
+
kind = kind_of_object(obj)
|
245
|
+
result.push Solargraph::Suggestion.new(obj.name, kind: kind, detail: obj.path, code_object: obj, arguments: args)
|
246
|
+
end
|
247
|
+
end
|
248
|
+
end
|
249
|
+
}
|
250
|
+
result
|
251
|
+
end
|
252
|
+
|
229
253
|
private
|
230
254
|
|
231
255
|
def cache
|
@@ -257,10 +281,18 @@ module Solargraph
|
|
257
281
|
|
258
282
|
def cache_core
|
259
283
|
c = get_constants '', ''
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
284
|
+
end
|
285
|
+
|
286
|
+
def kind_of_object obj
|
287
|
+
if obj.kind_of?(YARD::CodeObjects::MethodObject)
|
288
|
+
'Method'
|
289
|
+
elsif obj.kind_of?(YARD::CodeObjects::ClassObject)
|
290
|
+
'Class'
|
291
|
+
elsif obj.kind_of?(YARD::CodeObjects::ModuleObject)
|
292
|
+
'Module'
|
293
|
+
else
|
294
|
+
nil
|
295
|
+
end
|
264
296
|
end
|
265
297
|
end
|
266
298
|
|
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.8.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-05-
|
11
|
+
date: 2017-05-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: parser
|