spoom 1.7.2 → 1.7.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: 59987238a3b2bae115f02d1da2a7e2a4cd6b3532d816bbe80d9153fa7819f989
4
- data.tar.gz: d7e6bccfa046b7c457cb3e5d3d4383141243949021bd584b22cde0db0cc165ef
3
+ metadata.gz: c8447b66e12a52fef3147761f8331749ba52cebaaba146888a7ca35a253acdf9
4
+ data.tar.gz: d6a84c3091e71c56d26aceebb40f3a6486589266c0b9b984268bf32036b98a26
5
5
  SHA512:
6
- metadata.gz: b2f53478b7fdee59bfa7c579c3686b6d6c388db8737584c02f613daa2c4d42c0be2c1baaa39c50e90137697f62d7b8bb04e9fdbb458defdfa7813be3b6cbbd36
7
- data.tar.gz: 57b26d457d2235bedaff15c832accc34a9c5ffcb89876306394f12b74a87ce03964d0309cd62e213e9954607150968607227436ebeb522a84f27782f7cc8cac8
6
+ metadata.gz: 9827d000700721b1e30028eedcaf41c5e5e45811e1b62693dbaa2d859b5adf379c5f5da4acbaac8e0a0a78a8bb4928fbd5d8a395b5527a7c1f3fc0a72f207cc3
7
+ data.tar.gz: a7c46380dc2e26c622b8b96290964ede0b5f455d060a176d1336db3aa09ca3e7dbccb656d7a6c1451e43406b0e9cf7847b9a985418b905ae8114c20dae294240
data/Gemfile CHANGED
@@ -5,6 +5,8 @@ source "https://rubygems.org"
5
5
 
6
6
  gemspec
7
7
 
8
+ gem "minitest"
9
+
8
10
  group :development do
9
11
  gem "debug"
10
12
  gem "rubocop-shopify", require: false
@@ -7,6 +7,25 @@ module Spoom
7
7
  class ActiveJob < Base
8
8
  ignore_classes_named("ApplicationJob")
9
9
  ignore_methods_named("perform", "build_enumerator", "each_iteration")
10
+
11
+ CALLBACKS = [
12
+ "after_enqueue",
13
+ "after_perform",
14
+ "around_enqueue",
15
+ "around_perform",
16
+ "before_enqueue",
17
+ "before_perform",
18
+ ].freeze
19
+
20
+ # @override
21
+ #: (Send send) -> void
22
+ def on_send(send)
23
+ return unless send.recv.nil? && CALLBACKS.include?(send.name)
24
+
25
+ send.each_arg(Prism::SymbolNode) do |arg|
26
+ @index.reference_method(arg.unescaped, send.location)
27
+ end
28
+ end
10
29
  end
11
30
  end
12
31
  end
data/lib/spoom/rbs.rb CHANGED
@@ -4,7 +4,7 @@
4
4
  module Spoom
5
5
  module RBS
6
6
  class Comments
7
- #: Array[Annotations]
7
+ #: Array[Annotation]
8
8
  attr_reader :annotations
9
9
 
10
10
  #: Array[Signature]
@@ -12,7 +12,7 @@ module Spoom
12
12
 
13
13
  #: -> void
14
14
  def initialize
15
- @annotations = [] #: Array[Annotations]
15
+ @annotations = [] #: Array[Annotation]
16
16
  @signatures = [] #: Array[Signature]
17
17
  end
18
18
 
@@ -20,6 +20,32 @@ module Spoom
20
20
  def empty?
21
21
  @annotations.empty? && @signatures.empty?
22
22
  end
23
+
24
+ #: -> Array[Annotation]
25
+ def class_annotations
26
+ @annotations.select do |annotation|
27
+ case annotation.string
28
+ when "@abstract", "@interface", "@sealed", "@final"
29
+ true
30
+ when /^@requires_ancestor: /
31
+ true
32
+ else
33
+ false
34
+ end
35
+ end
36
+ end
37
+
38
+ #: -> Array[Annotation]
39
+ def method_annotations
40
+ @annotations.select do |annotation|
41
+ case annotation.string
42
+ when "@abstract", "@final", "@override", "@override(allow_incompatible: true)", "@overridable", "@without_runtime"
43
+ true
44
+ else
45
+ false
46
+ end
47
+ end
48
+ end
23
49
  end
24
50
 
25
51
  class Comment
@@ -36,7 +62,7 @@ module Spoom
36
62
  end
37
63
  end
38
64
 
39
- class Annotations < Comment; end
65
+ class Annotation < Comment; end
40
66
  class Signature < Comment; end
41
67
 
42
68
  module ExtractRBSComments
@@ -54,7 +80,7 @@ module Spoom
54
80
 
55
81
  if string.start_with?("# @")
56
82
  string = string.delete_prefix("#").strip
57
- res.annotations << Annotations.new(string, comment.location)
83
+ res.annotations << Annotation.new(string, comment.location)
58
84
  elsif string.start_with?("#: ")
59
85
  string = string.delete_prefix("#:").strip
60
86
  location = comment.location
@@ -34,9 +34,6 @@ module Spoom
34
34
  class CodeMetricsVisitor < Spoom::Visitor
35
35
  include RBS::ExtractRBSComments
36
36
 
37
- #: Counters
38
- attr_reader :counters
39
-
40
37
  #: (Spoom::Counters) -> void
41
38
  def initialize(counters)
42
39
  super()
@@ -48,14 +48,14 @@ module Spoom
48
48
  translator = RBI::RBS::MethodTypeTranslator.new(rbi_node)
