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