rubocop-performance 1.16.0 → 1.18.0

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