spoom 1.2.2 → 1.2.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5154e37a81129c70e93925cc2a545a0d7861fd645a3ec2422e6549efc0cb76b5
4
- data.tar.gz: 30c9ecdc3599a37309180fea890a7888d53b430c8701e0970f503bf5731979f9
3
+ metadata.gz: 8e7ef8ebef70bc8827cdcb4b2c0e49ed6c53686e0db409908354f3762ad07c10
4
+ data.tar.gz: a6adb405f0379cbe040e743f177e758e2bdaadcdea13ee9c7f75d84f764434b1
5
5
  SHA512:
6
- metadata.gz: a3246a42fa965e3ef75d0178ffe958a8cc5723812ecb86799b5e2e406d5da7487ffd738696ccb3f6d76ae140de281dab73dba3ec3d8af9fdef696820654ed869
7
- data.tar.gz: ba4c8ab2d87ff4451f420e2d062c7cebdd19202bc91226fd131ff9ab9f838e7494fa43560ffa317fc0565d023ecceef184c02f762e215ba6451d3ec164e3c75a
6
+ metadata.gz: 86d74bc7d9554d67c1421908116bbab7615d77e9cb096d461f7885429d495f2b02f19d6024117f7083423cfe7c48165b18918c143f29574896bfbb76a4fb651f
7
+ data.tar.gz: 754d41e8f26425a42288388879fe1658214adea03002421495297486343a827d6dc79a395e895553ed15f67cdc766a16f4a174aab2a3671bd2455e305a8c6f13
@@ -187,7 +187,7 @@ module Spoom
187
187
 
188
188
  no_commands do
189
189
  def parse_time(string, option)
190
- return nil unless string
190
+ return unless string
191
191
 
192
192
  Time.parse(string)
193
193
  rescue ArgumentError
@@ -13,7 +13,7 @@ module Spoom
13
13
  sig { params(string: String).returns(T.nilable(Commit)) }
14
14
  def parse_line(string)
15
15
  sha, epoch = string.split(" ", 2)
16
- return nil unless sha && epoch
16
+ return unless sha && epoch
17
17
 
18
18
  time = Time.strptime(epoch, "%s")
19
19
  Commit.new(sha: sha, time: time)
@@ -88,7 +88,7 @@ module Spoom
88
88
  sig { returns(T.nilable(String)) }
89
89
  def git_current_branch
90
90
  res = git("branch --show-current")
91
- return nil unless res.status
91
+ return unless res.status
92
92
 
93
93
  res.out.strip
94
94
  end
@@ -103,10 +103,10 @@ module Spoom
103
103
  sig { params(short_sha: T::Boolean).returns(T.nilable(Spoom::Git::Commit)) }
104
104
  def git_last_commit(short_sha: true)
105
105
  res = git_log("HEAD --format='%#{short_sha ? "h" : "H"} %at' -1")
106
- return nil unless res.status
106
+ return unless res.status
107
107
 
108
108
  out = res.out.strip
109
- return nil if out.empty?
109
+ return if out.empty?
110
110
 
111
111
  Spoom::Git::Commit.parse_line(out)
112
112
  end
@@ -52,7 +52,7 @@ module Spoom
52
52
  sorbet_bin: sorbet_bin,
53
53
  capture_err: capture_err,
54
54
  )
55
- return nil unless file?(metrics_file)
55
+ return unless file?(metrics_file)
56
56
 
57
57
  metrics_path = absolute_path_to(metrics_file)
58
58
  metrics = Spoom::Sorbet::MetricsParser.parse_file(metrics_path)
@@ -109,7 +109,7 @@ module Spoom
109
109
  sig { params(arg: String, sorbet_bin: T.nilable(String), capture_err: T::Boolean).returns(T.nilable(String)) }
110
110
  def srb_version(*arg, sorbet_bin: nil, capture_err: true)
111
111
  res = T.unsafe(self).srb_tc("--no-config", "--version", *arg, sorbet_bin: sorbet_bin, capture_err: capture_err)
112
- return nil unless res.status
112
+ return unless res.status
113
113
 
114
114
  res.out.split(" ")[2]
115
115
  end
@@ -147,10 +147,10 @@ module Spoom
147
147
  sig { returns(T.nilable(Spoom::Git::Commit)) }
