rubocop 1.1.0 → 1.4.1

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 (98) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +29 -12
  3. data/config/default.yml +113 -16
  4. data/exe/rubocop +1 -1
  5. data/lib/rubocop.rb +9 -0
  6. data/lib/rubocop/cli/command/execute_runner.rb +26 -11
  7. data/lib/rubocop/config_loader.rb +14 -5
  8. data/lib/rubocop/config_regeneration.rb +1 -1
  9. data/lib/rubocop/cop/bundler/duplicated_gem.rb +3 -3
  10. data/lib/rubocop/cop/bundler/gem_comment.rb +1 -1
  11. data/lib/rubocop/cop/commissioner.rb +1 -1
  12. data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +1 -1
  13. data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +3 -3
  14. data/lib/rubocop/cop/gemspec/required_ruby_version.rb +4 -5
  15. data/lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb +1 -1
  16. data/lib/rubocop/cop/generator.rb +2 -9
  17. data/lib/rubocop/cop/generator/configuration_injector.rb +1 -1
  18. data/lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +1 -1
  19. data/lib/rubocop/cop/layout/block_alignment.rb +3 -4
  20. data/lib/rubocop/cop/layout/class_structure.rb +15 -3
  21. data/lib/rubocop/cop/layout/else_alignment.rb +15 -2
  22. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +77 -7
  23. data/lib/rubocop/cop/layout/end_alignment.rb +3 -3
  24. data/lib/rubocop/cop/layout/hash_alignment.rb +4 -4
  25. data/lib/rubocop/cop/layout/line_length.rb +8 -1
  26. data/lib/rubocop/cop/layout/space_around_block_parameters.rb +24 -18
  27. data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +1 -1
  28. data/lib/rubocop/cop/layout/space_inside_parens.rb +35 -13
  29. data/lib/rubocop/cop/lint/ambiguous_regexp_literal.rb +2 -1
  30. data/lib/rubocop/cop/lint/constant_definition_in_block.rb +26 -2
  31. data/lib/rubocop/cop/lint/debugger.rb +17 -27
  32. data/lib/rubocop/cop/lint/duplicate_branch.rb +93 -0
  33. data/lib/rubocop/cop/lint/duplicate_case_condition.rb +2 -12
  34. data/lib/rubocop/cop/lint/else_layout.rb +29 -3
  35. data/lib/rubocop/cop/lint/empty_block.rb +38 -2
  36. data/lib/rubocop/cop/lint/empty_class.rb +93 -0
  37. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +22 -4
  38. data/lib/rubocop/cop/lint/loop.rb +4 -4
  39. data/lib/rubocop/cop/lint/missing_super.rb +7 -4
  40. data/lib/rubocop/cop/lint/nested_percent_literal.rb +14 -0
  41. data/lib/rubocop/cop/lint/no_return_in_begin_end_blocks.rb +58 -0
  42. data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +19 -16
  43. data/lib/rubocop/cop/lint/shadowed_exception.rb +4 -5
  44. data/lib/rubocop/cop/lint/to_enum_arguments.rb +6 -15
  45. data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +13 -4
  46. data/lib/rubocop/cop/lint/useless_method_definition.rb +2 -4
  47. data/lib/rubocop/cop/lint/useless_setter_call.rb +6 -1
  48. data/lib/rubocop/cop/metrics/method_length.rb +1 -1
  49. data/lib/rubocop/cop/mixin/check_line_breakable.rb +1 -1
  50. data/lib/rubocop/cop/mixin/configurable_numbering.rb +3 -3
  51. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +1 -1
  52. data/lib/rubocop/cop/mixin/statement_modifier.rb +9 -4
  53. data/lib/rubocop/cop/mixin/visibility_help.rb +1 -3
  54. data/lib/rubocop/cop/naming/binary_operator_parameter_name.rb +11 -1
  55. data/lib/rubocop/cop/naming/heredoc_delimiter_case.rb +11 -5
  56. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +67 -18
  57. data/lib/rubocop/cop/naming/variable_number.rb +98 -8
  58. data/lib/rubocop/cop/style/and_or.rb +1 -3
  59. data/lib/rubocop/cop/style/bisected_attr_accessor.rb +0 -4
  60. data/lib/rubocop/cop/style/case_like_if.rb +0 -4
  61. data/lib/rubocop/cop/style/collection_compact.rb +91 -0
  62. data/lib/rubocop/cop/style/document_dynamic_eval_definition.rb +107 -5
  63. data/lib/rubocop/cop/style/documentation.rb +12 -1
  64. data/lib/rubocop/cop/style/double_negation.rb +6 -1
  65. data/lib/rubocop/cop/style/hash_syntax.rb +3 -3
  66. data/lib/rubocop/cop/style/identical_conditional_branches.rb +7 -2
  67. data/lib/rubocop/cop/style/if_inside_else.rb +37 -1
  68. data/lib/rubocop/cop/style/if_unless_modifier.rb +7 -3
  69. data/lib/rubocop/cop/style/infinite_loop.rb +4 -0
  70. data/lib/rubocop/cop/style/keyword_parameters_order.rb +12 -0
  71. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +2 -2
  72. data/lib/rubocop/cop/style/mixin_grouping.rb +0 -4
  73. data/lib/rubocop/cop/style/multiple_comparison.rb +3 -2
  74. data/lib/rubocop/cop/style/negated_if_else_condition.rb +106 -0
  75. data/lib/rubocop/cop/style/nil_lambda.rb +52 -0
  76. data/lib/rubocop/cop/style/raise_args.rb +21 -6
  77. data/lib/rubocop/cop/style/redundant_argument.rb +73 -0
  78. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +1 -1
  79. data/lib/rubocop/cop/style/static_class.rb +97 -0
  80. data/lib/rubocop/cop/style/while_until_modifier.rb +9 -0
  81. data/lib/rubocop/cop/util.rb +5 -1
  82. data/lib/rubocop/cop/variable_force/branch.rb +1 -1
  83. data/lib/rubocop/cop/variable_force/scope.rb +1 -1
  84. data/lib/rubocop/ext/regexp_node.rb +10 -5
  85. data/lib/rubocop/ext/regexp_parser.rb +9 -2
  86. data/lib/rubocop/formatter/disabled_config_formatter.rb +21 -6
  87. data/lib/rubocop/formatter/formatter_set.rb +1 -0
  88. data/lib/rubocop/formatter/git_hub_actions_formatter.rb +47 -0
  89. data/lib/rubocop/options.rb +7 -0
  90. data/lib/rubocop/rake_task.rb +2 -2
  91. data/lib/rubocop/runner.rb +1 -1
  92. data/lib/rubocop/target_finder.rb +1 -1
  93. data/lib/rubocop/target_ruby.rb +65 -1
  94. data/lib/rubocop/version.rb +1 -1
  95. metadata +14 -8
  96. data/bin/console +0 -10
  97. data/bin/rubocop-profile +0 -32
  98. data/bin/setup +0 -7
