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 +4 -4
- data/lib/spoom/cli/coverage.rb +1 -1
- data/lib/spoom/context/git.rb +4 -4
- data/lib/spoom/context/sorbet.rb +6 -6
- data/lib/spoom/deadcode/indexer.rb +13 -4
- data/lib/spoom/deadcode/location.rb +1 -1
- data/lib/spoom/deadcode/plugins/base.rb +201 -0
- data/lib/spoom/deadcode/plugins/ruby.rb +64 -0
- data/lib/spoom/deadcode/plugins.rb +5 -0
- data/lib/spoom/deadcode.rb +7 -6
- data/lib/spoom/sorbet/lsp.rb +2 -2
- data/lib/spoom/sorbet/sigils.rb +2 -2
- data/lib/spoom/sorbet.rb +1 -0
- data/lib/spoom/version.rb +1 -1
- metadata +7 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8e7ef8ebef70bc8827cdcb4b2c0e49ed6c53686e0db409908354f3762ad07c10
|
4
|
+
data.tar.gz: a6adb405f0379cbe040e743f177e758e2bdaadcdea13ee9c7f75d84f764434b1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 86d74bc7d9554d67c1421908116bbab7615d77e9cb096d461f7885429d495f2b02f19d6024117f7083423cfe7c48165b18918c143f29574896bfbb76a4fb651f
|
7
|
+
data.tar.gz: 754d41e8f26425a42288388879fe1658214adea03002421495297486343a827d6dc79a395e895553ed15f67cdc766a16f4a174aab2a3671bd2455e305a8c6f13
|
data/lib/spoom/cli/coverage.rb
CHANGED
data/lib/spoom/context/git.rb
CHANGED
@@ -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
|
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
|
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
|
106
|
+
return unless res.status
|
107
107
|
|
108
108
|
out = res.out.strip
|
109
|
-
return
|
109
|
+
return if out.empty?
|
110
110
|
|
111
111
|
Spoom::Git::Commit.parse_line(out)
|
112
112
|
end
|
data/lib/spoom/context/sorbet.rb
CHANGED
@@ -52,7 +52,7 @@ module Spoom
|
|
52
52
|
sorbet_bin: sorbet_bin,
|
53
53
|
capture_err: capture_err,
|
54
54
|
)
|
55
|
-
return
|
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
|
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
|
150
|
+
return unless res.status
|
151
151
|
|
152
152
|
out = res.out.strip
|
153
|
-
return
|
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
|
162
|
+
return unless res.status
|
163
163
|
|
164
164
|
out = res.out.strip
|
165
|
-
return
|
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
|
@@ -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
|
data/lib/spoom/deadcode.rb
CHANGED
@@ -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
|
data/lib/spoom/sorbet/lsp.rb
CHANGED
@@ -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
|
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
|
104
|
+
return unless json && json["result"]
|
105
105
|
|
106
106
|
Hover.from_json(json["result"])
|
107
107
|
end
|
data/lib/spoom/sorbet/sigils.rb
CHANGED
@@ -28,7 +28,7 @@ module Spoom
|
|
28
28
|
T::Array[String],
|
29
29
|
)
|
30
30
|
|
31
|
-
SIGIL_REGEXP = T.let(/^#[
|
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
|
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
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.
|
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-
|
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.
|
208
|
+
rubygems_version: 3.4.17
|
220
209
|
signing_key:
|
221
210
|
specification_version: 4
|
222
211
|
summary: Useful tools for Sorbet enthusiasts.
|