rubocop 1.5.1 → 1.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (115) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +2 -2
  4. data/config/default.yml +111 -14
  5. data/config/obsoletion.yml +196 -0
  6. data/lib/rubocop.rb +20 -1
  7. data/lib/rubocop/cli/command/suggest_extensions.rb +19 -19
  8. data/lib/rubocop/comment_config.rb +6 -6
  9. data/lib/rubocop/config.rb +8 -5
  10. data/lib/rubocop/config_loader.rb +10 -6
  11. data/lib/rubocop/config_loader_resolver.rb +21 -4
  12. data/lib/rubocop/config_obsoletion.rb +64 -262
  13. data/lib/rubocop/config_obsoletion/changed_enforced_styles.rb +33 -0
  14. data/lib/rubocop/config_obsoletion/changed_parameter.rb +21 -0
  15. data/lib/rubocop/config_obsoletion/cop_rule.rb +34 -0
  16. data/lib/rubocop/config_obsoletion/extracted_cop.rb +44 -0
  17. data/lib/rubocop/config_obsoletion/parameter_rule.rb +44 -0
  18. data/lib/rubocop/config_obsoletion/removed_cop.rb +41 -0
  19. data/lib/rubocop/config_obsoletion/renamed_cop.rb +34 -0
  20. data/lib/rubocop/config_obsoletion/rule.rb +41 -0
  21. data/lib/rubocop/config_obsoletion/split_cop.rb +27 -0
  22. data/lib/rubocop/config_validator.rb +11 -4
  23. data/lib/rubocop/cop/base.rb +17 -15
  24. data/lib/rubocop/cop/cop.rb +2 -2
  25. data/lib/rubocop/cop/correctors/string_literal_corrector.rb +6 -8
  26. data/lib/rubocop/cop/gemspec/required_ruby_version.rb +3 -2
  27. data/lib/rubocop/cop/internal_affairs.rb +1 -0
  28. data/lib/rubocop/cop/internal_affairs/style_detected_api_use.rb +145 -0
  29. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +19 -3
  30. data/lib/rubocop/cop/layout/empty_lines_around_attribute_accessor.rb +1 -1
  31. data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +26 -0
  32. data/lib/rubocop/cop/layout/line_length.rb +6 -16
  33. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +7 -3
  34. data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +2 -2
  35. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +3 -10
  36. data/lib/rubocop/cop/layout/space_around_equals_in_parameter_default.rb +1 -0
  37. data/lib/rubocop/cop/layout/space_before_block_braces.rb +2 -0
  38. data/lib/rubocop/cop/layout/space_before_brackets.rb +62 -0
  39. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +13 -10
  40. data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +2 -2
  41. data/lib/rubocop/cop/lint/ambiguous_assignment.rb +59 -0
  42. data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +7 -2
  43. data/lib/rubocop/cop/lint/deprecated_constants.rb +75 -0
  44. data/lib/rubocop/cop/lint/duplicate_branch.rb +64 -2
  45. data/lib/rubocop/cop/lint/lambda_without_literal_block.rb +44 -0
  46. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +10 -6
  47. data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +2 -1
  48. data/lib/rubocop/cop/lint/redundant_dir_glob_sort.rb +48 -0
  49. data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +50 -17
  50. data/lib/rubocop/cop/lint/shadowed_exception.rb +1 -11
  51. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +13 -0
  52. data/lib/rubocop/cop/lint/unreachable_loop.rb +17 -0
  53. data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +1 -1
  54. data/lib/rubocop/cop/migration/department_name.rb +1 -1
  55. data/lib/rubocop/cop/mixin/allowed_identifiers.rb +18 -0
  56. data/lib/rubocop/cop/mixin/comments_help.rb +1 -10
  57. data/lib/rubocop/cop/mixin/first_element_line_break.rb +1 -1
  58. data/lib/rubocop/cop/mixin/string_help.rb +4 -1
  59. data/lib/rubocop/cop/naming/accessor_method_name.rb +15 -1
  60. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +59 -5
  61. data/lib/rubocop/cop/naming/variable_name.rb +2 -0
  62. data/lib/rubocop/cop/naming/variable_number.rb +1 -8
  63. data/lib/rubocop/cop/registry.rb +10 -0
  64. data/lib/rubocop/cop/style/access_modifier_declarations.rb +3 -1
  65. data/lib/rubocop/cop/style/character_literal.rb +10 -11
  66. data/lib/rubocop/cop/style/collection_methods.rb +14 -1
  67. data/lib/rubocop/cop/style/commented_keyword.rb +22 -5
  68. data/lib/rubocop/cop/style/empty_literal.rb +6 -2
  69. data/lib/rubocop/cop/style/endless_method.rb +102 -0
  70. data/lib/rubocop/cop/style/float_division.rb +44 -1
  71. data/lib/rubocop/cop/style/for.rb +2 -0
  72. data/lib/rubocop/cop/style/hash_except.rb +95 -0
  73. data/lib/rubocop/cop/style/hash_like_case.rb +2 -1
  74. data/lib/rubocop/cop/style/if_inside_else.rb +8 -3
  75. data/lib/rubocop/cop/style/if_unless_modifier.rb +4 -0
  76. data/lib/rubocop/cop/style/ip_addresses.rb +1 -1
  77. data/lib/rubocop/cop/style/keyword_parameters_order.rb +12 -2
  78. data/lib/rubocop/cop/style/lambda_call.rb +2 -1
  79. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +7 -0
  80. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +16 -6
  81. data/lib/rubocop/cop/style/method_def_parentheses.rb +7 -0
  82. data/lib/rubocop/cop/style/multiline_method_signature.rb +26 -1
  83. data/lib/rubocop/cop/style/multiline_when_then.rb +3 -1
  84. data/lib/rubocop/cop/style/mutable_constant.rb +13 -3
  85. data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +4 -0
  86. data/lib/rubocop/cop/style/perl_backrefs.rb +86 -9
  87. data/lib/rubocop/cop/style/raise_args.rb +5 -2
  88. data/lib/rubocop/cop/style/redundant_argument.rb +21 -2
  89. data/lib/rubocop/cop/style/redundant_freeze.rb +8 -4
  90. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +24 -8
  91. data/lib/rubocop/cop/style/redundant_return.rb +1 -1
  92. data/lib/rubocop/cop/style/single_line_block_params.rb +30 -7
  93. data/lib/rubocop/cop/style/single_line_methods.rb +33 -2
  94. data/lib/rubocop/cop/style/sole_nested_conditional.rb +25 -9
  95. data/lib/rubocop/cop/style/special_global_vars.rb +1 -13
  96. data/lib/rubocop/cop/style/string_concatenation.rb +26 -1
  97. data/lib/rubocop/cop/style/string_literals.rb +14 -8
  98. data/lib/rubocop/cop/style/string_literals_in_interpolation.rb +4 -3
  99. data/lib/rubocop/cop/style/symbol_proc.rb +5 -4
  100. data/lib/rubocop/cop/util.rb +3 -1
  101. data/lib/rubocop/ext/regexp_node.rb +31 -9
  102. data/lib/rubocop/ext/regexp_parser.rb +21 -3
  103. data/lib/rubocop/formatter/emacs_style_formatter.rb +2 -0
  104. data/lib/rubocop/formatter/simple_text_formatter.rb +2 -0
  105. data/lib/rubocop/formatter/tap_formatter.rb +2 -0
  106. data/lib/rubocop/lockfile.rb +40 -0
  107. data/lib/rubocop/options.rb +9 -9
  108. data/lib/rubocop/rspec/cop_helper.rb +0 -4
  109. data/lib/rubocop/rspec/expect_offense.rb +34 -22
  110. data/lib/rubocop/runner.rb +16 -1
  111. data/lib/rubocop/target_finder.rb +4 -2
  112. data/lib/rubocop/target_ruby.rb +47 -11
  113. data/lib/rubocop/util.rb +16 -0
  114. data/lib/rubocop/version.rb +8 -2
  115. metadata +42 -9