49
49
  translator.visit(method_type)
50
50
  sig = translator.result
51
- apply_member_annotations(comments.annotations, sig)
51
+ apply_member_annotations(comments.method_annotations, sig)
52
52
 
53
53
  @rewriter << Source::Replace.new(
54
54
  signature.location.start_offset,
55
55
  signature.location.end_offset,
56
56
  sig.string,
57
57
  )
58
- rescue ::RBS::ParsingError
58
+ rescue ::RBS::ParsingError, ::RBI::Error
59
59
  # Ignore signatures with errors
60
60
  next
61
61
  end
@@ -99,13 +99,16 @@ module Spoom
99
99
 
100
100
  sig.return_type = RBI::RBS::TypeTranslator.translate(attr_type)
101
101
 
102
- apply_member_annotations(comments.annotations, sig)
102
+ apply_member_annotations(comments.method_annotations, sig)
103
103
 
104
104
  @rewriter << Source::Replace.new(
105
105
  signature.location.start_offset,
106
106
  signature.location.end_offset,
107
107
  sig.string,
108
108
  )
109
+ rescue ::RBS::ParsingError, ::RBI::Error
110
+ # Ignore signatures with errors
111
+ next
109
112
  end
110
113
  end
111
114
 
@@ -124,12 +127,13 @@ module Spoom
124
127
  node.expression.location.end_offset
125
128
  end
126
129
 
127
- if comments.annotations.any?
130
+ class_annotations = comments.class_annotations
131
+ if class_annotations.any?
128
132
  unless already_extends?(node, /^(::)?T::Helpers$/)
129
133
  @rewriter << Source::Insert.new(insert_pos, "\n#{indent}extend T::Helpers\n")
130
134
  end
131
135
 
132
- comments.annotations.reverse_each do |annotation|
136
+ class_annotations.reverse_each do |annotation|
133
137
  from = adjust_to_line_start(annotation.location.start_offset)
134
138
  to = adjust_to_line_end(annotation.location.end_offset)
135
139
 
@@ -154,6 +158,9 @@ module Spoom
154
158
 
155
159
  newline = node.body.nil? ? "" : "\n"
156
160
  @rewriter << Source::Insert.new(insert_pos, "\n#{indent}#{content}#{newline}")
161
+ rescue ::RBS::ParsingError, ::RBI::Error
162
+ # Ignore annotations with errors
163
+ next
157
164
  end
158
165
  end
159
166
 
@@ -195,12 +202,15 @@ module Spoom
195
202
 
196
203
  newline = node.body.nil? ? "" : "\n"
197
204
  @rewriter << Source::Insert.new(insert_pos, "\n#{indent}#{type_member}#{newline}")
205
+ rescue ::RBS::ParsingError, ::RBI::Error
206
+ # Ignore signatures with errors
207
+ next
198
208
  end
199
209
  end
200
210
  end
201
211
  end
202
212
 
203
- #: (Array[RBS::Annotations], RBI::Sig) -> void
213
+ #: (Array[RBS::Annotation], RBI::Sig) -> void
204
214
  def apply_member_annotations(annotations, sig)
205
215
  annotations.each do |annotation|
206
216
  case annotation.string
@@ -9,22 +9,75 @@ module Spoom
9
9
  LINE_BREAK = "\n".ord #: Integer
10
10
 
11
11
  # @override
12
- #: (Prism::CallNode) -> void
13
- def visit_call_node(node)
14
- return super unless t_annotation?(node)
15
- return super unless at_end_of_line?(node)
12
+ #: (Prism::StatementsNode) -> void
13
+ def visit_statements_node(node)
14
+ node.body.each do |statement|
15
+ translated = maybe_translate_assertion(statement)
16
+ visit(statement) unless translated
17
+ end
18
+ end
19
+
20
+ # @override
21
+ #: (Prism::IfNode) -> void
22
+ def visit_if_node(node)
23
+ if node.if_keyword_loc
24
+ # We do not translate assertions in ternary expressions to avoid altering the semantic of the code.
25
+ #
26
+ # For example:
27
+ # ```rb
28
+ # a = T.must(b) ? T.must(c) : T.must(d)
29
+ # ```
30
+ #
31
+ # would become
32
+ # ```rb
33
+ # a = T.must(b) ? T.must(c) : d #: !nil
34
+ # ```
35
+ #
36
+ # which does not match the original intent.
37
+ super
38
+ end
39
+ end
40
+
41
+ private
42
+
43
+ #: (Prism::Node) -> bool
44
+ def maybe_translate_assertion(node)
45
+ node = case node
46
+ when Prism::MultiWriteNode,
47
+ Prism::ClassVariableWriteNode, Prism::ClassVariableAndWriteNode, Prism::ClassVariableOperatorWriteNode, Prism::ClassVariableOrWriteNode,
48
+ Prism::ConstantWriteNode, Prism::ConstantAndWriteNode, Prism::ConstantOperatorWriteNode, Prism::ConstantOrWriteNode,
49
+ Prism::ConstantPathWriteNode, Prism::ConstantPathAndWriteNode, Prism::ConstantPathOperatorWriteNode, Prism::ConstantPathOrWriteNode,
50
+ Prism::GlobalVariableWriteNode, Prism::GlobalVariableAndWriteNode, Prism::GlobalVariableOperatorWriteNode, Prism::GlobalVariableOrWriteNode,
51
+ Prism::InstanceVariableWriteNode, Prism::InstanceVariableAndWriteNode, Prism::InstanceVariableOperatorWriteNode, Prism::InstanceVariableOrWriteNode,
52
+ Prism::LocalVariableWriteNode, Prism::LocalVariableAndWriteNode, Prism::LocalVariableOperatorWriteNode, Prism::LocalVariableOrWriteNode,
53
+ Prism::CallAndWriteNode, Prism::CallOperatorWriteNode, Prism::CallOrWriteNode
54
+ node.value
55
+ when Prism::CallNode
56
+ node
57
+ else
58
+ return false
59
+ end
60
+
61
+ return false unless node.is_a?(Prism::CallNode)
62
+ return false unless t_annotation?(node)
63
+ return false unless at_end_of_line?(node)
16
64
 
