solargraph 0.52.0 → 0.53.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 (155) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/plugins.yml +40 -0
  3. data/.github/workflows/rspec.yml +1 -3
  4. data/.github/workflows/typecheck.yml +34 -0
  5. data/CHANGELOG.md +30 -0
  6. data/README.md +13 -16
  7. data/SPONSORS.md +1 -7
  8. data/lib/solargraph/api_map/cache.rb +59 -21
  9. data/lib/solargraph/api_map/store.rb +45 -9
  10. data/lib/solargraph/api_map.rb +152 -93
  11. data/lib/solargraph/bench.rb +2 -2
  12. data/lib/solargraph/cache.rb +29 -5
  13. data/lib/solargraph/complex_type/type_methods.rb +53 -8
  14. data/lib/solargraph/complex_type/unique_type.rb +149 -59
  15. data/lib/solargraph/complex_type.rb +62 -9
  16. data/lib/solargraph/convention.rb +0 -1
  17. data/lib/solargraph/converters/dd.rb +5 -0
  18. data/lib/solargraph/converters/dl.rb +3 -0
  19. data/lib/solargraph/converters/dt.rb +3 -0
  20. data/lib/solargraph/diagnostics/rubocop.rb +8 -7
  21. data/lib/solargraph/diagnostics/rubocop_helpers.rb +1 -0
  22. data/lib/solargraph/diagnostics/type_check.rb +1 -0
  23. data/lib/solargraph/diagnostics.rb +2 -2
  24. data/lib/solargraph/doc_map.rb +146 -0
  25. data/lib/solargraph/gem_pins.rb +64 -0
  26. data/lib/solargraph/language_server/host/cataloger.rb +1 -0
  27. data/lib/solargraph/language_server/host/diagnoser.rb +2 -2
  28. data/lib/solargraph/language_server/host/dispatch.rb +10 -4
  29. data/lib/solargraph/language_server/host/message_worker.rb +4 -0
  30. data/lib/solargraph/language_server/host/sources.rb +7 -4
  31. data/lib/solargraph/language_server/host.rb +15 -6
  32. data/lib/solargraph/language_server/message/completion_item/resolve.rb +3 -1
  33. data/lib/solargraph/language_server/message/extended/check_gem_version.rb +13 -1
  34. data/lib/solargraph/language_server/message/initialize.rb +5 -2
  35. data/lib/solargraph/language_server/message/text_document/hover.rb +2 -0
  36. data/lib/solargraph/language_server/message/text_document.rb +0 -1
  37. data/lib/solargraph/language_server/message/workspace/did_change_configuration.rb +5 -0
  38. data/lib/solargraph/language_server/transport/adapter.rb +16 -1
  39. data/lib/solargraph/language_server/transport/data_reader.rb +2 -0
  40. data/lib/solargraph/library.rb +58 -11
  41. data/lib/solargraph/location.rb +1 -0
  42. data/lib/solargraph/parser/comment_ripper.rb +3 -0
  43. data/lib/solargraph/parser/node_methods.rb +47 -8
  44. data/lib/solargraph/parser/node_processor/base.rb +9 -0
  45. data/lib/solargraph/parser/{legacy → parser_gem}/class_methods.rb +29 -3
  46. data/lib/solargraph/parser/{legacy → parser_gem}/flawed_builder.rb +3 -1
  47. data/lib/solargraph/parser/{legacy → parser_gem}/node_chainer.rb +42 -34
  48. data/lib/solargraph/parser/{legacy → parser_gem}/node_methods.rb +201 -29
  49. data/lib/solargraph/parser/{rubyvm → parser_gem}/node_processors/alias_node.rb +1 -1
  50. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/args_node.rb +4 -1
  51. data/lib/solargraph/parser/{rubyvm → parser_gem}/node_processors/begin_node.rb +1 -1
  52. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/block_node.rb +3 -2
  53. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/casgn_node.rb +2 -2
  54. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/cvasgn_node.rb +1 -1
  55. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/def_node.rb +1 -1
  56. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/defs_node.rb +2 -2
  57. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/gvasgn_node.rb +1 -1
  58. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/ivasgn_node.rb +2 -2
  59. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/lvasgn_node.rb +2 -2
  60. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/namespace_node.rb +2 -2
  61. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/orasgn_node.rb +1 -1
  62. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/resbody_node.rb +3 -3
  63. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/sclass_node.rb +1 -1
  64. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/send_node.rb +2 -2
  65. data/lib/solargraph/parser/{rubyvm → parser_gem}/node_processors/sym_node.rb +1 -1
  66. data/lib/solargraph/parser/parser_gem/node_processors.rb +54 -0
  67. data/lib/solargraph/parser/parser_gem.rb +12 -0
  68. data/lib/solargraph/parser/snippet.rb +2 -0
  69. data/lib/solargraph/parser.rb +8 -11
  70. data/lib/solargraph/pin/base.rb +63 -8
  71. data/lib/solargraph/pin/base_variable.rb +6 -2
  72. data/lib/solargraph/pin/block.rb +11 -6
  73. data/lib/solargraph/pin/closure.rb +17 -2
  74. data/lib/solargraph/pin/common.rb +7 -3
  75. data/lib/solargraph/pin/conversions.rb +33 -3
  76. data/lib/solargraph/pin/documenting.rb +25 -34
  77. data/lib/solargraph/pin/instance_variable.rb +4 -0
  78. data/lib/solargraph/pin/local_variable.rb +13 -1
  79. data/lib/solargraph/pin/method.rb +109 -15
  80. data/lib/solargraph/pin/namespace.rb +16 -10
  81. data/lib/solargraph/pin/parameter.rb +41 -10
  82. data/lib/solargraph/pin/reference/override.rb +2 -2
  83. data/lib/solargraph/pin/reference.rb +8 -0
  84. data/lib/solargraph/pin/search.rb +3 -3
  85. data/lib/solargraph/pin/signature.rb +114 -2
  86. data/lib/solargraph/pin.rb +0 -1
  87. data/lib/solargraph/range.rb +2 -2
  88. data/lib/solargraph/rbs_map/conversions.rb +212 -25
  89. data/lib/solargraph/rbs_map/core_fills.rb +4 -26
  90. data/lib/solargraph/rbs_map/core_map.rb +1 -0
  91. data/lib/solargraph/rbs_map/core_signs.rb +2 -0
  92. data/lib/solargraph/rbs_map/stdlib_map.rb +2 -8
  93. data/lib/solargraph/rbs_map.rb +19 -9
  94. data/lib/solargraph/shell.rb +62 -59
  95. data/lib/solargraph/source/chain/array.rb +4 -1
  96. data/lib/solargraph/source/chain/block_symbol.rb +13 -0
  97. data/lib/solargraph/source/chain/call.rb +95 -26
  98. data/lib/solargraph/source/chain/constant.rb +15 -1
  99. data/lib/solargraph/source/chain/if.rb +23 -0
  100. data/lib/solargraph/source/chain/link.rb +7 -1
  101. data/lib/solargraph/source/chain/or.rb +1 -1
  102. data/lib/solargraph/source/chain/z_super.rb +2 -2
  103. data/lib/solargraph/source/chain.rb +20 -4
  104. data/lib/solargraph/source/change.rb +3 -0
  105. data/lib/solargraph/source/cursor.rb +2 -0
  106. data/lib/solargraph/source/source_chainer.rb +6 -5
  107. data/lib/solargraph/source.rb +15 -16
  108. data/lib/solargraph/source_map/clip.rb +11 -7
  109. data/lib/solargraph/source_map/mapper.rb +10 -0
  110. data/lib/solargraph/source_map.rb +13 -3
  111. data/lib/solargraph/type_checker/checks.rb +10 -2
  112. data/lib/solargraph/type_checker.rb +74 -19
  113. data/lib/solargraph/version.rb +1 -1
  114. data/lib/solargraph/workspace/config.rb +8 -6
  115. data/lib/solargraph/workspace.rb +1 -1
  116. data/lib/solargraph/yard_map/cache.rb +6 -0
  117. data/lib/solargraph/yard_map/helpers.rb +1 -1
  118. data/lib/solargraph/yard_map/mapper/to_method.rb +11 -1
  119. data/lib/solargraph/yard_map/to_method.rb +11 -4
  120. data/lib/solargraph/yard_map.rb +0 -292
  121. data/lib/solargraph/yardoc.rb +52 -0
  122. data/lib/solargraph.rb +4 -1
  123. data/solargraph.gemspec +2 -2
  124. metadata +35 -57
  125. data/lib/solargraph/api_map/bundler_methods.rb +0 -22
  126. data/lib/solargraph/documentor.rb +0 -76
  127. data/lib/solargraph/parser/legacy/node_processors/alias_node.rb +0 -23
  128. data/lib/solargraph/parser/legacy/node_processors/begin_node.rb +0 -15
  129. data/lib/solargraph/parser/legacy/node_processors/sym_node.rb +0 -18
  130. data/lib/solargraph/parser/legacy/node_processors.rb +0 -55
  131. data/lib/solargraph/parser/legacy.rb +0 -12
  132. data/lib/solargraph/parser/rubyvm/class_methods.rb +0 -151
  133. data/lib/solargraph/parser/rubyvm/node_chainer.rb +0 -163
  134. data/lib/solargraph/parser/rubyvm/node_methods.rb +0 -317
  135. data/lib/solargraph/parser/rubyvm/node_processors/args_node.rb +0 -85
  136. data/lib/solargraph/parser/rubyvm/node_processors/block_node.rb +0 -42
  137. data/lib/solargraph/parser/rubyvm/node_processors/casgn_node.rb +0 -33
  138. data/lib/solargraph/parser/rubyvm/node_processors/cvasgn_node.rb +0 -23
  139. data/lib/solargraph/parser/rubyvm/node_processors/def_node.rb +0 -75
  140. data/lib/solargraph/parser/rubyvm/node_processors/defs_node.rb +0 -68
  141. data/lib/solargraph/parser/rubyvm/node_processors/gvasgn_node.rb +0 -23
  142. data/lib/solargraph/parser/rubyvm/node_processors/ivasgn_node.rb +0 -38
  143. data/lib/solargraph/parser/rubyvm/node_processors/kw_arg_node.rb +0 -39
  144. data/lib/solargraph/parser/rubyvm/node_processors/lit_node.rb +0 -20
  145. data/lib/solargraph/parser/rubyvm/node_processors/lvasgn_node.rb +0 -27
  146. data/lib/solargraph/parser/rubyvm/node_processors/namespace_node.rb +0 -39
  147. data/lib/solargraph/parser/rubyvm/node_processors/opt_arg_node.rb +0 -26
  148. data/lib/solargraph/parser/rubyvm/node_processors/orasgn_node.rb +0 -15
  149. data/lib/solargraph/parser/rubyvm/node_processors/resbody_node.rb +0 -51
  150. data/lib/solargraph/parser/rubyvm/node_processors/sclass_node.rb +0 -32
  151. data/lib/solargraph/parser/rubyvm/node_processors/scope_node.rb +0 -15
  152. data/lib/solargraph/parser/rubyvm/node_processors/send_node.rb +0 -279
  153. data/lib/solargraph/parser/rubyvm/node_processors.rb +0 -64
  154. data/lib/solargraph/parser/rubyvm/node_wrapper.rb +0 -47
  155. data/lib/solargraph/parser/rubyvm.rb +0 -40
