solargraph 0.56.0 → 0.58.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitattributes +2 -0
- data/.github/workflows/linting.yml +127 -0
- data/.github/workflows/plugins.yml +183 -7
- data/.github/workflows/rspec.yml +55 -5
- data/.github/workflows/typecheck.yml +6 -3
- data/.gitignore +6 -0
- data/.overcommit.yml +72 -0
- data/.rspec +1 -0
- data/.rubocop.yml +66 -0
- data/.rubocop_todo.yml +1279 -0
- data/.yardopts +1 -0
- data/CHANGELOG.md +92 -1
- data/README.md +8 -4
- data/Rakefile +125 -13
- data/bin/solargraph +3 -0
- data/lib/solargraph/api_map/cache.rb +110 -109
- data/lib/solargraph/api_map/constants.rb +279 -0
- data/lib/solargraph/api_map/index.rb +193 -175
- data/lib/solargraph/api_map/source_to_yard.rb +97 -88
- data/lib/solargraph/api_map/store.rb +384 -266
- data/lib/solargraph/api_map.rb +945 -973
- data/lib/solargraph/bench.rb +1 -0
- data/lib/solargraph/complex_type/type_methods.rb +228 -222
- data/lib/solargraph/complex_type/unique_type.rb +482 -475
- data/lib/solargraph/complex_type.rb +444 -423
- data/lib/solargraph/convention/active_support_concern.rb +111 -0
- data/lib/solargraph/convention/base.rb +17 -0
- data/lib/solargraph/convention/data_definition/data_assignment_node.rb +61 -0
- data/lib/solargraph/convention/data_definition/data_definition_node.rb +91 -0
- data/lib/solargraph/convention/data_definition.rb +105 -0
- data/lib/solargraph/convention/gemspec.rb +3 -2
- data/lib/solargraph/convention/struct_definition/struct_assignment_node.rb +61 -60
- data/lib/solargraph/convention/struct_definition/struct_definition_node.rb +102 -100
- data/lib/solargraph/convention/struct_definition.rb +164 -101
- data/lib/solargraph/convention.rb +32 -2
- data/lib/solargraph/diagnostics/require_not_found.rb +53 -53
- data/lib/solargraph/diagnostics/rubocop.rb +118 -113
- data/lib/solargraph/diagnostics/rubocop_helpers.rb +68 -66
- data/lib/solargraph/diagnostics/type_check.rb +55 -55
- data/lib/solargraph/doc_map.rb +439 -405
- data/lib/solargraph/environ.rb +9 -2
- data/lib/solargraph/equality.rb +34 -33
- data/lib/solargraph/gem_pins.rb +98 -88
- data/lib/solargraph/language_server/host/diagnoser.rb +89 -89
- data/lib/solargraph/language_server/host/dispatch.rb +130 -128
- data/lib/solargraph/language_server/host/message_worker.rb +112 -109
- data/lib/solargraph/language_server/host/sources.rb +99 -99
- data/lib/solargraph/language_server/host.rb +878 -871
- data/lib/solargraph/language_server/message/base.rb +2 -1
- data/lib/solargraph/language_server/message/extended/check_gem_version.rb +114 -114
- data/lib/solargraph/language_server/message/extended/document.rb +23 -23
- data/lib/solargraph/language_server/message/text_document/completion.rb +56 -56
- data/lib/solargraph/language_server/message/text_document/definition.rb +40 -38
- data/lib/solargraph/language_server/message/text_document/document_symbol.rb +26 -26
- data/lib/solargraph/language_server/message/text_document/formatting.rb +148 -131
- data/lib/solargraph/language_server/message/text_document/hover.rb +58 -58
- data/lib/solargraph/language_server/message/text_document/signature_help.rb +24 -24
- data/lib/solargraph/language_server/message/text_document/type_definition.rb +25 -24
- data/lib/solargraph/language_server/message/workspace/did_change_workspace_folders.rb +2 -0
- data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +23 -23
- data/lib/solargraph/language_server/progress.rb +8 -0
- data/lib/solargraph/language_server/request.rb +4 -1
- data/lib/solargraph/library.rb +683 -666
- data/lib/solargraph/location.rb +82 -79
- data/lib/solargraph/logging.rb +37 -28
- data/lib/solargraph/page.rb +3 -0
- data/lib/solargraph/parser/comment_ripper.rb +69 -62
- data/lib/solargraph/parser/flow_sensitive_typing.rb +255 -227
- data/lib/solargraph/parser/node_processor/base.rb +92 -87
- data/lib/solargraph/parser/node_processor.rb +62 -46
- data/lib/solargraph/parser/parser_gem/class_methods.rb +149 -159
- data/lib/solargraph/parser/parser_gem/flawed_builder.rb +1 -0
- data/lib/solargraph/parser/parser_gem/node_chainer.rb +166 -164
- data/lib/solargraph/parser/parser_gem/node_methods.rb +486 -497
- data/lib/solargraph/parser/parser_gem/node_processors/and_node.rb +22 -21
- data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +59 -59
- data/lib/solargraph/parser/parser_gem/node_processors/begin_node.rb +15 -15
- data/lib/solargraph/parser/parser_gem/node_processors/block_node.rb +46 -45
- data/lib/solargraph/parser/parser_gem/node_processors/casgn_node.rb +1 -21
- data/lib/solargraph/parser/parser_gem/node_processors/def_node.rb +53 -53
- data/lib/solargraph/parser/parser_gem/node_processors/if_node.rb +23 -21
- data/lib/solargraph/parser/parser_gem/node_processors/ivasgn_node.rb +40 -40
- data/lib/solargraph/parser/parser_gem/node_processors/lvasgn_node.rb +29 -29
- data/lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb +59 -53
- data/lib/solargraph/parser/parser_gem/node_processors/namespace_node.rb +0 -22
- data/lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb +98 -41
- data/lib/solargraph/parser/parser_gem/node_processors/orasgn_node.rb +17 -16
- data/lib/solargraph/parser/parser_gem/node_processors/resbody_node.rb +38 -37
- data/lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb +52 -43
- data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +291 -271
- data/lib/solargraph/parser/parser_gem/node_processors/sym_node.rb +1 -0
- data/lib/solargraph/parser/parser_gem/node_processors/while_node.rb +29 -29
- data/lib/solargraph/parser/parser_gem/node_processors.rb +70 -66
- data/lib/solargraph/parser/region.rb +69 -66
- data/lib/solargraph/parser/snippet.rb +17 -15
- data/lib/solargraph/pin/base.rb +729 -651
- data/lib/solargraph/pin/base_variable.rb +126 -125
- data/lib/solargraph/pin/block.rb +104 -103
- data/lib/solargraph/pin/breakable.rb +9 -9
- data/lib/solargraph/pin/callable.rb +231 -218
- data/lib/solargraph/pin/closure.rb +72 -74
- data/lib/solargraph/pin/common.rb +79 -75
- data/lib/solargraph/pin/constant.rb +2 -0
- data/lib/solargraph/pin/conversions.rb +123 -123
- data/lib/solargraph/pin/delegated_method.rb +120 -120
- data/lib/solargraph/pin/documenting.rb +114 -114
- data/lib/solargraph/pin/instance_variable.rb +34 -34
- data/lib/solargraph/pin/keyword.rb +20 -20
- data/lib/solargraph/pin/local_variable.rb +75 -76
- data/lib/solargraph/pin/method.rb +672 -651
- data/lib/solargraph/pin/method_alias.rb +34 -31
- data/lib/solargraph/pin/namespace.rb +115 -115
- data/lib/solargraph/pin/parameter.rb +275 -261
- data/lib/solargraph/pin/proxy_type.rb +39 -35
- data/lib/solargraph/pin/reference/override.rb +47 -33
- data/lib/solargraph/pin/reference/superclass.rb +15 -10
- data/lib/solargraph/pin/reference.rb +39 -22
- data/lib/solargraph/pin/search.rb +61 -56
- data/lib/solargraph/pin/signature.rb +61 -59
- data/lib/solargraph/pin/symbol.rb +53 -48
- data/lib/solargraph/pin/until.rb +18 -18
- data/lib/solargraph/pin/while.rb +18 -18
- data/lib/solargraph/pin.rb +44 -44
- data/lib/solargraph/pin_cache.rb +245 -185
- data/lib/solargraph/position.rb +132 -116
- data/lib/solargraph/range.rb +112 -107
- data/lib/solargraph/rbs_map/conversions.rb +823 -773
- data/lib/solargraph/rbs_map/core_fills.rb +18 -0
- data/lib/solargraph/rbs_map/core_map.rb +58 -51
- data/lib/solargraph/rbs_map/stdlib_map.rb +43 -43
- data/lib/solargraph/rbs_map.rb +163 -150
- data/lib/solargraph/shell.rb +352 -268
- data/lib/solargraph/source/chain/call.rb +337 -333
- data/lib/solargraph/source/chain/constant.rb +26 -89
- data/lib/solargraph/source/chain/hash.rb +34 -34
- data/lib/solargraph/source/chain/if.rb +28 -28
- data/lib/solargraph/source/chain/instance_variable.rb +13 -13
- data/lib/solargraph/source/chain/link.rb +11 -2
- data/lib/solargraph/source/chain/literal.rb +48 -48
- data/lib/solargraph/source/chain/or.rb +23 -23
- data/lib/solargraph/source/chain.rb +291 -282
- data/lib/solargraph/source/change.rb +82 -82
- data/lib/solargraph/source/cursor.rb +166 -167
- data/lib/solargraph/source/encoding_fixes.rb +23 -23
- data/lib/solargraph/source/source_chainer.rb +194 -194
- data/lib/solargraph/source/updater.rb +55 -55
- data/lib/solargraph/source.rb +498 -495
- data/lib/solargraph/source_map/clip.rb +226 -234
- data/lib/solargraph/source_map/data.rb +34 -30
- data/lib/solargraph/source_map/mapper.rb +259 -259
- data/lib/solargraph/source_map.rb +212 -200
- data/lib/solargraph/type_checker/checks.rb +124 -124
- data/lib/solargraph/type_checker/param_def.rb +37 -35
- data/lib/solargraph/type_checker/problem.rb +32 -32
- data/lib/solargraph/type_checker/rules.rb +84 -62
- data/lib/solargraph/type_checker.rb +814 -699
- data/lib/solargraph/version.rb +5 -5
- data/lib/solargraph/workspace/config.rb +255 -239
- data/lib/solargraph/workspace/require_paths.rb +97 -0
- data/lib/solargraph/workspace.rb +220 -249
- data/lib/solargraph/yard_map/helpers.rb +44 -16
- data/lib/solargraph/yard_map/mapper/to_constant.rb +5 -5
- data/lib/solargraph/yard_map/mapper/to_method.rb +130 -134
- data/lib/solargraph/yard_map/mapper/to_namespace.rb +31 -30
- data/lib/solargraph/yard_map/mapper.rb +79 -79
- data/lib/solargraph/yard_map/to_method.rb +89 -88
- data/lib/solargraph/yardoc.rb +87 -49
- data/lib/solargraph.rb +105 -90
- data/rbs/fills/bundler/0/bundler.rbs +4271 -0
- data/rbs/fills/open3/0/open3.rbs +172 -0
- data/rbs/fills/rubygems/0/basic_specification.rbs +326 -0
- data/rbs/fills/rubygems/0/errors.rbs +364 -0
- data/rbs/fills/rubygems/0/spec_fetcher.rbs +107 -0
- data/rbs/fills/rubygems/0/specification.rbs +1753 -0
- data/rbs/fills/{tuple.rbs → tuple/tuple.rbs} +2 -3
- data/rbs/shims/ast/0/node.rbs +5 -0
- data/rbs/shims/ast/2.4/.rbs_meta.yaml +9 -0
- data/rbs/shims/ast/2.4/ast.rbs +73 -0
- data/rbs/shims/parser/3.2.0.1/builders/default.rbs +195 -0
- data/rbs/shims/parser/3.2.0.1/manifest.yaml +7 -0
- data/rbs/shims/parser/3.2.0.1/parser.rbs +201 -0
- data/rbs/shims/parser/3.2.0.1/polyfill.rbs +4 -0
- data/rbs/shims/thor/1.2.0.1/.rbs_meta.yaml +9 -0
- data/rbs/shims/thor/1.2.0.1/manifest.yaml +7 -0
- data/rbs/shims/thor/1.2.0.1/thor.rbs +17 -0
- data/rbs_collection.yaml +4 -4
- data/solargraph.gemspec +26 -5
- metadata +187 -15
- data/lib/.rubocop.yml +0 -22
- data/lib/solargraph/parser/node_methods.rb +0 -97
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Solargraph
|
|
4
|
+
class ApiMap
|
|
5
|
+
# Methods for handling constants.
|
|
6
|
+
#
|
|
7
|
+
class Constants
|
|
8
|
+
# @param store [Store]
|
|
9
|
+
def initialize store
|
|
10
|
+
@store = store
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# Resolve a name to a fully qualified namespace or constant.
|
|
14
|
+
#
|
|
15
|
+
# `Constants#resolve` finds fully qualified (absolute)
|
|
16
|
+
# namespaces based on relative names and the open gates
|
|
17
|
+
# (namespaces) provided. Names must be runtime-visible (erased)
|
|
18
|
+
# non-literal types, non-duck, non-signature types - e.g.,
|
|
19
|
+
# TrueClass, NilClass, Integer and Hash instead of true, nil,
|
|
20
|
+
# 96, or Hash{String => Symbol}
|
|
21
|
+
#
|
|
22
|
+
# Note: You may want to be using #qualify. Notably, #resolve:
|
|
23
|
+
# - does not handle anything with type parameters
|
|
24
|
+
# - will not gracefully handle nil, self and Boolean
|
|
25
|
+
# - will return a constant name instead of following its assignment
|
|
26
|
+
#
|
|
27
|
+
# @param name [String] Namespace which may relative and not be rooted.
|
|
28
|
+
# @param gates [Array<Array<String>, String>] Namespaces to search while resolving the name
|
|
29
|
+
#
|
|
30
|
+
# @return [String, nil] fully qualified namespace (i.e., is
|
|
31
|
+
# absolute, but will not start with ::)
|
|
32
|
+
def resolve(name, *gates)
|
|
33
|
+
return store.get_path_pins(name[2..]).first&.path if name.start_with?('::')
|
|
34
|
+
|
|
35
|
+
flat = gates.flatten
|
|
36
|
+
flat.push '' if flat.empty?
|
|
37
|
+
if cached_resolve.include? [name, flat]
|
|
38
|
+
cached_result = cached_resolve[[name, flat]]
|
|
39
|
+
# don't recurse
|
|
40
|
+
return nil if cached_result == :in_process
|
|
41
|
+
return cached_result
|
|
42
|
+
end
|
|
43
|
+
resolve_and_cache(name, flat)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Get a fully qualified namespace from a reference pin.
|
|
47
|
+
#
|
|
48
|
+
# @param pin [Pin::Reference]
|
|
49
|
+
# @return [String, nil]
|
|
50
|
+
def dereference pin
|
|
51
|
+
qualify_type(pin.type, *pin.reference_gates)&.tag
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Collect a list of all constants defined in the specified gates.
|
|
55
|
+
#
|
|
56
|
+
# @param gates [Array<Array<String>, String>]
|
|
57
|
+
# @return [Array<Solargraph::Pin::Namespace, Solargraph::Pin::Constant>]
|
|
58
|
+
def collect(*gates)
|
|
59
|
+
flat = gates.flatten
|
|
60
|
+
cached_collect[flat] || collect_and_cache(flat)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# Determine a fully qualified namespace for a given tag
|
|
64
|
+
# referenced from the specified open gates. This method will
|
|
65
|
+
# search in each gate until it finds a match for the name.
|
|
66
|
+
#
|
|
67
|
+
# @param tag [String, nil] The type to match
|
|
68
|
+
# @param gates [Array<String>]
|
|
69
|
+
# @return [String, nil] fully qualified tag
|
|
70
|
+
def qualify tag, *gates
|
|
71
|
+
type = ComplexType.try_parse(tag)
|
|
72
|
+
qualify_type(type, *gates)&.tag
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# @param type [ComplexType, nil] The type to match
|
|
76
|
+
# @param gates [Array<String>]
|
|
77
|
+
#
|
|
78
|
+
# @return [ComplexType, nil] A new rooted ComplexType
|
|
79
|
+
def qualify_type type, *gates
|
|
80
|
+
return nil if type.nil?
|
|
81
|
+
return type if type.selfy? || type.literal? || type.tag == 'nil' || type.interface? ||
|
|
82
|
+
type.tag == 'Boolean'
|
|
83
|
+
|
|
84
|
+
gates.push '' unless gates.include?('')
|
|
85
|
+
fqns = resolve(type.rooted_namespace, *gates)
|
|
86
|
+
return unless fqns
|
|
87
|
+
pin = store.get_path_pins(fqns).first
|
|
88
|
+
if pin.is_a?(Pin::Constant)
|
|
89
|
+
const = Solargraph::Parser::NodeMethods.unpack_name(pin.assignment)
|
|
90
|
+
return unless const
|
|
91
|
+
fqns = resolve(const, *pin.gates)
|
|
92
|
+
end
|
|
93
|
+
type.recreate(new_name: fqns, make_rooted: true)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# @return [void]
|
|
97
|
+
def clear
|
|
98
|
+
[cached_collect, cached_resolve].each(&:clear)
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
private
|
|
102
|
+
|
|
103
|
+
# @return [Store]
|
|
104
|
+
attr_reader :store
|
|
105
|
+
|
|
106
|
+
# @param name [String]
|
|
107
|
+
# @param gates [Array<String>]
|
|
108
|
+
# @return [String, nil]
|
|
109
|
+
def resolve_and_cache name, gates
|
|
110
|
+
cached_resolve[[name, gates]] = :in_process
|
|
111
|
+
cached_resolve[[name, gates]] = resolve_uncached(name, gates)
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# @param name [String]
|
|
115
|
+
# @param gates [Array<String>]
|
|
116
|
+
# @return [String, nil]
|
|
117
|
+
def resolve_uncached name, gates
|
|
118
|
+
resolved = nil
|
|
119
|
+
base = gates
|
|
120
|
+
parts = name.split('::')
|
|
121
|
+
first = nil
|
|
122
|
+
parts.each.with_index do |nam, idx|
|
|
123
|
+
resolved, remainder = complex_resolve(nam, base, idx != parts.length - 1)
|
|
124
|
+
first ||= remainder
|
|
125
|
+
if resolved
|
|
126
|
+
base = [resolved]
|
|
127
|
+
else
|
|
128
|
+
return resolve(name, first) unless first.empty?
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
resolved
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
# @todo I'm not sure of a better way to express the return value in YARD.
|
|
135
|
+
# It's a tuple where the first element is a nullable string. Something
|
|
136
|
+
# like `Array(String|nil, Array<String>)` would be more accurate.
|
|
137
|
+
#
|
|
138
|
+
# @param name [String]
|
|
139
|
+
# @param gates [Array<String>]
|
|
140
|
+
# @param internal [Boolean] True if the name is not the last in the namespace
|
|
141
|
+
# @return [Array(Object, Array<String>)]
|
|
142
|
+
def complex_resolve name, gates, internal
|
|
143
|
+
resolved = nil
|
|
144
|
+
gates.each.with_index do |gate, idx|
|
|
145
|
+
resolved = simple_resolve(name, gate, internal)
|
|
146
|
+
return [resolved, gates[(idx + 1)..]] if resolved
|
|
147
|
+
store.get_ancestor_references(gate).each do |ref|
|
|
148
|
+
return ref.name.sub(/^::/, '') if ref.name.end_with?("::#{name}") && ref.name.start_with?('::')
|
|
149
|
+
|
|
150
|
+
mixin = resolve(ref.name, ref.reference_gates)
|
|
151
|
+
next unless mixin
|
|
152
|
+
|
|
153
|
+
resolved = simple_resolve(name, mixin, internal)
|
|
154
|
+
return [resolved, gates[(idx + 1)..]] if resolved
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
[nil, []]
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
# @param name [String]
|
|
161
|
+
# @param gate [String]
|
|
162
|
+
# @param internal [Boolean] True if the name is not the last in the namespace
|
|
163
|
+
# @return [String, nil]
|
|
164
|
+
def simple_resolve name, gate, internal
|
|
165
|
+
here = "#{gate}::#{name}".sub(/^::/, '').sub(/::$/, '')
|
|
166
|
+
pin = store.get_path_pins(here).first
|
|
167
|
+
if pin.is_a?(Pin::Constant) && internal
|
|
168
|
+
const = Solargraph::Parser::NodeMethods.unpack_name(pin.assignment)
|
|
169
|
+
return unless const
|
|
170
|
+
resolve(const, pin.gates)
|
|
171
|
+
else
|
|
172
|
+
pin&.path
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
# @param gates [Array<String>]
|
|
177
|
+
# @return [Array<Solargraph::Pin::Namespace, Solargraph::Pin::Constant>]
|
|
178
|
+
def collect_and_cache gates
|
|
179
|
+
skip = Set.new
|
|
180
|
+
cached_collect[gates] = gates.flat_map do |gate|
|
|
181
|
+
inner_get_constants(gate, %i[public private], skip)
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
# @return [Hash{Array(String, Array<String>) => String, :in_process, nil}]
|
|
186
|
+
def cached_resolve
|
|
187
|
+
@cached_resolve ||= {}
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
# @return [Hash{Array<String> => Array<Solargraph::Pin::Namespace, Solargraph::Pin::Constant>}]
|
|
191
|
+
def cached_collect
|
|
192
|
+
@cached_collect ||= {}
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
# Determine fully qualified namespace for a given namespace used
|
|
196
|
+
# inside the definition of another tag ("context"). This method
|
|
197
|
+
# will start the search in the specified context until it finds a
|
|
198
|
+
# match for the namespace.
|
|
199
|
+
#
|
|
200
|
+
# @param namespace [String, nil] The namespace to
|
|
201
|
+
# match
|
|
202
|
+
# @param context_namespace [String] The context namespace in which the
|
|
203
|
+
# tag was referenced; start from here to resolve the name
|
|
204
|
+
# @return [String, nil] fully qualified namespace
|
|
205
|
+
def qualify_namespace namespace, context_namespace = ''
|
|
206
|
+
if namespace.start_with?('::')
|
|
207
|
+
inner_qualify(namespace[2..], '', Set.new)
|
|
208
|
+
else
|
|
209
|
+
inner_qualify(namespace, context_namespace, Set.new)
|
|
210
|
+
end
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
# @param name [String] Namespace to fully qualify
|
|
214
|
+
# @param root [String] The context to search
|
|
215
|
+
# @param skip [Set<String>] Contexts already searched
|
|
216
|
+
# @return [String, nil] Fully qualified ("rooted") namespace
|
|
217
|
+
def inner_qualify name, root, skip
|
|
218
|
+
return name if name == ComplexType::GENERIC_TAG_NAME
|
|
219
|
+
return nil if name.nil?
|
|
220
|
+
return nil if skip.include?(root)
|
|
221
|
+
skip.add root
|
|
222
|
+
possibles = []
|
|
223
|
+
if name == ''
|
|
224
|
+
return '' if root == ''
|
|
225
|
+
|
|
226
|
+
inner_qualify(root, '', skip)
|
|
227
|
+
else
|
|
228
|
+
return name if root == '' && store.namespace_exists?(name)
|
|
229
|
+
roots = root.to_s.split('::')
|
|
230
|
+
while roots.length.positive?
|
|
231
|
+
fqns = "#{roots.join('::')}::#{name}"
|
|
232
|
+
return fqns if store.namespace_exists?(fqns)
|
|
233
|
+
incs = store.get_includes(roots.join('::'))
|
|
234
|
+
incs.each do |inc|
|
|
235
|
+
foundinc = inner_qualify(name, inc.type.to_s, skip)
|
|
236
|
+
possibles.push foundinc unless foundinc.nil?
|
|
237
|
+
end
|
|
238
|
+
roots.pop
|
|
239
|
+
end
|
|
240
|
+
if possibles.empty?
|
|
241
|
+
incs = store.get_includes('')
|
|
242
|
+
incs.each do |inc|
|
|
243
|
+
foundinc = inner_qualify(name, inc.type.to_s, skip)
|
|
244
|
+
possibles.push foundinc unless foundinc.nil?
|
|
245
|
+
end
|
|
246
|
+
end
|
|
247
|
+
return name if store.namespace_exists?(name)
|
|
248
|
+
possibles.last
|
|
249
|
+
end
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
# @param fqns [String]
|
|
253
|
+
# @param visibility [Array<Symbol>]
|
|
254
|
+
# @param skip [Set<String>]
|
|
255
|
+
# @return [Array<Solargraph::Pin::Namespace, Solargraph::Pin::Constant>]
|
|
256
|
+
def inner_get_constants fqns, visibility, skip
|
|
257
|
+
return [] if fqns.nil? || skip.include?(fqns)
|
|
258
|
+
skip.add fqns
|
|
259
|
+
result = []
|
|
260
|
+
|
|
261
|
+
store.get_prepends(fqns).each do |pre|
|
|
262
|
+
pre_fqns = resolve(pre.name, pre.closure.gates - skip.to_a)
|
|
263
|
+
result.concat inner_get_constants(pre_fqns, [:public], skip)
|
|
264
|
+
end
|
|
265
|
+
result.concat(store.get_constants(fqns, visibility).sort { |a, b| a.name <=> b.name })
|
|
266
|
+
store.get_includes(fqns).each do |pin|
|
|
267
|
+
inc_fqns = resolve(pin.name, pin.closure.gates - skip.to_a)
|
|
268
|
+
result.concat inner_get_constants(inc_fqns, [:public], skip)
|
|
269
|
+
end
|
|
270
|
+
sc_ref = store.get_superclass(fqns)
|
|
271
|
+
if sc_ref
|
|
272
|
+
fqsc = dereference(sc_ref)
|
|
273
|
+
result.concat inner_get_constants(fqsc, [:public], skip) unless %w[Object BasicObject].include?(fqsc)
|
|
274
|
+
end
|
|
275
|
+
result
|
|
276
|
+
end
|
|
277
|
+
end
|
|
278
|
+
end
|
|
279
|
+
end
|
|
@@ -1,175 +1,193 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Solargraph
|
|
4
|
-
class ApiMap
|
|
5
|
-
class Index
|
|
6
|
-
include Logging
|
|
7
|
-
|
|
8
|
-
# @param pins [Array<Pin::Base>]
|
|
9
|
-
def initialize pins = []
|
|
10
|
-
catalog pins
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
# @return [Array<Pin::Base>]
|
|
14
|
-
def pins
|
|
15
|
-
@pins ||= []
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
# @return [Hash{String => Array<Pin::Namespace>}]
|
|
19
|
-
def namespace_hash
|
|
20
|
-
@
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
@
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
end
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Solargraph
|
|
4
|
+
class ApiMap
|
|
5
|
+
class Index
|
|
6
|
+
include Logging
|
|
7
|
+
|
|
8
|
+
# @param pins [Array<Pin::Base>]
|
|
9
|
+
def initialize pins = []
|
|
10
|
+
catalog pins
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# @return [Array<Pin::Base>]
|
|
14
|
+
def pins
|
|
15
|
+
@pins ||= []
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# @return [Hash{String => Array<Pin::Namespace>}]
|
|
19
|
+
def namespace_hash
|
|
20
|
+
# @param h [String]
|
|
21
|
+
# @param k [Array<Pin::Namespace>]
|
|
22
|
+
@namespace_hash ||= Hash.new { |h, k| h[k] = [] }
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# @return [Hash{String => Array<Pin::Base>}]
|
|
26
|
+
def pin_class_hash
|
|
27
|
+
# @param h [String]
|
|
28
|
+
# @param k [Array<Pin::Base>]
|
|
29
|
+
@pin_class_hash ||= Hash.new { |h, k| h[k] = [] }
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# @return [Hash{String => Array<Pin::Base>}]
|
|
33
|
+
def path_pin_hash
|
|
34
|
+
# @param h [String]
|
|
35
|
+
# @param k [Array<Pin::Base>]
|
|
36
|
+
@path_pin_hash ||= Hash.new { |h, k| h[k] = [] }
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# @generic T
|
|
40
|
+
# @param klass [Class<generic<T>>]
|
|
41
|
+
# @return [Set<generic<T>>]
|
|
42
|
+
def pins_by_class klass
|
|
43
|
+
# @type [Set<Solargraph::Pin::Base>]
|
|
44
|
+
s = Set.new
|
|
45
|
+
# @sg-ignore need to support destructured args in blocks
|
|
46
|
+
@pin_select_cache[klass] ||= pin_class_hash.each_with_object(s) { |(key, o), n| n.merge(o) if key <= klass }
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# @return [Hash{String => Array<String>}]
|
|
50
|
+
def include_references
|
|
51
|
+
# @param h [String]
|
|
52
|
+
# @param k [Array<String>]
|
|
53
|
+
@include_references ||= Hash.new { |h, k| h[k] = [] }
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# @return [Hash{String => Array<Pin::Reference::Include>}]
|
|
57
|
+
def include_reference_pins
|
|
58
|
+
# @param h [String]
|
|
59
|
+
# @param k [Array<Pin::Reference::Include>]
|
|
60
|
+
@include_reference_pins ||= Hash.new { |h, k| h[k] = [] }
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# @return [Hash{String => Array<String>}]
|
|
64
|
+
def extend_references
|
|
65
|
+
# @param h [String]
|
|
66
|
+
# @param k [Array<String>]
|
|
67
|
+
@extend_references ||= Hash.new { |h, k| h[k] = [] }
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# @return [Hash{String => Array<String>}]
|
|
71
|
+
def prepend_references
|
|
72
|
+
# @param h [String]
|
|
73
|
+
# @param k [Array<String>]
|
|
74
|
+
@prepend_references ||= Hash.new { |h, k| h[k] = [] }
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# @return [Hash{String => Array<String>}]
|
|
78
|
+
def superclass_references
|
|
79
|
+
# @param h [String]
|
|
80
|
+
# @param k [Array<String>]
|
|
81
|
+
@superclass_references ||= Hash.new { |h, k| h[k] = [] }
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# @param pins [Enumerable<Pin::Base>]
|
|
85
|
+
# @return [self]
|
|
86
|
+
def merge pins
|
|
87
|
+
deep_clone.catalog pins
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
protected
|
|
91
|
+
|
|
92
|
+
attr_writer :pins, :pin_select_cache, :namespace_hash, :pin_class_hash, :path_pin_hash, :include_references,
|
|
93
|
+
:extend_references, :prepend_references, :superclass_references
|
|
94
|
+
|
|
95
|
+
# @return [self]
|
|
96
|
+
def deep_clone
|
|
97
|
+
Index.allocate.tap do |copy|
|
|
98
|
+
copy.pin_select_cache = {}
|
|
99
|
+
copy.pins = pins.clone
|
|
100
|
+
%i[
|
|
101
|
+
namespace_hash pin_class_hash path_pin_hash include_references extend_references prepend_references
|
|
102
|
+
superclass_references
|
|
103
|
+
].each do |sym|
|
|
104
|
+
copy.send("#{sym}=", send(sym).clone)
|
|
105
|
+
copy.send(sym)&.transform_values!(&:clone)
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# @param new_pins [Enumerable<Pin::Base>]
|
|
111
|
+
#
|
|
112
|
+
# @return [self]
|
|
113
|
+
def catalog new_pins
|
|
114
|
+
# @type [Hash{Class<generic<T>> => Set<generic<T>>}]
|
|
115
|
+
@pin_select_cache = {}
|
|
116
|
+
pins.concat new_pins
|
|
117
|
+
set = new_pins.to_set
|
|
118
|
+
# @param k [String]
|
|
119
|
+
# @param v [Set<Pin::Base>]
|
|
120
|
+
set.classify(&:class)
|
|
121
|
+
.map { |k, v| pin_class_hash[k].concat v.to_a }
|
|
122
|
+
# @param k [String]
|
|
123
|
+
# @param v [Set<Pin::Namespace>]
|
|
124
|
+
set.classify(&:namespace)
|
|
125
|
+
.map { |k, v| namespace_hash[k].concat v.to_a }
|
|
126
|
+
# @param k [String]
|
|
127
|
+
# @param v [Set<Pin::Base>]
|
|
128
|
+
set.classify(&:path)
|
|
129
|
+
.map { |k, v| path_pin_hash[k].concat v.to_a }
|
|
130
|
+
@namespaces = path_pin_hash.keys.compact.to_set
|
|
131
|
+
map_references Pin::Reference::Include, include_references
|
|
132
|
+
map_references Pin::Reference::Prepend, prepend_references
|
|
133
|
+
map_references Pin::Reference::Extend, extend_references
|
|
134
|
+
map_references Pin::Reference::Superclass, superclass_references
|
|
135
|
+
map_overrides
|
|
136
|
+
self
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
# @generic T
|
|
140
|
+
# @param klass [Class<generic<T>>]
|
|
141
|
+
# @param hash [Hash{String => generic<T>}]
|
|
142
|
+
#
|
|
143
|
+
# @return [void]
|
|
144
|
+
def map_references klass, hash
|
|
145
|
+
# @param pin [generic<T>]
|
|
146
|
+
pins_by_class(klass).each do |pin|
|
|
147
|
+
hash[pin.namespace].push pin
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
# @return [void]
|
|
152
|
+
def map_overrides
|
|
153
|
+
# @param ovr [Pin::Reference::Override]
|
|
154
|
+
pins_by_class(Pin::Reference::Override).each do |ovr|
|
|
155
|
+
logger.debug { "ApiMap::Index#map_overrides: Looking at override #{ovr} for #{ovr.name}" }
|
|
156
|
+
pins = path_pin_hash[ovr.name]
|
|
157
|
+
logger.debug { "ApiMap::Index#map_overrides: pins for path=#{ovr.name}: #{pins}" }
|
|
158
|
+
pins.each do |pin|
|
|
159
|
+
new_pin = if pin.path.end_with?('#initialize')
|
|
160
|
+
path_pin_hash[pin.path.sub(/#initialize/, '.new')].first
|
|
161
|
+
end
|
|
162
|
+
(ovr.tags.map(&:tag_name) + ovr.delete).uniq.each do |tag|
|
|
163
|
+
pin.docstring.delete_tags tag
|
|
164
|
+
new_pin.docstring.delete_tags tag if new_pin
|
|
165
|
+
end
|
|
166
|
+
ovr.tags.each do |tag|
|
|
167
|
+
pin.docstring.add_tag(tag)
|
|
168
|
+
redefine_return_type pin, tag
|
|
169
|
+
if new_pin
|
|
170
|
+
new_pin.docstring.add_tag(tag)
|
|
171
|
+
redefine_return_type new_pin, tag
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
# @param pin [Pin::Method]
|
|
179
|
+
# @param tag [YARD::Tags::Tag]
|
|
180
|
+
# @return [void]
|
|
181
|
+
def redefine_return_type pin, tag
|
|
182
|
+
# @todo can this be made to not mutate existing pins and use
|
|
183
|
+
# proxy() / proxy_with_signatures() instead?
|
|
184
|
+
return unless pin && tag.tag_name == 'return'
|
|
185
|
+
pin.instance_variable_set(:@return_type, ComplexType.try_parse(tag.type))
|
|
186
|
+
pin.signatures.each do |sig|
|
|
187
|
+
sig.instance_variable_set(:@return_type, ComplexType.try_parse(tag.type))
|
|
188
|
+
end
|
|
189
|
+
pin.reset_generated!
|
|
190
|
+
end
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
end
|