spoom 1.8.3 → 1.8.5

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.
@@ -12,7 +12,7 @@ module Spoom
12
12
  #: (Array[String]? bt) -> Array[String]
13
13
  def filter(bt)
14
14
  super.select do |line|
15
- SORBET_PATHS.none? { |path| line.include?(path) }
15
+ !SORBET_PATHS.intersect?(line)
16
16
  end
17
17
  end
18
18
  end
@@ -135,6 +135,10 @@ module Spoom
135
135
  end
136
136
 
137
137
  if result.status
138
+ parse_result = Sorbet::Errors::Parser.parse_result(result.err, error_url_base: error_url_base)
139
+ parse_result.warnings.each do |warning|
140
+ say_error(warning, status: nil, nl: false)
141
+ end
138
142
  Sorbet::Sigils.change_sigil_in_files(files_to_bump, to) unless dry
139
143
  print_changes(files_to_bump, command: cmd, from: from, to: to, dry: dry, path: exec_path)
140
144
  exit(files_to_bump.empty?)
@@ -147,7 +151,11 @@ module Spoom
147
151
  exit(1)
148
152
  end
149
153
 
150
- errors = Sorbet::Errors::Parser.parse_string(result.err, error_url_base: error_url_base)
154
+ parse_result = Sorbet::Errors::Parser.parse_result(result.err, error_url_base: error_url_base)
155
+ parse_result.warnings.each do |warning|
156
+ say_error(warning, status: nil, nl: false)
157
+ end
158
+ errors = parse_result.errors
151
159
 
152
160
  all_files = errors.flat_map do |err|
153
161
  [err.file, *err.files_from_error_sections]
@@ -17,11 +17,19 @@ module Spoom
17
17
  aliases: :p,
18
18
  desc: "Use positional names when translating from RBI to RBS",
19
19
  default: true
20
+ option :preserve_multiline_signatures,
21
+ type: :boolean,
22
+ desc: "Preserve multiline sig formatting when translating from RBI to RBS",
23
+ default: true
20
24
  option :include_rbi_files, type: :boolean, desc: "Include RBI files", default: false
21
25
  option :max_line_length, type: :numeric, desc: "Max line length (pass 0 to disable)", default: 120
22
26
  option :translate_generics, type: :boolean, desc: "Translate generics", default: false
23
27
  option :translate_helpers, type: :boolean, desc: "Translate helpers", default: false
24
28
  option :translate_abstract_methods, type: :boolean, desc: "Translate abstract methods", default: false
29
+ option :erase_generic_types,
30
+ type: :boolean,
31
+ desc: "Drop generic types when translating from RBS to RBI",
32
+ default: false
25
33
  def translate(*paths)
26
34
  from = options[:from]
27
35
  to = options[:to]
@@ -53,6 +61,7 @@ module Spoom
53
61
  contents,
54
62
  file: file,
55
63
  positional_names: options[:positional_names],
64
+ preserve_multiline_signatures: options[:preserve_multiline_signatures],
56
65
  max_line_length: max_line_length,
57
66
  translate_generics: options[:translate_generics],
58
67
  translate_helpers: options[:translate_helpers],
@@ -65,6 +74,7 @@ module Spoom
65
74
  contents,
66
75
  file: file,
67
76
  max_line_length: max_line_length,
77
+ erase_generic_types: options[:erase_generic_types],
68
78
  )
69
79
  end
70
80
  end
@@ -73,7 +73,11 @@ module Spoom
73
73
  exit(1)
74
74
  end
75
75
 
76
- errors = Spoom::Sorbet::Errors::Parser.parse_string(result.err, error_url_base: error_url_base)
76
+ parse_result = Spoom::Sorbet::Errors::Parser.parse_result(result.err, error_url_base: error_url_base)
77
+ parse_result.warnings.each do |warning|
78
+ say_error(warning, status: nil, nl: false)
79
+ end
80
+ errors = parse_result.errors
77
81
  errors_count = errors.size
78
82
 
79
83
  errors = errors.select { |e| e.code == code } if code
@@ -40,6 +40,15 @@ module Spoom
40
40
  super
41
41
  end
42
42
 
43
+ #: -> String
44
+ def wrapped_src
45
+ <<~RUBY
46
+ def __spoom_deadcode_erb_template__
47
+ #{src}
48
+ end
49
+ RUBY
50
+ end
51
+
43
52
  private
