spoom 1.3.1 → 1.3.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 (42) hide show
  1. checksums.yaml +4 -4
  2. data/lib/spoom/cli/deadcode.rb +21 -17
  3. data/lib/spoom/deadcode/index.rb +178 -10
  4. data/lib/spoom/deadcode/indexer.rb +14 -435
  5. data/lib/spoom/deadcode/plugins/action_mailer.rb +3 -3
  6. data/lib/spoom/deadcode/plugins/action_mailer_preview.rb +9 -3
  7. data/lib/spoom/deadcode/plugins/actionpack.rb +12 -9
  8. data/lib/spoom/deadcode/plugins/active_model.rb +8 -8
  9. data/lib/spoom/deadcode/plugins/active_record.rb +5 -5
  10. data/lib/spoom/deadcode/plugins/active_support.rb +4 -4
  11. data/lib/spoom/deadcode/plugins/base.rb +70 -57
  12. data/lib/spoom/deadcode/plugins/graphql.rb +8 -8
  13. data/lib/spoom/deadcode/plugins/minitest.rb +4 -3
  14. data/lib/spoom/deadcode/plugins/namespaces.rb +9 -12
  15. data/lib/spoom/deadcode/plugins/rails.rb +9 -9
  16. data/lib/spoom/deadcode/plugins/rubocop.rb +13 -17
  17. data/lib/spoom/deadcode/plugins/ruby.rb +9 -9
  18. data/lib/spoom/deadcode/plugins/sorbet.rb +15 -18
  19. data/lib/spoom/deadcode/plugins/thor.rb +5 -4
  20. data/lib/spoom/deadcode/plugins.rb +4 -5
  21. data/lib/spoom/deadcode/remover.rb +14 -10
  22. data/lib/spoom/deadcode/send.rb +1 -0
  23. data/lib/spoom/deadcode.rb +4 -73
  24. data/lib/spoom/location.rb +84 -0
  25. data/lib/spoom/model/builder.rb +246 -0
  26. data/lib/spoom/model/model.rb +328 -0
  27. data/lib/spoom/model/namespace_visitor.rb +50 -0
  28. data/lib/spoom/model/reference.rb +49 -0
  29. data/lib/spoom/model/references_visitor.rb +200 -0
  30. data/lib/spoom/model.rb +10 -0
  31. data/lib/spoom/parse.rb +28 -0
  32. data/lib/spoom/poset.rb +197 -0
  33. data/lib/spoom/sorbet/errors.rb +5 -3
  34. data/lib/spoom/sorbet/lsp/errors.rb +1 -1
  35. data/lib/spoom/sorbet.rb +1 -1
  36. data/lib/spoom/version.rb +1 -1
  37. data/lib/spoom/visitor.rb +755 -0
  38. data/lib/spoom.rb +2 -0
  39. metadata +20 -13
  40. data/lib/spoom/deadcode/location.rb +0 -86
  41. data/lib/spoom/deadcode/reference.rb +0 -34
  42. data/lib/spoom/deadcode/visitor.rb +0 -755
@@ -12,457 +12,36 @@ module Spoom
12
12
  sig { returns(Index) }
13
13
  attr_reader :index
14
14
 
15
- sig { params(path: String, source: String, index: Index, plugins: T::Array[Plugins::Base]).void }
16
- def initialize(path, source, index, plugins: [])
15
+ sig { params(path: String, index: Index, plugins: T::Array[Plugins::Base]).void }
16
+ def initialize(path, index, plugins: [])
17
17
  super()
18
18
 
19
19
  @path = path
20
- @file_name = T.let(File.basename(path), String)
21
- @source = source
22
20
  @index = index
23
21
  @plugins = plugins
24
- @previous_node = T.let(nil, T.nilable(Prism::Node))
25
- @names_nesting = T.let([], T::Array[String])
26
- @nodes_nesting = T.let([], T::Array[Prism::Node])
27
- @in_const_field = T.let(false, T::Boolean)
28
- @in_opassign = T.let(false, T::Boolean)
29
- @in_symbol_literal = T.let(false, T::Boolean)
30
22
  end
