rubocop 1.88.0 → 1.88.2

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.
Files changed (115) hide show
  1. checksums.yaml +4 -4
  2. data/config/default.yml +5 -1
  3. data/lib/rubocop/cop/base.rb +13 -8
  4. data/lib/rubocop/cop/bundler/gem_comment.rb +3 -1
  5. data/lib/rubocop/cop/commissioner.rb +13 -11
  6. data/lib/rubocop/cop/correctors/each_to_for_corrector.rb +1 -1
  7. data/lib/rubocop/cop/correctors/lambda_literal_to_method_corrector.rb +7 -1
  8. data/lib/rubocop/cop/correctors/ordered_gem_corrector.rb +8 -1
  9. data/lib/rubocop/cop/gemspec/development_dependencies.rb +1 -1
  10. data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +12 -2
  11. data/lib/rubocop/cop/gemspec/require_mfa.rb +4 -1
  12. data/lib/rubocop/cop/layout/block_alignment.rb +17 -0
  13. data/lib/rubocop/cop/layout/class_structure.rb +7 -3
  14. data/lib/rubocop/cop/layout/comment_indentation.rb +9 -2
  15. data/lib/rubocop/cop/layout/condition_position.rb +13 -3
  16. data/lib/rubocop/cop/layout/else_alignment.rb +1 -14
  17. data/lib/rubocop/cop/layout/empty_comment.rb +8 -10
  18. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +14 -1
  19. data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +13 -14
  20. data/lib/rubocop/cop/layout/indentation_width.rb +28 -0
  21. data/lib/rubocop/cop/layout/line_length.rb +10 -5
  22. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +6 -1
  23. data/lib/rubocop/cop/layout/space_around_operators.rb +6 -2
  24. data/lib/rubocop/cop/lint/assignment_in_condition.rb +13 -1
  25. data/lib/rubocop/cop/lint/debugger.rb +13 -1
  26. data/lib/rubocop/cop/lint/numeric_operation_with_constant_result.rb +7 -0
  27. data/lib/rubocop/cop/lint/to_enum_arguments.rb +7 -1
  28. data/lib/rubocop/cop/lint/to_json.rb +8 -1
  29. data/lib/rubocop/cop/lint/unescaped_bracket_in_regexp.rb +32 -8
  30. data/lib/rubocop/cop/lint/unreachable_code.rb +9 -4
  31. data/lib/rubocop/cop/lint/useless_numeric_operation.rb +10 -10
  32. data/lib/rubocop/cop/lint/void.rb +2 -2
  33. data/lib/rubocop/cop/metrics/method_length.rb +1 -1
  34. data/lib/rubocop/cop/metrics/perceived_complexity.rb +38 -7
  35. data/lib/rubocop/cop/mixin/allowed_methods.rb +5 -5
  36. data/lib/rubocop/cop/mixin/allowed_pattern.rb +5 -1
  37. data/lib/rubocop/cop/mixin/forbidden_pattern.rb +5 -1
  38. data/lib/rubocop/cop/mixin/hash_subset.rb +8 -0
  39. data/lib/rubocop/cop/mixin/hash_transform_method.rb +4 -0
  40. data/lib/rubocop/cop/mixin/statement_modifier.rb +1 -1
  41. data/lib/rubocop/cop/naming/file_name.rb +4 -3
  42. data/lib/rubocop/cop/naming/inclusive_language.rb +8 -2
  43. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +9 -0
  44. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +9 -3
  45. data/lib/rubocop/cop/security/io_methods.rb +1 -1
  46. data/lib/rubocop/cop/security/marshal_load.rb +1 -1
  47. data/lib/rubocop/cop/style/accessor_grouping.rb +11 -1
  48. data/lib/rubocop/cop/style/arguments_forwarding.rb +1 -1
  49. data/lib/rubocop/cop/style/array_intersect.rb +4 -4
  50. data/lib/rubocop/cop/style/collection_compact.rb +1 -1
  51. data/lib/rubocop/cop/style/data_inheritance.rb +4 -0
  52. data/lib/rubocop/cop/style/def_with_parentheses.rb +6 -2
  53. data/lib/rubocop/cop/style/dir_empty.rb +4 -0
  54. data/lib/rubocop/cop/style/documentation_method.rb +5 -1
  55. data/lib/rubocop/cop/style/empty_case_condition.rb +12 -2
  56. data/lib/rubocop/cop/style/empty_class_definition.rb +8 -1
  57. data/lib/rubocop/cop/style/empty_heredoc.rb +4 -0
  58. data/lib/rubocop/cop/style/empty_literal.rb +7 -2
  59. data/lib/rubocop/cop/style/empty_string_inside_interpolation.rb +30 -20
  60. data/lib/rubocop/cop/style/env_home.rb +4 -0
  61. data/lib/rubocop/cop/style/even_odd.rb +11 -1
  62. data/lib/rubocop/cop/style/exact_regexp_match.rb +8 -1
  63. data/lib/rubocop/cop/style/file_null.rb +4 -2
  64. data/lib/rubocop/cop/style/format_string.rb +13 -1
  65. data/lib/rubocop/cop/style/hash_conversion.rb +14 -6
  66. data/lib/rubocop/cop/style/hash_lookup_method.rb +2 -6
  67. data/lib/rubocop/cop/style/hash_syntax.rb +2 -0
  68. data/lib/rubocop/cop/style/identical_conditional_branches.rb +15 -4
  69. data/lib/rubocop/cop/style/if_unless_modifier.rb +4 -4
  70. data/lib/rubocop/cop/style/if_with_semicolon.rb +9 -1
  71. data/lib/rubocop/cop/style/inline_comment.rb +1 -1
  72. data/lib/rubocop/cop/style/invertible_unless_condition.rb +25 -5
  73. data/lib/rubocop/cop/style/keyword_arguments_merging.rb +4 -0
  74. data/lib/rubocop/cop/style/keyword_parameters_order.rb +7 -3
  75. data/lib/rubocop/cop/style/lambda.rb +7 -1
  76. data/lib/rubocop/cop/style/lambda_call.rb +11 -0
  77. data/lib/rubocop/cop/style/map_compact_with_conditional_block.rb +11 -0
  78. data/lib/rubocop/cop/style/map_into_array.rb +1 -1
  79. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +11 -5
  80. data/lib/rubocop/cop/style/method_def_parentheses.rb +5 -1
  81. data/lib/rubocop/cop/style/min_max_comparison.rb +3 -0
  82. data/lib/rubocop/cop/style/missing_respond_to_missing.rb +10 -7
  83. data/lib/rubocop/cop/style/mixin_usage.rb +1 -1
  84. data/lib/rubocop/cop/style/module_function.rb +4 -2
  85. data/lib/rubocop/cop/style/multiline_if_then.rb +1 -1
  86. data/lib/rubocop/cop/style/multiline_memoization.rb +7 -1
  87. data/lib/rubocop/cop/style/multiline_method_signature.rb +11 -4
  88. data/lib/rubocop/cop/style/nil_lambda.rb +8 -0
  89. data/lib/rubocop/cop/style/numeric_predicate.rb +1 -1
  90. data/lib/rubocop/cop/style/open_struct_use.rb +1 -1
  91. data/lib/rubocop/cop/style/option_hash.rb +1 -1
  92. data/lib/rubocop/cop/style/optional_arguments.rb +1 -0
  93. data/lib/rubocop/cop/style/parallel_assignment.rb +11 -2
  94. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +2 -0
  95. data/lib/rubocop/cop/style/perl_backrefs.rb +5 -3
  96. data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +13 -1
  97. data/lib/rubocop/cop/style/redundant_exception.rb +6 -0
  98. data/lib/rubocop/cop/style/redundant_filter_chain.rb +1 -1
  99. data/lib/rubocop/cop/style/redundant_format.rb +28 -0
  100. data/lib/rubocop/cop/style/redundant_heredoc_delimiter_quotes.rb +6 -1
  101. data/lib/rubocop/cop/style/redundant_line_continuation.rb +11 -3
  102. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +8 -4
  103. data/lib/rubocop/cop/style/redundant_self.rb +9 -0
  104. data/lib/rubocop/cop/style/redundant_struct_keyword_init.rb +23 -4
  105. data/lib/rubocop/cop/style/semicolon.rb +4 -4
  106. data/lib/rubocop/cop/style/single_line_do_end_block.rb +17 -4
  107. data/lib/rubocop/cop/style/string_hash_keys.rb +1 -0
  108. data/lib/rubocop/cop/style/struct_inheritance.rb +3 -1
  109. data/lib/rubocop/cop/style/ternary_parentheses.rb +11 -0
  110. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +7 -8
  111. data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
  112. data/lib/rubocop/cop/team.rb +18 -4
  113. data/lib/rubocop/runner.rb +55 -13
  114. data/lib/rubocop/version.rb +1 -1
  115. metadata +2 -2
