solargraph 0.58.1 → 0.59.0.dev.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (162) hide show
  1. checksums.yaml +4 -4
  2. data/.envrc +3 -0
  3. data/.github/workflows/linting.yml +4 -5
  4. data/.github/workflows/plugins.yml +40 -36
  5. data/.github/workflows/rspec.yml +45 -13
  6. data/.github/workflows/typecheck.yml +2 -2
  7. data/.rubocop_todo.yml +27 -49
  8. data/README.md +3 -3
  9. data/Rakefile +1 -0
  10. data/lib/solargraph/api_map/cache.rb +110 -110
  11. data/lib/solargraph/api_map/constants.rb +289 -279
  12. data/lib/solargraph/api_map/index.rb +204 -193
  13. data/lib/solargraph/api_map/source_to_yard.rb +109 -97
  14. data/lib/solargraph/api_map/store.rb +387 -384
  15. data/lib/solargraph/api_map.rb +1000 -945
  16. data/lib/solargraph/complex_type/conformance.rb +176 -0
  17. data/lib/solargraph/complex_type/type_methods.rb +242 -228
  18. data/lib/solargraph/complex_type/unique_type.rb +632 -482
  19. data/lib/solargraph/complex_type.rb +549 -444
  20. data/lib/solargraph/convention/data_definition/data_definition_node.rb +93 -91
  21. data/lib/solargraph/convention/data_definition.rb +108 -105
  22. data/lib/solargraph/convention/struct_definition/struct_assignment_node.rb +62 -61
  23. data/lib/solargraph/convention/struct_definition/struct_definition_node.rb +103 -102
  24. data/lib/solargraph/convention/struct_definition.rb +168 -164
  25. data/lib/solargraph/diagnostics/require_not_found.rb +54 -53
  26. data/lib/solargraph/diagnostics/rubocop.rb +119 -118
  27. data/lib/solargraph/diagnostics/rubocop_helpers.rb +70 -68
  28. data/lib/solargraph/diagnostics/type_check.rb +56 -55
  29. data/lib/solargraph/doc_map.rb +200 -439
  30. data/lib/solargraph/equality.rb +34 -34
  31. data/lib/solargraph/gem_pins.rb +97 -98
  32. data/lib/solargraph/language_server/host/dispatch.rb +131 -130
  33. data/lib/solargraph/language_server/host/message_worker.rb +113 -112
  34. data/lib/solargraph/language_server/host/sources.rb +100 -99
  35. data/lib/solargraph/language_server/host.rb +883 -878
  36. data/lib/solargraph/language_server/message/extended/check_gem_version.rb +109 -114
  37. data/lib/solargraph/language_server/message/extended/document.rb +24 -23
  38. data/lib/solargraph/language_server/message/text_document/completion.rb +58 -56
  39. data/lib/solargraph/language_server/message/text_document/definition.rb +42 -40
  40. data/lib/solargraph/language_server/message/text_document/document_symbol.rb +28 -26
  41. data/lib/solargraph/language_server/message/text_document/formatting.rb +150 -148
  42. data/lib/solargraph/language_server/message/text_document/hover.rb +60 -58
  43. data/lib/solargraph/language_server/message/text_document/signature_help.rb +25 -24
  44. data/lib/solargraph/language_server/message/text_document/type_definition.rb +27 -25
  45. data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +25 -23
  46. data/lib/solargraph/library.rb +729 -683
  47. data/lib/solargraph/location.rb +87 -82
  48. data/lib/solargraph/logging.rb +57 -37
  49. data/lib/solargraph/parser/comment_ripper.rb +76 -69
  50. data/lib/solargraph/parser/flow_sensitive_typing.rb +483 -255
  51. data/lib/solargraph/parser/node_processor/base.rb +122 -92
  52. data/lib/solargraph/parser/node_processor.rb +63 -62
  53. data/lib/solargraph/parser/parser_gem/class_methods.rb +167 -149
  54. data/lib/solargraph/parser/parser_gem/node_chainer.rb +191 -166
  55. data/lib/solargraph/parser/parser_gem/node_methods.rb +506 -486
  56. data/lib/solargraph/parser/parser_gem/node_processors/and_node.rb +22 -22
  57. data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +61 -59
  58. data/lib/solargraph/parser/parser_gem/node_processors/begin_node.rb +24 -15
  59. data/lib/solargraph/parser/parser_gem/node_processors/block_node.rb +46 -46
  60. data/lib/solargraph/parser/parser_gem/node_processors/def_node.rb +60 -53
  61. data/lib/solargraph/parser/parser_gem/node_processors/if_node.rb +53 -23
  62. data/lib/solargraph/parser/parser_gem/node_processors/ivasgn_node.rb +41 -40
  63. data/lib/solargraph/parser/parser_gem/node_processors/lvasgn_node.rb +30 -29
  64. data/lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb +61 -59
  65. data/lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb +98 -98
  66. data/lib/solargraph/parser/parser_gem/node_processors/or_node.rb +22 -0
  67. data/lib/solargraph/parser/parser_gem/node_processors/orasgn_node.rb +17 -17
  68. data/lib/solargraph/parser/parser_gem/node_processors/resbody_node.rb +39 -38
  69. data/lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb +53 -52
  70. data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +296 -291
  71. data/lib/solargraph/parser/parser_gem/node_processors/when_node.rb +23 -0
  72. data/lib/solargraph/parser/parser_gem/node_processors/while_node.rb +33 -29
  73. data/lib/solargraph/parser/parser_gem/node_processors.rb +74 -70
  74. data/lib/solargraph/parser/region.rb +75 -69
  75. data/lib/solargraph/parser/snippet.rb +17 -17
  76. data/lib/solargraph/pin/base.rb +761 -729
  77. data/lib/solargraph/pin/base_variable.rb +418 -126
  78. data/lib/solargraph/pin/block.rb +126 -104
  79. data/lib/solargraph/pin/breakable.rb +13 -9
  80. data/lib/solargraph/pin/callable.rb +278 -231
  81. data/lib/solargraph/pin/closure.rb +68 -72
  82. data/lib/solargraph/pin/common.rb +94 -79
  83. data/lib/solargraph/pin/compound_statement.rb +55 -0
  84. data/lib/solargraph/pin/conversions.rb +124 -123
  85. data/lib/solargraph/pin/delegated_method.rb +131 -120
  86. data/lib/solargraph/pin/documenting.rb +115 -114
  87. data/lib/solargraph/pin/instance_variable.rb +38 -34
  88. data/lib/solargraph/pin/keyword.rb +16 -20
  89. data/lib/solargraph/pin/local_variable.rb +31 -75
  90. data/lib/solargraph/pin/method.rb +720 -672
  91. data/lib/solargraph/pin/method_alias.rb +42 -34
  92. data/lib/solargraph/pin/namespace.rb +121 -115
  93. data/lib/solargraph/pin/parameter.rb +338 -275
  94. data/lib/solargraph/pin/proxy_type.rb +40 -39
  95. data/lib/solargraph/pin/reference/override.rb +47 -47
  96. data/lib/solargraph/pin/reference/superclass.rb +17 -15
  97. data/lib/solargraph/pin/reference.rb +41 -39
  98. data/lib/solargraph/pin/search.rb +62 -61
  99. data/lib/solargraph/pin/signature.rb +69 -61
  100. data/lib/solargraph/pin/symbol.rb +53 -53
  101. data/lib/solargraph/pin/until.rb +18 -18
  102. data/lib/solargraph/pin/while.rb +18 -18
  103. data/lib/solargraph/pin.rb +46 -44
  104. data/lib/solargraph/pin_cache.rb +665 -245
  105. data/lib/solargraph/position.rb +118 -119
  106. data/lib/solargraph/range.rb +112 -112
  107. data/lib/solargraph/rbs_map/conversions.rb +846 -823
  108. data/lib/solargraph/rbs_map/core_map.rb +65 -58
  109. data/lib/solargraph/rbs_map/stdlib_map.rb +72 -43
  110. data/lib/solargraph/rbs_map.rb +217 -163
  111. data/lib/solargraph/shell.rb +397 -352
  112. data/lib/solargraph/source/chain/call.rb +372 -337
  113. data/lib/solargraph/source/chain/constant.rb +28 -26
  114. data/lib/solargraph/source/chain/hash.rb +35 -34
  115. data/lib/solargraph/source/chain/if.rb +29 -28
  116. data/lib/solargraph/source/chain/instance_variable.rb +34 -13
  117. data/lib/solargraph/source/chain/literal.rb +53 -48
  118. data/lib/solargraph/source/chain/or.rb +31 -23
  119. data/lib/solargraph/source/chain.rb +294 -291
  120. data/lib/solargraph/source/change.rb +89 -82
  121. data/lib/solargraph/source/cursor.rb +172 -166
  122. data/lib/solargraph/source/source_chainer.rb +204 -194
  123. data/lib/solargraph/source/updater.rb +59 -55
  124. data/lib/solargraph/source.rb +524 -498
  125. data/lib/solargraph/source_map/clip.rb +237 -226
  126. data/lib/solargraph/source_map/data.rb +37 -34
  127. data/lib/solargraph/source_map/mapper.rb +282 -259
  128. data/lib/solargraph/source_map.rb +220 -212
  129. data/lib/solargraph/type_checker/problem.rb +34 -32
  130. data/lib/solargraph/type_checker/rules.rb +157 -84
  131. data/lib/solargraph/type_checker.rb +895 -814
  132. data/lib/solargraph/version.rb +1 -1
  133. data/lib/solargraph/workspace/config.rb +257 -255
  134. data/lib/solargraph/workspace/gemspecs.rb +367 -0
  135. data/lib/solargraph/workspace/require_paths.rb +98 -97
  136. data/lib/solargraph/workspace.rb +362 -220
  137. data/lib/solargraph/yard_map/helpers.rb +45 -44
  138. data/lib/solargraph/yard_map/mapper/to_method.rb +134 -130
  139. data/lib/solargraph/yard_map/mapper/to_namespace.rb +32 -31
  140. data/lib/solargraph/yard_map/mapper.rb +84 -79
  141. data/lib/solargraph/yardoc.rb +97 -87
  142. data/lib/solargraph.rb +126 -105
  143. data/rbs/fills/rubygems/0/dependency.rbs +193 -0
  144. data/rbs/fills/tuple/tuple.rbs +28 -0
  145. data/rbs/shims/ast/0/node.rbs +5 -0
  146. data/rbs/shims/diff-lcs/1.5/diff-lcs.rbs +11 -0
  147. data/rbs_collection.yaml +1 -1
  148. data/solargraph.gemspec +2 -1
  149. metadata +22 -17
  150. data/lib/solargraph/type_checker/checks.rb +0 -124
  151. data/lib/solargraph/type_checker/param_def.rb +0 -37
  152. data/lib/solargraph/yard_map/to_method.rb +0 -89
  153. data/sig/shims/ast/0/node.rbs +0 -5
  154. /data/{sig → rbs}/shims/ast/2.4/.rbs_meta.yaml +0 -0
  155. /data/{sig → rbs}/shims/ast/2.4/ast.rbs +0 -0
  156. /data/{sig → rbs}/shims/parser/3.2.0.1/builders/default.rbs +0 -0
  157. /data/{sig → rbs}/shims/parser/3.2.0.1/manifest.yaml +0 -0
  158. /data/{sig → rbs}/shims/parser/3.2.0.1/parser.rbs +0 -0
  159. /data/{sig → rbs}/shims/parser/3.2.0.1/polyfill.rbs +0 -0
  160. /data/{sig → rbs}/shims/thor/1.2.0.1/.rbs_meta.yaml +0 -0
  161. /data/{sig → rbs}/shims/thor/1.2.0.1/manifest.yaml +0 -0
  162. /data/{sig → rbs}/shims/thor/1.2.0.1/thor.rbs +0 -0
