solargraph 0.4.1 → 0.4.2
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 +67 -61
- data/lib/solargraph/code_map.rb +38 -15
- data/lib/solargraph/node_methods.rb +11 -9
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/yard_map.rb +46 -8
- 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: ef9da7f38a0665ebb95d8e779b511d54da955619
|
4
|
+
data.tar.gz: 4715dd2076a1497cf00cebb8456510a33f5ca43e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7999e6032efaf061fbf36a7e9ae2b6f1b81955324c68c465bd8b17039a740cdb2015fbb71207df9ebce2235d60847a07dfca118296dcb6b7b4a05b9abe9049d2
|
7
|
+
data.tar.gz: 9a8632ccc9e26c082df9162f945257414562558fb65629b33b07e218399c76e7c93d43a9b31ef38465ac331f58acc1b172948245fdae10e076ebe40443300bb7
|
data/lib/solargraph/api_map.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'parser/current'
|
3
3
|
require 'yard'
|
4
|
+
require 'yaml'
|
4
5
|
|
5
6
|
module Solargraph
|
6
7
|
class ApiMap
|
@@ -25,9 +26,16 @@ module Solargraph
|
|
25
26
|
@workspace = workspace
|
26
27
|
clear
|
27
28
|
unless @workspace.nil?
|
28
|
-
files =
|
29
|
-
|
30
|
-
|
29
|
+
files = []
|
30
|
+
opts = options
|
31
|
+
(opts[:include] - opts[:exclude]).each { |glob|
|
32
|
+
files += Dir[File.join @workspace, glob]
|
33
|
+
}
|
34
|
+
opts[:exclude].each { |glob|
|
35
|
+
files -= Dir[File.join @workspace, glob]
|
36
|
+
}
|
37
|
+
files.uniq.each { |f|
|
38
|
+
append_file f #unless yardoc_has_file?(f)
|
31
39
|
}
|
32
40
|
end
|
33
41
|
end
|
@@ -41,17 +49,18 @@ module Solargraph
|
|
41
49
|
@required = []
|
42
50
|
end
|
43
51
|
|
44
|
-
def
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
52
|
+
def options
|
53
|
+
o = {
|
54
|
+
include: ['app/**/*.rb', 'lib/**/*.rb'],
|
55
|
+
exclude: []
|
56
|
+
}
|
57
|
+
yaml = File.join(workspace, '.solargraph.yml')
|
58
|
+
if workspace && File.exist?(yaml)
|
59
|
+
l = YAML.load_file(yaml)
|
60
|
+
o[:include].concat l['include'] unless l['include'].nil?
|
61
|
+
o[:exclude].concat l[:exclude] unless l['exclude'].nil?
|
53
62
|
end
|
54
|
-
|
63
|
+
o
|
55
64
|
end
|
56
65
|
|
57
66
|
def append_file filename
|
@@ -67,9 +76,7 @@ module Solargraph
|
|
67
76
|
@file_comments[filename] = associate_comments(node, comments)
|
68
77
|
mapified = reduce(node, @file_comments[filename])
|
69
78
|
root = AST::Node.new(:begin, [filename])
|
70
|
-
|
71
|
-
root = root.append c
|
72
|
-
}
|
79
|
+
root = root.append mapified
|
73
80
|
@file_nodes[filename] = root
|
74
81
|
@required.uniq!
|
75
82
|
process_maps
|
@@ -110,20 +117,20 @@ module Solargraph
|
|
110
117
|
@namespace_map = {}
|
111
118
|
@namespace_tree = {}
|
112
119
|
@file_nodes.values.each { |f|
|
113
|
-
map_parents f
|
114
|
-
map_namespaces f
|
120
|
+
map_parents f
|
121
|
+
map_namespaces f
|
115
122
|
}
|
116
123
|
end
|
117
|
-
|
124
|
+
|
118
125
|
def namespaces
|
119
126
|
@namespace_map.keys
|
120
127
|
end
|
121
|
-
|
128
|
+
|
122
129
|
def namespace_exists? name, root = ''
|
123
130
|
!find_fully_qualified_namespace(name, root).nil?
|
124
131
|
end
|
125
|
-
|
126
|
-
def namespaces_in name, root = ''
|
132
|
+
|
133
|
+
def namespaces_in name, root = ''
|
127
134
|
result = []
|
128
135
|
result += inner_namespaces_in(name, root, [])
|
129
136
|
yard = YardMap.new(required: @required, workspace: @workspace)
|
@@ -137,43 +144,41 @@ module Solargraph
|
|
137
144
|
end
|
138
145
|
result
|
139
146
|
end
|
140
|
-
|
147
|
+
|
141
148
|
def inner_namespaces_in name, root, skip
|
142
149
|
result = []
|
143
150
|
fqns = find_fully_qualified_namespace(name, root)
|
144
|
-
|
145
|
-
return result
|
146
|
-
else
|
147
|
-
return result if skip.include?(fqns)
|
151
|
+
unless fqns.nil? or skip.include?(fqns)
|
148
152
|
skip.push fqns
|
149
153
|
nodes = get_namespace_nodes(fqns)
|
150
|
-
nodes.delete_if { |n| yardoc_has_file?(get_filename_for(n))}
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
}
|
157
|
-
unless cursor.nil?
|
158
|
-
cursor.keys.each { |k|
|
159
|
-
type = get_namespace_type(k, fqns)
|
160
|
-
kind = nil
|
161
|
-
detail = nil
|
162
|
-
if type == :class
|
163
|
-
kind = Suggestion::CLASS
|
164
|
-
detail = 'Class'
|
165
|
-
elsif type == :module
|
166
|
-
kind = Suggestion::MODULE
|
167
|
-
detail = 'Module'
|
168
|
-
end
|
169
|
-
result.push Suggestion.new(k, kind: kind, detail: detail)
|
154
|
+
#nodes.delete_if { |n| yardoc_has_file?(get_filename_for(n))}
|
155
|
+
unless nodes.empty?
|
156
|
+
cursor = @namespace_tree
|
157
|
+
parts = fqns.split('::')
|
158
|
+
parts.each { |p|
|
159
|
+
cursor = cursor[p]
|
170
160
|
}
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
161
|
+
unless cursor.nil?
|
162
|
+
cursor.keys.each { |k|
|
163
|
+
type = get_namespace_type(k, fqns)
|
164
|
+
kind = nil
|
165
|
+
detail = nil
|
166
|
+
if type == :class
|
167
|
+
kind = Suggestion::CLASS
|
168
|
+
detail = 'Class'
|
169
|
+
elsif type == :module
|
170
|
+
kind = Suggestion::MODULE
|
171
|
+
detail = 'Module'
|
172
|
+
end
|
173
|
+
result.push Suggestion.new(k, kind: kind, detail: detail)
|
175
174
|
}
|
176
|
-
|
175
|
+
nodes = get_namespace_nodes(fqns)
|
176
|
+
nodes.each { |n|
|
177
|
+
get_include_strings_from(n).each { |i|
|
178
|
+
result += inner_namespaces_in(i, fqns, skip)
|
179
|
+
}
|
180
|
+
}
|
181
|
+
end
|
177
182
|
end
|
178
183
|
end
|
179
184
|
result
|
@@ -217,7 +222,7 @@ module Solargraph
|
|
217
222
|
return @file_nodes.values if fqns == ''
|
218
223
|
@namespace_map[fqns] || []
|
219
224
|
end
|
220
|
-
|
225
|
+
|
221
226
|
def get_instance_variables(namespace, scope = :instance)
|
222
227
|
nodes = get_namespace_nodes(namespace) || @file_nodes.values
|
223
228
|
arr = []
|
@@ -226,7 +231,7 @@ module Solargraph
|
|
226
231
|
}
|
227
232
|
arr
|
228
233
|
end
|
229
|
-
|
234
|
+
|
230
235
|
def find_parent(node, *types)
|
231
236
|
parents = @parent_stack[node]
|
232
237
|
parents.each { |p|
|
@@ -234,7 +239,7 @@ module Solargraph
|
|
234
239
|
}
|
235
240
|
nil
|
236
241
|
end
|
237
|
-
|
242
|
+
|
238
243
|
def get_root_for(node)
|
239
244
|
s = @parent_stack[node]
|
240
245
|
return nil if s.nil?
|
@@ -253,7 +258,7 @@ module Solargraph
|
|
253
258
|
node.children.each { |c|
|
254
259
|
if c.kind_of?(AST::Node)
|
255
260
|
is_inst = !find_parent(c, :def).nil?
|
256
|
-
if c.type == :ivasgn and ( (scope == :instance and is_inst) or (scope != :instance and !is_inst) )
|
261
|
+
if c.type == :ivasgn and c.children[0] and ( (scope == :instance and is_inst) or (scope != :instance and !is_inst) )
|
257
262
|
arr.push Suggestion.new(c.children[0], kind: Suggestion::VARIABLE)
|
258
263
|
end
|
259
264
|
arr += inner_get_instance_variables(c, scope) unless [:class, :module].include?(c.type)
|
@@ -409,7 +414,7 @@ module Solargraph
|
|
409
414
|
return meths if fqns.nil?
|
410
415
|
nodes = get_namespace_nodes(fqns)
|
411
416
|
nodes.each { |n|
|
412
|
-
unless yardoc_has_file?(get_filename_for(n))
|
417
|
+
#unless yardoc_has_file?(get_filename_for(n))
|
413
418
|
if n.kind_of?(AST::Node)
|
414
419
|
if n.type == :class and !n.children[1].nil?
|
415
420
|
s = unpack_name(n.children[1])
|
@@ -430,7 +435,7 @@ module Solargraph
|
|
430
435
|
end
|
431
436
|
}
|
432
437
|
end
|
433
|
-
end
|
438
|
+
#end
|
434
439
|
}
|
435
440
|
meths.uniq
|
436
441
|
end
|
@@ -442,7 +447,7 @@ module Solargraph
|
|
442
447
|
skip.push fqns
|
443
448
|
nodes = get_namespace_nodes(fqns)
|
444
449
|
nodes.each { |n|
|
445
|
-
unless yardoc_has_file?(get_filename_for(n))
|
450
|
+
#unless yardoc_has_file?(get_filename_for(n))
|
446
451
|
if n.kind_of?(AST::Node)
|
447
452
|
if n.type == :class and !n.children[1].nil?
|
448
453
|
s = unpack_name(n.children[1])
|
@@ -481,7 +486,7 @@ module Solargraph
|
|
481
486
|
}
|
482
487
|
}
|
483
488
|
end
|
484
|
-
end
|
489
|
+
#end
|
485
490
|
}
|
486
491
|
meths.uniq
|
487
492
|
end
|
@@ -498,6 +503,7 @@ module Solargraph
|
|
498
503
|
end
|
499
504
|
|
500
505
|
def reduce node, comment_hash
|
506
|
+
return node unless node.kind_of?(AST::Node)
|
501
507
|
mappable = get_mappable_nodes(node.children, comment_hash)
|
502
508
|
result = node.updated nil, mappable
|
503
509
|
result
|
@@ -575,7 +581,7 @@ module Solargraph
|
|
575
581
|
def map_namespaces node, tree = []
|
576
582
|
if node.kind_of?(AST::Node)
|
577
583
|
if node.type == :class or node.type == :module
|
578
|
-
if node.children[0].children[0].kind_of?(AST::Node) and node.children[0].children[0].type == :cbase
|
584
|
+
if node.children[0].kind_of?(AST::Node) and node.children[0].children[0].kind_of?(AST::Node) and node.children[0].children[0].type == :cbase
|
579
585
|
tree = pack_name(node.children[0])
|
580
586
|
else
|
581
587
|
tree = tree + pack_name(node.children[0])
|
data/lib/solargraph/code_map.rb
CHANGED
@@ -207,6 +207,7 @@ module Solargraph
|
|
207
207
|
scope = parent_node_from(index, :class, :module, :def, :defs) || @node
|
208
208
|
var = find_local_variable_node(first, scope)
|
209
209
|
if var.nil?
|
210
|
+
# It's not a locally assigned variable.
|
210
211
|
if ['STDERR','STDOUT','STDIN'].include?(first)
|
211
212
|
obj = 'IO'
|
212
213
|
if parts.length == 0
|
@@ -214,13 +215,32 @@ module Solargraph
|
|
214
215
|
end
|
215
216
|
else
|
216
217
|
if parts.length == 0
|
217
|
-
|
218
|
+
# HACK: Assume that it's a constant (class or module) if it starts with an uppercase letter
|
219
|
+
if first[0] == first[0].upcase
|
220
|
+
return @api_map.get_methods(first, ns_here)
|
221
|
+
else
|
222
|
+
if scope.type == :def
|
223
|
+
meths = @api_map.get_instance_methods(ns_here).delete_if{|m| m.insert != first}
|
224
|
+
return [] if meths.empty?
|
225
|
+
return [] if meths[0].documentation.nil?
|
226
|
+
match = meths[0].documentation.all.match(/@return \[([a-z0-9:_]*)/i)
|
227
|
+
return [] if match[1].nil?
|
228
|
+
return @api_map.get_instance_methods(match[1], ns_here)
|
229
|
+
else
|
230
|
+
meths = @api_map.get_methods(ns_here).delete_if{|m| m.insert != first}
|
231
|
+
return [] if meths.empty?
|
232
|
+
return [] if meths[0].documentation.nil?
|
233
|
+
match = meths[0].documentation.all.match(/@return \[([a-z0-9:_]*)/i)
|
234
|
+
return [] if match[1].nil?
|
235
|
+
return @api_map.get_instance_methods(match[1], ns_here)
|
236
|
+
end
|
237
|
+
end
|
218
238
|
end
|
219
239
|
meth = parts.shift
|
220
240
|
if meth == 'new'
|
221
241
|
obj = first
|
222
242
|
else
|
223
|
-
obj = get_method_return_value first, ns_here, meth
|
243
|
+
obj = get_method_return_value first, ns_here, meth, :class
|
224
244
|
end
|
225
245
|
end
|
226
246
|
while parts.length > 0
|
@@ -237,27 +257,30 @@ module Solargraph
|
|
237
257
|
end
|
238
258
|
end
|
239
259
|
|
240
|
-
def get_method_return_value namespace, root, method
|
260
|
+
def get_method_return_value namespace, root, method, scope = :instance
|
241
261
|
meths = @api_map.get_methods(namespace, root).delete_if{ |m| m.insert != method }
|
242
262
|
meths.each { |m|
|
243
|
-
|
244
|
-
|
245
|
-
klass = match[1]
|
246
|
-
return klass unless klass.nil?
|
247
|
-
end
|
263
|
+
r = get_return_tag(m)
|
264
|
+
return r unless r.nil?
|
248
265
|
}
|
249
|
-
|
266
|
+
nil
|
250
267
|
end
|
251
268
|
|
252
269
|
def get_instance_method_return_value namespace, root, method
|
253
270
|
meths = @api_map.get_instance_methods(namespace, root).delete_if{ |m| m.insert != method }
|
254
271
|
meths.each { |m|
|
255
|
-
|
256
|
-
|
257
|
-
return match[1] unless match.nil?
|
258
|
-
end
|
272
|
+
r = get_return_tag(m)
|
273
|
+
return r unless r.nil?
|
259
274
|
}
|
260
|
-
|
275
|
+
nil
|
276
|
+
end
|
277
|
+
|
278
|
+
def get_return_tag suggestion
|
279
|
+
unless suggestion.documentation.nil?
|
280
|
+
match = suggestion.documentation.all.match(/@return \[([a-z0-9:_]*)/i)
|
281
|
+
return match[1]
|
282
|
+
end
|
283
|
+
nil
|
261
284
|
end
|
262
285
|
|
263
286
|
def get_signature_at index
|
@@ -339,7 +362,7 @@ module Solargraph
|
|
339
362
|
result += @api_map.get_methods(scope, visibility: [:public, :private, :protected])
|
340
363
|
end
|
341
364
|
result += @api_map.get_methods('Kernel')
|
342
|
-
result
|
365
|
+
result
|
343
366
|
end
|
344
367
|
|
345
368
|
private
|
@@ -6,17 +6,19 @@ module Solargraph
|
|
6
6
|
|
7
7
|
def pack_name(node)
|
8
8
|
parts = []
|
9
|
-
node.
|
10
|
-
|
11
|
-
if n.
|
12
|
-
|
9
|
+
if node.kind_of?(AST::Node)
|
10
|
+
node.children.each { |n|
|
11
|
+
if n.kind_of?(AST::Node)
|
12
|
+
if n.type == :cbase
|
13
|
+
parts = pack_name(n)
|
14
|
+
else
|
15
|
+
parts += pack_name(n)
|
16
|
+
end
|
13
17
|
else
|
14
|
-
parts
|
18
|
+
parts.push n unless n.nil?
|
15
19
|
end
|
16
|
-
|
17
|
-
|
18
|
-
end
|
19
|
-
}
|
20
|
+
}
|
21
|
+
end
|
20
22
|
parts
|
21
23
|
end
|
22
24
|
|
data/lib/solargraph/version.rb
CHANGED
data/lib/solargraph/yard_map.rb
CHANGED
@@ -6,10 +6,10 @@ module Solargraph
|
|
6
6
|
|
7
7
|
class YardMap
|
8
8
|
def initialize required: [], workspace: nil
|
9
|
-
unless workspace.nil?
|
10
|
-
|
11
|
-
|
12
|
-
end
|
9
|
+
#unless workspace.nil?
|
10
|
+
# wsy = File.join(workspace, '.yardoc')
|
11
|
+
# yardocs.push wsy if File.exist?(wsy)
|
12
|
+
#end
|
13
13
|
used = []
|
14
14
|
required.each { |r|
|
15
15
|
if workspace.nil? or !File.exist?(File.join workspace, 'lib', "#{r}.rb")
|
@@ -58,7 +58,11 @@ module Solargraph
|
|
58
58
|
unless yard.nil?
|
59
59
|
obj = yard.at query
|
60
60
|
#found.push YARD::Templates::Engine.render(format: :html, object: obj) unless obj.nil?
|
61
|
-
|
61
|
+
unless obj.nil?
|
62
|
+
# HACK: Fix return tags in core documentation
|
63
|
+
fix_return! obj if obj.kind_of?(YARD::CodeObjects::MethodObject) and y.include?('.solargraph')
|
64
|
+
found.push obj
|
65
|
+
end
|
62
66
|
end
|
63
67
|
}
|
64
68
|
found
|
@@ -125,15 +129,17 @@ module Solargraph
|
|
125
129
|
if scope == ''
|
126
130
|
ns = yard.at(namespace)
|
127
131
|
else
|
128
|
-
ns = yard
|
132
|
+
ns = find_first_resolved_namespace(yard, namespace, scope)
|
129
133
|
end
|
130
134
|
unless ns.nil? or !ns.kind_of?(YARD::CodeObjects::NamespaceObject)
|
131
135
|
ns.meths(scope: :class, visibility: visibility).each { |m|
|
136
|
+
# HACK: Fix return tags in core documentation
|
137
|
+
fix_return! m if y.include?('.solargraph')
|
132
138
|
n = m.to_s.split(/[\.#]/).last
|
133
139
|
label = "#{n}"
|
134
140
|
args = get_method_args(m)
|
135
141
|
label += " #{args.join(', ')}" unless args.empty?
|
136
|
-
meths.push Suggestion.new(label, insert: "#{n}", kind: Suggestion::METHOD, detail: "#{ns}"
|
142
|
+
meths.push Suggestion.new(label, insert: "#{n}", kind: Suggestion::METHOD, documentation: m.docstring, code_object: m, detail: "#{ns}", location: "#{m.file}:#{m.line}")
|
137
143
|
}
|
138
144
|
if ns.kind_of?(YARD::CodeObjects::ClassObject) and namespace != 'Class'
|
139
145
|
meths += get_instance_methods('Class')
|
@@ -153,10 +159,12 @@ module Solargraph
|
|
153
159
|
if scope == ''
|
154
160
|
ns = yard.at(namespace)
|
155
161
|
else
|
156
|
-
ns = yard
|
162
|
+
ns = find_first_resolved_namespace(yard, namespace, scope)
|
157
163
|
end
|
158
164
|
unless ns.nil?
|
159
165
|
ns.meths(scope: :instance, visibility: visibility).each { |m|
|
166
|
+
# HACK: Fix return tags in core documentation
|
167
|
+
fix_return! m if y.include?('.solargraph')
|
160
168
|
n = m.to_s.split(/[\.#]/).last
|
161
169
|
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:')
|
162
170
|
label = "#{n}"
|
@@ -174,6 +182,10 @@ module Solargraph
|
|
174
182
|
meths
|
175
183
|
end
|
176
184
|
|
185
|
+
def gem_names
|
186
|
+
Gem::Specification.map{ |s| s.name }.uniq
|
187
|
+
end
|
188
|
+
|
177
189
|
private
|
178
190
|
|
179
191
|
def get_method_args meth
|
@@ -183,6 +195,32 @@ module Solargraph
|
|
183
195
|
}
|
184
196
|
args
|
185
197
|
end
|
198
|
+
|
199
|
+
def fix_return! meth
|
200
|
+
return unless meth.tag(:return).nil?
|
201
|
+
return unless meth.docstring.all.include?('@return')
|
202
|
+
text = ''
|
203
|
+
meth.docstring.all.lines.each { |line|
|
204
|
+
if line.strip.start_with?('@return')
|
205
|
+
text += line.strip
|
206
|
+
else
|
207
|
+
text += line
|
208
|
+
end
|
209
|
+
text += "\n"
|
210
|
+
}
|
211
|
+
doc = YARD::Docstring.new(text, meth)
|
212
|
+
meth.docstring = doc
|
213
|
+
end
|
214
|
+
|
215
|
+
def find_first_resolved_namespace yard, namespace, scope
|
216
|
+
parts = scope.split('::')
|
217
|
+
while parts.length > 0
|
218
|
+
ns = yard.resolve(P(scope), namespace)
|
219
|
+
return ns unless ns.nil?
|
220
|
+
parts.pop
|
221
|
+
end
|
222
|
+
yard.at(namespace)
|
223
|
+
end
|
186
224
|
end
|
187
225
|
|
188
226
|
end
|
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.
|
4
|
+
version: 0.4.2
|
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-04-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: parser
|