rubocop 1.5.2 → 1.8.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 (113) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +3 -2
  4. data/config/default.yml +112 -16
  5. data/config/obsoletion.yml +196 -0
  6. data/lib/rubocop.rb +20 -1
  7. data/lib/rubocop/cli/command/suggest_extensions.rb +16 -44
  8. data/lib/rubocop/comment_config.rb +6 -6
  9. data/lib/rubocop/config.rb +8 -5
  10. data/lib/rubocop/config_loader.rb +11 -7
  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 +14 -0
  32. data/lib/rubocop/cop/layout/line_length.rb +6 -16
  33. data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +2 -2
  34. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +3 -10
  35. data/lib/rubocop/cop/layout/space_around_equals_in_parameter_default.rb +1 -0
  36. data/lib/rubocop/cop/layout/space_before_block_braces.rb +2 -0
  37. data/lib/rubocop/cop/layout/space_before_brackets.rb +62 -0
  38. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +13 -10
  39. data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +2 -2
  40. data/lib/rubocop/cop/lint/ambiguous_assignment.rb +59 -0
  41. data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +7 -2
  42. data/lib/rubocop/cop/lint/deprecated_constants.rb +75 -0
  43. data/lib/rubocop/cop/lint/duplicate_branch.rb +64 -2
  44. data/lib/rubocop/cop/lint/lambda_without_literal_block.rb +44 -0
  45. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +10 -6
  46. data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +2 -1
  47. data/lib/rubocop/cop/lint/redundant_dir_glob_sort.rb +50 -0
  48. data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +50 -17
  49. data/lib/rubocop/cop/lint/shadowed_exception.rb +1 -11
  50. data/lib/rubocop/cop/lint/unreachable_loop.rb +17 -0
  51. data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +1 -1
  52. data/lib/rubocop/cop/migration/department_name.rb +1 -1
  53. data/lib/rubocop/cop/mixin/allowed_identifiers.rb +18 -0
  54. data/lib/rubocop/cop/mixin/comments_help.rb +1 -10
  55. data/lib/rubocop/cop/mixin/first_element_line_break.rb +1 -1
  56. data/lib/rubocop/cop/mixin/string_help.rb +4 -1
  57. data/lib/rubocop/cop/mixin/uncommunicative_name.rb +5 -1
  58. data/lib/rubocop/cop/naming/accessor_method_name.rb +15 -1
  59. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +59 -5
  60. data/lib/rubocop/cop/naming/variable_name.rb +2 -0
  61. data/lib/rubocop/cop/naming/variable_number.rb +1 -8
  62. data/lib/rubocop/cop/registry.rb +10 -0
  63. data/lib/rubocop/cop/style/access_modifier_declarations.rb +3 -1
  64. data/lib/rubocop/cop/style/character_literal.rb +10 -11
  65. data/lib/rubocop/cop/style/collection_methods.rb +14 -1
  66. data/lib/rubocop/cop/style/commented_keyword.rb +22 -5
  67. data/lib/rubocop/cop/style/empty_literal.rb +6 -2
  68. data/lib/rubocop/cop/style/endless_method.rb +102 -0
  69. data/lib/rubocop/cop/style/explicit_block_argument.rb +10 -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_return.rb +1 -1
  91. data/lib/rubocop/cop/style/single_line_block_params.rb +30 -7
  92. data/lib/rubocop/cop/style/single_line_methods.rb +34 -2
  93. data/lib/rubocop/cop/style/sole_nested_conditional.rb +15 -9
  94. data/lib/rubocop/cop/style/special_global_vars.rb +1 -13
  95. data/lib/rubocop/cop/style/string_concatenation.rb +20 -1
  96. data/lib/rubocop/cop/style/string_literals.rb +14 -8
  97. data/lib/rubocop/cop/style/string_literals_in_interpolation.rb +4 -3
  98. data/lib/rubocop/cop/style/symbol_proc.rb +5 -4
  99. data/lib/rubocop/cop/style/while_until_modifier.rb +2 -4
  100. data/lib/rubocop/cop/util.rb +3 -1
  101. data/lib/rubocop/formatter/emacs_style_formatter.rb +2 -0
  102. data/lib/rubocop/formatter/simple_text_formatter.rb +2 -0
  103. data/lib/rubocop/formatter/tap_formatter.rb +2 -0
  104. data/lib/rubocop/lockfile.rb +40 -0
  105. data/lib/rubocop/options.rb +9 -9
  106. data/lib/rubocop/rspec/cop_helper.rb +0 -4
  107. data/lib/rubocop/rspec/expect_offense.rb +34 -22
  108. data/lib/rubocop/runner.rb +16 -1
  109. data/lib/rubocop/target_finder.rb +4 -2
  110. data/lib/rubocop/target_ruby.rb +47 -11
  111. data/lib/rubocop/util.rb +16 -0
  112. data/lib/rubocop/version.rb +8 -2
  113. metadata +28 -7