148
148
  def sorbet_intro_commit
149
149
  res = git_log("--diff-filter=A --format='%h %at' -1 -- sorbet/config")
150
- return nil unless res.status
150
+ return unless res.status
151
151
 
152
152
  out = res.out.strip
153
- return nil if out.empty?
153
+ return if out.empty?
154
154
 
155
155
  Spoom::Git::Commit.parse_line(out)
156
156
  end
@@ -159,10 +159,10 @@ module Spoom
159
159
  sig { returns(T.nilable(Spoom::Git::Commit)) }
160
160
  def sorbet_removal_commit
161
161
  res = git_log("--diff-filter=D --format='%h %at' -1 -- sorbet/config")
162
- return nil unless res.status
162
+ return unless res.status
163
163
 
164
164
  out = res.out.strip
165
- return nil if out.empty?
165
+ return if out.empty?
166
166
 
167
167
  Spoom::Git::Commit.parse_line(out)
168
168
  end
@@ -12,14 +12,15 @@ module Spoom
12
12
  sig { returns(Index) }
13
13
  attr_reader :index
14
14
 
15
- sig { params(path: String, source: String, index: Index).void }
16
- def initialize(path, source, index)
15
+ sig { params(path: String, source: String, index: Index, plugins: T::Array[Plugins::Base]).void }
16
+ def initialize(path, source, index, plugins: [])
17
17
  super()
18
18
 
19
19
  @path = path
20
20
  @file_name = T.let(File.basename(path), String)
21
21
  @source = source
22
22
  @index = index
23
+ @plugins = plugins
23
24
  @previous_node = T.let(nil, T.nilable(SyntaxTree::Node))
24
25
  @names_nesting = T.let([], T::Array[String])
25
26
  @nodes_nesting = T.let([], T::Array[SyntaxTree::Node])
@@ -228,6 +229,10 @@ module Spoom
228
229
  define_attr_writer("#{name}=", "#{full_name}=", arg)
229
230
  end
230
231
  else
232
+ @plugins.each do |plugin|
233
+ plugin.on_send(self, send)
234
+ end
235
+
231
236
  reference_method(send.name, send.node)
232
237
  visit_all(send.args)
233
238
  visit(send.block)
@@ -270,8 +275,6 @@ module Spoom
270
275
  visit_send(Send.new(node: node, name: node_string(node.value)))
271
276
  end
272
277
 
273
- private
274
-
275
278
  # Definition indexing
276
279
 
277
280
  sig { params(name: String, full_name: String, node: SyntaxTree::Node).void }
@@ -283,6 +286,7 @@ module Spoom
283
286
  location: node_location(node),
284
287
  )
285
288
  @index.define(definition)
289
+ @plugins.each { |plugin| plugin.on_define_accessor(self, definition) }
286
290
  end
287
291
 
288
292
  sig { params(name: String, full_name: String, node: SyntaxTree::Node).void }
@@ -294,6 +298,7 @@ module Spoom
294
298
  location: node_location(node),
295
299
  )
296
300
  @index.define(definition)
301
+ @plugins.each { |plugin| plugin.on_define_accessor(self, definition) }
297
302
  end
298
303
 
299
304
  sig { params(name: String, full_name: String, node: SyntaxTree::Node).void }
@@ -305,6 +310,7 @@ module Spoom
305
310
  location: node_location(node),
306
311
  )
307
312
  @index.define(definition)
313
+ @plugins.each { |plugin| plugin.on_define_class(self, definition) }
308
314
  end
309
315
 
310
316
  sig { params(name: String, full_name: String, node: SyntaxTree::Node).void }
@@ -316,6 +322,7 @@ module Spoom
316
322
  location: node_location(node),
317
323
  )
318
324
  @index.define(definition)
325
+ @plugins.each { |plugin| plugin.on_define_constant(self, definition) }
319
326
  end
320
327
 
321
328
  sig { params(name: String, full_name: String, node: SyntaxTree::Node).void }
@@ -327,6 +334,7 @@ module Spoom
327
334
  location: node_location(node),
328
335
  )
329
336
  @index.define(definition)
337
+ @plugins.each { |plugin| plugin.on_define_method(self, definition) }
330
338
  end
