solargraph 0.39.8 → 0.39.13
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/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
|