solargraph 0.39.8 → 0.39.13
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/SPONSORS.md +5 -0
- data/lib/solargraph/api_map.rb +1 -1
- data/lib/solargraph/language_server/message/text_document/formatting.rb +1 -1
- data/lib/solargraph/library.rb +17 -3
- data/lib/solargraph/parser/legacy/node_methods.rb +3 -1
- data/lib/solargraph/pin/documenting.rb +3 -2
- data/lib/solargraph/pin/method.rb +1 -1
- data/lib/solargraph/pin/yard_pin/method.rb +16 -1
- data/lib/solargraph/pin/yard_pin/yard_mixin.rb +2 -8
- data/lib/solargraph/source/chain/z_super.rb +0 -154
- data/lib/solargraph/source_map.rb +1 -0
- data/lib/solargraph/source_map/clip.rb +76 -43
- data/lib/solargraph/source_map/mapper.rb +20 -8
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/yard_map/rdoc_to_yard.rb +14 -10
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b06a4823fe5895875513bafc0192b627ecc2a5eff460bdc4e9bd511e8d31ecda
|
4
|
+
data.tar.gz: e5cfad1cfaa75dec019e2a772297c4f5c936370a9dcb49d1a61ae1e9e0529581
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3e169cdfe2badf421a2323c6e796d346dea9c17f1b919a2d96de47ac7f1d0a3ebc77a799ac1ff7f44022b6621c01936fb31178ec9db56ea0b6ee63f44e279f47
|
7
|
+
data.tar.gz: 1c7783cd9b43ed4b9dc29a30fea180c10c9440961a630e7180f4101bcc064b40db9fd9018b5d94594cf061c9b993402cf18ffdcff3a4537f0366dd6f29992865
|
data/SPONSORS.md
CHANGED
@@ -4,6 +4,11 @@ Solargraph is developed and maintained by [Castwide Technologies](https://castwi
|
|
4
4
|
|
5
5
|
The following people and organizations provide funding or other resources. [Become a sponsor](https://patreon.com/castwide)
|
6
6
|
|
7
|
+
## Linked Sponsors
|
8
|
+
|
9
|
+
- **[Calyptix Security](https://www.calyptix.com/)**
|
10
|
+
|
7
11
|
## Named Sponsors
|
8
12
|
|
9
13
|
- Emily Strickland
|
14
|
+
- Tom de Grunt
|
data/lib/solargraph/api_map.rb
CHANGED
@@ -423,7 +423,7 @@ module Solargraph
|
|
423
423
|
# api_map.document('String#split')
|
424
424
|
#
|
425
425
|
# @param path [String] The path to find
|
426
|
-
# @return [Array<YARD::
|
426
|
+
# @return [Array<YARD::CodeObjects::Base>]
|
427
427
|
def document path
|
428
428
|
rake_yard(store)
|
429
429
|
docs = []
|
@@ -26,10 +26,10 @@ module Solargraph
|
|
26
26
|
store = RuboCop::ConfigStore.new
|
27
27
|
redirect_stdout { RuboCop::Runner.new(options, store).run(paths) }
|
28
28
|
result = File.read(tempfile)
|
29
|
-
File.unlink tempfile
|
30
29
|
format original, result
|
31
30
|
rescue RuboCop::ValidationError, RuboCop::ConfigNotFoundError => e
|
32
31
|
set_error(Solargraph::LanguageServer::ErrorCodes::INTERNAL_ERROR, "[#{e.class}] #{e.message}")
|
32
|
+
ensure
|
33
33
|
File.unlink tempfile
|
34
34
|
end
|
35
35
|
end
|
data/lib/solargraph/library.rb
CHANGED
@@ -171,7 +171,21 @@ module Solargraph
|
|
171
171
|
def definitions_at filename, line, column
|
172
172
|
position = Position.new(line, column)
|
173
173
|
cursor = Source::Cursor.new(read(filename), position)
|
174
|
-
|
174
|
+
if cursor.comment?
|
175
|
+
source = read(filename)
|
176
|
+
offset = Solargraph::Position.to_offset(source.code, Solargraph::Position.new(line, column))
|
177
|
+
lft = source.code[0..offset-1].match(/[\[<, ]([a-z0-9_:]*)\z/i)
|
178
|
+
rgt = source.code[offset..-1].match(/^([a-z0-9_]*)(:[a-z0-9_:]*)?[\]>, ]/i)
|
179
|
+
if lft && rgt
|
180
|
+
tag = lft[1] + rgt[1]
|
181
|
+
clip = api_map.clip(cursor)
|
182
|
+
clip.translate tag
|
183
|
+
else
|
184
|
+
[]
|
185
|
+
end
|
186
|
+
else
|
187
|
+
api_map.clip(cursor).define.map { |pin| pin.realize(api_map) }
|
188
|
+
end
|
175
189
|
end
|
176
190
|
|
177
191
|
# Get signature suggestions for the method at the specified file and
|
@@ -245,7 +259,7 @@ module Solargraph
|
|
245
259
|
end
|
246
260
|
|
247
261
|
# @param query [String]
|
248
|
-
# @return [Array<YARD::
|
262
|
+
# @return [Array<YARD::CodeObjects::Base>]
|
249
263
|
def document query
|
250
264
|
catalog
|
251
265
|
api_map.document query
|
@@ -339,7 +353,7 @@ module Solargraph
|
|
339
353
|
logger.info "Cataloging #{workspace.directory.empty? ? 'generic workspace' : workspace.directory}"
|
340
354
|
api_map.catalog bundle
|
341
355
|
@synchronized = true
|
342
|
-
logger.info "Catalog complete (#{api_map.pins.length} pins)"
|
356
|
+
logger.info "Catalog complete (#{api_map.source_maps.length} files, #{api_map.pins.length} pins)" if logger.info?
|
343
357
|
end
|
344
358
|
end
|
345
359
|
|
@@ -124,7 +124,9 @@ module Solargraph
|
|
124
124
|
result = []
|
125
125
|
if node.type == :block
|
126
126
|
result.push node
|
127
|
-
node.children[0].children[
|
127
|
+
if Parser.is_ast_node?(node.children[0]) && node.children[0].children.length > 2
|
128
|
+
node.children[0].children[2..-1].each { |child| result.concat call_nodes_from(child) }
|
129
|
+
end
|
128
130
|
node.children[1..-1].each { |child| result.concat call_nodes_from(child) }
|
129
131
|
elsif node.type == :send
|
130
132
|
result.push node
|
@@ -53,13 +53,14 @@ module Solargraph
|
|
53
53
|
# @param text [String]
|
54
54
|
# @return [String]
|
55
55
|
def escape_brackets text
|
56
|
-
text.gsub(/(\[[^\]]*\])([^\(]|\z)/, '
|
56
|
+
# text.gsub(/(\[[^\]]*\])([^\(]|\z)/, '!!!^\1^!!!\2')
|
57
|
+
text.gsub('[', '!!!!b').gsub(']', 'e!!!!')
|
57
58
|
end
|
58
59
|
|
59
60
|
# @param text [String]
|
60
61
|
# @return [String]
|
61
62
|
def unescape_brackets text
|
62
|
-
text.gsub('
|
63
|
+
text.gsub('!!!!b', '[').gsub('e!!!!', ']')
|
63
64
|
end
|
64
65
|
end
|
65
66
|
|
@@ -6,6 +6,12 @@ module Solargraph
|
|
6
6
|
class Method < Pin::Method
|
7
7
|
include YardMixin
|
8
8
|
|
9
|
+
# @param code_object [YARD::CodeObjects::Base]
|
10
|
+
# @param name [String, nil]
|
11
|
+
# @param scope [Symbol, nil]
|
12
|
+
# @param visibility [Symbol, nil]
|
13
|
+
# @param closure [Solargraph::Pin::Closure, nil]
|
14
|
+
# @param spec [Gem::Specification]
|
9
15
|
def initialize code_object, name = nil, scope = nil, visibility = nil, closure = nil, spec = nil
|
10
16
|
closure ||= Solargraph::Pin::Namespace.new(
|
11
17
|
name: code_object.namespace.to_s,
|
@@ -25,9 +31,14 @@ module Solargraph
|
|
25
31
|
|
26
32
|
private
|
27
33
|
|
34
|
+
# @param code_object [YARD::CodeObjects::Base]
|
35
|
+
# @return [Array<Solargraph::Pin::Parameter>]
|
28
36
|
def get_parameters code_object
|
29
37
|
return [] unless code_object.is_a?(YARD::CodeObjects::MethodObject)
|
30
|
-
|
38
|
+
# HACK: Skip `nil` and `self` parameters that are sometimes emitted
|
39
|
+
# for methods defined in C
|
40
|
+
# See https://github.com/castwide/solargraph/issues/345
|
41
|
+
code_object.parameters.select { |a| a[0] && a[0] != 'self' }.map do |a|
|
31
42
|
Solargraph::Pin::Parameter.new(
|
32
43
|
location: location,
|
33
44
|
closure: self,
|
@@ -40,10 +51,14 @@ module Solargraph
|
|
40
51
|
end
|
41
52
|
end
|
42
53
|
|
54
|
+
# @param a [Array]
|
55
|
+
# @return [String]
|
43
56
|
def arg_name a
|
44
57
|
a[0].match(/[A-Za-z0-9_]*/)[0]
|
45
58
|
end
|
46
59
|
|
60
|
+
# @param a [Array]
|
61
|
+
# @return [Symbol]
|
47
62
|
def arg_type a
|
48
63
|
if a[0].start_with?('**')
|
49
64
|
:kwrestarg
|
@@ -4,16 +4,10 @@ module Solargraph
|
|
4
4
|
module Pin
|
5
5
|
module YardPin
|
6
6
|
module YardMixin
|
7
|
-
attr_reader :code_object
|
8
|
-
|
9
|
-
attr_reader :spec
|
10
|
-
|
11
|
-
attr_reader :location
|
12
|
-
|
13
|
-
@@gate_cache ||= {}
|
14
|
-
|
15
7
|
private
|
16
8
|
|
9
|
+
# @param code_object [YARD::CodeObjects::Base]
|
10
|
+
# @param spec [Gem::Specification]
|
17
11
|
# @return [Solargraph::Location, nil]
|
18
12
|
def object_location code_object, spec
|
19
13
|
return nil if spec.nil? || code_object.nil? || code_object.file.nil? || code_object.line.nil?
|
@@ -18,166 +18,12 @@ module Solargraph
|
|
18
18
|
super(word, [], with_block)
|
19
19
|
end
|
20
20
|
|
21
|
-
def with_block?
|
22
|
-
@with_block
|
23
|
-
end
|
24
|
-
|
25
21
|
# @param api_map [ApiMap]
|
26
22
|
# @param name_pin [Pin::Base]
|
27
23
|
# @param locals [Array<Pin::Base>]
|
28
24
|
def resolve api_map, name_pin, locals
|
29
25
|
return super_pins(api_map, name_pin)
|
30
26
|
end
|
31
|
-
|
32
|
-
private
|
33
|
-
|
34
|
-
# @param pins [Array<Pin::Base>]
|
35
|
-
# @param api_map [ApiMap]
|
36
|
-
# @param context [ComplexType]
|
37
|
-
# @param locals [Pin::LocalVariable]
|
38
|
-
# @return [Array<Pin::Base>]
|
39
|
-
def inferred_pins pins, api_map, context, locals
|
40
|
-
result = pins.map do |p|
|
41
|
-
overloads = p.docstring.tags(:overload)
|
42
|
-
# next p if overloads.empty?
|
43
|
-
type = ComplexType::UNDEFINED
|
44
|
-
# @param [YARD::Tags::OverloadTag]
|
45
|
-
overloads.each do |ol|
|
46
|
-
next unless arguments_match(arguments, ol.parameters)
|
47
|
-
next if ol.parameters.last && ol.parameters.last.first.start_with?('&') && ol.parameters.last.last.nil? && !with_block?
|
48
|
-
match = true
|
49
|
-
arguments.each_with_index do |arg, idx|
|
50
|
-
achain = arguments[idx]
|
51
|
-
next if achain.nil?
|
52
|
-
param = ol.parameters[idx]
|
53
|
-
if param.nil?
|
54
|
-
match = false unless ol.parameters.last && ol.parameters.last.first.start_with?('*')
|
55
|
-
break
|
56
|
-
end
|
57
|
-
par = ol.tags(:param).select { |pp| pp.name == param.first }.first
|
58
|
-
next if par.nil? || par.types.nil? || par.types.empty?
|
59
|
-
atype = achain.infer(api_map, Pin::ProxyType.anonymous(context), locals)
|
60
|
-
other = ComplexType.try_parse(*par.types)
|
61
|
-
# @todo Weak type comparison
|
62
|
-
unless atype.tag == other.tag || api_map.super_and_sub?(other.tag, atype.tag)
|
63
|
-
match = false
|
64
|
-
break
|
65
|
-
end
|
66
|
-
end
|
67
|
-
if match
|
68
|
-
type = extra_return_type(ol, context)
|
69
|
-
type = ComplexType.try_parse(*ol.tag(:return).types).self_to(context.to_s).qualify(api_map, context.namespace) if ol.has_tag?(:return) && ol.tag(:return).types && !ol.tag(:return).types.empty? && (type.nil? || type.undefined?)
|
70
|
-
type ||= ComplexType::UNDEFINED
|
71
|
-
end
|
72
|
-
break if type.defined?
|
73
|
-
end
|
74
|
-
next p.proxy(type) if type.defined?
|
75
|
-
type = extra_return_type(p.docstring, context)
|
76
|
-
if type
|
77
|
-
next Solargraph::Pin::Method.new(
|
78
|
-
location: p.location,
|
79
|
-
closure: p.closure,
|
80
|
-
name: p.name,
|
81
|
-
comments: "@return [#{context.subtypes.first.to_s}]",
|
82
|
-
scope: p.scope,
|
83
|
-
visibility: p.visibility,
|
84
|
-
parameters: p.parameters,
|
85
|
-
node: p.node
|
86
|
-
)
|
87
|
-
end
|
88
|
-
if p.is_a?(Pin::Method) && !p.macros.empty?
|
89
|
-
result = process_macro(p, api_map, context, locals)
|
90
|
-
next result unless result.return_type.undefined?
|
91
|
-
elsif !p.directives.empty?
|
92
|
-
result = process_directive(p, api_map, context, locals)
|
93
|
-
next result unless result.return_type.undefined?
|
94
|
-
end
|
95
|
-
p
|
96
|
-
end
|
97
|
-
result.map do |pin|
|
98
|
-
next pin if pin.return_type.undefined?
|
99
|
-
selfy = pin.return_type.self_to(context.tag)
|
100
|
-
selfy == pin.return_type ? pin : pin.proxy(selfy)
|
101
|
-
end
|
102
|
-
end
|
103
|
-
|
104
|
-
# @param pin [Pin::Method]
|
105
|
-
# @param api_map [ApiMap]
|
106
|
-
# @param context [ComplexType]
|
107
|
-
# @param locals [Pin::Base]
|
108
|
-
# @return [Pin::Base]
|
109
|
-
def process_macro pin, api_map, context, locals
|
110
|
-
pin.macros.each do |macro|
|
111
|
-
result = inner_process_macro(pin, macro, api_map, context, locals)
|
112
|
-
return result unless result.return_type.undefined?
|
113
|
-
end
|
114
|
-
Pin::ProxyType.anonymous(ComplexType::UNDEFINED)
|
115
|
-
end
|
116
|
-
|
117
|
-
# @param pin [Pin::Method]
|
118
|
-
# @param api_map [ApiMap]
|
119
|
-
# @param context [ComplexType]
|
120
|
-
# @param locals [Pin::Base]
|
121
|
-
# @return [Pin::ProxyType]
|
122
|
-
def process_directive pin, api_map, context, locals
|
123
|
-
pin.directives.each do |dir|
|
124
|
-
macro = api_map.named_macro(dir.tag.name)
|
125
|
-
next if macro.nil?
|
126
|
-
result = inner_process_macro(pin, macro, api_map, context, locals)
|
127
|
-
return result unless result.return_type.undefined?
|
128
|
-
end
|
129
|
-
Pin::ProxyType.anonymous ComplexType::UNDEFINED
|
130
|
-
end
|
131
|
-
|
132
|
-
# @param pin [Pin]
|
133
|
-
# @param macro [YARD::Tags::MacroDirective]
|
134
|
-
# @param api_map [ApiMap]
|
135
|
-
# @param context [ComplexType]
|
136
|
-
# @param locals [Array<Pin::Base>]
|
137
|
-
# @return [Pin::ProxyType]
|
138
|
-
def inner_process_macro pin, macro, api_map, context, locals
|
139
|
-
vals = arguments.map{ |c| Pin::ProxyType.anonymous(c.infer(api_map, pin, locals)) }
|
140
|
-
txt = macro.tag.text.clone
|
141
|
-
if txt.empty? && macro.tag.name
|
142
|
-
named = api_map.named_macro(macro.tag.name)
|
143
|
-
txt = named.tag.text.clone if named
|
144
|
-
end
|
145
|
-
i = 1
|
146
|
-
vals.each do |v|
|
147
|
-
txt.gsub!(/\$#{i}/, v.context.namespace)
|
148
|
-
i += 1
|
149
|
-
end
|
150
|
-
docstring = Solargraph::Source.parse_docstring(txt).to_docstring
|
151
|
-
tag = docstring.tag(:return)
|
152
|
-
unless tag.nil? || tag.types.nil?
|
153
|
-
return Pin::ProxyType.anonymous(ComplexType.try_parse(*tag.types))
|
154
|
-
end
|
155
|
-
Pin::ProxyType.anonymous(ComplexType::UNDEFINED)
|
156
|
-
end
|
157
|
-
|
158
|
-
# @param docstring [YARD::Docstring]
|
159
|
-
# @param context [ComplexType]
|
160
|
-
# @return [ComplexType]
|
161
|
-
def extra_return_type docstring, context
|
162
|
-
if docstring.has_tag?(:return_single_parameter) && context.subtypes.one?
|
163
|
-
return context.subtypes.first
|
164
|
-
elsif docstring.has_tag?(:return_value_parameter) && context.value_types.one?
|
165
|
-
return context.value_types.first
|
166
|
-
end
|
167
|
-
nil
|
168
|
-
end
|
169
|
-
|
170
|
-
# @param arguments [Array<Chain>]
|
171
|
-
# @param parameters [Array<String>]
|
172
|
-
# @return [Boolean]
|
173
|
-
def arguments_match arguments, parameters
|
174
|
-
argcount = arguments.length
|
175
|
-
# argcount -= 1 if !arguments.empty? && arguments.last.links.first.word.start_with?('&')
|
176
|
-
parcount = parameters.length
|
177
|
-
parcount -= 1 if !parameters.empty? && parameters.last.first.start_with?('&')
|
178
|
-
return false if argcount < parcount && !(argcount == parcount - 1 && parameters.last.first.start_with?('*'))
|
179
|
-
true
|
180
|
-
end
|
181
27
|
end
|
182
28
|
end
|
183
29
|
end
|
@@ -76,6 +76,7 @@ module Solargraph
|
|
76
76
|
# @param query [String]
|
77
77
|
# @return [Array<Pin::Base>]
|
78
78
|
def query_symbols query
|
79
|
+
return document_symbols if query && query.empty?
|
79
80
|
document_symbols.select{ |pin| fuzzy_string_match(pin.path, query) || fuzzy_string_match(pin.name, query) }
|
80
81
|
end
|
81
82
|
|
@@ -25,51 +25,12 @@ module Solargraph
|
|
25
25
|
def complete
|
26
26
|
return package_completions([]) if !source_map.source.parsed? || cursor.string?
|
27
27
|
return package_completions(api_map.get_symbols) if cursor.chain.literal? && cursor.chain.links.last.word == '<Symbol>'
|
28
|
-
return Completion.new([], cursor.range) if cursor.chain.literal?
|
29
|
-
|
30
|
-
|
31
|
-
if cursor.chain.constant? || cursor.start_of_constant?
|
32
|
-
full = cursor.chain.links.first.word
|
33
|
-
type = if cursor.chain.undefined?
|
34
|
-
cursor.chain.base.infer(api_map, context_pin, locals)
|
35
|
-
else
|
36
|
-
if full.include?('::') && cursor.chain.links.length == 1
|
37
|
-
ComplexType.try_parse(full.split('::')[0..-2].join('::'))
|
38
|
-
elsif cursor.chain.links.length > 1
|
39
|
-
ComplexType.try_parse(full)
|
40
|
-
else
|
41
|
-
ComplexType::UNDEFINED
|
42
|
-
end
|
43
|
-
end
|
44
|
-
if type.undefined?
|
45
|
-
if full.include?('::')
|
46
|
-
result.concat api_map.get_constants(full, *gates)
|
47
|
-
else
|
48
|
-
result.concat api_map.get_constants('', cursor.start_of_constant? ? '' : context_pin.full_context.namespace, *gates) #.select { |pin| pin.name.start_with?(full) }
|
49
|
-
end
|
50
|
-
else
|
51
|
-
result.concat api_map.get_constants(type.namespace, cursor.start_of_constant? ? '' : context_pin.full_context.namespace, *gates)
|
52
|
-
end
|
28
|
+
return Completion.new([], cursor.range) if cursor.chain.literal?
|
29
|
+
if cursor.comment?
|
30
|
+
tag_complete
|
53
31
|
else
|
54
|
-
|
55
|
-
result.concat api_map.get_complex_type_methods(type, block.binder.namespace, cursor.chain.links.length == 1)
|
56
|
-
if cursor.chain.links.length == 1
|
57
|
-
if cursor.word.start_with?('@@')
|
58
|
-
return package_completions(api_map.get_class_variable_pins(context_pin.full_context.namespace))
|
59
|
-
elsif cursor.word.start_with?('@')
|
60
|
-
return package_completions(api_map.get_instance_variable_pins(block.binder.namespace, block.binder.scope))
|
61
|
-
elsif cursor.word.start_with?('$')
|
62
|
-
return package_completions(api_map.get_global_variable_pins)
|
63
|
-
end
|
64
|
-
result.concat locals
|
65
|
-
result.concat api_map.get_constants(context_pin.context.namespace, *gates)
|
66
|
-
result.concat api_map.get_methods(block.binder.namespace, scope: block.binder.scope, visibility: [:public, :private, :protected])
|
67
|
-
result.concat api_map.get_methods('Kernel')
|
68
|
-
result.concat ApiMap.keywords
|
69
|
-
result.concat yielded_self_pins
|
70
|
-
end
|
32
|
+
code_complete
|
71
33
|
end
|
72
|
-
package_completions(result)
|
73
34
|
end
|
74
35
|
|
75
36
|
# @return [Array<Pin::Base>]
|
@@ -111,6 +72,13 @@ module Solargraph
|
|
111
72
|
end
|
112
73
|
end
|
113
74
|
|
75
|
+
# @param phrase [String]
|
76
|
+
# @return [Array<Solargraph::Pin::Base>]
|
77
|
+
def translate phrase
|
78
|
+
chain = Parser.chain(Parser.parse(phrase))
|
79
|
+
chain.define(api_map, block, locals)
|
80
|
+
end
|
81
|
+
|
114
82
|
private
|
115
83
|
|
116
84
|
# @return [ApiMap]
|
@@ -185,6 +153,71 @@ module Solargraph
|
|
185
153
|
}
|
186
154
|
Completion.new(filtered, cursor.range)
|
187
155
|
end
|
156
|
+
|
157
|
+
def tag_complete
|
158
|
+
result = []
|
159
|
+
match = source_map.code[0..cursor.offset-1].match(/[\[<, ]([a-z0-9_:]*)\z/i)
|
160
|
+
if match
|
161
|
+
full = match[1]
|
162
|
+
if full.include?('::')
|
163
|
+
if full.end_with?('::')
|
164
|
+
result.concat api_map.get_constants(full[0..-3], *gates)
|
165
|
+
else
|
166
|
+
result.concat api_map.get_constants(full.split('::')[0..-2].join('::'), *gates)
|
167
|
+
end
|
168
|
+
else
|
169
|
+
result.concat api_map.get_constants('', full.end_with?('::') ? '' : context_pin.full_context.namespace, *gates) #.select { |pin| pin.name.start_with?(full) }
|
170
|
+
end
|
171
|
+
end
|
172
|
+
package_completions(result)
|
173
|
+
end
|
174
|
+
|
175
|
+
def code_complete
|
176
|
+
result = []
|
177
|
+
result.concat complete_keyword_parameters
|
178
|
+
if cursor.chain.constant? || cursor.start_of_constant?
|
179
|
+
full = cursor.chain.links.first.word
|
180
|
+
type = if cursor.chain.undefined?
|
181
|
+
cursor.chain.base.infer(api_map, context_pin, locals)
|
182
|
+
else
|
183
|
+
if full.include?('::') && cursor.chain.links.length == 1
|
184
|
+
ComplexType.try_parse(full.split('::')[0..-2].join('::'))
|
185
|
+
elsif cursor.chain.links.length > 1
|
186
|
+
ComplexType.try_parse(full)
|
187
|
+
else
|
188
|
+
ComplexType::UNDEFINED
|
189
|
+
end
|
190
|
+
end
|
191
|
+
if type.undefined?
|
192
|
+
if full.include?('::')
|
193
|
+
result.concat api_map.get_constants(full, *gates)
|
194
|
+
else
|
195
|
+
result.concat api_map.get_constants('', cursor.start_of_constant? ? '' : context_pin.full_context.namespace, *gates) #.select { |pin| pin.name.start_with?(full) }
|
196
|
+
end
|
197
|
+
else
|
198
|
+
result.concat api_map.get_constants(type.namespace, cursor.start_of_constant? ? '' : context_pin.full_context.namespace, *gates)
|
199
|
+
end
|
200
|
+
else
|
201
|
+
type = cursor.chain.base.infer(api_map, block, locals)
|
202
|
+
result.concat api_map.get_complex_type_methods(type, block.binder.namespace, cursor.chain.links.length == 1)
|
203
|
+
if cursor.chain.links.length == 1
|
204
|
+
if cursor.word.start_with?('@@')
|
205
|
+
return package_completions(api_map.get_class_variable_pins(context_pin.full_context.namespace))
|
206
|
+
elsif cursor.word.start_with?('@')
|
207
|
+
return package_completions(api_map.get_instance_variable_pins(block.binder.namespace, block.binder.scope))
|
208
|
+
elsif cursor.word.start_with?('$')
|
209
|
+
return package_completions(api_map.get_global_variable_pins)
|
210
|
+
end
|
211
|
+
result.concat locals
|
212
|
+
result.concat api_map.get_constants(context_pin.context.namespace, *gates)
|
213
|
+
result.concat api_map.get_methods(block.binder.namespace, scope: block.binder.scope, visibility: [:public, :private, :protected])
|
214
|
+
result.concat api_map.get_methods('Kernel')
|
215
|
+
result.concat ApiMap.keywords
|
216
|
+
result.concat yielded_self_pins
|
217
|
+
end
|
218
|
+
end
|
219
|
+
package_completions(result)
|
220
|
+
end
|
188
221
|
end
|
189
222
|
end
|
190
223
|
end
|
@@ -95,6 +95,7 @@ module Solargraph
|
|
95
95
|
# @param source_position [Position]
|
96
96
|
# @param comment_position [Position]
|
97
97
|
# @param directive [YARD::Tags::Directive]
|
98
|
+
# @return [void]
|
98
99
|
def process_directive source_position, comment_position, directive
|
99
100
|
docstring = Solargraph::Source.parse_docstring(directive.tag.text).to_docstring
|
100
101
|
location = Location.new(@filename, Range.new(comment_position, comment_position))
|
@@ -104,10 +105,10 @@ module Solargraph
|
|
104
105
|
if namespace.location.range.start.line < comment_position.line
|
105
106
|
namespace = closure_at(comment_position)
|
106
107
|
end
|
107
|
-
region = Parser::Region.new(source: @source, closure: namespace)
|
108
108
|
begin
|
109
|
-
|
110
|
-
|
109
|
+
src = Solargraph::Source.load_string("def #{directive.tag.name};end", @source.filename)
|
110
|
+
region = Parser::Region.new(source: src, closure: namespace)
|
111
|
+
gen_pin = Parser.process_node(src.node, region).first.last
|
111
112
|
return if gen_pin.nil?
|
112
113
|
# Move the location to the end of the line so it gets recognized
|
113
114
|
# as originating from a comment
|
@@ -148,12 +149,23 @@ module Solargraph
|
|
148
149
|
)
|
149
150
|
end
|
150
151
|
when 'parse'
|
151
|
-
ns = closure_at(source_position)
|
152
|
-
region = Parser::Region.new(source: @source, closure: ns)
|
153
152
|
begin
|
154
|
-
|
153
|
+
ns = closure_at(source_position)
|
154
|
+
src = Solargraph::Source.load_string(directive.tag.text, @source.filename)
|
155
|
+
region = Parser::Region.new(source: src, closure: ns)
|
155
156
|
# @todo These pins may need to be marked not explicit
|
156
|
-
|
157
|
+
index = @pins.length
|
158
|
+
loff = if @code.lines[comment_position.line].strip.end_with?('@!parse')
|
159
|
+
comment_position.line + 1
|
160
|
+
else
|
161
|
+
comment_position.line
|
162
|
+
end
|
163
|
+
Parser.process_node(src.node, region, @pins)
|
164
|
+
@pins[index..-1].each do |p|
|
165
|
+
# @todo Smelly instance variable access
|
166
|
+
p.location.range.start.instance_variable_set(:@line, p.location.range.start.line + loff)
|
167
|
+
p.location.range.ending.instance_variable_set(:@line, p.location.range.ending.line + loff)
|
168
|
+
end
|
157
169
|
rescue Parser::SyntaxError => e
|
158
170
|
# @todo Handle parser errors in !parse directives
|
159
171
|
end
|
@@ -190,7 +202,7 @@ module Solargraph
|
|
190
202
|
code_lines = @code.lines
|
191
203
|
@source.associated_comments.each do |line, comments|
|
192
204
|
src_pos = line ? Position.new(line, code_lines[line].to_s.chomp.index(/[^\s]/) || 0) : Position.new(code_lines.length, 0)
|
193
|
-
com_pos = Position.new(line -
|
205
|
+
com_pos = Position.new(line + 1 - comments.lines.length, 0)
|
194
206
|
process_comment(src_pos, com_pos, comments)
|
195
207
|
end
|
196
208
|
end
|
data/lib/solargraph/version.rb
CHANGED
@@ -15,23 +15,23 @@ module Solargraph
|
|
15
15
|
# @return [void]
|
16
16
|
def self.run spec, cache_dir: nil
|
17
17
|
Dir.mktmpdir do |tmpdir|
|
18
|
-
rdir = File.join(tmpdir, '
|
19
|
-
Dir.
|
18
|
+
rdir = File.join(tmpdir, 'sg_tmp_rdoc')
|
19
|
+
FileUtils.cp_r Dir.glob(File.join(spec.full_gem_path, '*')), tmpdir
|
20
|
+
Dir.chdir tmpdir do
|
20
21
|
pins = []
|
21
22
|
pins.push Solargraph::Pin::ROOT_PIN
|
22
23
|
name_hash = {}
|
23
24
|
|
24
|
-
argv = ['-q', '-
|
25
|
+
argv = ['-q', '-r', '-N', '-o', rdir]
|
25
26
|
spec.load_paths.each do |path|
|
26
27
|
argv.concat ['-i', path]
|
27
28
|
end
|
28
29
|
rdoc = RDoc::RDoc.new
|
29
30
|
rdoc.document argv
|
30
|
-
|
31
|
-
store =
|
32
|
-
store.
|
31
|
+
# @type [RDoc::Store]
|
32
|
+
store = rdoc.store
|
33
|
+
store.path = rdir
|
33
34
|
store.cache[:modules].each do |mod|
|
34
|
-
# store.load_class(mod)
|
35
35
|
# @type [RDoc::NormalClass]
|
36
36
|
mod = store.find_class_or_module(mod)
|
37
37
|
closure = pins.select { |pin| pin.path == mod.full_name.split('::')[0..-2].join('::') }.first || pins.first
|
@@ -51,7 +51,7 @@ module Solargraph
|
|
51
51
|
closure: namepin
|
52
52
|
)
|
53
53
|
end
|
54
|
-
# @param
|
54
|
+
# @param ext [RDoc::Extend]
|
55
55
|
mod.extends.each do |ext|
|
56
56
|
pins.push Solargraph::Pin::Reference::Extend.new(
|
57
57
|
location: locate(ext),
|
@@ -105,7 +105,11 @@ module Solargraph
|
|
105
105
|
mod.full_name.split('::')[0..-2].join('::')
|
106
106
|
end
|
107
107
|
|
108
|
+
# @param cmnt [RDoc::Comment]
|
109
|
+
# @return [String]
|
108
110
|
def self.commentary cmnt
|
111
|
+
return cmnt if cmnt.is_a?(String)
|
112
|
+
return cmnt.text if cmnt.is_a?(RDoc::Comment)
|
109
113
|
result = []
|
110
114
|
cmnt.parts.each do |part|
|
111
115
|
result.push RDoc::Markup::ToHtml.new({}).to_html(part.text) if part.respond_to?(:text)
|
@@ -126,9 +130,9 @@ module Solargraph
|
|
126
130
|
|
127
131
|
def self.find_file obj
|
128
132
|
if obj.respond_to?(:in_files) && !obj.in_files.empty?
|
129
|
-
[obj.in_files.first.to_s.sub(/^file /, ''), obj.
|
133
|
+
[obj.in_files.first.to_s.sub(/^file /, ''), obj.line]
|
130
134
|
else
|
131
|
-
[obj.
|
135
|
+
[obj.file, obj.line]
|
132
136
|
end
|
133
137
|
end
|
134
138
|
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.39.
|
4
|
+
version: 0.39.13
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Fred Snyder
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-05
|
11
|
+
date: 2020-08-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: backport
|