17
65
  value = T.must(node.arguments&.arguments&.first)
18
66
  rbs_annotation = build_rbs_annotation(node)
19
67
 
20
68
  start_offset = node.location.start_offset
21
69
  end_offset = node.location.end_offset
22
- @rewriter << Source::Replace.new(start_offset, end_offset - 1, "#{dedent_value(node, value)} #{rbs_annotation}")
23
- end
24
70
 
25
- private
71
+ @rewriter << if node.name == :bind
72
+ Source::Replace.new(start_offset, end_offset - 1, rbs_annotation)
73
+ else
74
+ Source::Replace.new(start_offset, end_offset - 1, "#{dedent_value(node, value)} #{rbs_annotation}")
75
+ end
76
+
77
+ true
78
+ end
26
79
 
27
- #: (Prism::CallNode) -> void
80
+ #: (Prism::CallNode) -> String
28
81
  def build_rbs_annotation(call)
29
82
  case call.name
30
83
  when :let
@@ -35,6 +88,10 @@ module Spoom
35
88
  srb_type = call.arguments&.arguments&.last #: as !nil
36
89
  rbs_type = RBI::Type.parse_node(srb_type).rbs_string
37
90
  "#: as #{rbs_type}"
91
+ when :bind
92
+ srb_type = call.arguments&.arguments&.last #: as !nil
93
+ rbs_type = RBI::Type.parse_node(srb_type).rbs_string
94
+ "#: self as #{rbs_type}"
38
95
  when :must
39
96
  "#: as !nil"
40
97
  when :unsafe
@@ -65,6 +122,8 @@ module Spoom
65
122
  case node.name
66
123
  when :let, :cast
67
124
  return node.arguments&.arguments&.size == 2
125
+ when :bind
126
+ return node.arguments&.arguments&.size == 2 && node.arguments&.arguments&.first.is_a?(Prism::SelfNode)
68
127
  when :must, :unsafe
69
128
  return node.arguments&.arguments&.size == 1
70
129
  end
@@ -12,9 +12,12 @@ module Spoom
12
12
  super(ruby_contents, file: file)
13
13
 
14
14
  @positional_names = positional_names #: bool
15
- @nesting = [] #: Array[Prism::ClassNode | Prism::ModuleNode | Prism::SingletonClassNode]
16
15
  @last_sigs = [] #: Array[[Prism::CallNode, RBI::Sig]]
16
+ @class_annotations = [] #: Array[Prism::CallNode]
17
17
  @type_members = [] #: Array[String]
18
+ @extend_t_helpers = [] #: Array[Prism::CallNode]
19
+ @extend_t_generics = [] #: Array[Prism::CallNode]
20
+ @seen_mixes_in_class_methods = false #: bool
18
21
  end
19
22
 
20
23
  # @override
@@ -38,17 +41,18 @@ module Spoom
38
41
  # @override
39
42
  #: (Prism::DefNode) -> void
40
43
  def visit_def_node(node)
41
- return if @last_sigs.empty?
42
- return if @last_sigs.any? { |_, sig| sig.is_abstract }
44
+ last_sigs = collect_last_sigs
45
+ return if last_sigs.empty?
46
+ return if last_sigs.any? { |_, sig| sig.is_abstract }
43
47
 
44
- apply_member_annotations(@last_sigs)
48
+ apply_member_annotations(last_sigs)
45
49
 
46
50
  # Build the RBI::Method node so we can print the method signature as RBS.
47
51
  builder = RBI::Parser::TreeBuilder.new(@ruby_contents, comments: [], file: @file)
48
52
  builder.visit(node)
49
53
  rbi_node = builder.tree.nodes.first #: as RBI::Method
50
54
 
51
- @last_sigs.each do |node, sig|
55
+ last_sigs.each do |node, sig|
52
56
  out = StringIO.new
53
57
  p = RBI::RBSPrinter.new(out: out, indent: node.location.start_column, positional_names: @positional_names)
54
58
  p.print("#: ")
@@ -56,8 +60,6 @@ module Spoom
56
60
  p.print("\n")
57
61
  @rewriter << Source::Replace.new(node.location.start_offset, node.location.end_offset, out.string)
58
62
  end
59
-
60
- @last_sigs.clear
61
63
  end
62
64
 
63
65
  # @override
@@ -71,7 +73,9 @@ module Spoom
71
73
  when "extend"
72
74
  visit_extend(node)
73
75
  when "abstract!", "interface!", "sealed!", "final!", "requires_ancestor"
74
- visit_class_annotation(node)
76
+ @class_annotations << node
77
+ when "mixes_in_class_methods"
78
+ @seen_mixes_in_class_methods = true
75
79
  else
76
80
  super
77
81
  end
@@ -97,19 +101,39 @@ module Spoom
97
101
 
98
102
  #: (Prism::ClassNode | Prism::ModuleNode | Prism::SingletonClassNode) { -> void } -> void
