solargraph 0.55.4 → 0.56.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/.github/workflows/plugins.yml +2 -0
- data/.github/workflows/typecheck.yml +2 -0
- data/.gitignore +2 -0
- data/CHANGELOG.md +17 -0
- data/README.md +13 -3
- data/lib/solargraph/api_map/index.rb +23 -15
- data/lib/solargraph/api_map/store.rb +2 -1
- data/lib/solargraph/api_map.rb +53 -27
- data/lib/solargraph/complex_type/type_methods.rb +5 -1
- data/lib/solargraph/complex_type/unique_type.rb +7 -0
- data/lib/solargraph/convention/base.rb +3 -3
- data/lib/solargraph/convention.rb +3 -3
- data/lib/solargraph/doc_map.rb +200 -43
- data/lib/solargraph/gem_pins.rb +53 -38
- data/lib/solargraph/language_server/host.rb +9 -1
- data/lib/solargraph/language_server/message/extended/check_gem_version.rb +1 -0
- data/lib/solargraph/language_server/message/extended/document.rb +5 -2
- data/lib/solargraph/language_server/message/extended/document_gems.rb +3 -3
- data/lib/solargraph/library.rb +6 -3
- data/lib/solargraph/location.rb +13 -0
- data/lib/solargraph/parser/parser_gem/class_methods.rb +5 -8
- data/lib/solargraph/parser/parser_gem/node_processors/casgn_node.rb +2 -2
- data/lib/solargraph/parser/parser_gem/node_processors/namespace_node.rb +2 -2
- data/lib/solargraph/pin/base.rb +268 -24
- data/lib/solargraph/pin/base_variable.rb +9 -8
- data/lib/solargraph/pin/callable.rb +69 -0
- data/lib/solargraph/pin/closure.rb +12 -0
- data/lib/solargraph/pin/local_variable.rb +8 -5
- data/lib/solargraph/pin/method.rb +134 -17
- data/lib/solargraph/pin/parameter.rb +43 -6
- data/lib/solargraph/pin/signature.rb +38 -0
- data/lib/solargraph/pin_cache.rb +185 -0
- data/lib/solargraph/position.rb +9 -0
- data/lib/solargraph/range.rb +9 -0
- data/lib/solargraph/rbs_map/conversions.rb +19 -8
- data/lib/solargraph/rbs_map/core_map.rb +31 -9
- data/lib/solargraph/rbs_map/stdlib_map.rb +15 -5
- data/lib/solargraph/rbs_map.rb +74 -17
- data/lib/solargraph/shell.rb +16 -18
- data/lib/solargraph/source_map.rb +0 -17
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/views/_method.erb +10 -10
- data/lib/solargraph/views/_namespace.erb +3 -3
- data/lib/solargraph/views/document.erb +10 -10
- data/lib/solargraph/workspace.rb +15 -5
- data/lib/solargraph/yardoc.rb +6 -9
- data/lib/solargraph.rb +10 -12
- data/rbs_collection.yaml +19 -0
- data/solargraph.gemspec +1 -0
- metadata +19 -7
- data/lib/solargraph/cache.rb +0 -77
@@ -33,6 +33,70 @@ module Solargraph
|
|
33
33
|
@anon_splat = anon_splat
|
34
34
|
end
|
35
35
|
|
36
|
+
# @return [Array<Pin::Signature>]
|
37
|
+
def combine_all_signature_pins(*signature_pins)
|
38
|
+
by_arity = {}
|
39
|
+
signature_pins.each do |signature_pin|
|
40
|
+
by_arity[signature_pin.arity] ||= []
|
41
|
+
by_arity[signature_pin.arity] << signature_pin
|
42
|
+
end
|
43
|
+
by_arity.transform_values! do |same_arity_pins|
|
44
|
+
same_arity_pins.reduce(nil) do |memo, signature|
|
45
|
+
next signature if memo.nil?
|
46
|
+
memo.combine_with(signature)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
by_arity.values.flatten
|
50
|
+
end
|
51
|
+
|
52
|
+
# @param other [Pin::Method]
|
53
|
+
# @return [Symbol]
|
54
|
+
def combine_visibility(other)
|
55
|
+
if dodgy_visibility_source? && !other.dodgy_visibility_source?
|
56
|
+
other.visibility
|
57
|
+
elsif other.dodgy_visibility_source? && !dodgy_visibility_source?
|
58
|
+
visibility
|
59
|
+
else
|
60
|
+
assert_same(other, :visibility)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# @param other [Pin::Method]
|
65
|
+
# @return [Array<Pin::Signature>]
|
66
|
+
def combine_signatures(other)
|
67
|
+
all_undefined = signatures.all? { |sig| sig.return_type.undefined? }
|
68
|
+
other_all_undefined = other.signatures.all? { |sig| sig.return_type.undefined? }
|
69
|
+
if all_undefined && !other_all_undefined
|
70
|
+
other.signatures
|
71
|
+
elsif other_all_undefined && !all_undefined
|
72
|
+
signatures
|
73
|
+
else
|
74
|
+
combine_all_signature_pins(*signatures, *other.signatures)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def combine_with(other, attrs = {})
|
79
|
+
sigs = combine_signatures(other)
|
80
|
+
parameters = if sigs.length > 0
|
81
|
+
[].freeze
|
82
|
+
else
|
83
|
+
choose(other, :parameters).clone.freeze
|
84
|
+
end
|
85
|
+
new_attrs = {
|
86
|
+
visibility: combine_visibility(other),
|
87
|
+
explicit: explicit? || other.explicit?,
|
88
|
+
block: combine_blocks(other),
|
89
|
+
node: choose_node(other, :node),
|
90
|
+
attribute: prefer_rbs_location(other, :attribute?),
|
91
|
+
parameters: parameters,
|
92
|
+
signatures: sigs,
|
93
|
+
anon_splat: assert_same(other, :anon_splat?),
|
94
|
+
return_type: nil # pulled from signatures on first call
|
95
|
+
}.merge(attrs)
|
96
|
+
super(other, new_attrs)
|
97
|
+
end
|
98
|
+
|
99
|
+
# @param other [Pin::Method]
|
36
100
|
def == other
|
37
101
|
super && other.node == node
|
38
102
|
end
|
@@ -44,11 +108,24 @@ module Solargraph
|
|
44
108
|
sig.transform_types(&transform)
|
45
109
|
end
|
46
110
|
m.block = block&.transform_types(&transform)
|
47
|
-
m.
|
48
|
-
m.documentation = nil
|
111
|
+
m.reset_generated!
|
49
112
|
m
|
50
113
|
end
|
51
114
|
|
115
|
+
# @return [void]
|
116
|
+
def reset_generated!
|
117
|
+
super
|
118
|
+
unless signatures.empty?
|
119
|
+
return_type = nil
|
120
|
+
@block = :undefined
|
121
|
+
parameters = []
|
122
|
+
end
|
123
|
+
block&.reset_generated!
|
124
|
+
@signatures&.each(&:reset_generated!)
|
125
|
+
signature_help = nil
|
126
|
+
documentation = nil
|
127
|
+
end
|
128
|
+
|
52
129
|
def all_rooted?
|
53
130
|
super && parameters.all?(&:all_rooted?) && (!block || block&.all_rooted?) && signatures.all?(&:all_rooted?)
|
54
131
|
end
|
@@ -57,8 +134,7 @@ module Solargraph
|
|
57
134
|
# @return [Pin::Method]
|
58
135
|
def with_single_signature(signature)
|
59
136
|
m = proxy signature.return_type
|
60
|
-
m.
|
61
|
-
m.documentation = nil
|
137
|
+
m.reset_generated!
|
62
138
|
# @todo populating the single parameters/return_type/block
|
63
139
|
# arguments here seems to be needed for some specs to pass,
|
64
140
|
# even though we have a signature with the same information.
|
@@ -123,7 +199,7 @@ module Solargraph
|
|
123
199
|
)
|
124
200
|
end
|
125
201
|
yield_return_type = ComplexType.try_parse(*yieldreturn_tags.flat_map(&:types))
|
126
|
-
block = Signature.new(generics: generics, parameters: yield_parameters, return_type: yield_return_type, source: source)
|
202
|
+
block = Signature.new(generics: generics, parameters: yield_parameters, return_type: yield_return_type, source: source, closure: self)
|
127
203
|
end
|
128
204
|
signature = Signature.new(generics: generics, parameters: parameters, return_type: return_type, block: block, closure: self, source: source)
|
129
205
|
block.closure = signature if block
|
@@ -142,6 +218,14 @@ module Solargraph
|
|
142
218
|
end
|
143
219
|
end
|
144
220
|
|
221
|
+
# @param return_type [ComplexType]
|
222
|
+
# @return [self]
|
223
|
+
def proxy_with_signatures return_type
|
224
|
+
out = proxy return_type
|
225
|
+
out.signatures = out.signatures.map { |sig| sig.proxy return_type }
|
226
|
+
out
|
227
|
+
end
|
228
|
+
|
145
229
|
# @return [String, nil]
|
146
230
|
def detail
|
147
231
|
# This property is not cached in an instance variable because it can
|
@@ -193,12 +277,26 @@ module Solargraph
|
|
193
277
|
@path ||= "#{namespace}#{(scope == :instance ? '#' : '.')}#{name}"
|
194
278
|
end
|
195
279
|
|
280
|
+
# @return [String]
|
281
|
+
def method_name
|
282
|
+
name
|
283
|
+
end
|
284
|
+
|
196
285
|
def typify api_map
|
286
|
+
logger.debug { "Method#typify(self=#{self}, binder=#{binder}, closure=#{closure}, context=#{context.rooted_tags}, return_type=#{return_type.rooted_tags}) - starting" }
|
197
287
|
decl = super
|
198
|
-
|
288
|
+
unless decl.undefined?
|
289
|
+
logger.debug { "Method#typify(self=#{self}, binder=#{binder}, closure=#{closure}, context=#{context}) => #{decl.rooted_tags.inspect} - decl found" }
|
290
|
+
return decl
|
291
|
+
end
|
199
292
|
type = see_reference(api_map) || typify_from_super(api_map)
|
200
|
-
|
201
|
-
|
293
|
+
logger.debug { "Method#typify(self=#{self}) - type=#{type&.rooted_tags.inspect}" }
|
294
|
+
unless type.nil?
|
295
|
+
qualified = type.qualify(api_map, namespace)
|
296
|
+
logger.debug { "Method#typify(self=#{self}) => #{qualified.rooted_tags.inspect}" }
|
297
|
+
return qualified
|
298
|
+
end
|
299
|
+
super
|
202
300
|
end
|
203
301
|
|
204
302
|
# @sg-ignore
|
@@ -285,14 +383,6 @@ module Solargraph
|
|
285
383
|
attribute? ? infer_from_iv(api_map) : infer_from_return_nodes(api_map)
|
286
384
|
end
|
287
385
|
|
288
|
-
# @param pin [Pin::Method]
|
289
|
-
def try_merge! pin
|
290
|
-
return false unless super
|
291
|
-
@node = pin.node
|
292
|
-
@resolved_ref_tag = false
|
293
|
-
true
|
294
|
-
end
|
295
|
-
|
296
386
|
# @return [::Array<Pin::Method>]
|
297
387
|
def overloads
|
298
388
|
# Ignore overload tags with nil parameters. If it's not an array, the
|
@@ -313,6 +403,7 @@ module Solargraph
|
|
313
403
|
source: :overloads
|
314
404
|
)
|
315
405
|
end,
|
406
|
+
closure: self,
|
316
407
|
return_type: ComplexType.try_parse(*tag.docstring.tags(:return).flat_map(&:types)),
|
317
408
|
source: :overloads,
|
318
409
|
)
|
@@ -347,6 +438,12 @@ module Solargraph
|
|
347
438
|
self
|
348
439
|
end
|
349
440
|
|
441
|
+
# @param api_map [ApiMap]
|
442
|
+
# @return [Array<Pin::Method>]
|
443
|
+
def rest_of_stack api_map
|
444
|
+
api_map.get_method_stack(method_namespace, method_name, scope: scope).reject { |pin| pin.path == path }
|
445
|
+
end
|
446
|
+
|
350
447
|
protected
|
351
448
|
|
352
449
|
attr_writer :block
|
@@ -355,6 +452,21 @@ module Solargraph
|
|
355
452
|
|
356
453
|
attr_writer :documentation
|
357
454
|
|
455
|
+
def dodgy_visibility_source?
|
456
|
+
# as of 2025-03-12, the RBS generator used for
|
457
|
+
# e.g. activesupport did not understand 'private' markings
|
458
|
+
# inside 'class << self' blocks, but YARD did OK at it
|
459
|
+
source == :rbs && scope == :class && type_location&.filename&.include?('generated') && return_type.undefined? ||
|
460
|
+
# YARD's RBS generator seems to miss a lot of should-be protected instance methods
|
461
|
+
source == :rbs && scope == :instance && namespace.start_with?('YARD::') ||
|
462
|
+
# private on attr_readers seems to be broken in Prism's auto-generator script
|
463
|
+
source == :rbs && scope == :instance && namespace.start_with?('Prism::') ||
|
464
|
+
# The RBS for the RBS gem itself seems to use private as a
|
465
|
+
# 'is this a public API' concept, more aggressively than the
|
466
|
+
# actual code. Let's respect that and ignore the actual .rb file.
|
467
|
+
source == :yardoc && scope == :instance && namespace.start_with?('RBS::')
|
468
|
+
end
|
469
|
+
|
358
470
|
private
|
359
471
|
|
360
472
|
# @param name [String]
|
@@ -415,10 +527,15 @@ module Solargraph
|
|
415
527
|
resolve_reference match[1], api_map
|
416
528
|
end
|
417
529
|
|
530
|
+
# @return [String]
|
531
|
+
def method_namespace
|
532
|
+
namespace
|
533
|
+
end
|
534
|
+
|
418
535
|
# @param api_map [ApiMap]
|
419
536
|
# @return [ComplexType, nil]
|
420
537
|
def typify_from_super api_map
|
421
|
-
stack = api_map
|
538
|
+
stack = rest_of_stack api_map
|
422
539
|
return nil if stack.empty?
|
423
540
|
stack.each do |pin|
|
424
541
|
return pin.return_type unless pin.return_type.undefined?
|
@@ -21,6 +21,23 @@ module Solargraph
|
|
21
21
|
@decl = decl
|
22
22
|
end
|
23
23
|
|
24
|
+
def type_location
|
25
|
+
super || closure&.type_location
|
26
|
+
end
|
27
|
+
|
28
|
+
def location
|
29
|
+
super || closure&.type_location
|
30
|
+
end
|
31
|
+
|
32
|
+
def combine_with(other, attrs={})
|
33
|
+
new_attrs = {
|
34
|
+
decl: assert_same(other, :decl),
|
35
|
+
presence: choose(other, :presence),
|
36
|
+
asgn_code: choose(other, :asgn_code),
|
37
|
+
}.merge(attrs)
|
38
|
+
super(other, new_attrs)
|
39
|
+
end
|
40
|
+
|
24
41
|
def keyword?
|
25
42
|
[:kwarg, :kwoptarg].include?(decl)
|
26
43
|
end
|
@@ -29,6 +46,32 @@ module Solargraph
|
|
29
46
|
decl == :kwrestarg || (assignment && [:HASH, :hash].include?(assignment.type))
|
30
47
|
end
|
31
48
|
|
49
|
+
def needs_consistent_name?
|
50
|
+
keyword?
|
51
|
+
end
|
52
|
+
|
53
|
+
# @return [String]
|
54
|
+
def arity_decl
|
55
|
+
name = (self.name || '(anon)')
|
56
|
+
type = (return_type&.to_rbs || 'untyped')
|
57
|
+
case decl
|
58
|
+
when :arg
|
59
|
+
""
|
60
|
+
when :optarg
|
61
|
+
"?"
|
62
|
+
when :kwarg
|
63
|
+
"#{name}:"
|
64
|
+
when :kwoptarg
|
65
|
+
"?#{name}:"
|
66
|
+
when :restarg
|
67
|
+
"*"
|
68
|
+
when :kwrestarg
|
69
|
+
"**"
|
70
|
+
else
|
71
|
+
"(unknown decl: #{decl})"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
32
75
|
def arg?
|
33
76
|
decl == :arg
|
34
77
|
end
|
@@ -132,12 +175,6 @@ module Solargraph
|
|
132
175
|
tag.text
|
133
176
|
end
|
134
177
|
|
135
|
-
# @param pin [Pin::Parameter]
|
136
|
-
def try_merge! pin
|
137
|
-
return false unless super && closure == pin.closure
|
138
|
-
true
|
139
|
-
end
|
140
|
-
|
141
178
|
private
|
142
179
|
|
143
180
|
# @return [YARD::Tags::Tag, nil]
|
@@ -16,6 +16,44 @@ module Solargraph
|
|
16
16
|
def identity
|
17
17
|
@identity ||= "signature#{object_id}"
|
18
18
|
end
|
19
|
+
|
20
|
+
attr_writer :closure
|
21
|
+
|
22
|
+
def dodgy_return_type_source?
|
23
|
+
super || closure&.dodgy_return_type_source?
|
24
|
+
end
|
25
|
+
|
26
|
+
def type_location
|
27
|
+
super || closure&.type_location
|
28
|
+
end
|
29
|
+
|
30
|
+
def location
|
31
|
+
super || closure&.location
|
32
|
+
end
|
33
|
+
|
34
|
+
def typify api_map
|
35
|
+
if return_type.defined?
|
36
|
+
qualified = return_type.qualify(api_map, closure.namespace)
|
37
|
+
logger.debug { "Signature#typify(self=#{self}) => #{qualified.rooted_tags.inspect}" }
|
38
|
+
return qualified
|
39
|
+
end
|
40
|
+
return ComplexType::UNDEFINED if closure.nil?
|
41
|
+
return ComplexType::UNDEFINED unless closure.is_a?(Pin::Method)
|
42
|
+
method_stack = closure.rest_of_stack api_map
|
43
|
+
logger.debug { "Signature#typify(self=#{self}) - method_stack: #{method_stack}" }
|
44
|
+
method_stack.each do |pin|
|
45
|
+
sig = pin.signatures.find { |s| s.arity == self.arity }
|
46
|
+
next unless sig
|
47
|
+
unless sig.return_type.undefined?
|
48
|
+
qualified = sig.return_type.qualify(api_map, closure.namespace)
|
49
|
+
logger.debug { "Signature#typify(self=#{self}) => #{qualified.rooted_tags.inspect}" }
|
50
|
+
return qualified
|
51
|
+
end
|
52
|
+
end
|
53
|
+
out = super
|
54
|
+
logger.debug { "Signature#typify(self=#{self}) => #{out}" }
|
55
|
+
out
|
56
|
+
end
|
19
57
|
end
|
20
58
|
end
|
21
59
|
end
|
@@ -0,0 +1,185 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'rbs'
|
3
|
+
|
4
|
+
module Solargraph
|
5
|
+
module PinCache
|
6
|
+
class << self
|
7
|
+
include Logging
|
8
|
+
|
9
|
+
# The base directory where cached YARD documentation and serialized pins are serialized
|
10
|
+
#
|
11
|
+
# @return [String]
|
12
|
+
def base_dir
|
13
|
+
# The directory is not stored in a variable so it can be overridden
|
14
|
+
# in specs.
|
15
|
+
ENV['SOLARGRAPH_CACHE'] ||
|
16
|
+
(ENV['XDG_CACHE_HOME'] ? File.join(ENV['XDG_CACHE_HOME'], 'solargraph') : nil) ||
|
17
|
+
File.join(Dir.home, '.cache', 'solargraph')
|
18
|
+
end
|
19
|
+
|
20
|
+
# The working directory for the current Ruby, RBS, and Solargraph versions.
|
21
|
+
#
|
22
|
+
# @return [String]
|
23
|
+
def work_dir
|
24
|
+
# The directory is not stored in a variable so it can be overridden
|
25
|
+
# in specs.
|
26
|
+
File.join(base_dir, "ruby-#{RUBY_VERSION}", "rbs-#{RBS::VERSION}", "solargraph-#{Solargraph::VERSION}")
|
27
|
+
end
|
28
|
+
|
29
|
+
def yardoc_path gemspec
|
30
|
+
File.join(base_dir, "yard-#{YARD::VERSION}", "#{gemspec.name}-#{gemspec.version}.yardoc")
|
31
|
+
end
|
32
|
+
|
33
|
+
def stdlib_path
|
34
|
+
File.join(work_dir, 'stdlib')
|
35
|
+
end
|
36
|
+
|
37
|
+
def stdlib_require_path require
|
38
|
+
File.join(stdlib_path, "#{require}.ser")
|
39
|
+
end
|
40
|
+
|
41
|
+
def deserialize_stdlib_require require
|
42
|
+
load(stdlib_require_path(require))
|
43
|
+
end
|
44
|
+
|
45
|
+
def serialize_stdlib_require require, pins
|
46
|
+
save(stdlib_require_path(require), pins)
|
47
|
+
end
|
48
|
+
|
49
|
+
def core_path
|
50
|
+
File.join(work_dir, 'core.ser')
|
51
|
+
end
|
52
|
+
|
53
|
+
def deserialize_core
|
54
|
+
load(core_path)
|
55
|
+
end
|
56
|
+
|
57
|
+
def serialize_core pins
|
58
|
+
save(core_path, pins)
|
59
|
+
end
|
60
|
+
|
61
|
+
def yard_gem_path gemspec
|
62
|
+
File.join(work_dir, 'yard', "#{gemspec.name}-#{gemspec.version}.ser")
|
63
|
+
end
|
64
|
+
|
65
|
+
def deserialize_yard_gem(gemspec)
|
66
|
+
load(yard_gem_path(gemspec))
|
67
|
+
end
|
68
|
+
|
69
|
+
def serialize_yard_gem(gemspec, pins)
|
70
|
+
save(yard_gem_path(gemspec), pins)
|
71
|
+
end
|
72
|
+
|
73
|
+
def has_yard?(gemspec)
|
74
|
+
exist?(yard_gem_path(gemspec))
|
75
|
+
end
|
76
|
+
|
77
|
+
def rbs_collection_path(gemspec, hash)
|
78
|
+
File.join(work_dir, 'rbs', "#{gemspec.name}-#{gemspec.version}-#{hash || 0}.ser")
|
79
|
+
end
|
80
|
+
|
81
|
+
def rbs_collection_path_prefix(gemspec)
|
82
|
+
File.join(work_dir, 'rbs', "#{gemspec.name}-#{gemspec.version}-")
|
83
|
+
end
|
84
|
+
|
85
|
+
def deserialize_rbs_collection_gem(gemspec, hash)
|
86
|
+
load(rbs_collection_path(gemspec, hash))
|
87
|
+
end
|
88
|
+
|
89
|
+
def serialize_rbs_collection_gem(gemspec, hash, pins)
|
90
|
+
save(rbs_collection_path(gemspec, hash), pins)
|
91
|
+
end
|
92
|
+
|
93
|
+
def combined_path(gemspec, hash)
|
94
|
+
File.join(work_dir, 'combined', "#{gemspec.name}-#{gemspec.version}-#{hash || 0}.ser")
|
95
|
+
end
|
96
|
+
|
97
|
+
def combined_path_prefix(gemspec)
|
98
|
+
File.join(work_dir, 'combined', "#{gemspec.name}-#{gemspec.version}-")
|
99
|
+
end
|
100
|
+
|
101
|
+
def serialize_combined_gem(gemspec, hash, pins)
|
102
|
+
save(combined_path(gemspec, hash), pins)
|
103
|
+
end
|
104
|
+
|
105
|
+
def deserialize_combined_gem gemspec, hash
|
106
|
+
load(combined_path(gemspec, hash))
|
107
|
+
end
|
108
|
+
|
109
|
+
def has_rbs_collection?(gemspec, hash)
|
110
|
+
exist?(rbs_collection_path(gemspec, hash))
|
111
|
+
end
|
112
|
+
|
113
|
+
def uncache_core
|
114
|
+
uncache(core_path)
|
115
|
+
end
|
116
|
+
|
117
|
+
def uncache_stdlib
|
118
|
+
uncache(stdlib_path)
|
119
|
+
end
|
120
|
+
|
121
|
+
def uncache_gem(gemspec, out: nil)
|
122
|
+
uncache(yardoc_path(gemspec), out: out)
|
123
|
+
uncache_by_prefix(rbs_collection_path_prefix(gemspec), out: out)
|
124
|
+
uncache(yard_gem_path(gemspec), out: out)
|
125
|
+
uncache_by_prefix(combined_path_prefix(gemspec), out: out)
|
126
|
+
end
|
127
|
+
|
128
|
+
# @return [void]
|
129
|
+
def clear
|
130
|
+
FileUtils.rm_rf base_dir, secure: true
|
131
|
+
end
|
132
|
+
|
133
|
+
private
|
134
|
+
|
135
|
+
# @param file [String]
|
136
|
+
# @return [Array<Solargraph::Pin::Base>, nil]
|
137
|
+
def load file
|
138
|
+
return nil unless File.file?(file)
|
139
|
+
Marshal.load(File.read(file, mode: 'rb'))
|
140
|
+
rescue StandardError => e
|
141
|
+
Solargraph.logger.warn "Failed to load cached file #{file}: [#{e.class}] #{e.message}"
|
142
|
+
FileUtils.rm_f file
|
143
|
+
nil
|
144
|
+
end
|
145
|
+
|
146
|
+
def exist? *path
|
147
|
+
File.file? join(*path)
|
148
|
+
end
|
149
|
+
|
150
|
+
# @param path [Array<String>]
|
151
|
+
# @param pins [Array<Pin::Base>]
|
152
|
+
# @return [void]
|
153
|
+
def save file, pins
|
154
|
+
base = File.dirname(file)
|
155
|
+
FileUtils.mkdir_p base unless File.directory?(base)
|
156
|
+
ser = Marshal.dump(pins)
|
157
|
+
File.write file, ser, mode: 'wb'
|
158
|
+
logger.debug { "Cache#save: Saved #{pins.length} pins to #{file}" }
|
159
|
+
end
|
160
|
+
|
161
|
+
# @return [void]
|
162
|
+
# @param path_segments [Array<String>]
|
163
|
+
def uncache *path_segments, out: nil
|
164
|
+
path = File.join(*path_segments)
|
165
|
+
if File.exist?(path)
|
166
|
+
FileUtils.rm_rf path, secure: true
|
167
|
+
out.puts "Clearing pin cache in #{path}" unless out.nil?
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
# @return [void]
|
172
|
+
# @param path_segments [Array<String>]
|
173
|
+
def uncache_by_prefix *path_segments, out: nil
|
174
|
+
path = File.join(*path_segments)
|
175
|
+
glob = "#{path}*"
|
176
|
+
out.puts "Clearing pin cache in #{glob}" unless out.nil?
|
177
|
+
Dir.glob(glob).each do |file|
|
178
|
+
next unless File.file?(file)
|
179
|
+
FileUtils.rm_rf file, secure: true
|
180
|
+
out.puts "Clearing pin cache in #{file}" unless out.nil?
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|
data/lib/solargraph/position.rb
CHANGED
@@ -26,6 +26,15 @@ module Solargraph
|
|
26
26
|
[line, character]
|
27
27
|
end
|
28
28
|
|
29
|
+
def <=>(other)
|
30
|
+
return nil unless other.is_a?(Position)
|
31
|
+
if line == other.line
|
32
|
+
character <=> other.character
|
33
|
+
else
|
34
|
+
line <=> other.line
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
29
38
|
# Get a hash of the position. This representation is suitable for use in
|
30
39
|
# the language server protocol.
|
31
40
|
#
|
data/lib/solargraph/range.rb
CHANGED
@@ -24,6 +24,15 @@ module Solargraph
|
|
24
24
|
[start, ending]
|
25
25
|
end
|
26
26
|
|
27
|
+
def <=>(other)
|
28
|
+
return nil unless other.is_a?(Range)
|
29
|
+
if start == other.start
|
30
|
+
ending <=> other.ending
|
31
|
+
else
|
32
|
+
start <=> other.start
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
27
36
|
# Get a hash of the range. This representation is suitable for use in
|
28
37
|
# the language server protocol.
|
29
38
|
#
|
@@ -6,7 +6,7 @@ module Solargraph
|
|
6
6
|
class RbsMap
|
7
7
|
# Functions for converting RBS declarations to Solargraph pins
|
8
8
|
#
|
9
|
-
|
9
|
+
class Conversions
|
10
10
|
include Logging
|
11
11
|
|
12
12
|
# A container for tracking the current context of the RBS conversion
|
@@ -22,11 +22,17 @@ module Solargraph
|
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
-
|
26
|
-
|
27
|
-
@pins
|
25
|
+
def initialize(loader:)
|
26
|
+
@loader = loader
|
27
|
+
@pins = []
|
28
|
+
load_environment_to_pins(loader)
|
28
29
|
end
|
29
30
|
|
31
|
+
attr_reader :loader
|
32
|
+
|
33
|
+
# @return [Array<Pin::Base>]
|
34
|
+
attr_reader :pins
|
35
|
+
|
30
36
|
private
|
31
37
|
|
32
38
|
# @return [Hash{String => RBS::AST::Declarations::TypeAlias}]
|
@@ -39,6 +45,10 @@ module Solargraph
|
|
39
45
|
def load_environment_to_pins(loader)
|
40
46
|
environment = RBS::Environment.from_loader(loader).resolve_type_names
|
41
47
|
cursor = pins.length
|
48
|
+
if environment.declarations.empty?
|
49
|
+
Solargraph.logger.info "No RBS declarations found in environment for core_root #{loader.core_root.inspect}, libraries #{loader.libs} and directories #{loader.dirs}"
|
50
|
+
return
|
51
|
+
end
|
42
52
|
environment.declarations.each { |decl| convert_decl_to_pin(decl, Solargraph::Pin::ROOT_PIN) }
|
43
53
|
end
|
44
54
|
|
@@ -488,7 +498,7 @@ module Solargraph
|
|
488
498
|
type_location: location_decl_to_pin_location(decl.location),
|
489
499
|
closure: closure,
|
490
500
|
comments: decl.comment&.string,
|
491
|
-
scope:
|
501
|
+
scope: final_scope,
|
492
502
|
attribute: true,
|
493
503
|
visibility: visibility,
|
494
504
|
source: :rbs
|
@@ -512,7 +522,7 @@ module Solargraph
|
|
512
522
|
closure: closure,
|
513
523
|
parameters: [],
|
514
524
|
comments: decl.comment&.string,
|
515
|
-
scope:
|
525
|
+
scope: final_scope,
|
516
526
|
attribute: true,
|
517
527
|
visibility: visibility,
|
518
528
|
source: :rbs
|
@@ -628,11 +638,13 @@ module Solargraph
|
|
628
638
|
# @param closure [Pin::Namespace]
|
629
639
|
# @return [void]
|
630
640
|
def alias_to_pin decl, closure
|
641
|
+
final_scope = decl.singleton? ? :class : :instance
|
631
642
|
pins.push Solargraph::Pin::MethodAlias.new(
|
632
643
|
name: decl.new_name.to_s,
|
633
644
|
type_location: location_decl_to_pin_location(decl.location),
|
634
645
|
original: decl.old_name.to_s,
|
635
646
|
closure: closure,
|
647
|
+
scope: final_scope,
|
636
648
|
source: :rbs,
|
637
649
|
)
|
638
650
|
end
|
@@ -683,8 +695,7 @@ module Solargraph
|
|
683
695
|
if type.is_a?(RBS::Types::Optional)
|
684
696
|
"#{other_type_to_tag(type.type)}, nil"
|
685
697
|
elsif type.is_a?(RBS::Types::Bases::Any)
|
686
|
-
|
687
|
-
'BasicObject'
|
698
|
+
'undefined'
|
688
699
|
elsif type.is_a?(RBS::Types::Bases::Bool)
|
689
700
|
'Boolean'
|
690
701
|
elsif type.is_a?(RBS::Types::Tuple)
|
@@ -5,24 +5,46 @@ module Solargraph
|
|
5
5
|
# Ruby core pins
|
6
6
|
#
|
7
7
|
class CoreMap
|
8
|
-
|
8
|
+
|
9
|
+
def resolved?
|
10
|
+
true
|
11
|
+
end
|
9
12
|
|
10
13
|
FILLS_DIRECTORY = File.join(File.dirname(__FILE__), '..', '..', '..', 'rbs', 'fills')
|
11
14
|
|
12
|
-
def initialize
|
13
|
-
|
15
|
+
def initialize; end
|
16
|
+
|
17
|
+
def pins
|
18
|
+
return @pins if @pins
|
19
|
+
|
20
|
+
@pins = []
|
21
|
+
cache = PinCache.deserialize_core
|
14
22
|
if cache
|
15
|
-
pins.replace cache
|
23
|
+
@pins.replace cache
|
16
24
|
else
|
17
|
-
loader = RBS::EnvironmentLoader.new(repository: RBS::Repository.new(no_stdlib: false))
|
18
25
|
loader.add(path: Pathname(FILLS_DIRECTORY))
|
19
|
-
|
20
|
-
pins.concat RbsMap::CoreFills::ALL
|
26
|
+
@pins = conversions.pins
|
27
|
+
@pins.concat RbsMap::CoreFills::ALL
|
21
28
|
processed = ApiMap::Store.new(pins).pins.reject { |p| p.is_a?(Solargraph::Pin::Reference::Override) }
|
22
|
-
pins.replace processed
|
29
|
+
@pins.replace processed
|
23
30
|
|
24
|
-
|
31
|
+
PinCache.serialize_core @pins
|
25
32
|
end
|
33
|
+
@pins
|
34
|
+
end
|
35
|
+
|
36
|
+
def loader
|
37
|
+
@loader ||= RBS::EnvironmentLoader.new(repository: RBS::Repository.new(no_stdlib: false))
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def loader
|
43
|
+
@loader ||= RBS::EnvironmentLoader.new(repository: RBS::Repository.new(no_stdlib: false))
|
44
|
+
end
|
45
|
+
|
46
|
+
def conversions
|
47
|
+
@conversions ||= Conversions.new(loader: loader)
|
26
48
|
end
|
27
49
|
end
|
28
50
|
end
|