solargraph 0.58.0 → 0.59.0

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