31
23
 
32
24
  # Visit
33
25
 
34
- sig { override.params(node: T.nilable(Prism::Node)).void }
35
- def visit(node)
36
- return unless node
37
-
38
- @nodes_nesting << node
39
- super
40
- @nodes_nesting.pop
41
- @previous_node = node
42
- end
43
-
44
- sig { override.params(node: Prism::AliasMethodNode).void }
45
- def visit_alias_method_node(node)
46
- reference_method(node.old_name.slice, node)
47
- end
48
-
49
- sig { override.params(node: Prism::AndNode).void }
50
- def visit_and_node(node)
51
- reference_method(node.operator_loc.slice, node)
52
- super
53
- end
54
-
55
- sig { override.params(node: Prism::BlockArgumentNode).void }
56
- def visit_block_argument_node(node)
57
- expression = node.expression
58
- case expression
59
- when Prism::SymbolNode
60
- reference_method(expression.unescaped, expression)
61
- else
62
- visit(expression)
63
- end
64
- end
65
-
66
- sig { override.params(node: Prism::CallAndWriteNode).void }
67
- def visit_call_and_write_node(node)
68
- visit(node.receiver)
69
- reference_method(node.read_name.to_s, node)
70
- reference_method(node.write_name.to_s, node)
71
- visit(node.value)
72
- end
73
-
74
- sig { override.params(node: Prism::CallOperatorWriteNode).void }
75
- def visit_call_operator_write_node(node)
76
- visit(node.receiver)
77
- reference_method(node.read_name.to_s, node)
78
- reference_method(node.write_name.to_s, node)
79
- visit(node.value)
80
- end
81
-
82
- sig { override.params(node: Prism::CallOrWriteNode).void }
83
- def visit_call_or_write_node(node)
84
- visit(node.receiver)
85
- reference_method(node.read_name.to_s, node)
86
- reference_method(node.write_name.to_s, node)
87
- visit(node.value)
88
- end
89
-
90
26
  sig { override.params(node: Prism::CallNode).void }
91
27
  def visit_call_node(node)