@@ -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
 
@@ -12,7 +12,7 @@ module RuboCop
12
12
  # 1. This cop matches for method names only and hence cannot tell apart
13
13
  # methods with same name in different classes.
14
14
  # 2. This cop is limited to methods with single parameter.
15
- # 3. This cop is unsafe if certain special global variables (e.g. `$;`) are set.
15
+ # 3. This cop is unsafe if certain special global variables (e.g. `$;`, `$/`) are set.
16
16
  # That depends on the nature of the target methods, of course.
17
17
  #
18
18
  # Method names and their redundant arguments can be configured like this:
@@ -20,6 +20,8 @@ module RuboCop
20
20
  # Methods:
21
21
  # join: ''
22
22
  # split: ' '
23
+ # chomp: "\n"
24
+ # chomp!: "\n"
23
25
  # foo: 2
24
26
  #
25
27
  # @example
@@ -28,6 +30,8 @@ module RuboCop
28
30
  # [1, 2, 3].join("")
29
31
  # string.split(" ")
30
32
  # "first\nsecond".split(" ")
33
+ # string.chomp("\n")
34
+ # string.chomp!("\n")
31
35
  # A.foo(2)
32
36
  #
33
37
  # # good
@@ -35,8 +39,13 @@ module RuboCop
35
39
  # [1, 2, 3].join
36
40
  # string.split
37
41
  # "first second".split
42
+ # string.chomp
43
+ # string.chomp!
38
44
  # A.foo
39
45
  class RedundantArgument < Base
46
+ include RangeHelp
47
+ extend AutoCorrector
48
+
40
49
  MSG = 'Argument %<arg>s is redundant because it is implied by default.'
41
50
 
42
51
  def on_send(node)
@@ -44,7 +53,9 @@ module RuboCop
44
53
  return if node.arguments.count != 1
45
54
  return unless redundant_argument?(node)
46
55
 
47
- add_offense(node, message: format(MSG, arg: node.arguments.first.source))
56
+ add_offense(node, message: format(MSG, arg: node.arguments.first.source)) do |corrector|
57
+ corrector.remove(argument_range(node))
58
+ end
48
59
  end
49
60
 
50
61
  private
@@ -69,6 +80,14 @@ module RuboCop
69
80
  Parser::CurrentRuby.new(builder).parse(buffer)
70
81
  end
71
82
  end
83
+
84
+ def argument_range(node)
85
+ if node.parenthesized?
86
+ range_between(node.loc.begin.begin_pos, node.loc.end.end_pos)
87
+ else
88
+ range_with_surrounding_space(range: node.first_argument.source_range, newlines: false)
89
+ end
90
+ end
72
91
  end
73
92
  end
74
93
  end
@@ -3,7 +3,9 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Style
6
- # This cop check for uses of Object#freeze on immutable objects.
6
+ # This cop check for uses of `Object#freeze` on immutable objects.
7
+ #
8
+ # NOTE: Regexp and Range literals are frozen objects since Ruby 3.0.
7
9
  #
8
10
  # @example
9
11
  # # bad
@@ -37,8 +39,10 @@ module RuboCop
37
39
 
38
40
  return true if node.immutable_literal?
39
41
 
40
- FROZEN_STRING_LITERAL_TYPES.include?(node.type) &&
41
- frozen_string_literals_enabled?
42
+ return true if FROZEN_STRING_LITERAL_TYPES.include?(node.type) &&
43
+ frozen_string_literals_enabled?
44
+
45
+ target_ruby_version >= 3.0 && (node.regexp_type? || node.range_type?)
42
46
  end
43
47
 
44
48
  def strip_parenthesis(node)
@@ -52,7 +56,7 @@ module RuboCop
52
56
  def_node_matcher :operation_produces_immutable_object?, <<~PATTERN
53
57
  {
54
58
  (begin (send {float int} {:+ :- :* :** :/ :% :<<} _))
55
- (begin (send !(str _) {:+ :- :* :** :/ :%} {float int}))
59
+ (begin (send !{(str _) array} {:+ :- :* :** :/ :%} {float int}))
56
60
  (begin (send _ {:== :=== :!= :<= :>= :< :>} _))
57
61
  (send (const {nil? cbase} :ENV) :[] _)
58
62
  (send _ {:count :length :size} ...)