rubocop 1.5.2 → 1.8.1

Sign up to get free protection for your applications and to get access to all the features.
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} ...)