solargraph 0.47.2 → 0.54.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 (191) hide show
  1. checksums.yaml +4 -4
  2. data/.github/FUNDING.yml +1 -0
  3. data/.github/workflows/plugins.yml +40 -0
  4. data/.github/workflows/rspec.yml +4 -8
  5. data/.github/workflows/typecheck.yml +34 -0
  6. data/.yardopts +2 -2
  7. data/CHANGELOG.md +166 -3
  8. data/LICENSE +1 -1
  9. data/README.md +19 -16
  10. data/SPONSORS.md +2 -9
  11. data/lib/solargraph/api_map/cache.rb +50 -20
  12. data/lib/solargraph/api_map/source_to_yard.rb +17 -10
  13. data/lib/solargraph/api_map/store.rb +68 -15
  14. data/lib/solargraph/api_map.rb +238 -112
  15. data/lib/solargraph/bench.rb +3 -2
  16. data/lib/solargraph/cache.rb +77 -0
  17. data/lib/solargraph/complex_type/type_methods.rb +116 -35
  18. data/lib/solargraph/complex_type/unique_type.rb +261 -33
  19. data/lib/solargraph/complex_type.rb +149 -30
  20. data/lib/solargraph/convention/rakefile.rb +17 -0
  21. data/lib/solargraph/convention.rb +2 -3
  22. data/lib/solargraph/converters/dd.rb +5 -0
  23. data/lib/solargraph/converters/dl.rb +3 -0
  24. data/lib/solargraph/converters/dt.rb +3 -0
  25. data/lib/solargraph/diagnostics/rubocop.rb +23 -8
  26. data/lib/solargraph/diagnostics/rubocop_helpers.rb +4 -1
  27. data/lib/solargraph/diagnostics/type_check.rb +1 -0
  28. data/lib/solargraph/diagnostics.rb +2 -2
  29. data/lib/solargraph/doc_map.rb +187 -0
  30. data/lib/solargraph/gem_pins.rb +72 -0
  31. data/lib/solargraph/language_server/host/diagnoser.rb +2 -2
  32. data/lib/solargraph/language_server/host/dispatch.rb +22 -5
  33. data/lib/solargraph/language_server/host/message_worker.rb +4 -0
  34. data/lib/solargraph/language_server/host/sources.rb +8 -65
  35. data/lib/solargraph/language_server/host.rb +88 -93
  36. data/lib/solargraph/language_server/message/base.rb +1 -1
  37. data/lib/solargraph/language_server/message/completion_item/resolve.rb +3 -1
  38. data/lib/solargraph/language_server/message/extended/check_gem_version.rb +13 -1
  39. data/lib/solargraph/language_server/message/extended/download_core.rb +1 -5
  40. data/lib/solargraph/language_server/message/initialize.rb +27 -0
  41. data/lib/solargraph/language_server/message/initialized.rb +1 -0
  42. data/lib/solargraph/language_server/message/text_document/document_symbol.rb +4 -1
  43. data/lib/solargraph/language_server/message/text_document/formatting.rb +5 -4
  44. data/lib/solargraph/language_server/message/text_document/hover.rb +2 -0
  45. data/lib/solargraph/language_server/message/text_document/signature_help.rb +1 -6
  46. data/lib/solargraph/language_server/message/text_document/type_definition.rb +24 -0
  47. data/lib/solargraph/language_server/message/text_document.rb +1 -1
  48. data/lib/solargraph/language_server/message/workspace/did_change_configuration.rb +5 -0
  49. data/lib/solargraph/language_server/message/workspace/did_change_watched_files.rb +10 -3
  50. data/lib/solargraph/language_server/message.rb +1 -0
  51. data/lib/solargraph/language_server/progress.rb +118 -0
  52. data/lib/solargraph/language_server/transport/adapter.rb +16 -1
  53. data/lib/solargraph/language_server/transport/data_reader.rb +2 -0
  54. data/lib/solargraph/language_server.rb +1 -0
  55. data/lib/solargraph/library.rb +231 -104
  56. data/lib/solargraph/location.rb +1 -0
  57. data/lib/solargraph/page.rb +6 -0
  58. data/lib/solargraph/parser/comment_ripper.rb +4 -0
  59. data/lib/solargraph/parser/node_methods.rb +47 -7
  60. data/lib/solargraph/parser/node_processor/base.rb +11 -1
  61. data/lib/solargraph/parser/node_processor.rb +1 -0
  62. data/lib/solargraph/parser/{legacy → parser_gem}/class_methods.rb +31 -9
  63. data/lib/solargraph/parser/{legacy → parser_gem}/flawed_builder.rb +3 -1
  64. data/lib/solargraph/parser/{legacy → parser_gem}/node_chainer.rb +57 -41
  65. data/lib/solargraph/parser/parser_gem/node_methods.rb +495 -0
  66. data/lib/solargraph/parser/{rubyvm → parser_gem}/node_processors/alias_node.rb +1 -1
  67. data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +53 -0
  68. data/lib/solargraph/parser/{rubyvm → parser_gem}/node_processors/begin_node.rb +1 -1
  69. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/block_node.rb +3 -2
  70. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/casgn_node.rb +14 -4
  71. data/lib/solargraph/parser/{rubyvm → parser_gem}/node_processors/cvasgn_node.rb +1 -1
  72. data/lib/solargraph/parser/{rubyvm → parser_gem}/node_processors/def_node.rb +7 -20
  73. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/defs_node.rb +2 -2
  74. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/gvasgn_node.rb +1 -1
  75. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/ivasgn_node.rb +2 -2
  76. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/lvasgn_node.rb +2 -2
  77. data/lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb +47 -0
  78. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/namespace_node.rb +2 -2
  79. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/orasgn_node.rb +1 -1
  80. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/resbody_node.rb +3 -3
  81. data/lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb +42 -0
  82. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/send_node.rb +7 -5
  83. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/sym_node.rb +1 -1
  84. data/lib/solargraph/parser/parser_gem/node_processors.rb +56 -0
  85. data/lib/solargraph/parser/parser_gem.rb +12 -0
  86. data/lib/solargraph/parser/region.rb +1 -1
  87. data/lib/solargraph/parser/snippet.rb +2 -0
  88. data/lib/solargraph/parser.rb +9 -10
  89. data/lib/solargraph/pin/base.rb +69 -11
  90. data/lib/solargraph/pin/base_variable.rb +40 -7
  91. data/lib/solargraph/pin/block.rb +81 -33
  92. data/lib/solargraph/pin/closure.rb +17 -2
  93. data/lib/solargraph/pin/common.rb +7 -3
  94. data/lib/solargraph/pin/conversions.rb +34 -8
  95. data/lib/solargraph/pin/delegated_method.rb +101 -0
  96. data/lib/solargraph/pin/documenting.rb +25 -32
  97. data/lib/solargraph/pin/instance_variable.rb +4 -0
  98. data/lib/solargraph/pin/local_variable.rb +13 -1
  99. data/lib/solargraph/pin/method.rb +273 -17
  100. data/lib/solargraph/pin/namespace.rb +17 -1
  101. data/lib/solargraph/pin/parameter.rb +40 -28
  102. data/lib/solargraph/pin/reference/override.rb +2 -2
  103. data/lib/solargraph/pin/reference.rb +8 -0
  104. data/lib/solargraph/pin/search.rb +4 -4
  105. data/lib/solargraph/pin/signature.rb +143 -0
  106. data/lib/solargraph/pin.rb +2 -1
  107. data/lib/solargraph/range.rb +4 -6
  108. data/lib/solargraph/rbs_map/conversions.rb +607 -0
  109. data/lib/solargraph/rbs_map/core_fills.rb +50 -0
  110. data/lib/solargraph/rbs_map/core_map.rb +28 -0
  111. data/lib/solargraph/rbs_map/stdlib_map.rb +33 -0
  112. data/lib/solargraph/rbs_map.rb +92 -0
  113. data/lib/solargraph/shell.rb +85 -59
  114. data/lib/solargraph/source/chain/array.rb +32 -0
  115. data/lib/solargraph/source/chain/block_symbol.rb +13 -0
  116. data/lib/solargraph/source/chain/call.rb +125 -61
  117. data/lib/solargraph/source/chain/constant.rb +15 -1
  118. data/lib/solargraph/source/chain/if.rb +23 -0
  119. data/lib/solargraph/source/chain/link.rb +8 -2
  120. data/lib/solargraph/source/chain/or.rb +1 -1
  121. data/lib/solargraph/source/chain/z_super.rb +3 -3
  122. data/lib/solargraph/source/chain.rb +64 -14
  123. data/lib/solargraph/source/change.rb +3 -0
  124. data/lib/solargraph/source/cursor.rb +2 -0
  125. data/lib/solargraph/source/source_chainer.rb +8 -5
  126. data/lib/solargraph/source/updater.rb +1 -0
  127. data/lib/solargraph/source.rb +18 -63
  128. data/lib/solargraph/source_map/clip.rb +31 -23
  129. data/lib/solargraph/source_map/mapper.rb +23 -7
  130. data/lib/solargraph/source_map.rb +36 -11
  131. data/lib/solargraph/type_checker/checks.rb +10 -2
  132. data/lib/solargraph/type_checker.rb +229 -100
  133. data/lib/solargraph/version.rb +1 -1
  134. data/lib/solargraph/views/environment.erb +2 -2
  135. data/lib/solargraph/workspace/config.rb +15 -11
  136. data/lib/solargraph/workspace.rb +41 -17
  137. data/lib/solargraph/yard_map/cache.rb +6 -0
  138. data/lib/solargraph/yard_map/helpers.rb +1 -1
  139. data/lib/solargraph/yard_map/mapper/to_method.rb +23 -7
  140. data/lib/solargraph/yard_map/mapper.rb +1 -1
  141. data/lib/solargraph/yard_map/to_method.rb +11 -4
  142. data/lib/solargraph/yard_map.rb +1 -443
  143. data/lib/solargraph/yard_tags.rb +20 -0
  144. data/lib/solargraph/yardoc.rb +52 -0
  145. data/lib/solargraph.rb +8 -6
  146. data/solargraph.gemspec +19 -8
  147. metadata +164 -99
  148. data/.travis.yml +0 -19
  149. data/lib/solargraph/api_map/bundler_methods.rb +0 -22
  150. data/lib/solargraph/compat.rb +0 -37
  151. data/lib/solargraph/convention/rspec.rb +0 -30
  152. data/lib/solargraph/documentor.rb +0 -76
  153. data/lib/solargraph/language_server/host/cataloger.rb +0 -56
  154. data/lib/solargraph/parser/legacy/node_methods.rb +0 -325
  155. data/lib/solargraph/parser/legacy/node_processors/alias_node.rb +0 -23
  156. data/lib/solargraph/parser/legacy/node_processors/args_node.rb +0 -35
  157. data/lib/solargraph/parser/legacy/node_processors/begin_node.rb +0 -15
  158. data/lib/solargraph/parser/legacy/node_processors/cvasgn_node.rb +0 -23
  159. data/lib/solargraph/parser/legacy/node_processors/def_node.rb +0 -63
  160. data/lib/solargraph/parser/legacy/node_processors/sclass_node.rb +0 -21
  161. data/lib/solargraph/parser/legacy/node_processors.rb +0 -54
  162. data/lib/solargraph/parser/legacy.rb +0 -12
  163. data/lib/solargraph/parser/rubyvm/class_methods.rb +0 -144
  164. data/lib/solargraph/parser/rubyvm/node_chainer.rb +0 -160
  165. data/lib/solargraph/parser/rubyvm/node_methods.rb +0 -315
  166. data/lib/solargraph/parser/rubyvm/node_processors/args_node.rb +0 -85
  167. data/lib/solargraph/parser/rubyvm/node_processors/block_node.rb +0 -42
  168. data/lib/solargraph/parser/rubyvm/node_processors/casgn_node.rb +0 -22
  169. data/lib/solargraph/parser/rubyvm/node_processors/defs_node.rb +0 -57
  170. data/lib/solargraph/parser/rubyvm/node_processors/gvasgn_node.rb +0 -23
  171. data/lib/solargraph/parser/rubyvm/node_processors/ivasgn_node.rb +0 -38
  172. data/lib/solargraph/parser/rubyvm/node_processors/kw_arg_node.rb +0 -39
  173. data/lib/solargraph/parser/rubyvm/node_processors/lit_node.rb +0 -20
  174. data/lib/solargraph/parser/rubyvm/node_processors/lvasgn_node.rb +0 -27
  175. data/lib/solargraph/parser/rubyvm/node_processors/namespace_node.rb +0 -39
  176. data/lib/solargraph/parser/rubyvm/node_processors/opt_arg_node.rb +0 -26
  177. data/lib/solargraph/parser/rubyvm/node_processors/orasgn_node.rb +0 -15
  178. data/lib/solargraph/parser/rubyvm/node_processors/resbody_node.rb +0 -45
  179. data/lib/solargraph/parser/rubyvm/node_processors/sclass_node.rb +0 -21
  180. data/lib/solargraph/parser/rubyvm/node_processors/scope_node.rb +0 -15
  181. data/lib/solargraph/parser/rubyvm/node_processors/send_node.rb +0 -277
  182. data/lib/solargraph/parser/rubyvm/node_processors/sym_node.rb +0 -18
  183. data/lib/solargraph/parser/rubyvm/node_processors.rb +0 -63
  184. data/lib/solargraph/parser/rubyvm.rb +0 -40
  185. data/lib/solargraph/yard_map/core_docs.rb +0 -170
  186. data/lib/solargraph/yard_map/core_fills.rb +0 -208
  187. data/lib/solargraph/yard_map/core_gen.rb +0 -76
  188. data/lib/solargraph/yard_map/rdoc_to_yard.rb +0 -140
  189. data/lib/solargraph/yard_map/stdlib_fills.rb +0 -43
  190. data/lib/yard-solargraph.rb +0 -33
  191. data/yardoc/2.2.2.tar.gz +0 -0
