solargraph 0.59.0.dev.2 → 0.59.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/linting.yml +3 -1
- data/.github/workflows/plugins.yml +8 -2
- data/.github/workflows/rspec.yml +6 -40
- data/.github/workflows/typecheck.yml +2 -1
- data/.rubocop.yml +6 -1
- data/.rubocop_todo.yml +3 -0
- data/CHANGELOG.md +15 -0
- data/lib/solargraph/api_map/constants.rb +0 -1
- data/lib/solargraph/api_map/index.rb +6 -0
- data/lib/solargraph/api_map/store.rb +6 -0
- data/lib/solargraph/api_map.rb +20 -4
- data/lib/solargraph/complex_type/type_methods.rb +2 -1
- data/lib/solargraph/complex_type/unique_type.rb +2 -4
- data/lib/solargraph/complex_type.rb +1 -1
- data/lib/solargraph/doc_map.rb +370 -131
- data/lib/solargraph/gem_pins.rb +16 -17
- data/lib/solargraph/library.rb +44 -66
- data/lib/solargraph/logging.rb +0 -2
- data/lib/solargraph/parser/flow_sensitive_typing.rb +0 -2
- data/lib/solargraph/parser/parser_gem/class_methods.rb +0 -2
- data/lib/solargraph/parser/parser_gem/node_processors/block_node.rb +0 -1
- data/lib/solargraph/pin/base.rb +0 -2
- data/lib/solargraph/pin/method.rb +3 -0
- data/lib/solargraph/pin/reference/type_alias.rb +16 -0
- data/lib/solargraph/pin/reference.rb +1 -0
- data/lib/solargraph/pin_cache.rb +66 -480
- data/lib/solargraph/position.rb +7 -4
- data/lib/solargraph/rbs_map/conversions.rb +18 -18
- data/lib/solargraph/rbs_map.rb +2 -3
- data/lib/solargraph/shell.rb +163 -15
- data/lib/solargraph/source/chain.rb +3 -1
- data/lib/solargraph/source_map/mapper.rb +0 -2
- data/lib/solargraph/type_checker.rb +1 -2
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/workspace/config.rb +1 -1
- data/lib/solargraph/workspace/gemspecs.rb +2 -2
- data/lib/solargraph/workspace.rb +32 -129
- data/lib/solargraph/yard_map.rb +17 -18
- data/lib/solargraph/yardoc.rb +26 -33
- data/lib/solargraph.rb +2 -0
- data/solargraph.gemspec +2 -2
- metadata +6 -11
data/lib/solargraph/pin_cache.rb
CHANGED
|
@@ -1,437 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
require 'yard-activesupport-concern'
|
|
3
2
|
require 'fileutils'
|
|
3
|
+
require 'pathname' # @todo Required by RBS but not loaded in some use cases
|
|
4
4
|
require 'rbs'
|
|
5
|
-
require 'rubygems'
|
|
6
5
|
|
|
7
6
|
module Solargraph
|
|
8
|
-
|
|
9
|
-
include Logging
|
|
10
|
-
|
|
11
|
-
attr_reader :directory, :rbs_collection_path, :rbs_collection_config_path, :yard_plugins
|
|
12
|
-
|
|
13
|
-
# @param rbs_collection_path [String, nil]
|
|
14
|
-
# @param rbs_collection_config_path [String, nil]
|
|
15
|
-
# @param directory [String, nil]
|
|
16
|
-
# @param yard_plugins [Array<String>]
|
|
17
|
-
def initialize rbs_collection_path:, rbs_collection_config_path:,
|
|
18
|
-
directory:,
|
|
19
|
-
yard_plugins:
|
|
20
|
-
@rbs_collection_path = rbs_collection_path
|
|
21
|
-
@rbs_collection_config_path = rbs_collection_config_path
|
|
22
|
-
@directory = directory
|
|
23
|
-
@yard_plugins = yard_plugins
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
# @param gemspec [Gem::Specification, Bundler::LazySpecification]
|
|
27
|
-
def cached? gemspec
|
|
28
|
-
rbs_version_cache_key = lookup_rbs_version_cache_key(gemspec)
|
|
29
|
-
combined_gem?(gemspec, rbs_version_cache_key)
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
# @param gemspec [Gem::Specification]
|
|
33
|
-
# @param rebuild [Boolean] whether to rebuild the cache regardless of whether it already exists
|
|
34
|
-
# @param out [StringIO, IO, nil] output stream for logging
|
|
35
|
-
# @return [void]
|
|
36
|
-
def cache_gem gemspec:, rebuild: false, out: nil
|
|
37
|
-
rbs_version_cache_key = lookup_rbs_version_cache_key(gemspec)
|
|
38
|
-
|
|
39
|
-
build_yard, build_rbs_collection, build_combined =
|
|
40
|
-
calculate_build_needs(gemspec,
|
|
41
|
-
rebuild: rebuild,
|
|
42
|
-
rbs_version_cache_key: rbs_version_cache_key)
|
|
43
|
-
|
|
44
|
-
return unless build_yard || build_rbs_collection || build_combined
|
|
45
|
-
|
|
46
|
-
build_combine_and_cache(gemspec,
|
|
47
|
-
rbs_version_cache_key,
|
|
48
|
-
build_yard: build_yard,
|
|
49
|
-
build_rbs_collection: build_rbs_collection,
|
|
50
|
-
build_combined: build_combined,
|
|
51
|
-
out: out)
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
# @param gemspec [Gem::Specification, Bundler::LazySpecification]
|
|
55
|
-
# @param rbs_version_cache_key [String, nil]
|
|
56
|
-
def suppress_yard_cache? gemspec, rbs_version_cache_key
|
|
57
|
-
if gemspec.name == 'parser' && rbs_version_cache_key != RbsMap::CACHE_KEY_UNRESOLVED
|
|
58
|
-
# parser takes forever to build YARD pins, but has excellent RBS collection pins
|
|
59
|
-
return true
|
|
60
|
-
end
|
|
61
|
-
false
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
# @param out [StringIO, IO, nil] output stream for logging
|
|
65
|
-
# @param rebuild [Boolean] build pins regardless of whether we
|
|
66
|
-
# have cached them already
|
|
67
|
-
#
|
|
68
|
-
# @return [void]
|
|
69
|
-
def cache_all_stdlibs rebuild: false, out: $stderr
|
|
70
|
-
possible_stdlibs.each do |stdlib|
|
|
71
|
-
RbsMap::StdlibMap.new(stdlib, rebuild: rebuild, out: out)
|
|
72
|
-
end
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
# @param path [String] require path that might be in the RBS stdlib collection
|
|
76
|
-
# @return [void]
|
|
77
|
-
def cache_stdlib_rbs_map path
|
|
78
|
-
# these are held in memory in RbsMap::StdlibMap
|
|
79
|
-
map = RbsMap::StdlibMap.load(path)
|
|
80
|
-
if map.resolved?
|
|
81
|
-
logger.debug { "Loading stdlib pins for #{path}" }
|
|
82
|
-
pins = map.pins
|
|
83
|
-
logger.debug { "Loaded #{pins.length} stdlib pins for #{path}" }
|
|
84
|
-
pins
|
|
85
|
-
else
|
|
86
|
-
# @todo Temporarily ignoring unresolved `require 'set'`
|
|
87
|
-
logger.debug { "Require path #{path} could not be resolved in RBS" } unless path == 'set'
|
|
88
|
-
nil
|
|
89
|
-
end
|
|
90
|
-
end
|
|
91
|
-
|
|
92
|
-
# @param gemspec [Gem::Specification, Bundler::LazySpecification]
|
|
93
|
-
#
|
|
94
|
-
# @return [String]
|
|
95
|
-
def lookup_rbs_version_cache_key gemspec
|
|
96
|
-
rbs_map = RbsMap.from_gemspec(gemspec, rbs_collection_path, rbs_collection_config_path)
|
|
97
|
-
rbs_map.cache_key
|
|
98
|
-
end
|
|
99
|
-
|
|
100
|
-
# @param gemspec [Gem::Specification, Bundler::LazySpecification]
|
|
101
|
-
# @param rbs_version_cache_key [String, nil]
|
|
102
|
-
# @param yard_pins [Array<Pin::Base>]
|
|
103
|
-
# @param rbs_collection_pins [Array<Pin::Base>]
|
|
104
|
-
# @return [void]
|
|
105
|
-
def cache_combined_pins gemspec, rbs_version_cache_key, yard_pins, rbs_collection_pins
|
|
106
|
-
combined_pins = GemPins.combine(yard_pins, rbs_collection_pins)
|
|
107
|
-
serialize_combined_gem(gemspec, rbs_version_cache_key, combined_pins)
|
|
108
|
-
end
|
|
109
|
-
|
|
110
|
-
# @param gemspec [Gem::Specification, Bundler::LazySpecification]
|
|
111
|
-
# @return [Array<Pin::Base>, nil]
|
|
112
|
-
def deserialize_combined_pin_cache gemspec
|
|
113
|
-
rbs_version_cache_key = lookup_rbs_version_cache_key(gemspec)
|
|
114
|
-
|
|
115
|
-
load_combined_gem(gemspec, rbs_version_cache_key)
|
|
116
|
-
end
|
|
117
|
-
|
|
118
|
-
# @param gemspec [Gem::Specification, Bundler::LazySpecification]
|
|
119
|
-
# @param out [StringIO, IO, nil]
|
|
120
|
-
# @return [void]
|
|
121
|
-
def uncache_gem gemspec, out: nil
|
|
122
|
-
PinCache.uncache(yardoc_path(gemspec), out: out)
|
|
123
|
-
PinCache.uncache(yard_gem_path(gemspec), out: out)
|
|
124
|
-
uncache_by_prefix(rbs_collection_pins_path_prefix(gemspec), out: out)
|
|
125
|
-
uncache_by_prefix(combined_path_prefix(gemspec), out: out)
|
|
126
|
-
rbs_version_cache_key = lookup_rbs_version_cache_key(gemspec)
|
|
127
|
-
combined_pins_in_memory.delete([gemspec.name, gemspec.version, rbs_version_cache_key])
|
|
128
|
-
end
|
|
129
|
-
|
|
130
|
-
# @param gemspec [Gem::Specification, Bundler::LazySpecification]
|
|
131
|
-
def yardoc_processing? gemspec
|
|
132
|
-
Yardoc.processing?(yardoc_path(gemspec))
|
|
133
|
-
end
|
|
134
|
-
|
|
135
|
-
# @return [Array<String>] a list of possible standard library names
|
|
136
|
-
def possible_stdlibs
|
|
137
|
-
# all dirs and .rb files in Gem::RUBYGEMS_DIR
|
|
138
|
-
Dir.glob(File.join(Gem::RUBYGEMS_DIR, '*')).map do |file_or_dir|
|
|
139
|
-
basename = File.basename(file_or_dir)
|
|
140
|
-
# remove .rb
|
|
141
|
-
# @sg-ignore flow sensitive typing should be able to handle redefinition
|
|
142
|
-
basename = basename[0..-4] if basename.end_with?('.rb')
|
|
143
|
-
basename
|
|
144
|
-
end.sort.uniq
|
|
145
|
-
rescue StandardError => e
|
|
146
|
-
logger.info { "Failed to get possible stdlibs: #{e.message}" }
|
|
147
|
-
# @sg-ignore Need to add nil check here
|
|
148
|
-
logger.debug { e.backtrace.join("\n") }
|
|
149
|
-
[]
|
|
150
|
-
end
|
|
151
|
-
|
|
152
|
-
private
|
|
153
|
-
|
|
154
|
-
# @param gemspec [Gem::Specification, Bundler::LazySpecification]
|
|
155
|
-
# @param rebuild [Boolean] whether to rebuild the cache regardless of whether it already exists
|
|
156
|
-
# @param rbs_version_cache_key [String, nil] the cache key for the gem in the RBS collection
|
|
157
|
-
#
|
|
158
|
-
# @return [Array(Boolean, Boolean, Boolean)] whether to build YARD
|
|
159
|
-
# pins, RBS collection pins, and combined pins
|
|
160
|
-
def calculate_build_needs gemspec, rebuild:, rbs_version_cache_key:
|
|
161
|
-
if rebuild
|
|
162
|
-
build_yard = true
|
|
163
|
-
build_rbs_collection = true
|
|
164
|
-
build_combined = true
|
|
165
|
-
else
|
|
166
|
-
build_yard = !yard_gem?(gemspec)
|
|
167
|
-
build_rbs_collection = !rbs_collection_pins?(gemspec, rbs_version_cache_key)
|
|
168
|
-
# @sg-ignore Need to add nil check here
|
|
169
|
-
build_combined = !combined_gem?(gemspec, rbs_version_cache_key) || build_yard || build_rbs_collection
|
|
170
|
-
end
|
|
171
|
-
|
|
172
|
-
build_yard = false if suppress_yard_cache?(gemspec, rbs_version_cache_key)
|
|
173
|
-
|
|
174
|
-
[build_yard, build_rbs_collection, build_combined]
|
|
175
|
-
end
|
|
176
|
-
|
|
177
|
-
# @param gemspec [Gem::Specification]
|
|
178
|
-
# @param rbs_version_cache_key [String, nil]
|
|
179
|
-
# @param build_yard [Boolean]
|
|
180
|
-
# @param build_rbs_collection [Boolean]
|
|
181
|
-
# @param build_combined [Boolean]
|
|
182
|
-
# @param out [StringIO, IO, nil]
|
|
183
|
-
#
|
|
184
|
-
# @return [void]
|
|
185
|
-
def build_combine_and_cache gemspec,
|
|
186
|
-
rbs_version_cache_key,
|
|
187
|
-
build_yard:,
|
|
188
|
-
build_rbs_collection:,
|
|
189
|
-
build_combined:,
|
|
190
|
-
out:
|
|
191
|
-
log_cache_info(gemspec, rbs_version_cache_key,
|
|
192
|
-
build_yard: build_yard,
|
|
193
|
-
build_rbs_collection: build_rbs_collection,
|
|
194
|
-
build_combined: build_combined,
|
|
195
|
-
out: out)
|
|
196
|
-
cache_yard_pins(gemspec, out) if build_yard
|
|
197
|
-
# this can be nil even if we aren't told to build it - see suppress_yard_cache?
|
|
198
|
-
yard_pins = deserialize_yard_pin_cache(gemspec) || []
|
|
199
|
-
cache_rbs_collection_pins(gemspec, out) if build_rbs_collection
|
|
200
|
-
rbs_collection_pins = deserialize_rbs_collection_cache(gemspec, rbs_version_cache_key) || []
|
|
201
|
-
cache_combined_pins(gemspec, rbs_version_cache_key, yard_pins, rbs_collection_pins) if build_combined
|
|
202
|
-
end
|
|
203
|
-
|
|
204
|
-
# @param gemspec [Gem::Specification, Bundler::LazySpecification]
|
|
205
|
-
# @param rbs_version_cache_key [String, nil]
|
|
206
|
-
# @param build_yard [Boolean]
|
|
207
|
-
# @param build_rbs_collection [Boolean]
|
|
208
|
-
# @param build_combined [Boolean]
|
|
209
|
-
# @param out [StringIO, IO, nil]
|
|
210
|
-
#
|
|
211
|
-
# @return [void]
|
|
212
|
-
def log_cache_info gemspec,
|
|
213
|
-
rbs_version_cache_key,
|
|
214
|
-
build_yard:,
|
|
215
|
-
build_rbs_collection:,
|
|
216
|
-
build_combined:,
|
|
217
|
-
out:
|
|
218
|
-
type = []
|
|
219
|
-
type << 'YARD' if build_yard
|
|
220
|
-
rbs_source_desc = RbsMap.rbs_source_desc(rbs_version_cache_key)
|
|
221
|
-
type << rbs_source_desc if build_rbs_collection && !rbs_source_desc.nil?
|
|
222
|
-
# we'll build it anyway, but it won't take long to build with
|
|
223
|
-
# only a single source
|
|
224
|
-
|
|
225
|
-
# 'combining' is awkward terminology in this case
|
|
226
|
-
just_yard = build_yard && rbs_source_desc.nil?
|
|
227
|
-
|
|
228
|
-
type << 'combined' if build_combined && !just_yard
|
|
229
|
-
out&.puts("Caching #{type.join(' and ')} pins for gem #{gemspec.name}:#{gemspec.version}")
|
|
230
|
-
end
|
|
231
|
-
|
|
232
|
-
# @param gemspec [Gem::Specification]
|
|
233
|
-
# @param out [StringIO, IO, nil]
|
|
234
|
-
# @return [Array<Pin::Base>]
|
|
235
|
-
def cache_yard_pins gemspec, out
|
|
236
|
-
gem_yardoc_path = yardoc_path(gemspec)
|
|
237
|
-
Yardoc.build_docs(gem_yardoc_path, yard_plugins, gemspec) unless Yardoc.docs_built?(gem_yardoc_path)
|
|
238
|
-
pins = Yardoc.build_pins(gem_yardoc_path, gemspec, out: out)
|
|
239
|
-
serialize_yard_gem(gemspec, pins)
|
|
240
|
-
logger.info { "Cached #{pins.length} YARD pins for gem #{gemspec.name}:#{gemspec.version}" } unless pins.empty?
|
|
241
|
-
pins
|
|
242
|
-
end
|
|
243
|
-
|
|
244
|
-
# @return [Hash{Array(String, String, String) => Array<Pin::Base>}]
|
|
245
|
-
def combined_pins_in_memory
|
|
246
|
-
PinCache.all_combined_pins_in_memory[yard_plugins] ||= {}
|
|
247
|
-
end
|
|
248
|
-
|
|
249
|
-
# @param gemspec [Gem::Specification, Bundler::LazySpecification]
|
|
250
|
-
# @param _out [StringIO, IO, nil]
|
|
251
|
-
# @return [Array<Pin::Base>]
|
|
252
|
-
def cache_rbs_collection_pins gemspec, _out
|
|
253
|
-
rbs_map = RbsMap.from_gemspec(gemspec, rbs_collection_path, rbs_collection_config_path)
|
|
254
|
-
pins = rbs_map.pins
|
|
255
|
-
rbs_version_cache_key = rbs_map.cache_key
|
|
256
|
-
# cache pins even if result is zero, so we don't retry building pins
|
|
257
|
-
pins ||= []
|
|
258
|
-
serialize_rbs_collection_pins(gemspec, rbs_version_cache_key, pins)
|
|
259
|
-
logger.info do
|
|
260
|
-
unless pins.empty?
|
|
261
|
-
"Cached #{pins.length} RBS collection pins for gem #{gemspec.name} #{gemspec.version} with " \
|
|
262
|
-
"cache_key #{rbs_version_cache_key.inspect}"
|
|
263
|
-
end
|
|
264
|
-
end
|
|
265
|
-
pins
|
|
266
|
-
end
|
|
267
|
-
|
|
268
|
-
# @param gemspec [Gem::Specification, Bundler::LazySpecification]
|
|
269
|
-
# @return [Array<Pin::Base>, nil]
|
|
270
|
-
def deserialize_yard_pin_cache gemspec
|
|
271
|
-
cached = load_yard_gem(gemspec)
|
|
272
|
-
if cached
|
|
273
|
-
cached
|
|
274
|
-
else
|
|
275
|
-
logger.debug "No YARD pin cache for #{gemspec.name}:#{gemspec.version}"
|
|
276
|
-
nil
|
|
277
|
-
end
|
|
278
|
-
end
|
|
279
|
-
|
|
280
|
-
# @param gemspec [Gem::Specification, Bundler::LazySpecification]
|
|
281
|
-
# @param rbs_version_cache_key [String, nil]
|
|
282
|
-
# @return [Array<Pin::Base>, nil]
|
|
283
|
-
def deserialize_rbs_collection_cache gemspec, rbs_version_cache_key
|
|
284
|
-
cached = load_rbs_collection_pins(gemspec, rbs_version_cache_key)
|
|
285
|
-
Solargraph.assert_or_log(:pin_cache_rbs_collection, 'Asked for non-existent rbs collection') if cached.nil?
|
|
286
|
-
logger.info do
|
|
287
|
-
"Loaded #{cached&.length} pins from RBS collection cache for #{gemspec.name}:#{gemspec.version}"
|
|
288
|
-
end
|
|
289
|
-
cached
|
|
290
|
-
end
|
|
291
|
-
|
|
292
|
-
# @return [Array<String>]
|
|
293
|
-
def yard_path_components
|
|
294
|
-
["yard-#{YARD::VERSION}",
|
|
295
|
-
yard_plugins.sort.uniq.join('-')]
|
|
296
|
-
end
|
|
297
|
-
|
|
298
|
-
# @param gemspec [Gem::Specification, Bundler::LazySpecification]
|
|
299
|
-
# @return [String]
|
|
300
|
-
def yardoc_path gemspec
|
|
301
|
-
File.join(PinCache.base_dir,
|
|
302
|
-
*yard_path_components,
|
|
303
|
-
"#{gemspec.name}-#{gemspec.version}.yardoc")
|
|
304
|
-
end
|
|
305
|
-
|
|
306
|
-
# @param gemspec [Gem::Specification, Bundler::LazySpecification]
|
|
307
|
-
# @return [String]
|
|
308
|
-
def yard_gem_path gemspec
|
|
309
|
-
File.join(PinCache.work_dir, *yard_path_components, "#{gemspec.name}-#{gemspec.version}.ser")
|
|
310
|
-
end
|
|
311
|
-
|
|
312
|
-
# @param gemspec [Gem::Specification, Bundler::LazySpecification]
|
|
313
|
-
# @return [Array<Pin::Base>, nil]
|
|
314
|
-
def load_yard_gem gemspec
|
|
315
|
-
PinCache.load(yard_gem_path(gemspec))
|
|
316
|
-
end
|
|
317
|
-
|
|
318
|
-
# @param gemspec [Gem::Specification, Bundler::LazySpecification]
|
|
319
|
-
# @param pins [Array<Pin::Base>]
|
|
320
|
-
# @return [void]
|
|
321
|
-
def serialize_yard_gem gemspec, pins
|
|
322
|
-
PinCache.save(yard_gem_path(gemspec), pins)
|
|
323
|
-
end
|
|
324
|
-
|
|
325
|
-
# @param gemspec [Gem::Specification, Bundler::LazySpecification]
|
|
326
|
-
# @return [Boolean]
|
|
327
|
-
def yard_gem? gemspec
|
|
328
|
-
exist?(yard_gem_path(gemspec))
|
|
329
|
-
end
|
|
330
|
-
|
|
331
|
-
# @param gemspec [Gem::Specification, Bundler::LazySpecification]
|
|
332
|
-
# @param hash [String, nil]
|
|
333
|
-
# @return [String]
|
|
334
|
-
def rbs_collection_pins_path gemspec, hash
|
|
335
|
-
rbs_collection_pins_path_prefix(gemspec) + "#{hash || 0}.ser"
|
|
336
|
-
end
|
|
337
|
-
|
|
338
|
-
# @param gemspec [Gem::Specification, Bundler::LazySpecification]
|
|
339
|
-
# @return [String]
|
|
340
|
-
def rbs_collection_pins_path_prefix gemspec
|
|
341
|
-
File.join(PinCache.work_dir, 'rbs', "#{gemspec.name}-#{gemspec.version}-")
|
|
342
|
-
end
|
|
343
|
-
|
|
344
|
-
# @param gemspec [Gem::Specification, Bundler::LazySpecification]
|
|
345
|
-
# @param hash [String, nil]
|
|
346
|
-
#
|
|
347
|
-
# @return [Array<Pin::Base>, nil]
|
|
348
|
-
def load_rbs_collection_pins gemspec, hash
|
|
349
|
-
PinCache.load(rbs_collection_pins_path(gemspec, hash))
|
|
350
|
-
end
|
|
351
|
-
|
|
352
|
-
# @param gemspec [Gem::Specification, Bundler::LazySpecification]
|
|
353
|
-
# @param hash [String, nil]
|
|
354
|
-
# @param pins [Array<Pin::Base>]
|
|
355
|
-
# @return [void]
|
|
356
|
-
def serialize_rbs_collection_pins gemspec, hash, pins
|
|
357
|
-
PinCache.save(rbs_collection_pins_path(gemspec, hash), pins)
|
|
358
|
-
end
|
|
359
|
-
|
|
360
|
-
# @param gemspec [Gem::Specification, Bundler::LazySpecification]
|
|
361
|
-
# @param hash [String, nil]
|
|
362
|
-
# @return [String]
|
|
363
|
-
def combined_path gemspec, hash
|
|
364
|
-
File.join(combined_path_prefix(gemspec) + "-#{hash || 0}.ser")
|
|
365
|
-
end
|
|
366
|
-
|
|
367
|
-
# @param gemspec [Gem::Specification, Bundler::LazySpecification]
|
|
368
|
-
# @return [String]
|
|
369
|
-
def combined_path_prefix gemspec
|
|
370
|
-
File.join(PinCache.work_dir, 'combined', yard_plugins.sort.join('-'), "#{gemspec.name}-#{gemspec.version}")
|
|
371
|
-
end
|
|
372
|
-
|
|
373
|
-
# @param gemspec [Gem::Specification, Bundler::LazySpecification]
|
|
374
|
-
# @param hash [String, nil]
|
|
375
|
-
# @param pins [Array<Pin::Base>]
|
|
376
|
-
# @return [void]
|
|
377
|
-
def serialize_combined_gem gemspec, hash, pins
|
|
378
|
-
PinCache.save(combined_path(gemspec, hash), pins)
|
|
379
|
-
end
|
|
380
|
-
|
|
381
|
-
# @param gemspec [Gem::Specification, Bundler::LazySpecification]
|
|
382
|
-
# @param hash [String]
|
|
383
|
-
def combined_gem? gemspec, hash
|
|
384
|
-
exist?(combined_path(gemspec, hash))
|
|
385
|
-
end
|
|
386
|
-
|
|
387
|
-
# @param gemspec [Gem::Specification, Bundler::LazySpecification]
|
|
388
|
-
# @param hash [String, nil]
|
|
389
|
-
# @return [Array<Pin::Base>, nil]
|
|
390
|
-
def load_combined_gem gemspec, hash
|
|
391
|
-
cached = combined_pins_in_memory[[gemspec.name, gemspec.version, hash]]
|
|
392
|
-
return cached if cached
|
|
393
|
-
loaded = PinCache.load(combined_path(gemspec, hash))
|
|
394
|
-
combined_pins_in_memory[[gemspec.name, gemspec.version, hash]] = loaded if loaded
|
|
395
|
-
loaded
|
|
396
|
-
end
|
|
397
|
-
|
|
398
|
-
# @param gemspec [Gem::Specification, Bundler::LazySpecification]
|
|
399
|
-
# @param hash [String, nil]
|
|
400
|
-
def rbs_collection_pins? gemspec, hash
|
|
401
|
-
exist?(rbs_collection_pins_path(gemspec, hash))
|
|
402
|
-
end
|
|
403
|
-
|
|
404
|
-
include Logging
|
|
405
|
-
|
|
406
|
-
# @param path [String]
|
|
407
|
-
def exist? *path
|
|
408
|
-
File.file? File.join(*path)
|
|
409
|
-
end
|
|
410
|
-
|
|
411
|
-
# @return [void]
|
|
412
|
-
# @param path_segments [Array<String>]
|
|
413
|
-
# @param out [StringIO, IO, nil]
|
|
414
|
-
def uncache_by_prefix *path_segments, out: nil
|
|
415
|
-
path = File.join(*path_segments)
|
|
416
|
-
glob = "#{path}*"
|
|
417
|
-
out&.puts "Clearing pin cache in #{glob}"
|
|
418
|
-
Dir.glob(glob).each do |file|
|
|
419
|
-
next unless File.file?(file)
|
|
420
|
-
FileUtils.rm_rf file, secure: true
|
|
421
|
-
out&.puts "Clearing pin cache in #{file}"
|
|
422
|
-
end
|
|
423
|
-
end
|
|
424
|
-
|
|
7
|
+
module PinCache
|
|
425
8
|
class << self
|
|
426
9
|
include Logging
|
|
427
10
|
|
|
428
|
-
# @return [Hash{Array<String> => Hash{Array(String, String) =>
|
|
429
|
-
# Array<Pin::Base>}}] yard plugins, then gemspec name and
|
|
430
|
-
# version
|
|
431
|
-
def all_combined_pins_in_memory
|
|
432
|
-
@all_combined_pins_in_memory ||= {}
|
|
433
|
-
end
|
|
434
|
-
|
|
435
11
|
# The base directory where cached YARD documentation and serialized pins are serialized
|
|
436
12
|
#
|
|
437
13
|
# @return [String]
|
|
@@ -443,47 +19,6 @@ module Solargraph
|
|
|
443
19
|
File.join(Dir.home, '.cache', 'solargraph')
|
|
444
20
|
end
|
|
445
21
|
|
|
446
|
-
# @param path_segments [Array<String>]
|
|
447
|
-
# @param out [IO, nil]
|
|
448
|
-
# @return [void]
|
|
449
|
-
def uncache *path_segments, out: nil
|
|
450
|
-
path = File.join(*path_segments)
|
|
451
|
-
if File.exist?(path)
|
|
452
|
-
FileUtils.rm_rf path, secure: true
|
|
453
|
-
out&.puts "Clearing pin cache in #{path}"
|
|
454
|
-
else
|
|
455
|
-
out&.puts "Pin cache file #{path} does not exist"
|
|
456
|
-
end
|
|
457
|
-
end
|
|
458
|
-
|
|
459
|
-
# @return [void]
|
|
460
|
-
# @param out [IO, nil]
|
|
461
|
-
# @param path_segments [Array<String>]
|
|
462
|
-
def uncache_by_prefix *path_segments, out: nil
|
|
463
|
-
path = File.join(*path_segments)
|
|
464
|
-
glob = "#{path}*"
|
|
465
|
-
out&.puts "Clearing pin cache in #{glob}"
|
|
466
|
-
Dir.glob(glob).each do |file|
|
|
467
|
-
next unless File.file?(file)
|
|
468
|
-
FileUtils.rm_rf file, secure: true
|
|
469
|
-
out&.puts "Clearing pin cache in #{file}"
|
|
470
|
-
end
|
|
471
|
-
end
|
|
472
|
-
|
|
473
|
-
# @param out [StringIO, IO, nil]
|
|
474
|
-
# @return [void]
|
|
475
|
-
def uncache_core out: nil
|
|
476
|
-
uncache(core_path, out: out)
|
|
477
|
-
# ApiMap keep this in memory
|
|
478
|
-
ApiMap.reset_core(out: out)
|
|
479
|
-
end
|
|
480
|
-
|
|
481
|
-
# @param out [StringIO, IO, nil]
|
|
482
|
-
# @return [void]
|
|
483
|
-
def uncache_stdlib out: nil
|
|
484
|
-
uncache(stdlib_path, out: out)
|
|
485
|
-
end
|
|
486
|
-
|
|
487
22
|
# The working directory for the current Ruby, RBS, and Solargraph versions.
|
|
488
23
|
#
|
|
489
24
|
# @return [String]
|
|
@@ -493,6 +28,15 @@ module Solargraph
|
|
|
493
28
|
File.join(base_dir, "ruby-#{RUBY_VERSION}", "rbs-#{RBS::VERSION}", "solargraph-#{Solargraph::VERSION}")
|
|
494
29
|
end
|
|
495
30
|
|
|
31
|
+
# @param gemspec [Gem::Specification]
|
|
32
|
+
# @return [String]
|
|
33
|
+
def yardoc_path gemspec
|
|
34
|
+
File.join(base_dir,
|
|
35
|
+
"yard-#{YARD::VERSION}",
|
|
36
|
+
"yard-activesupport-concern-#{YARD::ActiveSupport::Concern::VERSION}",
|
|
37
|
+
"#{gemspec.name}-#{gemspec.version}.yardoc")
|
|
38
|
+
end
|
|
39
|
+
|
|
496
40
|
# @return [String]
|
|
497
41
|
def stdlib_path
|
|
498
42
|
File.join(work_dir, 'stdlib')
|
|
@@ -552,6 +96,12 @@ module Solargraph
|
|
|
552
96
|
save(yard_gem_path(gemspec), pins)
|
|
553
97
|
end
|
|
554
98
|
|
|
99
|
+
# @param gemspec [Gem::Specification]
|
|
100
|
+
# @return [Boolean]
|
|
101
|
+
def has_yard? gemspec
|
|
102
|
+
exist?(yard_gem_path(gemspec))
|
|
103
|
+
end
|
|
104
|
+
|
|
555
105
|
# @param gemspec [Gem::Specification]
|
|
556
106
|
# @param hash [String, nil]
|
|
557
107
|
# @return [String]
|
|
@@ -615,13 +165,35 @@ module Solargraph
|
|
|
615
165
|
exist?(rbs_collection_path(gemspec, hash))
|
|
616
166
|
end
|
|
617
167
|
|
|
168
|
+
# @return [void]
|
|
169
|
+
def uncache_core
|
|
170
|
+
uncache(core_path)
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
# @return [void]
|
|
174
|
+
def uncache_stdlib
|
|
175
|
+
uncache(stdlib_path)
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
# @param gemspec [Gem::Specification]
|
|
179
|
+
# @param out [IO, StringIO, nil]
|
|
180
|
+
# @return [void]
|
|
181
|
+
def uncache_gem gemspec, out: nil
|
|
182
|
+
uncache(yardoc_path(gemspec), out: out)
|
|
183
|
+
uncache_by_prefix(rbs_collection_path_prefix(gemspec), out: out)
|
|
184
|
+
uncache(yard_gem_path(gemspec), out: out)
|
|
185
|
+
uncache_by_prefix(combined_path_prefix(gemspec), out: out)
|
|
186
|
+
end
|
|
187
|
+
|
|
618
188
|
# @return [void]
|
|
619
189
|
def clear
|
|
620
190
|
FileUtils.rm_rf base_dir, secure: true
|
|
621
191
|
end
|
|
622
192
|
|
|
193
|
+
private
|
|
194
|
+
|
|
623
195
|
# @param file [String]
|
|
624
|
-
# @sg-ignore Marshal.load
|
|
196
|
+
# @sg-ignore Marshal.load returns Object; we know it's Array<Pin::Base>
|
|
625
197
|
# @return [Array<Solargraph::Pin::Base>, nil]
|
|
626
198
|
def load file
|
|
627
199
|
return nil unless File.file?(file)
|
|
@@ -632,6 +204,11 @@ module Solargraph
|
|
|
632
204
|
nil
|
|
633
205
|
end
|
|
634
206
|
|
|
207
|
+
# @param path [String]
|
|
208
|
+
def exist? *path
|
|
209
|
+
File.file? File.join(*path)
|
|
210
|
+
end
|
|
211
|
+
|
|
635
212
|
# @param file [String]
|
|
636
213
|
# @param pins [Array<Pin::Base>]
|
|
637
214
|
# @return [void]
|
|
@@ -643,19 +220,28 @@ module Solargraph
|
|
|
643
220
|
logger.debug { "Cache#save: Saved #{pins.length} pins to #{file}" }
|
|
644
221
|
end
|
|
645
222
|
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
223
|
+
# @param path_segments [Array<String>]
|
|
224
|
+
# @return [void]
|
|
225
|
+
# @param [Object, nil] out
|
|
226
|
+
def uncache *path_segments, out: nil
|
|
227
|
+
path = File.join(*path_segments)
|
|
228
|
+
return unless File.exist?(path)
|
|
229
|
+
FileUtils.rm_rf path, secure: true
|
|
230
|
+
out&.puts "Clearing pin cache in #{path}"
|
|
654
231
|
end
|
|
655
232
|
|
|
656
|
-
# @
|
|
657
|
-
|
|
658
|
-
|
|
233
|
+
# @return [void]
|
|
234
|
+
# @param path_segments [Array<String>]
|
|
235
|
+
# @param [Object, nil] out
|
|
236
|
+
def uncache_by_prefix *path_segments, out: nil
|
|
237
|
+
path = File.join(*path_segments)
|
|
238
|
+
glob = "#{path}*"
|
|
239
|
+
out&.puts "Clearing pin cache in #{glob}"
|
|
240
|
+
Dir.glob(glob).each do |file|
|
|
241
|
+
next unless File.file?(file)
|
|
242
|
+
FileUtils.rm_rf file, secure: true
|
|
243
|
+
out&.puts "Clearing pin cache in #{file}"
|
|
244
|
+
end
|
|
659
245
|
end
|
|
660
246
|
end
|
|
661
247
|
end
|
data/lib/solargraph/position.rb
CHANGED
|
@@ -58,7 +58,8 @@ module Solargraph
|
|
|
58
58
|
line = -1
|
|
59
59
|
last_line_index = 0
|
|
60
60
|
|
|
61
|
-
# @sg-ignore
|
|
61
|
+
# @sg-ignore Typechecker thinks `newline_index` inside of the assignment
|
|
62
|
+
# can be nil
|
|
62
63
|
while (newline_index = text.index("\n", newline_index + 1)) && line <= position.line
|
|
63
64
|
line += 1
|
|
64
65
|
break if line == position.line
|
|
@@ -67,7 +68,8 @@ module Solargraph
|
|
|
67
68
|
end
|
|
68
69
|
|
|
69
70
|
last_line_index += 1 if position.line.positive?
|
|
70
|
-
# @sg-ignore
|
|
71
|
+
# @sg-ignore `last_line_index` is always an Integer because `newline_index`
|
|
72
|
+
# is never nil inside the while block
|
|
71
73
|
last_line_index + position.character
|
|
72
74
|
end
|
|
73
75
|
|
|
@@ -97,10 +99,11 @@ module Solargraph
|
|
|
97
99
|
character = offset
|
|
98
100
|
newline_index = -1
|
|
99
101
|
|
|
100
|
-
# @sg-ignore
|
|
102
|
+
# @sg-ignore Typechecker thinks `newline_index` inside of the assignment
|
|
103
|
+
# can be nil
|
|
101
104
|
while (newline_index = text.index("\n", newline_index + 1)) && newline_index < offset
|
|
102
105
|
line += 1
|
|
103
|
-
# @sg-ignore
|
|
106
|
+
# @sg-ignore `newline_index` is always an Integer inside the while block
|
|
104
107
|
character = offset - newline_index - 1
|
|
105
108
|
end
|
|
106
109
|
character = 0 if character.nil? && (cursor - offset).between?(0, 1)
|