99
103
  def visit_scope(node, &block)
100
- @nesting << node
104
+ old_class_annotations = @class_annotations
105
+ @class_annotations = []
101
106
  old_type_members = @type_members
102
107
  @type_members = []
108
+ old_extend_t_helpers = @extend_t_helpers
109
+ @extend_t_helpers = []
110
+ old_extend_t_generics = @extend_t_generics
111
+ @extend_t_generics = []
112
+ old_seen_mixes_in_class_methods = @seen_mixes_in_class_methods
113
+ @seen_mixes_in_class_methods = false
103
114
 
104
115
  yield
105
116
 
117
+ delete_extend_t_generics
118
+
106
119
  if @type_members.any?
107
120
  indent = " " * node.location.start_column
108
121
  @rewriter << Source::Insert.new(node.location.start_offset, "#: [#{@type_members.join(", ")}]\n#{indent}")
109
122
  end
110
123
 
124
+ unless @seen_mixes_in_class_methods
125
+ delete_extend_t_helpers
126
+ end
127
+
128
+ @class_annotations.each do |call|
129
+ apply_class_annotation(node, call)
130
+ end
131
+
132
+ @class_annotations = old_class_annotations
111
133
  @type_members = old_type_members
112
- @nesting.pop
134
+ @extend_t_helpers = old_extend_t_helpers
135
+ @extend_t_generics = old_extend_t_generics
136
+ @seen_mixes_in_class_methods = old_seen_mixes_in_class_methods
113
137
  end
114
138
 
115
139
  #: (Prism::CallNode) -> void
@@ -130,16 +154,17 @@ module Spoom
130
154
  raise Error, "Expected attr_reader, attr_writer, or attr_accessor"
131
155
  end
132
156
 
133
- return if @last_sigs.empty?
134
- return if @last_sigs.any? { |_, sig| sig.is_abstract }
157
+ last_sigs = collect_last_sigs
158
+ return if last_sigs.empty?
159
+ return if last_sigs.any? { |_, sig| sig.is_abstract }
135
160
 
136
- apply_member_annotations(@last_sigs)
161
+ apply_member_annotations(last_sigs)
137
162
 
138
163
  builder = RBI::Parser::TreeBuilder.new(@ruby_contents, comments: [], file: @file)
139
164
  builder.visit(node)
140
165
  rbi_node = builder.tree.nodes.first #: as RBI::Attr
141
166
 
142
- @last_sigs.each do |node, sig|
167
+ last_sigs.each do |node, sig|
143
168
  out = StringIO.new
144
169
  p = RBI::RBSPrinter.new(out: out, indent: node.location.start_column, positional_names: @positional_names)
145
170
  p.print("#: ")
@@ -147,8 +172,6 @@ module Spoom
147
172
  p.print("\n")
148
173
  @rewriter << Source::Replace.new(node.location.start_offset, node.location.end_offset, out.string)
149
174
  end
150
-
151
- @last_sigs.clear
152
175
  end
153
176
 
154
177
  #: (Prism::CallNode node) -> void
@@ -160,16 +183,17 @@ module Spoom
160
183
 
161
184
  arg = node.arguments&.arguments&.first
162
185
  return unless arg.is_a?(Prism::ConstantPathNode)
163
- return unless arg.slice.match?(/^(::)?T::Helpers$/) || arg.slice.match?(/^(::)?T::Generic$/)
164
186
 
165
- from = adjust_to_line_start(node.location.start_offset)
166
- to = adjust_to_line_end(node.location.end_offset)
167
- to = adjust_to_new_line(to)
168
- @rewriter << Source::Delete.new(from, to)
187
+ case arg.slice
188
+ when /^(::)?T::Helpers$/
189
+ @extend_t_helpers << node
190
+ when /^(::)?T::Generic$/
191
+ @extend_t_generics << node
192
+ end
169
193
  end
170
194
 
171
- #: (Prism::CallNode node) -> void
172
- def visit_class_annotation(node)
195
+ #: (Prism::ClassNode | Prism::ModuleNode | Prism::SingletonClassNode, Prism::CallNode) -> void
196
+ def apply_class_annotation(parent, node)
173
197
  unless node.message == "abstract!" || node.message == "interface!" || node.message == "sealed!" ||
174
198
  node.message == "final!" || node.message == "requires_ancestor"
175
199
  raise Error, "Expected abstract!, interface!, sealed!, final!, or requires_ancestor"
@@ -178,18 +202,17 @@ module Spoom
178
202
  return unless node.receiver.nil? || node.receiver.is_a?(Prism::SelfNode)
179
203
  return unless node.arguments.nil?
180
204
 
181
- klass = @nesting.last #: as Prism::Node
182
- indent = " " * klass.location.start_column
205
+ indent = " " * parent.location.start_column
183
206
 
184
207
  case node.message
185
208
  when "abstract!"
186
- @rewriter << Source::Insert.new(klass.location.start_offset, "# @abstract\n#{indent}")
209
+ @rewriter << Source::Insert.new(parent.location.start_offset, "# @abstract\n#{indent}")
187
210
  when "interface!"
188
- @rewriter << Source::Insert.new(klass.location.start_offset, "# @interface\n#{indent}")
211
+ @rewriter << Source::Insert.new(parent.location.start_offset, "# @interface\n#{indent}")
189
212
  when "sealed!"
190
- @rewriter << Source::Insert.new(klass.location.start_offset, "# @sealed\n#{indent}")
213
+ @rewriter << Source::Insert.new(parent.location.start_offset, "# @sealed\n#{indent}")
191
214
  when "final!"