@@ -113,9 +113,7 @@ module RuboCop
113
113
 
114
114
  return unless first_offense
115
115
 
116
- if unused_variables_only?(first_offense, variables)
117
- return unused_range(node.type, mlhs_node, node.rhs)
118
- end
116
+ return unused_range(node, mlhs_node) if unused_variables_only?(first_offense, variables)
119
117
 
120
118
  return range_for_parentheses(first_offense, mlhs_node) if Util.parentheses?(mlhs_node)
121
119
 
@@ -130,13 +128,14 @@ module RuboCop
130
128
  offense.source_range == variables.first.source_range
131
129
  end
132
130
 
133
- def unused_range(node_type, mlhs_node, right)
131
+ def unused_range(node, mlhs_node)
134
132
  start_range = mlhs_node.source_range.begin_pos
135
133
 
136
- end_range = case node_type
137
- when :masgn
138
- right.source_range.begin_pos
139
- when :mlhs
134
+ # `node` can be an `mlhs` when recursing into a nested destructuring
135
+ # group; only a `masgn` has a right-hand side to anchor against.
136
+ end_range = if node.masgn_type?
137
+ node.rhs.source_range.begin_pos
138
+ else
140
139
  mlhs_node.source_range.end_pos
141
140
  end
142
141
 
@@ -234,7 +234,7 @@ module RuboCop
234
234
  def autocorrect_class(corrector, node)