@@ -68,7 +68,8 @@ module RuboCop
68
68
  length = cop_config['MinBranchesCount'] || 3
69
69
  return length if length.is_a?(Integer) && length.positive?
70
70
 
71
- raise 'MinBranchesCount needs to be a positive integer!'
71
+ warn Rainbow('`MinBranchesCount` needs to be a positive integer!').red
72
+ exit!
72
73
  end
73
74
  end
74
75
  end
@@ -82,12 +82,10 @@ module RuboCop
82
82
  def autocorrect(corrector, node)
83
83
  if node.modifier_form?
84
84
  correct_to_elsif_from_modifier_form(corrector, node)
85
- end_range = node.parent.loc.end
86
85
  else
87
86
  correct_to_elsif_from_if_inside_else_form(corrector, node, node.condition)
88
- end_range = node.loc.end
89
87
  end
90
- corrector.remove(range_by_whole_lines(end_range, include_final_newline: true))
88
+ corrector.remove(range_by_whole_lines(find_end_range(node), include_final_newline: true))
91
89
  corrector.remove(
92
90
  range_by_whole_lines(node.if_branch.source_range, include_final_newline: true)
93
91
  )
@@ -110,6 +108,13 @@ module RuboCop
110
108
  corrector.remove(condition)
111
109
  end