@@ -13,5 +13,5 @@ time = Benchmark.realtime do
13
13
  result = cli.run
14
14
  end
15
15
 
16
- puts "Finished in #{time} seconds" if cli.options[:debug]
16
+ puts "Finished in #{time} seconds" if cli.options[:debug] || cli.options[:display_time]
17
17
  exit result
@@ -259,6 +259,7 @@ require_relative 'rubocop/cop/lint/debugger'
259
259
  require_relative 'rubocop/cop/lint/deprecated_class_methods'
260
260
  require_relative 'rubocop/cop/lint/deprecated_open_ssl_constant'
261
261
  require_relative 'rubocop/cop/lint/disjunctive_assignment_in_constructor'
262
+ require_relative 'rubocop/cop/lint/duplicate_branch'
262
263
  require_relative 'rubocop/cop/lint/duplicate_case_condition'
263
264
  require_relative 'rubocop/cop/lint/duplicate_elsif_condition'
264
265
  require_relative 'rubocop/cop/lint/duplicate_hash_key'
@@ -269,6 +270,7 @@ require_relative 'rubocop/cop/lint/duplicate_rescue_exception'
269
270
  require_relative 'rubocop/cop/lint/each_with_object_argument'
270
271
  require_relative 'rubocop/cop/lint/else_layout'