92
- visit_send(
93
- Send.new(
94
- node: node,
95
- name: node.name.to_s,
96
- recv: node.receiver,
97
- args: node.arguments&.arguments || [],
98
- block: node.block,
99
- ),
100
- )
101
- end
102
-
103
- sig { override.params(node: Prism::ClassNode).void }
104
- def visit_class_node(node)
105
- constant_path = node.constant_path.slice
106
-
107
- if constant_path.start_with?("::")
108
- full_name = constant_path.delete_prefix("::")
109
-
110
- # We found a top level definition such as `class ::A; end`, we need to reset the name nesting
111
- old_nesting = @names_nesting.dup
112
- @names_nesting.clear
113
- @names_nesting << full_name
114
-
115
- define_class(T.must(constant_path.split("::").last), full_name, node)
116
-
117
- # We do not call `super` here because we don't want to visit the `constant` again
118
- visit(node.superclass) if node.superclass
119
- visit(node.body)
120
-
121
- # Restore the name nesting once we finished visited the class
122
- @names_nesting.clear
123
- @names_nesting = old_nesting
124
- else
125
- @names_nesting << constant_path
126
- define_class(T.must(constant_path.split("::").last), @names_nesting.join("::"), node)
127
-
128
- # We do not call `super` here because we don't want to visit the `constant` again
129
- visit(node.superclass) if node.superclass
130
- visit(node.body)
131
-
132
- @names_nesting.pop
133
- end
134
- end
135
-
136
- sig { override.params(node: Prism::ConstantAndWriteNode).void }
137
- def visit_constant_and_write_node(node)
138
- reference_constant(node.name.to_s, node)
139
- visit(node.value)
140
- end
141
-
142
- sig { override.params(node: Prism::ConstantOperatorWriteNode).void }
143
- def visit_constant_operator_write_node(node)
144
- reference_constant(node.name.to_s, node)
145
- visit(node.value)
146
- end
147
-
148
- sig { override.params(node: Prism::ConstantOrWriteNode).void }
149
- def visit_constant_or_write_node(node)
150
- reference_constant(node.name.to_s, node)
151
- visit(node.value)
152
- end
153
-
154
- sig { override.params(node: Prism::ConstantPathWriteNode).void }
155
- def visit_constant_path_write_node(node)
156
- parent = node.target.parent
157
- name = node.target.child.slice
158
-
159
- if parent
160
- visit(parent)
161
-
162
- parent_name = parent.slice
163
- full_name = [*@names_nesting, parent_name, name].compact.join("::")
164
- define_constant(name, full_name, node)
165
- else
166
- define_constant(name, name, node)
167
- end
168
-
169
- visit(node.value)
170
- end
171
-
172
- sig { override.params(node: Prism::ConstantReadNode).void }
173
- def visit_constant_read_node(node)
174
- reference_constant(node.name.to_s, node)
175
- end
176
-
177
- sig { override.params(node: Prism::ConstantWriteNode).void }
178
- def visit_constant_write_node(node)
179
- name = node.name.to_s
180
- full_name = [*@names_nesting, name].join("::")
181
- define_constant(name, full_name, node)
182
- visit(node.value)
183
- end
184
-
185
- sig { override.params(node: Prism::DefNode).void }
186
- def visit_def_node(node)
187
- name = node.name.to_s
188
- define_method(name, [*@names_nesting, name].join("::"), node)
189
-
190
- super
191
- end
192
-
193
- sig { override.params(node: Prism::LocalVariableAndWriteNode).void }
194
- def visit_local_variable_and_write_node(node)
195
- name = node.name.to_s
196
- reference_method(name, node)
197
- reference_method("#{name}=", node)
198
- visit(node.value)
199
- end
200
-
201
- sig { override.params(node: Prism::LocalVariableOperatorWriteNode).void }
202
- def visit_local_variable_operator_write_node(node)
203
- name = node.name.to_s
204
- reference_method(name, node)
205
- reference_method("#{name}=", node)
206
- visit(node.value)
207
- end
208
-
209
- sig { override.params(node: Prism::LocalVariableOrWriteNode).void }
210
- def visit_local_variable_or_write_node(node)
211
- name = node.name.to_s
212
- reference_method(name, node)
213
- reference_method("#{name}=", node)
214
- visit(node.value)
215
- end
216
-
217
- sig { override.params(node: Prism::LocalVariableWriteNode).void }
218
- def visit_local_variable_write_node(node)
219
- visit(node.value)
220
- reference_method("#{node.name}=", node)
221
- end
222
-
223
- sig { override.params(node: Prism::ModuleNode).void }
224
- def visit_module_node(node)
225
- constant_path = node.constant_path.slice
226
-
227
- if constant_path.start_with?("::")
228
- full_name = constant_path.delete_prefix("::")
229
-
230
- # We found a top level definition such as `class ::A; end`, we need to reset the name nesting
231
- old_nesting = @names_nesting.dup
232
- @names_nesting.clear
233
- @names_nesting << full_name
234
-
235
- define_module(T.must(constant_path.split("::").last), full_name, node)
236
-
237
- visit(node.body)
238
-
239
- # Restore the name nesting once we finished visited the class
240
- @names_nesting.clear
241
- @names_nesting = old_nesting
242
- else
243
- @names_nesting << constant_path
244
- define_module(T.must(constant_path.split("::").last), @names_nesting.join("::"), node)
245
-
246
- # We do not call `super` here because we don't want to visit the `constant` again
247
- visit(node.body)
248
-
249
- @names_nesting.pop
250
- end
251
- end
252
-
253
- sig { override.params(node: Prism::MultiWriteNode).void }
254
- def visit_multi_write_node(node)
255
- node.lefts.each do |const|
256
- case const
257
- when Prism::ConstantTargetNode, Prism::ConstantPathTargetNode
258
- name = const.slice
259
- define_constant(T.must(name.split("::").last), [*@names_nesting, name].join("::"), const)
260
- when Prism::LocalVariableTargetNode
261
- reference_method("#{const.name}=", node)
262
- end
263
- end
264
- visit(node.value)
265
- end
266
-
267
- sig { override.params(node: Prism::OrNode).void }
268
- def visit_or_node(node)
269
- reference_method(node.operator_loc.slice, node)
270
- super
271
- end
272
-
273
- sig { params(send: Send).void }
274
- def visit_send(send)
275
- visit(send.recv)
276
-
277
- case send.name
278
- when "attr_reader"
279
- send.args.each do |arg|
280
- next unless arg.is_a?(Prism::SymbolNode)
281
-
282
- name = arg.unescaped
283
- define_attr_reader(name, [*@names_nesting, name].join("::"), arg)
284
- end
285
- when "attr_writer"
286
- send.args.each do |arg|
287
- next unless arg.is_a?(Prism::SymbolNode)
288
-
289
- name = arg.unescaped
290
- define_attr_writer("#{name}=", "#{[*@names_nesting, name].join("::")}=", arg)
291
- end
292
- when "attr_accessor"
293
- send.args.each do |arg|
294
- next unless arg.is_a?(Prism::SymbolNode)
295
-
296
- name = arg.unescaped
297
- full_name = [*@names_nesting, name].join("::")
298
- define_attr_reader(name, full_name, arg)
299
- define_attr_writer("#{name}=", "#{full_name}=", arg)
300
- end
301
- else
302
- @plugins.each do |plugin|
303
- plugin.internal_on_send(self, send)
304
- end
305
-
306
- reference_method(send.name, send.node)
307
-
308
- case send.name
309
- when "<", ">", "<=", ">="
310
- # For comparison operators, we also reference the `<=>` method
311
- reference_method("<=>", send.node)
312
- end
313
-
314
- visit_all(send.args)
315
- visit(send.block)
316
- end
317
- end
318
-
319
- # Definition indexing
320
-
321
- sig { params(name: String, full_name: String, node: Prism::Node).void }
322
- def define_attr_reader(name, full_name, node)
323
- definition = Definition.new(
324
- kind: Definition::Kind::AttrReader,
325
- name: name,
326
- full_name: full_name,
327
- location: node_location(node),
328
- )
329
- @index.define(definition)
330
- @plugins.each { |plugin| plugin.internal_on_define_accessor(self, definition) }
331
- end
332
-
333
- sig { params(name: String, full_name: String, node: Prism::Node).void }
334
- def define_attr_writer(name, full_name, node)
335
- definition = Definition.new(
336
- kind: Definition::Kind::AttrWriter,
337
- name: name,
338
- full_name: full_name,
339
- location: node_location(node),
340
- )
341
- @index.define(definition)
342
- @plugins.each { |plugin| plugin.internal_on_define_accessor(self, definition) }
343
- end
344
-
345
- sig { params(name: String, full_name: String, node: Prism::Node).void }
346
- def define_class(name, full_name, node)
347
- definition = Definition.new(
348
- kind: Definition::Kind::Class,
349
- name: name,
350
- full_name: full_name,
351
- location: node_location(node),
352
- )
353
- @index.define(definition)
354
- @plugins.each { |plugin| plugin.internal_on_define_class(self, definition) }
355
- end
356
-
357
- sig { params(name: String, full_name: String, node: Prism::Node).void }
358
- def define_constant(name, full_name, node)
359
- definition = Definition.new(
360
- kind: Definition::Kind::Constant,
361
- name: name,
362
- full_name: full_name,
363
- location: node_location(node),
364
- )
365
- @index.define(definition)
366
- @plugins.each { |plugin| plugin.internal_on_define_constant(self, definition) }
367
- end
368
-
369
- sig { params(name: String, full_name: String, node: Prism::Node).void }
370
- def define_method(name, full_name, node)
371
- definition = Definition.new(
372
- kind: Definition::Kind::Method,
373
- name: name,
374
- full_name: full_name,
375
- location: node_location(node),
376
- )
377
- @index.define(definition)
378
- @plugins.each { |plugin| plugin.internal_on_define_method(self, definition) }
379
- end
28
+ visit(node.receiver)
380
29
 