112
110
 
111
+ def find_end_range(node)
112
+ end_range = node.loc.end
113
+ return end_range if end_range
114
+
115
+ find_end_range(node.parent)
116
+ end
117
+
113
118
  def allow_if_modifier_in_else_branch?(else_branch)
114
119
  allow_if_modifier? && else_branch&.modifier_form?
115
120
  end
@@ -46,6 +46,10 @@ module RuboCop
46
46
  MSG_USE_NORMAL =
47
47
  'Modifier form of `%<keyword>s` makes the line too long.'
48
48
 
49
+ def self.autocorrect_incompatible_with
50
+ [Style::SoleNestedConditional]
51
+ end
52
+
49
53
  def on_if(node)
50
54
  msg = if single_line_as_modifier?(node) && !named_capture_in_condition?(node)
51
55
  MSG_USE_MODIFIER
@@ -18,7 +18,7 @@ module RuboCop
18
18
  #
19
19
  # # good
20
20
  # ip_address = ENV['DEPLOYMENT_IP_ADDRESS']
21
- class IpAddresses < Cop
21
+ class IpAddresses < Base
22
22
  include StringHelp
23
23
 
24
24
  IPV6_MAX_SIZE = 45 # IPv4-mapped IPv6 is the longest
@@ -21,6 +21,16 @@ module RuboCop
21
21
  # # body omitted
22
22
  # end
23
23
  #
24
+ # # bad
25
+ # do_something do |first: false, second:, third: 10|
26
+ # # body omitted
27
+ # end
28
+ #
29
+ # # good
30
+ # do_something do |second:, first: false, third: 10|
31
+ # # body omitted
32
+ # end
33
+ #
24
34
  class KeywordParametersOrder < Base
25
35
  include RangeHelp
26
36
  extend AutoCorrector
@@ -35,7 +45,7 @@ module RuboCop
35
45
  if node.parent.find(&:kwoptarg_type?) == node
36
46
  corrector.insert_before(node, "#{kwarg_nodes.map(&:source).join(', ')}, ")
37
47
 
38
- arguments = node.each_ancestor(:def, :defs).first.arguments
48
+ arguments = node.each_ancestor(:def, :defs, :block).first.arguments
39
49
  append_newline_to_last_kwoptarg(arguments, corrector) unless parentheses?(arguments)
40
50
 
41
51
  remove_kwargs(kwarg_nodes, corrector)
@@ -50,7 +60,7 @@ module RuboCop
50
60
  return if last_argument.kwrestarg_type? || last_argument.blockarg_type?
51
61
 
52
62
  last_kwoptarg = arguments.reverse.find(&:kwoptarg_type?)
53
- corrector.insert_after(last_kwoptarg, "\n")
63
+ corrector.insert_after(last_kwoptarg, "\n") unless arguments.parent.block_type?
54
64
  end
55
65
 
56
66
  def remove_kwargs(kwarg_nodes, corrector)
@@ -27,8 +27,9 @@ module RuboCop
27
27
  def on_send(node)
28
28
  return unless node.receiver
29
29
 
30
- if offense?(node) && opposite_style_detected
30
+ if offense?(node)
31
31
  add_offense(node) do |corrector|
32
+ opposite_style_detected
32
33
  autocorrect(corrector, node)
33
34
  end
34
35
  else
@@ -40,6 +40,9 @@ module RuboCop
40
40
  # to `true` allows the presence of parentheses in such a method call
41
41
  # even with arguments.
42
42
  #
43
+ # NOTE: Parens are required around a method with arguments when inside an
44
+ # endless method definition (>= Ruby 3.0).
45
+ #
43
46
  # @example EnforcedStyle: require_parentheses (default)
44
47
  #
45
48
  # # bad
@@ -154,6 +157,10 @@ module RuboCop
154
157
  include OmitParentheses
