rubocop-performance 1.16.0 → 1.18.0

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 (31) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -2
  3. data/config/default.yml +1 -0
  4. data/lib/rubocop/cop/performance/case_when_splat.rb +2 -2
  5. data/lib/rubocop/cop/performance/compare_with_block.rb +19 -10
  6. data/lib/rubocop/cop/performance/constant_regexp.rb +4 -0
  7. data/lib/rubocop/cop/performance/count.rb +1 -1
  8. data/lib/rubocop/cop/performance/detect.rb +3 -6
  9. data/lib/rubocop/cop/performance/double_start_end_with.rb +2 -2
  10. data/lib/rubocop/cop/performance/end_with.rb +1 -1
  11. data/lib/rubocop/cop/performance/flat_map.rb +6 -4
  12. data/lib/rubocop/cop/performance/inefficient_hash_search.rb +1 -1
  13. data/lib/rubocop/cop/performance/io_readlines.rb +1 -1
  14. data/lib/rubocop/cop/performance/redundant_block_call.rb +1 -1
  15. data/lib/rubocop/cop/performance/redundant_equality_comparison_block.rb +34 -2
  16. data/lib/rubocop/cop/performance/redundant_match.rb +1 -1
  17. data/lib/rubocop/cop/performance/redundant_merge.rb +2 -2
  18. data/lib/rubocop/cop/performance/redundant_string_chars.rb +2 -2
  19. data/lib/rubocop/cop/performance/regexp_match.rb +16 -12
  20. data/lib/rubocop/cop/performance/reverse_first.rb +1 -1
  21. data/lib/rubocop/cop/performance/select_map.rb +1 -1
  22. data/lib/rubocop/cop/performance/squeeze.rb +1 -1
  23. data/lib/rubocop/cop/performance/start_with.rb +1 -1
  24. data/lib/rubocop/cop/performance/string_identifier_argument.rb +15 -10
  25. data/lib/rubocop/cop/performance/string_include.rb +1 -1
  26. data/lib/rubocop/cop/performance/string_replacement.rb +1 -1
  27. data/lib/rubocop/cop/performance/sum.rb +1 -1
  28. data/lib/rubocop/cop/performance/times_map.rb +1 -1
  29. data/lib/rubocop/cop/performance/uri_default_parser.rb +1 -1
  30. data/lib/rubocop/performance/version.rb +1 -1
  31. metadata +5 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7b0361feae763e4c8cbea3bd0160a1e4b0646b2e3b3246fb8dd55a5f21a53acd
4
- data.tar.gz: 152d09678555d309441fb809f60b07b69b04289b3949bf1eaca3e9b70b3afe13
3
+ metadata.gz: f4926be80598b4880037ffd36eef32c9025051af7f0398f69a34439c135c9d87
4
+ data.tar.gz: ba3d738da529cbc70c33e8c5d4baa4c6c8013a5498c834f2e28dc87a8811c15a
5
5
  SHA512:
6
- metadata.gz: 9f08bd2f25c0e0e537bf8fa5378e701d6b6b6794a45fe534229e73a0dd4bd623dd415965966655a802cc8e93a3776880d99c89245947aae090ba2c49f0bb183f
7
- data.tar.gz: 34f697ee70070d32d17b3684712cec5628e71cbdb393722fec3bb0dbc541cf65af92a762907dbbb0c5e6c3023f8dd4738e06a131a5a28014749dac440e15bc92
6
+ metadata.gz: 1b9a64379554a660c30bffea5a0fc8a8d36a9e31efef6ccb4576f4df432d2f270d91d76b0e7e7638740e6cf83a50b94b4dfe37d93e5366d0171b8a0f4e5bff50
7
+ data.tar.gz: d27b9db647eb1a53f3e80b0ec20cd43b37b0244127a28f7fbdacefcf9477205a7f4d373c0a27d882fcb43f902d4ab398ad73ea3f51cdd21e5d422cd419d621e9
data/README.md CHANGED
@@ -11,7 +11,7 @@ Performance optimization analysis for your projects, as an extension to [RuboCop
11
11
  Just install the `rubocop-performance` gem
12
12
 
13
13
  ```sh
14
- gem install rubocop-performance
14
+ $ gem install rubocop-performance
15
15
  ```
16
16
 
17
17
  or if you use bundler put this in your `Gemfile`
@@ -47,7 +47,7 @@ cops together with the standard cops.
47
47
  ### Command line
48
48
 
49
49
  ```sh
50
- rubocop --require rubocop-performance
50
+ $ rubocop --require rubocop-performance
51
51
  ```
52
52
 
53
53
  ### Rake task
data/config/default.yml CHANGED
@@ -226,6 +226,7 @@ Performance/RedundantEqualityComparisonBlock:
226
226
  Reference: 'https://github.com/rails/rails/pull/41363'
227
227
  Enabled: pending
228
228
  Safe: false
229
+ AllowRegexpMatch: true
229
230
  VersionAdded: '1.10'
230
231
 
231
232
  Performance/RedundantMatch:
@@ -99,7 +99,7 @@ module RuboCop
99
99
 
100
100
  def inline_fix_branch(corrector, when_node)
101
101
  conditions = when_node.conditions
102
- range = range_between(conditions[0].loc.expression.begin_pos, conditions[-1].loc.expression.end_pos)
102
+ range = range_between(conditions[0].source_range.begin_pos, conditions[-1].source_range.end_pos)
103
103
 
104
104
  corrector.replace(range, replacement(conditions))
105
105
  end
@@ -110,7 +110,7 @@ module RuboCop
110
110
  return if when_branches.one?
111
111
 
112
112
  corrector.remove(when_branch_range(when_node))
113
- corrector.insert_after(when_branches.last.source_range, reordering_correction(when_node))
113
+ corrector.insert_after(when_branches.last, reordering_correction(when_node))
114
114
  end
115
115
 
116
116
  def reordering_correction(when_node)
@@ -5,35 +5,42 @@ module RuboCop
5
5
  module Performance
6
6
  # Identifies places where `sort { |a, b| a.foo <=> b.foo }`
7
7
  # can be replaced by `sort_by(&:foo)`.
8
- # This cop also checks `max` and `min` methods.
8
+ # This cop also checks `sort!`, `min`, `max` and `minmax` methods.
9
9
  #
10
10
  # @example
11
11
  # # bad
12
- # array.sort { |a, b| a.foo <=> b.foo }
13
- # array.max { |a, b| a.foo <=> b.foo }
14
- # array.min { |a, b| a.foo <=> b.foo }
15
- # array.sort { |a, b| a[:foo] <=> b[:foo] }
12
+ # array.sort { |a, b| a.foo <=> b.foo }
13
+ # array.sort! { |a, b| a.foo <=> b.foo }
14
+ # array.max { |a, b| a.foo <=> b.foo }
15
+ # array.min { |a, b| a.foo <=> b.foo }
16
+ # array.minmax { |a, b| a.foo <=> b.foo }
17
+ # array.sort { |a, b| a[:foo] <=> b[:foo] }
16
18
  #
17
19
  # # good
18
20
  # array.sort_by(&:foo)
21
+ # array.sort_by!(&:foo)
19
22
  # array.sort_by { |v| v.foo }
20
23
  # array.sort_by do |var|
21
24
  # var.foo
22
25
  # end
23
26
  # array.max_by(&:foo)
24
27
  # array.min_by(&:foo)
28
+ # array.minmax_by(&:foo)
25
29
  # array.sort_by { |a| a[:foo] }
26
30
  class CompareWithBlock < Base
27
31
  include RangeHelp
28
32
  extend AutoCorrector
29
33
 
30
- MSG = 'Use `%<compare_method>s_by%<instead>s` instead of ' \
34
+ MSG = 'Use `%<replacement_method>s%<instead>s` instead of ' \
31
35
  '`%<compare_method>s { |%<var_a>s, %<var_b>s| %<str_a>s ' \
32
36
  '<=> %<str_b>s }`.'
33
37
 
38
+ REPLACEMENT = { sort: :sort_by, sort!: :sort_by!, min: :min_by, max: :max_by, minmax: :minmax_by }.freeze
39
+ private_constant :REPLACEMENT
40
+
34
41
  def_node_matcher :compare?, <<~PATTERN
35
42
  (block
36
- $(send _ {:sort :min :max})
43
+ $(send _ {:sort :sort! :min :max :minmax})
37
44
  (args (arg $_a) (arg $_b))
38
45
  $send)
39
46
  PATTERN
@@ -54,9 +61,9 @@ module RuboCop
54
61
 
55
62
  add_offense(range, message: message(send, method, var_a, var_b, args_a)) do |corrector|
56
63
  replacement = if method == :[]
57
- "#{send.method_name}_by { |a| a[#{args_a.first.source}] }"
64
+ "#{REPLACEMENT[send.method_name]} { |a| a[#{args_a.first.source}] }"
58
65
  else
59
- "#{send.method_name}_by(&:#{method})"
66
+ "#{REPLACEMENT[send.method_name]}(&:#{method})"
60
67
  end
61
68
  corrector.replace(range, replacement)
62
69
  end
@@ -82,7 +89,8 @@ module RuboCop
82
89
 
83
90
  # rubocop:disable Metrics/MethodLength
84
91
  def message(send, method, var_a, var_b, args)
85
- compare_method = send.method_name
92
+ compare_method = send.method_name
93
+ replacement_method = REPLACEMENT[compare_method]
86
94
  if method == :[]
87
95
  key = args.first
88
96
  instead = " { |a| a[#{key.source}] }"
@@ -94,6 +102,7 @@ module RuboCop
94
102
  str_b = "#{var_b}.#{method}"
95
103
  end
96
104
  format(MSG, compare_method: compare_method,
105
+ replacement_method: replacement_method,
97
106
  instead: instead,
98
107
  var_a: var_a,
99
108
  var_b: var_b,
@@ -38,6 +38,10 @@ module RuboCop
38
38
 
39
39
  MSG = 'Extract this regexp into a constant, memoize it, or append an `/o` option to its options.'
40
40
 
41
+ def self.autocorrect_incompatible_with
42
+ [RegexpMatch]
43
+ end
44
+
41
45
  def on_regexp(node)
42
46
  return if within_allowed_assignment?(node) || !include_interpolated_const?(node) || node.single_interpolation?
43
47
 
@@ -110,7 +110,7 @@ module RuboCop
110
110
 
111
111
  def negate_block_pass_reject(corrector, node)
112
112
  corrector.replace(
113
- node.receiver.loc.expression.with(begin_pos: node.receiver.loc.begin.begin_pos),
113
+ node.receiver.source_range.with(begin_pos: node.receiver.loc.begin.begin_pos),
114
114
  negate_block_pass_as_inline_block(node.receiver)
115
115
  )
116
116
  end
@@ -8,12 +8,9 @@ module RuboCop
8
8
  # `detect` instead.
9
9
  #
10
10
  # @safety
11
- # This cop is unsafe because is assumes the class implements the
12
- # `Enumerable` interface, but can't reliably detect this. This creates
13
- # known compatibility issues with `Hash`, `ActiveRecord` and other
14
- # frameworks. `Hash` and `ActiveRecord` do not implement a `detect`
15
- # method and `find` has its own meaning. Correcting `Hash` and
16
- # `ActiveRecord` methods with this cop should be considered unsafe.
11
+ # This cop is unsafe because it assumes that the receiver is an
12
+ # `Array` or equivalent, but can't reliably detect it. For example,
13
+ # if the receiver is a `Hash`, it may report a false positive.
17
14
  #
18
15
  # @example
19
16
  # # bad
@@ -58,8 +58,8 @@ module RuboCop
58
58
  private
59
59
 
60
60
  def autocorrect(corrector, first_call_args, second_call_args, combined_args)
61
- first_argument = first_call_args.first.loc.expression
62
- last_argument = second_call_args.last.loc.expression
61
+ first_argument = first_call_args.first.source_range
62
+ last_argument = second_call_args.last.source_range
63
63
  range = first_argument.join(last_argument)
64
64
 
65
65
  corrector.replace(range, combined_args)
@@ -69,7 +69,7 @@ module RuboCop
69
69
 
70
70
  new_source = "#{receiver.source}.end_with?(#{to_string_literal(regex_str)})"
71
71
 
72
- corrector.replace(node.source_range, new_source)
72
+ corrector.replace(node, new_source)
73
73
  end
74
74
  end
75
75
  alias on_match_with_lvasgn on_send
@@ -28,7 +28,7 @@ module RuboCop
28
28
  def_node_matcher :flat_map_candidate?, <<~PATTERN
29
29
  (send
30
30
  {
31
- (block $(send _ ${:collect :map}) ...)
31
+ $(block (send _ ${:collect :map}) ...)
32
32
  $(send _ ${:collect :map} (block_pass _))
33
33
  }
34
34
  ${:flatten :flatten!}
@@ -60,7 +60,8 @@ module RuboCop
60
60
  end
61
61
 
62
62
  def register_offense(node, map_node, first_method, flatten, message)
63
- range = range_between(map_node.loc.selector.begin_pos, node.loc.expression.end_pos)
63
+ map_send_node = map_node.block_type? ? map_node.send_node : map_node
64
+ range = range_between(map_send_node.loc.selector.begin_pos, node.source_range.end_pos)
64
65
  message = format(message, method: first_method, flatten: flatten)
65
66
 
66
67
  add_offense(range, message: message) do |corrector|
@@ -74,10 +75,11 @@ module RuboCop
74
75
 
75
76
  return unless flatten_level
76
77
 
77
- range = range_between(node.loc.dot.begin_pos, node.source_range.end_pos)
78
+ map_send_node = map_node.block_type? ? map_node.send_node : map_node
79
+ range = range_between(map_node.source_range.end_pos, node.source_range.end_pos)
78
80
 
79
81
  corrector.remove(range)
80
- corrector.replace(map_node.loc.selector, 'flat_map')
82
+ corrector.replace(map_send_node.loc.selector, 'flat_map')
81
83
  end
82
84
  end
83
85
  end
@@ -57,7 +57,7 @@ module RuboCop
57
57
  # Replace `keys.include?` or `values.include?` with the appropriate
58
58
  # `key?`/`value?` method.
59
59
  corrector.replace(
60
- node.loc.expression,
60
+ node,
61
61
  "#{autocorrect_hash_expression(node)}.#{autocorrect_method(node)}(#{autocorrect_argument(node)})"
62
62
  )
63
63
  end
@@ -95,7 +95,7 @@ module RuboCop
95
95
  begin_pos = readlines_call.loc.selector.begin_pos
96
96
 
97
97
  end_pos = if enumerable_call.method?(:each)
98
- enumerable_call.loc.expression.end_pos
98
+ enumerable_call.source_range.end_pos
99
99
  else
100
100
  enumerable_call.loc.dot.begin_pos
101
101
  end
@@ -75,7 +75,7 @@ module RuboCop
75
75
 
76
76
  new_source << CLOSE_PAREN if parentheses?(node) && !args.empty?
77
77
 
78
- corrector.replace(node.source_range, new_source)
78
+ corrector.replace(node, new_source)
79
79
  end
80
80
 
81
81
  def calls_to_report(argname, body)
@@ -10,6 +10,16 @@ module RuboCop
10
10
  # behavior is appropriately overridden in subclass. For example,
11
11
  # `Range#===` returns `true` when argument is within the range.
12
12
  #
13
+ # This cop has `AllowRegexpMatch` option and it is true by default because
14
+ # `regexp.match?('string')` often used in block changes to the opposite result:
15
+ #
16
+ # [source,ruby]
17
+ # ----
18
+ # [/pattern/].all? { |regexp| regexp.match?('pattern') } # => true
19
+ # [/pattern/].all? { |regexp| regexp =~ 'pattern' } # => true
20
+ # [/pattern/].all?('pattern') # => false
21
+ # ----
22
+ #
13
23
  # @safety
14
24
  # This cop is unsafe because `===` and `==` do not always behave the same.
15
25
  #
@@ -22,6 +32,19 @@ module RuboCop
22
32
  #
23
33
  # # good
24
34
  # items.all?(pattern)
35
+ # items.all?(Klass)
36
+ #
37
+ # @example AllowRegexpMatch: true (default)
38
+ #
39
+ # # good
40
+ # items.all? { |item| item =~ pattern }
41
+ # items.all? { |item| item.match?(pattern) }
42
+ #
43
+ # @example AllowRegexpMatch: false
44
+ #
45
+ # # bad
46
+ # items.all? { |item| item =~ pattern }
47
+ # items.all? { |item| item.match?(pattern) }
25
48
  #
26
49
  class RedundantEqualityComparisonBlock < Base
27
50
  extend AutoCorrector
@@ -33,6 +56,7 @@ module RuboCop
33
56
 
34
57
  TARGET_METHODS = %i[all? any? one? none?].freeze
35
58
  COMPARISON_METHODS = %i[== === is_a? kind_of?].freeze
59
+ REGEXP_METHODS = %i[=~ match?].freeze
36
60
  IS_A_METHODS = %i[is_a? kind_of?].freeze
37
61
 
38
62
  def on_block(node)
@@ -60,7 +84,11 @@ module RuboCop
60
84
  end
61
85
 
62
86
  def use_equality_comparison_block?(block_body)
63
- block_body.send_type? && COMPARISON_METHODS.include?(block_body.method_name)
87
+ return false unless block_body.send_type?
88
+
89
+ method_name = block_body.method_name
90
+
91
+ COMPARISON_METHODS.include?(method_name) || (!allow_regexp_match? && REGEXP_METHODS.include?(method_name))
64
92
  end
65
93
 
66
94
  def same_block_argument_and_is_a_argument?(block_body, block_argument)
@@ -69,7 +97,7 @@ module RuboCop
69
97
  elsif IS_A_METHODS.include?(block_body.method_name)
70
98
  block_argument.source == block_body.first_argument.source
71
99
  else
72
- false
100
+ block_body.receiver.source == block_body.first_argument.receiver&.source
73
101
  end
74
102
  end
75
103
 
@@ -99,6 +127,10 @@ module RuboCop
99
127
  def offense_range(node)
100
128
  node.send_node.loc.selector.join(node.source_range.end)
101
129
  end
130
+
131
+ def allow_regexp_match?
132
+ cop_config.fetch('AllowRegexpMatch', true)
133
+ end
102
134
  end
103
135
  end
104
136
  end
@@ -49,7 +49,7 @@ module RuboCop
49
49
  def autocorrect(corrector, node)
50
50
  new_source = "#{node.receiver.source} =~ #{node.first_argument.source}"
51
51
 
52
- corrector.replace(node.source_range, new_source)
52
+ corrector.replace(node, new_source)
53
53
  end
54
54
 
55
55
  def autocorrectable?(node)
@@ -112,11 +112,11 @@ module RuboCop
112
112
  new_source.gsub!(/\n/, padding)
113
113
  end
114
114
 
115
- corrector.replace(node.source_range, new_source)
115
+ corrector.replace(node, new_source)
116
116
  end
117
117
 
118
118
  def correct_single_element(corrector, node, new_source)
119
- corrector.replace(node.source_range, new_source)
119
+ corrector.replace(node, new_source)
120
120
  end
121
121
 
122
122
  def to_assignments(receiver, pairs)
@@ -69,11 +69,11 @@ module RuboCop
69
69
  private
70
70
 
71
71
  def offense_range(receiver, node)
72
- range_between(receiver.loc.selector.begin_pos, node.loc.expression.end_pos)
72
+ range_between(receiver.loc.selector.begin_pos, node.source_range.end_pos)
73
73
  end
74
74
 
75
75
  def correction_range(receiver, node)
76
- range_between(receiver.loc.dot.begin_pos, node.loc.expression.end_pos)
76
+ range_between(receiver.loc.dot.begin_pos, node.source_range.end_pos)
77
77
  end
78
78
 
79
79
  def build_message(method, args)
@@ -131,6 +131,10 @@ module RuboCop
131
131
  }
132
132
  PATTERN
133
133
 
134
+ def self.autocorrect_incompatible_with
135
+ [ConstantRegexp]
136
+ end
137
+
134
138
  def on_if(node)
135
139
  check_condition(node.condition)
136
140
  end
@@ -185,9 +189,9 @@ module RuboCop
185
189
 
186
190
  def range_to_search_for_last_matches(match_node, body, scope_root)
187
191
  expression = if modifier_form?(match_node)
188
- match_node.parent.if_branch.loc.expression
192
+ match_node.parent.if_branch.source_range
189
193
  else
190
- match_node.loc.expression
194
+ match_node.source_range
191
195
  end
192
196
 
193
197
  match_node_pos = expression.begin_pos
@@ -199,15 +203,15 @@ module RuboCop
199
203
  def next_match_pos(body, match_node_pos, scope_root)
200
204
  node = search_match_nodes(body).find do |match|
201
205
  begin_pos = if modifier_form?(match)
202
- match.parent.if_branch.loc.expression.begin_pos
206
+ match.parent.if_branch.source_range.begin_pos
203
207
  else
204
- match.loc.expression.begin_pos
208
+ match.source_range.begin_pos
205
209
  end
206
210
 
207
211
  begin_pos > match_node_pos && scope_root(match) == scope_root
208
212
  end
209
213
 
210
- node ? node.loc.expression.begin_pos : Float::INFINITY
214
+ node ? node.source_range.begin_pos : Float::INFINITY
211
215
  end
212
216
 
213
217
  def modifier_form?(match_node)
@@ -216,7 +220,7 @@ module RuboCop
216
220
 
217
221
  def find_last_match(body, range, scope_root)
218
222
  last_matches(body).find do |ref|
219
- ref_pos = ref.loc.expression.begin_pos
223
+ ref_pos = ref.source_range.begin_pos
220
224
  range.cover?(ref_pos) && scope_root(ref) == scope_root
221
225
  end
222
226
  end
@@ -248,8 +252,8 @@ module RuboCop
248
252
 
249
253
  replace_with_match_predicate_method(corrector, recv, arg, op_range)
250
254
 
251
- corrector.insert_after(arg.loc.expression, ')') unless op_range.source.end_with?('(')
252
- corrector.insert_before(recv.loc.expression, '!') if oper == :!~
255
+ corrector.insert_after(arg, ')') unless op_range.source.end_with?('(')
256
+ corrector.insert_before(recv, '!') if oper == :!~
253
257
  end
254
258
 
255
259
  def replace_with_match_predicate_method(corrector, recv, arg, op_range)
@@ -264,14 +268,14 @@ module RuboCop
264
268
  end
265
269
 
266
270
  def swap_receiver_and_arg(corrector, recv, arg)
267
- corrector.replace(recv.loc.expression, arg.source)
268
- corrector.replace(arg.loc.expression, recv.source)
271
+ corrector.replace(recv, arg.source)
272
+ corrector.replace(arg, recv.source)
269
273
  end
270
274
 
271
275
  def correction_range(recv, arg)
272
276
  buffer = processed_source.buffer
273
- op_begin_pos = recv.loc.expression.end_pos
274
- op_end_pos = arg.loc.expression.begin_pos
277
+ op_begin_pos = recv.source_range.end_pos
278
+ op_end_pos = arg.source_range.begin_pos
275
279
  Parser::Source::Range.new(buffer, op_begin_pos, op_end_pos)
276
280
  end
277
281
  end
@@ -43,7 +43,7 @@ module RuboCop
43
43
  private
44
44
 
45
45
  def correction_range(receiver, node)
46
- range_between(receiver.loc.selector.begin_pos, node.loc.expression.end_pos)
46
+ range_between(receiver.loc.selector.begin_pos, node.source_range.end_pos)
47
47
  end
48
48
 
49
49
  def build_message(node)
@@ -52,7 +52,7 @@ module RuboCop
52
52
  end
53
53
 
54
54
  def offense_range(node, map_method)
55
- range_between(node.loc.selector.begin_pos, map_method.loc.expression.end_pos)
55
+ range_between(node.loc.selector.begin_pos, map_method.source_range.end_pos)
56
56
  end
57
57
  end
58
58
  end
@@ -48,7 +48,7 @@ module RuboCop
48
48
  string_literal = to_string_literal(replace_str)
49
49
  new_code = "#{receiver.source}.#{good_method}(#{string_literal})"
50
50
 
51
- corrector.replace(node.source_range, new_code)
51
+ corrector.replace(node, new_code)
52
52
  end
53
53
  end
54
54
  end
@@ -69,7 +69,7 @@ module RuboCop
69
69
 
70
70
  new_source = "#{receiver.source}.start_with?(#{to_string_literal(regex_str)})"
71
71
 
72
- corrector.replace(node.source_range, new_source)
72
+ corrector.replace(node, new_source)
73
73
  end
74
74
  end
75
75
  alias on_match_with_lvasgn on_send
@@ -27,28 +27,33 @@ module RuboCop
27
27
 
28
28
  MSG = 'Use `%<symbol_arg>s` instead of `%<string_arg>s`.'
29
29
 
30
+ COMMAND_METHODS = %i[
31
+ alias_method attr_accessor attr_reader attr_writer autoload autoload? private private_constant
32
+ protected public public_constant module_function
33
+ ].freeze
34
+
30
35
  # NOTE: `attr` method is not included in this list as it can cause false positives in Nokogiri API.
31
36
  # And `attr` may not be used because `Style/Attr` registers an offense.
32
37
  # https://github.com/rubocop/rubocop-performance/issues/278
33
- RESTRICT_ON_SEND = %i[
34
- alias_method attr_accessor attr_reader attr_writer autoload autoload?
38
+ RESTRICT_ON_SEND = (%i[
35
39
  class_variable_defined? const_defined? const_get const_set const_source_location
36
40
  define_method instance_method method_defined? private_class_method? private_method_defined?
37
41
  protected_method_defined? public_class_method public_instance_method public_method_defined?
38
42
  remove_class_variable remove_method undef_method class_variable_get class_variable_set
39
- deprecate_constant module_function private private_constant protected public public_constant
40
- remove_const ruby2_keywords
41
- define_singleton_method instance_variable_defined? instance_variable_get instance_variable_set
42
- method public_method public_send remove_instance_variable respond_to? send singleton_method
43
- __send__
44
- ].freeze
43
+ deprecate_constant remove_const ruby2_keywords define_singleton_method instance_variable_defined?
44
+ instance_variable_get instance_variable_set method public_method public_send remove_instance_variable
45
+ respond_to? send singleton_method __send__
46
+ ] + COMMAND_METHODS).freeze
45
47
 
46
48
  def on_send(node)
49
+ return if COMMAND_METHODS.include?(node.method_name) && node.receiver
47
50
  return unless (first_argument = node.first_argument)
48
51
  return unless first_argument.str_type?
49
- return if first_argument.value.include?(' ') || first_argument.value.include?('::')
50
52
 
51
- replacement = first_argument.value.to_sym.inspect
53
+ first_argument_value = first_argument.value
54
+ return if first_argument_value.include?(' ') || first_argument_value.include?('::')
55
+
56
+ replacement = first_argument_value.to_sym.inspect
52
57
 
53
58
  message = format(MSG, symbol_arg: replacement, string_arg: first_argument.source)
54
59
 
@@ -43,7 +43,7 @@ module RuboCop
43
43
 
44
44
  new_source = "#{'!' if negation}#{receiver.source}.include?(#{to_string_literal(regex_str)})"
45
45
 
46
- corrector.replace(node.source_range, new_source)
46
+ corrector.replace(node, new_source)
47
47
  end
48
48
  end
49
49
  alias on_match_with_lvasgn on_send
@@ -70,7 +70,7 @@ module RuboCop
70
70
  replacement_method = replacement_method(node, first_source, second_source)
71
71
 
72
72
  corrector.replace(node.loc.selector, replacement_method)
73
- corrector.replace(first_param.source_range, to_string_literal(first_source)) unless first_param.str_type?
73
+ corrector.replace(first_param, to_string_literal(first_source)) unless first_param.str_type?
74
74
 
75
75
  remove_second_param(corrector, node, first_param) if second_source.empty? && first_source.length == 1
76
76
  end
@@ -183,7 +183,7 @@ module RuboCop
183
183
  end
184
184
 
185
185
  def sum_method_range(node)
186
- range_between(node.loc.selector.begin_pos, node.loc.expression.end_pos)
186
+ range_between(node.loc.selector.begin_pos, node.source_range.end_pos)
187
187
  end
188
188
 
189
189
  def sum_map_range(map, sum)
@@ -52,7 +52,7 @@ module RuboCop
52
52
  add_offense(node, message: message(map_or_collect, count)) do |corrector|
53
53
  replacement = "Array.new(#{count.source}#{map_or_collect.arguments.map { |arg| ", #{arg.source}" }.join})"
54
54
 
55
- corrector.replace(map_or_collect.loc.expression, replacement)
55
+ corrector.replace(map_or_collect, replacement)
56
56
  end
57
57
  end
58
58
  end
@@ -30,7 +30,7 @@ module RuboCop
30
30
  message = format(MSG, double_colon: double_colon)
31
31
 
32
32
  add_offense(node, message: message) do |corrector|
33
- corrector.replace(node.loc.expression, "#{double_colon}URI::DEFAULT_PARSER")
33
+ corrector.replace(node, "#{double_colon}URI::DEFAULT_PARSER")
34
34
  end
35
35
  end
36
36
  end
@@ -4,7 +4,7 @@ module RuboCop
4
4
  module Performance
5
5
  # This module holds the RuboCop Performance version information.
6
6
  module Version
7
- STRING = '1.16.0'
7
+ STRING = '1.18.0'
8
8
 
9
9
  def self.document_version
10
10
  STRING.match('\d+\.\d+').to_s
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubocop-performance
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.16.0
4
+ version: 1.18.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bozhidar Batsov
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2023-02-06 00:00:00.000000000 Z
13
+ date: 2023-05-21 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rubocop
@@ -123,7 +123,7 @@ metadata:
123
123
  homepage_uri: https://docs.rubocop.org/rubocop-performance/
124
124
  changelog_uri: https://github.com/rubocop/rubocop-performance/blob/master/CHANGELOG.md
125
125
  source_code_uri: https://github.com/rubocop/rubocop-performance/
126
- documentation_uri: https://docs.rubocop.org/rubocop-performance/1.16/
126
+ documentation_uri: https://docs.rubocop.org/rubocop-performance/1.18/
127
127
  bug_tracker_uri: https://github.com/rubocop/rubocop-performance/issues
128
128
  rubygems_mfa_required: 'true'
129
129
  post_install_message:
@@ -134,14 +134,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
134
134
  requirements:
135
135
  - - ">="
136
136
  - !ruby/object:Gem::Version
137
- version: 2.6.0
137
+ version: 2.7.0
138
138
  required_rubygems_version: !ruby/object:Gem::Requirement
139
139
  requirements:
140
140
  - - ">="
141
141
  - !ruby/object:Gem::Version
142
142
  version: '0'
143
143
  requirements: []
144
- rubygems_version: 3.3.26
144
+ rubygems_version: 3.5.0.dev
145
145
  signing_key:
146
146
  specification_version: 4
147
147
  summary: Automatic performance checking tool for Ruby code.