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.
Files changed (191) hide show
  1. checksums.yaml +4 -4
  2. data/.gitattributes +2 -0
  3. data/.github/workflows/linting.yml +127 -0
  4. data/.github/workflows/plugins.yml +183 -7
  5. data/.github/workflows/rspec.yml +55 -5
  6. data/.github/workflows/typecheck.yml +6 -3
  7. data/.gitignore +6 -0
  8. data/.overcommit.yml +72 -0
  9. data/.rspec +1 -0
  10. data/.rubocop.yml +66 -0
  11. data/.rubocop_todo.yml +1279 -0
  12. data/.yardopts +1 -0
  13. data/CHANGELOG.md +92 -1
  14. data/README.md +8 -4
  15. data/Rakefile +125 -13
  16. data/bin/solargraph +3 -0
  17. data/lib/solargraph/api_map/cache.rb +110 -109
  18. data/lib/solargraph/api_map/constants.rb +279 -0
  19. data/lib/solargraph/api_map/index.rb +193 -175
  20. data/lib/solargraph/api_map/source_to_yard.rb +97 -88
  21. data/lib/solargraph/api_map/store.rb +384 -266
  22. data/lib/solargraph/api_map.rb +945 -973
  23. data/lib/solargraph/bench.rb +1 -0
  24. data/lib/solargraph/complex_type/type_methods.rb +228 -222
  25. data/lib/solargraph/complex_type/unique_type.rb +482 -475
  26. data/lib/solargraph/complex_type.rb +444 -423
  27. data/lib/solargraph/convention/active_support_concern.rb +111 -0
  28. data/lib/solargraph/convention/base.rb +17 -0
  29. data/lib/solargraph/convention/data_definition/data_assignment_node.rb +61 -0
  30. data/lib/solargraph/convention/data_definition/data_definition_node.rb +91 -0
  31. data/lib/solargraph/convention/data_definition.rb +105 -0
  32. data/lib/solargraph/convention/gemspec.rb +3 -2
  33. data/lib/solargraph/convention/struct_definition/struct_assignment_node.rb +61 -60
  34. data/lib/solargraph/convention/struct_definition/struct_definition_node.rb +102 -100
  35. data/lib/solargraph/convention/struct_definition.rb +164 -101
  36. data/lib/solargraph/convention.rb +32 -2
  37. data/lib/solargraph/diagnostics/require_not_found.rb +53 -53
  38. data/lib/solargraph/diagnostics/rubocop.rb +118 -113
  39. data/lib/solargraph/diagnostics/rubocop_helpers.rb +68 -66
  40. data/lib/solargraph/diagnostics/type_check.rb +55 -55
  41. data/lib/solargraph/doc_map.rb +439 -405
  42. data/lib/solargraph/environ.rb +9 -2
  43. data/lib/solargraph/equality.rb +34 -33
  44. data/lib/solargraph/gem_pins.rb +98 -88
  45. data/lib/solargraph/language_server/host/diagnoser.rb +89 -89
  46. data/lib/solargraph/language_server/host/dispatch.rb +130 -128
  47. data/lib/solargraph/language_server/host/message_worker.rb +112 -109
  48. data/lib/solargraph/language_server/host/sources.rb +99 -99
  49. data/lib/solargraph/language_server/host.rb +878 -871
  50. data/lib/solargraph/language_server/message/base.rb +2 -1
  51. data/lib/solargraph/language_server/message/extended/check_gem_version.rb +114 -114
  52. data/lib/solargraph/language_server/message/extended/document.rb +23 -23
  53. data/lib/solargraph/language_server/message/text_document/completion.rb +56 -56
  54. data/lib/solargraph/language_server/message/text_document/definition.rb +40 -38
  55. data/lib/solargraph/language_server/message/text_document/document_symbol.rb +26 -26
  56. data/lib/solargraph/language_server/message/text_document/formatting.rb +148 -131
  57. data/lib/solargraph/language_server/message/text_document/hover.rb +58 -58
  58. data/lib/solargraph/language_server/message/text_document/signature_help.rb +24 -24
  59. data/lib/solargraph/language_server/message/text_document/type_definition.rb +25 -24
  60. data/lib/solargraph/language_server/message/workspace/did_change_workspace_folders.rb +2 -0
  61. data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +23 -23
  62. data/lib/solargraph/language_server/progress.rb +8 -0
  63. data/lib/solargraph/language_server/request.rb +4 -1
  64. data/lib/solargraph/library.rb +683 -666
  65. data/lib/solargraph/location.rb +82 -79
  66. data/lib/solargraph/logging.rb +37 -28
  67. data/lib/solargraph/page.rb +3 -0
  68. data/lib/solargraph/parser/comment_ripper.rb +69 -62
  69. data/lib/solargraph/parser/flow_sensitive_typing.rb +255 -227
  70. data/lib/solargraph/parser/node_processor/base.rb +92 -87
  71. data/lib/solargraph/parser/node_processor.rb +62 -46
  72. data/lib/solargraph/parser/parser_gem/class_methods.rb +149 -159
  73. data/lib/solargraph/parser/parser_gem/flawed_builder.rb +1 -0
  74. data/lib/solargraph/parser/parser_gem/node_chainer.rb +166 -164
  75. data/lib/solargraph/parser/parser_gem/node_methods.rb +486 -497
  76. data/lib/solargraph/parser/parser_gem/node_processors/and_node.rb +22 -21
  77. data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +59 -59
  78. data/lib/solargraph/parser/parser_gem/node_processors/begin_node.rb +15 -15
  79. data/lib/solargraph/parser/parser_gem/node_processors/block_node.rb +46 -45
  80. data/lib/solargraph/parser/parser_gem/node_processors/casgn_node.rb +1 -21
  81. data/lib/solargraph/parser/parser_gem/node_processors/def_node.rb +53 -53
  82. data/lib/solargraph/parser/parser_gem/node_processors/if_node.rb +23 -21
  83. data/lib/solargraph/parser/parser_gem/node_processors/ivasgn_node.rb +40 -40
  84. data/lib/solargraph/parser/parser_gem/node_processors/lvasgn_node.rb +29 -29
  85. data/lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb +59 -53
  86. data/lib/solargraph/parser/parser_gem/node_processors/namespace_node.rb +0 -22
  87. data/lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb +98 -41
  88. data/lib/solargraph/parser/parser_gem/node_processors/orasgn_node.rb +17 -16
  89. data/lib/solargraph/parser/parser_gem/node_processors/resbody_node.rb +38 -37
  90. data/lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb +52 -43
  91. data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +291 -271
  92. data/lib/solargraph/parser/parser_gem/node_processors/sym_node.rb +1 -0
  93. data/lib/solargraph/parser/parser_gem/node_processors/while_node.rb +29 -29
  94. data/lib/solargraph/parser/parser_gem/node_processors.rb +70 -66
  95. data/lib/solargraph/parser/region.rb +69 -66
  96. data/lib/solargraph/parser/snippet.rb +17 -15
  97. data/lib/solargraph/pin/base.rb +729 -651
  98. data/lib/solargraph/pin/base_variable.rb +126 -125
  99. data/lib/solargraph/pin/block.rb +104 -103
  100. data/lib/solargraph/pin/breakable.rb +9 -9
  101. data/lib/solargraph/pin/callable.rb +231 -218
  102. data/lib/solargraph/pin/closure.rb +72 -74
  103. data/lib/solargraph/pin/common.rb +79 -75
  104. data/lib/solargraph/pin/constant.rb +2 -0
  105. data/lib/solargraph/pin/conversions.rb +123 -123
  106. data/lib/solargraph/pin/delegated_method.rb +120 -120
  107. data/lib/solargraph/pin/documenting.rb +114 -114
  108. data/lib/solargraph/pin/instance_variable.rb +34 -34
  109. data/lib/solargraph/pin/keyword.rb +20 -20
  110. data/lib/solargraph/pin/local_variable.rb +75 -76
  111. data/lib/solargraph/pin/method.rb +672 -651
  112. data/lib/solargraph/pin/method_alias.rb +34 -31
  113. data/lib/solargraph/pin/namespace.rb +115 -115
  114. data/lib/solargraph/pin/parameter.rb +275 -261
  115. data/lib/solargraph/pin/proxy_type.rb +39 -35
  116. data/lib/solargraph/pin/reference/override.rb +47 -33
  117. data/lib/solargraph/pin/reference/superclass.rb +15 -10
  118. data/lib/solargraph/pin/reference.rb +39 -22
  119. data/lib/solargraph/pin/search.rb +61 -56
  120. data/lib/solargraph/pin/signature.rb +61 -59
  121. data/lib/solargraph/pin/symbol.rb +53 -48
  122. data/lib/solargraph/pin/until.rb +18 -18
  123. data/lib/solargraph/pin/while.rb +18 -18
  124. data/lib/solargraph/pin.rb +44 -44
  125. data/lib/solargraph/pin_cache.rb +245 -185
  126. data/lib/solargraph/position.rb +132 -116
  127. data/lib/solargraph/range.rb +112 -107
  128. data/lib/solargraph/rbs_map/conversions.rb +823 -773
  129. data/lib/solargraph/rbs_map/core_fills.rb +18 -0
  130. data/lib/solargraph/rbs_map/core_map.rb +58 -51
  131. data/lib/solargraph/rbs_map/stdlib_map.rb +43 -43
  132. data/lib/solargraph/rbs_map.rb +163 -150
  133. data/lib/solargraph/shell.rb +352 -268
  134. data/lib/solargraph/source/chain/call.rb +337 -333
  135. data/lib/solargraph/source/chain/constant.rb +26 -89
  136. data/lib/solargraph/source/chain/hash.rb +34 -34
  137. data/lib/solargraph/source/chain/if.rb +28 -28
  138. data/lib/solargraph/source/chain/instance_variable.rb +13 -13
  139. data/lib/solargraph/source/chain/link.rb +11 -2
  140. data/lib/solargraph/source/chain/literal.rb +48 -48
  141. data/lib/solargraph/source/chain/or.rb +23 -23
  142. data/lib/solargraph/source/chain.rb +291 -282
  143. data/lib/solargraph/source/change.rb +82 -82
  144. data/lib/solargraph/source/cursor.rb +166 -167
  145. data/lib/solargraph/source/encoding_fixes.rb +23 -23
  146. data/lib/solargraph/source/source_chainer.rb +194 -194
  147. data/lib/solargraph/source/updater.rb +55 -55
  148. data/lib/solargraph/source.rb +498 -495
  149. data/lib/solargraph/source_map/clip.rb +226 -234
  150. data/lib/solargraph/source_map/data.rb +34 -30
  151. data/lib/solargraph/source_map/mapper.rb +259 -259
  152. data/lib/solargraph/source_map.rb +212 -200
  153. data/lib/solargraph/type_checker/checks.rb +124 -124
  154. data/lib/solargraph/type_checker/param_def.rb +37 -35
  155. data/lib/solargraph/type_checker/problem.rb +32 -32
  156. data/lib/solargraph/type_checker/rules.rb +84 -62
  157. data/lib/solargraph/type_checker.rb +814 -699
  158. data/lib/solargraph/version.rb +5 -5
  159. data/lib/solargraph/workspace/config.rb +255 -239
  160. data/lib/solargraph/workspace/require_paths.rb +97 -0
  161. data/lib/solargraph/workspace.rb +220 -249
  162. data/lib/solargraph/yard_map/helpers.rb +44 -16
  163. data/lib/solargraph/yard_map/mapper/to_constant.rb +5 -5
  164. data/lib/solargraph/yard_map/mapper/to_method.rb +130 -134
  165. data/lib/solargraph/yard_map/mapper/to_namespace.rb +31 -30
  166. data/lib/solargraph/yard_map/mapper.rb +79 -79
  167. data/lib/solargraph/yard_map/to_method.rb +89 -88
  168. data/lib/solargraph/yardoc.rb +87 -49
  169. data/lib/solargraph.rb +105 -90
  170. data/rbs/fills/bundler/0/bundler.rbs +4271 -0
  171. data/rbs/fills/open3/0/open3.rbs +172 -0
  172. data/rbs/fills/rubygems/0/basic_specification.rbs +326 -0
  173. data/rbs/fills/rubygems/0/errors.rbs +364 -0
  174. data/rbs/fills/rubygems/0/spec_fetcher.rbs +107 -0
  175. data/rbs/fills/rubygems/0/specification.rbs +1753 -0
  176. data/rbs/fills/{tuple.rbs → tuple/tuple.rbs} +2 -3
  177. data/rbs/shims/ast/0/node.rbs +5 -0
  178. data/rbs/shims/ast/2.4/.rbs_meta.yaml +9 -0
  179. data/rbs/shims/ast/2.4/ast.rbs +73 -0
  180. data/rbs/shims/parser/3.2.0.1/builders/default.rbs +195 -0
  181. data/rbs/shims/parser/3.2.0.1/manifest.yaml +7 -0
  182. data/rbs/shims/parser/3.2.0.1/parser.rbs +201 -0
  183. data/rbs/shims/parser/3.2.0.1/polyfill.rbs +4 -0
  184. data/rbs/shims/thor/1.2.0.1/.rbs_meta.yaml +9 -0
  185. data/rbs/shims/thor/1.2.0.1/manifest.yaml +7 -0
  186. data/rbs/shims/thor/1.2.0.1/thor.rbs +17 -0
  187. data/rbs_collection.yaml +4 -4
  188. data/solargraph.gemspec +26 -5
  189. metadata +187 -15
  190. data/lib/.rubocop.yml +0 -22
  191. 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