@@ -1,10 +1,26 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'parser'
4
+ require 'ast'
4
5
 
6
+ # Teach AST::Node#children about its generic type
7
+ #
8
+ # @todo contribute back to https://github.com/ruby/gem_rbs_collection/blob/main/gems/ast/2.4/ast.rbs
9
+ #
10
+ # @!parse
11
+ # module ::AST
12
+ # class Node
13
+ # # New children
14
+ #
15
+ # # @return [Array<AST::Node>]
16
+ # attr_reader :children
17
+ # end
18
+ # end
19
+
20
+ # https://github.com/whitequark/parser
5
21
  module Solargraph
6
22
  module Parser
7
- module Legacy
23
+ module ParserGem
8
24
  module NodeMethods
9
25
  module_function
10
26
 
@@ -17,6 +33,7 @@ module Solargraph
17
33
  # @param node [Parser::AST::Node]
18
34
  # @return [Array<String>]
19
35
  def pack_name(node)
36
+ # @type [Array<String>]
20
37
  parts = []
21
38
  if node.is_a?(AST::Node)
22
39
  node.children.each { |n|
@@ -75,6 +92,10 @@ module Solargraph
75
92
  Position.new(node.loc.last_line, node.loc.last_column)
76
93
  end
77
94
 
95
+ # @param node [Parser::AST::Node]
96
+ # @param signature [String]
97
+ #
98
+ # @return [String]
78
99
  def drill_signature node, signature
79
100
  return signature unless node.is_a?(AST::Node)
80
101
  if node.type == :const or node.type == :cbase
@@ -96,6 +117,8 @@ module Solargraph
96
117
  signature
97
118
  end
98
119
 
120
+ # @param node [Parser::AST::Node]
121
+ # @return [Hash{Parser::AST::Node => Chain}]
99
122
  def convert_hash node
100
123
  return {} unless Parser.is_ast_node?(node)
101
124
  return convert_hash(node.children[0]) if node.type == :kwsplat
@@ -110,6 +133,9 @@ module Solargraph
110
133
 
111
134
  NIL_NODE = ::Parser::AST::Node.new(:nil)
112
135
 
136
+ # @param node [Parser::AST::Node]
137
+ #
138
+ # @return [Array<Parser::AST::Node>]
113
139
  def const_nodes_from node
114
140
  return [] unless Parser.is_ast_node?(node)
115
141
  result = []
@@ -121,20 +147,25 @@ module Solargraph
121
147
  result
122
148
  end
123
149
 
150
+ # @param node [Parser::AST::Node]
124
151
  def splatted_hash? node
125
152
  Parser.is_ast_node?(node.children[0]) && node.children[0].type == :kwsplat
126
153
  end
127
154
 
155
+ # @param node [Parser::AST::Node]
128
156
  def splatted_call? node
129
157
  return false unless Parser.is_ast_node?(node)
130
158
  Parser.is_ast_node?(node.children[0]) && node.children[0].type == :kwsplat && node.children[0].children[0].type != :hash
131
159
  end
132
160
 
161
+ # @param nodes [Enumerable<Parser::AST::Node>]
133
162
  def any_splatted_call?(nodes)
134
163
  nodes.any? { |n| splatted_call?(n) }
135
164
  end
136
165
 
137
166
  # @todo Temporarily here for testing. Move to Solargraph::Parser.
167
+ # @param node [Parser::AST::Node]
168
+ # @return [Array<Parser::AST::Node>]
138
169
  def call_nodes_from node
139
170
  return [] unless node.is_a?(::Parser::AST::Node)
140
171
  result = []
@@ -172,11 +203,22 @@ module Solargraph
172
203
  #
173
204
  # @param node [Parser::AST::Node]
174
205
  # @return [Array<Parser::AST::Node>]
175
- def returns_from node
176
- DeepInference.get_return_nodes(node).map { |n| n || NIL_NODE }
206
+ def returns_from_method_body node
207
+ # @todo is the || NIL_NODE necessary?
208
+ # STDERR.puts("Evaluating expression: #{node.inspect}")
209
+ DeepInference.from_method_body(node).map { |n| n || NIL_NODE }
210
+ end
211
+
212
+ # @param node [Parser::AST::Node]
213
+ # @return [Array<AST::Node>] low-level value nodes in
214
+ # value position. Does not include explicit return
215
+ # statements
216
+ def value_position_nodes_only(node)
217
+ DeepInference.value_position_nodes_only(node).map { |n| n || NIL_NODE }
177
218
  end
178
219
 
179
220
  # @param cursor [Solargraph::Source::Cursor]
221
+ # @return [Parser::AST::Node, nil]
180
222
  def find_recipient_node cursor
181
223
  return repaired_find_recipient_node(cursor) if cursor.source.repaired? && cursor.source.code[cursor.offset - 1] == '('
182
224
  source = cursor.source
@@ -211,36 +253,130 @@ module Solargraph
211
253
  nil
212
254
  end
213
255
 
256
+ # @param cursor [Solargraph::Source::Cursor]
257
+ # @return [Parser::AST::Node, nil]
214
258
  def repaired_find_recipient_node cursor
215
259
  cursor = cursor.source.cursor_at([cursor.position.line, cursor.position.column - 1])
216
260
  node = cursor.source.tree_at(cursor.position.line, cursor.position.column).first
217
261
  return node if node && node.type == :send
218
262
  end
219
263
 
264
+ #
265
+ # Concepts:
266
+ #
267
+ # - statement - one single node in the AST. Generally used
268
+ # synonymously with how the Parser gem uses the term
269
+ # 'expression'. This may have side effects (e.g.,
270
+ # registering a method in the namespace, modifying
271
+ # variables or doing I/O). It may encapsulate multiple
272
+ # other statements (see compound statement).
273
+ #
274
+ # - value - something that can be assigned to a variable by
275
+ # evaluating a statement
276
+ #
277
+ # - value node - the 'lowest level' AST node whose return
278
+ # type is a subset of the value type of the overall
279
+ # statement. Might be a literal, a method call, etc - the
280
+ # goal is to find the lowest level node, which we can use
281
+ # Chains and Pins later on to determine the type of.
282
+ #
283
+ # e.g., if the node 'b ? 123 : 456' were a return value, we
284
+ # know the actual return values possible are 123 and 456,
285
+ # and can disregard the rest.
286
+ #
287
+ # - value type - the type representing the multiple possible
288
+ # values that can result from evaluation of the statement.
289
+ #
290
+ # - return type - the type describing the values a statement
291
+ # might evaluate to. When used with a method, the term
292
+ # describes the values that may result from the method
293
+ # being called, and includes explicit return statements
294
+ # within the method body's closure.
295
+ #
296
+ # - method body - a compound statement with parameters whose
297
+ # return value type must account both for the explicit
298
+ # 'return' statemnts as well as the final statements
299
+ # executed in any given control flow through the method.
300
+ #
301
+ # - explicit return statement - a statement which, when part of a
302
+ # method body, is a possible value of a call to that method -
303
+ # e.g., "return 123"
304
+ #
305
+ # - compound statement - a statement which can be expanded to
306
+ # be multiple statements in a row, executed in the context
307
+ # of a method which can be explicitly returned from.
308
+ #
309
+ # - value position - the positions in the AST where the
310
+ # return type of the statement would be one of the return
311
+ # types of any compound statements it is a part of. For a
312
+ # compound statement, the last of the child statements
313
+ # would be in return position. This concept can be applied
314
+ # recursively through e.g. conditionals to find a list of
315
+ # statements in value positions.
220
316
  module DeepInference
221
317
  class << self
222
- CONDITIONAL = [:if, :unless]
223
- REDUCEABLE = [:begin, :kwbegin]
318
+ CONDITIONAL_ALL_BUT_FIRST = [:if, :unless, :or_asgn]
319
+ CONDITIONAL_ALL = [:or]
320
+ ONLY_ONE_CHILD = [:return]
321
+ FIRST_TWO_CHILDREN = [:rescue]
322
+ COMPOUND_STATEMENTS = [:begin, :kwbegin]
224
323
  SKIPPABLE = [:def, :defs, :class, :sclass, :module]
324
+ FUNCTION_VALUE = [:block]
325
+ CASE_STATEMENT = [:case]
225
326
 
226
- # @param node [Parser::AST::Node]
327
+ # @param node [AST::Node] a method body compound statement
328
+ # @param include_explicit_returns [Boolean] If true,
329
+ # include the value nodes of the parameter of the
330
+ # 'return' statements in the type returned.
331
+ # @return [Array<AST::Node>] low-level value nodes from
332
+ # both nodes in value position as well as explicit
333
+ # return statements in the method's closure.
334
+ def from_method_body node
335
+ from_value_position_statement(node, include_explicit_returns: true)
336
+ end
337
+
338
+ # @param node [AST::Node] an individual statement, to be
339
+ # evaluated outside the context of a containing method
340
+ # @return [Array<AST::Node>] low-level value nodes in
341
+ # value position. Does not include explicit return
342
+ # statements
343
+ def value_position_nodes_only(node)
344
+ from_value_position_statement(node, include_explicit_returns: false)
345
+ end
346
+
347
+ # Look at known control statements and use them to find
348
+ # more specific return nodes.
349
+ #
350
+ # @param node [Parser::AST::Node] Statement which is in
351
+ # value position for a method body
352
+ # @param include_explicit_returns [Boolean] If true,
353
+ # include the value nodes of the parameter of the
354
+ # 'return' statements in the type returned.
227
355
  # @return [Array<Parser::AST::Node>]
228
- def get_return_nodes node
356
+ def from_value_position_statement node, include_explicit_returns: true
357
+ # STDERR.puts("from_expression called on #{node.inspect}")
229
358
  return [] unless node.is_a?(::Parser::AST::Node)
359
+ # @type [Array<Parser::AST::Node>]
230
360
  result = []
231
- if REDUCEABLE.include?(node.type)
232
- result.concat get_return_nodes_from_children(node)
233
- elsif CONDITIONAL.include?(node.type)
361
+ if COMPOUND_STATEMENTS.include?(node.type)
362
+ result.concat from_value_position_compound_statement node
363
+ elsif CONDITIONAL_ALL_BUT_FIRST.include?(node.type)
234
364
  result.concat reduce_to_value_nodes(node.children[1..-1])
235
365
  # result.push NIL_NODE unless node.children[2]
236
- elsif node.type == :or
366
+ elsif CONDITIONAL_ALL.include?(node.type)
237
367
  result.concat reduce_to_value_nodes(node.children)
238
- elsif node.type == :return
368
+ elsif ONLY_ONE_CHILD.include?(node.type)
239
369
  result.concat reduce_to_value_nodes([node.children[0]])
240
- elsif node.type == :block
370
+ elsif FIRST_TWO_CHILDREN.include?(node.type)
371
+ result.concat reduce_to_value_nodes([node.children[0], node.children[1]])
372
+ elsif FUNCTION_VALUE.include?(node.type)
373
+ # the block itself is a first class value that could be returned
241
374
  result.push node
242
- result.concat get_return_nodes_only(node.children[2])
243
- elsif node.type == :case
375
+ # @todo any explicit returns actually return from
376
+ # scope in which the proc is run. This asssumes
377
+ # that the function is executed here.
378
+ result.concat explicit_return_values_from_compound_statement(node.children[2]) if include_explicit_returns
379
+ elsif CASE_STATEMENT.include?(node.type)
244
380
  node.children[1..-1].each do |cc|
245
381
  if cc.nil?
246
382
  result.push NIL_NODE
@@ -251,36 +387,68 @@ module Solargraph
251
387
  result.concat reduce_to_value_nodes([cc])
252
388
  end
253
389
  end
390
+ elsif node.type == :resbody
391
+ result.concat reduce_to_value_nodes([node.children[2]])
254
392
  else
255
393
  result.push node
256
394
  end
257
395
  result
258
396
  end
259
397
 
260
- private
261
-
262
- def get_return_nodes_from_children parent
398
+ # Treat parent as as a begin block and use the last node's
399
+ # return node plus any explicit return nodes' return nodes. e.g.,
400
+ #
401
+ # 123
402
+ # 456
403
+ # return 'a' if foo == bar
404
+ # 789
405
+ #
406
+ # would return 'a' and 789.
407
+ #
408
+ # @param parent [Parser::AST::Node]
409
+ #
410
+ # @return [Array<Parser::AST::Node>]
411
+ def from_value_position_compound_statement parent
263
412
  result = []
264
413
  nodes = parent.children.select{|n| n.is_a?(AST::Node)}
265
414
  nodes.each_with_index do |node, idx|
266
415
  if node.type == :block
267
- result.concat get_return_nodes_only(node.children[2])
416
+ result.concat explicit_return_values_from_compound_statement(node.children[2])
417
+ elsif node.type == :rescue
418
+ # body statements
419
+ result.concat from_value_position_statement(node.children[0])
420
+ # rescue statements
421
+ result.concat from_value_position_statement(node.children[1])
268
422
  elsif SKIPPABLE.include?(node.type)
269
423
  next
424
+ elsif node.type == :resbody
425
+ result.concat reduce_to_value_nodes([node.children[2]])
270
426
  elsif node.type == :return
271
427
  result.concat reduce_to_value_nodes([node.children[0]])
272
- # Return the result here because the rest of the code is
273
- # unreachable
428
+ # Return here because the rest of the code is
429
+ # unreachable and shouldn't be looked at
274
430
  return result
275
431
  else
276
- result.concat get_return_nodes_only(node)
432
+ result.concat explicit_return_values_from_compound_statement(node)
277
433
  end
278
- result.concat reduce_to_value_nodes([nodes.last]) if idx == nodes.length - 1
434
+ # handle last line of compound statements, which is in
435
+ # value position. we already have the explicit values
436
+ # from above; now we need to also gather the value
437
+ # position nodes
438
+ result.concat from_value_position_statement(nodes.last, include_explicit_returns: false) if idx == nodes.length - 1
279
439
  end
280
440
  result
281
441
  end
282
442
 
283
- def get_return_nodes_only parent
443
+ private
444
+
445
+ # Useful when this statement isn't in value position, but
446
+ # we care explicit return statements nonetheless.
447
+ #
448
+ # @param parent [Parser::AST::Node]
449
+ #
450
+ # @return [Array<Parser::AST::Node>]
451
+ def explicit_return_values_from_compound_statement parent
284
452
  return [] unless parent.is_a?(::Parser::AST::Node)
285
453
  result = []
286
454
  nodes = parent.children.select{|n| n.is_a?(::Parser::AST::Node)}
@@ -292,27 +460,31 @@ module Solargraph
292
460
  # unreachable
293
461
  return result
294
462
  else
295
- result.concat get_return_nodes_only(node)
463
+ result.concat explicit_return_values_from_compound_statement(node)
296
464
  end
297
465
  end
298
466
  result
299
467
  end
300
468
 
469
+ # @param nodes [Enumerable<Parser::AST::Node, BaseObject>]
470
+ # @return [Array<Parser::AST::Node, nil>]
301
471
  def reduce_to_value_nodes nodes
302
472
  result = []
303
473
  nodes.each do |node|
304
474
  if !node.is_a?(::Parser::AST::Node)
305
475
  result.push nil
306
- elsif REDUCEABLE.include?(node.type)
307
- result.concat get_return_nodes_from_children(node)
308
- elsif CONDITIONAL.include?(node.type)
476
+ elsif COMPOUND_STATEMENTS.include?(node.type)
477
+ result.concat from_value_position_compound_statement(node)
478
+ elsif CONDITIONAL_ALL_BUT_FIRST.include?(node.type)
309
479
  result.concat reduce_to_value_nodes(node.children[1..-1])
310
480
  elsif node.type == :return
311
481
  result.concat reduce_to_value_nodes([node.children[0]])
312
482
  elsif node.type == :or
313
483
  result.concat reduce_to_value_nodes(node.children)
314
484
  elsif node.type == :block
315
- result.concat get_return_nodes_only(node.children[2])
485
+ result.concat explicit_return_values_from_compound_statement(node.children[2])
486
+ elsif node.type == :resbody
487
+ result.concat reduce_to_value_nodes([node.children[2]])
316
488
  else
317
489
  result.push node
318
490
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Solargraph
4
4
  module Parser
5
- module Rubyvm
5
+ module ParserGem
6
6
  module NodeProcessors
7
7
  class AliasNode < Parser::NodeProcessor::Base
8
8
  def process
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Solargraph
4
4
  module Parser
5
- module Legacy
5
+ module ParserGem
6
6
  module NodeProcessors
7
7
  class ArgsNode < Parser::NodeProcessor::Base
8
8
  def process
@@ -29,6 +29,7 @@ module Solargraph
29
29
 
30
30
  private
31
31
 
32
+ # @return [void]
32
33
  def forward
33
34
  loc = get_node_location(node)
34
35
  locals.push Solargraph::Pin::Parameter.new(
@@ -40,6 +41,8 @@ module Solargraph
40
41
  region.closure.parameters.push locals.last
41
42
  end
42
43
 
44
+ # @param node [AST::Node]
45
+ # @return [Symbol]
43
46
  def get_decl node
44
47
  node.type
45
48
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Solargraph
4
4
  module Parser
5
- module Rubyvm
5
+ module ParserGem
6
6
  module NodeProcessors
7
7
  class BeginNode < Parser::NodeProcessor::Base
8
8
  def process
@@ -2,10 +2,10 @@
2
2
 
3
3
  module Solargraph
4
4
  module Parser
5
- module Legacy
5
+ module ParserGem
6
6
  module NodeProcessors
7
7
  class BlockNode < Parser::NodeProcessor::Base
8
- include Legacy::NodeMethods
8
+ include ParserGem::NodeMethods
9
9
 
10
10
  def process
11
11
  location = get_node_location(node)
@@ -21,6 +21,7 @@ module Solargraph
21
21
  pins.push Solargraph::Pin::Block.new(
22
22
  location: location,
23
23
  closure: parent,
24
+ node: node,
24
25
  receiver: node.children[0],
25
26
  comments: comments_for(node),
26
27
  scope: region.scope || region.closure.context.scope
@@ -2,10 +2,10 @@
2
2
 
3
3
  module Solargraph
4
4
  module Parser
5
- module Legacy
5
+ module ParserGem
6
6
  module NodeProcessors
7
7
  class CasgnNode < Parser::NodeProcessor::Base
8
- include Legacy::NodeMethods
8
+ include ParserGem::NodeMethods
9
9
 
10
10
  def process
11
11
  pins.push Solargraph::Pin::Constant.new(
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Solargraph
4
4
  module Parser
5
- module Legacy
5
+ module ParserGem
6
6
  module NodeProcessors
7
7
  class CvasgnNode < Parser::NodeProcessor::Base
8
8
  def process
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Solargraph
4
4
  module Parser
5
- module Legacy
5
+ module ParserGem
6
6
  module NodeProcessors
7
7
  class DefNode < Parser::NodeProcessor::Base
8
8
  def process
@@ -2,10 +2,10 @@
2
2
 
3
3
  module Solargraph
4
4
  module Parser
5
- module Legacy
5
+ module ParserGem
6
6
  module NodeProcessors
7
7
  class DefsNode < DefNode
8
- include Legacy::NodeMethods
8
+ include ParserGem::NodeMethods
9
9
 
10
10
  def process
11
11
  s_visi = region.visibility
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Solargraph
4
4
  module Parser
5
- module Legacy
5
+ module ParserGem
6
6
  module NodeProcessors
7
7
  class GvasgnNode < Parser::NodeProcessor::Base
8
8
  def process
@@ -2,10 +2,10 @@
2
2
 
3
3
  module Solargraph
4
4
  module Parser
5
- module Legacy
5
+ module ParserGem
6
6
  module NodeProcessors
7
7
  class IvasgnNode < Parser::NodeProcessor::Base
8
- include Legacy::NodeMethods
8
+ include ParserGem::NodeMethods
9
9
 
10
10
  def process
11
11
  loc = get_node_location(node)
@@ -2,10 +2,10 @@
2
2
 
3
3
  module Solargraph
4
4
  module Parser
5
- module Legacy
5
+ module ParserGem
6
6
  module NodeProcessors
7
7
  class LvasgnNode < Parser::NodeProcessor::Base
8
- include Legacy::NodeMethods
8
+ include ParserGem::NodeMethods
9
9
 
10
10
  def process
11
11
  here = get_node_start_position(node)
@@ -2,10 +2,10 @@
2
2
 
3
3
  module Solargraph
4
4
  module Parser
5
- module Legacy
5
+ module ParserGem
6
6
  module NodeProcessors
7
7
  class NamespaceNode < Parser::NodeProcessor::Base
8
- include Legacy::NodeMethods
8
+ include ParserGem::NodeMethods
9
9
 
10
10
  def process
11
11
  sc = nil
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Solargraph
4
4
  module Parser
5
- module Legacy
5
+ module ParserGem
6
6
  module NodeProcessors
7
7
  class OrasgnNode < Parser::NodeProcessor::Base
8
8
  def process
@@ -2,13 +2,13 @@
2
2
 
3
3
  module Solargraph
4
4
  module Parser
5
- module Legacy
5
+ module ParserGem
6
6
  module NodeProcessors
7
7
  class ResbodyNode < Parser::NodeProcessor::Base
8
- include Legacy::NodeMethods
8
+ include ParserGem::NodeMethods
9
9
 
10
10
  def process
11
- if node.children[1]
11
+ if node.children[1] # Exception local variable name
12
12
  here = get_node_start_position(node.children[1])
13
13
  presence = Range.new(here, region.closure.location.range.ending)
14
14
  loc = get_node_location(node.children[1])
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Solargraph
4
4
  module Parser
5
- module Legacy
5
+ module ParserGem
6
6
  module NodeProcessors
7
7
  class SclassNode < Parser::NodeProcessor::Base
8
8
  def process
@@ -2,10 +2,10 @@
2
2
 
3
3
  module Solargraph
4
4
  module Parser
5
- module Legacy
5
+ module ParserGem
6
6
  module NodeProcessors
7
7
  class SendNode < Parser::NodeProcessor::Base
8
- include Legacy::NodeMethods
8
+ include ParserGem::NodeMethods
9
9
 
10
10
  def process
11
11
  if node.children[0].nil?
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Solargraph
4
4
  module Parser
5
- module Rubyvm
5
+ module ParserGem
6
6
  module NodeProcessors
7
7
  class SymNode < Parser::NodeProcessor::Base
8
8
  def process
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'solargraph/parser/node_processor'
4
+
5
+ module Solargraph
6
+ module Parser
7
+ module ParserGem
8
+ module NodeProcessors
9
+ autoload :BeginNode, 'solargraph/parser/parser_gem/node_processors/begin_node'
10
+ autoload :DefNode, 'solargraph/parser/parser_gem/node_processors/def_node'
11
+ autoload :DefsNode, 'solargraph/parser/parser_gem/node_processors/defs_node'
12
+ autoload :SendNode, 'solargraph/parser/parser_gem/node_processors/send_node'
13
+ autoload :NamespaceNode, 'solargraph/parser/parser_gem/node_processors/namespace_node'
14
+ autoload :SclassNode, 'solargraph/parser/parser_gem/node_processors/sclass_node'
15
+ autoload :IvasgnNode, 'solargraph/parser/parser_gem/node_processors/ivasgn_node'
16
+ autoload :CvasgnNode, 'solargraph/parser/parser_gem/node_processors/cvasgn_node'
17
+ autoload :LvasgnNode, 'solargraph/parser/parser_gem/node_processors/lvasgn_node'
18
+ autoload :GvasgnNode, 'solargraph/parser/parser_gem/node_processors/gvasgn_node'
19
+ autoload :CasgnNode, 'solargraph/parser/parser_gem/node_processors/casgn_node'
20
+ autoload :AliasNode, 'solargraph/parser/parser_gem/node_processors/alias_node'
21
+ autoload :ArgsNode, 'solargraph/parser/parser_gem/node_processors/args_node'
22
+ autoload :BlockNode, 'solargraph/parser/parser_gem/node_processors/block_node'
23
+ autoload :OrasgnNode, 'solargraph/parser/parser_gem/node_processors/orasgn_node'
24
+ autoload :SymNode, 'solargraph/parser/parser_gem/node_processors/sym_node'
25
+ autoload :ResbodyNode, 'solargraph/parser/parser_gem/node_processors/resbody_node'
26
+ end
27
+ end
28
+
29
+ module NodeProcessor
30
+ register :source, ParserGem::NodeProcessors::BeginNode
31
+ register :begin, ParserGem::NodeProcessors::BeginNode
32
+ register :kwbegin, ParserGem::NodeProcessors::BeginNode
33
+ register :rescue, ParserGem::NodeProcessors::BeginNode
34
+ register :resbody, ParserGem::NodeProcessors::ResbodyNode
35
+ register :def, ParserGem::NodeProcessors::DefNode
36
+ register :defs, ParserGem::NodeProcessors::DefsNode
37
+ register :send, ParserGem::NodeProcessors::SendNode
38
+ register :class, ParserGem::NodeProcessors::NamespaceNode
39
+ register :module, ParserGem::NodeProcessors::NamespaceNode
40
+ register :sclass, ParserGem::NodeProcessors::SclassNode
41
+ register :ivasgn, ParserGem::NodeProcessors::IvasgnNode
42
+ register :cvasgn, ParserGem::NodeProcessors::CvasgnNode
43
+ register :lvasgn, ParserGem::NodeProcessors::LvasgnNode
44
+ register :gvasgn, ParserGem::NodeProcessors::GvasgnNode
45
+ register :casgn, ParserGem::NodeProcessors::CasgnNode
46
+ register :alias, ParserGem::NodeProcessors::AliasNode
47
+ register :args, ParserGem::NodeProcessors::ArgsNode
48
+ register :forward_args, ParserGem::NodeProcessors::ArgsNode
49
+ register :block, ParserGem::NodeProcessors::BlockNode
50
+ register :or_asgn, ParserGem::NodeProcessors::OrasgnNode
51
+ register :sym, ParserGem::NodeProcessors::SymNode
52
+ end
53
+ end
54
+ end