solargraph 0.10.1 → 0.10.3
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 +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
|