solargraph 0.56.0 → 0.58.2

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