solargraph 0.58.0 → 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.
Files changed (219) hide show
  1. checksums.yaml +4 -4
  2. data/.envrc +3 -0
  3. data/.gitattributes +2 -0
  4. data/.github/workflows/linting.yml +6 -5
  5. data/.github/workflows/plugins.yml +48 -35
  6. data/.github/workflows/rspec.yml +15 -28
  7. data/.github/workflows/typecheck.yml +3 -2
  8. data/.gitignore +1 -0
  9. data/.rubocop.yml +38 -6
  10. data/.rubocop_todo.yml +53 -966
  11. data/CHANGELOG.md +24 -0
  12. data/Gemfile +3 -1
  13. data/README.md +3 -3
  14. data/Rakefile +26 -23
  15. data/bin/solargraph +9 -8
  16. data/lib/solargraph/api_map/cache.rb +110 -110
  17. data/lib/solargraph/api_map/constants.rb +288 -279
  18. data/lib/solargraph/api_map/index.rb +204 -193
  19. data/lib/solargraph/api_map/source_to_yard.rb +110 -97
  20. data/lib/solargraph/api_map/store.rb +395 -384
  21. data/lib/solargraph/api_map.rb +1029 -945
  22. data/lib/solargraph/bench.rb +44 -45
  23. data/lib/solargraph/complex_type/conformance.rb +176 -0
  24. data/lib/solargraph/complex_type/type_methods.rb +240 -228
  25. data/lib/solargraph/complex_type/unique_type.rb +641 -482
  26. data/lib/solargraph/complex_type.rb +557 -444
  27. data/lib/solargraph/convention/data_definition/data_assignment_node.rb +61 -61
  28. data/lib/solargraph/convention/data_definition/data_definition_node.rb +93 -91
  29. data/lib/solargraph/convention/data_definition.rb +108 -105
  30. data/lib/solargraph/convention/gemfile.rb +15 -15
  31. data/lib/solargraph/convention/gemspec.rb +23 -23
  32. data/lib/solargraph/convention/rakefile.rb +17 -17
  33. data/lib/solargraph/convention/struct_definition/struct_assignment_node.rb +62 -61
  34. data/lib/solargraph/convention/struct_definition/struct_definition_node.rb +103 -102
  35. data/lib/solargraph/convention/struct_definition.rb +168 -164
  36. data/lib/solargraph/convention.rb +78 -78
  37. data/lib/solargraph/converters/dd.rb +19 -17
  38. data/lib/solargraph/converters/dl.rb +17 -15
  39. data/lib/solargraph/converters/dt.rb +17 -15
  40. data/lib/solargraph/converters/misc.rb +3 -1
  41. data/lib/solargraph/diagnostics/require_not_found.rb +54 -53
  42. data/lib/solargraph/diagnostics/rubocop.rb +119 -118
  43. data/lib/solargraph/diagnostics/rubocop_helpers.rb +70 -68
  44. data/lib/solargraph/diagnostics/type_check.rb +56 -55
  45. data/lib/solargraph/diagnostics/update_errors.rb +37 -41
  46. data/lib/solargraph/doc_map.rb +438 -439
  47. data/lib/solargraph/equality.rb +34 -34
  48. data/lib/solargraph/gem_pins.rb +98 -98
  49. data/lib/solargraph/language_server/error_codes.rb +20 -20
  50. data/lib/solargraph/language_server/host/diagnoser.rb +89 -89
  51. data/lib/solargraph/language_server/host/dispatch.rb +130 -130
  52. data/lib/solargraph/language_server/host/message_worker.rb +113 -112
  53. data/lib/solargraph/language_server/host/sources.rb +100 -99
  54. data/lib/solargraph/language_server/host.rb +886 -878
  55. data/lib/solargraph/language_server/message/base.rb +97 -97
  56. data/lib/solargraph/language_server/message/client/register_capability.rb +13 -15
  57. data/lib/solargraph/language_server/message/completion_item/resolve.rb +58 -60
  58. data/lib/solargraph/language_server/message/extended/check_gem_version.rb +108 -114
  59. data/lib/solargraph/language_server/message/extended/document.rb +24 -23
  60. data/lib/solargraph/language_server/message/extended/document_gems.rb +32 -32
  61. data/lib/solargraph/language_server/message/extended/download_core.rb +20 -19
  62. data/lib/solargraph/language_server/message/extended/search.rb +20 -20
  63. data/lib/solargraph/language_server/message/initialize.rb +197 -191
  64. data/lib/solargraph/language_server/message/text_document/completion.rb +58 -56
  65. data/lib/solargraph/language_server/message/text_document/definition.rb +49 -40
  66. data/lib/solargraph/language_server/message/text_document/document_highlight.rb +23 -16
  67. data/lib/solargraph/language_server/message/text_document/document_symbol.rb +36 -26
  68. data/lib/solargraph/language_server/message/text_document/formatting.rb +150 -148
  69. data/lib/solargraph/language_server/message/text_document/hover.rb +58 -58
  70. data/lib/solargraph/language_server/message/text_document/prepare_rename.rb +18 -11
  71. data/lib/solargraph/language_server/message/text_document/references.rb +23 -16
  72. data/lib/solargraph/language_server/message/text_document/rename.rb +26 -19
  73. data/lib/solargraph/language_server/message/text_document/signature_help.rb +25 -24
  74. data/lib/solargraph/language_server/message/text_document/type_definition.rb +33 -25
  75. data/lib/solargraph/language_server/message/workspace/did_change_configuration.rb +41 -35
  76. data/lib/solargraph/language_server/message/workspace/did_change_watched_files.rb +48 -40
  77. data/lib/solargraph/language_server/message/workspace/did_change_workspace_folders.rb +32 -26
  78. data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +33 -23
  79. data/lib/solargraph/language_server/message.rb +94 -94
  80. data/lib/solargraph/language_server/request.rb +29 -27
  81. data/lib/solargraph/language_server/transport/data_reader.rb +72 -74
  82. data/lib/solargraph/language_server/uri_helpers.rb +49 -49
  83. data/lib/solargraph/library.rb +702 -683
  84. data/lib/solargraph/location.rb +85 -82
  85. data/lib/solargraph/logging.rb +55 -37
  86. data/lib/solargraph/page.rb +92 -92
  87. data/lib/solargraph/parser/comment_ripper.rb +84 -69
  88. data/lib/solargraph/parser/flow_sensitive_typing.rb +471 -255
  89. data/lib/solargraph/parser/node_processor/base.rb +122 -92
  90. data/lib/solargraph/parser/node_processor.rb +63 -62
  91. data/lib/solargraph/parser/parser_gem/class_methods.rb +165 -149
  92. data/lib/solargraph/parser/parser_gem/flawed_builder.rb +19 -19
  93. data/lib/solargraph/parser/parser_gem/node_chainer.rb +191 -166
  94. data/lib/solargraph/parser/parser_gem/node_methods.rb +507 -486
  95. data/lib/solargraph/parser/parser_gem/node_processors/and_node.rb +22 -22
  96. data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +61 -59
  97. data/lib/solargraph/parser/parser_gem/node_processors/begin_node.rb +24 -15
  98. data/lib/solargraph/parser/parser_gem/node_processors/block_node.rb +45 -46
  99. data/lib/solargraph/parser/parser_gem/node_processors/def_node.rb +60 -53
  100. data/lib/solargraph/parser/parser_gem/node_processors/defs_node.rb +38 -37
  101. data/lib/solargraph/parser/parser_gem/node_processors/if_node.rb +53 -23
  102. data/lib/solargraph/parser/parser_gem/node_processors/ivasgn_node.rb +42 -40
  103. data/lib/solargraph/parser/parser_gem/node_processors/lvasgn_node.rb +30 -29
  104. data/lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb +61 -59
  105. data/lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb +98 -98
  106. data/lib/solargraph/parser/parser_gem/node_processors/or_node.rb +22 -0
  107. data/lib/solargraph/parser/parser_gem/node_processors/orasgn_node.rb +17 -17
  108. data/lib/solargraph/parser/parser_gem/node_processors/resbody_node.rb +39 -38
  109. data/lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb +51 -52
  110. data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +302 -291
  111. data/lib/solargraph/parser/parser_gem/node_processors/until_node.rb +29 -29
  112. data/lib/solargraph/parser/parser_gem/node_processors/when_node.rb +23 -0
  113. data/lib/solargraph/parser/parser_gem/node_processors/while_node.rb +33 -29
  114. data/lib/solargraph/parser/parser_gem/node_processors.rb +74 -70
  115. data/lib/solargraph/parser/parser_gem.rb +14 -12
  116. data/lib/solargraph/parser/region.rb +75 -69
  117. data/lib/solargraph/parser/snippet.rb +19 -17
  118. data/lib/solargraph/parser.rb +25 -23
  119. data/lib/solargraph/pin/base.rb +773 -729
  120. data/lib/solargraph/pin/base_variable.rb +375 -126
  121. data/lib/solargraph/pin/block.rb +127 -104
  122. data/lib/solargraph/pin/breakable.rb +15 -9
  123. data/lib/solargraph/pin/callable.rb +275 -231
  124. data/lib/solargraph/pin/closure.rb +69 -72
  125. data/lib/solargraph/pin/common.rb +97 -79
  126. data/lib/solargraph/pin/compound_statement.rb +55 -0
  127. data/lib/solargraph/pin/constant.rb +43 -45
  128. data/lib/solargraph/pin/conversions.rb +129 -123
  129. data/lib/solargraph/pin/delegated_method.rb +131 -120
  130. data/lib/solargraph/pin/documenting.rb +116 -114
  131. data/lib/solargraph/pin/instance_variable.rb +38 -34
  132. data/lib/solargraph/pin/keyword.rb +16 -20
  133. data/lib/solargraph/pin/local_variable.rb +31 -75
  134. data/lib/solargraph/pin/method.rb +724 -672
  135. data/lib/solargraph/pin/method_alias.rb +42 -34
  136. data/lib/solargraph/pin/namespace.rb +122 -115
  137. data/lib/solargraph/pin/parameter.rb +339 -275
  138. data/lib/solargraph/pin/proxy_type.rb +42 -39
  139. data/lib/solargraph/pin/reference/override.rb +47 -47
  140. data/lib/solargraph/pin/reference/superclass.rb +17 -15
  141. data/lib/solargraph/pin/reference/type_alias.rb +16 -0
  142. data/lib/solargraph/pin/reference.rb +59 -39
  143. data/lib/solargraph/pin/search.rb +62 -61
  144. data/lib/solargraph/pin/signature.rb +64 -61
  145. data/lib/solargraph/pin/symbol.rb +54 -53
  146. data/lib/solargraph/pin/until.rb +16 -18
  147. data/lib/solargraph/pin/while.rb +16 -18
  148. data/lib/solargraph/pin.rb +46 -44
  149. data/lib/solargraph/pin_cache.rb +248 -245
  150. data/lib/solargraph/position.rb +139 -119
  151. data/lib/solargraph/range.rb +113 -112
  152. data/lib/solargraph/rbs_map/conversions.rb +952 -823
  153. data/lib/solargraph/rbs_map/core_fills.rb +91 -84
  154. data/lib/solargraph/rbs_map/core_map.rb +65 -58
  155. data/lib/solargraph/rbs_map/stdlib_map.rb +71 -43
  156. data/lib/solargraph/rbs_map.rb +207 -163
  157. data/lib/solargraph/server_methods.rb +16 -16
  158. data/lib/solargraph/shell.rb +555 -352
  159. data/lib/solargraph/source/chain/array.rb +39 -37
  160. data/lib/solargraph/source/chain/call.rb +377 -337
  161. data/lib/solargraph/source/chain/class_variable.rb +13 -13
  162. data/lib/solargraph/source/chain/constant.rb +30 -26
  163. data/lib/solargraph/source/chain/global_variable.rb +13 -13
  164. data/lib/solargraph/source/chain/hash.rb +37 -34
  165. data/lib/solargraph/source/chain/if.rb +30 -28
  166. data/lib/solargraph/source/chain/instance_variable.rb +36 -13
  167. data/lib/solargraph/source/chain/link.rb +99 -109
  168. data/lib/solargraph/source/chain/literal.rb +51 -48
  169. data/lib/solargraph/source/chain/or.rb +29 -23
  170. data/lib/solargraph/source/chain/q_call.rb +13 -11
  171. data/lib/solargraph/source/chain/variable.rb +15 -13
  172. data/lib/solargraph/source/chain/z_super.rb +28 -30
  173. data/lib/solargraph/source/chain.rb +304 -291
  174. data/lib/solargraph/source/change.rb +89 -82
  175. data/lib/solargraph/source/cursor.rb +172 -166
  176. data/lib/solargraph/source/encoding_fixes.rb +22 -23
  177. data/lib/solargraph/source/source_chainer.rb +218 -194
  178. data/lib/solargraph/source/updater.rb +59 -55
  179. data/lib/solargraph/source.rb +522 -498
  180. data/lib/solargraph/source_map/clip.rb +245 -226
  181. data/lib/solargraph/source_map/data.rb +37 -34
  182. data/lib/solargraph/source_map/mapper.rb +286 -259
  183. data/lib/solargraph/source_map.rb +224 -212
  184. data/lib/solargraph/type_checker/problem.rb +34 -32
  185. data/lib/solargraph/type_checker/rules.rb +157 -84
  186. data/lib/solargraph/type_checker.rb +888 -814
  187. data/lib/solargraph/version.rb +5 -5
  188. data/lib/solargraph/workspace/config.rb +258 -255
  189. data/lib/solargraph/workspace/gemspecs.rb +367 -0
  190. data/lib/solargraph/workspace/require_paths.rb +98 -97
  191. data/lib/solargraph/workspace.rb +242 -220
  192. data/lib/solargraph/yard_map/helpers.rb +49 -44
  193. data/lib/solargraph/yard_map/mapper/to_method.rb +136 -130
  194. data/lib/solargraph/yard_map/mapper/to_namespace.rb +32 -31
  195. data/lib/solargraph/yard_map/mapper.rb +84 -79
  196. data/lib/solargraph/yard_map.rb +17 -18
  197. data/lib/solargraph/yard_tags.rb +20 -20
  198. data/lib/solargraph/yardoc.rb +90 -87
  199. data/lib/solargraph.rb +128 -105
  200. data/rbs/fills/rubygems/0/dependency.rbs +193 -0
  201. data/rbs/fills/tuple/tuple.rbs +28 -0
  202. data/rbs/shims/ast/0/node.rbs +5 -0
  203. data/rbs/shims/diff-lcs/1.5/diff-lcs.rbs +11 -0
  204. data/rbs_collection.yaml +1 -1
  205. data/solargraph.gemspec +37 -35
  206. metadata +52 -51
  207. data/lib/solargraph/type_checker/checks.rb +0 -124
  208. data/lib/solargraph/type_checker/param_def.rb +0 -37
  209. data/lib/solargraph/yard_map/to_method.rb +0 -89
  210. data/sig/shims/ast/0/node.rbs +0 -5
  211. /data/{sig → rbs}/shims/ast/2.4/.rbs_meta.yaml +0 -0
  212. /data/{sig → rbs}/shims/ast/2.4/ast.rbs +0 -0
  213. /data/{sig → rbs}/shims/parser/3.2.0.1/builders/default.rbs +0 -0
  214. /data/{sig → rbs}/shims/parser/3.2.0.1/manifest.yaml +0 -0
  215. /data/{sig → rbs}/shims/parser/3.2.0.1/parser.rbs +0 -0
  216. /data/{sig → rbs}/shims/parser/3.2.0.1/polyfill.rbs +0 -0
  217. /data/{sig → rbs}/shims/thor/1.2.0.1/.rbs_meta.yaml +0 -0
  218. /data/{sig → rbs}/shims/thor/1.2.0.1/manifest.yaml +0 -0
  219. /data/{sig → rbs}/shims/thor/1.2.0.1/thor.rbs +0 -0