192
- @rewriter << Source::Insert.new(klass.location.start_offset, "# @final\n#{indent}")
215
+ @rewriter << Source::Insert.new(parent.location.start_offset, "# @final\n#{indent}")
193
216
  when "requires_ancestor"
194
217
  block = node.block
195
218
  return unless block.is_a?(Prism::BlockNode)
@@ -200,7 +223,7 @@ module Spoom
200
223
 
201
224
  arg = body.body.first #: as Prism::Node
202
225
  srb_type = RBI::Type.parse_node(arg)
203
- @rewriter << Source::Insert.new(klass.location.start_offset, "# @requires_ancestor: #{srb_type.rbs_string}\n#{indent}")
226
+ @rewriter << Source::Insert.new(parent.location.start_offset, "# @requires_ancestor: #{srb_type.rbs_string}\n#{indent}")
204
227
  end
205
228
 
206
229
  from = adjust_to_line_start(node.location.start_offset)
@@ -287,6 +310,38 @@ module Spoom
287
310
 
288
311
  type_member
289
312
  end
313
+
314
+ #: -> void
315
+ def delete_extend_t_helpers
316
+ @extend_t_helpers.each do |helper|
317
+ from = adjust_to_line_start(helper.location.start_offset)
318
+ to = adjust_to_line_end(helper.location.end_offset)
319
+ to = adjust_to_new_line(to)
320
+ @rewriter << Source::Delete.new(from, to)
321
+ end
322
+
323
+ @extend_t_helpers.clear
324
+ end
325
+
326
+ #: -> void
327
+ def delete_extend_t_generics
328
+ @extend_t_generics.each do |generic|
329
+ from = adjust_to_line_start(generic.location.start_offset)
330
+ to = adjust_to_line_end(generic.location.end_offset)
331
+ to = adjust_to_new_line(to)
332
+ @rewriter << Source::Delete.new(from, to)
333
+ end
334
+
335
+ @extend_t_generics.clear
336
+ end
337
+
338
+ # Collects the last signatures visited and clears the current list
339
+ #: -> Array[[Prism::CallNode, RBI::Sig]]
340
+ def collect_last_sigs
341
+ last_sigs = @last_sigs
342
+ @last_sigs = []
343
+ last_sigs
344
+ end
290
345
  end
291
346
  end
292
347
  end
@@ -158,7 +158,10 @@ module Spoom
158
158
  def rewrite!(bytes)
159
159
  # To avoid remapping positions after each edit,
160
160
  # we sort the changes by position and apply them in reverse order.
161
- @edits.sort_by(&:range).reverse_each do |edit|
161
+ # When ranges are equal, preserve the original order
162
+ @edits.each_with_index.sort_by do |(edit, idx)|
163
+ [edit.range, idx]
164
+ end.reverse_each do |(edit, _)|
162
165
  edit.apply(bytes)
163
166
  end
164
167
  end
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.7.2"
5
+ VERSION = "1.7.3"
6
6
  end
data/rbi/spoom.rbi CHANGED
@@ -432,6 +432,12 @@ module Spoom::Context::Sorbet
432
432
  end
433
433
 
434
434
  class Spoom::Counters < ::Hash
435
+ extend T::Generic
436
+
437
+ K = type_member { { fixed: String } }
438
+ V = type_member { { fixed: Integer } }
439
+ Elem = type_member { { fixed: [String, Integer] } }
440
+
435
441
  sig { void }
436
442
  def initialize; end
437
443
 
@@ -645,10 +651,6 @@ class Spoom::Coverage::D3::ColorPalette < ::T::Struct
645
651
  prop :true, ::String
646
652
  prop :strict, ::String
647
653
  prop :strong, ::String
648
-
649
- class << self
650
- def inherited(s); end
651
- end
652
654
  end
653
655
 
654
656
  class Spoom::Coverage::D3::Pie < ::Spoom::Coverage::D3::Base
@@ -899,8 +901,6 @@ class Spoom::Coverage::Snapshot < ::T::Struct
899
901
 
900
902
  sig { params(obj: T::Hash[::String, T.untyped]).returns(::Spoom::Coverage::Snapshot) }
901
903
  def from_obj(obj); end
902
-
903
- def inherited(s); end
904
904
  end
905
905
  end
906
906
 
@@ -990,10 +990,6 @@ class Spoom::Deadcode::Definition < ::T::Struct
990
990
 
991
991
  sig { params(args: T.untyped).returns(::String) }
992
992
  def to_json(*args); end
993
-
994
- class << self
995
- def inherited(s); end
996
- end
997
993
  end
998
994
 
999
995
  class Spoom::Deadcode::Definition::Kind < ::T::Enum
@@ -1136,7 +1132,13 @@ class Spoom::Deadcode::Plugins::ActionPack < ::Spoom::Deadcode::Plugins::Base
1136
1132
  end
1137
1133
 
1138
1134
  Spoom::Deadcode::Plugins::ActionPack::CALLBACKS = T.let(T.unsafe(nil), Array)
1139
- class Spoom::Deadcode::Plugins::ActiveJob < ::Spoom::Deadcode::Plugins::Base; end
1135
+
1136
+ class Spoom::Deadcode::Plugins::ActiveJob < ::Spoom::Deadcode::Plugins::Base
1137
+ sig { override.params(send: ::Spoom::Deadcode::Send).void }
1138
+ def on_send(send); end
1139
+ end
1140
+
1141
+ Spoom::Deadcode::Plugins::ActiveJob::CALLBACKS = T.let(T.unsafe(nil), Array)
1140
1142
 
