solargraph 0.14.2 → 0.14.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.rb +0 -1
- data/lib/solargraph/api_map.rb +168 -123
- data/lib/solargraph/api_map/config.rb +41 -26
- data/lib/solargraph/api_map/source.rb +48 -31
- data/lib/solargraph/code_map.rb +22 -19
- data/lib/solargraph/live_map.rb +2 -1
- data/lib/solargraph/pin.rb +11 -10
- data/lib/solargraph/pin/base_variable.rb +4 -0
- data/lib/solargraph/pin/namespace.rb +23 -0
- data/lib/solargraph/plugin/process.rb +7 -5
- data/lib/solargraph/server.rb +57 -33
- data/lib/solargraph/shell.rb +4 -2
- data/lib/solargraph/suggestion.rb +1 -1
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/yard_map.rb +8 -5
- metadata +3 -17
- data/lib/solargraph/yard_methods.rb +0 -56
@@ -5,50 +5,65 @@ module Solargraph
|
|
5
5
|
class Config
|
6
6
|
# @return [String]
|
7
7
|
attr_reader :workspace
|
8
|
-
attr_reader :raw_data
|
9
|
-
|
10
|
-
# @return [Array<String>]
|
11
|
-
attr_reader :included
|
12
|
-
|
13
|
-
# @return [Array<String>]
|
14
|
-
attr_reader :excluded
|
15
8
|
|
16
|
-
# @return [
|
17
|
-
attr_reader :
|
9
|
+
# @return [Hash]
|
10
|
+
attr_reader :raw_data
|
18
11
|
|
19
12
|
def initialize workspace = nil
|
20
13
|
@workspace = workspace
|
21
14
|
include_globs = ['**/*.rb']
|
22
15
|
exclude_globs = ['spec/**/*', 'test/**/*']
|
23
|
-
@included = []
|
24
|
-
@excluded = []
|
25
|
-
@domains = []
|
26
16
|
unless @workspace.nil?
|
27
|
-
include_globs = ['**/*.rb']
|
28
|
-
exclude_globs = ['spec/**/*', 'test/**/*']
|
29
17
|
sfile = File.join(@workspace, '.solargraph.yml')
|
30
18
|
if File.file?(sfile)
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
19
|
+
begin
|
20
|
+
@raw_data = YAML.load(File.read(sfile))
|
21
|
+
conf = YAML.load(File.read(sfile))
|
22
|
+
include_globs = conf['include'] || include_globs
|
23
|
+
exclude_globs = conf['exclude'] || []
|
24
|
+
rescue Exception => e
|
25
|
+
STDERR.puts "Unable to read .solargraph.yml: #{e.class} #{e.message}"
|
26
|
+
@raw_data = {}
|
27
|
+
end
|
36
28
|
end
|
37
|
-
@included.concat process_globs(include_globs)
|
38
|
-
@excluded.concat process_globs(exclude_globs)
|
39
29
|
end
|
40
30
|
@raw_data ||= {}
|
41
|
-
@raw_data['include']
|
42
|
-
@raw_data['exclude']
|
43
|
-
|
31
|
+
@raw_data['include'] ||= include_globs
|
32
|
+
@raw_data['exclude'] ||= exclude_globs
|
33
|
+
@raw_data['domains'] ||= []
|
34
|
+
@raw_data['required'] ||= []
|
44
35
|
end
|
45
36
|
|
37
|
+
# An array of files included in the workspace (before calculating excluded files).
|
38
|
+
#
|
39
|
+
# @return [Array<String>]
|
46
40
|
def included
|
47
|
-
|
41
|
+
return [] if workspace.nil?
|
42
|
+
@included ||= process_globs(@raw_data['include'])
|
48
43
|
end
|
49
44
|
|
45
|
+
# An array of files excluded from the workspace.
|
46
|
+
#
|
47
|
+
# @return [Array<String>]
|
50
48
|
def excluded
|
51
|
-
|
49
|
+
return [] if workspace.nil?
|
50
|
+
@excluded ||= process_globs(@raw_data['exclude'])
|
51
|
+
end
|
52
|
+
|
53
|
+
# The calculated array of (included - excluded) files in the workspace.
|
54
|
+
#
|
55
|
+
# @return [Array<String>]
|
56
|
+
def calculated
|
57
|
+
@calculated ||= (included - excluded)
|
58
|
+
end
|
59
|
+
|
60
|
+
# @return [Array<String>]
|
61
|
+
def domains
|
62
|
+
raw_data['domains']
|
63
|
+
end
|
64
|
+
|
65
|
+
def required
|
66
|
+
raw_data['required']
|
52
67
|
end
|
53
68
|
|
54
69
|
private
|
@@ -70,46 +70,63 @@ module Solargraph
|
|
70
70
|
@superclasses ||= {}
|
71
71
|
end
|
72
72
|
|
73
|
+
# @return [Array<Solargraph::Pin::Method>]
|
73
74
|
def method_pins
|
74
75
|
@method_pins ||= []
|
75
76
|
end
|
76
77
|
|
78
|
+
# @return [Array<Solargraph::Pin::Attribute>]
|
77
79
|
def attribute_pins
|
78
80
|
@attribute_pins ||= []
|
79
81
|
end
|
80
82
|
|
83
|
+
# @return [Array<Solargraph::Pin::InstanceVariable>]
|
81
84
|
def instance_variable_pins
|
82
85
|
@instance_variable_pins ||= []
|
83
86
|
end
|
84
87
|
|
88
|
+
# @return [Array<Solargraph::Pin::ClassVariable>]
|
85
89
|
def class_variable_pins
|
86
90
|
@class_variable_pins ||= []
|
87
91
|
end
|
88
92
|
|
93
|
+
# @return [Array<Solargraph::Pin::LocalVariable>]
|
89
94
|
def local_variable_pins
|
90
95
|
@local_variable_pins ||= []
|
91
96
|
end
|
92
97
|
|
98
|
+
# @return [Array<Solargraph::Pin::GlobalVariable>]
|
93
99
|
def global_variable_pins
|
94
100
|
@global_variable_pins ||= []
|
95
101
|
end
|
96
102
|
|
103
|
+
# @return [Array<Solargraph::Pin::Constant>]
|
97
104
|
def constant_pins
|
98
105
|
@constant_pins ||= []
|
99
106
|
end
|
100
107
|
|
108
|
+
# @return [Array<Solargraph::Pin::Symbol>]
|
101
109
|
def symbol_pins
|
102
110
|
@symbol_pins ||= []
|
103
111
|
end
|
104
112
|
|
113
|
+
# @return [Array<Solargraph::Pin::Namespace>]
|
114
|
+
def namespace_pins
|
115
|
+
@namespace_pins ||= []
|
116
|
+
end
|
117
|
+
|
118
|
+
# @return [Array<String>]
|
105
119
|
def required
|
106
120
|
@required ||= []
|
107
121
|
end
|
108
122
|
|
123
|
+
# @return [YARD::Docstring]
|
109
124
|
def docstring_for node
|
110
|
-
@docstring_hash[node.loc]
|
125
|
+
return @docstring_hash[node.loc] if node.respond_to?(:loc)
|
126
|
+
nil
|
111
127
|
end
|
112
128
|
|
129
|
+
# @return [String]
|
113
130
|
def code_for node
|
114
131
|
b = node.location.expression.begin.begin_pos
|
115
132
|
e = node.location.expression.end.end_pos
|
@@ -121,6 +138,7 @@ module Solargraph
|
|
121
138
|
@node_tree[node] || []
|
122
139
|
end
|
123
140
|
|
141
|
+
# @return [String]
|
124
142
|
def namespace_for node
|
125
143
|
parts = []
|
126
144
|
([node] + (@node_tree[node] || [])).each do |n|
|
@@ -188,6 +206,7 @@ module Solargraph
|
|
188
206
|
fqn = tree.join('::')
|
189
207
|
@namespace_nodes[fqn] ||= []
|
190
208
|
@namespace_nodes[fqn].push node
|
209
|
+
namespace_pins.push Solargraph::Pin::Namespace.new(self, node, tree[0..-2].join('::') || '')
|
191
210
|
if node.type == :class and !node.children[1].nil?
|
192
211
|
sc = unpack_name(node.children[1])
|
193
212
|
superclasses[fqn] = sc
|
@@ -205,6 +224,7 @@ module Solargraph
|
|
205
224
|
unless ora.nil?
|
206
225
|
u = c.updated(:ivasgn, c.children + ora.children[1..-1], nil)
|
207
226
|
@node_tree[u] = @node_stack.clone
|
227
|
+
@docstring_hash[u.loc] = docstring_for(ora)
|
208
228
|
instance_variable_pins.push Solargraph::Pin::InstanceVariable.new(self, u, fqn || '', local_scope)
|
209
229
|
end
|
210
230
|
else
|
@@ -216,6 +236,7 @@ module Solargraph
|
|
216
236
|
unless ora.nil?
|
217
237
|
u = c.updated(:cvasgn, c.children + ora.children[1..-1], nil)
|
218
238
|
@node_tree[u] = @node_stack.clone
|
239
|
+
@docstring_hash[u.loc] = docstring_for(ora)
|
219
240
|
class_variable_pins.push Solargraph::Pin::ClassVariable.new(self, u, fqn || '')
|
220
241
|
end
|
221
242
|
else
|
@@ -241,38 +262,34 @@ module Solargraph
|
|
241
262
|
elsif c.type == :casgn
|
242
263
|
constant_pins.push Solargraph::Pin::Constant.new(self, c, fqn)
|
243
264
|
else
|
244
|
-
|
245
|
-
if c.
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
265
|
+
if c.kind_of?(AST::Node)
|
266
|
+
if c.type == :def and c.children[0].to_s[0].match(/[a-z]/i)
|
267
|
+
method_pins.push Solargraph::Pin::Method.new(source, c, fqn || '', scope, visibility)
|
268
|
+
elsif c.type == :defs
|
269
|
+
method_pins.push Solargraph::Pin::Method.new(source, c, fqn || '', :class, :public)
|
270
|
+
inner_map_node c, tree, :public, :class, fqn, stack
|
271
|
+
next
|
272
|
+
elsif c.type == :send and [:public, :protected, :private].include?(c.children[1])
|
273
|
+
visibility = c.children[1]
|
274
|
+
elsif c.type == :send and c.children[1] == :include #and node.type == :class
|
275
|
+
namespace_includes[fqn] ||= []
|
276
|
+
c.children[2..-1].each do |i|
|
277
|
+
namespace_includes[fqn].push unpack_name(i)
|
278
|
+
end
|
279
|
+
elsif c.type == :send and [:attr_reader, :attr_writer, :attr_accessor].include?(c.children[1])
|
280
|
+
c.children[2..-1].each do |a|
|
281
|
+
if c.children[1] == :attr_reader or c.children[1] == :attr_accessor
|
282
|
+
attribute_pins.push Solargraph::Pin::Attribute.new(self, a, fqn || '', :reader, docstring_for(c)) #AttrPin.new(c)
|
260
283
|
end
|
261
|
-
|
262
|
-
|
263
|
-
if c.children[1] == :attr_reader or c.children[1] == :attr_accessor
|
264
|
-
attribute_pins.push Solargraph::Pin::Attribute.new(self, a, fqn || '', :reader, docstring_for(c)) #AttrPin.new(c)
|
265
|
-
end
|
266
|
-
if c.children[1] == :attr_writer or c.children[1] == :attr_accessor
|
267
|
-
attribute_pins.push Solargraph::Pin::Attribute.new(self, a, fqn || '', :writer, docstring_for(c)) #AttrPin.new(c)
|
268
|
-
end
|
284
|
+
if c.children[1] == :attr_writer or c.children[1] == :attr_accessor
|
285
|
+
attribute_pins.push Solargraph::Pin::Attribute.new(self, a, fqn || '', :writer, docstring_for(c)) #AttrPin.new(c)
|
269
286
|
end
|
270
|
-
elsif c.type == :sclass and c.children[0].type == :self
|
271
|
-
inner_map_node c, tree, :public, :class, fqn || '', stack
|
272
|
-
next
|
273
287
|
end
|
288
|
+
elsif c.type == :sclass and c.children[0].type == :self
|
289
|
+
inner_map_node c, tree, :public, :class, fqn || '', stack
|
290
|
+
next
|
274
291
|
end
|
275
|
-
|
292
|
+
end
|
276
293
|
if c.type == :send and c.children[1] == :require
|
277
294
|
if c.children[2].kind_of?(AST::Node) and c.children[2].type == :str
|
278
295
|
required.push c.children[2].children[0].to_s
|
@@ -316,8 +333,8 @@ module Solargraph
|
|
316
333
|
fixed_cursor = false
|
317
334
|
begin
|
318
335
|
# HACK: The current file is parsed with a trailing underscore to fix
|
319
|
-
# incomplete trees resulting from short scripts (e.g.,
|
320
|
-
# assignment).
|
336
|
+
# incomplete trees resulting from short scripts (e.g., an unfinished
|
337
|
+
# variable assignment).
|
321
338
|
node, comments = Parser::CurrentRuby.parse_with_comments(tmp + "\n_")
|
322
339
|
Source.new(code, node, comments, filename)
|
323
340
|
rescue Parser::SyntaxError => e
|
data/lib/solargraph/code_map.rb
CHANGED
@@ -25,6 +25,7 @@ module Solargraph
|
|
25
25
|
|
26
26
|
# The root directory of the project. The ApiMap will search here for
|
27
27
|
# additional files to parse and analyze.
|
28
|
+
# @deprecated CodeMap will be server-agnostic in a future version.
|
28
29
|
#
|
29
30
|
# @return [String]
|
30
31
|
attr_reader :workspace
|
@@ -32,6 +33,7 @@ module Solargraph
|
|
32
33
|
include NodeMethods
|
33
34
|
|
34
35
|
def initialize code: '', filename: nil, workspace: nil, api_map: nil, cursor: nil
|
36
|
+
STDERR.puts "WARNING: the `workspace` parameter in Solargraph::CodeMap#new is deprecated and will be removed in a future version." unless workspace.nil?
|
35
37
|
@workspace = workspace
|
36
38
|
# HACK: Adjust incoming filename's path separator for yardoc file comparisons
|
37
39
|
filename = filename.gsub(File::ALT_SEPARATOR, File::SEPARATOR) unless filename.nil? or File::ALT_SEPARATOR.nil?
|
@@ -225,7 +227,7 @@ module Solargraph
|
|
225
227
|
if signature.include?('::')
|
226
228
|
parts = signature.split('::', -1)
|
227
229
|
ns = parts[0..-2].join('::')
|
228
|
-
result = api_map.
|
230
|
+
result = api_map.get_constants(ns, namespace)
|
229
231
|
else
|
230
232
|
type = infer_literal_node_type(node_at(index - 2))
|
231
233
|
if type.nil?
|
@@ -235,10 +237,10 @@ module Solargraph
|
|
235
237
|
result += ApiMap.get_keywords
|
236
238
|
while parts.length > 0
|
237
239
|
ns = parts.join('::')
|
238
|
-
result += api_map.
|
240
|
+
result += api_map.get_constants(ns, namespace)
|
239
241
|
parts.pop
|
240
242
|
end
|
241
|
-
result += api_map.
|
243
|
+
result += api_map.get_constants('')
|
242
244
|
result += api_map.get_instance_methods('Kernel')
|
243
245
|
result += api_map.get_methods('')
|
244
246
|
result += api_map.get_instance_methods('')
|
@@ -434,8 +436,9 @@ module Solargraph
|
|
434
436
|
return type unless type.nil?
|
435
437
|
else
|
436
438
|
# Signature starts with a local variable
|
437
|
-
type =
|
438
|
-
|
439
|
+
type = nil
|
440
|
+
lvp = source.local_variable_pins.select{|p| p.name == var.children[0].to_s and p.visible_from?(node) and (!p.nil_assignment? or p.return_type)}.first
|
441
|
+
type = lvp.return_type unless lvp.nil?
|
439
442
|
if type.nil?
|
440
443
|
vsig = resolve_node_signature(var.children[1])
|
441
444
|
type = infer_signature_from_node vsig, node
|
@@ -458,16 +461,6 @@ module Solargraph
|
|
458
461
|
inferred
|
459
462
|
end
|
460
463
|
|
461
|
-
def get_type_comment node
|
462
|
-
obj = nil
|
463
|
-
cmnt = @source.docstring_for(node)
|
464
|
-
unless cmnt.nil?
|
465
|
-
tag = cmnt.tag(:type)
|
466
|
-
obj = tag.types[0] unless tag.nil? or tag.types.empty?
|
467
|
-
end
|
468
|
-
obj
|
469
|
-
end
|
470
|
-
|
471
464
|
# Get the signature at the specified index.
|
472
465
|
# A signature is a method call that can start with a constant, method, or
|
473
466
|
# variable and does not include any method arguments. Examples:
|
@@ -513,7 +506,6 @@ module Solargraph
|
|
513
506
|
def get_local_variables_and_methods_at(index)
|
514
507
|
result = []
|
515
508
|
local = parent_node_from(index, :class, :module, :def, :defs) || @node
|
516
|
-
#result += get_local_variables_from(local)
|
517
509
|
result += get_local_variables_from(node_at(index))
|
518
510
|
scope = namespace_at(index) || @node
|
519
511
|
if local.type == :def
|
@@ -580,7 +572,7 @@ module Solargraph
|
|
580
572
|
def get_method_arguments_from node
|
581
573
|
return [] unless node.type == :def or node.type == :defs
|
582
574
|
param_hash = {}
|
583
|
-
cmnt = api_map.
|
575
|
+
cmnt = api_map.get_docstring_for(node)
|
584
576
|
unless cmnt.nil?
|
585
577
|
tags = cmnt.tags(:param)
|
586
578
|
tags.each do |tag|
|
@@ -649,9 +641,20 @@ module Solargraph
|
|
649
641
|
node ||= @node
|
650
642
|
namespace = namespace_from(node)
|
651
643
|
arr = []
|
644
|
+
nil_pins = []
|
645
|
+
val_names = []
|
652
646
|
@source.local_variable_pins.select{|p| p.visible_from?(node) }.each do |pin|
|
653
|
-
|
654
|
-
|
647
|
+
if pin.nil_assignment? and pin.return_type.nil?
|
648
|
+
nil_pins.push pin
|
649
|
+
else
|
650
|
+
unless val_names.include?(pin.name)
|
651
|
+
arr.push Suggestion.pull(pin)
|
652
|
+
val_names.push pin.name
|
653
|
+
end
|
654
|
+
end
|
655
|
+
end
|
656
|
+
nil_pins.reject{|p| val_names.include?(p.name)}.each do |pin|
|
657
|
+
arr.push Suggestion.pull(pin)
|
655
658
|
end
|
656
659
|
arr
|
657
660
|
end
|
data/lib/solargraph/live_map.rb
CHANGED
@@ -44,13 +44,14 @@ module Solargraph
|
|
44
44
|
end
|
45
45
|
suggestions = []
|
46
46
|
result.uniq.each do |r|
|
47
|
+
path = (r['namespace'].empty? ? '' : "#{r['namespace']}::") + r['name']
|
47
48
|
kind = Suggestion::CONSTANT
|
48
49
|
if r['class'] == 'Class'
|
49
50
|
kind = Suggestion::CLASS
|
50
51
|
elsif r['class'] == 'Module'
|
51
52
|
kind = Suggestion::MODULE
|
52
53
|
end
|
53
|
-
suggestions.push(Suggestion.new(r['name'], kind: kind))
|
54
|
+
suggestions.push(Suggestion.new(r['name'], kind: kind, path: path))
|
54
55
|
end
|
55
56
|
cache.set_constants(namespace, root, suggestions)
|
56
57
|
suggestions
|
data/lib/solargraph/pin.rb
CHANGED
@@ -1,15 +1,16 @@
|
|
1
1
|
module Solargraph
|
2
2
|
module Pin
|
3
|
-
autoload :Base,
|
4
|
-
autoload :Method,
|
5
|
-
autoload :Attribute,
|
6
|
-
autoload :BaseVariable,
|
3
|
+
autoload :Base, 'solargraph/pin/base'
|
4
|
+
autoload :Method, 'solargraph/pin/method'
|
5
|
+
autoload :Attribute, 'solargraph/pin/attribute'
|
6
|
+
autoload :BaseVariable, 'solargraph/pin/base_variable'
|
7
7
|
autoload :InstanceVariable, 'solargraph/pin/instance_variable'
|
8
|
-
autoload :ClassVariable,
|
9
|
-
autoload :LocalVariable,
|
10
|
-
autoload :GlobalVariable,
|
11
|
-
autoload :Constant,
|
12
|
-
autoload :Symbol,
|
13
|
-
autoload :Directed,
|
8
|
+
autoload :ClassVariable, 'solargraph/pin/class_variable'
|
9
|
+
autoload :LocalVariable, 'solargraph/pin/local_variable'
|
10
|
+
autoload :GlobalVariable, 'solargraph/pin/global_variable'
|
11
|
+
autoload :Constant, 'solargraph/pin/constant'
|
12
|
+
autoload :Symbol, 'solargraph/pin/symbol'
|
13
|
+
autoload :Directed, 'solargraph/pin/directed'
|
14
|
+
autoload :Namespace, 'solargraph/pin/namespace'
|
14
15
|
end
|
15
16
|
end
|
@@ -19,6 +19,10 @@ module Solargraph
|
|
19
19
|
@return_type ||= literal_from_assignment
|
20
20
|
end
|
21
21
|
|
22
|
+
def nil_assignment?
|
23
|
+
node.children[(node.type == :casgn ? 2 : 1)].type == :nil
|
24
|
+
end
|
25
|
+
|
22
26
|
def signature
|
23
27
|
@signature ||= resolve_node_signature(node.children[(node.type == :casgn ? 2 : 1)])
|
24
28
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Solargraph
|
2
|
+
module Pin
|
3
|
+
class Namespace < Pin::Base
|
4
|
+
include Solargraph::NodeMethods
|
5
|
+
|
6
|
+
def name
|
7
|
+
@name ||= pack_name(node.children[0]).last.to_s
|
8
|
+
end
|
9
|
+
|
10
|
+
def path
|
11
|
+
@path ||= (namespace.empty? ? '' : "#{namespace}::") + name
|
12
|
+
end
|
13
|
+
|
14
|
+
def kind
|
15
|
+
@kind ||= (node.type == :class ? Solargraph::Suggestion::CLASS : Solargraph::Suggestion::MODULE)
|
16
|
+
end
|
17
|
+
|
18
|
+
def return_type
|
19
|
+
@return_type ||= (node.type == :class ? 'Class' : 'Module') + "<#{path}>"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -32,6 +32,8 @@ module Solargraph
|
|
32
32
|
end
|
33
33
|
rescue JSON::ParserError => e
|
34
34
|
STDOUT.puts respond_err "Error parsing input: #{e.message}"
|
35
|
+
rescue Exception => e
|
36
|
+
STDOUT.puts respond_err "Error processing input: #{e.message}"
|
35
37
|
end
|
36
38
|
STDOUT.flush
|
37
39
|
end
|
@@ -63,15 +65,15 @@ module Solargraph
|
|
63
65
|
unless con.nil?
|
64
66
|
if (args['scope'] == 'class')
|
65
67
|
if args['with_private']
|
66
|
-
result.concat con.methods
|
68
|
+
result.concat con.methods(false)
|
67
69
|
else
|
68
|
-
result.concat con.public_methods
|
70
|
+
result.concat con.public_methods(false)
|
69
71
|
end
|
70
72
|
elsif (args['scope'] == 'instance')
|
71
73
|
if args['with_private']
|
72
|
-
result.concat con.instance_methods
|
74
|
+
result.concat con.instance_methods(false)
|
73
75
|
else
|
74
|
-
result.concat con.public_instance_methods
|
76
|
+
result.concat con.public_instance_methods(false)
|
75
77
|
end
|
76
78
|
end
|
77
79
|
end
|
@@ -85,8 +87,8 @@ module Solargraph
|
|
85
87
|
#result.concat con.constants
|
86
88
|
con.constants.each do |c|
|
87
89
|
next if c == :Solargraph and !@required.include?('solargraph')
|
88
|
-
item = { name: c }
|
89
90
|
here = con.const_get(c)
|
91
|
+
item = { namespace: con.to_s, name: c.to_s }
|
90
92
|
item[:class] = here.class.to_s
|
91
93
|
result.push item
|
92
94
|
end
|