solargraph 0.58.0 → 0.59.0

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