1141
1143
  class Spoom::Deadcode::Plugins::ActiveModel < ::Spoom::Deadcode::Plugins::Base
1142
1144
  sig { override.params(send: ::Spoom::Deadcode::Send).void }
@@ -1521,10 +1523,6 @@ class Spoom::Deadcode::Send < ::T::Struct
1521
1523
 
1522
1524
  sig { params(block: T.proc.params(key: ::Prism::Node, value: T.nilable(::Prism::Node)).void).void }
1523
1525
  def each_arg_assoc(&block); end
1524
-
1525
- class << self
1526
- def inherited(s); end
1527
- end
1528
1526
  end
1529
1527
 
1530
1528
  class Spoom::Error < ::StandardError; end
@@ -1537,10 +1535,6 @@ class Spoom::ExecResult < ::T::Struct
1537
1535
 
1538
1536
  sig { returns(::String) }
1539
1537
  def to_s; end
1540
-
1541
- class << self
1542
- def inherited(s); end
1543
- end
1544
1538
  end
1545
1539
 
1546
1540
  class Spoom::FileCollector
@@ -1660,10 +1654,6 @@ class Spoom::FileTree::Node < ::T::Struct
1660
1654
 
1661
1655
  sig { returns(::String) }
1662
1656
  def path; end
1663
-
1664
- class << self
1665
- def inherited(s); end
1666
- end
1667
1657
  end
1668
1658
 
1669
1659
  class Spoom::FileTree::Printer < ::Spoom::FileTree::Visitor
@@ -1708,8 +1698,6 @@ class Spoom::Git::Commit < ::T::Struct
1708
1698
  def timestamp; end
1709
1699
 
1710
1700
  class << self
1711
- def inherited(s); end
1712
-
1713
1701
  sig { params(string: ::String).returns(T.nilable(::Spoom::Git::Commit)) }
1714
1702
  def parse_line(string); end
1715
1703
  end
@@ -1788,8 +1776,6 @@ class Spoom::LSP::Diagnostic < ::T::Struct
1788
1776
  class << self
1789
1777
  sig { params(json: T::Hash[T.untyped, T.untyped]).returns(::Spoom::LSP::Diagnostic) }
1790
1778
  def from_json(json); end
1791
-
1792
- def inherited(s); end
1793
1779
  end
1794
1780
  end
1795
1781
 
@@ -1815,8 +1801,6 @@ class Spoom::LSP::DocumentSymbol < ::T::Struct
1815
1801
  class << self
1816
1802
  sig { params(json: T::Hash[T.untyped, T.untyped]).returns(::Spoom::LSP::DocumentSymbol) }
1817
1803
  def from_json(json); end
1818
-
1819
- def inherited(s); end
1820
1804
  end
1821
1805
  end
1822
1806
 
@@ -1856,8 +1840,6 @@ class Spoom::LSP::Hover < ::T::Struct
1856
1840
  class << self
1857
1841
  sig { params(json: T::Hash[T.untyped, T.untyped]).returns(::Spoom::LSP::Hover) }
1858
1842
  def from_json(json); end
1859
-
1860
- def inherited(s); end
1861
1843
  end
1862
1844
  end
1863
1845
 
@@ -1876,8 +1858,6 @@ class Spoom::LSP::Location < ::T::Struct
1876
1858
  class << self
1877
1859
  sig { params(json: T::Hash[T.untyped, T.untyped]).returns(::Spoom::LSP::Location) }
1878
1860
  def from_json(json); end
1879
-
1880
- def inherited(s); end
1881
1861
  end
1882
1862
  end
1883
1863
 
@@ -1918,8 +1898,6 @@ class Spoom::LSP::Position < ::T::Struct
1918
1898
  class << self
1919
1899
  sig { params(json: T::Hash[T.untyped, T.untyped]).returns(::Spoom::LSP::Position) }
1920
1900
  def from_json(json); end
1921
-
1922
- def inherited(s); end
1923
1901
  end
1924
1902
  end
1925
1903
 
@@ -1945,8 +1923,6 @@ class Spoom::LSP::Range < ::T::Struct
1945
1923
  class << self
1946
1924
  sig { params(json: T::Hash[T.untyped, T.untyped]).returns(::Spoom::LSP::Range) }
1947
1925
  def from_json(json); end
1948
-
1949
- def inherited(s); end
1950
1926
  end
1951
1927
  end
1952
1928
 
@@ -1993,8 +1969,6 @@ class Spoom::LSP::SignatureHelp < ::T::Struct
1993
1969
  class << self
1994
1970
  sig { params(json: T::Hash[T.untyped, T.untyped]).returns(::Spoom::LSP::SignatureHelp) }
1995
1971
  def from_json(json); end
1996
-
1997
- def inherited(s); end
1998
1972
  end
1999
1973
  end
2000
1974
 
@@ -2291,8 +2265,6 @@ class Spoom::Model::Reference < ::T::Struct
2291
2265
  sig { params(name: ::String, location: ::Spoom::Location).returns(::Spoom::Model::Reference) }
2292
2266
  def constant(name, location); end
2293
2267
 
2294
- def inherited(s); end
2295
-
2296
2268
  sig { params(name: ::String, location: ::Spoom::Location).returns(::Spoom::Model::Reference) }
2297
2269
  def method(name, location); end
2298
2270
  end
@@ -2465,25 +2437,29 @@ end
2465
2437
  class Spoom::ParseError < ::Spoom::Error; end
2466
2438
 