235
235
  kind = trivial_accessor_kind(node)
236
236
 
237
- return unless names_match?(node) && kind
237
+ return unless names_match?(node) && !node.predicate_method? && kind
238
238
 
239
239
  indent = ' ' * node.loc.column
240
240
  corrector.replace(
@@ -59,6 +59,16 @@ module RuboCop
59
59
 
60
60
  attr_reader :errors, :warnings, :updated_source_file, :cops
61
61
 
62
+ # When set to true, the corrected source is not written back to the
63
+ # inspected file; it is exposed through `#updated_source` instead.
64
+ # @api private
65
+ attr_accessor :defer_corrections
66
+
67
+ # The corrected source of the last investigation, if corrections were
68
+ # made with `#defer_corrections` enabled.
69
+ # @api private
70
+ attr_reader :updated_source
71
+
62
72
  alias updated_source_file? updated_source_file
63
73
 
64
74
  def initialize(cops, config = nil, options = {})
@@ -135,20 +145,24 @@ module RuboCop
135
145
 
136
146
  def autocorrect(processed_source, corrector)
137
147
  @updated_source_file = false
148
+ @updated_source = nil
138
149
  return unless autocorrect?
139
150
  return unless corrector
140
151
  return if corrector.empty?
141
152
 
142
- new_source = corrector.rewrite
153
+ apply_correction(processed_source, corrector.rewrite)
154
+ @updated_source_file = true
155
+ end
143
156
 
157
+ def apply_correction(processed_source, new_source)
144
158
  if @options[:stdin]
145
159
  # holds source read in from stdin, when --stdin option is used
146
160
  @options[:stdin] = new_source
161
+ elsif defer_corrections
162
+ @updated_source = new_source
147
163
  else
148
- filename = processed_source.file_path
149
- File.write(filename, new_source)
164
+ File.write(processed_source.file_path, new_source)
150
165
  end
151
- @updated_source_file = true
152
166
  end
153
167
 
154
168
  def be_ready
@@ -120,7 +120,6 @@ module RuboCop
120
120
  file_iterator(files) do |file|
121
121
  offenses = process_file(file)
122
122
  succeeded = offenses.none? { |o| considered_failure?(o) && offense_displayed?(o) }
123
- raise Parallel::Break if @options[:fail_fast] && !succeeded
124
123
 
125
124
  [offenses, succeeded]
126
125
  end
@@ -211,8 +210,11 @@ module RuboCop
211
210
  on_start.call(file, index)
212
211
  result = yield file
213
212
  on_finish.call(file, index, result)
214
- rescue Parallel::Break
215
- break
213
+
214
+ # Report and count the offending file before stopping so `--fail-fast`
215
+ # still shows its offenses and exits with a failing status.
216
+ _offenses, succeeded = result
217
+ break if @options[:fail_fast] && !succeeded
216
218
  end
217
219
  end
218
220
 
@@ -344,16 +346,18 @@ module RuboCop
344
346
  # inspection iteration. This is used to output meaningful infinite loop
345
347
  # error message.
346
348
  offenses_by_iteration = []
349
+ corrected_source = nil
347
350
 
348
- # When running with --autocorrect, we need to inspect the file (which
349
- # includes writing a corrected version of it) until no more corrections
350
- # are made. This is because automatic corrections can introduce new
351
- # offenses. In the normal case the loop is only executed once.
351
+ # When running with --autocorrect, we need to inspect the file until no
352
+ # more corrections are made. This is because automatic corrections can
353
+ # introduce new offenses. In the normal case the loop is only executed
354
+ # once. The corrections are kept in memory while iterating and written
355
+ # back to the file when the loop is done.
352
356
  iterate_until_no_changes(processed_source, offenses_by_iteration) do
353
357
  # The offenses that couldn't be corrected will be found again so we
354
358
  # only keep the corrected ones in order to avoid duplicate reporting.
355
359
  !offenses_by_iteration.empty? && offenses_by_iteration.last.select!(&:corrected?)
356
- new_offenses, updated_source_file = inspect_file(processed_source)
360
+ team, new_offenses, updated_source_file = inspect_iteration(processed_source)
357
361
  offenses_by_iteration.push(new_offenses)
358
362
 
359
363
  # We have to reprocess the source to pickup the changes. Since the
@@ -362,12 +366,43 @@ module RuboCop
362
366
  break unless updated_source_file
363
367
 
364
368
  # Autocorrect has happened, don't use the prism result since it is stale.
365
- processed_source = get_processed_source(file, nil)
369
+ # With --stdin the corrected source is kept in @options[:stdin] instead.
370
+ corrected_source = team.updated_source
371
+ processed_source = get_processed_source(file, nil, source: corrected_source)
366
372
  end
367
373
 
368
374
  # Return summary of corrected offenses after all iterations
369
- offenses = offenses_by_iteration.flatten.uniq
370
- [processed_source, offenses]
375
+ [processed_source, offenses_by_iteration.flatten.uniq]
376
+ ensure
377
+ # Write the file once, even when the loop was left through an exception
378
+ # (e.g. an infinite correction loop), like the per-iteration writes
379
+ # used to be.
380
+ File.write(file, corrected_source) if corrected_source
381
+ end
382
+
383
+ def inspect_iteration(processed_source)
384
+ team = mobilize_team(processed_source)
385
+ team.defer_corrections = in_memory_corrections_possible?
386
+ offenses, updated_source_file = inspect_file(processed_source, team)
387
+ [team, offenses, updated_source_file]
388
+ end
389
+
390
+ # When corrections were written to disk and read back between iterations,
391
+ # the text-mode write converted LF to CRLF on Windows, and cops like
392
+ # `Layout/EndOfLine` rely on seeing the source as it would be on disk.
393
+ # Apply the same conversion to the in-memory source. The final `File.write`
394
+ # still performs it for the file itself.
395
+ def emulate_write_read_cycle(source)
396
+ return source unless Platform.windows?
397
+
398
+ source.encode(source.encoding, crlf_newline: true)
399
+ end
400
+
401
+ # Custom ruby extractors may derive their fragments from the file on
402
+ # disk rather than from the passed processed source, so corrections can
403
+ # only be kept in memory when the default extractor is used.
404
+ def in_memory_corrections_possible?
405
+ self.class.ruby_extractors.one?
371
406
  end
372
407
 
373
408
  def iterate_until_no_changes(source, offenses_by_iteration)
@@ -550,12 +585,19 @@ module RuboCop
550
585
  end
551
586
 
552
587
  # rubocop:disable Metrics/MethodLength
553
- def get_processed_source(file, prism_result)
588
+ def get_processed_source(file, prism_result, source: nil)
554
589
  config = @config_store.for_file(file)
555
590
  ruby_version = config.target_ruby_version
556
591
  parser_engine = config.parser_engine
557
592
 
558
- processed_source = if @options[:stdin]
593
+ processed_source = if source
594
+ ProcessedSource.new(
595
+ emulate_write_read_cycle(source),
596
+ ruby_version,
597
+ file,
598
+ parser_engine: parser_engine
599
+ )
600
+ elsif @options[:stdin]
559
601
  ProcessedSource.new(
560
602
  @options[:stdin],
561
603
  ruby_version,
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  # This module holds the RuboCop version information.
5
5
  module Version
6
- STRING = '1.88.0'
6
+ STRING = '1.88.2'
7
7
 
8
8
  MSG = '%<version>s (using %<parser_version>s, ' \
9
9
  'rubocop-ast %<rubocop_ast_version>s, ' \
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubocop
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.88.0
4
+ version: 1.88.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bozhidar Batsov
@@ -1119,7 +1119,7 @@ licenses:
1119
1119
  - MIT
1120
1120
  metadata:
1121
1121
  homepage_uri: https://rubocop.org/
1122
- changelog_uri: https://github.com/rubocop/rubocop/releases/tag/v1.88.0
1122
+ changelog_uri: https://github.com/rubocop/rubocop/releases/tag/v1.88.2
1123
1123
  source_code_uri: https://github.com/rubocop/rubocop/
1124
1124
  documentation_uri: https://docs.rubocop.org/rubocop/1.88/
1125
1125
  bug_tracker_uri: https://github.com/rubocop/rubocop/issues