155
158
  extend AutoCorrector
156
159
 
160
+ def self.autocorrect_incompatible_with
161
+ [Style::NestedParenthesizedCalls]
162
+ end
163
+
157
164
  def on_send(node)
158
165
  send(style, node) # call require_parentheses or omit_parentheses
159
166
  end
@@ -14,25 +14,35 @@ module RuboCop
14
14
 
15
15
  def omit_parentheses(node)
16
16
  return unless node.parenthesized?
17
+ return if inside_endless_method_def?(node)
17
18
  return if node.implicit_call?
18
19
  return if super_call_without_arguments?(node)
19
20
  return if allowed_camel_case_method_call?(node)
20
21
  return if legitimate_call_with_parentheses?(node)
21
22
 
22
23
  add_offense(offense_range(node), message: OMIT_MSG) do |corrector|
23
- if parentheses_at_the_end_of_multiline_call?(node)
24
- corrector.replace(args_begin(node), ' \\')
25
- else
26
- corrector.replace(args_begin(node), ' ')
27
- end
28
- corrector.remove(node.loc.end)
24
+ auto_correct(corrector, node)
25
+ end
26
+ end
27
+
28
+ def auto_correct(corrector, node)
29
+ if parentheses_at_the_end_of_multiline_call?(node)
30
+ corrector.replace(args_begin(node), ' \\')
31
+ else
32
+ corrector.replace(args_begin(node), ' ')
29
33
  end
34
+ corrector.remove(node.loc.end)
30
35
  end
31
36
 
32
37
  def offense_range(node)
33
38
  node.loc.begin.join(node.loc.end)
34
39
  end
35
40
 
41
+ def inside_endless_method_def?(node)
42
+ # parens are required around arguments inside an endless method
43
+ node.each_ancestor(:def).any?(&:endless?) && node.arguments.any?
44
+ end
45
+
36
46
  def super_call_without_arguments?(node)
37
47
  node.super_type? && node.arguments.none?
38
48
  end
@@ -6,6 +6,9 @@ module RuboCop
6
6
  # This cop checks for parentheses around the arguments in method
7
7
  # definitions. Both instance and class/singleton methods are checked.
8
8
  #
9
+ # This cop does not consider endless methods, since parentheses are
10
+ # always required for them.
11
+ #
9
12
  # @example EnforcedStyle: require_parentheses (default)
10
13
  # # The `require_parentheses` style requires method definitions
11
14
  # # to always use parentheses
@@ -94,6 +97,8 @@ module RuboCop
94
97
  'parameters.'
95
98
 
96
99
  def on_def(node)
100
+ return if node.endless?
101
+
97
102
  args = node.arguments
98
103
 
99
104
  if require_parentheses?(args)
@@ -142,6 +147,7 @@ module RuboCop
142
147
 
143
148
  add_offense(location, message: MSG_MISSING) do |corrector|
144
149
  correct_definition(node, corrector)
150
+ unexpected_style_detected 'require_no_parentheses'
145
151
  end
146
152
  end
147
153
 
@@ -149,6 +155,7 @@ module RuboCop
149
155
  add_offense(args, message: MSG_PRESENT) do |corrector|
150
156
  # offense is registered on args node when parentheses are unwanted
151
157
  correct_arguments(args, corrector)
158
+ unexpected_style_detected 'require_parentheses'
152
159
  end
153
160
  end
154
161
  end
@@ -19,6 +19,9 @@ module RuboCop
19
19
  # end
20
20
  #
21
21
  class MultilineMethodSignature < Base
22
+ include RangeHelp
23
+ extend AutoCorrector
24
+
22
25
  MSG = 'Avoid multi-line method signatures.'
23
26
 
24
27
  def on_def(node)
@@ -26,12 +29,34 @@ module RuboCop
26
29
  return if opening_line(node) == closing_line(node)
27
30
  return if correction_exceeds_max_line_length?(node)
28
31
 
29
- add_offense(node)
32
+ add_offense(node) do |corrector|
33
+ autocorrect(corrector, node)
34
+ end
30
35
  end
31
36
  alias on_defs on_def
32
37
 
33
38
  private
34
39
 
