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.
- checksums.yaml +4 -4
- data/.github/FUNDING.yml +1 -0
- data/.github/workflows/plugins.yml +40 -0
- data/.github/workflows/rspec.yml +4 -8
- data/.github/workflows/typecheck.yml +34 -0
- data/.yardopts +2 -2
- data/CHANGELOG.md +166 -3
- data/LICENSE +1 -1
- data/README.md +19 -16
- data/SPONSORS.md +2 -9
- data/lib/solargraph/api_map/cache.rb +50 -20
- data/lib/solargraph/api_map/source_to_yard.rb +17 -10
- data/lib/solargraph/api_map/store.rb +68 -15
- data/lib/solargraph/api_map.rb +238 -112
- data/lib/solargraph/bench.rb +3 -2
- data/lib/solargraph/cache.rb +77 -0
- data/lib/solargraph/complex_type/type_methods.rb +116 -35
- data/lib/solargraph/complex_type/unique_type.rb +261 -33
- data/lib/solargraph/complex_type.rb +149 -30
- data/lib/solargraph/convention/rakefile.rb +17 -0
- data/lib/solargraph/convention.rb +2 -3
- 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 +23 -8
- data/lib/solargraph/diagnostics/rubocop_helpers.rb +4 -1
- data/lib/solargraph/diagnostics/type_check.rb +1 -0
- data/lib/solargraph/diagnostics.rb +2 -2
- data/lib/solargraph/doc_map.rb +187 -0
- data/lib/solargraph/gem_pins.rb +72 -0
- data/lib/solargraph/language_server/host/diagnoser.rb +2 -2
- data/lib/solargraph/language_server/host/dispatch.rb +22 -5
- data/lib/solargraph/language_server/host/message_worker.rb +4 -0
- data/lib/solargraph/language_server/host/sources.rb +8 -65
- data/lib/solargraph/language_server/host.rb +88 -93
- data/lib/solargraph/language_server/message/base.rb +1 -1
- 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/extended/download_core.rb +1 -5
- data/lib/solargraph/language_server/message/initialize.rb +27 -0
- data/lib/solargraph/language_server/message/initialized.rb +1 -0
- data/lib/solargraph/language_server/message/text_document/document_symbol.rb +4 -1
- data/lib/solargraph/language_server/message/text_document/formatting.rb +5 -4
- data/lib/solargraph/language_server/message/text_document/hover.rb +2 -0
- data/lib/solargraph/language_server/message/text_document/signature_help.rb +1 -6
- data/lib/solargraph/language_server/message/text_document/type_definition.rb +24 -0
- data/lib/solargraph/language_server/message/text_document.rb +1 -1
- data/lib/solargraph/language_server/message/workspace/did_change_configuration.rb +5 -0
- data/lib/solargraph/language_server/message/workspace/did_change_watched_files.rb +10 -3
- data/lib/solargraph/language_server/message.rb +1 -0
- data/lib/solargraph/language_server/progress.rb +118 -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/language_server.rb +1 -0
- data/lib/solargraph/library.rb +231 -104
- data/lib/solargraph/location.rb +1 -0
- data/lib/solargraph/page.rb +6 -0
- data/lib/solargraph/parser/comment_ripper.rb +4 -0
- data/lib/solargraph/parser/node_methods.rb +47 -7
- data/lib/solargraph/parser/node_processor/base.rb +11 -1
- data/lib/solargraph/parser/node_processor.rb +1 -0
- data/lib/solargraph/parser/{legacy → parser_gem}/class_methods.rb +31 -9
- data/lib/solargraph/parser/{legacy → parser_gem}/flawed_builder.rb +3 -1
- data/lib/solargraph/parser/{legacy → parser_gem}/node_chainer.rb +57 -41
- data/lib/solargraph/parser/parser_gem/node_methods.rb +495 -0
- data/lib/solargraph/parser/{rubyvm → parser_gem}/node_processors/alias_node.rb +1 -1
- data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +53 -0
- 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 +14 -4
- data/lib/solargraph/parser/{rubyvm → parser_gem}/node_processors/cvasgn_node.rb +1 -1
- data/lib/solargraph/parser/{rubyvm → parser_gem}/node_processors/def_node.rb +7 -20
- 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/parser_gem/node_processors/masgn_node.rb +47 -0
- 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/parser_gem/node_processors/sclass_node.rb +42 -0
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/send_node.rb +7 -5
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/sym_node.rb +1 -1
- data/lib/solargraph/parser/parser_gem/node_processors.rb +56 -0
- data/lib/solargraph/parser/parser_gem.rb +12 -0
- data/lib/solargraph/parser/region.rb +1 -1
- data/lib/solargraph/parser/snippet.rb +2 -0
- data/lib/solargraph/parser.rb +9 -10
- data/lib/solargraph/pin/base.rb +69 -11
- data/lib/solargraph/pin/base_variable.rb +40 -7
- data/lib/solargraph/pin/block.rb +81 -33
- data/lib/solargraph/pin/closure.rb +17 -2
- data/lib/solargraph/pin/common.rb +7 -3
- data/lib/solargraph/pin/conversions.rb +34 -8
- data/lib/solargraph/pin/delegated_method.rb +101 -0
- data/lib/solargraph/pin/documenting.rb +25 -32
- data/lib/solargraph/pin/instance_variable.rb +4 -0
- data/lib/solargraph/pin/local_variable.rb +13 -1
- data/lib/solargraph/pin/method.rb +273 -17
- data/lib/solargraph/pin/namespace.rb +17 -1
- data/lib/solargraph/pin/parameter.rb +40 -28
- data/lib/solargraph/pin/reference/override.rb +2 -2
- data/lib/solargraph/pin/reference.rb +8 -0
- data/lib/solargraph/pin/search.rb +4 -4
- data/lib/solargraph/pin/signature.rb +143 -0
- data/lib/solargraph/pin.rb +2 -1
- data/lib/solargraph/range.rb +4 -6
- data/lib/solargraph/rbs_map/conversions.rb +607 -0
- data/lib/solargraph/rbs_map/core_fills.rb +50 -0
- data/lib/solargraph/rbs_map/core_map.rb +28 -0
- data/lib/solargraph/rbs_map/stdlib_map.rb +33 -0
- data/lib/solargraph/rbs_map.rb +92 -0
- data/lib/solargraph/shell.rb +85 -59
- data/lib/solargraph/source/chain/array.rb +32 -0
- data/lib/solargraph/source/chain/block_symbol.rb +13 -0
- data/lib/solargraph/source/chain/call.rb +125 -61
- 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 +8 -2
- data/lib/solargraph/source/chain/or.rb +1 -1
- data/lib/solargraph/source/chain/z_super.rb +3 -3
- data/lib/solargraph/source/chain.rb +64 -14
- data/lib/solargraph/source/change.rb +3 -0
- data/lib/solargraph/source/cursor.rb +2 -0
- data/lib/solargraph/source/source_chainer.rb +8 -5
- data/lib/solargraph/source/updater.rb +1 -0
- data/lib/solargraph/source.rb +18 -63
- data/lib/solargraph/source_map/clip.rb +31 -23
- data/lib/solargraph/source_map/mapper.rb +23 -7
- data/lib/solargraph/source_map.rb +36 -11
- data/lib/solargraph/type_checker/checks.rb +10 -2
- data/lib/solargraph/type_checker.rb +229 -100
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/views/environment.erb +2 -2
- data/lib/solargraph/workspace/config.rb +15 -11
- data/lib/solargraph/workspace.rb +41 -17
- 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 +23 -7
- data/lib/solargraph/yard_map/mapper.rb +1 -1
- data/lib/solargraph/yard_map/to_method.rb +11 -4
- data/lib/solargraph/yard_map.rb +1 -443
- data/lib/solargraph/yard_tags.rb +20 -0
- data/lib/solargraph/yardoc.rb +52 -0
- data/lib/solargraph.rb +8 -6
- data/solargraph.gemspec +19 -8
- metadata +164 -99
- data/.travis.yml +0 -19
- data/lib/solargraph/api_map/bundler_methods.rb +0 -22
- data/lib/solargraph/compat.rb +0 -37
- data/lib/solargraph/convention/rspec.rb +0 -30
- data/lib/solargraph/documentor.rb +0 -76
- data/lib/solargraph/language_server/host/cataloger.rb +0 -56
- data/lib/solargraph/parser/legacy/node_methods.rb +0 -325
- data/lib/solargraph/parser/legacy/node_processors/alias_node.rb +0 -23
- data/lib/solargraph/parser/legacy/node_processors/args_node.rb +0 -35
- data/lib/solargraph/parser/legacy/node_processors/begin_node.rb +0 -15
- data/lib/solargraph/parser/legacy/node_processors/cvasgn_node.rb +0 -23
- data/lib/solargraph/parser/legacy/node_processors/def_node.rb +0 -63
- data/lib/solargraph/parser/legacy/node_processors/sclass_node.rb +0 -21
- data/lib/solargraph/parser/legacy/node_processors.rb +0 -54
- data/lib/solargraph/parser/legacy.rb +0 -12
- data/lib/solargraph/parser/rubyvm/class_methods.rb +0 -144
- data/lib/solargraph/parser/rubyvm/node_chainer.rb +0 -160
- data/lib/solargraph/parser/rubyvm/node_methods.rb +0 -315
- 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 -22
- data/lib/solargraph/parser/rubyvm/node_processors/defs_node.rb +0 -57
- 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 -45
- data/lib/solargraph/parser/rubyvm/node_processors/sclass_node.rb +0 -21
- data/lib/solargraph/parser/rubyvm/node_processors/scope_node.rb +0 -15
- data/lib/solargraph/parser/rubyvm/node_processors/send_node.rb +0 -277
- data/lib/solargraph/parser/rubyvm/node_processors/sym_node.rb +0 -18
- data/lib/solargraph/parser/rubyvm/node_processors.rb +0 -63
- data/lib/solargraph/parser/rubyvm.rb +0 -40
- data/lib/solargraph/yard_map/core_docs.rb +0 -170
- data/lib/solargraph/yard_map/core_fills.rb +0 -208
- data/lib/solargraph/yard_map/core_gen.rb +0 -76
- data/lib/solargraph/yard_map/rdoc_to_yard.rb +0 -140
- data/lib/solargraph/yard_map/stdlib_fills.rb +0 -43
- data/lib/yard-solargraph.rb +0 -33
- data/yardoc/2.2.2.tar.gz +0 -0
data/lib/solargraph/api_map.rb
CHANGED
@@ -1,10 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'rubygems'
|
4
|
-
require 'set'
|
5
3
|
require 'pathname'
|
6
4
|
require 'yard'
|
7
|
-
require '
|
5
|
+
require 'solargraph/yard_tags'
|
8
6
|
|
9
7
|
module Solargraph
|
10
8
|
# An aggregate provider for information about workspaces, sources, gems, and
|
@@ -14,13 +12,12 @@ 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
|
23
18
|
|
19
|
+
@@core_map = RbsMap::CoreMap.new
|
20
|
+
|
24
21
|
# @return [Array<String>]
|
25
22
|
attr_reader :missing_docs
|
26
23
|
|
@@ -32,6 +29,25 @@ module Solargraph
|
|
32
29
|
index pins
|
33
30
|
end
|
34
31
|
|
32
|
+
#
|
33
|
+
# This is a mutable object, which is cached in the Chain class -
|
34
|
+
# if you add any fields which change the results of calls (not
|
35
|
+
# just caches), please also change `equality_fields` below.
|
36
|
+
#
|
37
|
+
|
38
|
+
def eql?(other)
|
39
|
+
self.class == other.class &&
|
40
|
+
equality_fields == other.equality_fields
|
41
|
+
end
|
42
|
+
|
43
|
+
def ==(other)
|
44
|
+
self.eql?(other)
|
45
|
+
end
|
46
|
+
|
47
|
+
def hash
|
48
|
+
equality_fields.hash
|
49
|
+
end
|
50
|
+
|
35
51
|
# @param pins [Array<Pin::Base>]
|
36
52
|
# @return [self]
|
37
53
|
def index pins
|
@@ -40,7 +56,7 @@ module Solargraph
|
|
40
56
|
@source_map_hash = {}
|
41
57
|
implicit.clear
|
42
58
|
cache.clear
|
43
|
-
@store = Store.new(
|
59
|
+
@store = Store.new(@@core_map.pins + pins)
|
44
60
|
self
|
45
61
|
end
|
46
62
|
|
@@ -57,32 +73,50 @@ module Solargraph
|
|
57
73
|
# Catalog a bench.
|
58
74
|
#
|
59
75
|
# @param bench [Bench]
|
76
|
+
# @return [self]
|
60
77
|
def catalog bench
|
61
|
-
|
62
|
-
|
78
|
+
old_api_hash = @source_map_hash&.values&.map(&:api_hash)
|
79
|
+
need_to_uncache = (old_api_hash != bench.source_maps.map(&:api_hash))
|
63
80
|
@source_map_hash = bench.source_maps.map { |s| [s.filename, s] }.to_h
|
64
|
-
pins = bench.source_maps.
|
65
|
-
|
81
|
+
pins = bench.source_maps.flat_map(&:pins).flatten
|
82
|
+
implicit.clear
|
66
83
|
source_map_hash.each_value do |map|
|
67
84
|
implicit.merge map.environ
|
68
85
|
end
|
69
|
-
external_requires
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
@
|
76
|
-
|
86
|
+
unresolved_requires = (bench.external_requires + implicit.requires + bench.workspace.config.required).to_a.compact.uniq
|
87
|
+
if @unresolved_requires != unresolved_requires || @doc_map&.uncached_gemspecs&.any?
|
88
|
+
@doc_map = DocMap.new(unresolved_requires, [], bench.workspace.rbs_collection_path) # @todo Implement gem preferences
|
89
|
+
@unresolved_requires = unresolved_requires
|
90
|
+
need_to_uncache = true
|
91
|
+
end
|
92
|
+
@store = Store.new(@@core_map.pins + @doc_map.pins + implicit.pins + pins)
|
93
|
+
@cache.clear if need_to_uncache
|
94
|
+
|
95
|
+
@missing_docs = [] # @todo Implement missing docs
|
77
96
|
self
|
78
97
|
end
|
79
98
|
|
99
|
+
protected def equality_fields
|
100
|
+
[self.class, @source_map_hash, implicit, @doc_map, @unresolved_requires, @missing_docs]
|
101
|
+
end
|
102
|
+
|
103
|
+
# @return [::Array<Gem::Specification>]
|
104
|
+
def uncached_gemspecs
|
105
|
+
@doc_map&.uncached_gemspecs || []
|
106
|
+
end
|
107
|
+
|
108
|
+
# @return [Array<Pin::Base>]
|
109
|
+
def core_pins
|
110
|
+
@@core_map.pins
|
111
|
+
end
|
112
|
+
|
80
113
|
# @param name [String]
|
81
114
|
# @return [YARD::Tags::MacroDirective, nil]
|
82
115
|
def named_macro name
|
83
116
|
store.named_macros[name]
|
84
117
|
end
|
85
118
|
|
119
|
+
# @return [Set<String>]
|
86
120
|
def required
|
87
121
|
@required ||= Set.new
|
88
122
|
end
|
@@ -108,7 +142,7 @@ module Solargraph
|
|
108
142
|
# @return [SourceMap::Clip]
|
109
143
|
def clip_at filename, position
|
110
144
|
position = Position.normalize(position)
|
111
|
-
|
145
|
+
clip(cursor_at(filename, position))
|
112
146
|
end
|
113
147
|
|
114
148
|
# Create an ApiMap with a workspace in the specified directory.
|
@@ -125,21 +159,33 @@ module Solargraph
|
|
125
159
|
api_map
|
126
160
|
end
|
127
161
|
|
162
|
+
# Create an ApiMap with a workspace in the specified directory and cache
|
163
|
+
# any missing gems.
|
164
|
+
#
|
165
|
+
#
|
166
|
+
# @todo IO::NULL is incorrectly inferred to be a String.
|
167
|
+
# @sg-ignore
|
168
|
+
#
|
169
|
+
# @param directory [String]
|
170
|
+
# @param out [IO] The output stream for messages
|
171
|
+
# @return [ApiMap]
|
172
|
+
def self.load_with_cache directory, out = IO::NULL
|
173
|
+
api_map = load(directory)
|
174
|
+
return api_map if api_map.uncached_gemspecs.empty?
|
175
|
+
|
176
|
+
api_map.uncached_gemspecs.each do |gemspec|
|
177
|
+
out.puts "Caching gem #{gemspec.name} #{gemspec.version}"
|
178
|
+
pins = GemPins.build(gemspec)
|
179
|
+
Solargraph::Cache.save('gems', "#{gemspec.name}-#{gemspec.version}.ser", pins)
|
180
|
+
end
|
181
|
+
load(directory)
|
182
|
+
end
|
183
|
+
|
128
184
|
# @return [Array<Solargraph::Pin::Base>]
|
129
185
|
def pins
|
130
186
|
store.pins
|
131
187
|
end
|
132
188
|
|
133
|
-
def rebindable_method_names
|
134
|
-
@rebindable_method_names ||= begin
|
135
|
-
result = yard_map.rebindable_method_names
|
136
|
-
source_maps.each do |map|
|
137
|
-
result.merge map.rebindable_method_names
|
138
|
-
end
|
139
|
-
result
|
140
|
-
end
|
141
|
-
end
|
142
|
-
|
143
189
|
# An array of pins based on Ruby keywords (`if`, `end`, etc.).
|
144
190
|
#
|
145
191
|
# @return [Enumerable<Solargraph::Pin::Keyword>]
|
@@ -186,22 +232,60 @@ module Solargraph
|
|
186
232
|
result
|
187
233
|
end
|
188
234
|
|
189
|
-
#
|
190
|
-
#
|
191
|
-
#
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
235
|
+
# @param namespace [String]
|
236
|
+
# @param context [String]
|
237
|
+
# @return [Array<Pin::Namespace>]
|
238
|
+
def get_namespace_pins namespace, context
|
239
|
+
store.fqns_pins(qualify(namespace, context))
|
240
|
+
end
|
241
|
+
|
242
|
+
# Determine fully qualified tag for a given tag used inside the
|
243
|
+
# definition of another tag ("context"). This method will start
|
244
|
+
# the search in the specified context until it finds a match for
|
245
|
+
# the tag.
|
246
|
+
#
|
247
|
+
# Does not recurse into qualifying the type parameters, but
|
248
|
+
# returns any which were passed in unchanged.
|
249
|
+
#
|
250
|
+
# @param tag [String, nil] The namespace to
|
251
|
+
# match, complete with generic parameters set to appropriate
|
252
|
+
# values if available
|
253
|
+
# @param context_tag [String] The context in which the tag was
|
254
|
+
# referenced; start from here to resolve the name
|
255
|
+
# @return [String, nil] fully qualified tag
|
256
|
+
def qualify tag, context_tag = ''
|
257
|
+
return tag if ['self', nil].include?(tag)
|
258
|
+
context_type = ComplexType.try_parse(context_tag)
|
259
|
+
return unless context_type
|
260
|
+
|
261
|
+
type = ComplexType.try_parse(tag)
|
262
|
+
return unless type
|
263
|
+
|
264
|
+
fqns = qualify_namespace(type.rooted_namespace, context_type.rooted_namespace)
|
265
|
+
return unless fqns
|
266
|
+
|
267
|
+
fqns + type.substring
|
268
|
+
end
|
269
|
+
|
270
|
+
# Determine fully qualified namespace for a given namespace used
|
271
|
+
# inside the definition of another tag ("context"). This method
|
272
|
+
# will start the search in the specified context until it finds a
|
273
|
+
# match for the namespace.
|
274
|
+
#
|
275
|
+
# @param namespace [String, nil] The namespace to
|
276
|
+
# match
|
277
|
+
# @param context_namespace [String] The context namespace in which the
|
278
|
+
# tag was referenced; start from here to resolve the name
|
279
|
+
# @return [String, nil] fully qualified namespace
|
280
|
+
def qualify_namespace(namespace, context_namespace = '')
|
281
|
+
cached = cache.get_qualified_namespace(namespace, context_namespace)
|
198
282
|
return cached.clone unless cached.nil?
|
199
283
|
result = if namespace.start_with?('::')
|
200
284
|
inner_qualify(namespace[2..-1], '', Set.new)
|
201
285
|
else
|
202
|
-
inner_qualify(namespace,
|
286
|
+
inner_qualify(namespace, context_namespace, Set.new)
|
203
287
|
end
|
204
|
-
cache.set_qualified_namespace(namespace,
|
288
|
+
cache.set_qualified_namespace(namespace, context_namespace, result)
|
205
289
|
result
|
206
290
|
end
|
207
291
|
|
@@ -227,49 +311,70 @@ module Solargraph
|
|
227
311
|
# Get an array of class variable pins for a namespace.
|
228
312
|
#
|
229
313
|
# @param namespace [String] A fully qualified namespace
|
230
|
-
# @return [
|
314
|
+
# @return [Enumerable<Solargraph::Pin::ClassVariable>]
|
231
315
|
def get_class_variable_pins(namespace)
|
232
316
|
prefer_non_nil_variables(store.get_class_variables(namespace))
|
233
317
|
end
|
234
318
|
|
235
|
-
# @return [
|
319
|
+
# @return [Enumerable<Solargraph::Pin::Base>]
|
236
320
|
def get_symbols
|
237
321
|
store.get_symbols
|
238
322
|
end
|
239
323
|
|
240
|
-
# @return [
|
324
|
+
# @return [Enumerable<Solargraph::Pin::GlobalVariable>]
|
241
325
|
def get_global_variable_pins
|
242
326
|
store.pins_by_class(Pin::GlobalVariable)
|
243
327
|
end
|
244
328
|
|
245
329
|
# Get an array of methods available in a particular context.
|
246
330
|
#
|
247
|
-
# @param
|
331
|
+
# @param rooted_tag [String] The fully qualified namespace to search for methods
|
248
332
|
# @param scope [Symbol] :class or :instance
|
249
333
|
# @param visibility [Array<Symbol>] :public, :protected, and/or :private
|
250
334
|
# @param deep [Boolean] True to include superclasses, mixins, etc.
|
251
335
|
# @return [Array<Solargraph::Pin::Method>]
|
252
|
-
def get_methods
|
253
|
-
cached = cache.get_methods(
|
336
|
+
def get_methods rooted_tag, scope: :instance, visibility: [:public], deep: true
|
337
|
+
cached = cache.get_methods(rooted_tag, scope, visibility, deep)
|
254
338
|
return cached.clone unless cached.nil?
|
255
339
|
result = []
|
256
340
|
skip = Set.new
|
257
|
-
if
|
341
|
+
if rooted_tag == ''
|
258
342
|
# @todo Implement domains
|
259
343
|
implicit.domains.each do |domain|
|
260
344
|
type = ComplexType.try_parse(domain)
|
261
345
|
next if type.undefined?
|
262
346
|
result.concat inner_get_methods(type.name, type.scope, visibility, deep, skip)
|
263
347
|
end
|
264
|
-
result.concat inner_get_methods(
|
265
|
-
result.concat inner_get_methods(
|
348
|
+
result.concat inner_get_methods(rooted_tag, :class, visibility, deep, skip)
|
349
|
+
result.concat inner_get_methods(rooted_tag, :instance, visibility, deep, skip)
|
266
350
|
result.concat inner_get_methods('Kernel', :instance, visibility, deep, skip)
|
267
351
|
else
|
268
|
-
result.concat inner_get_methods(
|
352
|
+
result.concat inner_get_methods(rooted_tag, scope, visibility, deep, skip)
|
353
|
+
unless %w[Class Class<Class>].include?(rooted_tag)
|
354
|
+
result.map! do |pin|
|
355
|
+
next pin unless pin.path == 'Class#new'
|
356
|
+
init_pin = get_method_stack(rooted_tag, 'initialize').first
|
357
|
+
next pin unless init_pin
|
358
|
+
|
359
|
+
type = ComplexType.try_parse(ComplexType.try_parse(rooted_tag).namespace)
|
360
|
+
Pin::Method.new(
|
361
|
+
name: 'new',
|
362
|
+
scope: :class,
|
363
|
+
location: init_pin.location,
|
364
|
+
parameters: init_pin.parameters,
|
365
|
+
signatures: init_pin.signatures.map { |sig| sig.proxy(type) },
|
366
|
+
return_type: type,
|
367
|
+
comments: init_pin.comments,
|
368
|
+
closure: init_pin.closure
|
369
|
+
# @todo Hack to force TypeChecker#internal_or_core?
|
370
|
+
).tap { |pin| pin.source = :rbs }
|
371
|
+
end
|
372
|
+
end
|
269
373
|
result.concat inner_get_methods('Kernel', :instance, [:public], deep, skip) if visibility.include?(:private)
|
374
|
+
result.concat inner_get_methods('Module', scope, visibility, deep, skip) if scope == :module
|
270
375
|
end
|
271
376
|
resolved = resolve_method_aliases(result, visibility)
|
272
|
-
cache.set_methods(
|
377
|
+
cache.set_methods(rooted_tag, scope, visibility, deep, resolved)
|
273
378
|
resolved
|
274
379
|
end
|
275
380
|
|
@@ -307,27 +412,27 @@ module Solargraph
|
|
307
412
|
visibility.push :protected
|
308
413
|
visibility.push :private if internal
|
309
414
|
end
|
310
|
-
result.merge get_methods(type.
|
415
|
+
result.merge get_methods(type.tag, scope: type.scope, visibility: visibility)
|
311
416
|
end
|
312
417
|
end
|
313
418
|
end
|
314
419
|
result.to_a
|
315
420
|
end
|
316
421
|
|
317
|
-
# Get a stack of method pins for a method name in a
|
318
|
-
# of the pins corresponds to
|
319
|
-
# first.
|
422
|
+
# Get a stack of method pins for a method name in a potentially
|
423
|
+
# parameterized namespace. The order of the pins corresponds to
|
424
|
+
# the ancestry chain, with highest precedence first.
|
320
425
|
#
|
321
426
|
# @example
|
322
427
|
# api_map.get_method_stack('Subclass', 'method_name')
|
323
428
|
# #=> [ <Subclass#method_name pin>, <Superclass#method_name pin> ]
|
324
429
|
#
|
325
|
-
# @param
|
326
|
-
# @param name [String]
|
430
|
+
# @param rooted_tag [String] Parameterized namespace, fully qualified
|
431
|
+
# @param name [String] Method name to look up
|
327
432
|
# @param scope [Symbol] :instance or :class
|
328
433
|
# @return [Array<Solargraph::Pin::Method>]
|
329
|
-
def get_method_stack
|
330
|
-
get_methods(
|
434
|
+
def get_method_stack rooted_tag, name, scope: :instance
|
435
|
+
get_methods(rooted_tag, scope: scope, visibility: [:private, :protected, :public]).select { |p| p.name == name }
|
331
436
|
end
|
332
437
|
|
333
438
|
# Get an array of all suggestions that match the specified path.
|
@@ -335,7 +440,7 @@ module Solargraph
|
|
335
440
|
# @deprecated Use #get_path_pins instead.
|
336
441
|
#
|
337
442
|
# @param path [String] The path to find
|
338
|
-
# @return [
|
443
|
+
# @return [Enumerable<Solargraph::Pin::Base>]
|
339
444
|
def get_path_suggestions path
|
340
445
|
return [] if path.nil?
|
341
446
|
resolve_method_aliases store.get_path_pins(path)
|
@@ -344,7 +449,7 @@ module Solargraph
|
|
344
449
|
# Get an array of pins that match the specified path.
|
345
450
|
#
|
346
451
|
# @param path [String]
|
347
|
-
# @return [
|
452
|
+
# @return [Enumerable<Pin::Base>]
|
348
453
|
def get_path_pins path
|
349
454
|
get_path_suggestions(path)
|
350
455
|
end
|
@@ -357,15 +462,9 @@ module Solargraph
|
|
357
462
|
# @param query [String] The text to match
|
358
463
|
# @return [Array<String>]
|
359
464
|
def search query
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
if (found.empty? || (query.include?('.') || query.include?('#')) || !(k.include?('.') || k.include?('#'))) &&
|
364
|
-
k.downcase.include?(query.downcase)
|
365
|
-
found.push k
|
366
|
-
end
|
367
|
-
end
|
368
|
-
found
|
465
|
+
pins.map(&:path)
|
466
|
+
.compact
|
467
|
+
.select { |path| path.downcase.include?(query.downcase) }
|
369
468
|
end
|
370
469
|
|
371
470
|
# Get YARD documentation for the specified path.
|
@@ -373,13 +472,13 @@ module Solargraph
|
|
373
472
|
# @example
|
374
473
|
# api_map.document('String#split')
|
375
474
|
#
|
475
|
+
# @todo This method is likely superfluous. Calling get_path_pins directly
|
476
|
+
# should be sufficient.
|
477
|
+
#
|
376
478
|
# @param path [String] The path to find
|
377
|
-
# @return [
|
479
|
+
# @return [Enumerable<Pin::Base>]
|
378
480
|
def document path
|
379
|
-
|
380
|
-
docs = []
|
381
|
-
docs.push code_object_at(path) unless code_object_at(path).nil?
|
382
|
-
docs
|
481
|
+
get_path_pins(path)
|
383
482
|
end
|
384
483
|
|
385
484
|
# Get an array of all symbols in the workspace that match the query.
|
@@ -405,6 +504,7 @@ module Solargraph
|
|
405
504
|
# @return [SourceMap::Clip]
|
406
505
|
def clip cursor
|
407
506
|
raise FileNotFoundError, "ApiMap did not catalog #{cursor.filename}" unless source_map_hash.key?(cursor.filename)
|
507
|
+
|
408
508
|
SourceMap::Clip.new(self, cursor)
|
409
509
|
end
|
410
510
|
|
@@ -447,25 +547,24 @@ module Solargraph
|
|
447
547
|
def super_and_sub?(sup, sub)
|
448
548
|
fqsup = qualify(sup)
|
449
549
|
cls = qualify(sub)
|
450
|
-
|
550
|
+
tested = []
|
551
|
+
until fqsup.nil? || cls.nil? || tested.include?(cls)
|
451
552
|
return true if cls == fqsup
|
553
|
+
tested.push cls
|
452
554
|
cls = qualify_superclass(cls)
|
453
555
|
end
|
454
556
|
false
|
455
557
|
end
|
456
558
|
|
457
|
-
#
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
# Check if the host class includes the specified module.
|
559
|
+
# Check if the host class includes the specified module, ignoring
|
560
|
+
# type parameters used.
|
561
|
+
#
|
562
|
+
# @param host_ns [String] The class namesapce (no type parameters)
|
563
|
+
# @param module_ns [String] The module namespace (no type parameters)
|
463
564
|
#
|
464
|
-
# @param host [String] The class
|
465
|
-
# @param mod [String] The module
|
466
565
|
# @return [Boolean]
|
467
|
-
def type_include?(
|
468
|
-
store.get_includes(
|
566
|
+
def type_include?(host_ns, module_ns)
|
567
|
+
store.get_includes(host_ns).map { |inc_tag| ComplexType.parse(inc_tag).name }.include?(module_ns)
|
469
568
|
end
|
470
569
|
|
471
570
|
private
|
@@ -483,15 +582,19 @@ module Solargraph
|
|
483
582
|
# @return [Solargraph::ApiMap::Cache]
|
484
583
|
attr_reader :cache
|
485
584
|
|
486
|
-
# @param
|
585
|
+
# @param rooted_tag [String] A fully qualified namespace, with
|
586
|
+
# generic parameter values if applicable
|
487
587
|
# @param scope [Symbol] :class or :instance
|
488
588
|
# @param visibility [Array<Symbol>] :public, :protected, and/or :private
|
489
589
|
# @param deep [Boolean]
|
490
590
|
# @param skip [Set<String>]
|
491
591
|
# @param no_core [Boolean] Skip core classes if true
|
492
592
|
# @return [Array<Pin::Base>]
|
493
|
-
def inner_get_methods
|
494
|
-
|
593
|
+
def inner_get_methods rooted_tag, scope, visibility, deep, skip, no_core = false
|
594
|
+
rooted_type = ComplexType.parse(rooted_tag)
|
595
|
+
fqns = rooted_type.namespace
|
596
|
+
fqns_generic_params = rooted_type.all_params
|
597
|
+
return [] if no_core && fqns =~ /^(Object|BasicObject|Class|Module)$/
|
495
598
|
reqstr = "#{fqns}|#{scope}|#{visibility.sort}|#{deep}"
|
496
599
|
return [] if skip.include?(reqstr)
|
497
600
|
skip.add reqstr
|
@@ -502,12 +605,33 @@ module Solargraph
|
|
502
605
|
result.concat inner_get_methods(fqim, scope, visibility, deep, skip, true) unless fqim.nil?
|
503
606
|
end
|
504
607
|
end
|
505
|
-
|
608
|
+
# Store#get_methods doesn't know about full tags, just
|
609
|
+
# namespaces; resolving the generics in the method pins is this
|
610
|
+
# class' responsibility
|
611
|
+
raw_methods = store.get_methods(fqns, scope: scope, visibility: visibility).sort{ |a, b| a.name <=> b.name }
|
612
|
+
namespace_pin = store.get_path_pins(fqns).select { |p| p.is_a?(Pin::Namespace) }.first
|
613
|
+
methods = if namespace_pin && rooted_tag != fqns
|
614
|
+
methods = raw_methods.map do |method_pin|
|
615
|
+
method_pin.resolve_generics(namespace_pin, rooted_type)
|
616
|
+
end
|
617
|
+
else
|
618
|
+
raw_methods
|
619
|
+
end
|
620
|
+
result.concat methods
|
506
621
|
if deep
|
507
622
|
if scope == :instance
|
508
|
-
store.get_includes(fqns).reverse.each do |
|
509
|
-
|
510
|
-
|
623
|
+
store.get_includes(fqns).reverse.each do |include_tag|
|
624
|
+
rooted_include_tag = qualify(include_tag, rooted_tag)
|
625
|
+
# Ensure the types returned by the included methods are
|
626
|
+
# relative to the generics passed to the include. e.g.,
|
627
|
+
# Foo<String> might include Enumerable<String>
|
628
|
+
#
|
629
|
+
# @todo perform the same translation in the other areas
|
630
|
+
# here after adding a spec and handling things correctly
|
631
|
+
# in ApiMap::Store and RbsMap::Conversions
|
632
|
+
resolved_include_type = ComplexType.parse(rooted_include_tag).resolve_generics(namespace_pin, rooted_type)
|
633
|
+
methods = inner_get_methods(resolved_include_type.tag, scope, visibility, deep, skip, true)
|
634
|
+
result.concat methods
|
511
635
|
end
|
512
636
|
fqsc = qualify_superclass(fqns)
|
513
637
|
unless fqsc.nil?
|
@@ -571,6 +695,8 @@ module Solargraph
|
|
571
695
|
qualify namespace, context.split('::')[0..-2].join('::')
|
572
696
|
end
|
573
697
|
|
698
|
+
# @param fqsub [String]
|
699
|
+
# @return [String, nil]
|
574
700
|
def qualify_superclass fqsub
|
575
701
|
sup = store.get_superclass(fqsub)
|
576
702
|
return nil if sup.nil?
|
@@ -580,11 +706,12 @@ module Solargraph
|
|
580
706
|
qualify(sup, parts.join('::'))
|
581
707
|
end
|
582
708
|
|
583
|
-
# @param name [String]
|
584
|
-
# @param root [String]
|
585
|
-
# @param skip [Set<String>]
|
586
|
-
# @return [String, nil]
|
709
|
+
# @param name [String] Namespace to fully qualify
|
710
|
+
# @param root [String] The context to search
|
711
|
+
# @param skip [Set<String>] Contexts already searched
|
712
|
+
# @return [String, nil] Fully qualified ("rooted") namespace
|
587
713
|
def inner_qualify name, root, skip
|
714
|
+
return name if name == ComplexType::GENERIC_TAG_NAME
|
588
715
|
return nil if name.nil?
|
589
716
|
return nil if skip.include?(root)
|
590
717
|
skip.add root
|
@@ -634,8 +761,8 @@ module Solargraph
|
|
634
761
|
|
635
762
|
# Sort an array of pins to put nil or undefined variables last.
|
636
763
|
#
|
637
|
-
# @param pins [
|
638
|
-
# @return [
|
764
|
+
# @param pins [Enumerable<Solargraph::Pin::Base>]
|
765
|
+
# @return [Enumerable<Solargraph::Pin::Base>]
|
639
766
|
def prefer_non_nil_variables pins
|
640
767
|
result = []
|
641
768
|
nil_pins = []
|
@@ -649,27 +776,26 @@ module Solargraph
|
|
649
776
|
result + nil_pins
|
650
777
|
end
|
651
778
|
|
652
|
-
# @param pins [
|
653
|
-
# @param visibility [
|
779
|
+
# @param pins [Enumerable<Pin::Base>]
|
780
|
+
# @param visibility [Enumerable<Symbol>]
|
654
781
|
# @return [Array<Pin::Base>]
|
655
782
|
def resolve_method_aliases pins, visibility = [:public, :private, :protected]
|
656
|
-
|
657
|
-
pins.each do |pin|
|
783
|
+
pins.map do |pin|
|
658
784
|
resolved = resolve_method_alias(pin)
|
659
|
-
next if resolved.respond_to?(:visibility) && !visibility.include?(resolved.visibility)
|
660
|
-
|
661
|
-
end
|
662
|
-
result
|
785
|
+
next pin if resolved.respond_to?(:visibility) && !visibility.include?(resolved.visibility)
|
786
|
+
resolved
|
787
|
+
end.compact
|
663
788
|
end
|
664
789
|
|
665
790
|
# @param pin [Pin::MethodAlias, Pin::Base]
|
666
791
|
# @return [Pin::Method]
|
667
792
|
def resolve_method_alias pin
|
668
|
-
return pin
|
793
|
+
return pin unless pin.is_a?(Pin::MethodAlias)
|
794
|
+
return nil if @method_alias_stack.include?(pin.path)
|
669
795
|
@method_alias_stack.push pin.path
|
670
|
-
origin = get_method_stack(pin.full_context.
|
796
|
+
origin = get_method_stack(pin.full_context.tag, pin.original, scope: pin.scope).first
|
671
797
|
@method_alias_stack.pop
|
672
|
-
return
|
798
|
+
return nil if origin.nil?
|
673
799
|
args = {
|
674
800
|
location: pin.location,
|
675
801
|
closure: pin.closure,
|
@@ -677,7 +803,7 @@ module Solargraph
|
|
677
803
|
comments: origin.comments,
|
678
804
|
scope: origin.scope,
|
679
805
|
visibility: origin.visibility,
|
680
|
-
|
806
|
+
signatures: origin.signatures,
|
681
807
|
attribute: origin.attribute?
|
682
808
|
}
|
683
809
|
Pin::Method.new **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,9 @@ 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
|
+
.compact
|
25
|
+
.to_set
|
25
26
|
end
|
26
27
|
end
|
27
28
|
end
|