271
272
  require_relative 'rubocop/cop/lint/empty_block'
273
+ require_relative 'rubocop/cop/lint/empty_class'
272
274
  require_relative 'rubocop/cop/lint/empty_conditional_body'
273
275
  require_relative 'rubocop/cop/lint/empty_ensure'
274
276
  require_relative 'rubocop/cop/lint/empty_expression'
@@ -298,6 +300,7 @@ require_relative 'rubocop/cop/lint/multiple_comparison'
298
300
  require_relative 'rubocop/cop/lint/nested_method_definition'
299
301
  require_relative 'rubocop/cop/lint/nested_percent_literal'
300
302
  require_relative 'rubocop/cop/lint/next_without_accumulator'
303
+ require_relative 'rubocop/cop/lint/no_return_in_begin_end_blocks'
301
304
  require_relative 'rubocop/cop/lint/non_deterministic_require_order'
302
305
  require_relative 'rubocop/cop/lint/non_local_exit_from_iterator'
303
306
  require_relative 'rubocop/cop/lint/number_conversion'
@@ -409,6 +412,7 @@ require_relative 'rubocop/cop/style/class_equality_comparison'
409
412
  require_relative 'rubocop/cop/style/class_methods'
410
413
  require_relative 'rubocop/cop/style/class_methods_definitions'
411
414
  require_relative 'rubocop/cop/style/class_vars'
415
+ require_relative 'rubocop/cop/style/collection_compact'
412
416
  require_relative 'rubocop/cop/style/collection_methods'
413
417
  require_relative 'rubocop/cop/style/colon_method_call'
414
418
  require_relative 'rubocop/cop/style/colon_method_definition'
@@ -478,6 +482,7 @@ require_relative 'rubocop/cop/style/redundant_fetch_block'
478
482
  require_relative 'rubocop/cop/style/redundant_file_extension_in_require'
479
483
  require_relative 'rubocop/cop/style/redundant_self_assignment'
480
484
  require_relative 'rubocop/cop/style/sole_nested_conditional'
485
+ require_relative 'rubocop/cop/style/static_class'
481
486
  require_relative 'rubocop/cop/style/method_called_on_do_end_block'
482
487
  require_relative 'rubocop/cop/style/method_def_parentheses'
483
488
  require_relative 'rubocop/cop/style/min_max'
@@ -496,6 +501,7 @@ require_relative 'rubocop/cop/style/multiline_when_then'
496
501
  require_relative 'rubocop/cop/style/multiple_comparison'
497
502
  require_relative 'rubocop/cop/style/mutable_constant'
498
503
  require_relative 'rubocop/cop/style/negated_if'
504
+ require_relative 'rubocop/cop/style/negated_if_else_condition'
499
505
  require_relative 'rubocop/cop/style/negated_unless'
500
506
  require_relative 'rubocop/cop/style/negated_while'
501
507
  require_relative 'rubocop/cop/style/nested_modifier'
@@ -503,6 +509,7 @@ require_relative 'rubocop/cop/style/nested_parenthesized_calls'
503
509
  require_relative 'rubocop/cop/style/nested_ternary_operator'
504
510
  require_relative 'rubocop/cop/style/next'
505
511
  require_relative 'rubocop/cop/style/nil_comparison'
512
+ require_relative 'rubocop/cop/style/nil_lambda'
506
513
  require_relative 'rubocop/cop/style/non_nil_check'
507
514
  require_relative 'rubocop/cop/style/not'
508
515
  require_relative 'rubocop/cop/style/numeric_literals'
@@ -522,6 +529,7 @@ require_relative 'rubocop/cop/style/preferred_hash_methods'
522
529
  require_relative 'rubocop/cop/style/proc'
523
530
  require_relative 'rubocop/cop/style/raise_args'
524
531
  require_relative 'rubocop/cop/style/random_with_offset'
