solargraph 0.10.1 → 0.10.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/solargraph/api_map.rb +77 -23
- data/lib/solargraph/api_map/cache.rb +15 -0
- data/lib/solargraph/code_map.rb +57 -21
- data/lib/solargraph/server.rb +1 -1
- data/lib/solargraph/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7fca7cec06944baee613ea512c26052d002badf1
|
4
|
+
data.tar.gz: 56b786723a5f0b33ae2612d110977f74f1d4bb7f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3e8e40663cd4629b55a4436a33d8c8606b1087dbabbdd21d0180f1ca8b4cb26b563bd2f4f8076701ccf1fa7148513df4d01a063a04366bbd137df8b6cac5dcf9
|
7
|
+
data.tar.gz: d7bf1113b69a08d74805319918a756f6894810c5397912f68340cf15fb050fac2e989a292b89efb8f7899f56fd5c5d2e502c8d3d35d7a4b042a905993b8dd7bf
|
data/lib/solargraph/api_map.rb
CHANGED
@@ -5,6 +5,7 @@ require 'yaml'
|
|
5
5
|
module Solargraph
|
6
6
|
class ApiMap
|
7
7
|
autoload :Config, 'solargraph/api_map/config'
|
8
|
+
autoload :Cache, 'solargraph/api_map/cache'
|
8
9
|
|
9
10
|
KEYWORDS = [
|
10
11
|
'__ENCODING__', '__LINE__', '__FILE__', 'BEGIN', 'END', 'alias', 'and',
|
@@ -179,7 +180,7 @@ module Solargraph
|
|
179
180
|
nodes = get_namespace_nodes(namespace) || @file_nodes.values
|
180
181
|
arr = []
|
181
182
|
nodes.each { |n|
|
182
|
-
arr += inner_get_instance_variables(n, scope)
|
183
|
+
arr += inner_get_instance_variables(n, namespace, scope)
|
183
184
|
}
|
184
185
|
arr
|
185
186
|
end
|
@@ -188,7 +189,7 @@ module Solargraph
|
|
188
189
|
nodes = get_namespace_nodes(namespace) || @file_nodes.values
|
189
190
|
arr = []
|
190
191
|
nodes.each { |n|
|
191
|
-
arr += inner_get_class_variables(n)
|
192
|
+
arr += inner_get_class_variables(n, namespace)
|
192
193
|
}
|
193
194
|
arr
|
194
195
|
end
|
@@ -314,27 +315,45 @@ module Solargraph
|
|
314
315
|
end
|
315
316
|
|
316
317
|
def infer_signature_type signature, namespace, scope: :class
|
318
|
+
cached = cache.get_signature_type(signature, namespace, scope)
|
319
|
+
return cached unless cached.nil?
|
317
320
|
return nil if signature.nil? or signature.empty?
|
321
|
+
result = nil
|
318
322
|
if namespace.end_with?('#class')
|
319
|
-
|
320
|
-
end
|
321
|
-
parts = signature.split('.', 2)
|
322
|
-
if parts[0].start_with?('@@')
|
323
|
-
type = infer_class_variable(parts[0], namespace)
|
324
|
-
inner_infer_signature_type parts[1], type, scope: :instance
|
325
|
-
elsif parts[0].start_with?('@')
|
326
|
-
type = infer_instance_variable(parts[0], namespace, scope)
|
327
|
-
inner_infer_signature_type parts[1], type, scope: :instance
|
323
|
+
result = infer_signature_type signature, namespace[0..-7], scope: (scope == :class ? :instance : :class)
|
328
324
|
else
|
329
|
-
|
330
|
-
if
|
331
|
-
|
332
|
-
type
|
333
|
-
|
325
|
+
parts = signature.split('.', 2)
|
326
|
+
if parts[0].start_with?('@@')
|
327
|
+
type = infer_class_variable(parts[0], namespace)
|
328
|
+
if type.nil? or parts.empty?
|
329
|
+
result = inner_infer_signature_type(parts[1], type, scope: :instance)
|
330
|
+
else
|
331
|
+
result = type
|
332
|
+
end
|
333
|
+
elsif parts[0].start_with?('@')
|
334
|
+
type = infer_instance_variable(parts[0], namespace, scope)
|
335
|
+
if type.nil? or parts.empty?
|
336
|
+
result = inner_infer_signature_type(parts[1], type, scope: :instance)
|
337
|
+
else
|
338
|
+
result = type
|
339
|
+
end
|
334
340
|
else
|
335
|
-
|
341
|
+
type = find_fully_qualified_namespace(parts[0], namespace)
|
342
|
+
if type.nil?
|
343
|
+
# It's a method call
|
344
|
+
type = inner_infer_signature_type(parts[0], namespace, scope: scope)
|
345
|
+
if parts[1].nil?
|
346
|
+
result = type
|
347
|
+
else
|
348
|
+
result = inner_infer_signature_type(parts[1], type, scope: :instance)
|
349
|
+
end
|
350
|
+
else
|
351
|
+
result = inner_infer_signature_type(parts[1], type, scope: :class)
|
352
|
+
end
|
336
353
|
end
|
337
354
|
end
|
355
|
+
cache.set_signature_type signature, namespace, scope, result
|
356
|
+
result
|
338
357
|
end
|
339
358
|
|
340
359
|
def get_namespace_type namespace, root = ''
|
@@ -474,6 +493,10 @@ module Solargraph
|
|
474
493
|
|
475
494
|
private
|
476
495
|
|
496
|
+
def cache
|
497
|
+
@cache ||= Cache.new
|
498
|
+
end
|
499
|
+
|
477
500
|
def associate_comments node, comments
|
478
501
|
comment_hash = Parser::Source::Comment.associate_locations(node, comments)
|
479
502
|
yard_hash = {}
|
@@ -641,31 +664,59 @@ module Solargraph
|
|
641
664
|
result
|
642
665
|
end
|
643
666
|
|
644
|
-
def inner_get_instance_variables(node, scope)
|
667
|
+
def inner_get_instance_variables(node, namespace, scope)
|
645
668
|
arr = []
|
646
669
|
if node.kind_of?(AST::Node)
|
647
670
|
node.children.each { |c|
|
648
671
|
if c.kind_of?(AST::Node)
|
649
672
|
is_inst = !find_parent(c, :def).nil?
|
650
673
|
if c.type == :ivasgn and c.children[0] and ( (scope == :instance and is_inst) or (scope != :instance and !is_inst) )
|
651
|
-
|
674
|
+
type = nil
|
675
|
+
cmnt = get_comment_for(c)
|
676
|
+
if cmnt.nil?
|
677
|
+
sig = resolve_node_signature(c.children[1])
|
678
|
+
type = infer_signature_type(sig, namespace)
|
679
|
+
else
|
680
|
+
t = cmnt.tag(:type)
|
681
|
+
if t.nil?
|
682
|
+
sig = resolve_node_signature(c.children[1])
|
683
|
+
type = infer_signature_type(sig, namespace)
|
684
|
+
else
|
685
|
+
type = t.types[0]
|
686
|
+
end
|
687
|
+
end
|
688
|
+
arr.push Suggestion.new(c.children[0], kind: Suggestion::VARIABLE, documentation: cmnt, return_type: type)
|
652
689
|
end
|
653
|
-
arr += inner_get_instance_variables(c, scope) unless [:class, :module].include?(c.type)
|
690
|
+
arr += inner_get_instance_variables(c, namespace, scope) unless [:class, :module].include?(c.type)
|
654
691
|
end
|
655
692
|
}
|
656
693
|
end
|
657
694
|
arr
|
658
695
|
end
|
659
696
|
|
660
|
-
def inner_get_class_variables(node)
|
697
|
+
def inner_get_class_variables(node, namespace)
|
661
698
|
arr = []
|
662
699
|
if node.kind_of?(AST::Node)
|
663
700
|
node.children.each { |c|
|
664
701
|
next unless c.kind_of?(AST::Node)
|
665
702
|
if c.type == :cvasgn
|
666
|
-
|
703
|
+
type = nil
|
704
|
+
cmnt = get_comment_for(c)
|
705
|
+
if cmnt.nil?
|
706
|
+
sig = resolve_node_signature(c.children[1])
|
707
|
+
type = infer_signature_type(sig, namespace)
|
708
|
+
else
|
709
|
+
t = cmnt.tag(:type)
|
710
|
+
if t.nil?
|
711
|
+
sig = resolve_node_signature(c.children[1])
|
712
|
+
type = infer_signature_type(sig, namespace)
|
713
|
+
else
|
714
|
+
type = t.types[0]
|
715
|
+
end
|
716
|
+
end
|
717
|
+
arr.push Suggestion.new(c.children[0], kind: Suggestion::VARIABLE, documentation: cmnt, return_type: type)
|
667
718
|
end
|
668
|
-
arr += inner_get_class_variables(c) unless [:class, :module].include?(c.type)
|
719
|
+
arr += inner_get_class_variables(c, namespace) unless [:class, :module].include?(c.type)
|
669
720
|
}
|
670
721
|
end
|
671
722
|
arr
|
@@ -678,6 +729,8 @@ module Solargraph
|
|
678
729
|
# @return [String] The fully qualified namespace for the signature's type
|
679
730
|
# or nil if a type could not be determined
|
680
731
|
def inner_infer_signature_type signature, namespace, scope: :instance
|
732
|
+
return nil if signature.nil?
|
733
|
+
signature.gsub!(/\.$/, '')
|
681
734
|
if signature.nil? or signature.empty?
|
682
735
|
if scope == :class
|
683
736
|
return "#{namespace}#class"
|
@@ -694,6 +747,7 @@ module Solargraph
|
|
694
747
|
top = true
|
695
748
|
while parts.length > 0 and !type.nil?
|
696
749
|
p = parts.shift
|
750
|
+
next if p.empty?
|
697
751
|
if top and scope == :class
|
698
752
|
#next if p == 'new'
|
699
753
|
if p == 'new'
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Solargraph
|
2
|
+
class ApiMap
|
3
|
+
class Cache
|
4
|
+
def initialize
|
5
|
+
@signature_types = {}
|
6
|
+
end
|
7
|
+
def get_signature_type signature, namespace, scope
|
8
|
+
@signature_types[[signature, namespace, scope]]
|
9
|
+
end
|
10
|
+
def set_signature_type signature, namespace, scope, value
|
11
|
+
@signature_types[[signature, namespace, scope]] = value
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/lib/solargraph/code_map.rb
CHANGED
@@ -10,7 +10,7 @@ module Solargraph
|
|
10
10
|
|
11
11
|
include NodeMethods
|
12
12
|
|
13
|
-
def initialize code: '', filename: nil, workspace: nil, api_map: nil
|
13
|
+
def initialize code: '', filename: nil, workspace: nil, api_map: nil, cursor: nil
|
14
14
|
@workspace = workspace
|
15
15
|
# HACK: Adjust incoming filename's path separator for yardoc file comparisons
|
16
16
|
filename = filename.gsub(File::ALT_SEPARATOR, File::SEPARATOR) unless filename.nil? or File::ALT_SEPARATOR.nil?
|
@@ -19,6 +19,8 @@ module Solargraph
|
|
19
19
|
@code = code.gsub(/\r/, '')
|
20
20
|
tries = 0
|
21
21
|
tmp = @code
|
22
|
+
cursor = CodeMap.get_offset(@code, cursor[0], cursor[1]) if cursor.kind_of?(Array)
|
23
|
+
fixed_cursor = false
|
22
24
|
begin
|
23
25
|
# HACK: The current file is parsed with a trailing underscore to fix
|
24
26
|
# incomplete trees resulting from short scripts (e.g., a lone variable
|
@@ -34,21 +36,27 @@ module Solargraph
|
|
34
36
|
if tries == 10 and e.message.include?('token $end')
|
35
37
|
tmp += "\nend"
|
36
38
|
else
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
spot -= 1
|
42
|
-
elsif tmp[spot - 1] == '.'
|
43
|
-
# Stub unfinished method calls
|
44
|
-
repl = '#' if spot == tmp.length or tmp[spot] == '\n'
|
45
|
-
spot -= 2
|
39
|
+
if !fixed_cursor and !cursor.nil? and e.message.include?('token $end') and cursor >= 2
|
40
|
+
fixed_cursor = true
|
41
|
+
spot = cursor - 2
|
42
|
+
repl = '_'
|
46
43
|
else
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
44
|
+
spot = e.diagnostic.location.begin_pos
|
45
|
+
repl = '_'
|
46
|
+
if tmp[spot] == '@' or tmp[spot] == ':'
|
47
|
+
# Stub unfinished instance variables and symbols
|
48
|
+
spot -= 1
|
49
|
+
elsif tmp[spot - 1] == '.'
|
50
|
+
# Stub unfinished method calls
|
51
|
+
repl = '#' if spot == tmp.length or tmp[spot] == '\n'
|
52
|
+
spot -= 2
|
53
|
+
else
|
54
|
+
# Stub the whole line
|
55
|
+
spot = beginning_of_line_from(tmp, spot)
|
56
|
+
repl = '#'
|
57
|
+
if tmp[spot+1..-1].rstrip == 'end'
|
58
|
+
repl= 'end;end'
|
59
|
+
end
|
52
60
|
end
|
53
61
|
end
|
54
62
|
tmp = tmp[0..spot] + repl + tmp[spot+repl.length+1..-1].to_s
|
@@ -75,13 +83,17 @@ module Solargraph
|
|
75
83
|
# @param col [Integer]
|
76
84
|
# @return [Integer]
|
77
85
|
def get_offset line, col
|
86
|
+
CodeMap.get_offset @code, line, col
|
87
|
+
end
|
88
|
+
|
89
|
+
def self.get_offset text, line, col
|
78
90
|
offset = 0
|
79
91
|
if line > 0
|
80
|
-
|
92
|
+
text.lines[0..line - 1].each { |l|
|
81
93
|
offset += l.length
|
82
94
|
}
|
83
95
|
end
|
84
|
-
offset + col
|
96
|
+
offset + col
|
85
97
|
end
|
86
98
|
|
87
99
|
# Get an array of nodes containing the specified index, starting with the
|
@@ -358,7 +370,8 @@ module Solargraph
|
|
358
370
|
if parts[1].nil? or parts[1].empty?
|
359
371
|
result = yp.return_type
|
360
372
|
else
|
361
|
-
|
373
|
+
newsig = parts[1..-1].join('.')
|
374
|
+
result = api_map.infer_signature_type(newsig, yp.return_type, scope: :instance)
|
362
375
|
end
|
363
376
|
end
|
364
377
|
end
|
@@ -382,9 +395,23 @@ module Solargraph
|
|
382
395
|
start = parts[0]
|
383
396
|
return nil if start.nil?
|
384
397
|
remainder = parts[1..-1]
|
398
|
+
if start.start_with?('@@')
|
399
|
+
type = api_map.infer_class_variable(start, ns_here)
|
400
|
+
return nil if type.nil?
|
401
|
+
return type if remainder.empty?
|
402
|
+
return api_map.infer_signature_type(remainder.join('.'), type, scope: :instance)
|
403
|
+
elsif start.start_with?('@')
|
404
|
+
scope = (node.type == :def ? :instance : :scope)
|
405
|
+
type = api_map.infer_instance_variable(start, ns_here, scope: :instance)
|
406
|
+
return nil if type.nil?
|
407
|
+
return type if remainder.empty?
|
408
|
+
return api_map.infer_signature_type(remainder.join('.'), type, scope: :instance)
|
409
|
+
end
|
385
410
|
var = find_local_variable_node(start, node)
|
386
411
|
if var.nil?
|
387
|
-
|
412
|
+
scope = (node.type == :def ? :instance : :class)
|
413
|
+
type = api_map.infer_signature_type(signature, ns_here, scope: scope)
|
414
|
+
return type unless type.nil?
|
388
415
|
else
|
389
416
|
# Signature starts with a local variable
|
390
417
|
type = get_type_comment(var)
|
@@ -395,7 +422,14 @@ module Solargraph
|
|
395
422
|
end
|
396
423
|
end
|
397
424
|
unless type.nil?
|
398
|
-
if remainder
|
425
|
+
if remainder[0] == 'new'
|
426
|
+
remainder.shift
|
427
|
+
if remainder.empty?
|
428
|
+
inferred = type
|
429
|
+
else
|
430
|
+
inferred = api_map.infer_signature_type(remainder.join('.'), type, scope: :instance)
|
431
|
+
end
|
432
|
+
elsif remainder.empty?
|
399
433
|
inferred = type
|
400
434
|
else
|
401
435
|
inferred = api_map.infer_signature_type(remainder.join('.'), type, scope: :instance)
|
@@ -572,7 +606,9 @@ module Solargraph
|
|
572
606
|
tmp = resolve_node_signature(lvarnode.children[1])
|
573
607
|
sig = infer_signature_from_node tmp, scope_node
|
574
608
|
end
|
575
|
-
|
609
|
+
meths = api_map.get_instance_methods(sig, fqns)
|
610
|
+
meths += api_map.get_methods('')
|
611
|
+
meth = meths.keep_if{ |s| s.to_s == block_node.children[0].children[1].to_s }.first
|
576
612
|
yps = []
|
577
613
|
unless meth.nil? or meth.documentation.nil?
|
578
614
|
yps = meth.documentation.tags(:yieldparam) || []
|
data/lib/solargraph/server.rb
CHANGED
@@ -65,7 +65,7 @@ module Solargraph
|
|
65
65
|
workspace = params['workspace'] || nil
|
66
66
|
Server.prepare_workspace workspace unless @@api_hash.has_key?(workspace)
|
67
67
|
@@semaphore.synchronize {
|
68
|
-
code_map = CodeMap.new(code: params['text'], filename: params['filename'], api_map: @@api_hash[workspace])
|
68
|
+
code_map = CodeMap.new(code: params['text'], filename: params['filename'], api_map: @@api_hash[workspace], cursor: [params['line'].to_i, params['column'].to_i])
|
69
69
|
offset = code_map.get_offset(params['line'].to_i, params['column'].to_i)
|
70
70
|
sugg = code_map.resolve_object_at(offset)
|
71
71
|
}
|
data/lib/solargraph/version.rb
CHANGED
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.10.
|
4
|
+
version: 0.10.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Fred Snyder
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-08-
|
11
|
+
date: 2017-08-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: parser
|
@@ -130,6 +130,7 @@ files:
|
|
130
130
|
- bin/solargraph
|
131
131
|
- lib/solargraph.rb
|
132
132
|
- lib/solargraph/api_map.rb
|
133
|
+
- lib/solargraph/api_map/cache.rb
|
133
134
|
- lib/solargraph/api_map/config.rb
|
134
135
|
- lib/solargraph/code_map.rb
|
135
136
|
- lib/solargraph/mapper.rb
|