40
+ def autocorrect(corrector, node)
41
+ arguments = node.arguments
42
+ joined_arguments = arguments.map(&:source).join(', ')
43
+ last_line_source_of_arguments = processed_source[arguments.last_line - 1].strip
44
+
45
+ if last_line_source_of_arguments.start_with?(')')
46
+ joined_arguments = "#{joined_arguments}#{last_line_source_of_arguments}"
47
+
48
+ corrector.remove(range_by_whole_lines(arguments.loc.end, include_final_newline: true))
49
+ end
50
+
51
+ corrector.replace(arguments_range(node), joined_arguments)
52
+ end
53
+
54
+ def arguments_range(node)
55
+ range_between(
56
+ node.first_argument.source_range.begin_pos, node.last_argument.source_range.end_pos
57
+ )
58
+ end
59
+
35
60
  def opening_line(node)
36
61
  node.first_line
37
62
  end
@@ -58,7 +58,9 @@ module RuboCop
58
58
  private
59
59
 
60
60
  def require_then?(when_node)
61
- return true if when_node.conditions.count >= 2
61
+ unless when_node.conditions.first.first_line == when_node.conditions.last.last_line
62
+ return true
63
+ end
62
64
  return false unless when_node.body
63
65
 
64
66
  when_node.loc.line == when_node.body.loc.line
@@ -14,6 +14,8 @@ module RuboCop
14
14
  # positives. Luckily, there is no harm in freezing an already
15
15
  # frozen object.
16
16
  #
17
+ # NOTE: Regexp and Range literals are frozen objects since Ruby 3.0.
18
+ #
17
19
  # @example EnforcedStyle: literals (default)
18
20
  # # bad
19
21
  # CONST = [1, 2, 3]
@@ -94,7 +96,8 @@ module RuboCop
94
96
  range_enclosed_in_parentheses = range_enclosed_in_parentheses?(value)
95
97
 
96
98
  return unless mutable_literal?(value) ||
97
- range_enclosed_in_parentheses
99
+ target_ruby_version <= 2.7 && range_enclosed_in_parentheses
100
+
98
101
  return if FROZEN_STRING_LITERAL_TYPES.include?(value.type) &&
99
102
  frozen_string_literals_enabled?
100
103
 
@@ -119,11 +122,14 @@ module RuboCop
119
122
  end
120
123
 
121
124
  def mutable_literal?(value)
122
- value&.mutable_literal?
125
+ return false if value.nil?
126
+ return false if frozen_regexp_or_range_literals?(value)
127
+
128
+ value.mutable_literal?
123
129
  end
124
130
 
125
131
  def immutable_literal?(node)
126
- node.nil? || node.immutable_literal?
132
+ node.nil? || frozen_regexp_or_range_literals?(node) || node.immutable_literal?
127
133
  end
128
134
 
129
135
  def frozen_string_literal?(node)
@@ -131,6 +137,10 @@ module RuboCop
131
137
  frozen_string_literals_enabled?
132
138
  end
133
139
 
140
+ def frozen_regexp_or_range_literals?(node)
141
+ target_ruby_version >= 3.0 && (node.regexp_type? || node.range_type?)
142
+ end
143
+
134
144
  def requires_parentheses?(node)
135
145
  node.range_type? ||
136
146
  (node.send_type? && node.loc.dot.nil?)
@@ -19,6 +19,10 @@ module RuboCop
19
19
 
20
20
  MSG = 'Add parentheses to nested method call `%<source>s`.'
21
21
 
22
+ def self.autocorrect_incompatible_with
23
+ [Style::MethodCallWithArgsParentheses]
24
+ end
25
+
22
26
  def on_send(node)
23
27
  return unless node.parenthesized?
24
28
 
@@ -4,7 +4,8 @@ module RuboCop
4
4
  module Cop
5
5
  module Style
6
6
  # This cop looks for uses of Perl-style regexp match
7
- # backreferences like $1, $2, etc.
7
+ # backreferences and their English versions like
8
+ # $1, $2, $&, &+, $MATCH, $PREMATCH, etc.
8
9
  #
9
10
  # @example
10
11
  # # bad
@@ -15,19 +16,95 @@ module RuboCop
15
16
  class PerlBackrefs < Base
16
17
  extend AutoCorrector
17
18
 
18
- MSG = 'Avoid the use of Perl-style backrefs.'
19
+ MESSAGE_FORMAT = 'Prefer `%<preferred_expression>s` over `%<original_expression>s`.'
20
+
21
+ def on_back_ref(node)
22
+ on_back_ref_or_gvar_or_nth_ref(node)
23
+ end
24
+
25
+ def on_gvar(node)
26
+ on_back_ref_or_gvar_or_nth_ref(node)
27
+ end
19
28
 
