solargraph 0.58.1 → 0.58.2

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 (147) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/CHANGELOG.md +7 -1
  4. data/lib/solargraph/api_map/cache.rb +110 -110
  5. data/lib/solargraph/api_map/constants.rb +279 -279
  6. data/lib/solargraph/api_map/index.rb +193 -193
  7. data/lib/solargraph/api_map/source_to_yard.rb +97 -97
  8. data/lib/solargraph/api_map/store.rb +384 -384
  9. data/lib/solargraph/api_map.rb +945 -945
  10. data/lib/solargraph/complex_type/type_methods.rb +228 -228
  11. data/lib/solargraph/complex_type/unique_type.rb +482 -482
  12. data/lib/solargraph/complex_type.rb +444 -444
  13. data/lib/solargraph/convention/data_definition/data_definition_node.rb +91 -91
  14. data/lib/solargraph/convention/data_definition.rb +105 -105
  15. data/lib/solargraph/convention/struct_definition/struct_assignment_node.rb +61 -61
  16. data/lib/solargraph/convention/struct_definition/struct_definition_node.rb +102 -102
  17. data/lib/solargraph/convention/struct_definition.rb +164 -164
  18. data/lib/solargraph/diagnostics/require_not_found.rb +53 -53
  19. data/lib/solargraph/diagnostics/rubocop.rb +118 -118
  20. data/lib/solargraph/diagnostics/rubocop_helpers.rb +68 -68
  21. data/lib/solargraph/diagnostics/type_check.rb +55 -55
  22. data/lib/solargraph/doc_map.rb +439 -439
  23. data/lib/solargraph/equality.rb +34 -34
  24. data/lib/solargraph/gem_pins.rb +98 -98
  25. data/lib/solargraph/language_server/host/diagnoser.rb +89 -89
  26. data/lib/solargraph/language_server/host/dispatch.rb +130 -130
  27. data/lib/solargraph/language_server/host/message_worker.rb +112 -112
  28. data/lib/solargraph/language_server/host/sources.rb +99 -99
  29. data/lib/solargraph/language_server/host.rb +878 -878
  30. data/lib/solargraph/language_server/message/extended/check_gem_version.rb +114 -114
  31. data/lib/solargraph/language_server/message/extended/document.rb +23 -23
  32. data/lib/solargraph/language_server/message/text_document/completion.rb +56 -56
  33. data/lib/solargraph/language_server/message/text_document/definition.rb +40 -40
  34. data/lib/solargraph/language_server/message/text_document/document_symbol.rb +26 -26
  35. data/lib/solargraph/language_server/message/text_document/formatting.rb +148 -148
  36. data/lib/solargraph/language_server/message/text_document/hover.rb +58 -58
  37. data/lib/solargraph/language_server/message/text_document/signature_help.rb +24 -24
  38. data/lib/solargraph/language_server/message/text_document/type_definition.rb +25 -25
  39. data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +23 -23
  40. data/lib/solargraph/library.rb +683 -683
  41. data/lib/solargraph/location.rb +82 -82
  42. data/lib/solargraph/logging.rb +37 -37
  43. data/lib/solargraph/parser/comment_ripper.rb +69 -69
  44. data/lib/solargraph/parser/flow_sensitive_typing.rb +255 -255
  45. data/lib/solargraph/parser/node_processor/base.rb +92 -92
  46. data/lib/solargraph/parser/node_processor.rb +62 -62
  47. data/lib/solargraph/parser/parser_gem/class_methods.rb +149 -149
  48. data/lib/solargraph/parser/parser_gem/node_chainer.rb +166 -166
  49. data/lib/solargraph/parser/parser_gem/node_methods.rb +486 -486
  50. data/lib/solargraph/parser/parser_gem/node_processors/and_node.rb +22 -22
  51. data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +59 -59
  52. data/lib/solargraph/parser/parser_gem/node_processors/begin_node.rb +15 -15
  53. data/lib/solargraph/parser/parser_gem/node_processors/block_node.rb +46 -46
  54. data/lib/solargraph/parser/parser_gem/node_processors/def_node.rb +53 -53
  55. data/lib/solargraph/parser/parser_gem/node_processors/if_node.rb +23 -23
  56. data/lib/solargraph/parser/parser_gem/node_processors/ivasgn_node.rb +40 -40
  57. data/lib/solargraph/parser/parser_gem/node_processors/lvasgn_node.rb +29 -29
  58. data/lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb +59 -59
  59. data/lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb +98 -98
  60. data/lib/solargraph/parser/parser_gem/node_processors/orasgn_node.rb +17 -17
  61. data/lib/solargraph/parser/parser_gem/node_processors/resbody_node.rb +38 -38
  62. data/lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb +52 -52
  63. data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +291 -291
  64. data/lib/solargraph/parser/parser_gem/node_processors/while_node.rb +29 -29
  65. data/lib/solargraph/parser/parser_gem/node_processors.rb +70 -70
  66. data/lib/solargraph/parser/region.rb +69 -69
  67. data/lib/solargraph/parser/snippet.rb +17 -17
  68. data/lib/solargraph/pin/base.rb +729 -729
  69. data/lib/solargraph/pin/base_variable.rb +126 -126
  70. data/lib/solargraph/pin/block.rb +104 -104
  71. data/lib/solargraph/pin/breakable.rb +9 -9
  72. data/lib/solargraph/pin/callable.rb +231 -231
  73. data/lib/solargraph/pin/closure.rb +72 -72
  74. data/lib/solargraph/pin/common.rb +79 -79
  75. data/lib/solargraph/pin/conversions.rb +123 -123
  76. data/lib/solargraph/pin/delegated_method.rb +120 -120
  77. data/lib/solargraph/pin/documenting.rb +114 -114
  78. data/lib/solargraph/pin/instance_variable.rb +34 -34
  79. data/lib/solargraph/pin/keyword.rb +20 -20
  80. data/lib/solargraph/pin/local_variable.rb +75 -75
  81. data/lib/solargraph/pin/method.rb +672 -672
  82. data/lib/solargraph/pin/method_alias.rb +34 -34
  83. data/lib/solargraph/pin/namespace.rb +115 -115
  84. data/lib/solargraph/pin/parameter.rb +275 -275
  85. data/lib/solargraph/pin/proxy_type.rb +39 -39
  86. data/lib/solargraph/pin/reference/override.rb +47 -47
  87. data/lib/solargraph/pin/reference/superclass.rb +15 -15
  88. data/lib/solargraph/pin/reference.rb +39 -39
  89. data/lib/solargraph/pin/search.rb +61 -61
  90. data/lib/solargraph/pin/signature.rb +61 -61
  91. data/lib/solargraph/pin/symbol.rb +53 -53
  92. data/lib/solargraph/pin/until.rb +18 -18
  93. data/lib/solargraph/pin/while.rb +18 -18
  94. data/lib/solargraph/pin.rb +44 -44
  95. data/lib/solargraph/pin_cache.rb +245 -245
  96. data/lib/solargraph/position.rb +132 -119
  97. data/lib/solargraph/range.rb +112 -112
  98. data/lib/solargraph/rbs_map/conversions.rb +823 -823
  99. data/lib/solargraph/rbs_map/core_map.rb +58 -58
  100. data/lib/solargraph/rbs_map/stdlib_map.rb +43 -43
  101. data/lib/solargraph/rbs_map.rb +163 -163
  102. data/lib/solargraph/shell.rb +352 -352
  103. data/lib/solargraph/source/chain/call.rb +337 -337
  104. data/lib/solargraph/source/chain/constant.rb +26 -26
  105. data/lib/solargraph/source/chain/hash.rb +34 -34
  106. data/lib/solargraph/source/chain/if.rb +28 -28
  107. data/lib/solargraph/source/chain/instance_variable.rb +13 -13
  108. data/lib/solargraph/source/chain/literal.rb +48 -48
  109. data/lib/solargraph/source/chain/or.rb +23 -23
  110. data/lib/solargraph/source/chain.rb +291 -291
  111. data/lib/solargraph/source/change.rb +82 -82
  112. data/lib/solargraph/source/cursor.rb +166 -166
  113. data/lib/solargraph/source/source_chainer.rb +194 -194
  114. data/lib/solargraph/source/updater.rb +55 -55
  115. data/lib/solargraph/source.rb +498 -498
  116. data/lib/solargraph/source_map/clip.rb +226 -226
  117. data/lib/solargraph/source_map/data.rb +34 -34
  118. data/lib/solargraph/source_map/mapper.rb +259 -259
  119. data/lib/solargraph/source_map.rb +212 -212
  120. data/lib/solargraph/type_checker/checks.rb +124 -124
  121. data/lib/solargraph/type_checker/param_def.rb +37 -37
  122. data/lib/solargraph/type_checker/problem.rb +32 -32
  123. data/lib/solargraph/type_checker/rules.rb +84 -84
  124. data/lib/solargraph/type_checker.rb +814 -814
  125. data/lib/solargraph/version.rb +1 -1
  126. data/lib/solargraph/workspace/config.rb +255 -255
  127. data/lib/solargraph/workspace/require_paths.rb +97 -97
  128. data/lib/solargraph/workspace.rb +220 -220
  129. data/lib/solargraph/yard_map/helpers.rb +44 -44
  130. data/lib/solargraph/yard_map/mapper/to_method.rb +130 -130
  131. data/lib/solargraph/yard_map/mapper/to_namespace.rb +31 -31
  132. data/lib/solargraph/yard_map/mapper.rb +79 -79
  133. data/lib/solargraph/yard_map/to_method.rb +89 -89
  134. data/lib/solargraph/yardoc.rb +87 -87
  135. data/lib/solargraph.rb +105 -105
  136. data/rbs_collection.yaml +1 -1
  137. metadata +12 -12
  138. /data/{sig → rbs}/shims/ast/0/node.rbs +0 -0
  139. /data/{sig → rbs}/shims/ast/2.4/.rbs_meta.yaml +0 -0
  140. /data/{sig → rbs}/shims/ast/2.4/ast.rbs +0 -0
  141. /data/{sig → rbs}/shims/parser/3.2.0.1/builders/default.rbs +0 -0
  142. /data/{sig → rbs}/shims/parser/3.2.0.1/manifest.yaml +0 -0
  143. /data/{sig → rbs}/shims/parser/3.2.0.1/parser.rbs +0 -0
  144. /data/{sig → rbs}/shims/parser/3.2.0.1/polyfill.rbs +0 -0
  145. /data/{sig → rbs}/shims/thor/1.2.0.1/.rbs_meta.yaml +0 -0
  146. /data/{sig → rbs}/shims/thor/1.2.0.1/manifest.yaml +0 -0
  147. /data/{sig → rbs}/shims/thor/1.2.0.1/thor.rbs +0 -0
