solargraph 0.52.0 → 0.53.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/plugins.yml +40 -0
- data/.github/workflows/rspec.yml +1 -3
- data/.github/workflows/typecheck.yml +34 -0
- data/CHANGELOG.md +30 -0
- data/README.md +13 -16
- data/SPONSORS.md +1 -7
- data/lib/solargraph/api_map/cache.rb +59 -21
- data/lib/solargraph/api_map/store.rb +45 -9
- data/lib/solargraph/api_map.rb +152 -93
- data/lib/solargraph/bench.rb +2 -2
- data/lib/solargraph/cache.rb +29 -5
- data/lib/solargraph/complex_type/type_methods.rb +53 -8
- data/lib/solargraph/complex_type/unique_type.rb +149 -59
- data/lib/solargraph/complex_type.rb +62 -9
- data/lib/solargraph/convention.rb +0 -1
- data/lib/solargraph/converters/dd.rb +5 -0
- data/lib/solargraph/converters/dl.rb +3 -0
- data/lib/solargraph/converters/dt.rb +3 -0
- data/lib/solargraph/diagnostics/rubocop.rb +8 -7
- data/lib/solargraph/diagnostics/rubocop_helpers.rb +1 -0
- data/lib/solargraph/diagnostics/type_check.rb +1 -0
- data/lib/solargraph/diagnostics.rb +2 -2
- data/lib/solargraph/doc_map.rb +146 -0
- data/lib/solargraph/gem_pins.rb +64 -0
- data/lib/solargraph/language_server/host/cataloger.rb +1 -0
- data/lib/solargraph/language_server/host/diagnoser.rb +2 -2
- data/lib/solargraph/language_server/host/dispatch.rb +10 -4
- data/lib/solargraph/language_server/host/message_worker.rb +4 -0
- data/lib/solargraph/language_server/host/sources.rb +7 -4
- data/lib/solargraph/language_server/host.rb +15 -6
- data/lib/solargraph/language_server/message/completion_item/resolve.rb +3 -1
- data/lib/solargraph/language_server/message/extended/check_gem_version.rb +13 -1
- data/lib/solargraph/language_server/message/initialize.rb +5 -2
- data/lib/solargraph/language_server/message/text_document/hover.rb +2 -0
- data/lib/solargraph/language_server/message/text_document.rb +0 -1
- data/lib/solargraph/language_server/message/workspace/did_change_configuration.rb +5 -0
- data/lib/solargraph/language_server/transport/adapter.rb +16 -1
- data/lib/solargraph/language_server/transport/data_reader.rb +2 -0
- data/lib/solargraph/library.rb +58 -11
- data/lib/solargraph/location.rb +1 -0
- data/lib/solargraph/parser/comment_ripper.rb +3 -0
- data/lib/solargraph/parser/node_methods.rb +47 -8
- data/lib/solargraph/parser/node_processor/base.rb +9 -0
- data/lib/solargraph/parser/{legacy → parser_gem}/class_methods.rb +29 -3
- data/lib/solargraph/parser/{legacy → parser_gem}/flawed_builder.rb +3 -1
- data/lib/solargraph/parser/{legacy → parser_gem}/node_chainer.rb +42 -34
- data/lib/solargraph/parser/{legacy → parser_gem}/node_methods.rb +201 -29
- data/lib/solargraph/parser/{rubyvm → parser_gem}/node_processors/alias_node.rb +1 -1
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/args_node.rb +4 -1
- data/lib/solargraph/parser/{rubyvm → parser_gem}/node_processors/begin_node.rb +1 -1
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/block_node.rb +3 -2
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/casgn_node.rb +2 -2
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/cvasgn_node.rb +1 -1
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/def_node.rb +1 -1
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/defs_node.rb +2 -2
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/gvasgn_node.rb +1 -1
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/ivasgn_node.rb +2 -2
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/lvasgn_node.rb +2 -2
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/namespace_node.rb +2 -2
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/orasgn_node.rb +1 -1
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/resbody_node.rb +3 -3
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/sclass_node.rb +1 -1
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/send_node.rb +2 -2
- data/lib/solargraph/parser/{rubyvm → parser_gem}/node_processors/sym_node.rb +1 -1
- data/lib/solargraph/parser/parser_gem/node_processors.rb +54 -0
- data/lib/solargraph/parser/parser_gem.rb +12 -0
- data/lib/solargraph/parser/snippet.rb +2 -0
- data/lib/solargraph/parser.rb +8 -11
- data/lib/solargraph/pin/base.rb +63 -8
- data/lib/solargraph/pin/base_variable.rb +6 -2
- data/lib/solargraph/pin/block.rb +11 -6
- data/lib/solargraph/pin/closure.rb +17 -2
- data/lib/solargraph/pin/common.rb +7 -3
- data/lib/solargraph/pin/conversions.rb +33 -3
- data/lib/solargraph/pin/documenting.rb +25 -34
- data/lib/solargraph/pin/instance_variable.rb +4 -0
- data/lib/solargraph/pin/local_variable.rb +13 -1
- data/lib/solargraph/pin/method.rb +109 -15
- data/lib/solargraph/pin/namespace.rb +16 -10
- data/lib/solargraph/pin/parameter.rb +41 -10
- data/lib/solargraph/pin/reference/override.rb +2 -2
- data/lib/solargraph/pin/reference.rb +8 -0
- data/lib/solargraph/pin/search.rb +3 -3
- data/lib/solargraph/pin/signature.rb +114 -2
- data/lib/solargraph/pin.rb +0 -1
- data/lib/solargraph/range.rb +2 -2
- data/lib/solargraph/rbs_map/conversions.rb +212 -25
- data/lib/solargraph/rbs_map/core_fills.rb +4 -26
- data/lib/solargraph/rbs_map/core_map.rb +1 -0
- data/lib/solargraph/rbs_map/core_signs.rb +2 -0
- data/lib/solargraph/rbs_map/stdlib_map.rb +2 -8
- data/lib/solargraph/rbs_map.rb +19 -9
- data/lib/solargraph/shell.rb +62 -59
- data/lib/solargraph/source/chain/array.rb +4 -1
- data/lib/solargraph/source/chain/block_symbol.rb +13 -0
- data/lib/solargraph/source/chain/call.rb +95 -26
- data/lib/solargraph/source/chain/constant.rb +15 -1
- data/lib/solargraph/source/chain/if.rb +23 -0
- data/lib/solargraph/source/chain/link.rb +7 -1
- data/lib/solargraph/source/chain/or.rb +1 -1
- data/lib/solargraph/source/chain/z_super.rb +2 -2
- data/lib/solargraph/source/chain.rb +20 -4
- data/lib/solargraph/source/change.rb +3 -0
- data/lib/solargraph/source/cursor.rb +2 -0
- data/lib/solargraph/source/source_chainer.rb +6 -5
- data/lib/solargraph/source.rb +15 -16
- data/lib/solargraph/source_map/clip.rb +11 -7
- data/lib/solargraph/source_map/mapper.rb +10 -0
- data/lib/solargraph/source_map.rb +13 -3
- data/lib/solargraph/type_checker/checks.rb +10 -2
- data/lib/solargraph/type_checker.rb +74 -19
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/workspace/config.rb +8 -6
- data/lib/solargraph/workspace.rb +1 -1
- data/lib/solargraph/yard_map/cache.rb +6 -0
- data/lib/solargraph/yard_map/helpers.rb +1 -1
- data/lib/solargraph/yard_map/mapper/to_method.rb +11 -1
- data/lib/solargraph/yard_map/to_method.rb +11 -4
- data/lib/solargraph/yard_map.rb +0 -292
- data/lib/solargraph/yardoc.rb +52 -0
- data/lib/solargraph.rb +4 -1
- data/solargraph.gemspec +2 -2
- metadata +35 -57
- data/lib/solargraph/api_map/bundler_methods.rb +0 -22
- data/lib/solargraph/documentor.rb +0 -76
- data/lib/solargraph/parser/legacy/node_processors/alias_node.rb +0 -23
- data/lib/solargraph/parser/legacy/node_processors/begin_node.rb +0 -15
- data/lib/solargraph/parser/legacy/node_processors/sym_node.rb +0 -18
- data/lib/solargraph/parser/legacy/node_processors.rb +0 -55
- data/lib/solargraph/parser/legacy.rb +0 -12
- data/lib/solargraph/parser/rubyvm/class_methods.rb +0 -151
- data/lib/solargraph/parser/rubyvm/node_chainer.rb +0 -163
- data/lib/solargraph/parser/rubyvm/node_methods.rb +0 -317
- data/lib/solargraph/parser/rubyvm/node_processors/args_node.rb +0 -85
- data/lib/solargraph/parser/rubyvm/node_processors/block_node.rb +0 -42
- data/lib/solargraph/parser/rubyvm/node_processors/casgn_node.rb +0 -33
- data/lib/solargraph/parser/rubyvm/node_processors/cvasgn_node.rb +0 -23
- data/lib/solargraph/parser/rubyvm/node_processors/def_node.rb +0 -75
- data/lib/solargraph/parser/rubyvm/node_processors/defs_node.rb +0 -68
- data/lib/solargraph/parser/rubyvm/node_processors/gvasgn_node.rb +0 -23
- data/lib/solargraph/parser/rubyvm/node_processors/ivasgn_node.rb +0 -38
- data/lib/solargraph/parser/rubyvm/node_processors/kw_arg_node.rb +0 -39
- data/lib/solargraph/parser/rubyvm/node_processors/lit_node.rb +0 -20
- data/lib/solargraph/parser/rubyvm/node_processors/lvasgn_node.rb +0 -27
- data/lib/solargraph/parser/rubyvm/node_processors/namespace_node.rb +0 -39
- data/lib/solargraph/parser/rubyvm/node_processors/opt_arg_node.rb +0 -26
- data/lib/solargraph/parser/rubyvm/node_processors/orasgn_node.rb +0 -15
- data/lib/solargraph/parser/rubyvm/node_processors/resbody_node.rb +0 -51
- data/lib/solargraph/parser/rubyvm/node_processors/sclass_node.rb +0 -32
- data/lib/solargraph/parser/rubyvm/node_processors/scope_node.rb +0 -15
- data/lib/solargraph/parser/rubyvm/node_processors/send_node.rb +0 -279
- data/lib/solargraph/parser/rubyvm/node_processors.rb +0 -64
- data/lib/solargraph/parser/rubyvm/node_wrapper.rb +0 -47
- data/lib/solargraph/parser/rubyvm.rb +0 -40
data/lib/solargraph/api_map.rb
CHANGED
@@ -1,7 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'rubygems'
|
4
|
-
require 'set'
|
5
3
|
require 'pathname'
|
6
4
|
require 'yard'
|
7
5
|
require 'solargraph/yard_tags'
|
@@ -14,9 +12,6 @@ module Solargraph
|
|
14
12
|
autoload :Cache, 'solargraph/api_map/cache'
|
15
13
|
autoload :SourceToYard, 'solargraph/api_map/source_to_yard'
|
16
14
|
autoload :Store, 'solargraph/api_map/store'
|
17
|
-
autoload :BundlerMethods, 'solargraph/api_map/bundler_methods'
|
18
|
-
|
19
|
-
include SourceToYard
|
20
15
|
|
21
16
|
# @return [Array<String>]
|
22
17
|
attr_reader :unresolved_requires
|
@@ -59,34 +54,33 @@ module Solargraph
|
|
59
54
|
# Catalog a bench.
|
60
55
|
#
|
61
56
|
# @param bench [Bench]
|
57
|
+
# @return [self]
|
62
58
|
def catalog bench
|
63
59
|
implicit.clear
|
64
60
|
@cache.clear
|
65
61
|
@source_map_hash = bench.source_maps.map { |s| [s.filename, s] }.to_h
|
66
62
|
pins = bench.source_maps.map(&:pins).flatten
|
67
|
-
external_requires = bench.external_requires
|
68
63
|
source_map_hash.each_value do |map|
|
69
64
|
implicit.merge map.environ
|
70
65
|
end
|
71
|
-
external_requires
|
72
|
-
|
73
|
-
@
|
74
|
-
unresolved_requires = @
|
75
|
-
|
76
|
-
@store = Store.new(@@core_map.pins + @rbs_maps.flat_map(&:pins) + yard_map.pins + implicit.pins + pins)
|
77
|
-
@unresolved_requires = yard_map.unresolved_requires
|
78
|
-
@missing_docs = yard_map.missing_docs
|
66
|
+
unresolved_requires = (bench.external_requires + implicit.requires + bench.workspace.config.required).uniq
|
67
|
+
@doc_map = DocMap.new(unresolved_requires, []) # @todo Implement gem dependencies
|
68
|
+
@store = Store.new(@@core_map.pins + @doc_map.pins + implicit.pins + pins)
|
69
|
+
@unresolved_requires = @doc_map.unresolved_requires
|
70
|
+
@missing_docs = [] # @todo Implement missing docs
|
79
71
|
@rebindable_method_names = nil
|
80
72
|
store.block_pins.each { |blk| blk.rebind(self) }
|
81
73
|
self
|
82
74
|
end
|
83
75
|
|
84
|
-
|
85
|
-
|
76
|
+
# @return [::Array<Gem::Specification>]
|
77
|
+
def uncached_gemspecs
|
78
|
+
@doc_map&.uncached_gemspecs || []
|
86
79
|
end
|
87
80
|
|
88
|
-
|
89
|
-
|
81
|
+
# @return [Array<Pin::Base>]
|
82
|
+
def core_pins
|
83
|
+
@@core_map.pins
|
90
84
|
end
|
91
85
|
|
92
86
|
# @param name [String]
|
@@ -95,6 +89,7 @@ module Solargraph
|
|
95
89
|
store.named_macros[name]
|
96
90
|
end
|
97
91
|
|
92
|
+
# @return [Set<String>]
|
98
93
|
def required
|
99
94
|
@required ||= Set.new
|
100
95
|
end
|
@@ -120,7 +115,7 @@ module Solargraph
|
|
120
115
|
# @return [SourceMap::Clip]
|
121
116
|
def clip_at filename, position
|
122
117
|
position = Position.normalize(position)
|
123
|
-
|
118
|
+
clip(cursor_at(filename, position))
|
124
119
|
end
|
125
120
|
|
126
121
|
# Create an ApiMap with a workspace in the specified directory.
|
@@ -137,14 +132,31 @@ module Solargraph
|
|
137
132
|
api_map
|
138
133
|
end
|
139
134
|
|
140
|
-
#
|
135
|
+
# Create an ApiMap with a workspace in the specified directory and cache
|
136
|
+
# any missing gems.
|
137
|
+
#
|
138
|
+
# @param directory [String]
|
139
|
+
# @return [ApiMap]
|
140
|
+
def self.load_with_cache directory
|
141
|
+
api_map = load(directory)
|
142
|
+
return api_map if api_map.uncached_gemspecs.empty?
|
143
|
+
|
144
|
+
api_map.uncached_gemspecs.each do |gemspec|
|
145
|
+
Solargraph.logger.info "Caching #{gemspec.name} #{gemspec.version}..."
|
146
|
+
pins = GemPins.build(gemspec)
|
147
|
+
Solargraph::Cache.save('gems', "#{gemspec.name}-#{gemspec.version}.ser", pins)
|
148
|
+
end
|
149
|
+
load(directory)
|
150
|
+
end
|
151
|
+
|
152
|
+
# @return [Array<Solargraph::Pin::Base>]
|
141
153
|
def pins
|
142
154
|
store.pins
|
143
155
|
end
|
144
156
|
|
157
|
+
# @return [Set<String>]
|
145
158
|
def rebindable_method_names
|
146
159
|
@rebindable_method_names ||= begin
|
147
|
-
# result = yard_map.rebindable_method_names
|
148
160
|
result = ['instance_eval', 'instance_exec', 'class_eval', 'class_exec', 'module_eval', 'module_exec', 'define_method'].to_set
|
149
161
|
source_maps.each do |map|
|
150
162
|
result.merge map.rebindable_method_names
|
@@ -206,22 +218,48 @@ module Solargraph
|
|
206
218
|
store.fqns_pins(qualify(namespace, context))
|
207
219
|
end
|
208
220
|
|
209
|
-
#
|
210
|
-
#
|
221
|
+
# Determine fully qualified tag for a given tag used inside the
|
222
|
+
# definition of another tag ("context"). This method will start
|
223
|
+
# the search in the specified context until it finds a match for
|
224
|
+
# the tag.
|
225
|
+
#
|
226
|
+
# Does not recurse into qualifying the type parameters, but
|
227
|
+
# returns any which were passed in unchanged.
|
228
|
+
#
|
229
|
+
# @param tag [String, nil] The namespace to
|
230
|
+
# match, complete with generic parameters set to appropriate
|
231
|
+
# values if available
|
232
|
+
# @param context_tag [String] The context in which the tag was
|
233
|
+
# referenced; start from here to resolve the name
|
234
|
+
# @return [String, nil] fully qualified tag
|
235
|
+
def qualify tag, context_tag = ''
|
236
|
+
return tag if ['self', nil].include?(tag)
|
237
|
+
context_type = ComplexType.parse(context_tag)
|
238
|
+
type = ComplexType.parse(tag)
|
239
|
+
fqns = qualify_namespace(type.rooted_namespace, context_type.rooted_namespace)
|
240
|
+
return nil if fqns.nil?
|
241
|
+
fqns + type.substring
|
242
|
+
end
|
243
|
+
|
244
|
+
# Determine fully qualified namespace for a given namespace used
|
245
|
+
# inside the definition of another tag ("context"). This method
|
246
|
+
# will start the search in the specified context until it finds a
|
247
|
+
# match for the namespace.
|
211
248
|
#
|
212
|
-
# @param namespace [String, nil] The namespace to
|
213
|
-
#
|
214
|
-
# @
|
215
|
-
|
216
|
-
|
217
|
-
|
249
|
+
# @param namespace [String, nil] The namespace to
|
250
|
+
# match
|
251
|
+
# @param context_namespace [String] The context namespace in which the
|
252
|
+
# tag was referenced; start from here to resolve the name
|
253
|
+
# @return [String, nil] fully qualified namespace
|
254
|
+
def qualify_namespace(namespace, context_namespace = '')
|
255
|
+
cached = cache.get_qualified_namespace(namespace, context_namespace)
|
218
256
|
return cached.clone unless cached.nil?
|
219
257
|
result = if namespace.start_with?('::')
|
220
258
|
inner_qualify(namespace[2..-1], '', Set.new)
|
221
259
|
else
|
222
|
-
inner_qualify(namespace,
|
260
|
+
inner_qualify(namespace, context_namespace, Set.new)
|
223
261
|
end
|
224
|
-
cache.set_qualified_namespace(namespace,
|
262
|
+
cache.set_qualified_namespace(namespace, context_namespace, result)
|
225
263
|
result
|
226
264
|
end
|
227
265
|
|
@@ -247,7 +285,7 @@ module Solargraph
|
|
247
285
|
# Get an array of class variable pins for a namespace.
|
248
286
|
#
|
249
287
|
# @param namespace [String] A fully qualified namespace
|
250
|
-
# @return [
|
288
|
+
# @return [Enumerable<Solargraph::Pin::ClassVariable>]
|
251
289
|
def get_class_variable_pins(namespace)
|
252
290
|
prefer_non_nil_variables(store.get_class_variables(namespace))
|
253
291
|
end
|
@@ -264,32 +302,33 @@ module Solargraph
|
|
264
302
|
|
265
303
|
# Get an array of methods available in a particular context.
|
266
304
|
#
|
267
|
-
# @param
|
305
|
+
# @param rooted_tag [String] The fully qualified namespace to search for methods
|
268
306
|
# @param scope [Symbol] :class or :instance
|
269
307
|
# @param visibility [Array<Symbol>] :public, :protected, and/or :private
|
270
308
|
# @param deep [Boolean] True to include superclasses, mixins, etc.
|
271
309
|
# @return [Array<Solargraph::Pin::Method>]
|
272
|
-
def get_methods
|
273
|
-
cached = cache.get_methods(
|
310
|
+
def get_methods rooted_tag, scope: :instance, visibility: [:public], deep: true
|
311
|
+
cached = cache.get_methods(rooted_tag, scope, visibility, deep)
|
274
312
|
return cached.clone unless cached.nil?
|
275
313
|
result = []
|
276
314
|
skip = Set.new
|
277
|
-
if
|
315
|
+
if rooted_tag == ''
|
278
316
|
# @todo Implement domains
|
279
317
|
implicit.domains.each do |domain|
|
280
318
|
type = ComplexType.try_parse(domain)
|
281
319
|
next if type.undefined?
|
282
320
|
result.concat inner_get_methods(type.name, type.scope, visibility, deep, skip)
|
283
321
|
end
|
284
|
-
result.concat inner_get_methods(
|
285
|
-
result.concat inner_get_methods(
|
322
|
+
result.concat inner_get_methods(rooted_tag, :class, visibility, deep, skip)
|
323
|
+
result.concat inner_get_methods(rooted_tag, :instance, visibility, deep, skip)
|
286
324
|
result.concat inner_get_methods('Kernel', :instance, visibility, deep, skip)
|
287
325
|
else
|
288
|
-
result.concat inner_get_methods(
|
326
|
+
result.concat inner_get_methods(rooted_tag, scope, visibility, deep, skip)
|
289
327
|
result.concat inner_get_methods('Kernel', :instance, [:public], deep, skip) if visibility.include?(:private)
|
328
|
+
result.concat inner_get_methods('Module', scope, visibility, deep, skip)
|
290
329
|
end
|
291
330
|
resolved = resolve_method_aliases(result, visibility)
|
292
|
-
cache.set_methods(
|
331
|
+
cache.set_methods(rooted_tag, scope, visibility, deep, resolved)
|
293
332
|
resolved
|
294
333
|
end
|
295
334
|
|
@@ -327,27 +366,27 @@ module Solargraph
|
|
327
366
|
visibility.push :protected
|
328
367
|
visibility.push :private if internal
|
329
368
|
end
|
330
|
-
result.merge get_methods(type.
|
369
|
+
result.merge get_methods(type.tag, scope: type.scope, visibility: visibility)
|
331
370
|
end
|
332
371
|
end
|
333
372
|
end
|
334
373
|
result.to_a
|
335
374
|
end
|
336
375
|
|
337
|
-
# Get a stack of method pins for a method name in a
|
338
|
-
# of the pins corresponds to
|
339
|
-
# first.
|
376
|
+
# Get a stack of method pins for a method name in a potentially
|
377
|
+
# parameterized namespace. The order of the pins corresponds to
|
378
|
+
# the ancestry chain, with highest precedence first.
|
340
379
|
#
|
341
380
|
# @example
|
342
381
|
# api_map.get_method_stack('Subclass', 'method_name')
|
343
382
|
# #=> [ <Subclass#method_name pin>, <Superclass#method_name pin> ]
|
344
383
|
#
|
345
|
-
# @param
|
346
|
-
# @param name [String]
|
384
|
+
# @param rooted_tag [String] Parameterized namespace, fully qualified
|
385
|
+
# @param name [String] Method name to look up
|
347
386
|
# @param scope [Symbol] :instance or :class
|
348
387
|
# @return [Array<Solargraph::Pin::Method>]
|
349
|
-
def get_method_stack
|
350
|
-
get_methods(
|
388
|
+
def get_method_stack rooted_tag, name, scope: :instance
|
389
|
+
get_methods(rooted_tag, scope: scope, visibility: [:private, :protected, :public]).select { |p| p.name == name }
|
351
390
|
end
|
352
391
|
|
353
392
|
# Get an array of all suggestions that match the specified path.
|
@@ -355,7 +394,7 @@ module Solargraph
|
|
355
394
|
# @deprecated Use #get_path_pins instead.
|
356
395
|
#
|
357
396
|
# @param path [String] The path to find
|
358
|
-
# @return [
|
397
|
+
# @return [Enumerable<Solargraph::Pin::Base>]
|
359
398
|
def get_path_suggestions path
|
360
399
|
return [] if path.nil?
|
361
400
|
resolve_method_aliases store.get_path_pins(path)
|
@@ -364,7 +403,7 @@ module Solargraph
|
|
364
403
|
# Get an array of pins that match the specified path.
|
365
404
|
#
|
366
405
|
# @param path [String]
|
367
|
-
# @return [
|
406
|
+
# @return [Enumerable<Pin::Base>]
|
368
407
|
def get_path_pins path
|
369
408
|
get_path_suggestions(path)
|
370
409
|
end
|
@@ -377,15 +416,9 @@ module Solargraph
|
|
377
416
|
# @param query [String] The text to match
|
378
417
|
# @return [Array<String>]
|
379
418
|
def search query
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
if (found.empty? || (query.include?('.') || query.include?('#')) || !(k.include?('.') || k.include?('#'))) &&
|
384
|
-
k.downcase.include?(query.downcase)
|
385
|
-
found.push k
|
386
|
-
end
|
387
|
-
end
|
388
|
-
found
|
419
|
+
pins.map(&:path)
|
420
|
+
.compact
|
421
|
+
.select { |path| path.downcase.include?(query.downcase) }
|
389
422
|
end
|
390
423
|
|
391
424
|
# Get YARD documentation for the specified path.
|
@@ -393,13 +426,13 @@ module Solargraph
|
|
393
426
|
# @example
|
394
427
|
# api_map.document('String#split')
|
395
428
|
#
|
429
|
+
# @todo This method is likely superfluous. Calling get_path_pins directly
|
430
|
+
# should be sufficient.
|
431
|
+
#
|
396
432
|
# @param path [String] The path to find
|
397
|
-
# @return [
|
433
|
+
# @return [Enumerable<Pin::Base>]
|
398
434
|
def document path
|
399
|
-
|
400
|
-
docs = []
|
401
|
-
docs.push code_object_at(path) unless code_object_at(path).nil?
|
402
|
-
docs
|
435
|
+
get_path_pins(path)
|
403
436
|
end
|
404
437
|
|
405
438
|
# Get an array of all symbols in the workspace that match the query.
|
@@ -425,6 +458,10 @@ module Solargraph
|
|
425
458
|
# @return [SourceMap::Clip]
|
426
459
|
def clip cursor
|
427
460
|
raise FileNotFoundError, "ApiMap did not catalog #{cursor.filename}" unless source_map_hash.key?(cursor.filename)
|
461
|
+
|
462
|
+
# @todo Clip caches are disabled pending resolution of a stale cache bug
|
463
|
+
# cache.get_clip(cursor) ||
|
464
|
+
# SourceMap::Clip.new(self, cursor).tap { |clip| cache.set_clip(cursor, clip) }
|
428
465
|
SourceMap::Clip.new(self, cursor)
|
429
466
|
end
|
430
467
|
|
@@ -476,13 +513,15 @@ module Solargraph
|
|
476
513
|
false
|
477
514
|
end
|
478
515
|
|
479
|
-
# Check if the host class includes the specified module
|
516
|
+
# Check if the host class includes the specified module, ignoring
|
517
|
+
# type parameters used.
|
518
|
+
#
|
519
|
+
# @param host_ns [String] The class namesapce (no type parameters)
|
520
|
+
# @param module_ns [String] The module namespace (no type parameters)
|
480
521
|
#
|
481
|
-
# @param host [String] The class
|
482
|
-
# @param mod [String] The module
|
483
522
|
# @return [Boolean]
|
484
|
-
def type_include?(
|
485
|
-
store.get_includes(
|
523
|
+
def type_include?(host_ns, module_ns)
|
524
|
+
store.get_includes(host_ns).map { |inc_tag| ComplexType.parse(inc_tag).name }.include?(module_ns)
|
486
525
|
end
|
487
526
|
|
488
527
|
private
|
@@ -492,14 +531,6 @@ module Solargraph
|
|
492
531
|
# @return [Hash{String => SourceMap}]
|
493
532
|
attr_reader :source_map_hash
|
494
533
|
|
495
|
-
# @param library [String]
|
496
|
-
# @return [RbsMap]
|
497
|
-
def load_rbs_map library
|
498
|
-
# map = RbsMap.load(library)
|
499
|
-
# return map if map.resolved?
|
500
|
-
RbsMap::StdlibMap.load(library)
|
501
|
-
end
|
502
|
-
|
503
534
|
# @return [ApiMap::Store]
|
504
535
|
def store
|
505
536
|
@store ||= Store.new
|
@@ -508,15 +539,19 @@ module Solargraph
|
|
508
539
|
# @return [Solargraph::ApiMap::Cache]
|
509
540
|
attr_reader :cache
|
510
541
|
|
511
|
-
# @param
|
542
|
+
# @param rooted_tag [String] A fully qualified namespace, with
|
543
|
+
# generic parameter values if applicable
|
512
544
|
# @param scope [Symbol] :class or :instance
|
513
545
|
# @param visibility [Array<Symbol>] :public, :protected, and/or :private
|
514
546
|
# @param deep [Boolean]
|
515
547
|
# @param skip [Set<String>]
|
516
548
|
# @param no_core [Boolean] Skip core classes if true
|
517
549
|
# @return [Array<Pin::Base>]
|
518
|
-
def inner_get_methods
|
519
|
-
|
550
|
+
def inner_get_methods rooted_tag, scope, visibility, deep, skip, no_core = false
|
551
|
+
rooted_type = ComplexType.parse(rooted_tag)
|
552
|
+
fqns = rooted_type.namespace
|
553
|
+
fqns_generic_params = rooted_type.all_params
|
554
|
+
return [] if no_core && fqns =~ /^(Object|BasicObject|Class|Module)$/
|
520
555
|
reqstr = "#{fqns}|#{scope}|#{visibility.sort}|#{deep}"
|
521
556
|
return [] if skip.include?(reqstr)
|
522
557
|
skip.add reqstr
|
@@ -527,12 +562,33 @@ module Solargraph
|
|
527
562
|
result.concat inner_get_methods(fqim, scope, visibility, deep, skip, true) unless fqim.nil?
|
528
563
|
end
|
529
564
|
end
|
530
|
-
|
565
|
+
# Store#get_methods doesn't know about full tags, just
|
566
|
+
# namespaces; resolving the generics in the method pins is this
|
567
|
+
# class' responsibility
|
568
|
+
raw_methods = store.get_methods(fqns, scope: scope, visibility: visibility).sort{ |a, b| a.name <=> b.name }
|
569
|
+
namespace_pin = store.get_path_pins(fqns).select{|p| p.is_a?(Pin::Namespace)}.first
|
570
|
+
methods = if rooted_tag != fqns
|
571
|
+
methods = raw_methods.map do |method_pin|
|
572
|
+
method_pin.resolve_generics(namespace_pin, rooted_type)
|
573
|
+
end
|
574
|
+
else
|
575
|
+
raw_methods
|
576
|
+
end
|
577
|
+
result.concat methods
|
531
578
|
if deep
|
532
579
|
if scope == :instance
|
533
|
-
store.get_includes(fqns).reverse.each do |
|
534
|
-
|
535
|
-
|
580
|
+
store.get_includes(fqns).reverse.each do |include_tag|
|
581
|
+
rooted_include_tag = qualify(include_tag, rooted_tag)
|
582
|
+
# Ensure the types returned by the included methods are
|
583
|
+
# relative to the generics passed to the include. e.g.,
|
584
|
+
# Foo<String> might include Enumerable<String>
|
585
|
+
#
|
586
|
+
# @todo perform the same translation in the other areas
|
587
|
+
# here after adding a spec and handling things correctly
|
588
|
+
# in ApiMap::Store and RbsMap::Conversions
|
589
|
+
resolved_include_type = ComplexType.parse(rooted_include_tag).resolve_generics(namespace_pin, rooted_type)
|
590
|
+
methods = inner_get_methods(resolved_include_type.tag, scope, visibility, deep, skip, true)
|
591
|
+
result.concat methods
|
536
592
|
end
|
537
593
|
fqsc = qualify_superclass(fqns)
|
538
594
|
unless fqsc.nil?
|
@@ -596,6 +652,8 @@ module Solargraph
|
|
596
652
|
qualify namespace, context.split('::')[0..-2].join('::')
|
597
653
|
end
|
598
654
|
|
655
|
+
# @param fqsub [String]
|
656
|
+
# @return [String, nil]
|
599
657
|
def qualify_superclass fqsub
|
600
658
|
sup = store.get_superclass(fqsub)
|
601
659
|
return nil if sup.nil?
|
@@ -605,11 +663,12 @@ module Solargraph
|
|
605
663
|
qualify(sup, parts.join('::'))
|
606
664
|
end
|
607
665
|
|
608
|
-
# @param name [String]
|
609
|
-
# @param root [String]
|
610
|
-
# @param skip [Set<String>]
|
611
|
-
# @return [String, nil]
|
666
|
+
# @param name [String] Namespace to fully qualify
|
667
|
+
# @param root [String] The context to search
|
668
|
+
# @param skip [Set<String>] Contexts already searched
|
669
|
+
# @return [String, nil] Fully qualified ("rooted") namespace
|
612
670
|
def inner_qualify name, root, skip
|
671
|
+
return name if name == ComplexType::GENERIC_TAG_NAME
|
613
672
|
return nil if name.nil?
|
614
673
|
return nil if skip.include?(root)
|
615
674
|
skip.add root
|
@@ -659,8 +718,8 @@ module Solargraph
|
|
659
718
|
|
660
719
|
# Sort an array of pins to put nil or undefined variables last.
|
661
720
|
#
|
662
|
-
# @param pins [
|
663
|
-
# @return [
|
721
|
+
# @param pins [Enumerable<Solargraph::Pin::Base>]
|
722
|
+
# @return [Enumerable<Solargraph::Pin::Base>]
|
664
723
|
def prefer_non_nil_variables pins
|
665
724
|
result = []
|
666
725
|
nil_pins = []
|
@@ -674,8 +733,8 @@ module Solargraph
|
|
674
733
|
result + nil_pins
|
675
734
|
end
|
676
735
|
|
677
|
-
# @param pins [
|
678
|
-
# @param visibility [
|
736
|
+
# @param pins [Enumerable<Pin::Base>]
|
737
|
+
# @param visibility [Enumerable<Symbol>]
|
679
738
|
# @return [Array<Pin::Base>]
|
680
739
|
def resolve_method_aliases pins, visibility = [:public, :private, :protected]
|
681
740
|
result = []
|
@@ -692,7 +751,7 @@ module Solargraph
|
|
692
751
|
def resolve_method_alias pin
|
693
752
|
return pin if !pin.is_a?(Pin::MethodAlias) || @method_alias_stack.include?(pin.path)
|
694
753
|
@method_alias_stack.push pin.path
|
695
|
-
origin = get_method_stack(pin.full_context.
|
754
|
+
origin = get_method_stack(pin.full_context.tag, pin.original, scope: pin.scope).first
|
696
755
|
@method_alias_stack.pop
|
697
756
|
return pin if origin.nil?
|
698
757
|
args = {
|
data/lib/solargraph/bench.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'set'
|
4
3
|
|
5
4
|
module Solargraph
|
6
5
|
# A container of source maps and workspace data to be cataloged in an ApiMap.
|
@@ -21,7 +20,8 @@ module Solargraph
|
|
21
20
|
def initialize source_maps: [], workspace: Workspace.new, external_requires: []
|
22
21
|
@source_maps = source_maps.to_set
|
23
22
|
@workspace = workspace
|
24
|
-
@external_requires = external_requires.
|
23
|
+
@external_requires = external_requires.reject { |path| workspace.would_require?(path) }
|
24
|
+
.to_set
|
25
25
|
end
|
26
26
|
end
|
27
27
|
end
|
data/lib/solargraph/cache.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'fileutils'
|
2
|
+
require 'rbs'
|
2
3
|
|
3
4
|
module Solargraph
|
4
5
|
module Cache
|
@@ -14,7 +15,7 @@ module Solargraph
|
|
14
15
|
File.join(Dir.home, '.cache', 'solargraph')
|
15
16
|
end
|
16
17
|
|
17
|
-
# The working directory for the current Ruby and Solargraph versions.
|
18
|
+
# The working directory for the current Ruby, RBS, and Solargraph versions.
|
18
19
|
#
|
19
20
|
# @return [String]
|
20
21
|
def work_dir
|
@@ -23,9 +24,21 @@ module Solargraph
|
|
23
24
|
File.join(base_dir, "ruby-#{RUBY_VERSION}", "rbs-#{RBS::VERSION}", "solargraph-#{Solargraph::VERSION}")
|
24
25
|
end
|
25
26
|
|
27
|
+
# Append the given path to the current cache directory (`work_dir`).
|
28
|
+
#
|
29
|
+
# @example
|
30
|
+
# Cache.join('date-3.4.1.ser')
|
31
|
+
#
|
32
|
+
# @param path [Array<String>]
|
33
|
+
# @return [String]
|
34
|
+
def join *path
|
35
|
+
File.join(work_dir, *path)
|
36
|
+
end
|
37
|
+
|
38
|
+
# @param path [Array<String>]
|
26
39
|
# @return [Array<Solargraph::Pin::Base>, nil]
|
27
40
|
def load *path
|
28
|
-
file =
|
41
|
+
file = join(*path)
|
29
42
|
return nil unless File.file?(file)
|
30
43
|
Marshal.load(File.read(file, mode: 'rb'))
|
31
44
|
rescue StandardError => e
|
@@ -34,17 +47,28 @@ module Solargraph
|
|
34
47
|
nil
|
35
48
|
end
|
36
49
|
|
37
|
-
|
50
|
+
def exist? *path
|
51
|
+
File.file? join(*path)
|
52
|
+
end
|
53
|
+
|
54
|
+
# @param path [Array<String>]
|
55
|
+
# @param pins [Array<Pin::Base>]
|
56
|
+
# @return [void]
|
38
57
|
def save *path, pins
|
39
|
-
return false if pins.empty?
|
40
58
|
file = File.join(work_dir, *path)
|
41
59
|
base = File.dirname(file)
|
42
60
|
FileUtils.mkdir_p base unless File.directory?(base)
|
43
61
|
ser = Marshal.dump(pins)
|
44
62
|
File.write file, ser, mode: 'wb'
|
45
|
-
true
|
46
63
|
end
|
47
64
|
|
65
|
+
# @return [void]
|
66
|
+
# @param path [Array<String>]
|
67
|
+
def uncache *path
|
68
|
+
FileUtils.rm_rf File.join(work_dir, *path), secure: true
|
69
|
+
end
|
70
|
+
|
71
|
+
# @return [void]
|
48
72
|
def clear
|
49
73
|
FileUtils.rm_rf base_dir, secure: true
|
50
74
|
end
|
@@ -2,9 +2,23 @@
|
|
2
2
|
|
3
3
|
module Solargraph
|
4
4
|
class ComplexType
|
5
|
-
# Methods for accessing type data
|
5
|
+
# Methods for accessing type data available from
|
6
|
+
# both ComplexType and UniqueType.
|
6
7
|
#
|
8
|
+
# @abstract This mixin relies on these -
|
9
|
+
# instance variables:
|
10
|
+
# @name: String
|
11
|
+
# @subtypes: Array<ComplexType>
|
12
|
+
# @rooted: boolish
|
13
|
+
# methods:
|
14
|
+
# transform()
|
7
15
|
module TypeMethods
|
16
|
+
# @!method transform(new_name = nil, &transform_type)
|
17
|
+
# @param new_name [String, nil]
|
18
|
+
# @yieldparam t [UniqueType]
|
19
|
+
# @yieldreturn [UniqueType]
|
20
|
+
# @return [UniqueType, nil]
|
21
|
+
|
8
22
|
# @return [String]
|
9
23
|
attr_reader :name
|
10
24
|
|
@@ -24,8 +38,7 @@ module Solargraph
|
|
24
38
|
|
25
39
|
# @return [Boolean]
|
26
40
|
def nil_type?
|
27
|
-
@nil_type
|
28
|
-
@nil_type
|
41
|
+
@nil_type ||= (name.casecmp('nil') == 0)
|
29
42
|
end
|
30
43
|
|
31
44
|
# @return [Boolean]
|
@@ -45,6 +58,22 @@ module Solargraph
|
|
45
58
|
name == 'undefined'
|
46
59
|
end
|
47
60
|
|
61
|
+
# @param generics_to_erase [Enumerable<String>]
|
62
|
+
# @return [self]
|
63
|
+
def erase_generics(generics_to_erase)
|
64
|
+
transform do |type|
|
65
|
+
if type.name == ComplexType::GENERIC_TAG_NAME
|
66
|
+
if type.all_params.length == 1 && generics_to_erase.include?(type.all_params.first.to_s)
|
67
|
+
ComplexType::UNDEFINED
|
68
|
+
else
|
69
|
+
type
|
70
|
+
end
|
71
|
+
else
|
72
|
+
type
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
48
77
|
# @return [Boolean]
|
49
78
|
def list_parameters?
|
50
79
|
substring.start_with?('<')
|
@@ -80,12 +109,25 @@ module Solargraph
|
|
80
109
|
end.call
|
81
110
|
end
|
82
111
|
|
83
|
-
# @return [
|
112
|
+
# @return [String]
|
113
|
+
def rooted_namespace
|
114
|
+
return namespace unless rooted?
|
115
|
+
"::#{namespace}"
|
116
|
+
end
|
117
|
+
|
118
|
+
# @return [String]
|
119
|
+
def rooted_name
|
120
|
+
return name unless rooted?
|
121
|
+
"::#{name}"
|
122
|
+
end
|
123
|
+
|
124
|
+
# @return [::Symbol] :class or :instance
|
84
125
|
def scope
|
85
126
|
@scope ||= :instance if duck_type? || nil_type?
|
86
127
|
@scope ||= (name == 'Class' || name == 'Module') && !subtypes.empty? ? :class : :instance
|
87
128
|
end
|
88
129
|
|
130
|
+
# @param other [Object]
|
89
131
|
def == other
|
90
132
|
return false unless self.class == other.class
|
91
133
|
tag == other.tag
|
@@ -99,7 +141,7 @@ module Solargraph
|
|
99
141
|
#
|
100
142
|
# @param api_map [ApiMap] The ApiMap that performs qualification
|
101
143
|
# @param context [String] The namespace from which to resolve names
|
102
|
-
# @return [ComplexType] The generated ComplexType
|
144
|
+
# @return [self, ComplexType, UniqueType] The generated ComplexType
|
103
145
|
def qualify api_map, context = ''
|
104
146
|
return self if name == GENERIC_TAG_NAME
|
105
147
|
return ComplexType.new([self]) if duck_type? || void? || undefined?
|
@@ -110,13 +152,16 @@ module Solargraph
|
|
110
152
|
return UniqueType::UNDEFINED
|
111
153
|
end
|
112
154
|
fqns = "::#{fqns}" # Ensure the resulting complex type is rooted
|
113
|
-
|
114
|
-
|
155
|
+
all_ltypes = key_types.map { |t| t.qualify api_map, context }.uniq
|
156
|
+
all_rtypes = value_types.map { |t| t.qualify api_map, context }
|
115
157
|
if list_parameters?
|
158
|
+
rtypes = all_rtypes.uniq
|
116
159
|
Solargraph::ComplexType.parse("#{fqns}<#{rtypes.map(&:tag).join(', ')}>")
|
117
160
|
elsif fixed_parameters?
|
118
|
-
Solargraph::ComplexType.parse("#{fqns}(#{
|
161
|
+
Solargraph::ComplexType.parse("#{fqns}(#{all_rtypes.map(&:tag).join(', ')})")
|
119
162
|
elsif hash_parameters?
|
163
|
+
ltypes = all_ltypes.uniq
|
164
|
+
rtypes = all_rtypes.uniq
|
120
165
|
Solargraph::ComplexType.parse("#{fqns}{#{ltypes.map(&:tag).join(', ')} => #{rtypes.map(&:tag).join(', ')}}")
|
121
166
|
else
|
122
167
|
Solargraph::ComplexType.parse(fqns)
|