331
339
 
332
340
  sig { params(name: String, full_name: String, node: SyntaxTree::Node).void }
@@ -338,6 +346,7 @@ module Spoom
338
346
  location: node_location(node),
339
347
  )
340
348
  @index.define(definition)
349
+ @plugins.each { |plugin| plugin.on_define_module(self, definition) }
341
350
  end
342
351
 
343
352
  # Reference indexing
@@ -44,7 +44,7 @@ module Spoom
44
44
 
45
45
  sig { override.params(other: BasicObject).returns(T.nilable(Integer)) }
46
46
  def <=>(other)
47
- return nil unless Location === other
47
+ return unless Location === other
48
48
 
49
49
  to_s <=> other.to_s
50
50
  end
@@ -0,0 +1,201 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ require "set"
5
+
6
+ module Spoom
7
+ module Deadcode
8
+ module Plugins
9
+ class Base
10
+ extend T::Sig
11
+ extend T::Helpers
12
+
13
+ abstract!
14
+
15
+ class << self
16
+ extend T::Sig
17
+
18
+ # Plugins DSL
19
+
20
+ # Mark methods matching `names` as ignored.
21
+ #
22
+ # Names can be either strings or regexps:
23
+ #
24
+ # ~~~rb
25
+ # class MyPlugin < Spoom::Deadcode::Plugins::Base
26
+ # ignore_method_names(
27
+ # "foo",
28
+ # "bar",
29
+ # /baz.*/,
30
+ # )
31
+ # end
32
+ # ~~~
33
+ sig { params(names: T.any(String, Regexp)).void }
34
+ def ignore_method_names(*names)
35
+ save_names_and_patterns(names, :@ignored_method_names, :@ignored_method_patterns)
36
+ end
37
+
38
+ private
39
+
40
+ sig { params(names: T::Array[T.any(String, Regexp)], names_variable: Symbol, patterns_variable: Symbol).void }
41
+ def save_names_and_patterns(names, names_variable, patterns_variable)
42
+ ignored_names = instance_variable_set(names_variable, Set.new)
43
+ ignored_patterns = instance_variable_set(patterns_variable, [])
44
+
45
+ names.each do |name|
46
+ case name
47
+ when String
48
+ ignored_names << name
49
+ when Regexp
50
+ ignored_patterns << name
51
+ end
52
+ end
53
+ end
54
+ end
55
+
56
+ # Indexing event methods
57
+
58
+ # Called when an accessor is defined.
59
+ #
60
+ # Will be called when the indexer processes a `attr_reader`, `attr_writer` or `attr_accessor` node.
61
+ # Note that when this method is called, the definition for the node has already been added to the index.
62
+ # It is still possible to ignore it from the plugin:
63
+ #
64
+ # ~~~rb
65
+ # class MyPlugin < Spoom::Deadcode::Plugins::Base
66
+ # def on_define_accessor(indexer, definition)
67
+ # definition.ignored! if definition.name == "foo"
68
+ # end
69
+ # end
70
+ # ~~~
71
+ sig { params(indexer: Indexer, definition: Definition).void }
72
+ def on_define_accessor(indexer, definition)
73
+ # no-op
74
+ end
75
+
76
+ # Called when a class is defined.
77
+ #
78
+ # Will be called when the indexer processes a `class` node.
79
+ # Note that when this method is called, the definition for the node has already been added to the index.
80
+ # It is still possible to ignore it from the plugin:
81
+ #
82
+ # ~~~rb
83
+ # class MyPlugin < Spoom::Deadcode::Plugins::Base
84
+ # def on_define_class(indexer, definition)
85
+ # definition.ignored! if definition.name == "Foo"
86
+ # end
87
+ # end
88
+ # ~~~
89
+ sig { params(indexer: Indexer, definition: Definition).void }
90
+ def on_define_class(indexer, definition)
91
+ # no-op
92
+ end
93
+
94
+ # Called when a constant is defined.
95
+ #
96
+ # Will be called when the indexer processes a `CONST =` node.
97
+ # Note that when this method is called, the definition for the node has already been added to the index.
98
+ # It is still possible to ignore it from the plugin:
99
+ #
100
+ # ~~~rb
101
+ # class MyPlugin < Spoom::Deadcode::Plugins::Base
102
+ # def on_define_constant(indexer, definition)
103
+ # definition.ignored! if definition.name == "FOO"
104
+ # end
105
+ # end
106
+ # ~~~
107
+ sig { params(indexer: Indexer, definition: Definition).void }
108
+ def on_define_constant(indexer, definition)
109
+ # no-op
110
+ end
111
+
112
+ # Called when a method is defined.
113
+ #
114
+ # Will be called when the indexer processes a `def` or `defs` node.
115
+ # Note that when this method is called, the definition for the node has already been added to the index.
116
+ # It is still possible to ignore it from the plugin:
117
+ #
118
+ # ~~~rb
119
+ # class MyPlugin < Spoom::Deadcode::Plugins::Base
120
+ # def on_define_method(indexer, definition)
121
+ # super # So the `ignore_method_names` DSL is still applied
122
+ #
123
+ # definition.ignored! if definition.name == "foo"
124
+ # end
125
+ # end
126
+ # ~~~
127
+ sig { params(indexer: Indexer, definition: Definition).void }
128
+ def on_define_method(indexer, definition)
129
+ definition.ignored! if ignored_method_name?(definition.name)
130
+ end
131
+
132
+ # Called when a module is defined.
133
+ #
134
+ # Will be called when the indexer processes a `module` node.
135
+ # Note that when this method is called, the definition for the node has already been added to the index.
136
+ # It is still possible to ignore it from the plugin:
137
+ #
138
+ # ~~~rb
139
+ # class MyPlugin < Spoom::Deadcode::Plugins::Base
140
+ # def on_define_module(indexer, definition)
141
+ # definition.ignored! if definition.name == "Foo"
142
+ # end
143
+ # end
144
+ # ~~~
145
+ sig { params(indexer: Indexer, definition: Definition).void }
146
+ def on_define_module(indexer, definition)
147
+ # no-op
148
+ end
149
+
150
+ # Called when a send is being processed
151
+ #
152
+ # ~~~rb
153
+ # class MyPlugin < Spoom::Deadcode::Plugins::Base
154
+ # def on_send(indexer, send)
155
+ # return unless send.name == "dsl_method"
156
+ # return if send.args.empty?
157
+ #
158
+ # method_name = indexer.node_string(send.args.first).delete_prefix(":")
159
+ # indexer.reference_method(method_name, send.node)
160
+ # end
161
+ # end
162
+ # ~~~
163
+ sig { params(indexer: Indexer, send: Send).void }
164
+ def on_send(indexer, send)
165
+ # no-op
166
+ end
167
+
168
+ private
169
+
170
+ sig { params(name: String).returns(T::Boolean) }
171
+ def ignored_method_name?(name)
172
+ ignored_name?(name, :@ignored_method_names, :@ignored_method_patterns)
173
+ end
174
+
175
+ sig { params(const: Symbol).returns(T::Set[String]) }
176
+ def names(const)
177
+ self.class.instance_variable_get(const) || Set.new
178
+ end
179
+
180
+ sig { params(name: String, names_variable: Symbol, patterns_variable: Symbol).returns(T::Boolean) }
181
+ def ignored_name?(name, names_variable, patterns_variable)
182
+ names(names_variable).include?(name) || patterns(patterns_variable).any? { |pattern| pattern.match?(name) }
183
+ end
184
+
185
+ sig { params(const: Symbol).returns(T::Array[Regexp]) }
186
+ def patterns(const)
187
+ self.class.instance_variable_get(const) || []
188
+ end
189
+
190
+ sig { params(indexer: Indexer, send: Send).void }
191
+ def reference_send_first_symbol_as_method(indexer, send)
192
+ first_arg = send.args.first
193
+ return unless first_arg.is_a?(SyntaxTree::SymbolLiteral)
194
+
195
+ name = indexer.node_string(first_arg.value)
196
+ indexer.reference_method(name, send.node)
197
+ end
198
+ end
199
+ end
200
+ end
201
+ end
@@ -0,0 +1,64 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ module Spoom
5
+ module Deadcode
6
+ module Plugins
7
+ class Ruby < Base
8
+ extend T::Sig
9
+
10
+ ignore_method_names(
11
+ "==",
12
+ "extended",
13
+ "included",
14
+ "inherited",
15
+ "initialize",
16
+ "method_added",
17
+ "method_missing",
18
+ "prepended",
19
+ "respond_to_missing?",
20
+ "to_s",
21
+ )
22
+
23
+ sig { override.params(indexer: Indexer, send: Send).void }
24
+ def on_send(indexer, send)
25
+ case send.name
26
+ when "const_defined?", "const_get", "const_source_location"
27
+ reference_symbol_as_constant(indexer, send, T.must(send.args.first))
28
+ when "send", "__send__", "try"
29
+ reference_send_first_symbol_as_method(indexer, send)
30
+ when "alias_method"
31
+ last_arg = send.args.last
32
+
33
+ name = case last_arg
34
+ when SyntaxTree::SymbolLiteral
35
+ indexer.node_string(last_arg.value)
36
+ when SyntaxTree::StringLiteral
37
+ last_arg.parts.map { |part| indexer.node_string(part) }.join
38
+ end
39
+
40
+ return unless name
41
+
42
+ indexer.reference_method(name, send.node)
43
+ end
44
+ end
45
+
46
+ private
47
+
48
+ sig { params(indexer: Indexer, send: Send, node: SyntaxTree::Node).void }
49
+ def reference_symbol_as_constant(indexer, send, node)
50
+ case node
51
+ when SyntaxTree::SymbolLiteral
52
+ name = indexer.node_string(node.value)
53
+ indexer.reference_constant(name, send.node)
54
+ when SyntaxTree::StringLiteral
55
+ string = T.must(indexer.node_string(node)[1..-2])
56
+ string.split("::").each do |name|
57
+ indexer.reference_constant(name, send.node) unless name.empty?
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,5 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ require_relative "plugins/base"
5
+ require_relative "plugins/ruby"
@@ -12,6 +12,7 @@ require_relative "deadcode/location"
12
12
  require_relative "deadcode/definition"