2467
2439
  class Spoom::Poset
2440
+ extend T::Generic
2441
+
2442
+ E = type_member { { upper: Object } }
2443
+
2468
2444
  sig { void }
2469
2445
  def initialize; end
2470
2446
 
2471
- sig { params(value: T.untyped).returns(Spoom::Poset::Element[T.untyped]) }
2447
+ sig { params(value: E).returns(Spoom::Poset::Element[E]) }
2472
2448
  def [](value); end
2473
2449
 
2474
- sig { params(from: T.untyped, to: T.untyped).void }
2450
+ sig { params(from: E, to: E).void }
2475
2451
  def add_direct_edge(from, to); end
2476
2452
 
2477
- sig { params(value: T.untyped).returns(Spoom::Poset::Element[T.untyped]) }
2453
+ sig { params(value: E).returns(Spoom::Poset::Element[E]) }
2478
2454
  def add_element(value); end
2479
2455
 
2480
- sig { params(from: T.untyped, to: T.untyped).returns(T::Boolean) }
2456
+ sig { params(from: E, to: E).returns(T::Boolean) }
2481
2457
  def direct_edge?(from, to); end
2482
2458
 
2483
- sig { params(from: T.untyped, to: T.untyped).returns(T::Boolean) }
2459
+ sig { params(from: E, to: E).returns(T::Boolean) }
2484
2460
  def edge?(from, to); end
2485
2461
 
2486
- sig { params(value: T.untyped).returns(T::Boolean) }
2462
+ sig { params(value: E).returns(T::Boolean) }
2487
2463
  def element?(value); end
2488
2464
 
2489
2465
  sig { params(direct: T::Boolean, transitive: T::Boolean).void }
@@ -2494,36 +2470,39 @@ class Spoom::Poset
2494
2470
  end
2495
2471
 
2496
2472
  class Spoom::Poset::Element
2473
+ extend T::Generic
2497
2474
  include ::Comparable
2498
2475
 
2499
- sig { params(value: T.untyped).void }
2476
+ E = type_member { { upper: Object } }
2477
+
2478
+ sig { params(value: E).void }
2500
2479
  def initialize(value); end
2501
2480
 
2502
2481
  sig { params(other: T.untyped).returns(T.nilable(::Integer)) }
2503
2482
  def <=>(other); end
2504
2483
 
2505
- sig { returns(T::Array[T.untyped]) }
2484
+ sig { returns(T::Array[E]) }
2506
2485
  def ancestors; end
2507
2486
 
2508
- sig { returns(T::Array[T.untyped]) }
2487
+ sig { returns(T::Array[E]) }
2509
2488
  def children; end
2510
2489
 
2511
- sig { returns(T::Array[T.untyped]) }
2490
+ sig { returns(T::Array[E]) }
2512
2491
  def descendants; end
2513
2492
 
2514
2493
  def dfroms; end
2515
2494
 
2516
- sig { returns(T::Set[Spoom::Poset::Element[T.untyped]]) }
2495
+ sig { returns(T::Set[Spoom::Poset::Element[E]]) }
2517
2496
  def dtos; end
2518
2497
 
2519
2498
  def froms; end
2520
2499
 
2521
- sig { returns(T::Array[T.untyped]) }
2500
+ sig { returns(T::Array[E]) }
2522
2501
  def parents; end
2523
2502
 
2524
2503
  def tos; end
2525
2504
 
2526
- sig { returns(T.untyped) }
2505
+ sig { returns(E) }
2527
2506
  def value; end
2528
2507
  end
2529
2508
 
@@ -2566,7 +2545,7 @@ class Spoom::Printer
2566
2545
  end
2567
2546
 
2568
2547
  module Spoom::RBS; end
2569
- class Spoom::RBS::Annotations < ::Spoom::RBS::Comment; end
2548
+ class Spoom::RBS::Annotation < ::Spoom::RBS::Comment; end
2570
2549
 
2571
2550
  class Spoom::RBS::Comment
2572
2551
  sig { params(string: ::String, location: ::Prism::Location).void }
@@ -2583,12 +2562,18 @@ class Spoom::RBS::Comments
2583
2562
  sig { void }
2584
2563
  def initialize; end
2585
2564
 
2586
- sig { returns(T::Array[::Spoom::RBS::Annotations]) }
2565
+ sig { returns(T::Array[::Spoom::RBS::Annotation]) }
2587
2566
  def annotations; end
2588
2567
 
2568
+ sig { returns(T::Array[::Spoom::RBS::Annotation]) }
2569
+ def class_annotations; end
2570
+
2589
2571
  sig { returns(T::Boolean) }
2590
2572
  def empty?; end
2591
2573
 
2574
+ sig { returns(T::Array[::Spoom::RBS::Annotation]) }
2575
+ def method_annotations; end
2576
+
2592
2577
  sig { returns(T::Array[::Spoom::RBS::Signature]) }
2593
2578
  def signatures; end
2594
2579
  end
@@ -2758,9 +2743,6 @@ class Spoom::Sorbet::Metrics::CodeMetricsVisitor < ::Spoom::Visitor
2758
2743
  sig { params(counters: Spoom::Counters).void }
2759
2744
  def initialize(counters); end
2760
2745
 
2761
- sig { returns(Spoom::Counters) }
2762
- def counters; end
2763
-
2764
2746
  sig { override.params(node: T.nilable(::Prism::Node)).void }
2765
2747
  def visit(node); end
2766
2748
 