20
29
  def on_nth_ref(node)
21
- add_offense(node) do |corrector|
22
- backref, = *node
23
- parent_type = node.parent ? node.parent.type : nil
30
+ on_back_ref_or_gvar_or_nth_ref(node)
31
+ end
24
32
 
25
- if %i[dstr xstr regexp].include?(parent_type)
26
- corrector.replace(node, "{Regexp.last_match(#{backref})}")
33
+ private
34
+
35
+ # @private
36
+ # @param [RuboCop::AST::Node] node
37
+ # @return [Boolean]
38
+ def derived_from_braceless_interpolation?(node)
39
+ %i[
40
+ dstr
41
+ regexp
42
+ xstr
43
+ ].include?(node.parent&.type)
44
+ end
45
+
46
+ # @private
47
+ # @param [RuboCop::AST::Node] node
48
+ # @param [String] preferred_expression
49
+ # @return [String]
50
+ def format_message(node:, preferred_expression:)
51
+ original_expression = original_expression_of(node)
52
+ format(
53
+ MESSAGE_FORMAT,
54
+ original_expression: original_expression,
55
+ preferred_expression: preferred_expression
56
+ )
57
+ end
27
58
 
28
- else
29
- corrector.replace(node, "Regexp.last_match(#{backref})")
59
+ # @private
60
+ # @param [RuboCop::AST::Node] node
61
+ # @return [String]
62
+ def original_expression_of(node)
63
+ first = node.to_a.first
64
+ if first.is_a?(::Integer)
65
+ "$#{first}"
66
+ else
67
+ first.to_s
68
+ end
69
+ end
70
+
71
+ # @private
72
+ # @param [RuboCop::AST::Node] node
73
+ # @return [String, nil]
74
+ def preferred_expression_to(node)
75
+ first = node.to_a.first
76
+ case first
77
+ when ::Integer
78
+ "Regexp.last_match(#{first})"
79
+ when :$&, :$MATCH
80
+ 'Regexp.last_match(0)'
81
+ when :$`, :$PREMATCH
82
+ 'Regexp.last_match.pre_match'
83
+ when :$', :$POSTMATCH
84
+ 'Regexp.last_match.post_match'
85
+ when :$+, :$LAST_PAREN_MATCH
86
+ 'Regexp.last_match(-1)'
87
+ end
88
+ end
89
+
90
+ # @private
91
+ # @param [RuboCop::AST::Node] node
92
+ def on_back_ref_or_gvar_or_nth_ref(node)
93
+ preferred_expression = preferred_expression_to(node)
94
+ return unless preferred_expression
95
+
96
+ add_offense(
97
+ node,
98
+ message: format_message(
99
+ node: node,
100
+ preferred_expression: preferred_expression
101
+ )
102
+ ) do |corrector|
103
+ if derived_from_braceless_interpolation?(node)
104
+ preferred_expression = "{#{preferred_expression}}"
30
105
  end
106
+
107
+ corrector.replace(node, preferred_expression)
31
108
  end
32
109
  end
33
110
  end
@@ -81,11 +81,12 @@ module RuboCop
81
81
  return node.source if message_nodes.size > 1
82
82
 
83
83
  argument = message_nodes.first.source
84
+ exception_class = exception_node.const_name || exception_node.receiver.source
84
85
 
85
86
  if node.parent && requires_parens?(node.parent)
86
- "#{node.method_name}(#{exception_node.const_name}.new(#{argument}))"
87
+ "#{node.method_name}(#{exception_class}.new(#{argument}))"
87
88
  else
88
- "#{node.method_name} #{exception_node.const_name}.new(#{argument})"
89
+ "#{node.method_name} #{exception_class}.new(#{argument})"
89
90
  end
90
91
  end
91
92
 
@@ -95,6 +96,7 @@ module RuboCop
95
96
  replacement = correction_exploded_to_compact(node)
96
97
 
97
98
  corrector.replace(node, replacement)
99
+ opposite_style_detected
98
100
  end
99
101
  else
100
102
  correct_style_detected
@@ -115,6 +117,7 @@ module RuboCop
115
117
  replacement = correction_compact_to_exploded(node)
116
118
 
117
119
  corrector.replace(node, replacement)
120
+ opposite_style_detected
118
121
  end
119
122
  end
120
123