@@ -1,291 +1,296 @@
1
- # frozen_string_literal: true
2
-
3
- module Solargraph
4
- module Parser
5
- module ParserGem
6
- module NodeProcessors
7
- class SendNode < Parser::NodeProcessor::Base
8
- include ParserGem::NodeMethods
9
-
10
- def process
11
- # @sg-ignore Variable type could not be inferred for method_name
12
- # @type [Symbol]
13
- method_name = node.children[1]
14
- # :nocov:
15
- unless method_name.instance_of?(Symbol)
16
- Solargraph.assert_or_log(:parser_method_name, "Expected method name to be a Symbol, got #{method_name.class} for node #{node.inspect}")
17
- return process_children
18
- end
19
- # :nocov:
20
- if node.children[0].nil?
21
- if [:private, :public, :protected].include?(method_name)
22
- process_visibility
23
- elsif method_name == :module_function
24
- process_module_function
25
- elsif [:attr_reader, :attr_writer, :attr_accessor].include?(method_name)
26
- process_attribute
27
- elsif method_name == :include
28
- process_include
29
- elsif method_name == :extend
30
- process_extend
31
- elsif method_name == :prepend
32
- process_prepend
33
- elsif method_name == :require
34
- process_require
35
- elsif method_name == :autoload
36
- process_autoload
37
- elsif method_name == :private_constant
38
- process_private_constant
39
- elsif method_name == :alias_method && node.children[2] && node.children[2] && node.children[2].type == :sym && node.children[3] && node.children[3].type == :sym
40
- process_alias_method
41
- elsif method_name == :private_class_method && node.children[2].is_a?(AST::Node)
42
- # Processing a private class can potentially handle children on its own
43
- return if process_private_class_method
44
- end
45
- elsif method_name == :require && node.children[0].to_s == '(const nil :Bundler)'
46
- pins.push Pin::Reference::Require.new(Solargraph::Location.new(region.filename, Solargraph::Range.from_to(0, 0, 0, 0)), 'bundler/require', source: :parser)
47
- end
48
- process_children
49
- end
50
-
51
- private
52
-
53
- # @return [void]
54
- def process_visibility
55
- if (node.children.length > 2)
56
- node.children[2..-1].each do |child|
57
- # @sg-ignore Variable type could not be inferred for method_name
58
- # @type [Symbol]
59
- visibility = node.children[1]
60
- # :nocov:
61
- unless visibility.instance_of?(Symbol)
62
- Solargraph.assert_or_log(:parser_visibility, "Expected visibility name to be a Symbol, got #{visibility.class} for node #{node.inspect}")
63
- return process_children
64
- end
65
- # :nocov:
66
- if child.is_a?(::Parser::AST::Node) && (child.type == :sym || child.type == :str)
67
- name = child.children[0].to_s
68
- matches = pins.select{ |pin| pin.is_a?(Pin::Method) && pin.name == name && pin.namespace == region.closure.full_context.namespace && pin.context.scope == (region.scope || :instance)}
69
- matches.each do |pin|
70
- # @todo Smelly instance variable access
71
- pin.instance_variable_set(:@visibility, visibility)
72
- end
73
- else
74
- process_children region.update(visibility: visibility)
75
- end
76
- end
77
- else
78
- # @todo Smelly instance variable access
79
- region.instance_variable_set(:@visibility, node.children[1])
80
- end
81
- end
82
-
83
- # @return [void]
84
- def process_attribute
85
- node.children[2..-1].each do |a|
86
- loc = get_node_location(node)
87
- clos = region.closure
88
- cmnt = comments_for(node)
89
- if node.children[1] == :attr_reader || node.children[1] == :attr_accessor
90
- pins.push Solargraph::Pin::Method.new(
91
- location: loc,
92
- closure: clos,
93
- name: a.children[0].to_s,
94
- comments: cmnt,
95
- scope: region.scope || :instance,
96
- visibility: region.visibility,
97
- attribute: true,
98
- source: :parser
99
- )
100
- end
101
- if node.children[1] == :attr_writer || node.children[1] == :attr_accessor
102
- method_pin = Solargraph::Pin::Method.new(
103
- location: loc,
104
- closure: clos,
105
- name: "#{a.children[0]}=",
106
- comments: cmnt,
107
- scope: region.scope || :instance,
108
- visibility: region.visibility,
109
- attribute: true,
110
- source: :parser
111
- )
112
- pins.push method_pin
113
- method_pin.parameters.push Pin::Parameter.new(name: 'value', decl: :arg, closure: pins.last, source: :parser)
114
- if method_pin.return_type.defined?
115
- pins.last.docstring.add_tag YARD::Tags::Tag.new(:param, '', pins.last.return_type.items.map(&:rooted_tags), 'value')
116
- end
117
- end
118
- end
119
- end
120
-
121
- # @return [void]
122
- def process_include
123
- if node.children[2].is_a?(AST::Node) && node.children[2].type == :const
124
- cp = region.closure
125
- node.children[2..-1].each do |i|
126
- type = region.scope == :class ? Pin::Reference::Extend : Pin::Reference::Include
127
- pins.push type.new(
128
- location: get_node_location(i),
129
- closure: cp,
130
- name: unpack_name(i),
131
- source: :parser
132
- )
133
- end
134
- end
135
- end
136
-
137
- # @return [void]
138
- def process_prepend
139
- if node.children[2].is_a?(AST::Node) && node.children[2].type == :const
140
- cp = region.closure
141
- node.children[2..-1].each do |i|
142
- pins.push Pin::Reference::Prepend.new(
143
- location: get_node_location(i),
144
- closure: cp,
145
- name: unpack_name(i),
146
- source: :parser
147
- )
148
- end
149
- end
150
- end
151
-
152
- # @return [void]
153
- def process_extend
154
- node.children[2..-1].each do |i|
155
- loc = get_node_location(node)
156
- if i.type == :self
157
- pins.push Pin::Reference::Extend.new(
158
- location: loc,
159
- closure: region.closure,
160
- name: region.closure.full_context.namespace,
161
- source: :parser
162
- )
163
- else
164
- pins.push Pin::Reference::Extend.new(
165
- location: loc,
166
- closure: region.closure,
167
- name: unpack_name(i),
168
- source: :parser
169
- )
170
- end
171
- end
172
- end
173
-
174
- # @return [void]
175
- def process_require
176
- if node.children[2].is_a?(AST::Node) && node.children[2].type == :str
177
- path = node.children[2].children[0].to_s
178
- pins.push Pin::Reference::Require.new(get_node_location(node), path, source: :parser)
179
- end
180
- end
181
-
182
- # @return [void]
183
- def process_autoload
184
- if node.children[3].is_a?(AST::Node) && node.children[3].type == :str
185
- path = node.children[3].children[0].to_s
186
- pins.push Pin::Reference::Require.new(get_node_location(node), path, source: :parser)
187
- end
188
- end
189
-
190
- # @return [void]
191
- def process_module_function
192
- if node.children[2].nil?
193
- # @todo Smelly instance variable access
194
- region.instance_variable_set(:@visibility, :module_function)
195
- elsif node.children[2].type == :sym || node.children[2].type == :str
196
- node.children[2..-1].each do |x|
197
- cn = x.children[0].to_s
198
- # @type [Pin::Method, nil]
199
- ref = pins.find { |p| p.is_a?(Pin::Method) && p.namespace == region.closure.full_context.namespace && p.name == cn }
200
- unless ref.nil?
201
- pins.delete ref
202
- mm = Solargraph::Pin::Method.new(
203
- location: ref.location,
204
- closure: ref.closure,
205
- name: ref.name,
206
- parameters: ref.parameters,
207
- comments: ref.comments,
208
- scope: :class,
209
- visibility: :public,
210
- node: ref.node,
211
- source: :parser
212
- )
213
- cm = Solargraph::Pin::Method.new(
214
- location: ref.location,
215
- closure: ref.closure,
216
- name: ref.name,
217
- parameters: ref.parameters,
218
- comments: ref.comments,
219
- scope: :instance,
220
- visibility: :private,
221
- node: ref.node,
222
- source: :parser)
223
- pins.push mm, cm
224
- pins.select{|pin| pin.is_a?(Pin::InstanceVariable) && pin.closure.path == ref.path}.each do |ivar|
225
- pins.delete ivar
226
- pins.push Solargraph::Pin::InstanceVariable.new(
227
- location: ivar.location,
228
- closure: cm,
229
- name: ivar.name,
230
- comments: ivar.comments,
231
- # @sg-ignore https://github.com/castwide/solargraph/pull/1114
232
- assignment: ivar.assignment,
233
- source: :parser
234
- )
235
- pins.push Solargraph::Pin::InstanceVariable.new(
236
- location: ivar.location,
237
- closure: mm,
238
- name: ivar.name,
239
- comments: ivar.comments,
240
- # @sg-ignore https://github.com/castwide/solargraph/pull/1114
241
- assignment: ivar.assignment,
242
- source: :parser
243
- )
244
- end
245
- end
246
- end
247
- elsif node.children[2].type == :def
248
- NodeProcessor.process node.children[2], region.update(visibility: :module_function), pins, locals
249
- end
250
- end
251
-
252
- # @return [void]
253
- def process_private_constant
254
- if node.children[2] && (node.children[2].type == :sym || node.children[2].type == :str)
255
- cn = node.children[2].children[0].to_s
256
- ref = pins.select{|p| [Solargraph::Pin::Namespace, Solargraph::Pin::Constant].include?(p.class) && p.namespace == region.closure.full_context.namespace && p.name == cn}.first
257
- # HACK: Smelly instance variable access
258
- ref.instance_variable_set(:@visibility, :private) unless ref.nil?
259
- end
260
- end
261
-
262
- # @return [void]
263
- def process_alias_method
264
- loc = get_node_location(node)
265
- pins.push Solargraph::Pin::MethodAlias.new(
266
- location: get_node_location(node),
267
- closure: region.closure,
268
- name: node.children[2].children[0].to_s,
269
- original: node.children[3].children[0].to_s,
270
- scope: region.scope || :instance,
271
- source: :parser
272
- )
273
- end
274
-
275
- # @return [Boolean]
276
- def process_private_class_method
277
- if node.children[2].type == :sym || node.children[2].type == :str
278
- ref = pins.select { |p| p.is_a?(Pin::Method) && p.namespace == region.closure.full_context.namespace && p.name == node.children[2].children[0].to_s }.first
279
- # HACK: Smelly instance variable access
280
- ref.instance_variable_set(:@visibility, :private) unless ref.nil?
281
- false
282
- else
283
- process_children region.update(scope: :class, visibility: :private)
284
- true
285
- end
286
- end
287
- end
288
- end
289
- end
290
- end
291
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ module Parser
5
+ module ParserGem
6
+ module NodeProcessors
7
+ class SendNode < Parser::NodeProcessor::Base
8
+ include ParserGem::NodeMethods
9
+
10
+ # @sg-ignore @override is adding, not overriding
11
+ def process
12
+ # @sg-ignore Variable type could not be inferred for method_name
13
+ # @type [Symbol]
14
+ method_name = node.children[1]
15
+ # :nocov:
16
+ unless method_name.instance_of?(Symbol)
17
+ Solargraph.assert_or_log(:parser_method_name, "Expected method name to be a Symbol, got #{method_name.class} for node #{node.inspect}")
18
+ return process_children
19
+ end
20
+ # :nocov:
21
+ if node.children[0].nil?
22
+ if [:private, :public, :protected].include?(method_name)
23
+ process_visibility
24
+ elsif method_name == :module_function
25
+ process_module_function
26
+ elsif [:attr_reader, :attr_writer, :attr_accessor].include?(method_name)
27
+ process_attribute
28
+ elsif method_name == :include
29
+ process_include
30
+ elsif method_name == :extend
31
+ process_extend
32
+ elsif method_name == :prepend
33
+ process_prepend
34
+ elsif method_name == :require
35
+ process_require
36
+ elsif method_name == :autoload
37
+ process_autoload
38
+ elsif method_name == :private_constant
39
+ process_private_constant
40
+ elsif method_name == :alias_method && node.children[2] && node.children[2] && node.children[2].type == :sym && node.children[3] && node.children[3].type == :sym
41
+ process_alias_method
42
+ elsif method_name == :private_class_method && node.children[2].is_a?(AST::Node)
43
+ # Processing a private class can potentially handle children on its own
44
+ return if process_private_class_method
45
+ end
46
+ elsif method_name == :require && node.children[0].to_s == '(const nil :Bundler)'
47
+ pins.push Pin::Reference::Require.new(Solargraph::Location.new(region.filename, Solargraph::Range.from_to(0, 0, 0, 0)), 'bundler/require', source: :parser)
48
+ end
49
+ process_children
50
+ end
51
+
52
+ private
53
+
54
+ # @return [void]
55
+ def process_visibility
56
+ if (node.children.length > 2)
57
+ # @sg-ignore Need to add nil check here
58
+ node.children[2..-1].each do |child|
59
+ # @sg-ignore Variable type could not be inferred for method_name
60
+ # @type [Symbol]
61
+ visibility = node.children[1]
62
+ # :nocov:
63
+ unless visibility.instance_of?(Symbol)
64
+ Solargraph.assert_or_log(:parser_visibility, "Expected visibility name to be a Symbol, got #{visibility.class} for node #{node.inspect}")
65
+ return process_children
66
+ end
67
+ # :nocov:
68
+ if child.is_a?(::Parser::AST::Node) && (child.type == :sym || child.type == :str)
69
+ name = child.children[0].to_s
70
+ matches = pins.select{ |pin| pin.is_a?(Pin::Method) && pin.name == name && pin.namespace == region.closure.full_context.namespace && pin.context.scope == (region.scope || :instance)}
71
+ matches.each do |pin|
72
+ # @todo Smelly instance variable access
73
+ pin.instance_variable_set(:@visibility, visibility)
74
+ end
75
+ else
76
+ process_children region.update(visibility: visibility)
77
+ end
78
+ end
79
+ else
80
+ # @todo Smelly instance variable access
81
+ region.instance_variable_set(:@visibility, node.children[1])
82
+ end
83
+ end
84
+
85
+ # @return [void]
86
+ def process_attribute
87
+ # @sg-ignore Need to add nil check here
88
+ node.children[2..-1].each do |a|
89
+ loc = get_node_location(node)
90
+ clos = region.closure
91
+ cmnt = comments_for(node)
92
+ if node.children[1] == :attr_reader || node.children[1] == :attr_accessor
93
+ pins.push Solargraph::Pin::Method.new(
94
+ location: loc,
95
+ closure: clos,
96
+ name: a.children[0].to_s,
97
+ comments: cmnt,
98
+ scope: region.scope || :instance,
99
+ visibility: region.visibility,
100
+ attribute: true,
101
+ source: :parser
102
+ )
103
+ end
104
+ if node.children[1] == :attr_writer || node.children[1] == :attr_accessor
105
+ method_pin = Solargraph::Pin::Method.new(
106
+ location: loc,
107
+ closure: clos,
108
+ name: "#{a.children[0]}=",
109
+ comments: cmnt,
110
+ scope: region.scope || :instance,
111
+ visibility: region.visibility,
112
+ attribute: true,
113
+ source: :parser
114
+ )
115
+ pins.push method_pin
116
+ method_pin.parameters.push Pin::Parameter.new(name: 'value', decl: :arg, closure: pins.last, source: :parser)
117
+ if method_pin.return_type.defined?
118
+ pins.last.docstring.add_tag YARD::Tags::Tag.new(:param, '', pins.last.return_type.items.map(&:rooted_tags), 'value')
119
+ end
120
+ end
121
+ end
122
+ end
123
+
124
+ # @return [void]
125
+ def process_include
126
+ if node.children[2].is_a?(AST::Node) && node.children[2].type == :const
127
+ cp = region.closure
128
+ # @sg-ignore Need to add nil check here
129
+ node.children[2..-1].each do |i|
130
+ type = region.scope == :class ? Pin::Reference::Extend : Pin::Reference::Include
131
+ pins.push type.new(
132
+ location: get_node_location(i),
133
+ closure: cp,
134
+ name: unpack_name(i),
135
+ source: :parser
136
+ )
137
+ end
138
+ end
139
+ end
140
+
141
+ # @return [void]
142
+ def process_prepend
143
+ if node.children[2].is_a?(AST::Node) && node.children[2].type == :const
144
+ cp = region.closure
145
+ # @sg-ignore Need to add nil check here
146
+ node.children[2..-1].each do |i|
147
+ pins.push Pin::Reference::Prepend.new(
148
+ location: get_node_location(i),
149
+ closure: cp,
150
+ name: unpack_name(i),
151
+ source: :parser
152
+ )
153
+ end
154
+ end
155
+ end
156
+
157
+ # @return [void]
158
+ def process_extend
159
+ # @sg-ignore Need to add nil check here
160
+ node.children[2..-1].each do |i|
161
+ loc = get_node_location(node)
162
+ if i.type == :self
163
+ pins.push Pin::Reference::Extend.new(
164
+ location: loc,
165
+ closure: region.closure,
166
+ name: region.closure.full_context.namespace,
167
+ source: :parser
168
+ )
169
+ else
170
+ pins.push Pin::Reference::Extend.new(
171
+ location: loc,
172
+ closure: region.closure,
173
+ name: unpack_name(i),
174
+ source: :parser
175
+ )
176
+ end
177
+ end
178
+ end
179
+
180
+ # @return [void]
181
+ def process_require
182
+ if node.children[2].is_a?(AST::Node) && node.children[2].type == :str
183
+ path = node.children[2].children[0].to_s
184
+ pins.push Pin::Reference::Require.new(get_node_location(node), path, source: :parser)
185
+ end
186
+ end
187
+
188
+ # @return [void]
189
+ def process_autoload
190
+ if node.children[3].is_a?(AST::Node) && node.children[3].type == :str
191
+ path = node.children[3].children[0].to_s
192
+ pins.push Pin::Reference::Require.new(get_node_location(node), path, source: :parser)
193
+ end
194
+ end
195
+
196
+ # @return [void]
197
+ def process_module_function
198
+ if node.children[2].nil?
199
+ # @todo Smelly instance variable access
200
+ region.instance_variable_set(:@visibility, :module_function)
201
+ elsif node.children[2].type == :sym || node.children[2].type == :str
202
+ # @sg-ignore Need to add nil check here
203
+ node.children[2..-1].each do |x|
204
+ cn = x.children[0].to_s
205
+ # @type [Pin::Method, nil]
206
+ ref = pins.find { |p| p.is_a?(Pin::Method) && p.namespace == region.closure.full_context.namespace && p.name == cn }
207
+ unless ref.nil?
208
+ pins.delete ref
209
+ mm = Solargraph::Pin::Method.new(
210
+ location: ref.location,
211
+ closure: ref.closure,
212
+ name: ref.name,
213
+ parameters: ref.parameters,
214
+ comments: ref.comments,
215
+ scope: :class,
216
+ visibility: :public,
217
+ node: ref.node,
218
+ source: :parser
219
+ )
220
+ cm = Solargraph::Pin::Method.new(
221
+ location: ref.location,
222
+ closure: ref.closure,
223
+ name: ref.name,
224
+ parameters: ref.parameters,
225
+ comments: ref.comments,
226
+ scope: :instance,
227
+ visibility: :private,
228
+ node: ref.node,
229
+ source: :parser)
230
+ pins.push mm, cm
231
+ ivars.select{|pin| pin.is_a?(Pin::InstanceVariable) && pin.closure.path == ref.path}.each do |ivar|
232
+ ivars.delete ivar
233
+ ivars.push Solargraph::Pin::InstanceVariable.new(
234
+ location: ivar.location,
235
+ closure: cm,
236
+ name: ivar.name,
237
+ comments: ivar.comments,
238
+ assignment: ivar.assignment,
239
+ source: :parser
240
+ )
241
+ ivars.push Solargraph::Pin::InstanceVariable.new(
242
+ location: ivar.location,
243
+ closure: mm,
244
+ name: ivar.name,
245
+ comments: ivar.comments,
246
+ assignment: ivar.assignment,
247
+ source: :parser
248
+ )
249
+ end
250
+ end
251
+ end
252
+ elsif node.children[2].type == :def
253
+ NodeProcessor.process node.children[2], region.update(visibility: :module_function), pins, locals, ivars
254
+ end
255
+ end
256
+
257
+ # @return [void]
258
+ def process_private_constant
259
+ if node.children[2] && (node.children[2].type == :sym || node.children[2].type == :str)
260
+ cn = node.children[2].children[0].to_s
261
+ ref = pins.select{|p| [Solargraph::Pin::Namespace, Solargraph::Pin::Constant].include?(p.class) && p.namespace == region.closure.full_context.namespace && p.name == cn}.first
262
+ # HACK: Smelly instance variable access
263
+ ref.instance_variable_set(:@visibility, :private) unless ref.nil?
264
+ end
265
+ end
266
+
267
+ # @return [void]
268
+ def process_alias_method
269
+ loc = get_node_location(node)
270
+ pins.push Solargraph::Pin::MethodAlias.new(
271
+ location: get_node_location(node),
272
+ closure: region.closure,
273
+ name: node.children[2].children[0].to_s,
274
+ original: node.children[3].children[0].to_s,
275
+ scope: region.scope || :instance,
276
+ source: :parser
277
+ )
278
+ end
279
+
280
+ # @return [Boolean]
281
+ def process_private_class_method
282
+ if node.children[2].type == :sym || node.children[2].type == :str
283
+ ref = pins.select { |p| p.is_a?(Pin::Method) && p.namespace == region.closure.full_context.namespace && p.name == node.children[2].children[0].to_s }.first
284
+ # HACK: Smelly instance variable access
285
+ ref.instance_variable_set(:@visibility, :private) unless ref.nil?
286
+ false
287
+ else
288
+ process_children region.update(scope: :class, visibility: :private)
289
+ true
290
+ end
291
+ end
292
+ end
293
+ end
294
+ end
295
+ end
296
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ module Parser
5
+ module ParserGem
6
+ module NodeProcessors
7
+ class WhenNode < Parser::NodeProcessor::Base
8
+ include ParserGem::NodeMethods
9
+
10
+ def process
11
+ pins.push Solargraph::Pin::CompoundStatement.new(
12
+ location: get_node_location(node),
13
+ closure: region.closure,
14
+ node: node,
15
+ source: :parser,
16
+ )
17
+ process_children
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end