532
+ require_relative 'rubocop/cop/style/redundant_argument'
525
533
  require_relative 'rubocop/cop/style/redundant_begin'
526
534
  require_relative 'rubocop/cop/style/redundant_capital_w'
527
535
  require_relative 'rubocop/cop/style/redundant_condition'
@@ -602,6 +610,7 @@ require_relative 'rubocop/formatter/disabled_config_formatter'
602
610
  require_relative 'rubocop/formatter/emacs_style_formatter'
603
611
  require_relative 'rubocop/formatter/file_list_formatter'
604
612
  require_relative 'rubocop/formatter/fuubar_style_formatter'
613
+ require_relative 'rubocop/formatter/git_hub_actions_formatter'
605
614
  require_relative 'rubocop/formatter/html_formatter'
606
615
  require_relative 'rubocop/formatter/json_formatter'
607
616
  require_relative 'rubocop/formatter/junit_formatter'
@@ -22,12 +22,13 @@ module RuboCop
22
22
  def execute_runner(paths)
23
23
  runner = Runner.new(@options, @config_store)
24
24
 
25
- all_passed = runner.run(paths)
26
- display_warning_summary(runner.warnings)
27
- display_error_summary(runner.errors)
28
- maybe_print_corrected_source
25
+ all_pass_or_excluded = with_redirect do
26
+ all_passed = runner.run(paths)
27
+ display_summary(runner)
28
+ all_passed || @options[:auto_gen_config]
29
+ end
29
30
 
30
- all_pass_or_excluded = all_passed || @options[:auto_gen_config]
31
+ maybe_print_corrected_source
31
32
 
32
33
  if runner.aborting?
33
34
  STATUS_INTERRUPTED
@@ -38,6 +39,25 @@ module RuboCop
38
39
  end
39
40
  end
40
41
 
42
+ def with_redirect
43
+ if @options[:stderr]
44
+ orig_stdout = $stdout.dup
45
+ $stdout.reopen($stderr)
46
+
47
+ result = yield
48
+
49
+ $stdout.reopen(orig_stdout)
50
+ result
51
+ else
52
+ yield
53
+ end
54
+ end
55
+
56
+ def display_summary(runner)
57
+ display_warning_summary(runner.warnings)
58
+ display_error_summary(runner.errors)
59
+ end
60
+
41
61
  def display_warning_summary(warnings)
42
62
  return if warnings.empty?
43
63
 
@@ -69,14 +89,9 @@ module RuboCop
69
89
  # See: https://github.com/rubocop-hq/rubocop/issues/8673
70
90
  return if INTEGRATION_FORMATTERS.include?(@options[:format])
71
91
 
72
- # If we are asked to autocorrect source code read from stdin, the only
73
- # reasonable place to write it is to stdout
74
- # Unfortunately, we also write other information to stdout
75
- # So a delimiter is needed for tools to easily identify where the
76
- # autocorrected source begins
77
92
  return unless @options[:stdin] && @options[:auto_correct]
78
93
 
79
- puts '=' * 20
94
+ (@options[:stderr] ? $stderr : $stdout).puts '=' * 20
80
95
  print @options[:stdin]
81
96
  end
82
97
  end
@@ -256,16 +256,25 @@ module RuboCop
256
256
  end
257
257
 
258
258
  def yaml_safe_load(yaml_code, filename)
259
- if defined?(SafeYAML) && SafeYAML.respond_to?(:load)
260
- SafeYAML.load(yaml_code, filename, whitelisted_tags: %w[!ruby/regexp])
261
- # Ruby 2.6+
262
- elsif Gem::Version.new(Psych::VERSION) >= Gem::Version.new('3.1.0')
259
+ yaml_safe_load!(yaml_code, filename)
260
+ rescue ::StandardError
261
+ if defined?(::SafeYAML)
262
+ raise 'SafeYAML is unmaintained, no longer needed and should be removed'
263
+ end
264
+
265
+ raise
266
+ end
267
+
268
+ if Gem::Version.new(Psych::VERSION) >= Gem::Version.new('3.1.0')
269
+ def yaml_safe_load!(yaml_code, filename)
263
270
  YAML.safe_load(yaml_code,
264
271
  permitted_classes: [Regexp, Symbol],
265
272
  permitted_symbols: [],
266
273
  aliases: true,
267
274
  filename: filename)