13
13
  require_relative "deadcode/reference"
14
14
  require_relative "deadcode/send"
15
+ require_relative "deadcode/plugins"
15
16
 
16
17
  module Spoom
17
18
  module Deadcode
@@ -34,10 +35,10 @@ module Spoom
34
35
  class << self
35
36
  extend T::Sig
36
37
 
37
- sig { params(index: Index, ruby: String, file: String).void }
38
- def index_ruby(index, ruby, file:)
38
+ sig { params(index: Index, ruby: String, file: String, plugins: T::Array[Deadcode::Plugins::Base]).void }
39
+ def index_ruby(index, ruby, file:, plugins: [])
39
40
  node = SyntaxTree.parse(ruby)
40
- visitor = Spoom::Deadcode::Indexer.new(file, ruby, index)
41
+ visitor = Spoom::Deadcode::Indexer.new(file, ruby, index, plugins: plugins)
41
42
  visitor.visit(node)
42
43
  rescue SyntaxTree::Parser::ParseError => e
43
44
  raise ParserError.new("Error while parsing #{file} (#{e.message} at #{e.lineno}:#{e.column})", parent: e)
@@ -45,10 +46,10 @@ module Spoom
45
46
  raise IndexerError.new("Error while indexing #{file} (#{e.message})", parent: e)
