solargraph 0.60.4 → 0.61.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 +1 -1
- data/.github/workflows/rspec.yml +3 -1
- data/CHANGELOG.md +16 -0
- data/Gemfile +0 -3
- data/lib/solargraph/api_map/index.rb +15 -2
- data/lib/solargraph/api_map/store.rb +13 -0
- data/lib/solargraph/api_map.rb +60 -81
- data/lib/solargraph/cache_dir.rb +58 -0
- data/lib/solargraph/collection/base.rb +50 -0
- data/lib/solargraph/collection/core.rb +17 -0
- data/lib/solargraph/collection/gem.rb +57 -0
- data/lib/solargraph/collection/rbs.rb +49 -0
- data/lib/solargraph/collection/stdlib.rb +25 -0
- data/lib/solargraph/collection.rb +31 -0
- data/lib/solargraph/convention.rb +5 -3
- data/lib/solargraph/diagnostics/require_not_found.rb +0 -4
- data/lib/solargraph/external.rb +159 -0
- data/lib/solargraph/language_server/message/text_document/definition.rb +4 -1
- data/lib/solargraph/language_server/message/text_document/hover.rb +1 -2
- data/lib/solargraph/library.rb +11 -24
- data/lib/solargraph/metagem.rb +80 -0
- data/lib/solargraph/parser/parser_gem/node_chainer.rb +22 -3
- data/lib/solargraph/pin/closure.rb +17 -0
- data/lib/solargraph/pin/factory_parameter.rb +84 -0
- data/lib/solargraph/pin.rb +1 -0
- data/lib/solargraph/rbs_map/base.rb +31 -0
- data/lib/solargraph/rbs_map/conversions.rb +3 -1
- data/lib/solargraph/rbs_map/{core_map.rb → core.rb} +18 -39
- data/lib/solargraph/rbs_map/core_fills.rb +1 -1
- data/lib/solargraph/rbs_map/gem.rb +13 -0
- data/lib/solargraph/rbs_map/helpers.rb +60 -0
- data/lib/solargraph/rbs_map/path.rb +19 -0
- data/lib/solargraph/rbs_map/stdlib.rb +24 -0
- data/lib/solargraph/rbs_map.rb +7 -198
- data/lib/solargraph/repo.rb +177 -0
- data/lib/solargraph/shell.rb +49 -99
- data/lib/solargraph/source/chain/call.rb +29 -4
- data/lib/solargraph/source/chain/literal.rb +17 -17
- data/lib/solargraph/source/chain/parameter.rb +79 -0
- data/lib/solargraph/source/chain.rb +8 -0
- data/lib/solargraph/source/source_chainer.rb +40 -44
- data/lib/solargraph/source_map/clip.rb +5 -3
- data/lib/solargraph/source_map/mapper.rb +6 -2
- data/lib/solargraph/source_map.rb +10 -5
- data/lib/solargraph/type_checker/rules.rb +2 -1
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/workspace.rb +0 -1
- data/lib/solargraph/yard_map/cache.rb +1 -1
- data/lib/solargraph/yard_map/directives/attribute_directive.rb +1 -1
- data/lib/solargraph/yard_map/directives/domain_directive.rb +1 -1
- data/lib/solargraph/yard_map/directives/method_directive.rb +1 -1
- data/lib/solargraph/yard_map/directives/override_directive.rb +1 -1
- data/lib/solargraph/yard_map/directives/parse_directive.rb +1 -1
- data/lib/solargraph/yard_map/directives/scope_directive.rb +178 -0
- data/lib/solargraph/yard_map/directives/visibility_directive.rb +1 -1
- data/lib/solargraph/yard_map/directives.rb +5 -2
- data/lib/solargraph/yard_map/helpers.rb +1 -1
- data/lib/solargraph/yard_map/macro.rb +34 -5
- data/lib/solargraph/yard_map/mapper/to_constant.rb +1 -1
- data/lib/solargraph/yard_map/mapper/to_method.rb +1 -1
- data/lib/solargraph/yard_map/mapper/to_namespace.rb +1 -1
- data/lib/solargraph/yard_map/mapper.rb +2 -2
- data/lib/solargraph/yard_map.rb +1 -1
- data/lib/solargraph/yardoc.rb +43 -60
- data/lib/solargraph.rb +6 -3
- data/solargraph.gemspec +1 -1
- metadata +22 -9
- data/lib/solargraph/doc_map.rb +0 -439
- data/lib/solargraph/gem_pins.rb +0 -87
- data/lib/solargraph/pin_cache.rb +0 -248
- data/lib/solargraph/rbs_map/stdlib_map.rb +0 -71
- data/lib/solargraph/workspace/gemspecs.rb +0 -373
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 7b386e8d7447871b7850f167cab1483351050f92debdc40bb4b2ee9538e820e1
|
|
4
|
+
data.tar.gz: 3b88afe53d55f28b96004941ff37c2c8c9254c7e83ed597d90122aa1b6e374c2
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 97f94421c920c20c8c5e2d5d8deae43ef7559cd082cedc022041ebc22252c04cb713e25fb8d5e96af1c258fe7aecffbc527c88829876944868911e31f20990ee
|
|
7
|
+
data.tar.gz: ad5d661d4340531998b669b8d499922f2c05c2fc94d04f1cdb9c2ed3ce207d0aa08875fd18e9a63f6e5a9c0688354e8ea8ada6bd865f76eaaa5a92393d2c6917
|
|
@@ -129,7 +129,7 @@ jobs:
|
|
|
129
129
|
- name: clone https://github.com/lekemula/solargraph-rspec/
|
|
130
130
|
run: |
|
|
131
131
|
cd ..
|
|
132
|
-
git clone https://github.com/lekemula/solargraph-rspec
|
|
132
|
+
git clone https://github.com/lekemula/solargraph-rspec/
|
|
133
133
|
cd solargraph-rspec
|
|
134
134
|
- name: Set up Ruby
|
|
135
135
|
uses: ruby/setup-ruby@v1
|
data/.github/workflows/rspec.yml
CHANGED
|
@@ -25,7 +25,7 @@ jobs:
|
|
|
25
25
|
# It currently 404s ("Unavailable version head for ruby"), failing CI:
|
|
26
26
|
# https://github.com/castwide/solargraph/actions/runs/25863741955/job/76000137015?pr=1187
|
|
27
27
|
ruby-version: ['3.1', '3.2', '3.3', '3.4', '4.0']
|
|
28
|
-
rbs-version: ['3.10.
|
|
28
|
+
rbs-version: ['3.10.4', '4.0.0', '4.0.1', '4.0.2']
|
|
29
29
|
exclude:
|
|
30
30
|
- ruby-version: '3.1'
|
|
31
31
|
rbs-version: '4.0.0'
|
|
@@ -48,6 +48,8 @@ jobs:
|
|
|
48
48
|
# starting from Ruby 3.6.0
|
|
49
49
|
- name: Work around legacy rbs deprecation on ruby > 3.4
|
|
50
50
|
run: echo "gem 'tsort'" >> .Gemfile
|
|
51
|
+
- name: Install bundle
|
|
52
|
+
run: bundle install
|
|
51
53
|
- name: Update gems
|
|
52
54
|
run: |
|
|
53
55
|
bundle update rbs # use latest available for this Ruby version
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,19 @@
|
|
|
1
|
+
## 0.61.0 - October 7, 2026
|
|
2
|
+
- Clips qualify constant pins for completion (#1368)
|
|
3
|
+
- Unused spec tags (#1370)
|
|
4
|
+
- External gem dependency management (#1369)
|
|
5
|
+
- Use a development branch of Solargraph::RSpec for plugin tests (#1371)
|
|
6
|
+
- Pin::Base spec changes (#1372)
|
|
7
|
+
- Consolidate cache and gems commands (#1373)
|
|
8
|
+
- Sleep timeouts (#1375)
|
|
9
|
+
- RbsMap loads minimal pins (#1377)
|
|
10
|
+
- Fix 10x slowdown when analyzing projects with many gems (#1374)
|
|
11
|
+
- Clone main solargraph-rspec repo in plugins workflow (#1388)
|
|
12
|
+
- Add new Pin::FactoryParameter (#1063)
|
|
13
|
+
- Support YARD `@!scope` directive (#1387)
|
|
14
|
+
- Add nil guard to Hover (#1389)
|
|
15
|
+
- Stop dropping union members that differ only by type parameter (#1273)
|
|
16
|
+
|
|
1
17
|
## 0.60.4 - August 30, 2026
|
|
2
18
|
- Fix @yieldparam type lost on multi-overload block-form methods (#1289) (#1290)
|
|
3
19
|
- Read inline RBS superclass params only on the class line (#1301)
|
data/Gemfile
CHANGED
|
@@ -4,9 +4,6 @@ source 'https://rubygems.org'
|
|
|
4
4
|
|
|
5
5
|
gemspec name: 'solargraph'
|
|
6
6
|
|
|
7
|
-
# Test fixture gems
|
|
8
|
-
gem 'gem-with-yard-macros', path: 'spec/fixtures/gem-with-yard-macros'
|
|
9
|
-
|
|
10
7
|
# Local gemfile for development tools, etc.
|
|
11
8
|
local_gemfile = File.expand_path('.Gemfile', __dir__)
|
|
12
9
|
instance_eval File.read local_gemfile if File.exist? local_gemfile
|
|
@@ -92,6 +92,11 @@ module Solargraph
|
|
|
92
92
|
@superclass_references ||= Hash.new { |h, k| h[k] = [] }
|
|
93
93
|
end
|
|
94
94
|
|
|
95
|
+
# @return [Hash{String => Array<Pin::FactoryParameter>}]
|
|
96
|
+
def factory_parameter_hash
|
|
97
|
+
@factory_parameter_hash ||= Hash.new { |h, k| h[k] = [] }
|
|
98
|
+
end
|
|
99
|
+
|
|
95
100
|
# @param pins [Enumerable<Pin::Base>]
|
|
96
101
|
# @return [self]
|
|
97
102
|
def merge pins
|
|
@@ -101,8 +106,8 @@ module Solargraph
|
|
|
101
106
|
protected
|
|
102
107
|
|
|
103
108
|
attr_writer :pins, :pin_select_cache, :namespace_hash, :pin_class_hash, :path_pin_hash, :include_references,
|
|
104
|
-
:extend_references, :prepend_references, :superclass_references, :
|
|
105
|
-
:macro_method_name_pins
|
|
109
|
+
:extend_references, :prepend_references, :superclass_references, :factory_parameter_hash,
|
|
110
|
+
:macro_method_names, :macro_method_name_pins
|
|
106
111
|
|
|
107
112
|
# @return [self]
|
|
108
113
|
def deep_clone
|
|
@@ -148,6 +153,7 @@ module Solargraph
|
|
|
148
153
|
macro_pins = pins_by_class(Pin::Method).select { |pin| pin.macros.any? }
|
|
149
154
|
@macro_method_names = macro_pins.to_set(&:name)
|
|
150
155
|
@macro_method_name_pins = macro_pins.to_set.classify(&:name)
|
|
156
|
+
map_factory_parameters
|
|
151
157
|
map_overrides
|
|
152
158
|
pins_by_class(Pin::Reference::TypeAlias).each { |pin| alias_hash[pin.name] = pin.return_type }
|
|
153
159
|
self
|
|
@@ -210,6 +216,13 @@ module Solargraph
|
|
|
210
216
|
sig.instance_variable_set(:@return_type, ComplexType.try_parse(tag.type))
|
|
211
217
|
end
|
|
212
218
|
end
|
|
219
|
+
|
|
220
|
+
# @return [void]
|
|
221
|
+
def map_factory_parameters
|
|
222
|
+
pins_by_class(Pin::FactoryParameter).each do |fp|
|
|
223
|
+
factory_parameter_hash[fp.method_path] << fp
|
|
224
|
+
end
|
|
225
|
+
end
|
|
213
226
|
end
|
|
214
227
|
end
|
|
215
228
|
end
|
|
@@ -261,6 +261,14 @@ module Solargraph
|
|
|
261
261
|
ancestors.compact.uniq
|
|
262
262
|
end
|
|
263
263
|
|
|
264
|
+
# Get factory parameters for a method pin.
|
|
265
|
+
#
|
|
266
|
+
# @param method_pin [Pin::Method]
|
|
267
|
+
# @return [Array<Pin::FactoryParameter>]
|
|
268
|
+
def factory_parameters_for_method method_pin
|
|
269
|
+
factory_parameter_hash[method_pin.path] || []
|
|
270
|
+
end
|
|
271
|
+
|
|
264
272
|
# @param fqns [String]
|
|
265
273
|
#
|
|
266
274
|
# @return [Array<Solargraph::Pin::Reference>]
|
|
@@ -358,6 +366,11 @@ module Solargraph
|
|
|
358
366
|
index.extend_references
|
|
359
367
|
end
|
|
360
368
|
|
|
369
|
+
# @return [Hash{String => Array<Pin::FactoryParameter>}]
|
|
370
|
+
def factory_parameter_hash
|
|
371
|
+
index.factory_parameter_hash
|
|
372
|
+
end
|
|
373
|
+
|
|
361
374
|
# @param name [String]
|
|
362
375
|
# @return [Enumerable<Solargraph::Pin::Base>]
|
|
363
376
|
def namespace_children name
|
data/lib/solargraph/api_map.rb
CHANGED
|
@@ -15,13 +15,9 @@ module Solargraph
|
|
|
15
15
|
autoload :Index, 'solargraph/api_map/index'
|
|
16
16
|
autoload :Constants, 'solargraph/api_map/constants'
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
attr_reader :unresolved_requires
|
|
20
|
-
|
|
21
|
-
@@core_map = RbsMap::CoreMap.new
|
|
18
|
+
include Equality
|
|
22
19
|
|
|
23
|
-
|
|
24
|
-
attr_reader :missing_docs
|
|
20
|
+
@@core_pins = Collection::Core.load
|
|
25
21
|
|
|
26
22
|
# @param pins [Array<Solargraph::Pin::Base>]
|
|
27
23
|
# @param loose_unions [Boolean] if true, a potential type can be
|
|
@@ -38,12 +34,6 @@ module Solargraph
|
|
|
38
34
|
index pins
|
|
39
35
|
end
|
|
40
36
|
|
|
41
|
-
# @param out [StringIO, IO, nil] output stream for logging
|
|
42
|
-
# @return [void]
|
|
43
|
-
def self.reset_core out: nil
|
|
44
|
-
@@core_map = RbsMap::CoreMap.new
|
|
45
|
-
end
|
|
46
|
-
|
|
47
37
|
#
|
|
48
38
|
# This is a mutable object, which is cached in the Chain class -
|
|
49
39
|
# if you add any fields which change the results of calls (not
|
|
@@ -86,7 +76,7 @@ module Solargraph
|
|
|
86
76
|
@source_map_hash = {}
|
|
87
77
|
conventions_environ.clear
|
|
88
78
|
cache.clear
|
|
89
|
-
store.update @@
|
|
79
|
+
store.update @@core_pins, pins
|
|
90
80
|
self
|
|
91
81
|
end
|
|
92
82
|
|
|
@@ -106,6 +96,8 @@ module Solargraph
|
|
|
106
96
|
# @param bench [Bench]
|
|
107
97
|
# @return [self]
|
|
108
98
|
def catalog bench
|
|
99
|
+
start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
100
|
+
@workspace = bench.workspace
|
|
109
101
|
@source_map_hash = bench.source_map_hash
|
|
110
102
|
# @type [Array<Pin::Base>]
|
|
111
103
|
iced_pins = bench.icebox.flat_map(&:pins)
|
|
@@ -114,24 +106,27 @@ module Solargraph
|
|
|
114
106
|
source_map_hash.each_value do |map|
|
|
115
107
|
conventions_environ.merge map.conventions_environ
|
|
116
108
|
end
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
if recreate_docmap
|
|
124
|
-
@doc_map = DocMap.new(unresolved_requires, bench.workspace, out: nil) # @todo Implement gem preferences
|
|
125
|
-
@unresolved_requires = @doc_map.unresolved_requires
|
|
126
|
-
end
|
|
127
|
-
start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
128
|
-
Solargraph.logger.info 'Cataloging ApiMap started'
|
|
129
|
-
@cache.clear if store.update(@@core_map.pins, @doc_map.pins, conventions_environ.pins, iced_pins, live_pins) { process_macros }
|
|
130
|
-
@missing_docs = [] # @todo Implement missing docs
|
|
109
|
+
# @todo Determine what needs to be sent to global conventions
|
|
110
|
+
conventions_environ.merge Convention.for_global(nil)
|
|
111
|
+
external_changed = external.update(bench.external_requires.to_a + conventions_environ.requires)
|
|
112
|
+
store_changed = store.update(@@core_pins, external.pins.clone, conventions_environ.pins, iced_pins, live_pins) { process_macros }
|
|
113
|
+
@cache.clear if external_changed || store_changed
|
|
131
114
|
Solargraph.logger.info "Cataloging ApiMap finished in #{Process.clock_gettime(Process::CLOCK_MONOTONIC) - start_time} seconds"
|
|
132
115
|
self
|
|
133
116
|
end
|
|
134
117
|
|
|
118
|
+
def external
|
|
119
|
+
@external ||= External.new(workspace&.directory, [])
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def unresolved_requires
|
|
123
|
+
external.unresolved_requires
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def unloaded_gems
|
|
127
|
+
external.unloaded_gems
|
|
128
|
+
end
|
|
129
|
+
|
|
135
130
|
# @return [Array<Pin::Base>]
|
|
136
131
|
def process_macros
|
|
137
132
|
macro_pins = []
|
|
@@ -144,45 +139,23 @@ module Solargraph
|
|
|
144
139
|
method_candidates.each do |node|
|
|
145
140
|
closure = source_map.locate_closure_pin(node.location.line, node.location.column)
|
|
146
141
|
chain = Solargraph::Parser::ParserGem::NodeChainer.chain(node)
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
end
|
|
155
|
-
next
|
|
156
|
-
end
|
|
142
|
+
next unless node.children[0].nil? && store.macro_method_name_pins.key?(node.children[1].to_s)
|
|
143
|
+
match = store.macro_method_name_pins[node.children[1].to_s].find do |pin|
|
|
144
|
+
get_complex_type_methods(closure.return_type).include?(pin)
|
|
145
|
+
end
|
|
146
|
+
next unless match
|
|
147
|
+
match.macros.each do |macro|
|
|
148
|
+
macro_pins.concat macro.generate_pins_from(chain, match, source_map)
|
|
157
149
|
end
|
|
150
|
+
next
|
|
158
151
|
end
|
|
159
152
|
end
|
|
160
153
|
macro_pins
|
|
161
154
|
end
|
|
162
155
|
|
|
163
|
-
# @return [DocMap]
|
|
164
|
-
def doc_map
|
|
165
|
-
@doc_map ||= DocMap.new([], Workspace.new('.'))
|
|
166
|
-
end
|
|
167
|
-
|
|
168
|
-
# @return [::Array<Gem::Specification>]
|
|
169
|
-
def uncached_gemspecs
|
|
170
|
-
doc_map.uncached_gemspecs || []
|
|
171
|
-
end
|
|
172
|
-
|
|
173
|
-
# @return [::Array<Gem::Specification>]
|
|
174
|
-
def uncached_rbs_collection_gemspecs
|
|
175
|
-
@doc_map.uncached_rbs_collection_gemspecs
|
|
176
|
-
end
|
|
177
|
-
|
|
178
|
-
# @return [::Array<Gem::Specification>]
|
|
179
|
-
def uncached_yard_gemspecs
|
|
180
|
-
@doc_map.uncached_yard_gemspecs
|
|
181
|
-
end
|
|
182
|
-
|
|
183
156
|
# @return [Enumerable<Pin::Base>]
|
|
184
157
|
def core_pins
|
|
185
|
-
@@
|
|
158
|
+
@@core_pins
|
|
186
159
|
end
|
|
187
160
|
|
|
188
161
|
# @param name [String, nil]
|
|
@@ -237,21 +210,6 @@ module Solargraph
|
|
|
237
210
|
api_map
|
|
238
211
|
end
|
|
239
212
|
|
|
240
|
-
# @param out [StringIO, IO, nil]
|
|
241
|
-
# @param rebuild [Boolean] whether to rebuild the pins even if they are cached
|
|
242
|
-
# @return [void]
|
|
243
|
-
def cache_all_for_doc_map! out: $stderr, rebuild: false
|
|
244
|
-
doc_map.cache_all!(out, rebuild: rebuild)
|
|
245
|
-
end
|
|
246
|
-
|
|
247
|
-
# @param gemspec [Gem::Specification]
|
|
248
|
-
# @param rebuild [Boolean]
|
|
249
|
-
# @param out [StringIO, IO, nil]
|
|
250
|
-
# @return [void]
|
|
251
|
-
def cache_gem gemspec, rebuild: false, out: nil
|
|
252
|
-
doc_map.cache(gemspec, rebuild: rebuild, out: out)
|
|
253
|
-
end
|
|
254
|
-
|
|
255
213
|
class << self
|
|
256
214
|
include Logging
|
|
257
215
|
end
|
|
@@ -267,12 +225,12 @@ module Solargraph
|
|
|
267
225
|
# @return [ApiMap]
|
|
268
226
|
def self.load_with_cache directory, out = $stderr, loose_unions: true
|
|
269
227
|
api_map = load(directory, loose_unions: loose_unions)
|
|
270
|
-
if api_map.
|
|
271
|
-
logger.info { "All gems cached for #{directory}" }
|
|
272
|
-
return api_map
|
|
273
|
-
end
|
|
228
|
+
return api_map if api_map.external.unloaded_gems.empty?
|
|
274
229
|
|
|
275
|
-
api_map.
|
|
230
|
+
api_map.external.unloaded_gems.each do |metagem|
|
|
231
|
+
out&.puts "Caching gem #{metagem.name} (#{metagem.cache_name})"
|
|
232
|
+
Collection::Gem.load metagem
|
|
233
|
+
end
|
|
276
234
|
load(directory, loose_unions: loose_unions)
|
|
277
235
|
end
|
|
278
236
|
|
|
@@ -288,6 +246,21 @@ module Solargraph
|
|
|
288
246
|
store.pins_by_class(Pin::Keyword)
|
|
289
247
|
end
|
|
290
248
|
|
|
249
|
+
# An array of pins based on factory parameters.
|
|
250
|
+
#
|
|
251
|
+
# @return [Enumerable<Solargraph::Pin::FactoryParameter>]
|
|
252
|
+
def factory_parameter_pins
|
|
253
|
+
store.pins_by_class(Pin::FactoryParameter)
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
# Get factory parameters for a method pin.
|
|
257
|
+
#
|
|
258
|
+
# @param method_pin [Solargraph::Pin::Method]
|
|
259
|
+
# @return [Array<Solargraph::Pin::FactoryParameter>]
|
|
260
|
+
def factory_parameters_for_method method_pin
|
|
261
|
+
store.factory_parameters_for_method(method_pin)
|
|
262
|
+
end
|
|
263
|
+
|
|
291
264
|
# @param name [String]
|
|
292
265
|
# @return [ComplexType, nil]
|
|
293
266
|
def unalias name
|
|
@@ -609,6 +582,9 @@ module Solargraph
|
|
|
609
582
|
|
|
610
583
|
# Get an array of pins that match the specified path.
|
|
611
584
|
#
|
|
585
|
+
# @example
|
|
586
|
+
# api_map.get_pins_by_path('String#split')
|
|
587
|
+
#
|
|
612
588
|
# @param path [String]
|
|
613
589
|
# @return [Array<Pin::Base>]
|
|
614
590
|
def get_path_pins path
|
|
@@ -755,7 +731,7 @@ module Solargraph
|
|
|
755
731
|
|
|
756
732
|
# @return [Workspace, nil]
|
|
757
733
|
def workspace
|
|
758
|
-
|
|
734
|
+
@workspace
|
|
759
735
|
end
|
|
760
736
|
|
|
761
737
|
# @param fq_reference_tag [String] A fully qualified whose method should be pulled in
|
|
@@ -1051,8 +1027,11 @@ module Solargraph
|
|
|
1051
1027
|
# that this overload of 'protected' will typecheck @sg-ignore
|
|
1052
1028
|
# @sg-ignore
|
|
1053
1029
|
def equality_fields
|
|
1054
|
-
|
|
1055
|
-
|
|
1030
|
+
# External is compared by identity and generation instead of by its pins:
|
|
1031
|
+
# Chain#infer hashes the ApiMap on every inference, and Array#hash would
|
|
1032
|
+
# walk every gem pin on each of those calls.
|
|
1033
|
+
[@source_map_hash, conventions_environ, @external, @external&.generation,
|
|
1034
|
+
@unresolved_requires, @loose_unions]
|
|
1056
1035
|
end
|
|
1057
1036
|
end
|
|
1058
1037
|
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'fileutils'
|
|
4
|
+
require 'rbs'
|
|
5
|
+
|
|
6
|
+
module Solargraph
|
|
7
|
+
module CacheDir
|
|
8
|
+
module_function
|
|
9
|
+
|
|
10
|
+
# The base directory for cached YARD documentation and serialized pins.
|
|
11
|
+
#
|
|
12
|
+
# @return [String]
|
|
13
|
+
def base_dir
|
|
14
|
+
ENV['SOLARGRAPH_CACHE'] ||
|
|
15
|
+
(ENV['XDG_CACHE_HOME'] ? File.join(ENV['XDG_CACHE_HOME'], 'solargraph') : nil) ||
|
|
16
|
+
File.join(Dir.home, '.cache', 'solargraph')
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# The working directory for the current Ruby, RBS, and Solargraph versions.
|
|
20
|
+
#
|
|
21
|
+
# @return [String]
|
|
22
|
+
def work_dir
|
|
23
|
+
File.join(base_dir, "ruby-#{RUBY_VERSION}", "rbs-#{RBS::VERSION}", "solargraph-#{Solargraph::VERSION}")
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# The current gem directory.
|
|
27
|
+
#
|
|
28
|
+
# @return [String]
|
|
29
|
+
def gem_dir
|
|
30
|
+
File.join(work_dir, 'gems')
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# The current stdlib directory.
|
|
34
|
+
#
|
|
35
|
+
# @return [String]
|
|
36
|
+
def stdlib_dir
|
|
37
|
+
File.join(work_dir, 'stdlib')
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# The current RBS collection directory.
|
|
41
|
+
#
|
|
42
|
+
# @return [String]
|
|
43
|
+
def rbs_dir
|
|
44
|
+
File.join(work_dir, 'rbs')
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# The directory for the current YARD version.
|
|
48
|
+
#
|
|
49
|
+
# @return [String]
|
|
50
|
+
def yard_dir
|
|
51
|
+
File.join(base_dir, "yard-#{YARD::VERSION}", "yard-activesupport-concern-#{YARD::ActiveSupport::Concern::VERSION}")
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def clear
|
|
55
|
+
FileUtils.rm_rf base_dir
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'fileutils'
|
|
4
|
+
|
|
5
|
+
module Solargraph
|
|
6
|
+
module Collection
|
|
7
|
+
# The base class for cacheable pin collections. Subclasses need to
|
|
8
|
+
# implement #pins and #cache_file.
|
|
9
|
+
#
|
|
10
|
+
# @!method pins
|
|
11
|
+
# The array of pins for this collection.
|
|
12
|
+
# @abstract
|
|
13
|
+
# @return [Array<Pin::Base>]
|
|
14
|
+
# @!method cache_file
|
|
15
|
+
# The file that will store serialized pins.
|
|
16
|
+
# @abstract
|
|
17
|
+
# @return [String]
|
|
18
|
+
class Base
|
|
19
|
+
# @return [Array<Pin::Base>]
|
|
20
|
+
def load
|
|
21
|
+
Collection.cached(cache_file) { file_cache_pins || generate_pin_caches }
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# @return [Array<Pin::Base>]
|
|
25
|
+
def self.load(...)
|
|
26
|
+
new(...).load
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def self.uncache(...)
|
|
30
|
+
cache_file = new(...).cache_file
|
|
31
|
+
FileUtils.rm_rf cache_file
|
|
32
|
+
Collection.mem_cache.delete cache_file
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
private
|
|
36
|
+
|
|
37
|
+
def file_cache_pins
|
|
38
|
+
Marshal.load(File.read(cache_file, mode: 'rb')) if File.exist?(cache_file) # rubocop:disable Security/MarshalLoad
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def generate_pin_caches
|
|
42
|
+
Collection.mem_cache[cache_file] = pins
|
|
43
|
+
serial = Marshal.dump(pins)
|
|
44
|
+
FileUtils.mkdir_p File.dirname(cache_file)
|
|
45
|
+
File.write cache_file, serial, mode: 'wb'
|
|
46
|
+
pins
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Solargraph
|
|
4
|
+
module Collection
|
|
5
|
+
# Cacheable core pins.
|
|
6
|
+
#
|
|
7
|
+
class Core < Base
|
|
8
|
+
def cache_file
|
|
9
|
+
File.join CacheDir.work_dir, 'core.ser'
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def pins
|
|
13
|
+
@pins ||= RbsMap::Core.pins
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Solargraph
|
|
4
|
+
module Collection
|
|
5
|
+
# Cacheable gem pins.
|
|
6
|
+
#
|
|
7
|
+
class Gem < Base
|
|
8
|
+
include Logging
|
|
9
|
+
|
|
10
|
+
attr_reader :metagem
|
|
11
|
+
|
|
12
|
+
# @param metagem [Metagem]
|
|
13
|
+
def initialize metagem
|
|
14
|
+
super()
|
|
15
|
+
@metagem = metagem
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def cache_file
|
|
19
|
+
File.join CacheDir.gem_dir, "#{metagem.cache_name}.ser"
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def load
|
|
23
|
+
return pins unless metagem.cacheable?
|
|
24
|
+
super
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def pins
|
|
28
|
+
@pins ||= if metagem.cacheable?
|
|
29
|
+
cacheable_pins
|
|
30
|
+
else
|
|
31
|
+
uncacheable_pins
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def self.cached? metagem
|
|
36
|
+
metagem.cacheable? && File.exist?(new(metagem).cache_file)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
private
|
|
40
|
+
|
|
41
|
+
def cacheable_pins
|
|
42
|
+
code_objects = Yardoc.load!(metagem)
|
|
43
|
+
yard_pins = YardMap::Mapper.new(code_objects, metagem).map
|
|
44
|
+
rbs_pins = RbsMap::Gem.pins(metagem)
|
|
45
|
+
RbsMap::Helpers.combine(yard_pins, rbs_pins)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def uncacheable_pins
|
|
49
|
+
files = metagem.require_paths.flat_map { |path| Dir.glob(File.join(metagem.full_path, path, '**', '*.rb')) }
|
|
50
|
+
source_maps = files.map { |file| Solargraph::SourceMap.load(file) }
|
|
51
|
+
source_pins = source_maps.flat_map(&:pins)
|
|
52
|
+
rbs_pins = RbsMap::Gem.pins(metagem)
|
|
53
|
+
RbsMap::Helpers.combine(source_pins, rbs_pins)
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'digest'
|
|
4
|
+
|
|
5
|
+
module Solargraph
|
|
6
|
+
module Collection
|
|
7
|
+
# Cacheable pins from an RBS collection directory.
|
|
8
|
+
#
|
|
9
|
+
class Rbs < Base
|
|
10
|
+
# @return [String]
|
|
11
|
+
attr_reader :path
|
|
12
|
+
|
|
13
|
+
# @param path [String]
|
|
14
|
+
# @return [Array<Pin::Base>]
|
|
15
|
+
def self.load path
|
|
16
|
+
new(path).load
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# @param path [String]
|
|
20
|
+
def initialize path
|
|
21
|
+
super()
|
|
22
|
+
@path = path
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# @return [Array<Pin::Base>]
|
|
26
|
+
def pins
|
|
27
|
+
@pins ||= RbsMap::Path.pins(path)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# @return [String]
|
|
31
|
+
def cache_file
|
|
32
|
+
File.join CacheDir.rbs_dir, "#{key}.ser"
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
private
|
|
36
|
+
|
|
37
|
+
# A collection is rewritten in place by `rbs collection install`, so the
|
|
38
|
+
# newest signature mtime distinguishes one installation from the next.
|
|
39
|
+
#
|
|
40
|
+
# @return [String]
|
|
41
|
+
def key
|
|
42
|
+
@key ||= begin
|
|
43
|
+
stamp = Dir.glob(File.join(path, '**', '*.rbs')).map { |file| File.mtime(file).to_i }.max
|
|
44
|
+
format('%.32s', Digest::SHA256.hexdigest("#{File.expand_path(path)}:#{stamp}"))
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Solargraph
|
|
4
|
+
module Collection
|
|
5
|
+
# Cacheable stdlib pins.
|
|
6
|
+
#
|
|
7
|
+
class Stdlib < Base
|
|
8
|
+
attr_reader :library
|
|
9
|
+
|
|
10
|
+
# @param library [String]
|
|
11
|
+
def initialize library
|
|
12
|
+
super()
|
|
13
|
+
@library = library
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def pins
|
|
17
|
+
@pins ||= RbsMap::Stdlib.pins(library)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def cache_file
|
|
21
|
+
File.join CacheDir.stdlib_dir, "#{library}.ser"
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Solargraph
|
|
4
|
+
module Collection
|
|
5
|
+
autoload :Base, 'solargraph/collection/base'
|
|
6
|
+
autoload :Core, 'solargraph/collection/core'
|
|
7
|
+
autoload :Gem, 'solargraph/collection/gem'
|
|
8
|
+
autoload :Rbs, 'solargraph/collection/rbs'
|
|
9
|
+
autoload :Stdlib, 'solargraph/collection/stdlib'
|
|
10
|
+
|
|
11
|
+
# A hash for storing pin collections in memory.
|
|
12
|
+
#
|
|
13
|
+
# @return [Hash{String => Array<Pin::Base>}]
|
|
14
|
+
def self.mem_cache
|
|
15
|
+
@mem_cache ||= {}
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# The pins cached under a key, storing the block result on a miss.
|
|
19
|
+
#
|
|
20
|
+
# @param key [String]
|
|
21
|
+
# @return [Array<Pin::Base>]
|
|
22
|
+
def self.cached key
|
|
23
|
+
mem_cache.fetch(key) { mem_cache[key] = yield }
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# @return [void]
|
|
27
|
+
def self.clear_mem_cache
|
|
28
|
+
mem_cache.clear
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|