solargraph 0.4.1 → 0.4.2
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 +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
|