44
53
 
45
54
  # @override
@@ -50,32 +59,34 @@ module Spoom
50
59
  if text == "\n"
51
60
  @newline_pending += 1
52
61
  else
53
- src << bufvar << ".safe_append='"
54
- src << "\n" * @newline_pending if @newline_pending > 0
55
- src << text.gsub(/['\\]/, '\\\\\&')
56
- src << "'.freeze;"
57
-
62
+ with_buffer do
63
+ src << ".safe_append='"
64
+ src << "\n" * @newline_pending if @newline_pending > 0
65
+ src << text.gsub(/['\\]/, '\\\\\&') << @text_end
66
+ end
58
67
  @newline_pending = 0
59
68
  end
60
69
  end
61
70
 
62
- BLOCK_EXPR = /\s*((\s+|\))do|\{)(\s*\|[^|]*\|)?\s*\Z/
71
+ BLOCK_EXPR = /((\s|\))do|\{)(\s*\|[^|]*\|)?\s*\Z/
63
72
 
64
73
  # @override
65
74
  #: (untyped indicator, untyped code) -> void
66
75
  def add_expression(indicator, code)
67
76
  flush_newline_if_pending(src)
68
77
 
69
- src << bufvar << if (indicator == "==") || @escape
70
- ".safe_expr_append="
71
- else
72
- ".append="
73
- end
78
+ with_buffer do
79
+ src << if (indicator == "==") || @escape
80
+ ".safe_expr_append="
81
+ else
82
+ ".append="
83
+ end
74
84
 
75
- if BLOCK_EXPR.match?(code)
76
- src << " " << code
77
- else
78
- src << "(" << code << ");"
85
+ if BLOCK_EXPR.match?(code)
86
+ src << " " << code
87
+ else
88
+ src << "(" << code << ")"
89
+ end
79
90
  end
80
91
  end
81
92
 
@@ -96,7 +107,7 @@ module Spoom
96
107
  #: (untyped src) -> void
97
108
  def flush_newline_if_pending(src)
98
109
  if @newline_pending > 0
99
- src << bufvar << ".safe_append='#{"\n" * @newline_pending}'.freeze;"
110
+ with_buffer { src << ".safe_append='#{"\n" * @newline_pending}" << @text_end }
100
111
  @newline_pending = 0
101
112
  end
102
113
  end
@@ -44,7 +44,7 @@ module Spoom
44
44
 
45
45
  #: (String erb, file: String, ?plugins: Array[Plugins::Base]) -> void
46
46
  def index_erb(erb, file:, plugins: [])
47
- index_ruby(Deadcode::ERB.new(erb).src, file: file, plugins: plugins)
47
+ index_ruby(Deadcode::ERB.new(erb).wrapped_src, file: file, plugins: plugins)
48
48
  end
49
49
 
50
50
  #: (String rb, file: String, ?plugins: Array[Plugins::Base]) -> void
@@ -55,6 +55,11 @@ module Spoom
55
55
  model_builder = Model::Builder.new(@model, file)
56
56
  model_builder.visit(node)
57
57
 
58
+ # Ignore the special synthetic method generated by the ERB engine
59
+ if (spoom_erb_wrapper = @model.symbols["__spoom_deadcode_erb_template__"])
60
+ @ignored.merge(spoom_erb_wrapper.definitions)
61
+ end
62
+
58
63
  # Index references
59
64
  refs_visitor = Model::ReferencesVisitor.new(file)
60
65
  refs_visitor.visit(node)
@@ -117,6 +117,7 @@ module Spoom
117
117
  Prism::ConstantPathAndWriteNode, Prism::ConstantPathOrWriteNode
118
118
  # Nesting node is an assign, it means only one constant is assigned on the line
119
119
  # so we can remove the whole assign
120
+ remove_constant_visibility_call(context)
120
121
  delete_node_and_comments_and_sigs(context)
121
122
  return
122
123
  end
@@ -127,6 +128,7 @@ module Spoom
127
128
  if parent_node.is_a?(Prism::ConstantWriteNode)
128
129
  # Nesting node is an assign, it means only one constant is assigned on the line
129
130
  # so we can remove the whole assign
131
+ remove_constant_visibility_call(parent_context)
130
132
  delete_node_and_comments_and_sigs(parent_context)
131
133
  return
132
134
  elsif parent_node.is_a?(Prism::MultiWriteNode) && parent_node.lefts.size == 1
@@ -190,6 +192,64 @@ module Spoom
190
192
  end
191
193
  end
192
194
 
195
+ # A dead constant is often followed by a `private_constant`/`public_constant` call naming it.
196
+ # That call references the now-removed constant (a load-time `NameError` if left behind), so
197
+ # remove the reference too: delete the whole call when the constant is its only argument, or
198
+ # drop just that symbol when the call lists several constants.
199
+ #: (NodeContext context) -> void
200
+ def remove_constant_visibility_call(context)
201
+ node = context.node
202
+ return unless node.is_a?(Prism::ConstantWriteNode)
203
+
204
+ name = node.name
205
+ call = context.next_nodes.find { |sibling| constant_visibility_call?(sibling, name) }
206
+ return unless call.is_a?(Prism::CallNode)
207
+
208
+ call_context = NodeContext.new(@old_source, @node_context.comments, call, context.nesting)
209
+ arguments = call.arguments&.arguments #: Array[Prism::Node]?
210
+ if arguments && arguments.size > 1
211
+ delete_symbol_argument(call_context, name)
212
+ else
213
+ delete_node_and_comments_and_sigs(call_context)
214
+ end
215
+ end
216
+
217
+ # Whether `node` is a bare `private_constant`/`public_constant` call listing `name`.
218
+ #: (Prism::Node node, Symbol name) -> bool
219
+ def constant_visibility_call?(node, name)
220
+ return false unless node.is_a?(Prism::CallNode)
221
+ return false unless node.receiver.nil?
222
+ return false unless node.name == :private_constant || node.name == :public_constant
223
+
224
+ arguments = node.arguments&.arguments
225
+ return false unless arguments
226
+
227
+ arguments.any? { |argument| argument.is_a?(Prism::SymbolNode) && argument.value == name.to_s }
228
+ end
229
+
230
+ # Drop the `:name` symbol from a `private_constant`/`public_constant` call that lists several
231
+ # constants, keeping the call and the other names intact.
232
+ #: (NodeContext context, Symbol name) -> void
233
+ def delete_symbol_argument(context, name)
234
+ arguments = T.cast(context.node, Prism::CallNode).arguments&.arguments
235
+ return unless arguments
236
+
237
+ index = arguments.index { |argument| argument.is_a?(Prism::SymbolNode) && argument.value == name.to_s }
238
+ return unless index
239
+
240
+ argument = arguments.fetch(index)
241
+ prev_argument = arguments[index - 1] if index.positive?
242
+ next_argument = arguments[index + 1]
243
+
244
+ if prev_argument && next_argument
245
+ replace_chars(prev_argument.location.end_offset, next_argument.location.start_offset, ", ")
246
+ elsif prev_argument
247
+ delete_chars(prev_argument.location.end_offset, argument.location.end_offset)
248
+ elsif next_argument
249
+ delete_chars(argument.location.start_offset, next_argument.location.start_offset)
250
+ end
251
+ end
252
+
193
253
  #: (NodeContext context) -> void
194
254
  def delete_attr_accessor(context)
195
255
  args_context = context.parent_context
@@ -56,22 +56,35 @@ module Spoom
56
56
  ] #: Array[String]
57
57
 
58
58
  class << self
59
+ # Used when only Sorbet errors are needed and leading stderr warnings can be ignored.
59
60
  #: (String output, ?error_url_base: String) -> Array[Error]
60
61
  def parse_string(output, error_url_base: DEFAULT_ERROR_URL_BASE)
62
+ parse_result(output, error_url_base: error_url_base).errors
63
+ end
64
+
65
+ # Used when callers need both parsed Sorbet errors and leading stderr warnings.
66
+ #: (String output, ?error_url_base: String) -> ParseResult
67
+ def parse_result(output, error_url_base: DEFAULT_ERROR_URL_BASE)
61
68
  parser = Spoom::Sorbet::Errors::Parser.new(error_url_base: error_url_base)
62
- parser.parse(output)
69
+ parser.parse_result(output)
63
70
  end
64
71
  end
65
72
 
66
73
  #: (?error_url_base: String) -> void
67
74
  def initialize(error_url_base: DEFAULT_ERROR_URL_BASE)
68
75
  @errors = [] #: Array[Error]
76
+ @warnings = [] #: Array[String]
69
77
  @error_line_match_regex = error_line_match_regexp(error_url_base) #: Regexp
70
78
  @current_error = nil #: Error?
71
79
  end
72
80
 
73
81
  #: (String output) -> Array[Error]
74
82
  def parse(output)
83
+ parse_result(output).errors
84
+ end
85
+
86
+ #: (String output) -> ParseResult
87
+ def parse_result(output)
75
88
  output.each_line do |line|
76
89
  break if /^No errors! Great job\./.match?(line)
77
90
  break if /^Errors: /.match?(line)
@@ -85,10 +98,14 @@ module Spoom
85
98
  next
86
99
  end
87
100
 
88
- append_error(line) if @current_error
101
+ if @current_error
102
+ append_error(line)
103
+ else
104
+ append_warning(line)
105
+ end
89
106
  end
90
107
  close_error if @current_error
91
- @errors
108
+ ParseResult.new(@errors, @warnings)
92
109
  end
93
110
 
94
111
  private
@@ -144,6 +161,11 @@ module Spoom
144
161
  end
145
162
  @current_error.more << line
146
163
  end
164
+
165
+ #: (String warning) -> void
166
+ def append_warning(warning)
167
+ @warnings << warning
168
+ end
147
169
  end
148
170
 
149
171
  class Error
@@ -214,6 +236,20 @@ module Spoom
214
236
  testcase_element
215
237
  end
216
238
  end
239
+
240
+ class ParseResult
241
+ #: Array[Error]
242
+ attr_reader :errors
243
+
244
+ #: Array[String]
245
+ attr_reader :warnings
246
+
247
+ #: (Array[Error] errors, Array[String] warnings) -> void
248
+ def initialize(errors, warnings)
249
+ @errors = errors
250
+ @warnings = warnings
251
+ end
252
+ end
217
253
  end
218
254
  end
219
255
  end
@@ -26,7 +26,8 @@ module Spoom
26
26
 
27
27
  @overloads_strategy = options.overloads_strategy #: Symbol
28
28
  @translate_abstract_methods = options.translate_abstract_methods #: bool
29
- @type_translator = RBI::RBS::TypeTranslator.new #: RBI::RBS::TypeTranslator
29
+ @options = options #: Options
30
+ @type_translator = RBI::RBS::TypeTranslator.new(options: options.rbi_options) #: RBI::RBS::TypeTranslator
30
31
  end
31
32
 
32
33
  # @override
@@ -163,7 +164,7 @@ module Spoom
163
164
  next
164
165
  end
165
166
 
166
- translator = RBI::RBS::MethodTypeTranslator.new(rbi_node)
167
+ translator = RBI::RBS::MethodTypeTranslator.new(rbi_node, options: @options.rbi_options)
167
168
 
168
169
  begin
169
170
  translator.visit(method_type)
@@ -273,6 +274,18 @@ module Spoom
273
274
  rewrite_type_params_signature(signature, type_params:)
274
275
  next if type_params.empty?
275
276
 
277
+ if @options.erase_generic_types
278
+ type_params.each do |type_param|
279
+ insert_type_member(
280
+ "#{type_param.name} = ::T.type_alias { ::T.anything }",
281
+ parent_node: node,
282
+ insert_pos:,
283
+ )
284
+ end
285
+
286
+ next
287
+ end
288
+
276
289
  unless already_extends?(node, /^(::)?T::Generic$/)
277
290
  extend_with("T::Generic", into: node, at: insert_pos)
278
291
  end
@@ -462,7 +475,7 @@ module Spoom
462
475
  )
463
476
 
464
477
  @rewriter << Source::Delete.new(from, to)
465
- content = "#{indent}#{alias_name} = T.type_alias { #{sorbet_type.to_rbi} }\n"
478
+ content = "#{indent}#{alias_name} = ::T.type_alias { #{sorbet_type.to_rbi} }\n"
466
479
  content = pad_out_line_count(of: content, to_height_of: type_alias)
467
480
  @rewriter << Source::Insert.new(insert_pos, content)
468
481
  rescue ::RBS::ParsingError, ::RBI::Error
@@ -44,6 +44,12 @@ module Spoom
44
44
 
45
45
  ALLOWED_OVERLOAD_STRATEGIES = [:translate_all, :translate_last, :raise].freeze
46
46
 
47
+ #: bool
48
+ attr_reader :erase_generic_types
49
+
50
+ #: RBI::RBS::MethodTypeTranslator::Options
51
+ attr_reader :rbi_options
52
+
47
53
  #: BaseRBIFormat
48
54
  attr_reader :output_format
49
55
 
@@ -52,11 +58,13 @@ module Spoom
52
58
 
53
59
  #: (
54
60
  #| ?overloads_strategy: Symbol,
61
+ #| ?erase_generic_types: bool,
55
62
  #| ?output_format: BaseRBIFormat,
56
63
  #| ?translate_abstract_methods: bool,
57
64
  #| ) -> void
58
65
  def initialize(
59
66
  overloads_strategy: :translate_all,
67
+ erase_generic_types: false,
60
68
  output_format: HumanReadableRBIFormat.default,
61
69
  translate_abstract_methods: true
62
70
  )
@@ -66,6 +74,8 @@ module Spoom
66
74
  end
67
75
 
68
76
  @overloads_strategy = overloads_strategy
77
+ @erase_generic_types = erase_generic_types
78
+ @rbi_options = RBI::RBS::MethodTypeTranslator::Options.new(erase_generic_types:) #: RBI::RBS::MethodTypeTranslator::Options
69
79
  @output_format = output_format
70
80
  @translate_abstract_methods = translate_abstract_methods
71
81
 
@@ -28,17 +28,20 @@ module Spoom
28
28
  #| String ruby_contents,
29
29
  #| file: String,
30
30
  #| ?max_line_length: Integer?,
31
- #| ?overloads_strategy: Symbol) -> String
31
+ #| ?overloads_strategy: Symbol,
32
+ #| ?erase_generic_types: bool) -> String
32
33
  def rewrite_if_needed(
33
34
  ruby_contents,
34
35
  file:,
35
36
  max_line_length: nil,
36
- overloads_strategy: :translate_all
37
+ overloads_strategy: :translate_all,
38
+ erase_generic_types: false
37
39
  )
38
40
  return ruby_contents unless contains_rbs_syntax?(ruby_contents)
39
41
 
40
42
  options = Options.new(
41
43
  overloads_strategy:,
44
+ erase_generic_types:,
42
45
  output_format: HumanReadableRBIFormat.new(
43
46
  max_line_length:,
44
47
  ),
@@ -11,6 +11,7 @@ module Spoom
11
11
  #| String,
12
12
  #| file: String,
13
13
  #| positional_names: bool,
14
+ #| ?preserve_multiline_signatures: bool,
14
15
  #| ?max_line_length: Integer?,
15
16
  #| ?translate_generics: bool,
16
17
  #| ?translate_helpers: bool,
@@ -20,6 +21,7 @@ module Spoom
20
21
  ruby_contents,
21
22
  file:,
22
23
  positional_names:,
24
+ preserve_multiline_signatures: true,
23
25
  max_line_length: nil,
24
26
  translate_generics: true,
25
27
  translate_helpers: true,
@@ -34,6 +36,8 @@ module Spoom
34
36
  @extend_t_helpers = [] #: Array[Prism::CallNode]
35
37
  @extend_t_generics = [] #: Array[Prism::CallNode]
36
38
  @seen_mixes_in_class_methods = false #: bool
39
+
40
+ @preserve_multiline_signatures = preserve_multiline_signatures
37
41
  @max_line_length = max_line_length #: Integer?
38
42
 
39
43
  @translate_generics = translate_generics #: bool
@@ -75,7 +79,12 @@ module Spoom
75
79
  last_sigs.each do |node, sig|
76
80
  next if sig.is_abstract && !@translate_abstract_methods
77
81
 
78
- out = rbs_print(node.location.start_column) do |printer|
82
+ preserve_multiline_signatures = !!(@preserve_multiline_signatures && sig.loc&.multiline?)
83
+
84
+ out = rbs_print(
85
+ node.location.start_column,
86
+ preserve_multiline_signatures: preserve_multiline_signatures,
87
+ ) do |printer|
79
88
  printer.print_method_sig(rbi_node, sig)
80
89
  end
81
90
  @rewriter << Source::Replace.new(node.location.start_offset, node.location.end_offset, out)
@@ -180,7 +189,7 @@ module Spoom
180
189
  return unless sorbet_sig?(node)
181
190
 
182
191
  builder = RBI::Parser::SigBuilder.new(@ruby_contents, file: @file)
183
- builder.current.loc = node.location
192
+ builder.current.loc = RBI::Loc.from_prism(@file, node.location)
184
193
  builder.visit_call_node(node)
185
194
  builder.current.comments = []
186
195
 
@@ -204,7 +213,7 @@ module Spoom
204
213
  rbi_node = builder.tree.nodes.first #: as RBI::Attr
205
214
 
206
215
  last_sigs.each do |node, sig|
207
- out = rbs_print(node.location.start_column) do |printer|
216
+ out = rbs_print(node.location.start_column, preserve_multiline_signatures: false) do |printer|
208
217
  printer.print_attr_sig(rbi_node, sig)
209
218
  end
210
219
  @rewriter << Source::Replace.new(node.location.start_offset, node.location.end_offset, out)
@@ -387,10 +396,16 @@ module Spoom
387
396
  last_sigs
388
397
  end
389
398
 
390
- #: (Integer) { (RBI::RBSPrinter) -> void } -> String
391
- def rbs_print(indent, &block)
399
+ #: (Integer, preserve_multiline_signatures: bool) { (RBI::RBSPrinter) -> void } -> String
400
+ def rbs_print(indent, preserve_multiline_signatures:, &block)
392
401
  out = StringIO.new
393
- p = RBI::RBSPrinter.new(out: out, positional_names: @positional_names, max_line_length: @max_line_length)
402
+
403
+ p = RBI::RBSPrinter.new(
404
+ out: out,
405
+ positional_names: @positional_names,
406
+ max_line_length: @max_line_length,
407
+ force_multiline_signatures: preserve_multiline_signatures,
408
+ )
394
409
  block.call(p)
395
410
  string = out.string
396
411
 
@@ -30,13 +30,17 @@ module Spoom
30
30
  #| String,
31
31
  #| file: String,
32
32
  #| ?positional_names: bool,
33
+ #| ?preserve_multiline_signatures: bool,
33
34
  #| ?max_line_length: Integer?,
34
35
  #| ?translate_generics: bool,
35
36
  #| ?translate_helpers: bool,
36
37
  #| ?translate_abstract_methods: bool
37
38
  #| ) -> String
38
39
  def sorbet_sigs_to_rbs_comments(
39
- ruby_contents, file:, positional_names: true, max_line_length: nil,
40
+ ruby_contents, file:,
41
+ positional_names: true,
42
+ preserve_multiline_signatures: true,
43
+ max_line_length: nil,
40
44
  translate_generics: true,
41
45
  translate_helpers: true,
42
46
  translate_abstract_methods: true
@@ -45,6 +49,7 @@ module Spoom
45
49
  ruby_contents,
46
50
  file: file,
47
51
  positional_names: positional_names,
52
+ preserve_multiline_signatures: preserve_multiline_signatures,
48
53
  max_line_length: max_line_length,
49
54
  translate_generics: translate_generics,
50
55
  translate_helpers: translate_helpers,
@@ -54,13 +59,16 @@ module Spoom
54
59
 
55
60
  # Converts all the RBS comments in the given Ruby code to `sig` nodes.
56
61
  # It also handles type members and class annotations.
57
- #: (String ruby_contents, file: String, ?max_line_length: Integer?, ?overloads_strategy: Symbol) -> String
58
- def rbs_comments_to_sorbet_sigs(ruby_contents, file:, max_line_length: nil, overloads_strategy: :translate_all)
62
+ #: (String ruby_contents, file: String, ?max_line_length: Integer?,
63
+ #| ?overloads_strategy: Symbol, ?erase_generic_types: bool) -> String
64
+ def rbs_comments_to_sorbet_sigs(ruby_contents, file:, max_line_length: nil, overloads_strategy: :translate_all,
65
+ erase_generic_types: false)
59
66
  RBSCommentsToSorbetSigs.rewrite_if_needed(
60
67
  ruby_contents,
61
68
  file: file,
62
69
  max_line_length: max_line_length,
63
70
  overloads_strategy: overloads_strategy,
71
+ erase_generic_types: erase_generic_types,
64
72
  )
65
73
  end
66
74
 
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.8.3"
5
+ VERSION = "1.8.5"
6
6
  end