@@ -1,245 +1,248 @@
1
- require 'yard-activesupport-concern'
2
- require 'fileutils'
3
- require 'rbs'
4
-
5
- module Solargraph
6
- module PinCache
7
- class << self
8
- include Logging
9
-
10
- # The base directory where cached YARD documentation and serialized pins are serialized
11
- #
12
- # @return [String]
13
- def base_dir
14
- # The directory is not stored in a variable so it can be overridden
15
- # in specs.
16
- ENV['SOLARGRAPH_CACHE'] ||
17
- (ENV['XDG_CACHE_HOME'] ? File.join(ENV['XDG_CACHE_HOME'], 'solargraph') : nil) ||
18
- File.join(Dir.home, '.cache', 'solargraph')
19
- end
20
-
21
- # The working directory for the current Ruby, RBS, and Solargraph versions.
22
- #
23
- # @return [String]
24
- def work_dir
25
- # The directory is not stored in a variable so it can be overridden
26
- # in specs.
27
- File.join(base_dir, "ruby-#{RUBY_VERSION}", "rbs-#{RBS::VERSION}", "solargraph-#{Solargraph::VERSION}")
28
- end
29
-
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
- # @return [String]
40
- def stdlib_path
41
- File.join(work_dir, 'stdlib')
42
- end
43
-
44
- # @param require [String]
45
- # @return [String]
46
- def stdlib_require_path require
47
- File.join(stdlib_path, "#{require}.ser")
48
- end
49
-
50
- # @param require [String]
51
- # @return [Array<Pin::Base>, nil]
52
- def deserialize_stdlib_require require
53
- load(stdlib_require_path(require))
54
- end
55
-
56
- # @param require [String]
57
- # @param pins [Array<Pin::Base>]
58
- # @return [void]
59
- def serialize_stdlib_require require, pins
60
- save(stdlib_require_path(require), pins)
61
- end
62
-
63
- # @return [String]
64
- def core_path
65
- File.join(work_dir, 'core.ser')
66
- end
67
-
68
- # @return [Array<Pin::Base>, nil]
69
- def deserialize_core
70
- load(core_path)
71
- end
72
-
73
- # @param pins [Array<Pin::Base>]
74
- # @return [void]
75
- def serialize_core pins
76
- save(core_path, pins)
77
- end
78
-
79
- # @param gemspec [Gem::Specification]
80
- # @return [String]
81
- def yard_gem_path gemspec
82
- File.join(work_dir, 'yard', "#{gemspec.name}-#{gemspec.version}.ser")
83
- end
84
-
85
- # @param gemspec [Gem::Specification]
86
- # @return [Array<Pin::Base>, nil]
87
- def deserialize_yard_gem(gemspec)
88
- load(yard_gem_path(gemspec))
89
- end
90
-
91
- # @param gemspec [Gem::Specification]
92
- # @param pins [Array<Pin::Base>]
93
- # @return [void]
94
- def serialize_yard_gem(gemspec, pins)
95
- save(yard_gem_path(gemspec), pins)
96
- end
97
-
98
- # @param gemspec [Gem::Specification]
99
- # @return [Boolean]
100
- def has_yard?(gemspec)
101
- exist?(yard_gem_path(gemspec))
102
- end
103
-
104
- # @param gemspec [Gem::Specification]
105
- # @param hash [String, nil]
106
- # @return [String]
107
- def rbs_collection_path(gemspec, hash)
108
- File.join(work_dir, 'rbs', "#{gemspec.name}-#{gemspec.version}-#{hash || 0}.ser")
109
- end
110
-
111
- # @param gemspec [Gem::Specification]
112
- # @return [String]
113
- def rbs_collection_path_prefix(gemspec)
114
- File.join(work_dir, 'rbs', "#{gemspec.name}-#{gemspec.version}-")
115
- end
116
-
117
- # @param gemspec [Gem::Specification]
118
- # @param hash [String, nil]
119
- # @return [Array<Pin::Base>, nil]
120
- def deserialize_rbs_collection_gem(gemspec, hash)
121
- load(rbs_collection_path(gemspec, hash))
122
- end
123
-
124
- # @param gemspec [Gem::Specification]
125
- # @param hash [String, nil]
126
- # @param pins [Array<Pin::Base>]n
127
- # @return [void]
128
- def serialize_rbs_collection_gem(gemspec, hash, pins)
129
- save(rbs_collection_path(gemspec, hash), pins)
130
- end
131
-
132
- # @param gemspec [Gem::Specification]
133
- # @param hash [String, nil]
134
- # @return [String]
135
- def combined_path(gemspec, hash)
136
- File.join(work_dir, 'combined', "#{gemspec.name}-#{gemspec.version}-#{hash || 0}.ser")
137
- end
138
-
139
- # @param gemspec [Gem::Specification]
140
- # @return [String]
141
- def combined_path_prefix(gemspec)
142
- File.join(work_dir, 'combined', "#{gemspec.name}-#{gemspec.version}-")
143
- end
144
-
145
- # @param gemspec [Gem::Specification]
146
- # @param hash [String, nil]
147
- # @param pins [Array<Pin::Base>]
148
- # @return [void]
149
- def serialize_combined_gem(gemspec, hash, pins)
150
- save(combined_path(gemspec, hash), pins)
151
- end
152
-
153
- # @param gemspec [Gem::Specification]
154
- # @param hash [String, nil]
155
- # @return [Array<Pin::Base>, nil]
156
- def deserialize_combined_gem gemspec, hash
157
- load(combined_path(gemspec, hash))
158
- end
159
-
160
- # @param gemspec [Gem::Specification]
161
- # @param hash [String, nil]
162
- # @return [Boolean]
163
- def has_rbs_collection?(gemspec, hash)
164
- exist?(rbs_collection_path(gemspec, hash))
165
- end
166
-
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
- # @return [void]
188
- def clear
189
- FileUtils.rm_rf base_dir, secure: true
190
- end
191
-
192
- private
193
-
194
- # @param file [String]
195
- # @return [Array<Solargraph::Pin::Base>, nil]
196
- def load file
197
- return nil unless File.file?(file)
198
- Marshal.load(File.read(file, mode: 'rb'))
199
- rescue StandardError => e
200
- Solargraph.logger.warn "Failed to load cached file #{file}: [#{e.class}] #{e.message}"
201
- FileUtils.rm_f file
202
- nil
203
- end
204
-
205
- # @param path [String]
206
- def exist? *path
207
- File.file? File.join(*path)
208
- end
209
-
210
- # @param file [String]
211
- # @param pins [Array<Pin::Base>]
212
- # @return [void]
213
- def save file, pins
214
- base = File.dirname(file)
215
- FileUtils.mkdir_p base unless File.directory?(base)
216
- ser = Marshal.dump(pins)
217
- File.write file, ser, mode: 'wb'
218
- logger.debug { "Cache#save: Saved #{pins.length} pins to #{file}" }
219
- end
220
-
221
- # @param path_segments [Array<String>]
222
- # @return [void]
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
229
- end
230
-
231
- # @return [void]
232
- # @param path_segments [Array<String>]
233
- def uncache_by_prefix *path_segments, out: nil
234
- path = File.join(*path_segments)
235
- glob = "#{path}*"
236
- out.puts "Clearing pin cache in #{glob}" unless out.nil?
237
- Dir.glob(glob).each do |file|
238
- next unless File.file?(file)
239
- FileUtils.rm_rf file, secure: true
240
- out.puts "Clearing pin cache in #{file}" unless out.nil?
241
- end
242
- end
243
- end
244
- end
245
- end
1
+ require 'yard-activesupport-concern'
2
+ require 'fileutils'
3
+ require 'pathname' # @todo Required by RBS but not loaded in some use cases
4
+ require 'rbs'
5
+
6
+ module Solargraph
7
+ module PinCache
8
+ class << self
9
+ include Logging
10
+
11
+ # The base directory where cached YARD documentation and serialized pins are serialized
12
+ #
13
+ # @return [String]
14
+ def base_dir
15
+ # The directory is not stored in a variable so it can be overridden
16
+ # in specs.
17
+ ENV['SOLARGRAPH_CACHE'] ||
18
+ (ENV['XDG_CACHE_HOME'] ? File.join(ENV['XDG_CACHE_HOME'], 'solargraph') : nil) ||
19
+ File.join(Dir.home, '.cache', 'solargraph')
20
+ end
21
+
22
+ # The working directory for the current Ruby, RBS, and Solargraph versions.
23
+ #
24
+ # @return [String]
25
+ def work_dir
26
+ # The directory is not stored in a variable so it can be overridden
27
+ # in specs.
28
+ File.join(base_dir, "ruby-#{RUBY_VERSION}", "rbs-#{RBS::VERSION}", "solargraph-#{Solargraph::VERSION}")
29
+ end
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
+
40
+ # @return [String]
41
+ def stdlib_path
42
+ File.join(work_dir, 'stdlib')
43
+ end
44
+
45
+ # @param require [String]
46
+ # @return [String]
47
+ def stdlib_require_path require
48
+ File.join(stdlib_path, "#{require}.ser")
49
+ end
50
+
51
+ # @param require [String]
52
+ # @return [Array<Pin::Base>, nil]
53
+ def deserialize_stdlib_require require
54
+ load(stdlib_require_path(require))
55
+ end
56
+
57
+ # @param require [String]
58
+ # @param pins [Array<Pin::Base>]
59
+ # @return [void]
60
+ def serialize_stdlib_require require, pins
61
+ save(stdlib_require_path(require), pins)
62
+ end
63
+
64
+ # @return [String]
65
+ def core_path
66
+ File.join(work_dir, 'core.ser')
67
+ end
68
+
69
+ # @return [Array<Pin::Base>, nil]
70
+ def deserialize_core
71
+ load(core_path)
72
+ end
73
+
74
+ # @param pins [Array<Pin::Base>]
75
+ # @return [void]
76
+ def serialize_core pins
77
+ save(core_path, pins)
78
+ end
79
+
80
+ # @param gemspec [Gem::Specification]
81
+ # @return [String]
82
+ def yard_gem_path gemspec
83
+ File.join(work_dir, 'yard', "#{gemspec.name}-#{gemspec.version}.ser")
84
+ end
85
+
86
+ # @param gemspec [Gem::Specification]
87
+ # @return [Array<Pin::Base>, nil]
88
+ def deserialize_yard_gem gemspec
89
+ load(yard_gem_path(gemspec))
90
+ end
91
+
92
+ # @param gemspec [Gem::Specification]
93
+ # @param pins [Array<Pin::Base>]
94
+ # @return [void]
95
+ def serialize_yard_gem gemspec, pins
96
+ save(yard_gem_path(gemspec), pins)
97
+ end
98
+
99
+ # @param gemspec [Gem::Specification]
100
+ # @return [Boolean]
101
+ def has_yard? gemspec
102
+ exist?(yard_gem_path(gemspec))
103
+ end
104
+
105
+ # @param gemspec [Gem::Specification]
106
+ # @param hash [String, nil]
107
+ # @return [String]
108
+ def rbs_collection_path gemspec, hash
109
+ File.join(work_dir, 'rbs', "#{gemspec.name}-#{gemspec.version}-#{hash || 0}.ser")
110
+ end
111
+
112
+ # @param gemspec [Gem::Specification]
113
+ # @return [String]
114
+ def rbs_collection_path_prefix gemspec
115
+ File.join(work_dir, 'rbs', "#{gemspec.name}-#{gemspec.version}-")
116
+ end
117
+
118
+ # @param gemspec [Gem::Specification]
119
+ # @param hash [String, nil]
120
+ # @return [Array<Pin::Base>, nil]
121
+ def deserialize_rbs_collection_gem gemspec, hash
122
+ load(rbs_collection_path(gemspec, hash))
123
+ end
124
+
125
+ # @param gemspec [Gem::Specification]
126
+ # @param hash [String, nil]
127
+ # @param pins [Array<Pin::Base>]n
128
+ # @return [void]
129
+ def serialize_rbs_collection_gem gemspec, hash, pins
130
+ save(rbs_collection_path(gemspec, hash), pins)
131
+ end
132
+
133
+ # @param gemspec [Gem::Specification]
134
+ # @param hash [String, nil]
135
+ # @return [String]
136
+ def combined_path gemspec, hash
137
+ File.join(work_dir, 'combined', "#{gemspec.name}-#{gemspec.version}-#{hash || 0}.ser")
138
+ end
139
+
140
+ # @param gemspec [Gem::Specification]
141
+ # @return [String]
142
+ def combined_path_prefix gemspec
143
+ File.join(work_dir, 'combined', "#{gemspec.name}-#{gemspec.version}-")
144
+ end
145
+
146
+ # @param gemspec [Gem::Specification]
147
+ # @param hash [String, nil]
148
+ # @param pins [Array<Pin::Base>]
149
+ # @return [void]
150
+ def serialize_combined_gem gemspec, hash, pins
151
+ save(combined_path(gemspec, hash), pins)
152
+ end
153
+
154
+ # @param gemspec [Gem::Specification]
155
+ # @param hash [String, nil]
156
+ # @return [Array<Pin::Base>, nil]
157
+ def deserialize_combined_gem gemspec, hash
158
+ load(combined_path(gemspec, hash))
159
+ end
160
+
161
+ # @param gemspec [Gem::Specification]
162
+ # @param hash [String, nil]
163
+ # @return [Boolean]
164
+ def has_rbs_collection? gemspec, hash
165
+ exist?(rbs_collection_path(gemspec, hash))
166
+ end
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
+
188
+ # @return [void]
189
+ def clear
190
+ FileUtils.rm_rf base_dir, secure: true
191
+ end
192
+
193
+ private
194
+
195
+ # @param file [String]
196
+ # @sg-ignore Marshal.load returns Object; we know it's Array<Pin::Base>
197
+ # @return [Array<Solargraph::Pin::Base>, nil]
198
+ def load file
199
+ return nil unless File.file?(file)
200
+ Marshal.load(File.read(file, mode: 'rb'))
201
+ rescue StandardError => e
202
+ Solargraph.logger.warn "Failed to load cached file #{file}: [#{e.class}] #{e.message}"
203
+ FileUtils.rm_f file
204
+ nil
205
+ end
206
+
207
+ # @param path [String]
208
+ def exist? *path
209
+ File.file? File.join(*path)
210
+ end
211
+
212
+ # @param file [String]
213
+ # @param pins [Array<Pin::Base>]
214
+ # @return [void]
215
+ def save file, pins
216
+ base = File.dirname(file)
217
+ FileUtils.mkdir_p base unless File.directory?(base)
218
+ ser = Marshal.dump(pins)
219
+ File.write file, ser, mode: 'wb'
220
+ logger.debug { "Cache#save: Saved #{pins.length} pins to #{file}" }
221
+ end
222
+
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}"
231
+ end
232
+
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
245
+ end
246
+ end
247
+ end
248
+ end