381
- sig { params(name: String, full_name: String, node: Prism::Node).void }
382
- def define_module(name, full_name, node)
383
- definition = Definition.new(
384
- kind: Definition::Kind::Module,
385
- name: name,
386
- full_name: full_name,
387
- location: node_location(node),
30
+ send = Send.new(
31
+ node: node,
32
+ name: node.name.to_s,
33
+ recv: node.receiver,
34
+ args: node.arguments&.arguments || [],
35
+ block: node.block,
36
+ location: Location.from_prism(@path, node.location),
388
37
  )
389
- @index.define(definition)
390
- @plugins.each { |plugin| plugin.internal_on_define_module(self, definition) }
391
- end
392
-
393
- # Reference indexing
394
-
395
- sig { params(name: String, node: Prism::Node).void }
396
- def reference_constant(name, node)
397
- @index.reference(Reference.new(name: name, kind: Reference::Kind::Constant, location: node_location(node)))
398
- end
399
38
 
400
- sig { params(name: String, node: Prism::Node).void }
401
- def reference_method(name, node)
402
- @index.reference(Reference.new(name: name, kind: Reference::Kind::Method, location: node_location(node)))
403
- end
404
-
405
- # Context
406
-
407
- sig { returns(Prism::Node) }
408
- def current_node
409
- T.must(@nodes_nesting.last)
410
- end
411
-
412
- sig { type_parameters(:N).params(type: T::Class[T.type_parameter(:N)]).returns(T.nilable(T.type_parameter(:N))) }
413
- def nesting_node(type)
414
- @nodes_nesting.reverse_each do |node|
415
- return T.unsafe(node) if node.is_a?(type)
39
+ @plugins.each do |plugin|
40
+ plugin.on_send(send)
416
41
  end
417
42
 
418
- nil
419
- end
420
-
421
- sig { returns(T.nilable(Prism::ClassNode)) }
422
- def nesting_class
423
- nesting_node(Prism::ClassNode)
424
- end
425
-
426
- sig { returns(T.nilable(Prism::BlockNode)) }
427
- def nesting_block
428
- nesting_node(Prism::BlockNode)
429
- end
430
-
431
- sig { returns(T.nilable(Prism::CallNode)) }
432
- def nesting_call
433
- nesting_node(Prism::CallNode)
434
- end
435
-
436
- sig { returns(T.nilable(String)) }
437
- def nesting_class_name
438
- nesting_class = self.nesting_class
439
- return unless nesting_class
440
-
441
- nesting_class.name.to_s
442
- end
443
-
444
- sig { returns(T.nilable(String)) }
445
- def nesting_class_superclass_name
446
- nesting_class_superclass = nesting_class&.superclass
447
- return unless nesting_class_superclass
448
-
449
- nesting_class_superclass.slice.delete_prefix("::")
450
- end
451
-
452
- sig { returns(T.nilable(String)) }
453
- def last_sig
454
- previous_call = @previous_node
455
- return unless previous_call.is_a?(Prism::CallNode)
456
- return unless previous_call.name == :sig
457
-
458
- previous_call.slice
459
- end
460
-
461
- # Node utils
462
-
463
- sig { params(node: Prism::Node).returns(Location) }
464
- def node_location(node)
465
- Location.from_prism(@path, node.location)
43
+ visit(node.arguments)
44
+ visit(send.block)
466
45
  end
467
46
  end
468
47
  end
@@ -7,12 +7,12 @@ module Spoom
7
7
  class ActionMailer < Base
8
8
  extend T::Sig
9
9
 
10
- sig { override.params(indexer: Indexer, send: Send).void }
11
- def on_send(indexer, send)
10
+ sig { override.params(send: Send).void }
11
+ def on_send(send)
12
12
  return unless send.recv.nil? && ActionPack::CALLBACKS.include?(send.name)
13
13
 
14
14
  send.each_arg(Prism::SymbolNode) do |arg|
15
- indexer.reference_method(arg.unescaped, send.node)
15
+ @index.reference_method(arg.unescaped, send.location)
16
16
  end
17
17
  end
18
18
  end
@@ -9,9 +9,15 @@ module Spoom
9
9
 
10
10
  ignore_classes_inheriting_from("ActionMailer::Preview")
11
11
 
12
- sig { override.params(indexer: Indexer, definition: Definition).void }
13
- def on_define_method(indexer, definition)
14
- definition.ignored! if indexer.nesting_class_superclass_name == "ActionMailer::Preview"
12
+ sig { override.params(definition: Model::Method).void }
13
+ def on_define_method(definition)
14
+ owner = definition.owner
15
+ return unless owner.is_a?(Model::Class)
16
+
17
+ superclass_name = owner.superclass_name
18
+ return unless superclass_name
19
+
20
+ @index.ignore(definition) if superclass_name == "ActionMailer::Preview"
15
21
  end
16
22
  end
17
23
  end
@@ -7,6 +7,8 @@ module Spoom
7
7
  class ActionPack < Base
8
8
  extend T::Sig
9
9
 
10
+ ignore_classes_inheriting_from("ApplicationController")
11
+
10
12
  CALLBACKS = T.let(
11
13
  [
12
14
  "after_action",
@@ -25,21 +27,22 @@ module Spoom
25
27
  T::Array[String],
26
28
  )
27
29
 
28
- ignore_classes_named(/Controller$/)
30
+ sig { override.params(definition: Model::Method).void }
31
+ def on_define_method(definition)
32
+ owner = definition.owner
33
+ return unless owner.is_a?(Model::Class)
29
34
 
30
- sig { override.params(indexer: Indexer, definition: Definition).void }
31
- def on_define_method(indexer, definition)
32
- definition.ignored! if ignored_class_name?(indexer.nesting_class_name)
35
+ @index.ignore(definition) if ignored_subclass?(owner)
33
36
  end
34
37
 
35
- sig { override.params(indexer: Indexer, send: Send).void }
36
- def on_send(indexer, send)
38
+ sig { override.params(send: Send).void }
39
+ def on_send(send)
37
40
  return unless send.recv.nil? && CALLBACKS.include?(send.name)
38
41
 
39
42
  arg = send.args.first
40
43
  case arg
41
44
  when Prism::SymbolNode
42
- indexer.reference_method(arg.unescaped, send.node)
45
+ @index.reference_method(arg.unescaped, send.location)
43
46
  end
44
47
 
45
48
  send.each_arg_assoc do |key, value|
@@ -47,9 +50,9 @@ module Spoom
47
50
 
48
51
  case key
49
52
  when "if", "unless"
50
- indexer.reference_method(value.slice.delete_prefix(":"), send.node) if value
53
+ @index.reference_method(value.slice.delete_prefix(":"), send.location) if value
51
54
  else
52
- indexer.reference_constant(camelize(key), send.node)
55
+ @index.reference_constant(camelize(key), send.location)
53
56
  end
54
57
  end
55
58
  end
@@ -7,36 +7,36 @@ module Spoom
7
7
  class ActiveModel < Base
8
8
  extend T::Sig
9
9
 
10
- ignore_classes_inheriting_from(/^(::)?ActiveModel::EachValidator$/)
10
+ ignore_classes_inheriting_from("ActiveModel::EachValidator")
11
11
  ignore_methods_named("validate_each")
12
12
 
13
- sig { override.params(indexer: Indexer, send: Send).void }
14
- def on_send(indexer, send)
13
+ sig { override.params(send: Send).void }
14
+ def on_send(send)
15
15
  return if send.recv
16
16
 
17
17
  case send.name
18
18
  when "attribute", "attributes"
19
19
  send.each_arg(Prism::SymbolNode) do |arg|
20
- indexer.reference_method(arg.unescaped, send.node)
20
+ @index.reference_method(arg.unescaped, send.location)
21
21
  end
22
22
  when "validate", "validates", "validates!", "validates_each"
23
23
  send.each_arg(Prism::SymbolNode) do |arg|
24
- indexer.reference_method(arg.unescaped, send.node)
24
+ @index.reference_method(arg.unescaped, send.location)
25
25
  end
26
26
  send.each_arg_assoc do |key, value|
27
27
  key = key.slice.delete_suffix(":")
28
28
 
29
29
  case key
30
30
  when "if", "unless"
31
- indexer.reference_method(value.slice.delete_prefix(":"), send.node) if value
31
+ @index.reference_method(value.slice.delete_prefix(":"), send.location) if value
32
32
  else
33
- indexer.reference_constant(camelize(key), send.node)
33
+ @index.reference_constant(camelize(key), send.location)
34
34
  end
35
35
  end
36
36
  when "validates_with"
37
37
  arg = send.args.first
38
38
  if arg.is_a?(Prism::SymbolNode)
39
- indexer.reference_constant(arg.unescaped, send.node)
39
+ @index.reference_constant(arg.unescaped, send.location)
40
40
  end
41
41
  end
42
42
  end
@@ -70,11 +70,11 @@ module Spoom
70
70
  T::Array[String],
71
71
  )
72
72
 
73
- sig { override.params(indexer: Indexer, send: Send).void }
74
- def on_send(indexer, send)
73
+ sig { override.params(send: Send).void }
74
+ def on_send(send)
75
75
  if send.recv.nil? && CALLBACKS.include?(send.name)
76
76
  send.each_arg(Prism::SymbolNode) do |arg|
77
- indexer.reference_method(arg.unescaped, send.node)
77
+ @index.reference_method(arg.unescaped, send.location)
78
78
  end
79
79
  return
80
80
  end
@@ -85,7 +85,7 @@ module Spoom
85
85
  when *CRUD_METHODS
86
86
  send.each_arg_assoc do |key, _value|
87
87
  key = key.slice.delete_suffix(":")
88
- indexer.reference_method("#{key}=", send.node)
88
+ @index.reference_method("#{key}=", send.location)
89
89
  end
90
90
  when *ARRAY_METHODS
91
91
  send.each_arg(Prism::ArrayNode) do |arg|
@@ -96,7 +96,7 @@ module Spoom
96
96
  next unless assoc.is_a?(Prism::AssocNode)
97
97
 
98
98
  key = assoc.key.slice.delete_suffix(":")
99
- indexer.reference_method("#{key}=", send.node)
99
+ @index.reference_method("#{key}=", send.location)
100
100
  end
101
101
  end
102
102
  end
@@ -5,7 +5,7 @@ module Spoom
5
5
  module Deadcode
6
6
  module Plugins
7
7
  class ActiveSupport < Base
8
- ignore_classes_inheriting_from(/^(::)?ActiveSupport::TestCase$/)
8
+ ignore_classes_inheriting_from("ActiveSupport::TestCase")
9
9
 
10
10
  ignore_methods_named(
11
11
  "after_all",
@@ -18,12 +18,12 @@ module Spoom
18
18
 
19
19
  SETUP_AND_TEARDOWN_METHODS = T.let(["setup", "teardown"], T::Array[String])
20
20
 
21
- sig { override.params(indexer: Indexer, send: Send).void }
22
- def on_send(indexer, send)
21
+ sig { override.params(send: Send).void }
22
+ def on_send(send)
23
23
  return unless send.recv.nil? && SETUP_AND_TEARDOWN_METHODS.include?(send.name)
24
24
 
25
25
  send.each_arg(Prism::SymbolNode) do |arg|
26
- indexer.reference_method(T.must(arg.value), send.node)
26
+ @index.reference_method(T.must(arg.value), send.location)
27
27
  end
28
28
  end
29
29
  end