@@ -2904,7 +2886,7 @@ class Spoom::Sorbet::Translate::RBSCommentsToSorbetSigs < ::Spoom::Sorbet::Trans
2904
2886
  sig { params(node: T.any(::Prism::ClassNode, ::Prism::ModuleNode, ::Prism::SingletonClassNode)).void }
2905
2887
  def apply_class_annotations(node); end
2906
2888
 
2907
- sig { params(annotations: T::Array[::Spoom::RBS::Annotations], sig: ::RBI::Sig).void }
2889
+ sig { params(annotations: T::Array[::Spoom::RBS::Annotation], sig: ::RBI::Sig).void }
2908
2890
  def apply_member_annotations(annotations, sig); end
2909
2891
 
2910
2892
  sig { params(node: ::Prism::CallNode).void }
@@ -2912,20 +2894,26 @@ class Spoom::Sorbet::Translate::RBSCommentsToSorbetSigs < ::Spoom::Sorbet::Trans
2912
2894
  end
2913
2895
 
2914
2896
  class Spoom::Sorbet::Translate::SorbetAssertionsToRBSComments < ::Spoom::Sorbet::Translate::Translator
2915
- sig { override.params(node: ::Prism::CallNode).void }
2916
- def visit_call_node(node); end
2897
+ sig { override.params(node: ::Prism::IfNode).void }
2898
+ def visit_if_node(node); end
2899
+
2900
+ sig { override.params(node: ::Prism::StatementsNode).void }
2901
+ def visit_statements_node(node); end
2917
2902
 
2918
2903
  private
2919
2904
 
2920
2905
  sig { params(node: ::Prism::Node).returns(T::Boolean) }
2921
2906
  def at_end_of_line?(node); end
2922
2907
 
2923
- sig { params(call: ::Prism::CallNode).void }
2908
+ sig { params(call: ::Prism::CallNode).returns(::String) }
2924
2909
  def build_rbs_annotation(call); end
2925
2910
 
2926
2911
  sig { params(assign: ::Prism::Node, value: ::Prism::Node).returns(::String) }
2927
2912
  def dedent_value(assign, value); end
2928
2913
 
2914
+ sig { params(node: ::Prism::Node).returns(T::Boolean) }
2915
+ def maybe_translate_assertion(node); end
2916
+
2929
2917
  sig { params(node: T.nilable(::Prism::Node)).returns(T::Boolean) }
2930
2918
  def t?(node); end
2931
2919
 
@@ -2959,17 +2947,31 @@ class Spoom::Sorbet::Translate::SorbetSigsToRBSComments < ::Spoom::Sorbet::Trans
2959
2947
 
2960
2948
  private
2961
2949
 
2950
+ sig do
2951
+ params(
2952
+ parent: T.any(::Prism::ClassNode, ::Prism::ModuleNode, ::Prism::SingletonClassNode),
2953
+ node: ::Prism::CallNode
2954
+ ).void
2955
+ end
2956
+ def apply_class_annotation(parent, node); end
2957
+
2962
2958
  sig { params(sigs: T::Array[[::Prism::CallNode, ::RBI::Sig]]).void }
2963
2959
  def apply_member_annotations(sigs); end
2964
2960
 
2965
2961
  sig { params(node: ::Prism::ConstantWriteNode).returns(::String) }
2966
2962
  def build_type_member_string(node); end
2967
2963
 
2968
- sig { params(node: ::Prism::CallNode).void }
2969
- def visit_attr(node); end
2964
+ sig { returns(T::Array[[::Prism::CallNode, ::RBI::Sig]]) }
2965
+ def collect_last_sigs; end
2966
+
2967
+ sig { void }
2968
+ def delete_extend_t_generics; end
2969
+
2970
+ sig { void }
2971
+ def delete_extend_t_helpers; end
2970
2972
 
2971
2973
  sig { params(node: ::Prism::CallNode).void }
2972
- def visit_class_annotation(node); end
2974
+ def visit_attr(node); end
2973
2975
 
2974
2976
  sig { params(node: ::Prism::CallNode).void }
2975
2977
  def visit_extend(node); end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spoom
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.7.2
4
+ version: 1.7.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alexandre Terrasa
@@ -23,20 +23,6 @@ dependencies:
23
23
  - - ">="
24
24
  - !ruby/object:Gem::Version
25
25
  version: 2.2.10
26
- - !ruby/object:Gem::Dependency
27
- name: minitest
28
- requirement: !ruby/object:Gem::Requirement
29
- requirements:
30
- - - "~>"
31
- - !ruby/object:Gem::Version
32
- version: '5.0'
33
- type: :development
34
- prerelease: false
35
- version_requirements: !ruby/object:Gem::Requirement
36
- requirements:
37
- - - "~>"
38
- - !ruby/object:Gem::Version
39
- version: '5.0'
40
26
  - !ruby/object:Gem::Dependency
41
27
  name: minitest-reporters
42
28
  requirement: !ruby/object:Gem::Requirement
@@ -57,14 +43,14 @@ dependencies:
57
43
  requirements:
58
44
  - - "~>"
59
45
  - !ruby/object:Gem::Version
60
- version: 13.2.1
46
+ version: 13.3.0
61
47
  type: :development
62
48
  prerelease: false
63
49
  version_requirements: !ruby/object:Gem::Requirement
64
50
  requirements:
65
51
  - - "~>"
66
52
  - !ruby/object:Gem::Version
67
- version: 13.2.1
53
+ version: 13.3.0
68
54
  - !ruby/object:Gem::Dependency
69
55
  name: erubi
70
56
  requirement: !ruby/object:Gem::Requirement