268
- else
275
+ end
276
+ else # Ruby < 2.6
277
+ def yaml_safe_load!(yaml_code, filename)
269
278
  YAML.safe_load(yaml_code, [Regexp, Symbol], [], true, filename)
270
279
  end
271
280
  end
@@ -16,7 +16,7 @@ module RuboCop
16
16
  match = generation_command.match(COMMAND_REGEX)
17
17
  return DEFAULT_OPTIONS unless match
18
18
 
19
- options = match[1].split(' ')
19
+ options = match[1].split
20
20
  Options.new.parse(options).first
21
21
  end
22
22
 
@@ -35,13 +35,13 @@ module RuboCop
35
35
  # gem 'rubocop', '~> 0.90.0'
36
36
  # end
37
37
  #
38
- class DuplicatedGem < Cop
38
+ class DuplicatedGem < Base
39
39
  include RangeHelp
40
40
 
41
41
  MSG = 'Gem `%<gem_name>s` requirements already given on line '\
42
42
  '%<line_of_first_occurrence>d of the Gemfile.'
43
43
 
44
- def investigate(processed_source)
44
+ def on_new_investigation
45
45
  return if processed_source.blank?
46
46
 
47
47
  duplicated_gem_nodes.each do |nodes|
@@ -89,7 +89,7 @@ module RuboCop
89
89
  gem_name: gem_name,
90
90
  line_of_first_occurrence: line_of_first_occurrence
91
91
  )
92
- add_offense(node, location: offense_location, message: message)
92
+ add_offense(offense_location, message: message)
93
93
  end
94
94
  end
95
95
  end
@@ -58,7 +58,7 @@ module RuboCop
58
58
  # # Version 2.1 introduces breaking change baz
59
59
  # gem 'bar', '< 2.1'
60
60
  #
61
- class GemComment < Cop
61
+ class GemComment < Base
62
62
  include DefNode
63
63
 
64
64
  MSG = 'Missing gem description comment.'
@@ -138,7 +138,7 @@ module RuboCop
138
138
  end
139
139
  end
140
140
 
141
- # Note: mutates `callbacks` in place
141
+ # NOTE: mutates `callbacks` in place
142
142
  def restricted_map(callbacks)
143
143
  map = {}
144
144
  callbacks&.select! do |cop|
@@ -48,7 +48,7 @@ module RuboCop
48
48
  def autocorrect_multiline_words(node, escape, delimiters)
49
49
  contents = process_multiline_words(node, escape, delimiters)
50
50
  contents << end_content(node.source)
51
- contents.join('')
51
+ contents.join
52
52
  end
53
53
 
54
54
  def autocorrect_words(node, escape, delimiters)
@@ -34,7 +34,7 @@ module RuboCop
34
34
  # spec.add_runtime_dependency('parallel', '~> 1.10')
35
35
  # spec.add_runtime_dependency('parser', '>= 2.3.3.1', '< 3.0')
36
36
  # end
37
- class DuplicatedAssignment < Cop
37
+ class DuplicatedAssignment < Base
38
38
  include RangeHelp
39
39
 
40
40
  MSG = '`%<assignment>s` method calls already given on line '\
@@ -54,7 +54,7 @@ module RuboCop
54
54
  (lvar #match_block_variable_name?) #assignment_method? ...)
55
55
  PATTERN
56
56
 
57
- def investigate(processed_source)
57
+ def on_new_investigation
58
58
  return if processed_source.blank?
59
59
 
60
60
  duplicated_assignment_method_nodes.each do |nodes|
@@ -96,7 +96,7 @@ module RuboCop
96
96
  assignment: assignment,
97
97
  line_of_first_occurrence: line_of_first_occurrence
98
98
  )
99
- add_offense(node, location: offense_location, message: message)
99
+ add_offense(offense_location, message: message)
100
100
  end