46
47
  end
47
48
 
48
- sig { params(index: Index, erb: String, file: String).void }
49
- def index_erb(index, erb, file:)
49
+ sig { params(index: Index, erb: String, file: String, plugins: T::Array[Deadcode::Plugins::Base]).void }
50
+ def index_erb(index, erb, file:, plugins: [])
50
51
  ruby = ERB.new(erb).src
51
- index_ruby(index, ruby, file: file)
52
+ index_ruby(index, ruby, file: file, plugins: plugins)
52
53
  end
53
54
  end
54
55
  end
@@ -53,7 +53,7 @@ module Spoom
53
53
  sig { returns(T.nilable(T::Hash[T.untyped, T.untyped])) }
54
54
  def read
55
55
  raw_string = read_raw
56
- return nil unless raw_string
56
+ return unless raw_string
57
57
 
58
58
  json = JSON.parse(raw_string)
59
59
 
@@ -101,7 +101,7 @@ module Spoom
101
101
  },
102
102
  ))
103
103
 
104
- return nil unless json && json["result"]
104
+ return unless json && json["result"]
105
105
 
106
106
  Hover.from_json(json["result"])
107
107
  end
@@ -28,7 +28,7 @@ module Spoom
28
28
  T::Array[String],
29
29
  )
30
30
 
