solargraph 0.31.1 → 0.31.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/solargraph/api_map.rb +9 -4
- data/lib/solargraph/complex_type/type_methods.rb +8 -3
- data/lib/solargraph/complex_type/unique_type.rb +8 -2
- data/lib/solargraph/language_server/host.rb +17 -27
- data/lib/solargraph/language_server/host/dispatch.rb +4 -2
- data/lib/solargraph/library.rb +2 -2
- data/lib/solargraph/pin/base.rb +25 -0
- data/lib/solargraph/pin/block_parameter.rb +2 -1
- data/lib/solargraph/source.rb +16 -16
- data/lib/solargraph/source/chain/call.rb +1 -1
- data/lib/solargraph/source_map.rb +3 -3
- data/lib/solargraph/source_map/clip.rb +21 -0
- data/lib/solargraph/source_map/mapper.rb +9 -24
- data/lib/solargraph/version.rb +1 -1
- data/lib/yard-solargraph.rb +2 -0
- 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: ad024bb9d47484f46c548f061033e61bae31c8108f8c22a1910d6ec9daebc172
|
4
|
+
data.tar.gz: 18235c0ac8d50fcf1cbce67e8545d9f92e5c7363c9b7a9b22ce6894afbc0b4ee
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d3479bfd3f3ac8e55ac40f9edbd304e7ade94618c316327cdca6bc3f06dcded61e6cec6d8f4388052e436aa96abe95c46db3572bd09bf9296ea3821a4f0192fc
|
7
|
+
data.tar.gz: 3c49842db66464930b789325e10dac77b9fa35131a44b587a32ac8d3293b99ce89a498d716693663dd2c511be254dffe8316168bd824a301b5b4fd0bea7d5bf5
|
data/lib/solargraph/api_map.rb
CHANGED
@@ -429,10 +429,10 @@ module Solargraph
|
|
429
429
|
end
|
430
430
|
|
431
431
|
# @param location [Solargraph::Location]
|
432
|
-
# @return [Solargraph::Pin::Base]
|
433
|
-
def
|
434
|
-
return
|
435
|
-
source_map_hash[location.filename].
|
432
|
+
# @return [Array<Solargraph::Pin::Base>]
|
433
|
+
def locate_pins location
|
434
|
+
return [] if location.nil? || !source_map_hash.has_key?(location.filename)
|
435
|
+
source_map_hash[location.filename].locate_pins(location)
|
436
436
|
end
|
437
437
|
|
438
438
|
# @raise [FileNotFoundError] if the cursor's file is not in the ApiMap
|
@@ -587,6 +587,11 @@ module Solargraph
|
|
587
587
|
while roots.length > 0
|
588
588
|
fqns = roots.join('::') + '::' + name
|
589
589
|
return fqns if store.namespace_exists?(fqns)
|
590
|
+
incs = store.get_includes(roots.join('::'))
|
591
|
+
incs.each do |inc|
|
592
|
+
foundinc = inner_qualify(name, inc, skip)
|
593
|
+
return foundinc unless foundinc.nil?
|
594
|
+
end
|
590
595
|
roots.pop
|
591
596
|
end
|
592
597
|
return name if store.namespace_exists?(name)
|
@@ -85,19 +85,24 @@ module Solargraph
|
|
85
85
|
tag == other.tag
|
86
86
|
end
|
87
87
|
|
88
|
+
def rooted?
|
89
|
+
@rooted
|
90
|
+
end
|
91
|
+
|
88
92
|
# Generate a ComplexType that fully qualifies this type's namespaces.
|
89
93
|
#
|
90
94
|
# @param api_map [ApiMap] The ApiMap that performs qualification
|
91
95
|
# @param context [String] The namespace from which to resolve names
|
92
96
|
# @return [ComplexType] The generated ComplexType
|
93
97
|
def qualify api_map, context = ''
|
94
|
-
return ComplexType.
|
95
|
-
|
96
|
-
|
98
|
+
return ComplexType.new([self]) if duck_type? || void? || undefined?
|
99
|
+
recon = (rooted? ? '' : context)
|
100
|
+
fqns = api_map.qualify(name, recon)
|
97
101
|
if fqns.nil?
|
98
102
|
return ComplexType.parse('Boolean') if tag == 'Boolean'
|
99
103
|
return ComplexType::UNDEFINED
|
100
104
|
end
|
105
|
+
fqns = "::#{fqns}" # Ensure the resulting complex type is rooted
|
101
106
|
ltypes = key_types.map do |t|
|
102
107
|
t.qualify api_map, context
|
103
108
|
end
|
@@ -14,9 +14,15 @@ module Solargraph
|
|
14
14
|
# @param name [String] The name of the type
|
15
15
|
# @param substring [String] The substring of the type
|
16
16
|
def initialize name, substring = ''
|
17
|
-
|
17
|
+
if name.start_with?('::')
|
18
|
+
@name = name[2..-1]
|
19
|
+
@rooted = true
|
20
|
+
else
|
21
|
+
@name = name
|
22
|
+
@rooted = false
|
23
|
+
end
|
18
24
|
@substring = substring
|
19
|
-
@tag = name + substring
|
25
|
+
@tag = @name + substring
|
20
26
|
@key_types = []
|
21
27
|
@subtypes = []
|
22
28
|
return unless parameters?
|
@@ -423,42 +423,32 @@ module Solargraph
|
|
423
423
|
@stopped
|
424
424
|
end
|
425
425
|
|
426
|
-
# Locate a pin based on the location of a completion item, or nil if the
|
427
|
-
# library does not have a source at that location.
|
428
|
-
#
|
429
|
-
# @param params [Hash] A hash representation of a completion item
|
430
|
-
# @return [Pin::Base, nil]
|
431
|
-
def locate_pin params
|
432
|
-
return nil unless params['data'] && params['data']['uri'] && params['data']['location']
|
433
|
-
library = library_for(params['data']['uri'])
|
434
|
-
location = Location.new(
|
435
|
-
params['data']['location']['filename'],
|
436
|
-
Range.from_to(
|
437
|
-
params['data']['location']['range']['start']['line'],
|
438
|
-
params['data']['location']['range']['start']['character'],
|
439
|
-
params['data']['location']['range']['end']['line'],
|
440
|
-
params['data']['location']['range']['end']['character']
|
441
|
-
)
|
442
|
-
)
|
443
|
-
library.locate_pin(location)
|
444
|
-
end
|
445
|
-
|
446
426
|
# Locate multiple pins that match a completion item. The first match is
|
447
|
-
# based on the corresponding location in a library source if available
|
448
|
-
#
|
427
|
+
# based on the corresponding location in a library source if available.
|
428
|
+
# Subsequent matches are based on path.
|
449
429
|
#
|
450
430
|
# @param params [Hash] A hash representation of a completion item
|
451
431
|
# @return [Array<Pin::Base>]
|
452
432
|
def locate_pins params
|
453
433
|
return [] unless params['data'] && params['data']['uri']
|
454
|
-
exact = locate_pin(params)
|
455
434
|
library = library_for(params['data']['uri'])
|
456
435
|
result = []
|
457
|
-
|
458
|
-
|
436
|
+
if params['data']['location']
|
437
|
+
location = Location.new(
|
438
|
+
params['data']['location']['filename'],
|
439
|
+
Range.from_to(
|
440
|
+
params['data']['location']['range']['start']['line'],
|
441
|
+
params['data']['location']['range']['start']['character'],
|
442
|
+
params['data']['location']['range']['end']['line'],
|
443
|
+
params['data']['location']['range']['end']['character']
|
444
|
+
)
|
445
|
+
)
|
446
|
+
result.concat library.locate_pins(location).select{ |pin| pin.name == params['label'] }
|
459
447
|
end
|
460
|
-
|
461
|
-
|
448
|
+
if params['data']['path']
|
449
|
+
result.concat library.path_pins(params['data']['path'])
|
450
|
+
end
|
451
|
+
result.uniq
|
462
452
|
end
|
463
453
|
|
464
454
|
# @param uri [String]
|
@@ -26,8 +26,10 @@ module Solargraph
|
|
26
26
|
def update_libraries src
|
27
27
|
# @todo This module should not call cataloger and diagnoser
|
28
28
|
libraries.each do |lib|
|
29
|
-
lib.
|
30
|
-
|
29
|
+
if lib.contain?(src.filename) || lib.open?(src.filename)
|
30
|
+
lib.merge src
|
31
|
+
cataloger.ping(lib)
|
32
|
+
end
|
31
33
|
end
|
32
34
|
diagnoser.schedule file_to_uri(src.filename) if src.synchronized?
|
33
35
|
end
|
data/lib/solargraph/library.rb
CHANGED
@@ -229,8 +229,8 @@ module Solargraph
|
|
229
229
|
#
|
230
230
|
# @param location [Location]
|
231
231
|
# @return [Solargraph::Pin::Base]
|
232
|
-
def
|
233
|
-
api_map.
|
232
|
+
def locate_pins location
|
233
|
+
api_map.locate_pins location
|
234
234
|
end
|
235
235
|
|
236
236
|
# Get an array of pins that match a path.
|
data/lib/solargraph/pin/base.rb
CHANGED
@@ -192,6 +192,31 @@ module Solargraph
|
|
192
192
|
true
|
193
193
|
end
|
194
194
|
|
195
|
+
def proxied?
|
196
|
+
@proxied ||= false
|
197
|
+
end
|
198
|
+
|
199
|
+
# Return a proxy for this pin with the specified return type. Other than
|
200
|
+
# the return type and the #proxied? setting, the proxy should be a clone
|
201
|
+
# of the original.
|
202
|
+
#
|
203
|
+
# @param return_type [ComplexType]
|
204
|
+
# @return [self]
|
205
|
+
def proxy return_type
|
206
|
+
result = dup
|
207
|
+
result.return_complex_type = return_type
|
208
|
+
result.proxied = true
|
209
|
+
result
|
210
|
+
end
|
211
|
+
|
212
|
+
protected
|
213
|
+
|
214
|
+
# @return [Boolean]
|
215
|
+
attr_writer :proxied
|
216
|
+
|
217
|
+
# @return [ComplexType]
|
218
|
+
attr_writer :return_complex_type
|
219
|
+
|
195
220
|
private
|
196
221
|
|
197
222
|
# @return [void]
|
@@ -71,6 +71,7 @@ module Solargraph
|
|
71
71
|
block
|
72
72
|
end
|
73
73
|
|
74
|
+
# @param api_map [ApiMap]
|
74
75
|
def typify api_map
|
75
76
|
# @todo Does anything need to be eliminated because it's more accurately a probe?
|
76
77
|
type = super
|
@@ -87,7 +88,7 @@ module Solargraph
|
|
87
88
|
else
|
88
89
|
yps = meth.docstring.tags(:yieldparam)
|
89
90
|
unless yps[index].nil? or yps[index].types.nil? or yps[index].types.empty?
|
90
|
-
return ComplexType.parse(yps[index].types
|
91
|
+
return ComplexType.parse(yps[index].types.first).qualify(api_map, meth.context.namespace)
|
91
92
|
end
|
92
93
|
end
|
93
94
|
end
|
data/lib/solargraph/source.rb
CHANGED
@@ -281,6 +281,22 @@ module Solargraph
|
|
281
281
|
@synchronized
|
282
282
|
end
|
283
283
|
|
284
|
+
# Get a hash of comments grouped by the line numbers of the associated code.
|
285
|
+
#
|
286
|
+
# @return [Hash{Integer => Array<Parser::Source::Comment>}]
|
287
|
+
def associated_comments
|
288
|
+
@associated_comments ||= begin
|
289
|
+
result = {}
|
290
|
+
Parser::Source::Comment.associate_locations(node, comments).each_pair do |loc, all|
|
291
|
+
block = all #.select{ |l| l.document? || code.lines[l.loc.line].strip.start_with?('#')}
|
292
|
+
next if block.empty?
|
293
|
+
result[loc.line] ||= []
|
294
|
+
result[loc.line].concat block
|
295
|
+
end
|
296
|
+
result
|
297
|
+
end
|
298
|
+
end
|
299
|
+
|
284
300
|
private
|
285
301
|
|
286
302
|
# @param top [Parser::AST::Node]
|
@@ -299,22 +315,6 @@ module Solargraph
|
|
299
315
|
end
|
300
316
|
end
|
301
317
|
|
302
|
-
# Get a hash of comments grouped by the line numbers of the associated code.
|
303
|
-
#
|
304
|
-
# @return [Hash{Integer => Array<Parser::Source::Comment>}]
|
305
|
-
def associated_comments
|
306
|
-
@associated_comments ||= begin
|
307
|
-
result = {}
|
308
|
-
Parser::Source::Comment.associate_locations(node, comments).each_pair do |loc, all|
|
309
|
-
block = all #.select{ |l| l.document? || code.lines[l.loc.line].strip.start_with?('#')}
|
310
|
-
next if block.empty?
|
311
|
-
result[loc.line] ||= []
|
312
|
-
result[loc.line].concat block
|
313
|
-
end
|
314
|
-
result
|
315
|
-
end
|
316
|
-
end
|
317
|
-
|
318
318
|
# Get a string representation of an array of comments.
|
319
319
|
#
|
320
320
|
# @param comments [Array<Parser::Source::Comment>]
|
@@ -84,10 +84,10 @@ module Solargraph
|
|
84
84
|
end
|
85
85
|
|
86
86
|
# @param location [Solargraph::Location]
|
87
|
-
# @return [Solargraph::Pin::Base]
|
88
|
-
def
|
87
|
+
# @return [Array<Solargraph::Pin::Base>]
|
88
|
+
def locate_pins location
|
89
89
|
# return nil unless location.start_with?("#{filename}:")
|
90
|
-
pins.select { |pin| pin.location == location }
|
90
|
+
pins.select { |pin| pin.location == location }
|
91
91
|
end
|
92
92
|
|
93
93
|
def locate_named_path_pin line, character
|
@@ -54,6 +54,7 @@ module Solargraph
|
|
54
54
|
result.concat api_map.get_methods(context_pin.context.namespace, scope: context_pin.context.scope, visibility: [:public, :private, :protected])
|
55
55
|
result.concat api_map.get_methods('Kernel')
|
56
56
|
result.concat ApiMap.keywords
|
57
|
+
result.concat yielded_self_pins
|
57
58
|
end
|
58
59
|
end
|
59
60
|
package_completions(result)
|
@@ -107,6 +108,26 @@ module Solargraph
|
|
107
108
|
@context_pin ||= source_map.locate_named_path_pin(cursor.node_position.line, cursor.node_position.character)
|
108
109
|
end
|
109
110
|
|
111
|
+
# @return [Array<Pin::Base>]
|
112
|
+
def yielded_self_pins
|
113
|
+
return [] unless block.is_a?(Pin::Block) && block.receiver
|
114
|
+
chain = Solargraph::Source::NodeChainer.chain(block.receiver, source_map.source.filename)
|
115
|
+
receiver_pin = chain.define(api_map, context_pin, locals).first
|
116
|
+
return [] if receiver_pin.nil?
|
117
|
+
result = []
|
118
|
+
ys = receiver_pin.docstring.tag(:yieldself)
|
119
|
+
unless ys.nil? || ys.types.empty?
|
120
|
+
ysct = ComplexType.parse(*ys.types).qualify(api_map, receiver_pin.context.namespace)
|
121
|
+
result.concat api_map.get_complex_type_methods(ysct, ysct.namespace, true)
|
122
|
+
end
|
123
|
+
ys = receiver_pin.docstring.tag(:yieldpublic)
|
124
|
+
unless ys.nil? || ys.types.empty?
|
125
|
+
ysct = ComplexType.parse(*ys.types).qualify(api_map, receiver_pin.context.namespace)
|
126
|
+
result.concat api_map.get_complex_type_methods(ysct, '', false)
|
127
|
+
end
|
128
|
+
result
|
129
|
+
end
|
130
|
+
|
110
131
|
# @param result [Array<Pin::Base>]
|
111
132
|
# @return [Completion]
|
112
133
|
def package_completions result
|
@@ -10,6 +10,8 @@ module Solargraph
|
|
10
10
|
|
11
11
|
private_class_method :new
|
12
12
|
|
13
|
+
MACRO_REGEXP = /(@\!method|@\!attribute|@\!domain|@\!macro|@\!parse)/.freeze
|
14
|
+
|
13
15
|
# Generate the data.
|
14
16
|
#
|
15
17
|
# @param source [Source]
|
@@ -58,7 +60,7 @@ module Solargraph
|
|
58
60
|
end
|
59
61
|
|
60
62
|
def process_comment position, comment
|
61
|
-
return unless comment =~
|
63
|
+
return unless comment =~ MACRO_REGEXP
|
62
64
|
cmnt = remove_inline_comment_hashes(comment)
|
63
65
|
parse = YARD::Docstring.parser.parse(cmnt)
|
64
66
|
parse.directives.each { |d| process_directive(position, d) }
|
@@ -121,30 +123,13 @@ module Solargraph
|
|
121
123
|
ctxt
|
122
124
|
end
|
123
125
|
|
126
|
+
# @return [void]
|
124
127
|
def process_comment_directives
|
125
|
-
return unless @code =~
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
if last_line.nil? || cmnt.loc.expression.line == last_line + 1
|
131
|
-
if cmnt.loc.expression.column.zero? || @code.lines[cmnt.loc.expression.line][0..cmnt.loc.expression.column-1].strip.empty?
|
132
|
-
current.push cmnt
|
133
|
-
else
|
134
|
-
# @todo Connected to a line of code. Handle separately
|
135
|
-
end
|
136
|
-
elsif !current.empty?
|
137
|
-
process_comment Position.new(current.last.loc.expression.line, current.last.loc.expression.column), current.map(&:text).join("\n")
|
138
|
-
current.clear
|
139
|
-
current.push cmnt
|
140
|
-
end
|
141
|
-
else
|
142
|
-
# @todo Handle block comments
|
143
|
-
end
|
144
|
-
last_line = cmnt.loc.expression.line
|
145
|
-
end
|
146
|
-
unless current.empty?
|
147
|
-
process_comment Position.new(current.last.loc.expression.line, current.last.loc.expression.column), current.map(&:text).join("\n")
|
128
|
+
return unless @code =~ MACRO_REGEXP
|
129
|
+
@source.associated_comments.each do |line, comments|
|
130
|
+
pos = Position.new(line, @code.lines[line].chomp.length)
|
131
|
+
txt = comments.map(&:text).join("\n")
|
132
|
+
process_comment(pos, txt)
|
148
133
|
end
|
149
134
|
end
|
150
135
|
end
|
data/lib/solargraph/version.rb
CHANGED
data/lib/yard-solargraph.rb
CHANGED
@@ -12,5 +12,7 @@ end
|
|
12
12
|
YARD::Tags::Library.define_tag("Type", :type, :with_types_and_name)
|
13
13
|
# Define a @yieldself tag for documenting block contexts
|
14
14
|
YARD::Tags::Library.define_tag("Yieldself", :yieldself, :with_types)
|
15
|
+
# Define a @yieldpublic tag for documenting block domains
|
16
|
+
YARD::Tags::Library.define_tag("Yieldpublic", :yieldpublic, :with_types)
|
15
17
|
# Define a @!domain directive for documenting DSLs
|
16
18
|
YARD::Tags::Library.define_directive("domain", :with_types, Solargraph::DomainDirective)
|
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.31.
|
4
|
+
version: 0.31.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Fred Snyder
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-01-
|
11
|
+
date: 2019-01-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: backport
|