@@ -1,44 +1,44 @@
1
- # frozen_string_literal: true
2
-
3
- require 'yard'
4
-
5
- module Solargraph
6
- # The namespace for Pins used in SourceMaps.
7
- #
8
- # Pins represent declarations, from gems, Sources, and the Ruby core.
9
- #
10
- module Pin
11
- autoload :Common, 'solargraph/pin/common'
12
- autoload :Conversions, 'solargraph/pin/conversions'
13
- autoload :Base, 'solargraph/pin/base'
14
- autoload :Method, 'solargraph/pin/method'
15
- autoload :Signature, 'solargraph/pin/signature'
16
- autoload :MethodAlias, 'solargraph/pin/method_alias'
17
- autoload :DelegatedMethod, 'solargraph/pin/delegated_method'
18
- autoload :BaseVariable, 'solargraph/pin/base_variable'
19
- autoload :InstanceVariable, 'solargraph/pin/instance_variable'
20
- autoload :ClassVariable, 'solargraph/pin/class_variable'
21
- autoload :LocalVariable, 'solargraph/pin/local_variable'
22
- autoload :GlobalVariable, 'solargraph/pin/global_variable'
23
- autoload :Constant, 'solargraph/pin/constant'
24
- autoload :Symbol, 'solargraph/pin/symbol'
25
- autoload :Closure, 'solargraph/pin/closure'
26
- autoload :Namespace, 'solargraph/pin/namespace'
27
- autoload :Keyword, 'solargraph/pin/keyword'
28
- autoload :Parameter, 'solargraph/pin/parameter'
29
- autoload :Reference, 'solargraph/pin/reference'
30
- autoload :Documenting, 'solargraph/pin/documenting'
31
- autoload :Block, 'solargraph/pin/block'
32
- autoload :ProxyType, 'solargraph/pin/proxy_type'
33
- autoload :DuckMethod, 'solargraph/pin/duck_method'
34
- autoload :Singleton, 'solargraph/pin/singleton'
35
- autoload :KeywordParam, 'solargraph/pin/keyword_param'
36
- autoload :Search, 'solargraph/pin/search'
37
- autoload :Breakable, 'solargraph/pin/breakable'
38
- autoload :Until, 'solargraph/pin/until'
39
- autoload :While, 'solargraph/pin/while'
40
- autoload :Callable, 'solargraph/pin/callable'
41
-
42
- ROOT_PIN = Pin::Namespace.new(type: :class, name: '', closure: nil, source: :pin_rb)
43
- end
44
- end
1
+ # frozen_string_literal: true
2
+
3
+ require 'yard'
4
+
5
+ module Solargraph
6
+ # The namespace for Pins used in SourceMaps.
7
+ #
8
+ # Pins represent declarations, from gems, Sources, and the Ruby core.
9
+ #
10
+ module Pin
11
+ autoload :Common, 'solargraph/pin/common'
12
+ autoload :Conversions, 'solargraph/pin/conversions'
13
+ autoload :Base, 'solargraph/pin/base'
14
+ autoload :Method, 'solargraph/pin/method'
15
+ autoload :Signature, 'solargraph/pin/signature'
16
+ autoload :MethodAlias, 'solargraph/pin/method_alias'
17
+ autoload :DelegatedMethod, 'solargraph/pin/delegated_method'
18
+ autoload :BaseVariable, 'solargraph/pin/base_variable'
19
+ autoload :InstanceVariable, 'solargraph/pin/instance_variable'
20
+ autoload :ClassVariable, 'solargraph/pin/class_variable'
21
+ autoload :LocalVariable, 'solargraph/pin/local_variable'
22
+ autoload :GlobalVariable, 'solargraph/pin/global_variable'
23
+ autoload :Constant, 'solargraph/pin/constant'
24
+ autoload :Symbol, 'solargraph/pin/symbol'
25
+ autoload :Closure, 'solargraph/pin/closure'
26
+ autoload :Namespace, 'solargraph/pin/namespace'
27
+ autoload :Keyword, 'solargraph/pin/keyword'
28
+ autoload :Parameter, 'solargraph/pin/parameter'
29
+ autoload :Reference, 'solargraph/pin/reference'
30
+ autoload :Documenting, 'solargraph/pin/documenting'
31
+ autoload :Block, 'solargraph/pin/block'
32
+ autoload :ProxyType, 'solargraph/pin/proxy_type'
33
+ autoload :DuckMethod, 'solargraph/pin/duck_method'
34
+ autoload :Singleton, 'solargraph/pin/singleton'
35
+ autoload :KeywordParam, 'solargraph/pin/keyword_param'
36
+ autoload :Search, 'solargraph/pin/search'
37
+ autoload :Breakable, 'solargraph/pin/breakable'
38
+ autoload :Until, 'solargraph/pin/until'
39
+ autoload :While, 'solargraph/pin/while'
40
+ autoload :Callable, 'solargraph/pin/callable'
41
+
42
+ ROOT_PIN = Pin::Namespace.new(type: :class, name: '', closure: nil, source: :pin_rb)
43
+ end
44
+ end
@@ -1,245 +1,245 @@
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 '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