31
- SIGIL_REGEXP = T.let(/^#[\ t]*typed[\ t]*:[ \t]*(\w*)[ \t]*/, Regexp)
31
+ SIGIL_REGEXP = T.let(/^#[[:blank:]]*typed:[[:blank:]]*(\S*)/, Regexp)
32
32
 
33
33
  class << self
34
34
  extend T::Sig
@@ -61,7 +61,7 @@ module Spoom
61
61
  # * returns nil if no sigil
62
62
  sig { params(path: T.any(String, Pathname)).returns(T.nilable(String)) }
63
63
  def file_strictness(path)
64
- return nil unless File.file?(path)
64
+ return unless File.file?(path)
65
65
 
66
66
  content = File.read(path, encoding: Encoding::ASCII_8BIT)
67
67
  strictness_in_content(content)
data/lib/spoom/sorbet.rb CHANGED
@@ -35,6 +35,7 @@ module Spoom
35
35
 
36
36
  CONFIG_PATH = "sorbet/config"
37
37
  GEM_PATH = T.let(Gem::Specification.find_by_name("sorbet-static").full_gem_path, String)
38
+ GEM_VERSION = T.let(Gem::Specification.find_by_name("sorbet-static-and-runtime").version.to_s, String)
38
39
  BIN_PATH = T.let((Pathname.new(GEM_PATH) / "libexec" / "sorbet").to_s, String)
39
40
 
40
41
  KILLED_CODE = 137
data/lib/spoom/version.rb CHANGED
@@ -2,5 +2,5 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module Spoom
5
- VERSION = "1.2.2"
5
+ VERSION = "1.2.3"
6
6
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spoom
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.2
4
+ version: 1.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alexandre Terrasa
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-06-21 00:00:00.000000000 Z
11
+ date: 2023-08-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -81,7 +81,7 @@ dependencies:
81
81
  - !ruby/object:Gem::Version
82
82
  version: 1.10.0
83
83
  - !ruby/object:Gem::Dependency
84
- name: sorbet
84
+ name: sorbet-static-and-runtime
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
87
  - - ">="
@@ -94,20 +94,6 @@ dependencies:
94
94
  - - ">="
95
95
  - !ruby/object:Gem::Version
96
96
  version: 0.5.10187
97
- - !ruby/object:Gem::Dependency
98
- name: sorbet-runtime
99
- requirement: !ruby/object:Gem::Requirement
100
- requirements:
101
- - - ">="
102
- - !ruby/object:Gem::Version
103
- version: 0.5.9204
104
- type: :runtime
105
- prerelease: false
106
- version_requirements: !ruby/object:Gem::Requirement
107
- requirements:
108
- - - ">="
109
- - !ruby/object:Gem::Version
110
- version: 0.5.9204
111
97
  - !ruby/object:Gem::Dependency
112
98
  name: syntax_tree
113
99
  requirement: !ruby/object:Gem::Requirement
@@ -177,6 +163,9 @@ files:
177
163
  - lib/spoom/deadcode/index.rb
178
164
  - lib/spoom/deadcode/indexer.rb
179
165
  - lib/spoom/deadcode/location.rb
166
+ - lib/spoom/deadcode/plugins.rb
167
+ - lib/spoom/deadcode/plugins/base.rb
168
+ - lib/spoom/deadcode/plugins/ruby.rb
180
169
  - lib/spoom/deadcode/reference.rb
181
170
  - lib/spoom/deadcode/send.rb
182
171
  - lib/spoom/file_collector.rb
@@ -216,7 +205,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
216
205
  - !ruby/object:Gem::Version
217
206
  version: '0'
218
207
  requirements: []
219
- rubygems_version: 3.4.14
208
+ rubygems_version: 3.4.17
220
209
  signing_key:
221
210
  specification_version: 4
222
211
  summary: Useful tools for Sorbet enthusiasts.