101
101
  end
102
102
  end
@@ -45,7 +45,7 @@ module RuboCop
45
45
  # Gem::Specification.new do |spec|
46
46
  # spec.required_ruby_version = '~> 2.5'
47
47
  # end
48
- class RequiredRubyVersion < Cop
48
+ class RequiredRubyVersion < Base
49
49
  include RangeHelp
50
50
 
51
51
  NOT_EQUAL_MSG = '`required_ruby_version` (%<required_ruby_version>s, ' \
@@ -64,7 +64,7 @@ module RuboCop
64
64
  PATTERN
65
65
 
66
66
  # rubocop:disable Metrics/AbcSize
67
- def investigate(processed_source)
67
+ def on_new_investigation
68
68
  version_def = required_ruby_version(processed_source.ast).first
69
69
 
70
70
  if version_def
@@ -72,13 +72,12 @@ module RuboCop
72
72
  return if !ruby_version || ruby_version == target_ruby_version.to_s
73
73
 
74
74
  add_offense(
75
- processed_source.ast,
76
- location: version_def.loc.expression,
75
+ version_def.loc.expression,
77
76
  message: not_equal_message(ruby_version, target_ruby_version)
78
77
  )
79
78
  else
80
79
  range = source_range(processed_source.buffer, 1, 0)
81
- add_offense(nil, location: range, message: MISSING_MSG)
80
+ add_offense(range, message: MISSING_MSG)
82
81
  end
83
82
  end
84
83
  # rubocop:enable Metrics/AbcSize
@@ -25,7 +25,7 @@ module RuboCop
25
25
  # spec.add_runtime_dependency 'gem_a'
26
26
  # end
27
27
  #
28
- class RubyVersionGlobalsUsage < Cop
28
+ class RubyVersionGlobalsUsage < Base
29
29
  MSG = 'Do not use `RUBY_VERSION` in gemspec file.'
30
30
 
31
31
  def_node_matcher :ruby_version?, '(const {cbase nil?} :RUBY_VERSION)'
@@ -8,7 +8,7 @@ module RuboCop
8
8
  # and spec file when given a valid qualified cop name.
9
9
  # @api private
10
10
  class Generator
11
- # Note: RDoc 5.1.0 or lower has the following issue.
11
+ # NOTE: RDoc 5.1.0 or lower has the following issue.
12
12
  # https://github.com/rubocop-hq/rubocop/issues/7043
13
13
  #
14
14
  # The following `String#gsub` can be replaced with
@@ -17,7 +17,6 @@ module RuboCop
17
17
  SOURCE_TEMPLATE = <<-RUBY.gsub(/^ {8}/, '')
18
18
  # frozen_string_literal: true
19
19
 
20
- # TODO: when finished, run `rake generate_cops_documentation` to update the docs
21
20
  module RuboCop
22
21
  module Cop
23
22
  module %<department>s
@@ -134,7 +133,7 @@ module RuboCop
134
133
  end
135
134
 
136
135
  def inject_config(config_file_path: 'config/default.yml',
137
- version_added: bump_minor_version)
136
+ version_added: '<<next>>')
138
137
  injector =