@@ -1,9 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'yard'
4
- require 'yard-solargraph'
5
- require 'rubygems/package'
6
- require 'set'
4
+ require 'solargraph/yard_tags'
7
5
 
8
6
  module Solargraph
9
7
  # The YardMap provides access to YARD documentation for the Ruby core, the
@@ -13,448 +11,8 @@ module Solargraph
13
11
  class NoYardocError < StandardError; end
14
12
 
15
13
  autoload :Cache, 'solargraph/yard_map/cache'
16
- autoload :CoreDocs, 'solargraph/yard_map/core_docs'
17
- autoload :CoreGen, 'solargraph/yard_map/core_gen'
18
14
  autoload :Mapper, 'solargraph/yard_map/mapper'
19
- autoload :RdocToYard, 'solargraph/yard_map/rdoc_to_yard'
20
- autoload :CoreFills, 'solargraph/yard_map/core_fills'
21
- autoload :StdlibFills, 'solargraph/yard_map/stdlib_fills'
22
15
  autoload :Helpers, 'solargraph/yard_map/helpers'
23
16
  autoload :ToMethod, 'solargraph/yard_map/to_method'
24
-
25
- include ApiMap::BundlerMethods
26
-
27
- CoreDocs.require_minimum
28
-
29
- def stdlib_paths
30
- @@stdlib_paths ||= begin
31
- result = {}
32
- YARD::Registry.load! CoreDocs.yardoc_stdlib_file
33
- YARD::Registry.all.each do |co|
34
- next if co.file.nil?
35
- path = co.file.sub(/^(ext|lib)\//, '').sub(/\.(rb|c)$/, '')
36
- base = path.split('/').first
37
- result[base] ||= []
38
- result[base].push co
39
- end
40
- result
41
- end
42
- end
43
-
44
- # @return [Boolean]
45
- attr_writer :with_dependencies
46
-
47
- # @param required [Array<String>, Set<String>]
48
- # @param directory [String]
49
- # @param source_gems [Array<String>, Set<String>]
50
- # @param with_dependencies [Boolean]
51
- def initialize(required: [], directory: '', source_gems: [], with_dependencies: true)
52
- @with_dependencies = with_dependencies
53
- change required.to_set, directory, source_gems.to_set
54
- end
55
-
56
- # @return [Array<Solargraph::Pin::Base>]
57
- def pins
58
- @pins ||= []
59
- end
60
-
61
- def with_dependencies?
62
- @with_dependencies ||= true unless @with_dependencies == false
63
- @with_dependencies
64
- end
65
-
66
- # @param new_requires [Set<String>] Required paths to use for loading gems
67
- # @param new_directory [String] The workspace directory
68
- # @param new_source_gems [Set<String>] Gems under local development (i.e., part of the workspace)
69
- # @return [Boolean]
70
- def change new_requires, new_directory, new_source_gems
71
- return false if new_requires == base_required && new_directory == @directory && new_source_gems == @source_gems
72
- @gem_paths = {}
73
- base_required.replace new_requires
74
- required.replace new_requires
75
- # HACK: Hardcoded YAML handling
76
- required.add 'psych' if new_requires.include?('yaml')
77
- @source_gems = new_source_gems
78
- @directory = new_directory
79
- process_requires
80
- @rebindable_method_names = nil
81
- @pin_class_hash = nil
82
- @pin_select_cache = {}
83
- true
84
- end
85
-
86
- # @return [Set<String>]
87
- def rebindable_method_names
88
- @rebindable_method_names ||= pins_by_class(Pin::Method)
89
- .select { |pin| pin.comments && pin.comments.include?('@yieldself') }
90
- .map(&:name)
91
- .concat(['instance_eval', 'instance_exec', 'class_eval', 'class_exec', 'module_eval', 'module_exec', 'define_method'])
92
- .to_set
93
- end
94
-
95
- # @return [Array<String>]
96
- def yardocs
97
- @yardocs ||= []
98
- end
99
-
100
- # @return [Set<String>]
101
- def required
102
- @required ||= Set.new
103
- end
104
-
105
- # @return [Array<String>]
106
- def unresolved_requires
107
- @unresolved_requires ||= []
108
- end
109
-
110
- # @return [Array<String>]
111
- def missing_docs
112
- @missing_docs ||= []
113
- end
114
-
115
- # @param y [String]
116
- # @return [YARD::Registry]
117
- def load_yardoc y
118
- if y.is_a?(Array)
119
- YARD::Registry.load y, true
120
- else
121
- YARD::Registry.load! y
122
- end
123
- rescue StandardError => e
124
- Solargraph::Logging.logger.warn "Error loading yardoc '#{y}' #{e.class} #{e.message}"
125
- yardocs.delete y
126
- nil
127
- end
128
-
129
- # @return [Array<Solargraph::Pin::Base>]
130
- def core_pins
131
- # Using a class variable to reduce loads
132
- @@core_pins ||= load_core_pins
133
- end
134
-
135
- # @param path [String]
136
- # @return [Pin::Base]
137
- def path_pin path
138
- pins.select { |p| p.path == path }.first
139
- end
140
-
141
- # Get the location of a file referenced by a require path.
142
- #
143
- # @param path [String]
144
- # @return [Location]
145
- def require_reference path
146
- # @type [Gem::Specification]
147
- spec = spec_for_require(path)
148
- spec.full_require_paths.each do |rp|
149
- file = File.join(rp, "#{path}.rb")
150
- next unless File.file?(file)
151
- return Solargraph::Location.new(file, Solargraph::Range.from_to(0, 0, 0, 0))
152
- end
153
- nil
154
- rescue Gem::LoadError
155
- nil
156
- end
157
-
158
- def stdlib_pins
159
- @stdlib_pins ||= []
160
- end
161
-
162
- def base_required
163
- @base_required ||= Set.new
164
- end
165
-
166
- def directory
167
- @directory ||= ''
168
- end
169
-
170
- private
171
-
172
- # @return [YardMap::Cache]
173
- def cache
174
- @cache ||= YardMap::Cache.new
175
- end
176
-
177
- # @return [Hash]
178
- def pin_class_hash
179
- @pin_class_hash ||= pins.to_set.classify(&:class).transform_values(&:to_a)
180
- end
181
-
182
- # @return [Array<Pin::Base>]
183
- def pins_by_class klass
184
- @pin_select_cache[klass] ||= pin_class_hash.select { |key, _| key <= klass }.values.flatten
185
- end
186
-
187
- # @param ns [YARD::CodeObjects::NamespaceObject]
188
- # @return [Array<YARD::CodeObjects::Base>]
189
- def recurse_namespace_object ns
190
- result = []
191
- ns.children.each do |c|
192
- result.push c
193
- result.concat recurse_namespace_object(c) if c.respond_to?(:children)
194
- end
195
- result
196
- end
197
-
198
- # @return [void]
199
- def process_requires
200
- @gemset = process_gemsets
201
- required.merge @gemset.keys if required.include?('bundler/require')
202
- pins.replace core_pins
203
- unresolved_requires.clear
204
- missing_docs.clear
205
- stdlib_pins.clear
206
- environ = Convention.for_global(self)
207
- done = []
208
- already_errored = []
209
- (required + environ.requires).each do |r|
210
- next if r.nil? || r.empty? || done.include?(r)
211
- done.push r
212
- cached = cache.get_path_pins(r)
213
- unless cached.nil?
214
- pins.concat cached
215
- next
216
- end
217
- result = []
218
- begin
219
- spec = spec_for_require(r)
220
- if @source_gems.include?(spec.name)
221
- next
222
- end
223
- next if @gem_paths.key?(spec.name)
224
- yd = yardoc_file_for_spec(spec)
225
- # YARD detects gems for certain libraries that do not have a yardoc
226
- # but exist in the stdlib. `fileutils` is an example. Treat those
227
- # cases as errors and check the stdlib yardoc.
228
- if yd.nil?
229
- process_error(r, result, already_errored, nil)
230
- next
231
- end
232
- @gem_paths[spec.name] = spec.full_gem_path
233
- unless yardocs.include?(yd)
234
- yardocs.unshift yd
235
- result.concat process_yardoc yd, spec
236
- result.concat add_gem_dependencies(spec) if with_dependencies?
237
- end
238
- rescue Gem::LoadError, NoYardocError
239
- process_error(r, result, already_errored)
240
- end
241
- result.delete_if(&:nil?)
242
- unless result.empty?
243
- cache.set_path_pins r, result
244
- pins.concat result
245
- end
246
- end
247
- if required.include?('yaml') && required.include?('psych')
248
- # HACK: Hardcoded YAML handling
249
- # @todo Why can't this be handled with an override or a virtual pin?
250
- pin = path_pin('YAML')
251
- pin.instance_variable_set(:@return_type, ComplexType.parse('Module<Psych>')) unless pin.nil?
252
- end
253
- pins.concat environ.pins
254
- end
255
-
256
- def process_error(req, result, already_errored, yd = 1)
257
- base = req.split('/').first
258
- return if already_errored.include?(base)
259
- already_errored.push base
260
- stdtmp = load_stdlib_pins(base)
261
- if yd.nil?
262
- missing_docs.push req
263
- elsif stdtmp.empty?
264
- unresolved_requires.push req
265
- else
266
- stdlib_pins.concat stdtmp
267
- result.concat stdtmp
268
- end
269
- end
270
-
271
- def process_gemsets
272
- return {} if directory.empty? || !File.file?(File.join(directory, 'Gemfile'))
273
- require_from_bundle(directory)
274
- end
275
-
276
- # @param spec [Gem::Specification]
277
- # @return [void]
278
- def add_gem_dependencies spec
279
- result = []
280
- (spec.dependencies - spec.development_dependencies).each do |dep|
281
- begin
282
- next if @source_gems.include?(dep.name) || @gem_paths.key?(dep.name)
283
- depspec = Gem::Specification.find_by_name(dep.name)
284
- next if depspec.nil?
285
- @gem_paths[depspec.name] = depspec.full_gem_path
286
- gy = yardoc_file_for_spec(depspec)
287
- if gy.nil?
288
- missing_docs.push dep.name
289
- else
290
- next if yardocs.include?(gy)
291
- yardocs.unshift gy
292
- result.concat process_yardoc gy, depspec
293
- result.concat add_gem_dependencies(depspec)
294
- end
295
- rescue Gem::LoadError
296
- # This error probably indicates a bug in an installed gem
297
- Solargraph::Logging.logger.warn "Failed to resolve #{dep.name} gem dependency for #{spec.name}"
298
- end
299
- end
300
- result
301
- end
302
-
303
- # @param y [String, nil]
304
- # @param spec [Gem::Specification, nil]
305
- # @return [Array<Pin::Base>]
306
- def process_yardoc y, spec = nil
307
- return [] if y.nil?
308
- if spec
309
- ser = File.join(CoreDocs.cache_dir, 'gems', "#{spec.name}-#{spec.version}.ser")
310
- if File.file?(ser)
311
- Solargraph.logger.info "Loading #{spec.name} #{spec.version} from cache"
312
- file = File.open(ser, 'rb')
313
- dump = file.read
314
- file.close
315
- begin
316
- result = Marshal.load(dump)
317
- return result unless result.nil? || result.empty?
318
- Solargraph.logger.warn "Empty cache for #{spec.name} #{spec.version}. Reloading"
319
- File.unlink ser
320
- rescue StandardError => e
321
- Solargraph.logger.warn "Error loading pin cache: [#{e.class}] #{e.message}"
322
- File.unlink ser
323
- end
324
- end
325
- end
326
- size = Dir.glob(File.join(y, '**', '*'))
327
- .map{ |f| File.size(f) }
328
- .inject(:+)
329
- if !size.nil? && size > 20_000_000
330
- Solargraph::Logging.logger.warn "Yardoc at #{y} is too large to process (#{size} bytes)"
331
- return []
332
- end
333
- Solargraph.logger.info "Loading #{spec.name} #{spec.version} from #{y}"
334
- load_yardoc y
335
- result = Mapper.new(YARD::Registry.all, spec).map
336
- raise NoYardocError, "Yardoc at #{y} is empty" if result.empty?
337
- if spec
338
- ser = File.join(CoreDocs.cache_dir, 'gems', "#{spec.name}-#{spec.version}.ser")
339
- file = File.open(ser, 'wb')
340
- file.write Marshal.dump(result)
341
- file.close
342
- end
343
- result
344
- end
345
-
346
- # @param spec [Gem::Specification]
347
- # @return [String]
348
- def yardoc_file_for_spec spec
349
- cache_dir = File.join(Solargraph::YardMap::CoreDocs.cache_dir, 'gems', "#{spec.name}-#{spec.version}", 'yardoc')
350
- if File.exist?(cache_dir)
351
- Solargraph.logger.info "Using cached documentation for #{spec.name} at #{cache_dir}"
352
- cache_dir
353
- else
354
- YARD::Registry.yardoc_file_for_gem(spec.name, "= #{spec.version}")
355
- end
356
- end
357
-
358
- # @param path [String]
359
- # @return [Gem::Specification]
360
- def spec_for_require path
361
- name = path.split('/').first
362
- spec = Gem::Specification.find_by_name(name, @gemset[name])
363
-
364
- # Avoid loading the spec again if it's going to be skipped anyway
365
- return spec if @source_gems.include?(spec.name)
366
- # Avoid loading the spec again if it's already the correct version
367
- if @gemset[spec.name] && @gemset[spec.name] != spec.version
368
- begin
369
- return Gem::Specification.find_by_name(spec.name, "= #{@gemset[spec.name]}")
370
- rescue Gem::LoadError
371
- Solargraph.logger.warn "Unable to load #{spec.name} #{@gemset[spec.name]} specified by workspace, using #{spec.version} instead"
372
- end
373
- end
374
- spec
375
- end
376
-
377
- def load_core_pins
378
- yd = CoreDocs.yardoc_file
379
- ser = File.join(File.dirname(yd), 'core.ser')
380
- result = if File.file?(ser)
381
- file = File.open(ser, 'rb')
382
- dump = file.read
383
- file.close
384
- begin
385
- Marshal.load(dump)
386
- rescue StandardError => e
387
- Solargraph.logger.warn "Error loading core pin cache: [#{e.class}] #{e.message}"
388
- File.unlink ser
389
- read_core_and_save_cache(yd, ser)
390
- end
391
- else
392
- read_core_and_save_cache(yd, ser)
393
- end
394
- ApiMap::Store.new(result + CoreFills::ALL).pins.reject { |pin| pin.is_a?(Pin::Reference::Override) }
395
- end
396
-
397
- def read_core_and_save_cache yd, ser
398
- result = []
399
- load_yardoc yd
400
- result.concat Mapper.new(YARD::Registry.all).map
401
- # HACK: Assume core methods with a single `args` parameter accept restarg
402
- result.select { |pin| pin.is_a?(Solargraph::Pin::Method )}.each do |pin|
403
- if pin.parameters.length == 1 && pin.parameters.first.name == 'args' && pin.parameters.first.decl == :arg
404
- # @todo Smelly instance variable access
405
- pin.parameters.first.instance_variable_set(:@decl, :restarg)
406
- end
407
- end
408
- # HACK: Set missing parameters on `==` methods, e.g., `Symbol#==`
409
- result.select { |pin| pin.name == '==' && pin.parameters.empty? }.each do |pin|
410
- pin.parameters.push Pin::Parameter.new(decl: :arg, name: 'obj2')
411
- end
412
- dump = Marshal.dump(result)
413
- file = File.open(ser, 'wb')
414
- file.write dump
415
- file.close
416
- result
417
- end
418
-
419
- def load_stdlib_pins base
420
- ser = File.join(File.dirname(CoreDocs.yardoc_stdlib_file), "#{base}.ser")
421
- result = if File.file?(ser)
422
- Solargraph.logger.info "Loading #{base} stdlib from cache"
423
- file = File.open(ser, 'rb')
424
- dump = file.read
425
- file.close
426
- begin
427
- Marshal.load(dump)
428
- rescue StandardError => e
429
- Solargraph.logger.warn "Error loading #{base} stdlib pin cache: [#{e.class}] #{e.message}"
430
- File.unlink ser
431
- read_stdlib_and_save_cache(base, ser)
432
- end
433
- else
434
- read_stdlib_and_save_cache(base, ser)
435
- end
436
- fills = StdlibFills.get(base)
437
- unless fills.empty?
438
- result = ApiMap::Store.new(result + fills).pins.reject { |pin| pin.is_a?(Pin::Reference::Override) }
439
- end
440
- result
441
- end
442
-
443
- def read_stdlib_and_save_cache base, ser
444
- result = []
445
- if stdlib_paths[base]
446
- Solargraph.logger.info "Loading #{base} stdlib from yardoc"
447
- result.concat Mapper.new(stdlib_paths[base]).map
448
- unless result.empty?
449
- dump = Marshal.dump(result)
450
- file = File.open(ser, 'wb')
451
- file.write dump
452
- file.close
453
- end
454
- end
455
- result
456
- end
457
17
  end
458
18
  end
459
-
460
- Solargraph::YardMap::CoreDocs.require_minimum
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'yard'
4
+
5
+ # Change YARD log IO to avoid sending unexpected messages to STDOUT
6
+ YARD::Logger.instance.io = File.new(File::NULL, 'w')
7
+
8
+ module Solargraph
9
+ # A placeholder for the @!domain directive. It doesn't need to do anything
10
+ # for yardocs. It's only used for Solargraph API maps.
11
+ class DomainDirective < YARD::Tags::Directive
12
+ def call; end
13
+ end
14
+ end
15
+
16
+ # Define a @type tag for documenting variables
17
+ YARD::Tags::Library.define_tag("Type", :type, :with_types_and_name)
18
+
19
+ # Define an @!override directive for overriding method tags
20
+ YARD::Tags::Library.define_directive("override", :with_name, Solargraph::DomainDirective)
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ # Methods for caching and loading YARD documentation for gems.
5
+ #
6
+ module Yardoc
7
+ module_function
8
+
9
+ # Build and cache a gem's yardoc and return the path. If the cache already
10
+ # exists, do nothing and return the path.
11
+ #
12
+ # @param gemspec [Gem::Specification]
13
+ # @return [String] The path to the cached yardoc.
14
+ def cache(gemspec)
15
+ path = path_for(gemspec)
16
+ return path if cached?(gemspec)
17
+
18
+ Solargraph.logger.info "Caching yardoc for #{gemspec.name} #{gemspec.version}"
19
+ Dir.chdir gemspec.gem_dir do
20
+ `yardoc --db #{path} --no-output --plugin solargraph`
21
+ end
22
+ path
23
+ end
24
+
25
+ # True if the gem yardoc is cached.
26
+ #
27
+ # @param gemspec [Gem::Specification]
28
+ def cached?(gemspec)
29
+ yardoc = File.join(path_for(gemspec), 'complete')
30
+ File.exist?(yardoc)
31
+ end
32
+
33
+ # Get the absolute path for a cached gem yardoc.
34
+ #
35
+ # @param gemspec [Gem::Specification]
36
+ # @return [String]
37
+ def path_for(gemspec)
38
+ File.join(Solargraph::Cache.work_dir, 'gems', "#{gemspec.name}-#{gemspec.version}.yardoc")
39
+ end
40
+
41
+ # Load a gem's yardoc and return its code objects.
42
+ #
43
+ # @note This method modifies the global YARD registry.
44
+ #
45
+ # @param gemspec [Gem::Specification]
46
+ # @return [Array<YARD::CodeObjects::Base>]
47
+ def load!(gemspec)
48
+ YARD::Registry.load! path_for(gemspec)
49
+ YARD::Registry.all
50
+ end
51
+ end
52
+ end
data/lib/solargraph.rb CHANGED
@@ -2,7 +2,9 @@
2
2
 
3
3
  Encoding.default_external = 'UTF-8'
4
4
 
5
- require 'solargraph/compat'
5
+ require 'set'
6
+ require 'yard-solargraph'
7
+ require 'solargraph/yard_tags'
6
8
  require 'solargraph/version'
7
9
 
8
10
  # The top-level namespace for the Solargraph code mapping, documentation,
@@ -25,8 +27,10 @@ module Solargraph
25
27
  autoload :Source, 'solargraph/source'
26
28
  autoload :SourceMap, 'solargraph/source_map'
27
29
  autoload :ApiMap, 'solargraph/api_map'
30
+ autoload :Yardoc, 'solargraph/yardoc'
28
31
  autoload :YardMap, 'solargraph/yard_map'
29
32
  autoload :Pin, 'solargraph/pin'
33
+ autoload :DocMap, 'solargraph/doc_map'
30
34
  autoload :ServerMethods, 'solargraph/server_methods'
31
35
  autoload :LanguageServer, 'solargraph/language_server'
32
36
  autoload :Workspace, 'solargraph/workspace'
@@ -39,12 +43,12 @@ module Solargraph
39
43
  autoload :TypeChecker, 'solargraph/type_checker'
40
44
  autoload :Environ, 'solargraph/environ'
41
45
  autoload :Convention, 'solargraph/convention'
42
- autoload :Documentor, 'solargraph/documentor'
43
46
  autoload :Parser, 'solargraph/parser'
47
+ autoload :RbsMap, 'solargraph/rbs_map'
48
+ autoload :GemPins, 'solargraph/gem_pins'
49
+ autoload :Cache, 'solargraph/cache'
44
50
 
45
51
  dir = File.dirname(__FILE__)
46
- YARDOC_PATH = File.realpath(File.join(dir, '..', 'yardoc'))
47
- YARD_EXTENSION_FILE = File.join(dir, 'yard-solargraph.rb')
48
52
  VIEWS_PATH = File.join(dir, 'solargraph', 'views')
49
53
 
50
54
  # A convenience method for Solargraph::Logging.logger.
@@ -56,8 +60,6 @@ module Solargraph
56
60
 
57
61
  # A helper method that runs Bundler.with_unbundled_env or falls back to
58
62
  # Bundler.with_clean_env for earlier versions of Bundler.
59
- #
60
- # @return [void]
61
63
  def self.with_clean_env &block
62
64
  meth = if Bundler.respond_to?(:with_original_env)
63
65
  :with_original_env
data/solargraph.gemspec CHANGED
@@ -13,30 +13,41 @@ Gem::Specification.new do |s|
13
13
  s.files = Dir.chdir(File.expand_path('..', __FILE__)) do
14
14
  `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
15
15
  end
16
- s.homepage = 'http://solargraph.org'
16
+ s.homepage = 'https://solargraph.org'
17
17
  s.license = 'MIT'
18
18
  s.executables = ['solargraph']
19
+ s.metadata["funding_uri"] = "https://www.patreon.com/castwide"
20
+ s.metadata["bug_tracker_uri"] = "https://github.com/castwide/solargraph/issues"
21
+ s.metadata["changelog_uri"] = "https://github.com/castwide/solargraph/blob/master/CHANGELOG.md"
22
+ s.metadata["source_code_uri"] = "https://github.com/castwide/solargraph"
19
23
 
20
- s.required_ruby_version = '>= 2.4'
24
+ s.required_ruby_version = '>= 3.0'
21
25
 
22
26
  s.add_runtime_dependency 'backport', '~> 1.2'
23
27
  s.add_runtime_dependency 'benchmark'
24
- s.add_runtime_dependency 'bundler', '>= 1.17.2'
28
+ s.add_runtime_dependency 'bundler', '~> 2.0'
25
29
  s.add_runtime_dependency 'diff-lcs', '~> 1.4'
26
- s.add_runtime_dependency 'e2mmap'
27
- s.add_runtime_dependency 'jaro_winkler', '~> 1.5'
30
+ s.add_runtime_dependency 'jaro_winkler', '~> 1.6'
28
31
  s.add_runtime_dependency 'kramdown', '~> 2.3'
29
32
  s.add_runtime_dependency 'kramdown-parser-gfm', '~> 1.1'
33
+ s.add_runtime_dependency 'logger', '~> 1.6'
34
+ s.add_runtime_dependency 'observer', '~> 0.1'
35
+ s.add_runtime_dependency 'ostruct', '~> 0.6'
30
36
  s.add_runtime_dependency 'parser', '~> 3.0'
31
- s.add_runtime_dependency 'reverse_markdown', '>= 1.0.5', '< 3'
32
- s.add_runtime_dependency 'rubocop', '>= 0.52'
37
+ s.add_runtime_dependency 'rbs', '~> 3.3'
38
+ s.add_runtime_dependency 'reverse_markdown', '>= 2.0', '< 4'
39
+ s.add_runtime_dependency 'rubocop', '~> 1.38'
33
40
  s.add_runtime_dependency 'thor', '~> 1.0'
34
41
  s.add_runtime_dependency 'tilt', '~> 2.0'
35
42
  s.add_runtime_dependency 'yard', '~> 0.9', '>= 0.9.24'
43
+ s.add_runtime_dependency 'yard-solargraph', '~> 0.1'
36
44
 
37
45
  s.add_development_dependency 'pry'
38
46
  s.add_development_dependency 'public_suffix', '~> 3.1'
39
- s.add_development_dependency 'rspec', '~> 3.5', '>= 3.5.0'
47
+ s.add_development_dependency 'rake', '~> 13.2'
48
+ s.add_development_dependency 'rspec', '~> 3.5'
40
49
  s.add_development_dependency 'simplecov', '~> 0.14'
41
50
  s.add_development_dependency 'webmock', '~> 3.6'
51
+ # work around missing yard dependency needed as of Ruby 3.5
52
+ s.add_development_dependency 'irb'
42
53
  end