solargraph 0.57.0 → 0.58.3

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 (216) hide show
  1. checksums.yaml +4 -4
  2. data/.gitattributes +2 -0
  3. data/.github/workflows/linting.yml +4 -2
  4. data/.github/workflows/plugins.yml +63 -28
  5. data/.github/workflows/rspec.yml +19 -4
  6. data/.github/workflows/typecheck.yml +2 -2
  7. data/.gitignore +1 -0
  8. data/.rubocop.yml +1 -1
  9. data/.rubocop_todo.yml +90 -1438
  10. data/CHANGELOG.md +39 -0
  11. data/Rakefile +1 -1
  12. data/bin/solargraph +3 -0
  13. data/lib/solargraph/api_map/cache.rb +110 -110
  14. data/lib/solargraph/api_map/constants.rb +279 -218
  15. data/lib/solargraph/api_map/index.rb +193 -169
  16. data/lib/solargraph/api_map/source_to_yard.rb +97 -94
  17. data/lib/solargraph/api_map/store.rb +384 -374
  18. data/lib/solargraph/api_map.rb +945 -951
  19. data/lib/solargraph/bench.rb +45 -45
  20. data/lib/solargraph/complex_type/type_methods.rb +228 -223
  21. data/lib/solargraph/complex_type/unique_type.rb +482 -475
  22. data/lib/solargraph/complex_type.rb +444 -427
  23. data/lib/solargraph/convention/active_support_concern.rb +1 -1
  24. data/lib/solargraph/convention/data_definition/data_assignment_node.rb +61 -61
  25. data/lib/solargraph/convention/data_definition/data_definition_node.rb +91 -91
  26. data/lib/solargraph/convention/data_definition.rb +105 -105
  27. data/lib/solargraph/convention/gemfile.rb +15 -15
  28. data/lib/solargraph/convention/gemspec.rb +23 -23
  29. data/lib/solargraph/convention/rakefile.rb +17 -17
  30. data/lib/solargraph/convention/struct_definition/struct_assignment_node.rb +61 -61
  31. data/lib/solargraph/convention/struct_definition/struct_definition_node.rb +102 -102
  32. data/lib/solargraph/convention/struct_definition.rb +164 -164
  33. data/lib/solargraph/convention.rb +78 -78
  34. data/lib/solargraph/converters/dd.rb +17 -17
  35. data/lib/solargraph/converters/dl.rb +15 -15
  36. data/lib/solargraph/converters/dt.rb +15 -15
  37. data/lib/solargraph/converters/misc.rb +1 -1
  38. data/lib/solargraph/diagnostics/require_not_found.rb +53 -53
  39. data/lib/solargraph/diagnostics/rubocop.rb +118 -118
  40. data/lib/solargraph/diagnostics/rubocop_helpers.rb +68 -66
  41. data/lib/solargraph/diagnostics/type_check.rb +55 -55
  42. data/lib/solargraph/diagnostics/update_errors.rb +41 -41
  43. data/lib/solargraph/doc_map.rb +439 -436
  44. data/lib/solargraph/environ.rb +1 -1
  45. data/lib/solargraph/equality.rb +34 -33
  46. data/lib/solargraph/gem_pins.rb +98 -94
  47. data/lib/solargraph/language_server/error_codes.rb +20 -20
  48. data/lib/solargraph/language_server/host/diagnoser.rb +89 -89
  49. data/lib/solargraph/language_server/host/dispatch.rb +130 -130
  50. data/lib/solargraph/language_server/host/message_worker.rb +112 -112
  51. data/lib/solargraph/language_server/host/sources.rb +99 -99
  52. data/lib/solargraph/language_server/host.rb +878 -872
  53. data/lib/solargraph/language_server/message/base.rb +97 -97
  54. data/lib/solargraph/language_server/message/client/register_capability.rb +15 -15
  55. data/lib/solargraph/language_server/message/completion_item/resolve.rb +60 -60
  56. data/lib/solargraph/language_server/message/extended/check_gem_version.rb +114 -114
  57. data/lib/solargraph/language_server/message/extended/document.rb +23 -23
  58. data/lib/solargraph/language_server/message/extended/document_gems.rb +32 -32
  59. data/lib/solargraph/language_server/message/extended/download_core.rb +19 -19
  60. data/lib/solargraph/language_server/message/extended/search.rb +20 -20
  61. data/lib/solargraph/language_server/message/initialize.rb +191 -191
  62. data/lib/solargraph/language_server/message/text_document/completion.rb +56 -56
  63. data/lib/solargraph/language_server/message/text_document/definition.rb +40 -40
  64. data/lib/solargraph/language_server/message/text_document/document_highlight.rb +16 -16
  65. data/lib/solargraph/language_server/message/text_document/document_symbol.rb +26 -26
  66. data/lib/solargraph/language_server/message/text_document/formatting.rb +148 -145
  67. data/lib/solargraph/language_server/message/text_document/hover.rb +58 -58
  68. data/lib/solargraph/language_server/message/text_document/prepare_rename.rb +11 -11
  69. data/lib/solargraph/language_server/message/text_document/references.rb +16 -16
  70. data/lib/solargraph/language_server/message/text_document/rename.rb +19 -19
  71. data/lib/solargraph/language_server/message/text_document/signature_help.rb +24 -24
  72. data/lib/solargraph/language_server/message/text_document/type_definition.rb +25 -25
  73. data/lib/solargraph/language_server/message/workspace/did_change_configuration.rb +35 -35
  74. data/lib/solargraph/language_server/message/workspace/did_change_watched_files.rb +40 -40
  75. data/lib/solargraph/language_server/message/workspace/did_change_workspace_folders.rb +26 -26
  76. data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +23 -23
  77. data/lib/solargraph/language_server/message.rb +94 -94
  78. data/lib/solargraph/language_server/progress.rb +1 -1
  79. data/lib/solargraph/language_server/request.rb +27 -25
  80. data/lib/solargraph/language_server/transport/data_reader.rb +74 -74
  81. data/lib/solargraph/language_server/uri_helpers.rb +49 -49
  82. data/lib/solargraph/library.rb +683 -683
  83. data/lib/solargraph/location.rb +82 -81
  84. data/lib/solargraph/logging.rb +37 -37
  85. data/lib/solargraph/page.rb +92 -93
  86. data/lib/solargraph/parser/comment_ripper.rb +69 -69
  87. data/lib/solargraph/parser/flow_sensitive_typing.rb +255 -255
  88. data/lib/solargraph/parser/node_processor/base.rb +92 -92
  89. data/lib/solargraph/parser/node_processor.rb +62 -62
  90. data/lib/solargraph/parser/parser_gem/class_methods.rb +149 -159
  91. data/lib/solargraph/parser/parser_gem/flawed_builder.rb +19 -19
  92. data/lib/solargraph/parser/parser_gem/node_chainer.rb +166 -166
  93. data/lib/solargraph/parser/parser_gem/node_methods.rb +486 -499
  94. data/lib/solargraph/parser/parser_gem/node_processors/and_node.rb +22 -21
  95. data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +59 -59
  96. data/lib/solargraph/parser/parser_gem/node_processors/begin_node.rb +15 -15
  97. data/lib/solargraph/parser/parser_gem/node_processors/block_node.rb +46 -46
  98. data/lib/solargraph/parser/parser_gem/node_processors/def_node.rb +53 -53
  99. data/lib/solargraph/parser/parser_gem/node_processors/defs_node.rb +37 -37
  100. data/lib/solargraph/parser/parser_gem/node_processors/if_node.rb +23 -23
  101. data/lib/solargraph/parser/parser_gem/node_processors/ivasgn_node.rb +40 -40
  102. data/lib/solargraph/parser/parser_gem/node_processors/lvasgn_node.rb +29 -29
  103. data/lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb +59 -59
  104. data/lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb +98 -42
  105. data/lib/solargraph/parser/parser_gem/node_processors/orasgn_node.rb +17 -17
  106. data/lib/solargraph/parser/parser_gem/node_processors/resbody_node.rb +38 -38
  107. data/lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb +52 -43
  108. data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +291 -292
  109. data/lib/solargraph/parser/parser_gem/node_processors/until_node.rb +29 -29
  110. data/lib/solargraph/parser/parser_gem/node_processors/while_node.rb +29 -29
  111. data/lib/solargraph/parser/parser_gem/node_processors.rb +70 -70
  112. data/lib/solargraph/parser/parser_gem.rb +12 -12
  113. data/lib/solargraph/parser/region.rb +69 -69
  114. data/lib/solargraph/parser/snippet.rb +17 -17
  115. data/lib/solargraph/parser.rb +23 -23
  116. data/lib/solargraph/pin/base.rb +729 -708
  117. data/lib/solargraph/pin/base_variable.rb +126 -124
  118. data/lib/solargraph/pin/block.rb +104 -103
  119. data/lib/solargraph/pin/breakable.rb +9 -9
  120. data/lib/solargraph/pin/callable.rb +231 -227
  121. data/lib/solargraph/pin/closure.rb +72 -76
  122. data/lib/solargraph/pin/common.rb +79 -79
  123. data/lib/solargraph/pin/constant.rb +45 -45
  124. data/lib/solargraph/pin/conversions.rb +123 -123
  125. data/lib/solargraph/pin/delegated_method.rb +120 -121
  126. data/lib/solargraph/pin/documenting.rb +114 -114
  127. data/lib/solargraph/pin/instance_variable.rb +34 -34
  128. data/lib/solargraph/pin/keyword.rb +20 -20
  129. data/lib/solargraph/pin/local_variable.rb +75 -79
  130. data/lib/solargraph/pin/method.rb +672 -656
  131. data/lib/solargraph/pin/method_alias.rb +34 -34
  132. data/lib/solargraph/pin/namespace.rb +115 -115
  133. data/lib/solargraph/pin/parameter.rb +275 -271
  134. data/lib/solargraph/pin/proxy_type.rb +39 -36
  135. data/lib/solargraph/pin/reference/override.rb +47 -47
  136. data/lib/solargraph/pin/reference/superclass.rb +15 -15
  137. data/lib/solargraph/pin/reference.rb +39 -48
  138. data/lib/solargraph/pin/search.rb +61 -58
  139. data/lib/solargraph/pin/signature.rb +61 -61
  140. data/lib/solargraph/pin/symbol.rb +53 -53
  141. data/lib/solargraph/pin/until.rb +18 -18
  142. data/lib/solargraph/pin/while.rb +18 -18
  143. data/lib/solargraph/pin.rb +44 -44
  144. data/lib/solargraph/pin_cache.rb +245 -245
  145. data/lib/solargraph/position.rb +132 -118
  146. data/lib/solargraph/range.rb +112 -108
  147. data/lib/solargraph/rbs_map/conversions.rb +823 -802
  148. data/lib/solargraph/rbs_map/core_fills.rb +84 -66
  149. data/lib/solargraph/rbs_map/core_map.rb +58 -54
  150. data/lib/solargraph/rbs_map/stdlib_map.rb +43 -43
  151. data/lib/solargraph/rbs_map.rb +163 -163
  152. data/lib/solargraph/server_methods.rb +16 -16
  153. data/lib/solargraph/shell.rb +363 -271
  154. data/lib/solargraph/source/chain/array.rb +37 -37
  155. data/lib/solargraph/source/chain/call.rb +337 -333
  156. data/lib/solargraph/source/chain/class_variable.rb +13 -13
  157. data/lib/solargraph/source/chain/constant.rb +26 -89
  158. data/lib/solargraph/source/chain/global_variable.rb +13 -13
  159. data/lib/solargraph/source/chain/hash.rb +34 -34
  160. data/lib/solargraph/source/chain/if.rb +28 -28
  161. data/lib/solargraph/source/chain/instance_variable.rb +13 -13
  162. data/lib/solargraph/source/chain/link.rb +109 -109
  163. data/lib/solargraph/source/chain/literal.rb +48 -48
  164. data/lib/solargraph/source/chain/or.rb +23 -23
  165. data/lib/solargraph/source/chain/q_call.rb +11 -11
  166. data/lib/solargraph/source/chain/variable.rb +13 -13
  167. data/lib/solargraph/source/chain/z_super.rb +30 -30
  168. data/lib/solargraph/source/chain.rb +291 -289
  169. data/lib/solargraph/source/change.rb +82 -82
  170. data/lib/solargraph/source/cursor.rb +166 -166
  171. data/lib/solargraph/source/encoding_fixes.rb +23 -23
  172. data/lib/solargraph/source/source_chainer.rb +194 -194
  173. data/lib/solargraph/source/updater.rb +55 -55
  174. data/lib/solargraph/source.rb +498 -498
  175. data/lib/solargraph/source_map/clip.rb +226 -234
  176. data/lib/solargraph/source_map/data.rb +34 -34
  177. data/lib/solargraph/source_map/mapper.rb +259 -261
  178. data/lib/solargraph/source_map.rb +212 -207
  179. data/lib/solargraph/type_checker/checks.rb +124 -124
  180. data/lib/solargraph/type_checker/param_def.rb +37 -37
  181. data/lib/solargraph/type_checker/problem.rb +32 -32
  182. data/lib/solargraph/type_checker/rules.rb +84 -70
  183. data/lib/solargraph/type_checker.rb +814 -752
  184. data/lib/solargraph/version.rb +5 -5
  185. data/lib/solargraph/workspace/config.rb +255 -237
  186. data/lib/solargraph/workspace/require_paths.rb +97 -98
  187. data/lib/solargraph/workspace.rb +220 -225
  188. data/lib/solargraph/yard_map/helpers.rb +44 -44
  189. data/lib/solargraph/yard_map/mapper/to_method.rb +130 -129
  190. data/lib/solargraph/yard_map/mapper/to_namespace.rb +31 -30
  191. data/lib/solargraph/yard_map/mapper.rb +79 -79
  192. data/lib/solargraph/yard_map/to_method.rb +89 -88
  193. data/lib/solargraph/yard_tags.rb +20 -20
  194. data/lib/solargraph/yardoc.rb +87 -64
  195. data/lib/solargraph.rb +105 -105
  196. data/rbs/fills/bundler/0/bundler.rbs +4271 -0
  197. data/rbs/fills/open3/0/open3.rbs +172 -0
  198. data/rbs/fills/rubygems/0/basic_specification.rbs +326 -0
  199. data/rbs/fills/rubygems/0/errors.rbs +364 -0
  200. data/rbs/fills/rubygems/0/spec_fetcher.rbs +107 -0
  201. data/rbs/fills/rubygems/0/specification.rbs +1753 -0
  202. data/rbs/shims/ast/0/node.rbs +5 -0
  203. data/rbs/shims/ast/2.4/.rbs_meta.yaml +9 -0
  204. data/rbs/shims/ast/2.4/ast.rbs +73 -0
  205. data/rbs/shims/parser/3.2.0.1/manifest.yaml +7 -0
  206. data/rbs/shims/parser/3.2.0.1/parser.rbs +201 -0
  207. data/rbs/shims/parser/3.2.0.1/polyfill.rbs +4 -0
  208. data/rbs_collection.yaml +4 -4
  209. data/solargraph.gemspec +15 -4
  210. metadata +71 -16
  211. data/lib/solargraph/parser/node_methods.rb +0 -97
  212. /data/rbs/fills/{tuple.rbs → tuple/tuple.rbs} +0 -0
  213. /data/{sig → rbs}/shims/parser/3.2.0.1/builders/default.rbs +0 -0
  214. /data/{sig → rbs}/shims/thor/1.2.0.1/.rbs_meta.yaml +0 -0
  215. /data/{sig → rbs}/shims/thor/1.2.0.1/manifest.yaml +0 -0
  216. /data/{sig → rbs}/shims/thor/1.2.0.1/thor.rbs +0 -0