- @namespace_hash ||= Hash.new { |h, k| h[k] = [] }
21
- end
22
-
23
- # @return [Hash{String => Array<Pin::Base>}]
24
- def pin_class_hash
25
- @pin_class_hash ||= Hash.new { |h, k| h[k] = [] }
26
- end
27
-
28
- # @return [Hash{String => Array<Pin::Base>}]
29
- def path_pin_hash
30
- @path_pin_hash ||= Hash.new { |h, k| h[k] = [] }
31
- end
32
-
33
- # @generic T
34
- # @param klass [Class<generic<T>>]
35
- # @return [Set<generic<T>>]
36
- def pins_by_class klass
37
- # @type [Set<Solargraph::Pin::Base>]
38
- s = Set.new
39
- @pin_select_cache[klass] ||= pin_class_hash.each_with_object(s) { |(key, o), n| n.merge(o) if key <= klass }
40
- end
41
-
42
- # @return [Hash{String => Array<Pin::Reference::Include>}]
43
- def include_references
44
- @include_references ||= Hash.new { |h, k| h[k] = [] }
45
- end
46
-
47
- # @return [Hash{String => Array<Pin::Reference::Extend>}]
48
- def extend_references
49
- @extend_references ||= Hash.new { |h, k| h[k] = [] }
50
- end
51
-
52
- # @return [Hash{String => Array<Pin::Reference::Prepend>}]
53
- def prepend_references
54
- @prepend_references ||= Hash.new { |h, k| h[k] = [] }
55
- end
56
-
57
- # @return [Hash{String => Array<Pin::Reference::Superclass>}]
58
- def superclass_references
59
- @superclass_references ||= Hash.new { |h, k| h[k] = [] }
60
- end
61
-
62
- # @param pins [Array<Pin::Base>]
63
- def merge pins
64
- deep_clone.catalog pins
65
- end
66
-
67
- protected
68
-
69
- attr_writer :pins, :pin_select_cache, :namespace_hash, :pin_class_hash, :path_pin_hash, :include_references,
70
- :extend_references, :prepend_references, :superclass_references
71
-
72
- def deep_clone
73
- Index.allocate.tap do |copy|
74
- copy.pin_select_cache = {}
75
- copy.pins = pins.clone
76
- %i[
77
- namespace_hash pin_class_hash path_pin_hash include_references extend_references prepend_references
78
- superclass_references
79
- ].each do |sym|
80
- copy.send("#{sym}=", send(sym).clone)
81
- copy.send(sym)&.transform_values!(&:clone)
82
- end
83
- end
84
- end
85
-
86
- # @param new_pins [Array<Pin::Base>]
87
- def catalog new_pins
88
- @pin_select_cache = {}
89
- pins.concat new_pins
90
- set = new_pins.to_set
91
- set.classify(&:class)
92
- .map { |k, v| pin_class_hash[k].concat v.to_a }
93
- set.classify(&:namespace)
94
- .map { |k, v| namespace_hash[k].concat v.to_a }
95
- set.classify(&:path)
96
- .map { |k, v| path_pin_hash[k].concat v.to_a }
97
- @namespaces = path_pin_hash.keys.compact.to_set
98
- map_references Pin::Reference::Include, include_references
99
- map_references Pin::Reference::Prepend, prepend_references
100
- map_references Pin::Reference::Extend, extend_references
101
- map_references Pin::Reference::Superclass, superclass_references
102
- map_overrides
103
- self
104
- end
105
-
106
- # @param klass [Class<Pin::Reference>]
107
- # @param hash [Hash{String => Array<Pin::Reference>}]
108
- # @return [void]
109
- def map_references klass, hash
110
- pins_by_class(klass).each do |pin|
111
- store_parametric_reference(hash, pin)
112
- end
113
- end
114
-
115
- # Add references to a map
116
- #
117
- # @param hash [Hash{String => Array<Pin::Reference>}]
118
- # @param reference_pin [Pin::Reference]
119
- #
120
- # @return [void]
121
- def store_parametric_reference(hash, reference_pin)
122
- referenced_ns = reference_pin.name
123
- referenced_tag_params = reference_pin.generic_values
124
- referenced_tag = referenced_ns +
125
- if referenced_tag_params && referenced_tag_params.length > 0
126
- "<" + referenced_tag_params.join(', ') + ">"
127
- else
128
- ''
129
- end
130
- referencing_ns = reference_pin.namespace
131
- hash[referencing_ns].push referenced_tag
132
- end
133
-
134
- # @return [void]
135
- def map_overrides
136
- pins_by_class(Pin::Reference::Override).each do |ovr|
137
- logger.debug { "ApiMap::Index#map_overrides: Looking at override #{ovr} for #{ovr.name}" }
138
- pins = path_pin_hash[ovr.name]
139
- logger.debug { "ApiMap::Index#map_overrides: pins for path=#{ovr.name}: #{pins}" }
140
- pins.each do |pin|
141
- new_pin = if pin.path.end_with?('#initialize')
142
- path_pin_hash[pin.path.sub(/#initialize/, '.new')].first
143
- end
144
- (ovr.tags.map(&:tag_name) + ovr.delete).uniq.each do |tag|
145
- pin.docstring.delete_tags tag
146
- new_pin.docstring.delete_tags tag if new_pin
147
- end
148
- ovr.tags.each do |tag|
149
- pin.docstring.add_tag(tag)
150
- redefine_return_type pin, tag
151
- if new_pin
152
- new_pin.docstring.add_tag(tag)
153
- redefine_return_type new_pin, tag
154
- end
155
- end
156
- end
157
- end
158
- end
159
-
160
- # @param pin [Pin::Method]
161
- # @param tag [YARD::Tags::Tag]
162
- # @return [void]
163
- def redefine_return_type pin, tag
164
- # @todo can this be made to not mutate existing pins and use
165
- # proxy() / proxy_with_signatures() instead?
166
- return unless pin && tag.tag_name == 'return'
167
- pin.instance_variable_set(:@return_type, ComplexType.try_parse(tag.type))
168
- pin.signatures.each do |sig|
169
- sig.instance_variable_set(:@return_type, ComplexType.try_parse(tag.type))
170
- end
171
- pin.reset_generated!
172
- end
173
- end
174
- end
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