139
138
  ConfigurationInjector.new(configuration_file_path: config_file_path,
140
139
  badge: badge,
@@ -213,12 +212,6 @@ module RuboCop
213
212
  .gsub(/([A-Z])([A-Z][^A-Z\d]+)/, '\1_\2')
214
213
  .downcase
215
214
  end
216
-
217
- def bump_minor_version
218
- versions = RuboCop::Version::STRING.split('.')
219
-
220
- "#{versions[0]}.#{versions[1].succ}"
221
- end
222
215
  end
223
216
  end
224
217
  end
@@ -14,7 +14,7 @@ module RuboCop
14
14
  VersionAdded: '%<version_added>s'
15
15
  YAML
16
16
 
17
- def initialize(configuration_file_path:, badge:, version_added:)
17
+ def initialize(configuration_file_path:, badge:, version_added: '<<next>>')
18
18
  @configuration_file_path = configuration_file_path
19
19
  @badge = badge
20
20
  @version_added = version_added
@@ -38,7 +38,7 @@ module RuboCop
38
38
 
39
39
  def assertions_using_described_class_msg
40
40
  described_class_msg(processed_source.ast).reject do |node|
41
- node.ancestors.any?(&method(:rspec_expectation_on_msg?))
41
+ node.ancestors.any? { |ancestor| rspec_expectation_on_msg?(ancestor) }
42
42
  end
43
43
  end
44
44
 
@@ -210,10 +210,9 @@ module RuboCop
210
210
  end
211
211
 
212
212
  def alt_start_msg(start_loc, source_line_column)
213
- if style != :either
214
- ''
215
- elsif start_loc.line == source_line_column[:line] &&
216
- start_loc.column == source_line_column[:column]
213
+ if style != :either ||
214
+ (start_loc.line == source_line_column[:line] &&
215
+ start_loc.column == source_line_column[:column])
217
216
  ''
218
217
  else
219
218
  " or #{format_source_line_column(source_line_column)}"
@@ -147,6 +147,10 @@ module RuboCop
147
147
  MSG = '`%<category>s` is supposed to appear before ' \
148
148
  '`%<previous>s`.'
149
149
 
150
+ def_node_matcher :dynamic_constant?, <<~PATTERN
151
+ (casgn nil? _ (send ...))
152
+ PATTERN
153
+
150
154
  # Validates code style on class declaration.
151
155
  # Add offense when find a node out of expected order.
152
156
  def on_class(class_node)
@@ -168,11 +172,10 @@ module RuboCop
168
172
 
169
173
  # Autocorrect by swapping between two nodes autocorrecting them
170
174
  def autocorrect(corrector, node)
171
- node_classification = classify(node)
172
175
  previous = node.left_siblings.find do |sibling|
173
- classification = classify(sibling)
174
- !ignore?(classification) && node_classification != classification
176
+ !ignore_for_autocorrect?(node, sibling)
175
177
  end
178
+ return unless previous
176
179
 
177
180
  current_range = source_range_with_comment(node)
178
181
  previous_range = source_range_with_comment(previous)
@@ -241,6 +244,15 @@ module RuboCop
241
244
  expected_order.index(classification).nil?
242
245
  end
243
246
 
247
+ def ignore_for_autocorrect?(node, sibling)
248
+ classification = classify(node)
249
+ sibling_class = classify(sibling)
250
+
251
+ ignore?(sibling_class) ||
252
+ classification == sibling_class ||
253
+ dynamic_constant?(node)
254
+ end
255
+
244
256
  def humanize_node(node)
245
257
  if node.def_type?
246
258
  return :initializer if node.method?(:initialize)
@@ -4,7 +4,7 @@ module RuboCop
4
4
  module Cop
5
5
  module Layout
6
6
  # This cop checks the alignment of else keywords. Normally they should
7
- # be aligned with an if/unless/while/until/begin/def keyword, but there
7
+ # be aligned with an if/unless/while/until/begin/def/rescue keyword, but there
8
8
  # are special cases when they should follow the same rules as the
9
9
  # alignment of end.
10
10
  #
@@ -93,7 +93,13 @@ module RuboCop
93
93
  case parent.type
94
94
  when :def, :defs then base_for_method_definition(parent)
95
95
  when :kwbegin then parent.loc.begin
96
- when :block then parent.send_node.source_range
96
+ when :block
97
+ assignment_node = assignment_node(parent)
98
+ if same_line?(parent, assignment_node)
99
+ assignment_node.source_range
100
+ else
101
+ parent.send_node.source_range
102
+ end
97
103
  else node.loc.keyword
98
104
  end
99
105
  end
@@ -136,6 +142,13 @@ module RuboCop
136
142
  )
137
143
  add_offense(else_range, location: else_range, message: message)
138
144
  end
145
+
146
+ def assignment_node(node)
147
+ assignment_node = node.ancestors.first
148
+ return unless assignment_node&.assignment?
149
+
150
+ assignment_node
151
+ end
139
152
  end
140
153
  end
141
154
  end