solargraph 0.58.1 → 0.59.0.dev.1
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/.envrc +3 -0
- data/.github/workflows/linting.yml +4 -5
- data/.github/workflows/plugins.yml +40 -36
- data/.github/workflows/rspec.yml +45 -13
- data/.github/workflows/typecheck.yml +2 -2
- data/.rubocop_todo.yml +27 -49
- data/README.md +3 -3
- data/Rakefile +1 -0
- data/lib/solargraph/api_map/cache.rb +110 -110
- data/lib/solargraph/api_map/constants.rb +289 -279
- data/lib/solargraph/api_map/index.rb +204 -193
- data/lib/solargraph/api_map/source_to_yard.rb +109 -97
- data/lib/solargraph/api_map/store.rb +387 -384
- data/lib/solargraph/api_map.rb +1000 -945
- data/lib/solargraph/complex_type/conformance.rb +176 -0
- data/lib/solargraph/complex_type/type_methods.rb +242 -228
- data/lib/solargraph/complex_type/unique_type.rb +632 -482
- data/lib/solargraph/complex_type.rb +549 -444
- data/lib/solargraph/convention/data_definition/data_definition_node.rb +93 -91
- data/lib/solargraph/convention/data_definition.rb +108 -105
- data/lib/solargraph/convention/struct_definition/struct_assignment_node.rb +62 -61
- data/lib/solargraph/convention/struct_definition/struct_definition_node.rb +103 -102
- data/lib/solargraph/convention/struct_definition.rb +168 -164
- data/lib/solargraph/diagnostics/require_not_found.rb +54 -53
- data/lib/solargraph/diagnostics/rubocop.rb +119 -118
- data/lib/solargraph/diagnostics/rubocop_helpers.rb +70 -68
- data/lib/solargraph/diagnostics/type_check.rb +56 -55
- data/lib/solargraph/doc_map.rb +200 -439
- data/lib/solargraph/equality.rb +34 -34
- data/lib/solargraph/gem_pins.rb +97 -98
- data/lib/solargraph/language_server/host/dispatch.rb +131 -130
- data/lib/solargraph/language_server/host/message_worker.rb +113 -112
- data/lib/solargraph/language_server/host/sources.rb +100 -99
- data/lib/solargraph/language_server/host.rb +883 -878
- data/lib/solargraph/language_server/message/extended/check_gem_version.rb +109 -114
- data/lib/solargraph/language_server/message/extended/document.rb +24 -23
- data/lib/solargraph/language_server/message/text_document/completion.rb +58 -56
- data/lib/solargraph/language_server/message/text_document/definition.rb +42 -40
- data/lib/solargraph/language_server/message/text_document/document_symbol.rb +28 -26
- data/lib/solargraph/language_server/message/text_document/formatting.rb +150 -148
- data/lib/solargraph/language_server/message/text_document/hover.rb +60 -58
- data/lib/solargraph/language_server/message/text_document/signature_help.rb +25 -24
- data/lib/solargraph/language_server/message/text_document/type_definition.rb +27 -25
- data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +25 -23
- data/lib/solargraph/library.rb +729 -683
- data/lib/solargraph/location.rb +87 -82
- data/lib/solargraph/logging.rb +57 -37
- data/lib/solargraph/parser/comment_ripper.rb +76 -69
- data/lib/solargraph/parser/flow_sensitive_typing.rb +483 -255
- data/lib/solargraph/parser/node_processor/base.rb +122 -92
- data/lib/solargraph/parser/node_processor.rb +63 -62
- data/lib/solargraph/parser/parser_gem/class_methods.rb +167 -149
- data/lib/solargraph/parser/parser_gem/node_chainer.rb +191 -166
- data/lib/solargraph/parser/parser_gem/node_methods.rb +506 -486
- data/lib/solargraph/parser/parser_gem/node_processors/and_node.rb +22 -22
- data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +61 -59
- data/lib/solargraph/parser/parser_gem/node_processors/begin_node.rb +24 -15
- data/lib/solargraph/parser/parser_gem/node_processors/block_node.rb +46 -46
- data/lib/solargraph/parser/parser_gem/node_processors/def_node.rb +60 -53
- data/lib/solargraph/parser/parser_gem/node_processors/if_node.rb +53 -23
- data/lib/solargraph/parser/parser_gem/node_processors/ivasgn_node.rb +41 -40
- data/lib/solargraph/parser/parser_gem/node_processors/lvasgn_node.rb +30 -29
- data/lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb +61 -59
- data/lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb +98 -98
- data/lib/solargraph/parser/parser_gem/node_processors/or_node.rb +22 -0
- data/lib/solargraph/parser/parser_gem/node_processors/orasgn_node.rb +17 -17
- data/lib/solargraph/parser/parser_gem/node_processors/resbody_node.rb +39 -38
- data/lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb +53 -52
- data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +296 -291
- data/lib/solargraph/parser/parser_gem/node_processors/when_node.rb +23 -0
- data/lib/solargraph/parser/parser_gem/node_processors/while_node.rb +33 -29
- data/lib/solargraph/parser/parser_gem/node_processors.rb +74 -70
- data/lib/solargraph/parser/region.rb +75 -69
- data/lib/solargraph/parser/snippet.rb +17 -17
- data/lib/solargraph/pin/base.rb +761 -729
- data/lib/solargraph/pin/base_variable.rb +418 -126
- data/lib/solargraph/pin/block.rb +126 -104
- data/lib/solargraph/pin/breakable.rb +13 -9
- data/lib/solargraph/pin/callable.rb +278 -231
- data/lib/solargraph/pin/closure.rb +68 -72
- data/lib/solargraph/pin/common.rb +94 -79
- data/lib/solargraph/pin/compound_statement.rb +55 -0
- data/lib/solargraph/pin/conversions.rb +124 -123
- data/lib/solargraph/pin/delegated_method.rb +131 -120
- data/lib/solargraph/pin/documenting.rb +115 -114
- data/lib/solargraph/pin/instance_variable.rb +38 -34
- data/lib/solargraph/pin/keyword.rb +16 -20
- data/lib/solargraph/pin/local_variable.rb +31 -75
- data/lib/solargraph/pin/method.rb +720 -672
- data/lib/solargraph/pin/method_alias.rb +42 -34
- data/lib/solargraph/pin/namespace.rb +121 -115
- data/lib/solargraph/pin/parameter.rb +338 -275
- data/lib/solargraph/pin/proxy_type.rb +40 -39
- data/lib/solargraph/pin/reference/override.rb +47 -47
- data/lib/solargraph/pin/reference/superclass.rb +17 -15
- data/lib/solargraph/pin/reference.rb +41 -39
- data/lib/solargraph/pin/search.rb +62 -61
- data/lib/solargraph/pin/signature.rb +69 -61
- data/lib/solargraph/pin/symbol.rb +53 -53
- data/lib/solargraph/pin/until.rb +18 -18
- data/lib/solargraph/pin/while.rb +18 -18
- data/lib/solargraph/pin.rb +46 -44
- data/lib/solargraph/pin_cache.rb +665 -245
- data/lib/solargraph/position.rb +118 -119
- data/lib/solargraph/range.rb +112 -112
- data/lib/solargraph/rbs_map/conversions.rb +846 -823
- data/lib/solargraph/rbs_map/core_map.rb +65 -58
- data/lib/solargraph/rbs_map/stdlib_map.rb +72 -43
- data/lib/solargraph/rbs_map.rb +217 -163
- data/lib/solargraph/shell.rb +397 -352
- data/lib/solargraph/source/chain/call.rb +372 -337
- data/lib/solargraph/source/chain/constant.rb +28 -26
- data/lib/solargraph/source/chain/hash.rb +35 -34
- data/lib/solargraph/source/chain/if.rb +29 -28
- data/lib/solargraph/source/chain/instance_variable.rb +34 -13
- data/lib/solargraph/source/chain/literal.rb +53 -48
- data/lib/solargraph/source/chain/or.rb +31 -23
- data/lib/solargraph/source/chain.rb +294 -291
- data/lib/solargraph/source/change.rb +89 -82
- data/lib/solargraph/source/cursor.rb +172 -166
- data/lib/solargraph/source/source_chainer.rb +204 -194
- data/lib/solargraph/source/updater.rb +59 -55
- data/lib/solargraph/source.rb +524 -498
- data/lib/solargraph/source_map/clip.rb +237 -226
- data/lib/solargraph/source_map/data.rb +37 -34
- data/lib/solargraph/source_map/mapper.rb +282 -259
- data/lib/solargraph/source_map.rb +220 -212
- data/lib/solargraph/type_checker/problem.rb +34 -32
- data/lib/solargraph/type_checker/rules.rb +157 -84
- data/lib/solargraph/type_checker.rb +895 -814
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/workspace/config.rb +257 -255
- data/lib/solargraph/workspace/gemspecs.rb +367 -0
- data/lib/solargraph/workspace/require_paths.rb +98 -97
- data/lib/solargraph/workspace.rb +362 -220
- data/lib/solargraph/yard_map/helpers.rb +45 -44
- data/lib/solargraph/yard_map/mapper/to_method.rb +134 -130
- data/lib/solargraph/yard_map/mapper/to_namespace.rb +32 -31
- data/lib/solargraph/yard_map/mapper.rb +84 -79
- data/lib/solargraph/yardoc.rb +97 -87
- data/lib/solargraph.rb +126 -105
- data/rbs/fills/rubygems/0/dependency.rbs +193 -0
- data/rbs/fills/tuple/tuple.rbs +28 -0
- data/rbs/shims/ast/0/node.rbs +5 -0
- data/rbs/shims/diff-lcs/1.5/diff-lcs.rbs +11 -0
- data/rbs_collection.yaml +1 -1
- data/solargraph.gemspec +2 -1
- metadata +22 -17
- data/lib/solargraph/type_checker/checks.rb +0 -124
- data/lib/solargraph/type_checker/param_def.rb +0 -37
- data/lib/solargraph/yard_map/to_method.rb +0 -89
- data/sig/shims/ast/0/node.rbs +0 -5
- /data/{sig → rbs}/shims/ast/2.4/.rbs_meta.yaml +0 -0
- /data/{sig → rbs}/shims/ast/2.4/ast.rbs +0 -0
- /data/{sig → rbs}/shims/parser/3.2.0.1/builders/default.rbs +0 -0
- /data/{sig → rbs}/shims/parser/3.2.0.1/manifest.yaml +0 -0
- /data/{sig → rbs}/shims/parser/3.2.0.1/parser.rbs +0 -0
- /data/{sig → rbs}/shims/parser/3.2.0.1/polyfill.rbs +0 -0
- /data/{sig → rbs}/shims/thor/1.2.0.1/.rbs_meta.yaml +0 -0
- /data/{sig → rbs}/shims/thor/1.2.0.1/manifest.yaml +0 -0
- /data/{sig → rbs}/shims/thor/1.2.0.1/thor.rbs +0 -0
|
@@ -1,384 +1,387 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Solargraph
|
|
4
|
-
class ApiMap
|
|
5
|
-
# Queryable collection of Pins representing a Workspace, gems and the Ruby
|
|
6
|
-
# core.
|
|
7
|
-
#
|
|
8
|
-
class Store
|
|
9
|
-
# @param pinsets [Array<Enumerable<Pin::Base>>]
|
|
10
|
-
def initialize *pinsets
|
|
11
|
-
@pinsets = pinsets
|
|
12
|
-
catalog pinsets
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
# @return [Array<Solargraph::Pin::Base>]
|
|
16
|
-
def pins
|
|
17
|
-
index.pins
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
# @param pinsets [Array<Array<Pin::Base>>]
|
|
21
|
-
# - pinsets[0] = core Ruby pins
|
|
22
|
-
# - pinsets[1] = documentation/gem pins
|
|
23
|
-
# - pinsets[2] = convention pins
|
|
24
|
-
# - pinsets[3] = workspace source pins
|
|
25
|
-
# - pinsets[4] = currently open file pins
|
|
26
|
-
# @return [Boolean] True if the index was updated
|
|
27
|
-
def update *pinsets
|
|
28
|
-
return catalog(pinsets) if pinsets.length != @pinsets.length
|
|
29
|
-
|
|
30
|
-
changed = pinsets.find_index.with_index { |pinset, idx| @pinsets[idx] != pinset }
|
|
31
|
-
return false unless changed
|
|
32
|
-
|
|
33
|
-
# @todo Fix this map
|
|
34
|
-
@fqns_pins_map = nil
|
|
35
|
-
return catalog(pinsets) if changed == 0
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
@
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
# @param
|
|
60
|
-
# @
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
# @param
|
|
70
|
-
# @param
|
|
71
|
-
# @
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
pin.is_a?(Pin::Method) && pin.scope == scope && visibility.include?(pin.visibility)
|
|
76
|
-
end
|
|
77
|
-
GemPins.combine_method_pins_by_path(all_pins)
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
BOOLEAN_SUPERCLASS_PIN = Pin::Reference::Superclass.new(name: 'Boolean', closure: Pin::ROOT_PIN, source: :solargraph)
|
|
81
|
-
OBJECT_SUPERCLASS_PIN = Pin::Reference::Superclass.new(name: 'Object', closure: Pin::ROOT_PIN, source: :solargraph)
|
|
82
|
-
|
|
83
|
-
# @param fqns [String]
|
|
84
|
-
# @return [Pin::Reference::Superclass]
|
|
85
|
-
def get_superclass fqns
|
|
86
|
-
return nil if fqns.nil? || fqns.empty?
|
|
87
|
-
return BOOLEAN_SUPERCLASS_PIN if %w[TrueClass FalseClass].include?(fqns)
|
|
88
|
-
|
|
89
|
-
superclass_references[fqns].first || try_special_superclasses(fqns)
|
|
90
|
-
end
|
|
91
|
-
|
|
92
|
-
# @param fq_sub_tag [String]
|
|
93
|
-
# @return [String, nil]
|
|
94
|
-
def qualify_superclass fq_sub_tag
|
|
95
|
-
cached_qualify_superclass[fq_sub_tag] || qualify_and_cache_superclass(fq_sub_tag)
|
|
96
|
-
type = ComplexType.try_parse(fq_sub_tag)
|
|
97
|
-
return type.simplify_literals.to_s if type.literal?
|
|
98
|
-
ref = get_superclass(fq_sub_tag)
|
|
99
|
-
return unless ref
|
|
100
|
-
res = constants.dereference(ref)
|
|
101
|
-
return unless res
|
|
102
|
-
res
|
|
103
|
-
end
|
|
104
|
-
|
|
105
|
-
# @param fqns [String]
|
|
106
|
-
# @return [Array<Pin::Reference::Include>]
|
|
107
|
-
def get_includes fqns
|
|
108
|
-
include_references[fqns] || []
|
|
109
|
-
end
|
|
110
|
-
|
|
111
|
-
# @param fqns [String]
|
|
112
|
-
# @return [Array<Pin::Reference::Prepend>]
|
|
113
|
-
def get_prepends fqns
|
|
114
|
-
prepend_references[fqns] || []
|
|
115
|
-
end
|
|
116
|
-
|
|
117
|
-
# @param fqns [String]
|
|
118
|
-
# @return [Array<Pin::Reference::Extend>]
|
|
119
|
-
def get_extends fqns
|
|
120
|
-
extend_references[fqns] || []
|
|
121
|
-
end
|
|
122
|
-
|
|
123
|
-
# @param path [String]
|
|
124
|
-
# @return [Array<Solargraph::Pin::Base>]
|
|
125
|
-
def get_path_pins path
|
|
126
|
-
index.path_pin_hash[path]
|
|
127
|
-
end
|
|
128
|
-
|
|
129
|
-
# @param fqns [String]
|
|
130
|
-
# @param scope [Symbol] :class or :instance
|
|
131
|
-
# @return [Enumerable<Solargraph::Pin::Base>]
|
|
132
|
-
def get_instance_variables(fqns, scope = :instance)
|
|
133
|
-
all_instance_variables.select { |pin|
|
|
134
|
-
pin.binder.namespace == fqns && pin.binder.scope == scope
|
|
135
|
-
}
|
|
136
|
-
end
|
|
137
|
-
|
|
138
|
-
# @param fqns [String]
|
|
139
|
-
#
|
|
140
|
-
# @return [Enumerable<Solargraph::Pin::ClassVariable>]
|
|
141
|
-
def get_class_variables(fqns)
|
|
142
|
-
namespace_children(fqns).select { |pin| pin.is_a?(Pin::ClassVariable)}
|
|
143
|
-
end
|
|
144
|
-
|
|
145
|
-
# @return [Enumerable<Solargraph::Pin::Base>]
|
|
146
|
-
def get_symbols
|
|
147
|
-
symbols.uniq(&:name)
|
|
148
|
-
end
|
|
149
|
-
|
|
150
|
-
# @param fqns [String]
|
|
151
|
-
# @return [Boolean]
|
|
152
|
-
def namespace_exists?(fqns)
|
|
153
|
-
fqns_pins(fqns).any?
|
|
154
|
-
end
|
|
155
|
-
|
|
156
|
-
# @return [Enumerable<Solargraph::Pin::Namespace>]
|
|
157
|
-
def namespace_pins
|
|
158
|
-
pins_by_class(Solargraph::Pin::Namespace)
|
|
159
|
-
end
|
|
160
|
-
|
|
161
|
-
# @return [Enumerable<Solargraph::Pin::Method>]
|
|
162
|
-
def method_pins
|
|
163
|
-
pins_by_class(Solargraph::Pin::Method)
|
|
164
|
-
end
|
|
165
|
-
|
|
166
|
-
# @param fqns [String]
|
|
167
|
-
# @return [Array<String>]
|
|
168
|
-
def domains(fqns)
|
|
169
|
-
result = []
|
|
170
|
-
fqns_pins(fqns).each do |nspin|
|
|
171
|
-
result.concat nspin.domains
|
|
172
|
-
end
|
|
173
|
-
result
|
|
174
|
-
end
|
|
175
|
-
|
|
176
|
-
# @return [Hash{String => YARD::Tags::MacroDirective}]
|
|
177
|
-
def named_macros
|
|
178
|
-
@named_macros ||= begin
|
|
179
|
-
result = {}
|
|
180
|
-
pins.each do |pin|
|
|
181
|
-
pin.macros.select{|m| m.tag.tag_name == 'macro' && !m.tag.text.empty? }.each do |macro|
|
|
182
|
-
next if macro.tag.name.nil? || macro.tag.name.empty?
|
|
183
|
-
result[macro.tag.name] = macro
|
|
184
|
-
end
|
|
185
|
-
end
|
|
186
|
-
result
|
|
187
|
-
end
|
|
188
|
-
end
|
|
189
|
-
|
|
190
|
-
# @return [Enumerable<Pin::Block>]
|
|
191
|
-
def block_pins
|
|
192
|
-
pins_by_class(Pin::Block)
|
|
193
|
-
end
|
|
194
|
-
|
|
195
|
-
# @generic T
|
|
196
|
-
# @param klass [Class<generic<T>>]
|
|
197
|
-
# @return [Set<generic<T>>]
|
|
198
|
-
def pins_by_class klass
|
|
199
|
-
index.pins_by_class klass
|
|
200
|
-
end
|
|
201
|
-
|
|
202
|
-
# @param fqns [String]
|
|
203
|
-
# @return [Array<Solargraph::Pin::Namespace>]
|
|
204
|
-
def fqns_pins fqns
|
|
205
|
-
return [] if fqns.nil?
|
|
206
|
-
if fqns.include?('::')
|
|
207
|
-
parts = fqns.split('::')
|
|
208
|
-
name = parts.pop
|
|
209
|
-
base = parts.join('::')
|
|
210
|
-
else
|
|
211
|
-
base = ''
|
|
212
|
-
name = fqns
|
|
213
|
-
end
|
|
214
|
-
fqns_pins_map[[base, name]]
|
|
215
|
-
end
|
|
216
|
-
|
|
217
|
-
# Get all ancestors (superclasses, includes, prepends, extends) for a namespace
|
|
218
|
-
# @param fqns [String] The fully qualified namespace
|
|
219
|
-
# @return [Array<String>] Array of ancestor namespaces including the original
|
|
220
|
-
def get_ancestors(fqns)
|
|
221
|
-
return [] if fqns.nil? || fqns.empty?
|
|
222
|
-
|
|
223
|
-
ancestors = [fqns]
|
|
224
|
-
visited = Set.new
|
|
225
|
-
queue = [fqns]
|
|
226
|
-
|
|
227
|
-
until queue.empty?
|
|
228
|
-
current = queue.shift
|
|
229
|
-
next if current.nil? || current.empty? || visited.include?(current)
|
|
230
|
-
visited.add(current)
|
|
231
|
-
|
|
232
|
-
current = current.gsub(/^::/, '')
|
|
233
|
-
|
|
234
|
-
# Add superclass
|
|
235
|
-
ref = get_superclass(current)
|
|
236
|
-
superclass = ref && constants.dereference(ref)
|
|
237
|
-
if superclass && !superclass.empty? && !visited.include?(superclass)
|
|
238
|
-
ancestors << superclass
|
|
239
|
-
queue << superclass
|
|
240
|
-
end
|
|
241
|
-
|
|
242
|
-
# Add includes, prepends, and extends
|
|
243
|
-
[get_includes(current), get_prepends(current), get_extends(current)].each do |refs|
|
|
244
|
-
next if refs.nil?
|
|
245
|
-
# @param ref [String]
|
|
246
|
-
refs.map(&:type).map(&:to_s).each do |ref|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
pinsets
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
@
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
return
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
end
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Solargraph
|
|
4
|
+
class ApiMap
|
|
5
|
+
# Queryable collection of Pins representing a Workspace, gems and the Ruby
|
|
6
|
+
# core.
|
|
7
|
+
#
|
|
8
|
+
class Store
|
|
9
|
+
# @param pinsets [Array<Enumerable<Pin::Base>>]
|
|
10
|
+
def initialize *pinsets
|
|
11
|
+
@pinsets = pinsets
|
|
12
|
+
catalog pinsets
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# @return [Array<Solargraph::Pin::Base>]
|
|
16
|
+
def pins
|
|
17
|
+
index.pins
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# @param pinsets [Array<Array<Pin::Base>>]
|
|
21
|
+
# - pinsets[0] = core Ruby pins
|
|
22
|
+
# - pinsets[1] = documentation/gem pins
|
|
23
|
+
# - pinsets[2] = convention pins
|
|
24
|
+
# - pinsets[3] = workspace source pins
|
|
25
|
+
# - pinsets[4] = currently open file pins
|
|
26
|
+
# @return [Boolean] True if the index was updated
|
|
27
|
+
def update *pinsets
|
|
28
|
+
return catalog(pinsets) if pinsets.length != @pinsets.length
|
|
29
|
+
|
|
30
|
+
changed = pinsets.find_index.with_index { |pinset, idx| @pinsets[idx] != pinset }
|
|
31
|
+
return false unless changed
|
|
32
|
+
|
|
33
|
+
# @todo Fix this map
|
|
34
|
+
@fqns_pins_map = nil
|
|
35
|
+
return catalog(pinsets) if changed == 0
|
|
36
|
+
|
|
37
|
+
# @sg-ignore Need to add nil check here
|
|
38
|
+
pinsets[changed..].each_with_index do |pins, idx|
|
|
39
|
+
@pinsets[changed + idx] = pins
|
|
40
|
+
@indexes[changed + idx] = if pins.empty?
|
|
41
|
+
@indexes[changed + idx - 1]
|
|
42
|
+
else
|
|
43
|
+
@indexes[changed + idx - 1].merge(pins)
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
constants.clear
|
|
47
|
+
cached_qualify_superclass.clear
|
|
48
|
+
true
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def to_s
|
|
52
|
+
self.class.to_s
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def inspect
|
|
56
|
+
to_s
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# @param fqns [String]
|
|
60
|
+
# @param visibility [Array<Symbol>]
|
|
61
|
+
# @return [Enumerable<Solargraph::Pin::Namespace, Solargraph::Pin::Constant>]
|
|
62
|
+
def get_constants fqns, visibility = [:public]
|
|
63
|
+
namespace_children(fqns).select { |pin|
|
|
64
|
+
# @sg-ignore flow sensitive typing not smart enough to handle this case
|
|
65
|
+
!pin.name.empty? && (pin.is_a?(Pin::Namespace) || pin.is_a?(Pin::Constant)) && visibility.include?(pin.visibility)
|
|
66
|
+
}
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# @param fqns [String]
|
|
70
|
+
# @param scope [Symbol]
|
|
71
|
+
# @param visibility [Array<Symbol>]
|
|
72
|
+
# @return [Enumerable<Solargraph::Pin::Method>]
|
|
73
|
+
def get_methods fqns, scope: :instance, visibility: [:public]
|
|
74
|
+
all_pins = namespace_children(fqns).select do |pin|
|
|
75
|
+
pin.is_a?(Pin::Method) && pin.scope == scope && visibility.include?(pin.visibility)
|
|
76
|
+
end
|
|
77
|
+
GemPins.combine_method_pins_by_path(all_pins)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
BOOLEAN_SUPERCLASS_PIN = Pin::Reference::Superclass.new(name: 'Boolean', closure: Pin::ROOT_PIN, source: :solargraph)
|
|
81
|
+
OBJECT_SUPERCLASS_PIN = Pin::Reference::Superclass.new(name: 'Object', closure: Pin::ROOT_PIN, source: :solargraph)
|
|
82
|
+
|
|
83
|
+
# @param fqns [String, nil]
|
|
84
|
+
# @return [Pin::Reference::Superclass, nil]
|
|
85
|
+
def get_superclass fqns
|
|
86
|
+
return nil if fqns.nil? || fqns.empty?
|
|
87
|
+
return BOOLEAN_SUPERCLASS_PIN if %w[TrueClass FalseClass].include?(fqns)
|
|
88
|
+
|
|
89
|
+
superclass_references[fqns].first || try_special_superclasses(fqns)
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# @param fq_sub_tag [String]
|
|
93
|
+
# @return [String, nil]
|
|
94
|
+
def qualify_superclass fq_sub_tag
|
|
95
|
+
cached_qualify_superclass[fq_sub_tag] || qualify_and_cache_superclass(fq_sub_tag)
|
|
96
|
+
type = ComplexType.try_parse(fq_sub_tag)
|
|
97
|
+
return type.simplify_literals.to_s if type.literal?
|
|
98
|
+
ref = get_superclass(fq_sub_tag)
|
|
99
|
+
return unless ref
|
|
100
|
+
res = constants.dereference(ref)
|
|
101
|
+
return unless res
|
|
102
|
+
res
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# @param fqns [String]
|
|
106
|
+
# @return [Array<Pin::Reference::Include>]
|
|
107
|
+
def get_includes fqns
|
|
108
|
+
include_references[fqns] || []
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
# @param fqns [String]
|
|
112
|
+
# @return [Array<Pin::Reference::Prepend>]
|
|
113
|
+
def get_prepends fqns
|
|
114
|
+
prepend_references[fqns] || []
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
# @param fqns [String]
|
|
118
|
+
# @return [Array<Pin::Reference::Extend>]
|
|
119
|
+
def get_extends fqns
|
|
120
|
+
extend_references[fqns] || []
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
# @param path [String]
|
|
124
|
+
# @return [Array<Solargraph::Pin::Base>]
|
|
125
|
+
def get_path_pins path
|
|
126
|
+
index.path_pin_hash[path]
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
# @param fqns [String, nil]
|
|
130
|
+
# @param scope [Symbol] :class or :instance
|
|
131
|
+
# @return [Enumerable<Solargraph::Pin::Base>]
|
|
132
|
+
def get_instance_variables(fqns, scope = :instance)
|
|
133
|
+
all_instance_variables.select { |pin|
|
|
134
|
+
pin.binder.namespace == fqns && pin.binder.scope == scope
|
|
135
|
+
}
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
# @param fqns [String]
|
|
139
|
+
#
|
|
140
|
+
# @return [Enumerable<Solargraph::Pin::ClassVariable>]
|
|
141
|
+
def get_class_variables(fqns)
|
|
142
|
+
namespace_children(fqns).select { |pin| pin.is_a?(Pin::ClassVariable)}
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
# @return [Enumerable<Solargraph::Pin::Base>]
|
|
146
|
+
def get_symbols
|
|
147
|
+
symbols.uniq(&:name)
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
# @param fqns [String]
|
|
151
|
+
# @return [Boolean]
|
|
152
|
+
def namespace_exists?(fqns)
|
|
153
|
+
fqns_pins(fqns).any?
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
# @return [Enumerable<Solargraph::Pin::Namespace>]
|
|
157
|
+
def namespace_pins
|
|
158
|
+
pins_by_class(Solargraph::Pin::Namespace)
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
# @return [Enumerable<Solargraph::Pin::Method>]
|
|
162
|
+
def method_pins
|
|
163
|
+
pins_by_class(Solargraph::Pin::Method)
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
# @param fqns [String]
|
|
167
|
+
# @return [Array<String>]
|
|
168
|
+
def domains(fqns)
|
|
169
|
+
result = []
|
|
170
|
+
fqns_pins(fqns).each do |nspin|
|
|
171
|
+
result.concat nspin.domains
|
|
172
|
+
end
|
|
173
|
+
result
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
# @return [Hash{String => YARD::Tags::MacroDirective}]
|
|
177
|
+
def named_macros
|
|
178
|
+
@named_macros ||= begin
|
|
179
|
+
result = {}
|
|
180
|
+
pins.each do |pin|
|
|
181
|
+
pin.macros.select{|m| m.tag.tag_name == 'macro' && !m.tag.text.empty? }.each do |macro|
|
|
182
|
+
next if macro.tag.name.nil? || macro.tag.name.empty?
|
|
183
|
+
result[macro.tag.name] = macro
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
result
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
# @return [Enumerable<Pin::Block>]
|
|
191
|
+
def block_pins
|
|
192
|
+
pins_by_class(Pin::Block)
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
# @generic T
|
|
196
|
+
# @param klass [Class<generic<T>>]
|
|
197
|
+
# @return [Set<generic<T>>]
|
|
198
|
+
def pins_by_class klass
|
|
199
|
+
index.pins_by_class klass
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
# @param fqns [String, nil]
|
|
203
|
+
# @return [Array<Solargraph::Pin::Namespace>]
|
|
204
|
+
def fqns_pins fqns
|
|
205
|
+
return [] if fqns.nil?
|
|
206
|
+
if fqns.include?('::')
|
|
207
|
+
parts = fqns.split('::')
|
|
208
|
+
name = parts.pop
|
|
209
|
+
base = parts.join('::')
|
|
210
|
+
else
|
|
211
|
+
base = ''
|
|
212
|
+
name = fqns
|
|
213
|
+
end
|
|
214
|
+
fqns_pins_map[[base, name]]
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
# Get all ancestors (superclasses, includes, prepends, extends) for a namespace
|
|
218
|
+
# @param fqns [String] The fully qualified namespace
|
|
219
|
+
# @return [Array<String>] Array of ancestor namespaces including the original
|
|
220
|
+
def get_ancestors(fqns)
|
|
221
|
+
return [] if fqns.nil? || fqns.empty?
|
|
222
|
+
|
|
223
|
+
ancestors = [fqns]
|
|
224
|
+
visited = Set.new
|
|
225
|
+
queue = [fqns]
|
|
226
|
+
|
|
227
|
+
until queue.empty?
|
|
228
|
+
current = queue.shift
|
|
229
|
+
next if current.nil? || current.empty? || visited.include?(current)
|
|
230
|
+
visited.add(current)
|
|
231
|
+
|
|
232
|
+
current = current.gsub(/^::/, '')
|
|
233
|
+
|
|
234
|
+
# Add superclass
|
|
235
|
+
ref = get_superclass(current)
|
|
236
|
+
superclass = ref && constants.dereference(ref)
|
|
237
|
+
if superclass && !superclass.empty? && !visited.include?(superclass)
|
|
238
|
+
ancestors << superclass
|
|
239
|
+
queue << superclass
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
# Add includes, prepends, and extends
|
|
243
|
+
[get_includes(current), get_prepends(current), get_extends(current)].each do |refs|
|
|
244
|
+
next if refs.nil?
|
|
245
|
+
# @param ref [String]
|
|
246
|
+
refs.map(&:type).map(&:to_s).each do |ref|
|
|
247
|
+
# @sg-ignore flow sensitive typing should be able to handle redefinition
|
|
248
|
+
next if ref.nil? || ref.empty? || visited.include?(ref)
|
|
249
|
+
# @sg-ignore flow sensitive typing should be able to handle redefinition
|
|
250
|
+
ancestors << ref
|
|
251
|
+
# @sg-ignore flow sensitive typing should be able to handle redefinition
|
|
252
|
+
queue << ref
|
|
253
|
+
end
|
|
254
|
+
end
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
ancestors.compact.uniq
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
# @param fqns [String]
|
|
261
|
+
#
|
|
262
|
+
# @return [Array<Solargraph::Pin::Reference>]
|
|
263
|
+
def get_ancestor_references(fqns)
|
|
264
|
+
(get_prepends(fqns) + get_includes(fqns) + [get_superclass(fqns)]).compact
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
# @return [Constants]
|
|
268
|
+
def constants
|
|
269
|
+
@constants ||= Constants.new(self)
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
private
|
|
273
|
+
|
|
274
|
+
# @return [Index]
|
|
275
|
+
def index
|
|
276
|
+
@indexes.last
|
|
277
|
+
end
|
|
278
|
+
|
|
279
|
+
# @param pinsets [Array<Array<Pin::Base>>]
|
|
280
|
+
#
|
|
281
|
+
# @return [true]
|
|
282
|
+
def catalog pinsets
|
|
283
|
+
@pinsets = pinsets
|
|
284
|
+
# @type [Array<Index>]
|
|
285
|
+
@indexes = []
|
|
286
|
+
pinsets.each do |pins|
|
|
287
|
+
if @indexes.last && pins.empty?
|
|
288
|
+
@indexes.push @indexes.last
|
|
289
|
+
else
|
|
290
|
+
@indexes.push(@indexes.last&.merge(pins) || Solargraph::ApiMap::Index.new(pins))
|
|
291
|
+
end
|
|
292
|
+
end
|
|
293
|
+
constants.clear
|
|
294
|
+
cached_qualify_superclass.clear
|
|
295
|
+
true
|
|
296
|
+
end
|
|
297
|
+
|
|
298
|
+
# @return [Hash{::Array(String, String) => ::Array<Pin::Namespace>}]
|
|
299
|
+
def fqns_pins_map
|
|
300
|
+
# @param h [Hash{::Array(String, String) => ::Array<Pin::Namespace>}]
|
|
301
|
+
# @param base [String]
|
|
302
|
+
# @param name [String]
|
|
303
|
+
@fqns_pins_map ||= Hash.new do |h, (base, name)|
|
|
304
|
+
value = namespace_children(base).select { |pin| pin.name == name && pin.is_a?(Pin::Namespace) }
|
|
305
|
+
h[[base, name]] = value
|
|
306
|
+
end
|
|
307
|
+
end
|
|
308
|
+
|
|
309
|
+
# @return [Enumerable<Solargraph::Pin::Symbol>]
|
|
310
|
+
def symbols
|
|
311
|
+
index.pins_by_class(Pin::Symbol)
|
|
312
|
+
end
|
|
313
|
+
|
|
314
|
+
# @return [Hash{String => Array<Pin::Reference::Superclass>}]
|
|
315
|
+
def superclass_references
|
|
316
|
+
index.superclass_references
|
|
317
|
+
end
|
|
318
|
+
|
|
319
|
+
# @return [Hash{String => Array<Pin::Reference::Include>}]
|
|
320
|
+
def include_references
|
|
321
|
+
index.include_references
|
|
322
|
+
end
|
|
323
|
+
|
|
324
|
+
# @return [Hash{String => Array<Solargraph::Pin::Reference::Include>}]
|
|
325
|
+
def include_reference_pins
|
|
326
|
+
index.include_reference_pins
|
|
327
|
+
end
|
|
328
|
+
|
|
329
|
+
# @return [Hash{String => Array<Pin::Reference::Prepend>}]
|
|
330
|
+
def prepend_references
|
|
331
|
+
index.prepend_references
|
|
332
|
+
end
|
|
333
|
+
|
|
334
|
+
# @return [Hash{String => Array<Pin::Reference::Extend>}]
|
|
335
|
+
def extend_references
|
|
336
|
+
index.extend_references
|
|
337
|
+
end
|
|
338
|
+
|
|
339
|
+
# @param name [String]
|
|
340
|
+
# @return [Enumerable<Solargraph::Pin::Base>]
|
|
341
|
+
def namespace_children name
|
|
342
|
+
return [] unless index.namespace_hash.key?(name)
|
|
343
|
+
index.namespace_hash[name]
|
|
344
|
+
end
|
|
345
|
+
|
|
346
|
+
# @return [Enumerable<Pin::InstanceVariable>]
|
|
347
|
+
def all_instance_variables
|
|
348
|
+
index.pins_by_class(Pin::InstanceVariable)
|
|
349
|
+
end
|
|
350
|
+
|
|
351
|
+
# @param fqns [String]
|
|
352
|
+
# @return [Pin::Reference::Superclass, nil]
|
|
353
|
+
def try_special_superclasses(fqns)
|
|
354
|
+
return OBJECT_SUPERCLASS_PIN if fqns == 'Boolean'
|
|
355
|
+
return OBJECT_SUPERCLASS_PIN if !%w[BasicObject Object].include?(fqns) && namespace_exists?(fqns)
|
|
356
|
+
|
|
357
|
+
sub = ComplexType.try_parse(fqns)
|
|
358
|
+
return get_superclass(sub.simplify_literals.name) if sub.literal?
|
|
359
|
+
|
|
360
|
+
get_superclass(sub.namespace) if sub.namespace != fqns
|
|
361
|
+
end
|
|
362
|
+
|
|
363
|
+
# @param fq_sub_tag [String]
|
|
364
|
+
# @return [String, nil]
|
|
365
|
+
def qualify_and_cache_superclass fq_sub_tag
|
|
366
|
+
cached_qualify_superclass[fq_sub_tag] = uncached_qualify_superclass(fq_sub_tag)
|
|
367
|
+
end
|
|
368
|
+
|
|
369
|
+
# @return [Hash{String => String, nil}]
|
|
370
|
+
def cached_qualify_superclass
|
|
371
|
+
@cached_qualify_superclass ||= {}
|
|
372
|
+
end
|
|
373
|
+
|
|
374
|
+
# @param fq_sub_tag [String]
|
|
375
|
+
# @return [String, nil]
|
|
376
|
+
def uncached_qualify_superclass fq_sub_tag
|
|
377
|
+
type = ComplexType.try_parse(fq_sub_tag)
|
|
378
|
+
return type.simplify_literals.to_s if type.literal?
|
|
379
|
+
ref = get_superclass(fq_sub_tag)
|
|
380
|
+
return unless ref
|
|
381
|
+
res = constants.dereference(ref)
|
|
382
|
+
return unless res
|
|
383
|
+
res + type.substring
|
|
384
|
+
end
|
|
385
|
+
end
|
|
386
|
+
end
|
|
387
|
+
end
|