solargraph 0.12.2 → 0.13.0
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.rb +1 -0
- data/lib/solargraph/api_map.rb +179 -431
- data/lib/solargraph/api_map/cache.rb +4 -0
- data/lib/solargraph/api_map/config.rb +1 -1
- data/lib/solargraph/api_map/source.rb +297 -0
- data/lib/solargraph/code_map.rb +81 -134
- data/lib/solargraph/pin.rb +12 -0
- data/lib/solargraph/pin/attribute.rb +16 -0
- data/lib/solargraph/pin/base.rb +47 -0
- data/lib/solargraph/pin/base_variable.rb +33 -0
- data/lib/solargraph/pin/class_variable.rb +6 -0
- data/lib/solargraph/pin/constant.rb +18 -0
- data/lib/solargraph/pin/instance_variable.rb +12 -0
- data/lib/solargraph/pin/method.rb +65 -0
- data/lib/solargraph/pin/symbol.rb +9 -0
- data/lib/solargraph/server.rb +15 -7
- data/lib/solargraph/shell.rb +7 -0
- data/lib/solargraph/suggestion.rb +7 -2
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/yard_map.rb +1 -1
- data/lib/solargraph/yard_methods.rb +28 -1
- metadata +12 -6
- data/lib/solargraph/api_map/attr_pin.rb +0 -37
- data/lib/solargraph/api_map/cvar_pin.rb +0 -27
- data/lib/solargraph/api_map/ivar_pin.rb +0 -29
- data/lib/solargraph/api_map/method_pin.rb +0 -56
@@ -10,6 +10,10 @@ module Solargraph
|
|
10
10
|
@signature_types[[signature, namespace, scope]]
|
11
11
|
end
|
12
12
|
|
13
|
+
def has_signature_type?(signature, namespace, scope)
|
14
|
+
@signature_types.has_key?([signature, namespace, scope])
|
15
|
+
end
|
16
|
+
|
13
17
|
def set_signature_type signature, namespace, scope, value
|
14
18
|
@signature_types[[signature, namespace, scope]] = value
|
15
19
|
end
|
@@ -0,0 +1,297 @@
|
|
1
|
+
require 'parser/current'
|
2
|
+
|
3
|
+
module Solargraph
|
4
|
+
class ApiMap
|
5
|
+
class Source
|
6
|
+
attr_reader :code
|
7
|
+
attr_reader :node
|
8
|
+
attr_reader :comments
|
9
|
+
attr_reader :filename
|
10
|
+
|
11
|
+
include NodeMethods
|
12
|
+
|
13
|
+
def initialize code, node, comments, filename
|
14
|
+
@code = code
|
15
|
+
root = AST::Node.new(:begin, [filename])
|
16
|
+
root = root.append node
|
17
|
+
@node = root
|
18
|
+
@comments = comments
|
19
|
+
@docstring_hash = associate_comments(node, comments)
|
20
|
+
@filename = filename
|
21
|
+
@namespace_nodes = {}
|
22
|
+
@all_nodes = []
|
23
|
+
inner_map_node @node
|
24
|
+
end
|
25
|
+
|
26
|
+
def namespaces
|
27
|
+
@namespace_nodes.keys
|
28
|
+
end
|
29
|
+
|
30
|
+
def namespace_nodes
|
31
|
+
@namespace_nodes
|
32
|
+
end
|
33
|
+
|
34
|
+
def namespace_includes
|
35
|
+
@namespace_includes ||= {}
|
36
|
+
end
|
37
|
+
|
38
|
+
def superclasses
|
39
|
+
@superclasses ||= {}
|
40
|
+
end
|
41
|
+
|
42
|
+
def method_pins
|
43
|
+
@method_pins ||= []
|
44
|
+
end
|
45
|
+
|
46
|
+
def attribute_pins
|
47
|
+
@attribute_pins ||= []
|
48
|
+
end
|
49
|
+
|
50
|
+
def instance_variable_pins
|
51
|
+
@instance_variable_pins ||= []
|
52
|
+
end
|
53
|
+
|
54
|
+
def class_variable_pins
|
55
|
+
@class_variable_pins ||= []
|
56
|
+
end
|
57
|
+
|
58
|
+
def constant_pins
|
59
|
+
@constant_pins ||= []
|
60
|
+
end
|
61
|
+
|
62
|
+
def symbol_pins
|
63
|
+
@symbol_pins ||= []
|
64
|
+
end
|
65
|
+
|
66
|
+
def required
|
67
|
+
@required ||= []
|
68
|
+
end
|
69
|
+
|
70
|
+
def docstring_for node
|
71
|
+
@docstring_hash[node.loc]
|
72
|
+
end
|
73
|
+
|
74
|
+
def code_for node
|
75
|
+
b = node.location.expression.begin.begin_pos
|
76
|
+
e = node.location.expression.end.end_pos
|
77
|
+
frag = code[b..e-1].to_s
|
78
|
+
frag.strip.gsub(/,$/, '')
|
79
|
+
end
|
80
|
+
|
81
|
+
def include? node
|
82
|
+
@all_nodes.include? node
|
83
|
+
end
|
84
|
+
|
85
|
+
private
|
86
|
+
|
87
|
+
def associate_comments node, comments
|
88
|
+
comment_hash = Parser::Source::Comment.associate_locations(node, comments)
|
89
|
+
yard_hash = {}
|
90
|
+
comment_hash.each_pair { |k, v|
|
91
|
+
ctxt = ''
|
92
|
+
num = nil
|
93
|
+
started = false
|
94
|
+
v.each { |l|
|
95
|
+
# Trim the comment and minimum leading whitespace
|
96
|
+
p = l.text.gsub(/^#/, '')
|
97
|
+
if num.nil? and !p.strip.empty?
|
98
|
+
num = p.index(/[^ ]/)
|
99
|
+
started = true
|
100
|
+
elsif started and !p.strip.empty?
|
101
|
+
cur = p.index(/[^ ]/)
|
102
|
+
num = cur if cur < num
|
103
|
+
end
|
104
|
+
if started
|
105
|
+
ctxt += "#{p[num..-1]}\n"
|
106
|
+
end
|
107
|
+
}
|
108
|
+
yard_hash[k] = YARD::Docstring.parser.parse(ctxt).to_docstring
|
109
|
+
}
|
110
|
+
yard_hash
|
111
|
+
end
|
112
|
+
|
113
|
+
def inner_map_node node, tree = [], visibility = :public, scope = :instance, fqn = nil, stack = []
|
114
|
+
stack.push node
|
115
|
+
source = self
|
116
|
+
if node.kind_of?(AST::Node)
|
117
|
+
@all_nodes.push node
|
118
|
+
return if node.type == :str or node.type == :dstr
|
119
|
+
if node.type == :class or node.type == :module
|
120
|
+
visibility = :public
|
121
|
+
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
|
122
|
+
tree = pack_name(node.children[0])
|
123
|
+
else
|
124
|
+
tree = tree + pack_name(node.children[0])
|
125
|
+
end
|
126
|
+
fqn = tree.join('::')
|
127
|
+
@namespace_nodes[fqn] ||= []
|
128
|
+
@namespace_nodes[fqn].push node
|
129
|
+
if node.type == :class and !node.children[1].nil?
|
130
|
+
sc = unpack_name(node.children[1])
|
131
|
+
superclasses[fqn] = sc
|
132
|
+
end
|
133
|
+
end
|
134
|
+
file = source.filename
|
135
|
+
node.children.each do |c|
|
136
|
+
if c.kind_of?(AST::Node)
|
137
|
+
if c.type == :ivasgn
|
138
|
+
par = find_parent(stack, :class, :module, :def, :defs)
|
139
|
+
local_scope = ( (par.kind_of?(AST::Node) and par.type == :def) ? :instance : :class )
|
140
|
+
if c.children[1].nil?
|
141
|
+
ora = find_parent(stack, :or_asgn)
|
142
|
+
unless ora.nil?
|
143
|
+
u = c.updated(:ivasgn, c.children + ora.children[1..-1], nil)
|
144
|
+
instance_variable_pins.push Solargraph::Pin::InstanceVariable.new(self, u, fqn || '', local_scope)
|
145
|
+
end
|
146
|
+
else
|
147
|
+
instance_variable_pins.push Solargraph::Pin::InstanceVariable.new(self, c, fqn || '', local_scope)
|
148
|
+
end
|
149
|
+
elsif c.type == :cvasgn
|
150
|
+
if c.children[1].nil?
|
151
|
+
ora = find_parent(stack, :or_asgn)
|
152
|
+
unless ora.nil?
|
153
|
+
u = c.updated(:cvasgn, c.children + ora.children[1..-1], nil)
|
154
|
+
class_variable_pins.push Solargraph::Pin::ClassVariable.new(self, u, fqn || '')
|
155
|
+
end
|
156
|
+
else
|
157
|
+
class_variable_pins.push Solargraph::Pin::ClassVariable.new(self, c, fqn || '')
|
158
|
+
end
|
159
|
+
elsif c.type == :sym
|
160
|
+
symbol_pins.push Solargraph::Pin::Symbol.new(self, c, fqn)
|
161
|
+
elsif c.type == :casgn
|
162
|
+
constant_pins.push Solargraph::Pin::Constant.new(self, c, fqn)
|
163
|
+
else
|
164
|
+
unless fqn.nil?
|
165
|
+
if c.kind_of?(AST::Node)
|
166
|
+
if c.type == :def and c.children[0].to_s[0].match(/[a-z]/i)
|
167
|
+
method_pins.push Solargraph::Pin::Method.new(source, c, fqn, scope, visibility)
|
168
|
+
inner_map_node c, tree, visibility, scope, fqn, stack
|
169
|
+
next
|
170
|
+
elsif c.type == :defs
|
171
|
+
method_pins.push Solargraph::Pin::Method.new(source, c, fqn, :class, :public)
|
172
|
+
inner_map_node c, tree, :public, :class, fqn, stack
|
173
|
+
next
|
174
|
+
elsif c.type == :send and [:public, :protected, :private].include?(c.children[1])
|
175
|
+
visibility = c.children[1]
|
176
|
+
elsif c.type == :send and c.children[1] == :include #and node.type == :class
|
177
|
+
namespace_includes[fqn] ||= []
|
178
|
+
c.children[2..-1].each do |i|
|
179
|
+
namespace_includes[fqn].push unpack_name(i)
|
180
|
+
end
|
181
|
+
elsif c.type == :send and [:attr_reader, :attr_writer, :attr_accessor].include?(c.children[1])
|
182
|
+
c.children[2..-1].each do |a|
|
183
|
+
if c.children[1] == :attr_reader or c.children[1] == :attr_accessor
|
184
|
+
attribute_pins.push Solargraph::Pin::Attribute.new(self, a, fqn, :reader) #AttrPin.new(c)
|
185
|
+
end
|
186
|
+
if c.children[1] == :attr_writer or c.children[1] == :attr_accessor
|
187
|
+
attribute_pins.push Solargraph::Pin::Attribute.new(self, a, fqn, :writer) #AttrPin.new(c)
|
188
|
+
end
|
189
|
+
end
|
190
|
+
elsif c.type == :sclass and c.children[0].type == :self
|
191
|
+
inner_map_node c, tree, :public, :class, fqn, stack
|
192
|
+
next
|
193
|
+
end
|
194
|
+
end
|
195
|
+
end
|
196
|
+
if c.type == :send and c.children[1] == :require
|
197
|
+
if c.children[2].kind_of?(AST::Node) and c.children[2].type == :str
|
198
|
+
required.push c.children[2].children[0].to_s
|
199
|
+
end
|
200
|
+
end
|
201
|
+
inner_map_node c, tree, visibility, scope, fqn, stack
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|
206
|
+
stack.pop
|
207
|
+
end
|
208
|
+
|
209
|
+
def find_parent(stack, *types)
|
210
|
+
stack.reverse.each { |p|
|
211
|
+
return p if types.include?(p.type)
|
212
|
+
}
|
213
|
+
nil
|
214
|
+
end
|
215
|
+
|
216
|
+
class << self
|
217
|
+
# @return [Solargraph::ApiMap::Source]
|
218
|
+
def load filename
|
219
|
+
code = File.read(filename).gsub(/\r/, '')
|
220
|
+
Source.virtual(filename, code)
|
221
|
+
end
|
222
|
+
|
223
|
+
def virtual filename, code
|
224
|
+
node, comments = Parser::CurrentRuby.parse_with_comments(code)
|
225
|
+
Source.new(code, node, comments, filename)
|
226
|
+
end
|
227
|
+
|
228
|
+
def fix filename, code, cursor = nil
|
229
|
+
tries = 0
|
230
|
+
code.gsub!(/\r/, '')
|
231
|
+
tmp = code
|
232
|
+
cursor = CodeMap.get_offset(code, cursor[0], cursor[1]) if cursor.kind_of?(Array)
|
233
|
+
fixed_cursor = false
|
234
|
+
begin
|
235
|
+
# HACK: The current file is parsed with a trailing underscore to fix
|
236
|
+
# incomplete trees resulting from short scripts (e.g., a lone variable
|
237
|
+
# assignment).
|
238
|
+
node, comments = Parser::CurrentRuby.parse_with_comments(tmp + "\n_")
|
239
|
+
#@node = self.api_map.append_node(node, @comments, filename)
|
240
|
+
#@parsed = tmp
|
241
|
+
#@code.freeze
|
242
|
+
#@parsed.freeze
|
243
|
+
Source.new(code, node, comments, filename)
|
244
|
+
rescue Parser::SyntaxError => e
|
245
|
+
if tries < 10
|
246
|
+
tries += 1
|
247
|
+
if tries == 10 and e.message.include?('token $end')
|
248
|
+
tmp += "\nend"
|
249
|
+
else
|
250
|
+
if !fixed_cursor and !cursor.nil? and e.message.include?('token $end') and cursor >= 2
|
251
|
+
fixed_cursor = true
|
252
|
+
spot = cursor - 2
|
253
|
+
if tmp[cursor - 1] == '.'
|
254
|
+
repl = ';'
|
255
|
+
else
|
256
|
+
repl = '#'
|
257
|
+
end
|
258
|
+
else
|
259
|
+
spot = e.diagnostic.location.begin_pos
|
260
|
+
repl = '_'
|
261
|
+
if tmp[spot] == '@' or tmp[spot] == ':'
|
262
|
+
# Stub unfinished instance variables and symbols
|
263
|
+
spot -= 1
|
264
|
+
elsif tmp[spot - 1] == '.'
|
265
|
+
# Stub unfinished method calls
|
266
|
+
repl = '#' if spot == tmp.length or tmp[spot] == '\n'
|
267
|
+
spot -= 2
|
268
|
+
else
|
269
|
+
# Stub the whole line
|
270
|
+
spot = beginning_of_line_from(tmp, spot)
|
271
|
+
repl = '#'
|
272
|
+
if tmp[spot+1..-1].rstrip == 'end'
|
273
|
+
repl= 'end;end'
|
274
|
+
end
|
275
|
+
end
|
276
|
+
end
|
277
|
+
tmp = tmp[0..spot] + repl + tmp[spot+repl.length+1..-1].to_s
|
278
|
+
end
|
279
|
+
retry
|
280
|
+
end
|
281
|
+
raise e
|
282
|
+
end
|
283
|
+
end
|
284
|
+
|
285
|
+
def beginning_of_line_from str, i
|
286
|
+
while i > 0 and str[i] != "\n"
|
287
|
+
i -= 1
|
288
|
+
end
|
289
|
+
if i > 0 and str[i..-1].strip == ''
|
290
|
+
i = beginning_of_line_from str, i -1
|
291
|
+
end
|
292
|
+
i
|
293
|
+
end
|
294
|
+
end
|
295
|
+
end
|
296
|
+
end
|
297
|
+
end
|
data/lib/solargraph/code_map.rb
CHANGED
@@ -6,19 +6,13 @@ module Solargraph
|
|
6
6
|
# The root node of the parsed code.
|
7
7
|
#
|
8
8
|
# @return [AST::Node]
|
9
|
-
|
9
|
+
attr_reader :node
|
10
10
|
|
11
11
|
# The source code being analyzed.
|
12
12
|
#
|
13
13
|
# @return [String]
|
14
14
|
attr_reader :code
|
15
15
|
|
16
|
-
# The source code after modification to fix syntax errors during parsing.
|
17
|
-
# This string will match #code if no modifications were made.
|
18
|
-
#
|
19
|
-
# @return [String]
|
20
|
-
attr_reader :parsed
|
21
|
-
|
22
16
|
# The filename for the source code.
|
23
17
|
#
|
24
18
|
# @return [String]
|
@@ -38,59 +32,11 @@ module Solargraph
|
|
38
32
|
filename = filename.gsub(File::ALT_SEPARATOR, File::SEPARATOR) unless filename.nil? or File::ALT_SEPARATOR.nil?
|
39
33
|
@filename = filename
|
40
34
|
@api_map = api_map
|
41
|
-
@
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
begin
|
47
|
-
# HACK: The current file is parsed with a trailing underscore to fix
|
48
|
-
# incomplete trees resulting from short scripts (e.g., a lone variable
|
49
|
-
# assignment).
|
50
|
-
node, @comments = Parser::CurrentRuby.parse_with_comments(tmp + "\n_")
|
51
|
-
@node = self.api_map.append_node(node, @comments, filename)
|
52
|
-
@parsed = tmp
|
53
|
-
@code.freeze
|
54
|
-
@parsed.freeze
|
55
|
-
rescue Parser::SyntaxError => e
|
56
|
-
if tries < 10
|
57
|
-
tries += 1
|
58
|
-
if tries == 10 and e.message.include?('token $end')
|
59
|
-
tmp += "\nend"
|
60
|
-
else
|
61
|
-
if !fixed_cursor and !cursor.nil? and e.message.include?('token $end') and cursor >= 2
|
62
|
-
fixed_cursor = true
|
63
|
-
spot = cursor - 2
|
64
|
-
if tmp[cursor - 1] == '.'
|
65
|
-
repl = ';'
|
66
|
-
else
|
67
|
-
repl = '#'
|
68
|
-
end
|
69
|
-
else
|
70
|
-
spot = e.diagnostic.location.begin_pos
|
71
|
-
repl = '_'
|
72
|
-
if tmp[spot] == '@' or tmp[spot] == ':'
|
73
|
-
# Stub unfinished instance variables and symbols
|
74
|
-
spot -= 1
|
75
|
-
elsif tmp[spot - 1] == '.'
|
76
|
-
# Stub unfinished method calls
|
77
|
-
repl = '#' if spot == tmp.length or tmp[spot] == '\n'
|
78
|
-
spot -= 2
|
79
|
-
else
|
80
|
-
# Stub the whole line
|
81
|
-
spot = beginning_of_line_from(tmp, spot)
|
82
|
-
repl = '#'
|
83
|
-
if tmp[spot+1..-1].rstrip == 'end'
|
84
|
-
repl= 'end;end'
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|
88
|
-
tmp = tmp[0..spot] + repl + tmp[spot+repl.length+1..-1].to_s
|
89
|
-
end
|
90
|
-
retry
|
91
|
-
end
|
92
|
-
raise e
|
93
|
-
end
|
35
|
+
@source = self.api_map.virtualize filename, code, cursor
|
36
|
+
@node = @source.node
|
37
|
+
@code = @source.code
|
38
|
+
@comments = @source.comments
|
39
|
+
self.api_map.refresh
|
94
40
|
end
|
95
41
|
|
96
42
|
# Get the ApiMap that was generated for this CodeMap.
|
@@ -98,8 +44,8 @@ module Solargraph
|
|
98
44
|
# @return [Solargraph::ApiMap]
|
99
45
|
def api_map
|
100
46
|
@api_map ||= ApiMap.new(workspace)
|
101
|
-
|
102
|
-
|
47
|
+
#@api_map.refresh
|
48
|
+
#@api_map
|
103
49
|
end
|
104
50
|
|
105
51
|
# Get the offset of the specified line and column.
|
@@ -253,9 +199,11 @@ module Solargraph
|
|
253
199
|
end
|
254
200
|
|
255
201
|
def get_instance_variables_at(index)
|
256
|
-
|
202
|
+
# @todo There are a lot of other cases that need to be handled here
|
203
|
+
node = parent_node_from(index, :def, :defs, :class, :module, :sclass)
|
257
204
|
ns = namespace_at(index) || ''
|
258
|
-
|
205
|
+
scope = (node.type == :def ? :instance : :class)
|
206
|
+
api_map.get_instance_variables(ns, scope)
|
259
207
|
end
|
260
208
|
|
261
209
|
# Get suggestions for code completion at the specified location in the
|
@@ -266,64 +214,68 @@ module Solargraph
|
|
266
214
|
return [] if string_at?(index) or string_at?(index - 1) or comment_at?(index)
|
267
215
|
result = []
|
268
216
|
signature = get_signature_at(index)
|
269
|
-
if
|
270
|
-
|
217
|
+
if signature.start_with?(':')
|
218
|
+
result.concat api_map.get_symbols
|
271
219
|
else
|
272
|
-
if
|
273
|
-
|
274
|
-
if last_period.nil?
|
275
|
-
type = infer_signature_at(index)
|
276
|
-
else
|
277
|
-
type = infer_signature_at(last_period)
|
278
|
-
end
|
220
|
+
if index == 0 or @code[index - 1].match(/[\.\s]/)
|
221
|
+
type = infer_signature_at(index)
|
279
222
|
else
|
280
|
-
if signature.
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
223
|
+
if signature.include?('.')
|
224
|
+
last_period = @code[0..index].rindex('.')
|
225
|
+
if last_period.nil?
|
226
|
+
type = infer_signature_at(index)
|
227
|
+
else
|
228
|
+
type = infer_signature_at(last_period)
|
229
|
+
end
|
286
230
|
else
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
phrase = phrase_at(index)
|
294
|
-
signature = get_signature_at(index)
|
295
|
-
namespace = namespace_at(index)
|
296
|
-
if phrase.include?('::')
|
297
|
-
parts = phrase.split('::', -1)
|
298
|
-
ns = parts[0..-2].join('::')
|
299
|
-
if parts.last.include?('.')
|
300
|
-
ns = parts[0..-2].join('::') + '::' + parts.last[0..parts.last.index('.')-1]
|
301
|
-
result = api_map.get_methods(ns)
|
231
|
+
if signature.start_with?('@@')
|
232
|
+
return get_class_variables_at(index)
|
233
|
+
elsif signature.start_with?('@')
|
234
|
+
return get_instance_variables_at(index)
|
235
|
+
elsif signature.start_with?('$')
|
236
|
+
return api_map.get_global_variables
|
302
237
|
else
|
303
|
-
|
238
|
+
type = infer_signature_at(index)
|
304
239
|
end
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
parts.
|
240
|
+
end
|
241
|
+
end
|
242
|
+
if type.nil?
|
243
|
+
unless signature.include?('.')
|
244
|
+
phrase = phrase_at(index)
|
245
|
+
signature = get_signature_at(index)
|
246
|
+
namespace = namespace_at(index)
|
247
|
+
if phrase.include?('::')
|
248
|
+
parts = phrase.split('::', -1)
|
249
|
+
ns = parts[0..-2].join('::')
|
250
|
+
if parts.last.include?('.')
|
251
|
+
ns = parts[0..-2].join('::') + '::' + parts.last[0..parts.last.index('.')-1]
|
252
|
+
result = api_map.get_methods(ns)
|
253
|
+
else
|
254
|
+
result = api_map.namespaces_in(ns, namespace)
|
317
255
|
end
|
318
|
-
result += api_map.namespaces_in('')
|
319
|
-
result += api_map.get_instance_methods('Kernel')
|
320
256
|
else
|
321
|
-
|
257
|
+
type = infer_literal_node_type(node_at(index - 2))
|
258
|
+
if type.nil?
|
259
|
+
current_namespace = namespace_at(index)
|
260
|
+
parts = current_namespace.to_s.split('::')
|
261
|
+
result += get_snippets_at(index) if with_snippets
|
262
|
+
result += get_local_variables_and_methods_at(index)
|
263
|
+
result += ApiMap.get_keywords
|
264
|
+
while parts.length > 0
|
265
|
+
ns = parts.join('::')
|
266
|
+
result += api_map.namespaces_in(ns, namespace)
|
267
|
+
parts.pop
|
268
|
+
end
|
269
|
+
result += api_map.namespaces_in('')
|
270
|
+
result += api_map.get_instance_methods('Kernel')
|
271
|
+
else
|
272
|
+
result.concat api_map.get_instance_methods(type)
|
273
|
+
end
|
322
274
|
end
|
323
275
|
end
|
276
|
+
else
|
277
|
+
result.concat api_map.get_instance_methods(type)
|
324
278
|
end
|
325
|
-
else
|
326
|
-
result.concat api_map.get_instance_methods(type)
|
327
279
|
end
|
328
280
|
result = reduce_starting_with(result, word_at(index)) if filtered
|
329
281
|
result.uniq{|s| s.path}.sort{|a,b| a.label <=> b.label}
|
@@ -493,16 +445,20 @@ module Solargraph
|
|
493
445
|
return nil if start.nil?
|
494
446
|
remainder = parts[1..-1]
|
495
447
|
if start.start_with?('@@')
|
496
|
-
type = api_map.infer_class_variable(start, ns_here)
|
497
|
-
return nil if type.nil?
|
498
|
-
return type if remainder.empty?
|
499
|
-
return api_map.infer_signature_type(remainder.join('.'), type, scope: :instance)
|
448
|
+
#type = api_map.infer_class_variable(start, ns_here)
|
449
|
+
#return nil if type.nil?
|
450
|
+
#return type if remainder.empty?
|
451
|
+
#return api_map.infer_signature_type(remainder.join('.'), type, scope: :instance)
|
452
|
+
cv = api_map.get_class_variables(ns_here).select{|s| s.label == start}.first
|
453
|
+
return cv.return_type unless cv.nil?
|
500
454
|
elsif start.start_with?('@')
|
501
|
-
scope = (node.type == :def ? :instance : :
|
502
|
-
type = api_map.infer_instance_variable(start, ns_here, scope)
|
503
|
-
return nil if type.nil?
|
504
|
-
return type if remainder.empty?
|
505
|
-
return api_map.infer_signature_type(remainder.join('.'), type, scope: :instance)
|
455
|
+
scope = (node.type == :def ? :instance : :class)
|
456
|
+
#type = api_map.infer_instance_variable(start, ns_here, scope)
|
457
|
+
#return nil if type.nil?
|
458
|
+
#return type if remainder.empty?
|
459
|
+
#return api_map.infer_signature_type(remainder.join('.'), type, scope: :instance)
|
460
|
+
iv = api_map.get_instance_variables(ns_here, scope).select{|s| s.label == start}.first
|
461
|
+
return iv.return_type unless iv.nil?
|
506
462
|
end
|
507
463
|
var = find_local_variable_node(start, node)
|
508
464
|
if var.nil?
|
@@ -537,7 +493,7 @@ module Solargraph
|
|
537
493
|
|
538
494
|
def get_type_comment node
|
539
495
|
obj = nil
|
540
|
-
cmnt =
|
496
|
+
cmnt = @source.docstring_for(node)
|
541
497
|
unless cmnt.nil?
|
542
498
|
tag = cmnt.tag(:type)
|
543
499
|
obj = tag.types[0] unless tag.nil? or tag.types.empty?
|
@@ -806,7 +762,9 @@ module Solargraph
|
|
806
762
|
while parts.length > 0
|
807
763
|
result = api_map.find_fully_qualified_namespace("#{conc}::#{parts[0]}", namespace)
|
808
764
|
if result.nil? or result.empty?
|
809
|
-
sugg = api_map.namespaces_in(conc, namespace).select{ |s| s.label == parts[0] }.first
|
765
|
+
#sugg = api_map.namespaces_in(conc, namespace).select{ |s| s.label == parts[0] }.first
|
766
|
+
bla = api_map.get_constants(conc, namespace)
|
767
|
+
sugg = api_map.get_constants(conc, namespace).select{|s| s.label == parts[0]}.first
|
810
768
|
return nil if sugg.nil?
|
811
769
|
result = sugg.return_type
|
812
770
|
break if result.nil?
|
@@ -819,17 +777,6 @@ module Solargraph
|
|
819
777
|
end
|
820
778
|
end
|
821
779
|
return result if is_constant
|
822
|
-
nil
|
823
|
-
end
|
824
|
-
|
825
|
-
def beginning_of_line_from str, i
|
826
|
-
while i > 0 and str[i] != "\n"
|
827
|
-
i -= 1
|
828
|
-
end
|
829
|
-
if i > 0 and str[i..-1].strip == ''
|
830
|
-
i = beginning_of_line_from str, i -1
|
831
|
-
end
|
832
|
-
i
|
833
780
|
end
|
834
781
|
|
835
782
|
def signature_index_before index
|