spoom 1.5.4 → 1.6.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.
- checksums.yaml +4 -4
- data/lib/spoom/backtrace_filter/minitest.rb +2 -3
- data/lib/spoom/cli/deadcode.rb +1 -2
- data/lib/spoom/cli/helper.rb +36 -28
- data/lib/spoom/cli/srb/assertions.rb +48 -0
- data/lib/spoom/cli/srb/bump.rb +1 -2
- data/lib/spoom/cli/srb/sigs.rb +133 -18
- data/lib/spoom/cli/srb.rb +8 -4
- data/lib/spoom/cli.rb +1 -2
- data/lib/spoom/colors.rb +2 -6
- data/lib/spoom/context/bundle.rb +8 -9
- data/lib/spoom/context/exec.rb +2 -5
- data/lib/spoom/context/file_system.rb +12 -19
- data/lib/spoom/context/git.rb +14 -19
- data/lib/spoom/context/sorbet.rb +13 -26
- data/lib/spoom/context.rb +3 -7
- data/lib/spoom/coverage/d3/base.rb +6 -8
- data/lib/spoom/coverage/d3/circle_map.rb +6 -16
- data/lib/spoom/coverage/d3/pie.rb +14 -19
- data/lib/spoom/coverage/d3/timeline.rb +46 -47
- data/lib/spoom/coverage/d3.rb +2 -4
- data/lib/spoom/coverage/report.rb +38 -76
- data/lib/spoom/coverage/snapshot.rb +7 -13
- data/lib/spoom/coverage.rb +3 -5
- data/lib/spoom/deadcode/definition.rb +12 -14
- data/lib/spoom/deadcode/erb.rb +10 -8
- data/lib/spoom/deadcode/index.rb +19 -23
- data/lib/spoom/deadcode/indexer.rb +5 -6
- data/lib/spoom/deadcode/plugins/action_mailer.rb +2 -3
- data/lib/spoom/deadcode/plugins/action_mailer_preview.rb +2 -3
- data/lib/spoom/deadcode/plugins/actionpack.rb +4 -4
- data/lib/spoom/deadcode/plugins/active_model.rb +2 -3
- data/lib/spoom/deadcode/plugins/active_record.rb +2 -3
- data/lib/spoom/deadcode/plugins/active_support.rb +2 -1
- data/lib/spoom/deadcode/plugins/base.rb +29 -32
- data/lib/spoom/deadcode/plugins/graphql.rb +2 -3
- data/lib/spoom/deadcode/plugins/minitest.rb +4 -4
- data/lib/spoom/deadcode/plugins/namespaces.rb +5 -5
- data/lib/spoom/deadcode/plugins/rails.rb +5 -5
- data/lib/spoom/deadcode/plugins/rubocop.rb +4 -4
- data/lib/spoom/deadcode/plugins/ruby.rb +3 -4
- data/lib/spoom/deadcode/plugins/sorbet.rb +12 -6
- data/lib/spoom/deadcode/plugins/thor.rb +2 -3
- data/lib/spoom/deadcode/plugins.rb +2 -4
- data/lib/spoom/deadcode/remover.rb +37 -59
- data/lib/spoom/deadcode/send.rb +2 -8
- data/lib/spoom/file_collector.rb +10 -18
- data/lib/spoom/file_tree.rb +31 -46
- data/lib/spoom/location.rb +9 -20
- data/lib/spoom/model/builder.rb +60 -15
- data/lib/spoom/model/model.rb +65 -68
- data/lib/spoom/model/namespace_visitor.rb +3 -2
- data/lib/spoom/model/reference.rb +4 -8
- data/lib/spoom/model/references_visitor.rb +49 -29
- data/lib/spoom/parse.rb +17 -3
- data/lib/spoom/poset.rb +17 -19
- data/lib/spoom/printer.rb +10 -13
- data/lib/spoom/sorbet/assertions.rb +278 -0
- data/lib/spoom/sorbet/config.rb +8 -12
- data/lib/spoom/sorbet/errors.rb +16 -31
- data/lib/spoom/sorbet/lsp/base.rb +9 -15
- data/lib/spoom/sorbet/lsp/errors.rb +8 -16
- data/lib/spoom/sorbet/lsp/structures.rb +36 -59
- data/lib/spoom/sorbet/lsp.rb +15 -17
- data/lib/spoom/sorbet/metrics.rb +3 -5
- data/lib/spoom/sorbet/sigils.rb +7 -11
- data/lib/spoom/sorbet/sigs.rb +118 -25
- data/lib/spoom/sorbet.rb +3 -9
- data/lib/spoom/timeline.rb +4 -6
- data/lib/spoom/version.rb +1 -1
- data/lib/spoom/visitor.rb +298 -151
- data/lib/spoom.rb +0 -2
- data/rbi/spoom.rbi +3963 -0
- metadata +6 -3
data/lib/spoom/model/model.rb
CHANGED
@@ -3,46 +3,57 @@
|
|
3
3
|
|
4
4
|
module Spoom
|
5
5
|
class Model
|
6
|
-
extend T::Sig
|
7
|
-
|
8
6
|
class Error < Spoom::Error; end
|
9
7
|
|
8
|
+
class Comment
|
9
|
+
#: String
|
10
|
+
attr_reader :string
|
11
|
+
|
12
|
+
#: Location
|
13
|
+
attr_reader :location
|
14
|
+
|
15
|
+
#: (String string, Location location) -> void
|
16
|
+
def initialize(string, location)
|
17
|
+
@string = string
|
18
|
+
@location = location
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
10
22
|
# A Symbol is a uniquely named entity in the Ruby codebase
|
11
23
|
#
|
12
24
|
# A symbol can have multiple definitions, e.g. a class can be reopened.
|
13
25
|
# Sometimes a symbol can have multiple definitions of different types,
|
14
26
|
# e.g. `foo` method can be defined both as a method and as an attribute accessor.
|
15
27
|
class Symbol
|
16
|
-
extend T::Sig
|
17
|
-
|
18
28
|
# The full, unique name of this symbol
|
19
|
-
|
29
|
+
#: String
|
20
30
|
attr_reader :full_name
|
21
31
|
|
22
32
|
# The definitions of this symbol (where it exists in the code)
|
23
|
-
|
33
|
+
#: Array[SymbolDef]
|
24
34
|
attr_reader :definitions
|
25
35
|
|
26
|
-
|
36
|
+
#: (String full_name) -> void
|
27
37
|
def initialize(full_name)
|
28
38
|
@full_name = full_name
|
29
39
|
@definitions = T.let([], T::Array[SymbolDef])
|
30
40
|
end
|
31
41
|
|
32
42
|
# The short name of this symbol
|
33
|
-
|
43
|
+
#: -> String
|
34
44
|
def name
|
35
45
|
T.must(@full_name.split("::").last)
|
36
46
|
end
|
37
47
|
|
38
|
-
|
48
|
+
#: -> String
|
39
49
|
def to_s
|
40
50
|
@full_name
|
41
51
|
end
|
42
52
|
end
|
43
53
|
|
44
54
|
class UnresolvedSymbol < Symbol
|
45
|
-
|
55
|
+
# @override
|
56
|
+
#: -> String
|
46
57
|
def to_s
|
47
58
|
"<#{@full_name}>"
|
48
59
|
end
|
@@ -53,41 +64,45 @@ module Spoom
|
|
53
64
|
# It can be a class, module, constant, method, etc.
|
54
65
|
# A SymbolDef has a location pointing to the actual code that defines the symbol.
|
55
66
|
class SymbolDef
|
56
|
-
extend T::Sig
|
57
67
|
extend T::Helpers
|
58
68
|
|
59
69
|
abstract!
|
60
70
|
|
61
71
|
# The symbol this definition belongs to
|
62
|
-
|
72
|
+
#: Symbol
|
63
73
|
attr_reader :symbol
|
64
74
|
|
65
75
|
# The enclosing namespace this definition belongs to
|
66
|
-
|
76
|
+
#: Namespace?
|
67
77
|
attr_reader :owner
|
68
78
|
|
69
79
|
# The actual code location of this definition
|
70
|
-
|
80
|
+
#: Location
|
71
81
|
attr_reader :location
|
72
82
|
|
73
|
-
|
74
|
-
|
83
|
+
# The comments associated with this definition
|
84
|
+
#: Array[Comment]
|
85
|
+
attr_reader :comments
|
86
|
+
|
87
|
+
#: (Symbol symbol, owner: Namespace?, location: Location, ?comments: Array[Comment]) -> void
|
88
|
+
def initialize(symbol, owner:, location:, comments:)
|
75
89
|
@symbol = symbol
|
76
90
|
@owner = owner
|
77
91
|
@location = location
|
92
|
+
@comments = comments
|
78
93
|
|
79
94
|
symbol.definitions << self
|
80
95
|
owner.children << self if owner
|
81
96
|
end
|
82
97
|
|
83
98
|
# The full name of the symbol this definition belongs to
|
84
|
-
|
99
|
+
#: -> String
|
85
100
|
def full_name
|
86
101
|
@symbol.full_name
|
87
102
|
end
|
88
103
|
|
89
104
|
# The short name of the symbol this definition belongs to
|
90
|
-
|
105
|
+
#: -> String
|
91
106
|
def name
|
92
107
|
@symbol.name
|
93
108
|
end
|
@@ -97,15 +112,15 @@ module Spoom
|
|
97
112
|
class Namespace < SymbolDef
|
98
113
|
abstract!
|
99
114
|
|
100
|
-
|
115
|
+
#: Array[SymbolDef]
|
101
116
|
attr_reader :children
|
102
117
|
|
103
|
-
|
118
|
+
#: Array[Mixin]
|
104
119
|
attr_reader :mixins
|
105
120
|
|
106
|
-
|
107
|
-
def initialize(symbol, owner:, location:)
|
108
|
-
super(symbol, owner: owner, location: location)
|
121
|
+
#: (Symbol symbol, owner: Namespace?, location: Location, ?comments: Array[Comment]) -> void
|
122
|
+
def initialize(symbol, owner:, location:, comments: [])
|
123
|
+
super(symbol, owner: owner, location: location, comments: comments)
|
109
124
|
|
110
125
|
@children = T.let([], T::Array[SymbolDef])
|
111
126
|
@mixins = T.let([], T::Array[Mixin])
|
@@ -115,19 +130,12 @@ module Spoom
|
|
115
130
|
class SingletonClass < Namespace; end
|
116
131
|
|
117
132
|
class Class < Namespace
|
118
|
-
|
133
|
+
#: String?
|
119
134
|
attr_accessor :superclass_name
|
120
135
|
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
owner: T.nilable(Namespace),
|
125
|
-
location: Location,
|
126
|
-
superclass_name: T.nilable(String),
|
127
|
-
).void
|
128
|
-
end
|
129
|
-
def initialize(symbol, owner:, location:, superclass_name: nil)
|
130
|
-
super(symbol, owner: owner, location: location)
|
136
|
+
#: (Symbol symbol, owner: Namespace?, location: Location, ?superclass_name: String?, ?comments: Array[Comment]) -> void
|
137
|
+
def initialize(symbol, owner:, location:, superclass_name: nil, comments: [])
|
138
|
+
super(symbol, owner: owner, location: location, comments: comments)
|
131
139
|
|
132
140
|
@superclass_name = superclass_name
|
133
141
|
end
|
@@ -136,12 +144,12 @@ module Spoom
|
|
136
144
|
class Module < Namespace; end
|
137
145
|
|
138
146
|
class Constant < SymbolDef
|
139
|
-
|
147
|
+
#: String
|
140
148
|
attr_reader :value
|
141
149
|
|
142
|
-
|
143
|
-
def initialize(symbol, owner:, location:, value:)
|
144
|
-
super(symbol, owner: owner, location: location)
|
150
|
+
#: (Symbol symbol, owner: Namespace?, location: Location, value: String, ?comments: Array[Comment]) -> void
|
151
|
+
def initialize(symbol, owner:, location:, value:, comments: [])
|
152
|
+
super(symbol, owner: owner, location: location, comments: comments)
|
145
153
|
|
146
154
|
@value = value
|
147
155
|
end
|
@@ -151,23 +159,15 @@ module Spoom
|
|
151
159
|
class Property < SymbolDef
|
152
160
|
abstract!
|
153
161
|
|
154
|
-
|
162
|
+
#: Visibility
|
155
163
|
attr_reader :visibility
|
156
164
|
|
157
|
-
|
165
|
+
#: Array[Sig]
|
158
166
|
attr_reader :sigs
|
159
167
|
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
owner: T.nilable(Namespace),
|
164
|
-
location: Location,
|
165
|
-
visibility: Visibility,
|
166
|
-
sigs: T::Array[Sig],
|
167
|
-
).void
|
168
|
-
end
|
169
|
-
def initialize(symbol, owner:, location:, visibility:, sigs: [])
|
170
|
-
super(symbol, owner: owner, location: location)
|
168
|
+
#: (Symbol symbol, owner: Namespace?, location: Location, visibility: Visibility, ?sigs: Array[Sig], ?comments: Array[Comment]) -> void
|
169
|
+
def initialize(symbol, owner:, location:, visibility:, sigs: [], comments: [])
|
170
|
+
super(symbol, owner: owner, location: location, comments: comments)
|
171
171
|
|
172
172
|
@visibility = visibility
|
173
173
|
@sigs = sigs
|
@@ -194,15 +194,14 @@ module Spoom
|
|
194
194
|
|
195
195
|
# A mixin (include, prepend, extend) to a namespace
|
196
196
|
class Mixin
|
197
|
-
extend T::Sig
|
198
197
|
extend T::Helpers
|
199
198
|
|
200
199
|
abstract!
|
201
200
|
|
202
|
-
|
201
|
+
#: String
|
203
202
|
attr_reader :name
|
204
203
|
|
205
|
-
|
204
|
+
#: (String name) -> void
|
206
205
|
def initialize(name)
|
207
206
|
@name = name
|
208
207
|
end
|
@@ -214,12 +213,10 @@ module Spoom
|
|
214
213
|
|
215
214
|
# A Sorbet signature (sig block)
|
216
215
|
class Sig
|
217
|
-
|
218
|
-
|
219
|
-
sig { returns(String) }
|
216
|
+
#: String
|
220
217
|
attr_reader :string
|
221
218
|
|
222
|
-
|
219
|
+
#: (String string) -> void
|
223
220
|
def initialize(string)
|
224
221
|
@string = string
|
225
222
|
end
|
@@ -228,13 +225,13 @@ module Spoom
|
|
228
225
|
# Model
|
229
226
|
|
230
227
|
# All the symbols registered in this model
|
231
|
-
|
228
|
+
#: Hash[String, Symbol]
|
232
229
|
attr_reader :symbols
|
233
230
|
|
234
|
-
|
231
|
+
#: Poset[Symbol]
|
235
232
|
attr_reader :symbols_hierarchy
|
236
233
|
|
237
|
-
|
234
|
+
#: -> void
|
238
235
|
def initialize
|
239
236
|
@symbols = T.let({}, T::Hash[String, Symbol])
|
240
237
|
@symbols_hierarchy = T.let(Poset[Symbol].new, Poset[Symbol])
|
@@ -243,7 +240,7 @@ module Spoom
|
|
243
240
|
# Get a symbol by it's full name
|
244
241
|
#
|
245
242
|
# Raises an error if the symbol is not found
|
246
|
-
|
243
|
+
#: (String full_name) -> Symbol
|
247
244
|
def [](full_name)
|
248
245
|
symbol = @symbols[full_name]
|
249
246
|
raise Error, "Symbol not found: #{full_name}" unless symbol
|
@@ -254,12 +251,12 @@ module Spoom
|
|
254
251
|
# Register a new symbol by it's full name
|
255
252
|
#
|
256
253
|
# If the symbol already exists, it will be returned.
|
257
|
-
|
254
|
+
#: (String full_name) -> Symbol
|
258
255
|
def register_symbol(full_name)
|
259
256
|
@symbols[full_name] ||= Symbol.new(full_name)
|
260
257
|
end
|
261
258
|
|
262
|
-
|
259
|
+
#: (String full_name, context: Symbol) -> Symbol
|
263
260
|
def resolve_symbol(full_name, context:)
|
264
261
|
if full_name.start_with?("::")
|
265
262
|
full_name = full_name.delete_prefix("::")
|
@@ -280,26 +277,26 @@ module Spoom
|
|
280
277
|
@symbols[full_name] = UnresolvedSymbol.new(full_name)
|
281
278
|
end
|
282
279
|
|
283
|
-
|
280
|
+
#: (Symbol symbol) -> Array[Symbol]
|
284
281
|
def supertypes(symbol)
|
285
282
|
poe = @symbols_hierarchy[symbol]
|
286
283
|
poe.ancestors
|
287
284
|
end
|
288
285
|
|
289
|
-
|
286
|
+
#: (Symbol symbol) -> Array[Symbol]
|
290
287
|
def subtypes(symbol)
|
291
288
|
poe = @symbols_hierarchy[symbol]
|
292
289
|
poe.descendants
|
293
290
|
end
|
294
291
|
|
295
|
-
|
292
|
+
#: -> void
|
296
293
|
def finalize!
|
297
294
|
compute_symbols_hierarchy!
|
298
295
|
end
|
299
296
|
|
300
297
|
private
|
301
298
|
|
302
|
-
|
299
|
+
#: -> void
|
303
300
|
def compute_symbols_hierarchy!
|
304
301
|
@symbols.dup.each do |_full_name, symbol|
|
305
302
|
symbol.definitions.each do |definition|
|
@@ -8,14 +8,15 @@ module Spoom
|
|
8
8
|
|
9
9
|
abstract!
|
10
10
|
|
11
|
-
|
11
|
+
#: -> void
|
12
12
|
def initialize
|
13
13
|
super()
|
14
14
|
|
15
15
|
@names_nesting = T.let([], T::Array[String])
|
16
16
|
end
|
17
17
|
|
18
|
-
|
18
|
+
# @override
|
19
|
+
#: (Prism::Node? node) -> void
|
19
20
|
def visit(node)
|
20
21
|
case node
|
21
22
|
when Prism::ClassNode, Prism::ModuleNode
|
@@ -8,8 +8,6 @@ module Spoom
|
|
8
8
|
# Constants could be classes, modules, or actual constants.
|
9
9
|
# Methods could be accessors, instance or class methods, aliases, etc.
|
10
10
|
class Reference < T::Struct
|
11
|
-
extend T::Sig
|
12
|
-
|
13
11
|
class Kind < T::Enum
|
14
12
|
enums do
|
15
13
|
Constant = new("constant")
|
@@ -18,14 +16,12 @@ module Spoom
|
|
18
16
|
end
|
19
17
|
|
20
18
|
class << self
|
21
|
-
|
22
|
-
|
23
|
-
sig { params(name: String, location: Spoom::Location).returns(Reference) }
|
19
|
+
#: (String name, Spoom::Location location) -> Reference
|
24
20
|
def constant(name, location)
|
25
21
|
new(name: name, kind: Kind::Constant, location: location)
|
26
22
|
end
|
27
23
|
|
28
|
-
|
24
|
+
#: (String name, Spoom::Location location) -> Reference
|
29
25
|
def method(name, location)
|
30
26
|
new(name: name, kind: Kind::Method, location: location)
|
31
27
|
end
|
@@ -35,12 +31,12 @@ module Spoom
|
|
35
31
|
const :name, String
|
36
32
|
const :location, Spoom::Location
|
37
33
|
|
38
|
-
|
34
|
+
#: -> bool
|
39
35
|
def constant?
|
40
36
|
kind == Kind::Constant
|
41
37
|
end
|
42
38
|
|
43
|
-
|
39
|
+
#: -> bool
|
44
40
|
def method?
|
45
41
|
kind == Kind::Method
|
46
42
|
end
|
@@ -5,12 +5,10 @@ module Spoom
|
|
5
5
|
class Model
|
6
6
|
# Visit a file to collect all the references to constants and methods
|
7
7
|
class ReferencesVisitor < Visitor
|
8
|
-
|
9
|
-
|
10
|
-
sig { returns(T::Array[Reference]) }
|
8
|
+
#: Array[Reference]
|
11
9
|
attr_reader :references
|
12
10
|
|
13
|
-
|
11
|
+
#: (String file) -> void
|
14
12
|
def initialize(file)
|
15
13
|
super()
|
16
14
|
|
@@ -18,18 +16,21 @@ module Spoom
|
|
18
16
|
@references = T.let([], T::Array[Reference])
|
19
17
|
end
|
20
18
|
|
21
|
-
|
19
|
+
# @override
|
20
|
+
#: (Prism::AliasMethodNode node) -> void
|
22
21
|
def visit_alias_method_node(node)
|
23
22
|
reference_method(node.old_name.slice, node)
|
24
23
|
end
|
25
24
|
|
26
|
-
|
25
|
+
# @override
|
26
|
+
#: (Prism::AndNode node) -> void
|
27
27
|
def visit_and_node(node)
|
28
28
|
reference_method(node.operator_loc.slice, node)
|
29
29
|
super
|
30
30
|
end
|
31
31
|
|
32
|
-
|
32
|
+
# @override
|
33
|
+
#: (Prism::BlockArgumentNode node) -> void
|
33
34
|
def visit_block_argument_node(node)
|
34
35
|
expression = node.expression
|
35
36
|
case expression
|
@@ -40,7 +41,8 @@ module Spoom
|
|
40
41
|
end
|
41
42
|
end
|
42
43
|
|
43
|
-
|
44
|
+
# @override
|
45
|
+
#: (Prism::CallAndWriteNode node) -> void
|
44
46
|
def visit_call_and_write_node(node)
|
45
47
|
visit(node.receiver)
|
46
48
|
reference_method(node.read_name.to_s, node)
|
@@ -48,7 +50,8 @@ module Spoom
|
|
48
50
|
visit(node.value)
|
49
51
|
end
|
50
52
|
|
51
|
-
|
53
|
+
# @override
|
54
|
+
#: (Prism::CallOperatorWriteNode node) -> void
|
52
55
|
def visit_call_operator_write_node(node)
|
53
56
|
visit(node.receiver)
|
54
57
|
reference_method(node.read_name.to_s, node)
|
@@ -56,7 +59,8 @@ module Spoom
|
|
56
59
|
visit(node.value)
|
57
60
|
end
|
58
61
|
|
59
|
-
|
62
|
+
# @override
|
63
|
+
#: (Prism::CallOrWriteNode node) -> void
|
60
64
|
def visit_call_or_write_node(node)
|
61
65
|
visit(node.receiver)
|
62
66
|
reference_method(node.read_name.to_s, node)
|
@@ -64,7 +68,8 @@ module Spoom
|
|
64
68
|
visit(node.value)
|
65
69
|
end
|
66
70
|
|
67
|
-
|
71
|
+
# @override
|
72
|
+
#: (Prism::CallNode node) -> void
|
68
73
|
def visit_call_node(node)
|
69
74
|
visit(node.receiver)
|
70
75
|
|
@@ -81,53 +86,62 @@ module Spoom
|
|
81
86
|
visit(node.block)
|
82
87
|
end
|
83
88
|
|
84
|
-
|
89
|
+
# @override
|
90
|
+
#: (Prism::ClassNode node) -> void
|
85
91
|
def visit_class_node(node)
|
86
92
|
visit(node.superclass) if node.superclass
|
87
93
|
visit(node.body)
|
88
94
|
end
|
89
95
|
|
90
|
-
|
96
|
+
# @override
|
97
|
+
#: (Prism::ConstantAndWriteNode node) -> void
|
91
98
|
def visit_constant_and_write_node(node)
|
92
99
|
reference_constant(node.name.to_s, node)
|
93
100
|
visit(node.value)
|
94
101
|
end
|
95
102
|
|
96
|
-
|
103
|
+
# @override
|
104
|
+
#: (Prism::ConstantOperatorWriteNode node) -> void
|
97
105
|
def visit_constant_operator_write_node(node)
|
98
106
|
reference_constant(node.name.to_s, node)
|
99
107
|
visit(node.value)
|
100
108
|
end
|
101
109
|
|
102
|
-
|
110
|
+
# @override
|
111
|
+
#: (Prism::ConstantOrWriteNode node) -> void
|
103
112
|
def visit_constant_or_write_node(node)
|
104
113
|
reference_constant(node.name.to_s, node)
|
105
114
|
visit(node.value)
|
106
115
|
end
|
107
116
|
|
108
|
-
|
117
|
+
# @override
|
118
|
+
#: (Prism::ConstantPathNode node) -> void
|
109
119
|
def visit_constant_path_node(node)
|
110
120
|
visit(node.parent)
|
111
121
|
reference_constant(node.name.to_s, node)
|
112
122
|
end
|
113
123
|
|
114
|
-
|
124
|
+
# @override
|
125
|
+
#: (Prism::ConstantPathWriteNode node) -> void
|
115
126
|
def visit_constant_path_write_node(node)
|
116
127
|
visit(node.target.parent)
|
117
128
|
visit(node.value)
|
118
129
|
end
|
119
130
|
|
120
|
-
|
131
|
+
# @override
|
132
|
+
#: (Prism::ConstantReadNode node) -> void
|
121
133
|
def visit_constant_read_node(node)
|
122
134
|
reference_constant(node.name.to_s, node)
|
123
135
|
end
|
124
136
|
|
125
|
-
|
137
|
+
# @override
|
138
|
+
#: (Prism::ConstantWriteNode node) -> void
|
126
139
|
def visit_constant_write_node(node)
|
127
140
|
visit(node.value)
|
128
141
|
end
|
129
142
|
|
130
|
-
|
143
|
+
# @override
|
144
|
+
#: (Prism::LocalVariableAndWriteNode node) -> void
|
131
145
|
def visit_local_variable_and_write_node(node)
|
132
146
|
name = node.name.to_s
|
133
147
|
reference_method(name, node)
|
@@ -135,7 +149,8 @@ module Spoom
|
|
135
149
|
visit(node.value)
|
136
150
|
end
|
137
151
|
|
138
|
-
|
152
|
+
# @override
|
153
|
+
#: (Prism::LocalVariableOperatorWriteNode node) -> void
|
139
154
|
def visit_local_variable_operator_write_node(node)
|
140
155
|
name = node.name.to_s
|
141
156
|
reference_method(name, node)
|
@@ -143,7 +158,8 @@ module Spoom
|
|
143
158
|
visit(node.value)
|
144
159
|
end
|
145
160
|
|
146
|
-
|
161
|
+
# @override
|
162
|
+
#: (Prism::LocalVariableOrWriteNode node) -> void
|
147
163
|
def visit_local_variable_or_write_node(node)
|
148
164
|
name = node.name.to_s
|
149
165
|
reference_method(name, node)
|
@@ -151,18 +167,21 @@ module Spoom
|
|
151
167
|
visit(node.value)
|
152
168
|
end
|
153
169
|
|
154
|
-
|
170
|
+
# @override
|
171
|
+
#: (Prism::LocalVariableWriteNode node) -> void
|
155
172
|
def visit_local_variable_write_node(node)
|
156
173
|
reference_method("#{node.name}=", node)
|
157
174
|
visit(node.value)
|
158
175
|
end
|
159
176
|
|
160
|
-
|
177
|
+
# @override
|
178
|
+
#: (Prism::ModuleNode node) -> void
|
161
179
|
def visit_module_node(node)
|
162
180
|
visit(node.body)
|
163
181
|
end
|
164
182
|
|
165
|
-
|
183
|
+
# @override
|
184
|
+
#: (Prism::MultiWriteNode node) -> void
|
166
185
|
def visit_multi_write_node(node)
|
167
186
|
node.lefts.each do |const|
|
168
187
|
case const
|
@@ -173,7 +192,8 @@ module Spoom
|
|
173
192
|
visit(node.value)
|
174
193
|
end
|
175
194
|
|
176
|
-
|
195
|
+
# @override
|
196
|
+
#: (Prism::OrNode node) -> void
|
177
197
|
def visit_or_node(node)
|
178
198
|
reference_method(node.operator_loc.slice, node)
|
179
199
|
super
|
@@ -181,17 +201,17 @@ module Spoom
|
|
181
201
|
|
182
202
|
private
|
183
203
|
|
184
|
-
|
204
|
+
#: (String name, Prism::Node node) -> void
|
185
205
|
def reference_constant(name, node)
|
186
206
|
@references << Reference.constant(name, node_location(node))
|
187
207
|
end
|
188
208
|
|
189
|
-
|
209
|
+
#: (String name, Prism::Node node) -> void
|
190
210
|
def reference_method(name, node)
|
191
211
|
@references << Reference.method(name, node_location(node))
|
192
212
|
end
|
193
213
|
|
194
|
-
|
214
|
+
#: (Prism::Node node) -> Location
|
195
215
|
def node_location(node)
|
196
216
|
Location.from_prism(@file, node.location)
|
197
217
|
end
|
data/lib/spoom/parse.rb
CHANGED
@@ -7,9 +7,7 @@ module Spoom
|
|
7
7
|
class ParseError < Error; end
|
8
8
|
|
9
9
|
class << self
|
10
|
-
|
11
|
-
|
12
|
-
sig { params(ruby: String, file: String).returns(Prism::Node) }
|
10
|
+
#: (String ruby, file: String) -> Prism::Node
|
13
11
|
def parse_ruby(ruby, file:)
|
14
12
|
result = Prism.parse(ruby)
|
15
13
|
unless result.success?
|
@@ -24,5 +22,21 @@ module Spoom
|
|
24
22
|
|
25
23
|
result.value
|
26
24
|
end
|
25
|
+
|
26
|
+
#: (String ruby, file: String) -> [Prism::Node, Array[Prism::Comment]]
|
27
|
+
def parse_ruby_with_comments(ruby, file:)
|
28
|
+
result = Prism.parse(ruby)
|
29
|
+
unless result.success?
|
30
|
+
message = +"Error while parsing #{file}:\n"
|
31
|
+
|
32
|
+
result.errors.each do |e|
|
33
|
+
message << "- #{e.message} (at #{e.location.start_line}:#{e.location.start_column})\n"
|
34
|
+
end
|
35
|
+
|
36
|
+
raise ParseError, message
|
37
|
+
end
|
38
|
+
|
39
|
+
[result.value, result.comments]
|
40
|
+
end
|
27
41
|
end
|
28
42
|
end
|