@@ -1,166 +1,166 @@
1
- # frozen_string_literal: true
2
-
3
- module Solargraph
4
- module Parser
5
- module ParserGem
6
- # A factory for generating chains from nodes.
7
- #
8
- class NodeChainer
9
- include NodeMethods
10
-
11
- Chain = Source::Chain
12
-
13
- # @param node [Parser::AST::Node]
14
- # @param filename [String, nil]
15
- # @param parent [Parser::AST::Node, nil]
16
- def initialize node, filename = nil, parent = nil
17
- @node = node
18
- @filename = filename
19
- @parent = parent
20
- end
21
-
22
- # @return [Source::Chain]
23
- def chain
24
- links = generate_links(@node)
25
- Chain.new(links, @node, (Parser.is_ast_node?(@node) && @node.type == :splat))
26
- end
27
-
28
- class << self
29
- # @param node [Parser::AST::Node]
30
- # @param filename [String, nil]
31
- # @param parent [Parser::AST::Node, nil]
32
- # @return [Source::Chain]
33
- def chain node, filename = nil, parent = nil
34
- NodeChainer.new(node, filename, parent).chain
35
- end
36
-
37
- # @param code [String]
38
- # @return [Source::Chain]
39
- def load_string(code)
40
- node = Parser.parse(code.sub(/\.$/, ''))
41
- chain = NodeChainer.new(node).chain
42
- chain.links.push(Chain::Link.new) if code.end_with?('.')
43
- chain
44
- end
45
- end
46
-
47
- private
48
-
49
- # @param n [Parser::AST::Node]
50
- # @return [Array<Chain::Link>]
51
- def generate_links n
52
- return [] unless n.is_a?(::Parser::AST::Node)
53
- return generate_links(n.children[0]) if n.type == :splat
54
- # @type [Array<Chain::Link>]
55
- result = []
56
- if n.type == :block
57
- result.concat NodeChainer.chain(n.children[0], @filename, n).links
58
- elsif n.type == :send
59
- if n.children[0].is_a?(::Parser::AST::Node)
60
- result.concat generate_links(n.children[0])
61
- result.push Chain::Call.new(n.children[1].to_s, Location.from_node(n), node_args(n), passed_block(n))
62
- elsif n.children[0].nil?
63
- args = []
64
- n.children[2..-1].each do |c|
65
- args.push NodeChainer.chain(c, @filename, n)
66
- end
67
- result.push Chain::Call.new(n.children[1].to_s, Location.from_node(n), node_args(n), passed_block(n))
68
- else
69
- raise "No idea what to do with #{n}"
70
- end
71
- elsif n.type == :csend
72
- if n.children[0].is_a?(::Parser::AST::Node)
73
- result.concat generate_links(n.children[0])
74
- result.push Chain::QCall.new(n.children[1].to_s, Location.from_node(n), node_args(n))
75
- elsif n.children[0].nil?
76
- result.push Chain::QCall.new(n.children[1].to_s, Location.from_node(n), node_args(n))
77
- else
78
- raise "No idea what to do with #{n}"
79
- end
80
- elsif n.type == :self
81
- result.push Chain::Head.new('self')
82
- elsif n.type == :zsuper
83
- result.push Chain::ZSuper.new('super')
84
- elsif n.type == :super
85
- args = n.children.map { |c| NodeChainer.chain(c, @filename, n) }
86
- result.push Chain::Call.new('super', Location.from_node(n), args)
87
- elsif n.type == :yield
88
- args = n.children.map { |c| NodeChainer.chain(c, @filename, n) }
89
- result.push Chain::Call.new('yield', Location.from_node(n), args)
90
- elsif n.type == :const
91
- const = unpack_name(n)
92
- result.push Chain::Constant.new(const)
93
- elsif [:lvar, :lvasgn].include?(n.type)
94
- result.push Chain::Call.new(n.children[0].to_s, Location.from_node(n))
95
- elsif [:ivar, :ivasgn].include?(n.type)
96
- result.push Chain::InstanceVariable.new(n.children[0].to_s)
97
- elsif [:cvar, :cvasgn].include?(n.type)
98
- result.push Chain::ClassVariable.new(n.children[0].to_s)
99
- elsif [:gvar, :gvasgn].include?(n.type)
100
- result.push Chain::GlobalVariable.new(n.children[0].to_s)
101
- elsif n.type == :or_asgn
102
- new_node = n.updated(n.children[0].type, n.children[0].children + [n.children[1]])
103
- result.concat generate_links new_node
104
- elsif [:class, :module, :def, :defs].include?(n.type)
105
- # @todo Undefined or what?
106
- result.push Chain::UNDEFINED_CALL
107
- elsif n.type == :and
108
- result.concat generate_links(n.children.last)
109
- elsif n.type == :or
110
- result.push Chain::Or.new([NodeChainer.chain(n.children[0], @filename), NodeChainer.chain(n.children[1], @filename, n)])
111
- elsif n.type == :if
112
- result.push Chain::If.new([NodeChainer.chain(n.children[1], @filename), NodeChainer.chain(n.children[2], @filename, n)])
113
- elsif [:begin, :kwbegin].include?(n.type)
114
- result.concat generate_links(n.children.last)
115
- elsif n.type == :block_pass
116
- block_variable_name_node = n.children[0]
117
- if block_variable_name_node.nil?
118
- # anonymous block forwarding (e.g., "&")
119
- # added in Ruby 3.1 - https://bugs.ruby-lang.org/issues/11256
120
- result.push Chain::BlockVariable.new(nil)
121
- else
122
- if block_variable_name_node.type == :sym
123
- result.push Chain::BlockSymbol.new("#{block_variable_name_node.children[0].to_s}")
124
- else
125
- result.push Chain::BlockVariable.new("&#{block_variable_name_node.children[0].to_s}")
126
- end
127
- end
128
- elsif n.type == :hash
129
- result.push Chain::Hash.new('::Hash', n, hash_is_splatted?(n))
130
- elsif n.type == :array
131
- chained_children = n.children.map { |c| NodeChainer.chain(c) }
132
- result.push Source::Chain::Array.new(chained_children, n)
133
- else
134
- lit = infer_literal_node_type(n)
135
- result.push (lit ? Chain::Literal.new(lit, n) : Chain::Link.new)
136
- end
137
- result
138
- end
139
-
140
- # @param node [Parser::AST::Node]
141
- def hash_is_splatted? node
142
- return false unless Parser.is_ast_node?(node) && node.type == :hash
143
- return false unless Parser.is_ast_node?(node.children.last) && node.children.last.type == :kwsplat
144
- return false if Parser.is_ast_node?(node.children.last.children[0]) && node.children.last.children[0].type == :hash
145
- true
146
- end
147
-
148
- # @param node [Parser::AST::Node]
149
- # @return [Source::Chain, nil]
150
- def passed_block node
151
- return unless node == @node && @parent&.type == :block
152
-
153
- NodeChainer.chain(@parent.children[2], @filename)
154
- end
155
-
156
- # @param node [Parser::AST::Node]
157
- # @return [Array<Source::Chain>]
158
- def node_args node
159
- node.children[2..-1].map do |child|
160
- NodeChainer.chain(child, @filename, node)
161
- end
162
- end
163
- end
164
- end
165
- end
166
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ module Parser
5
+ module ParserGem
6
+ # A factory for generating chains from nodes.
7
+ #
8
+ class NodeChainer
9
+ include NodeMethods
10
+
11
+ Chain = Source::Chain
12
+
13
+ # @param node [Parser::AST::Node]
14
+ # @param filename [String, nil]
15
+ # @param parent [Parser::AST::Node, nil]
16
+ def initialize node, filename = nil, parent = nil
17
+ @node = node
18
+ @filename = filename
19
+ @parent = parent
20
+ end
21
+
22
+ # @return [Source::Chain]
23
+ def chain
24
+ links = generate_links(@node)
25
+ Chain.new(links, @node, (Parser.is_ast_node?(@node) && @node.type == :splat))
26
+ end
27
+
28
+ class << self
29
+ # @param node [Parser::AST::Node]
30
+ # @param filename [String, nil]
31
+ # @param parent [Parser::AST::Node, nil]
32
+ # @return [Source::Chain]
33
+ def chain node, filename = nil, parent = nil
34
+ NodeChainer.new(node, filename, parent).chain
35
+ end
36
+
37
+ # @param code [String]
38
+ # @return [Source::Chain]
39
+ def load_string(code)
40
+ node = Parser.parse(code.sub(/\.$/, ''))
41
+ chain = NodeChainer.new(node).chain
42
+ chain.links.push(Chain::Link.new) if code.end_with?('.')
43
+ chain
44
+ end
45
+ end
46
+
47
+ private
48
+
49
+ # @param n [Parser::AST::Node]
50
+ # @return [Array<Chain::Link>]
51
+ def generate_links n
52
+ return [] unless n.is_a?(::Parser::AST::Node)
53
+ return generate_links(n.children[0]) if n.type == :splat
54
+ # @type [Array<Chain::Link>]
55
+ result = []
56
+ if n.type == :block
57
+ result.concat NodeChainer.chain(n.children[0], @filename, n).links
58
+ elsif n.type == :send
59
+ if n.children[0].is_a?(::Parser::AST::Node)
60
+ result.concat generate_links(n.children[0])
61
+ result.push Chain::Call.new(n.children[1].to_s, Location.from_node(n), node_args(n), passed_block(n))
62
+ elsif n.children[0].nil?
63
+ args = []
64
+ n.children[2..-1].each do |c|
65
+ args.push NodeChainer.chain(c, @filename, n)
66
+ end
67
+ result.push Chain::Call.new(n.children[1].to_s, Location.from_node(n), node_args(n), passed_block(n))
68
+ else
69
+ raise "No idea what to do with #{n}"
70
+ end
71
+ elsif n.type == :csend
72
+ if n.children[0].is_a?(::Parser::AST::Node)
73
+ result.concat generate_links(n.children[0])
74
+ result.push Chain::QCall.new(n.children[1].to_s, Location.from_node(n), node_args(n))
75
+ elsif n.children[0].nil?
76
+ result.push Chain::QCall.new(n.children[1].to_s, Location.from_node(n), node_args(n))
77
+ else
78
+ raise "No idea what to do with #{n}"
79
+ end
80
+ elsif n.type == :self
81
+ result.push Chain::Head.new('self')
82
+ elsif n.type == :zsuper
83
+ result.push Chain::ZSuper.new('super')
84
+ elsif n.type == :super
85
+ args = n.children.map { |c| NodeChainer.chain(c, @filename, n) }
86
+ result.push Chain::Call.new('super', Location.from_node(n), args)
87
+ elsif n.type == :yield
88
+ args = n.children.map { |c| NodeChainer.chain(c, @filename, n) }
89
+ result.push Chain::Call.new('yield', Location.from_node(n), args)
90
+ elsif n.type == :const
91
+ const = unpack_name(n)
92
+ result.push Chain::Constant.new(const)
93
+ elsif [:lvar, :lvasgn].include?(n.type)
94
+ result.push Chain::Call.new(n.children[0].to_s, Location.from_node(n))
95
+ elsif [:ivar, :ivasgn].include?(n.type)
96
+ result.push Chain::InstanceVariable.new(n.children[0].to_s)
97
+ elsif [:cvar, :cvasgn].include?(n.type)
98
+ result.push Chain::ClassVariable.new(n.children[0].to_s)
99
+ elsif [:gvar, :gvasgn].include?(n.type)
100
+ result.push Chain::GlobalVariable.new(n.children[0].to_s)
101
+ elsif n.type == :or_asgn
102
+ new_node = n.updated(n.children[0].type, n.children[0].children + [n.children[1]])
103
+ result.concat generate_links new_node
104
+ elsif [:class, :module, :def, :defs].include?(n.type)
105
+ # @todo Undefined or what?
106
+ result.push Chain::UNDEFINED_CALL
107
+ elsif n.type == :and
108
+ result.concat generate_links(n.children.last)
109
+ elsif n.type == :or
110
+ result.push Chain::Or.new([NodeChainer.chain(n.children[0], @filename), NodeChainer.chain(n.children[1], @filename, n)])
111
+ elsif n.type == :if
112
+ result.push Chain::If.new([NodeChainer.chain(n.children[1], @filename), NodeChainer.chain(n.children[2], @filename, n)])
113
+ elsif [:begin, :kwbegin].include?(n.type)
114
+ result.concat generate_links(n.children.last)
115
+ elsif n.type == :block_pass
116
+ block_variable_name_node = n.children[0]
117
+ if block_variable_name_node.nil?
118
+ # anonymous block forwarding (e.g., "&")
119
+ # added in Ruby 3.1 - https://bugs.ruby-lang.org/issues/11256
120
+ result.push Chain::BlockVariable.new(nil)
121
+ else
122
+ if block_variable_name_node.type == :sym
123
+ result.push Chain::BlockSymbol.new("#{block_variable_name_node.children[0].to_s}")
124
+ else
125
+ result.push Chain::BlockVariable.new("&#{block_variable_name_node.children[0].to_s}")
126
+ end
127
+ end
128
+ elsif n.type == :hash
129
+ result.push Chain::Hash.new('::Hash', n, hash_is_splatted?(n))
130
+ elsif n.type == :array
131
+ chained_children = n.children.map { |c| NodeChainer.chain(c) }
132
+ result.push Source::Chain::Array.new(chained_children, n)
133
+ else
134
+ lit = infer_literal_node_type(n)
135
+ result.push (lit ? Chain::Literal.new(lit, n) : Chain::Link.new)
136
+ end
137
+ result
138
+ end
139
+
140
+ # @param node [Parser::AST::Node]
141
+ def hash_is_splatted? node
142
+ return false unless Parser.is_ast_node?(node) && node.type == :hash
143
+ return false unless Parser.is_ast_node?(node.children.last) && node.children.last.type == :kwsplat
144
+ return false if Parser.is_ast_node?(node.children.last.children[0]) && node.children.last.children[0].type == :hash
145
+ true
146
+ end
147
+
148
+ # @param node [Parser::AST::Node]
149
+ # @return [Source::Chain, nil]
150
+ def passed_block node
151
+ return unless node == @node && @parent&.type == :block
152
+
153
+ NodeChainer.chain(@parent.children[2], @filename)
154
+ end
155
+
156
+ # @param node [Parser::AST::Node]
157
+ # @return [Array<Source::Chain>]
158
+ def node_args node
159
+ node.children[2..-1].map do |child|
160
+ NodeChainer.chain(child, @filename, node)
161
+ end
162
+ end
163
+ end
164
+ end
165
+ end
166
+ end