rubocop-performance 1.16.0 → 1.19.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -2
  3. data/config/default.yml +7 -0
  4. data/lib/rubocop/cop/performance/array_semi_infinite_range_slice.rb +2 -1
  5. data/lib/rubocop/cop/performance/case_when_splat.rb +2 -2
  6. data/lib/rubocop/cop/performance/compare_with_block.rb +19 -10
  7. data/lib/rubocop/cop/performance/constant_regexp.rb +4 -0
  8. data/lib/rubocop/cop/performance/count.rb +1 -1
  9. data/lib/rubocop/cop/performance/delete_prefix.rb +5 -2
  10. data/lib/rubocop/cop/performance/delete_suffix.rb +5 -2
  11. data/lib/rubocop/cop/performance/detect.rb +6 -8
  12. data/lib/rubocop/cop/performance/double_start_end_with.rb +2 -2
  13. data/lib/rubocop/cop/performance/end_with.rb +5 -3
  14. data/lib/rubocop/cop/performance/fixed_size.rb +2 -2
  15. data/lib/rubocop/cop/performance/flat_map.rb +6 -4
  16. data/lib/rubocop/cop/performance/inefficient_hash_search.rb +15 -9
  17. data/lib/rubocop/cop/performance/io_readlines.rb +1 -1
  18. data/lib/rubocop/cop/performance/map_compact.rb +3 -2
  19. data/lib/rubocop/cop/performance/map_method_chain.rb +87 -0
  20. data/lib/rubocop/cop/performance/redundant_block_call.rb +1 -1
  21. data/lib/rubocop/cop/performance/redundant_equality_comparison_block.rb +34 -2
  22. data/lib/rubocop/cop/performance/redundant_match.rb +1 -1
  23. data/lib/rubocop/cop/performance/redundant_merge.rb +4 -4
  24. data/lib/rubocop/cop/performance/redundant_split_regexp_argument.rb +2 -1
  25. data/lib/rubocop/cop/performance/redundant_string_chars.rb +2 -2
  26. data/lib/rubocop/cop/performance/regexp_match.rb +16 -12
  27. data/lib/rubocop/cop/performance/reverse_each.rb +2 -1
  28. data/lib/rubocop/cop/performance/reverse_first.rb +3 -2
  29. data/lib/rubocop/cop/performance/select_map.rb +2 -1
  30. data/lib/rubocop/cop/performance/squeeze.rb +6 -3
  31. data/lib/rubocop/cop/performance/start_with.rb +5 -3
  32. data/lib/rubocop/cop/performance/string_identifier_argument.rb +15 -10
  33. data/lib/rubocop/cop/performance/string_include.rb +7 -3
  34. data/lib/rubocop/cop/performance/string_replacement.rb +3 -2
  35. data/lib/rubocop/cop/performance/sum.rb +1 -1
  36. data/lib/rubocop/cop/performance/times_map.rb +1 -1
  37. data/lib/rubocop/cop/performance/uri_default_parser.rb +2 -2
  38. data/lib/rubocop/cop/performance_cops.rb +1 -0
  39. data/lib/rubocop/performance/version.rb +1 -1
  40. metadata +6 -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: 06f3e8346dc7f9be72a1f18c62a25dc02aeac41debcfe3c58df68e2a6904df43
4
+ data.tar.gz: f01facdb92a3056d05990e2ed2b6b1920de0501edf53a08e95e08620651c8557
5
5
  SHA512:
6
- metadata.gz: 9f08bd2f25c0e0e537bf8fa5378e701d6b6b6794a45fe534229e73a0dd4bd623dd415965966655a802cc8e93a3776880d99c89245947aae090ba2c49f0bb183f
7
- data.tar.gz: 34f697ee70070d32d17b3684712cec5628e71cbdb393722fec3bb0dbc541cf65af92a762907dbbb0c5e6c3023f8dd4738e06a131a5a28014749dac440e15bc92
6
+ metadata.gz: 07eb541698b6ccf2985ef62392bd78703bf6607e2877ef3865ab1762d62910c4c346fbb7e9bc48af7b7d98b0e1ad22e8c79ea2425555fbe75c2a5e614837eaa7
7
+ data.tar.gz: 60fc9f900906cca518d0da62170f71ae6e5f5ffd44f4c1cbe75af83f9a1fef252b6bab95d3af4f49f328d4a856cd17c7f47621ee62575ab282eacfd26dc09841
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
@@ -193,6 +193,12 @@ Performance/MapCompact:
193
193
  SafeAutoCorrect: false
194
194
  VersionAdded: '1.11'
195
195
 
196
+ Performance/MapMethodChain:
197
+ Description: 'Checks if the `map` method is used in a chain.'
198
+ Enabled: pending
199
+ Safe: false
200
+ VersionAdded: '1.19'
201
+
196
202
  Performance/MethodObjectAsBlock:
197
203
  Description: 'Use block explicitly instead of block-passing a method object.'
198
204
  Reference: 'https://github.com/JuanitoFatas/fast-ruby#normal-way-to-apply-method-vs-method-code'
@@ -226,6 +232,7 @@ Performance/RedundantEqualityComparisonBlock:
226
232
  Reference: 'https://github.com/rails/rails/pull/41363'
227
233
  Enabled: pending
228
234
  Safe: false
235
+ AllowRegexpMatch: true
229
236
  VersionAdded: '1.10'
230
237
 
231
238
  Performance/RedundantMatch:
@@ -39,7 +39,7 @@ module RuboCop
39
39
  RESTRICT_ON_SEND = SLICE_METHODS
40
40
 
41
41
  def_node_matcher :endless_range_slice?, <<~PATTERN
42
- (send $_ $%SLICE_METHODS $#endless_range?)
42
+ (call $_ $%SLICE_METHODS $#endless_range?)
43
43
  PATTERN
44
44
 
45
45
  def_node_matcher :endless_range?, <<~PATTERN
@@ -59,6 +59,7 @@ module RuboCop
59
59
  end
60
60
  end
61
61
  end
62
+ alias on_csend on_send
62
63
 
63
64
  private
64
65
 
@@ -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
@@ -64,9 +64,10 @@ module RuboCop
64
64
  }.freeze
65
65
 
66
66
  def_node_matcher :delete_prefix_candidate?, <<~PATTERN
67
- (send $!nil? ${:gsub :gsub! :sub :sub!} (regexp (str $#literal_at_start?) (regopt)) (str $_))
67
+ (call $!nil? ${:gsub :gsub! :sub :sub!} (regexp (str $#literal_at_start?) (regopt)) (str $_))
68
68
  PATTERN
69
69
 
70
+ # rubocop:disable Metrics/AbcSize
70
71
  def on_send(node)
71
72
  return unless (receiver, bad_method, regexp_str, replace_string = delete_prefix_candidate?(node))
72
73
  return unless replace_string.empty?
@@ -80,11 +81,13 @@ module RuboCop
80
81
  regexp_str = interpret_string_escapes(regexp_str)
81
82
  string_literal = to_string_literal(regexp_str)
82
83
 
83
- new_code = "#{receiver.source}.#{good_method}(#{string_literal})"
84
+ new_code = "#{receiver.source}#{node.loc.dot.source}#{good_method}(#{string_literal})"
84
85
 
85
86
  corrector.replace(node, new_code)
86
87
  end
87
88
  end
89
+ # rubocop:enable Metrics/AbcSize
90
+ alias on_csend on_send
88
91
  end
89
92
  end
90
93
  end
@@ -64,9 +64,10 @@ module RuboCop
64
64
  }.freeze
65
65
 
66
66
  def_node_matcher :delete_suffix_candidate?, <<~PATTERN
67
- (send $!nil? ${:gsub :gsub! :sub :sub!} (regexp (str $#literal_at_end?) (regopt)) (str $_))
67
+ (call $!nil? ${:gsub :gsub! :sub :sub!} (regexp (str $#literal_at_end?) (regopt)) (str $_))
68
68
  PATTERN
69
69
 
70
+ # rubocop:disable Metrics/AbcSize
70
71
  def on_send(node)
71
72
  return unless (receiver, bad_method, regexp_str, replace_string = delete_suffix_candidate?(node))
72
73
  return unless replace_string.empty?
@@ -80,11 +81,13 @@ module RuboCop
80
81
  regexp_str = interpret_string_escapes(regexp_str)
81
82
  string_literal = to_string_literal(regexp_str)
82
83
 
83
- new_code = "#{receiver.source}.#{good_method}(#{string_literal})"
84
+ new_code = "#{receiver.source}#{node.loc.dot.source}#{good_method}(#{string_literal})"
84
85
 
85
86
  corrector.replace(node, new_code)
86
87
  end
87
88
  end
89
+ # rubocop:enable Metrics/AbcSize
90
+ alias on_csend on_send
88
91
  end
89
92
  end
90
93
  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
@@ -43,9 +40,9 @@ module RuboCop
43
40
 
44
41
  def_node_matcher :detect_candidate?, <<~PATTERN
45
42
  {
46
- (send $(block (send _ %CANDIDATE_METHODS) ...) ${:first :last} $...)
43
+ (send $(block (call _ %CANDIDATE_METHODS) ...) ${:first :last} $...)
47
44
  (send $(block (send _ %CANDIDATE_METHODS) ...) $:[] (int ${0 -1}))
48
- (send $(send _ %CANDIDATE_METHODS ...) ${:first :last} $...)
45
+ (send $(call _ %CANDIDATE_METHODS ...) ${:first :last} $...)
49
46
  (send $(send _ %CANDIDATE_METHODS ...) $:[] (int ${0 -1}))
50
47
  }
51
48
  PATTERN
@@ -66,6 +63,7 @@ module RuboCop
66
63
  register_offense(node, receiver, second_method, index)
67
64
  end
68
65
  end
66
+ alias on_csend on_send
69
67
 
70
68
  private
71
69
 
@@ -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)
@@ -54,7 +54,7 @@ module RuboCop
54
54
  RESTRICT_ON_SEND = %i[match =~ match?].freeze
55
55
 
56
56
  def_node_matcher :redundant_regex?, <<~PATTERN
57
- {(send $!nil? {:match :=~ :match?} (regexp (str $#literal_at_end?) (regopt)))
57
+ {(call $!nil? {:match :=~ :match?} (regexp (str $#literal_at_end?) (regopt)))
58
58
  (send (regexp (str $#literal_at_end?) (regopt)) {:match :match?} $_)
59
59
  (match-with-lvasgn (regexp (str $#literal_at_end?) (regopt)) $_)}
60
60
  PATTERN
@@ -66,12 +66,14 @@ module RuboCop
66
66
  receiver, regex_str = regex_str, receiver if receiver.is_a?(String)
67
67
  regex_str = drop_end_metacharacter(regex_str)
68
68
  regex_str = interpret_string_escapes(regex_str)
69
+ dot = node.loc.dot ? node.loc.dot.source : '.'
69
70
 
70
- new_source = "#{receiver.source}.end_with?(#{to_string_literal(regex_str)})"
71
+ new_source = "#{receiver.source}#{dot}end_with?(#{to_string_literal(regex_str)})"
71
72
 
72
- corrector.replace(node.source_range, new_source)
73
+ corrector.replace(node, new_source)
73
74
  end
74
75
  end
76
+ alias on_csend on_send
75
77
  alias on_match_with_lvasgn on_send
76
78
  end
77
79
  end
@@ -78,13 +78,13 @@ module RuboCop
78
78
  end
79
79
 
80
80
  def contains_splat?(node)
81
- return unless node.array_type?
81
+ return false unless node.array_type?
82
82
 
83
83
  node.each_child_node(:splat).any?
84
84
  end
85
85
 
86
86
  def contains_double_splat?(node)
87
- return unless node.hash_type?
87
+ return false unless node.hash_type?
88
88
 
89
89
  node.each_child_node(:kwsplat).any?
90
90
  end
@@ -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
@@ -45,7 +45,7 @@ module RuboCop
45
45
  RESTRICT_ON_SEND = %i[include?].freeze
46
46
 
47
47
  def_node_matcher :inefficient_include?, <<~PATTERN
48
- (send (send $_ {:keys :values}) :include? _)
48
+ (send (call $_ {:keys :values}) :include? _)
49
49
  PATTERN
50
50
 
51
51
  def on_send(node)
@@ -56,21 +56,23 @@ module RuboCop
56
56
  add_offense(node, message: message) do |corrector|
57
57
  # Replace `keys.include?` or `values.include?` with the appropriate
58
58
  # `key?`/`value?` method.
59
- corrector.replace(
60
- node.loc.expression,
61
- "#{autocorrect_hash_expression(node)}.#{autocorrect_method(node)}(#{autocorrect_argument(node)})"
62
- )
59
+ corrector.replace(node, replacement(node))
63
60
  end
64
61
  end
65
62
  end
63
+ alias on_csend on_send
66
64
 
67
65
  private
68
66
 
69
67
  def message(node)
70
- "Use `##{autocorrect_method(node)}` instead of `##{current_method(node)}.include?`."
68
+ "Use `##{correct_method(node)}` instead of `##{current_method(node)}.include?`."
71
69
  end
72
70
 
73
- def autocorrect_method(node)
71
+ def replacement(node)
72
+ "#{correct_hash_expression(node)}#{correct_dot(node)}#{correct_method(node)}(#{correct_argument(node)})"
73
+ end
74
+
75
+ def correct_method(node)
74
76
  case current_method(node)
75
77
  when :keys then use_long_method ? 'has_key?' : 'key?'
76
78
  when :values then use_long_method ? 'has_value?' : 'value?'
@@ -86,13 +88,17 @@ module RuboCop
86
88
  preferred_config && preferred_config['EnforcedStyle'] == 'long' && preferred_config['Enabled']
87
89
  end
88
90
 
89
- def autocorrect_argument(node)
91
+ def correct_argument(node)
90
92
  node.arguments.first.source
91
93
  end
92
94
 
93
- def autocorrect_hash_expression(node)
95
+ def correct_hash_expression(node)
94
96
  node.receiver.receiver.source
95
97
  end
98
+
99
+ def correct_dot(node)
100
+ node.receiver.loc.dot.source
101
+ end
96
102
  end
97
103
  end
98
104
  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
@@ -40,12 +40,12 @@ module RuboCop
40
40
  def_node_matcher :map_compact, <<~PATTERN
41
41
  {
42
42
  (send
43
- $(send _ {:map :collect}
43
+ $(call _ {:map :collect}
44
44
  (block_pass
45
45
  (sym _))) _)
46
46
  (send
47
47
  (block
48
- $(send _ {:map :collect})
48
+ $(call _ {:map :collect})
49
49
  (args ...) _) _)
50
50
  }
51
51
  PATTERN
@@ -61,6 +61,7 @@ module RuboCop
61
61
  remove_compact_method(corrector, map_node, node, node.parent)
62
62
  end
63
63
  end
64
+ alias on_csend on_send
64
65
 
65
66
  private
66
67
 
@@ -0,0 +1,87 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Performance
6
+ # Checks if the map method is used in a chain.
7
+ #
8
+ # Autocorrection is not supported because an appropriate block variable name cannot be determined automatically.
9
+ #
10
+ # @safety
11
+ # This cop is unsafe because false positives occur if the number of times the first method is executed
12
+ # affects the return value of subsequent methods.
13
+ #
14
+ # [source,ruby]
15
+ # ----
16
+ # class X
17
+ # def initialize
18
+ # @@num = 0
19
+ # end
20
+ #
21
+ # def foo
22
+ # @@num += 1
23
+ # self
24
+ # end
25
+ #
26
+ # def bar
27
+ # @@num * 2
28
+ # end
29
+ # end
30
+ #
31
+ # [X.new, X.new].map(&:foo).map(&:bar) # => [4, 4]
32
+ # [X.new, X.new].map { |x| x.foo.bar } # => [2, 4]
33
+ # ----
34
+ #
35
+ # @example
36
+ #
37
+ # # bad
38
+ # array.map(&:foo).map(&:bar)
39
+ #
40
+ # # good
41
+ # array.map { |item| item.foo.bar }
42
+ #
43
+ class MapMethodChain < Base
44
+ include IgnoredNode
45
+
46
+ MSG = 'Use `%<method_name>s { |x| x.%<map_args>s }` instead of `%<method_name>s` method chain.'
47
+ RESTRICT_ON_SEND = %i[map collect].freeze
48
+
49
+ def_node_matcher :block_pass_with_symbol_arg?, <<~PATTERN
50
+ (:block_pass (:sym $_))
51
+ PATTERN
52
+
53
+ def on_send(node)
54
+ return if part_of_ignored_node?(node)
55
+ return unless (map_arg = block_pass_with_symbol_arg?(node.first_argument))
56
+
57
+ map_args = [map_arg]
58
+
59
+ return unless (begin_of_chained_map_method = find_begin_of_chained_map_method(node, map_args))
60
+
61
+ range = begin_of_chained_map_method.loc.selector.begin.join(node.source_range.end)
62
+ message = format(MSG, method_name: begin_of_chained_map_method.method_name, map_args: map_args.join('.'))
63
+
64
+ add_offense(range, message: message)
65
+
66
+ ignore_node(node)
67
+ end
68
+
69
+ private
70
+
71
+ def find_begin_of_chained_map_method(node, map_args)
72
+ return unless (chained_map_method = node.receiver)
73
+ return if !chained_map_method.call_type? || !RESTRICT_ON_SEND.include?(chained_map_method.method_name)
74
+ return unless (map_arg = block_pass_with_symbol_arg?(chained_map_method.first_argument))
75
+
76
+ map_args.unshift(map_arg)
77
+
78
+ receiver = chained_map_method.receiver
79
+
80
+ return chained_map_method unless receiver.call_type? && block_pass_with_symbol_arg?(receiver.first_argument)
81
+
82
+ find_begin_of_chained_map_method(chained_map_method, map_args)
83
+ end
84
+ end
85
+ end
86
+ end
87
+ 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)
@@ -109,14 +109,14 @@ module RuboCop
109
109
  node = parent
110
110
  else
111
111
  padding = "\n#{leading_spaces(node)}"
112
- new_source.gsub!(/\n/, padding)
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)
@@ -132,7 +132,7 @@ module RuboCop
132
132
  def rewrite_with_modifier(node, parent, new_source)
133
133
  indent = ' ' * configured_indentation_width
134
134
  padding = "\n#{indent + leading_spaces(node)}"
135
- new_source.gsub!(/\n/, padding)
135
+ new_source.gsub!("\n", padding)
136
136
 
137
137
  format(WITH_MODIFIER_CORRECTION, keyword: parent.loc.keyword.source,
138
138
  condition: parent.condition.source,
@@ -21,7 +21,7 @@ module RuboCop
21
21
  STR_SPECIAL_CHARS = %w[\n \" \' \\\\ \t \b \f \r].freeze
22
22
 
23
23
  def_node_matcher :split_call_with_regexp?, <<~PATTERN
24
- {(send !nil? :split $regexp)}
24
+ {(call !nil? :split $regexp)}
25
25
  PATTERN
26
26
 
27
27
  def on_send(node)
@@ -35,6 +35,7 @@ module RuboCop
35
35
  corrector.replace(regexp_node, "\"#{new_argument}\"")
36
36
  end
37
37
  end
38
+ alias on_csend on_send
38
39
 
39
40
  private
40
41
 
@@ -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
@@ -27,7 +27,7 @@ module RuboCop
27
27
  RESTRICT_ON_SEND = %i[each].freeze
28
28
 
29
29
  def_node_matcher :reverse_each?, <<~MATCHER
30
- (send (send _ :reverse) :each)
30
+ (send (call _ :reverse) :each)
31
31
  MATCHER
32
32
 
33
33
  def on_send(node)
@@ -41,6 +41,7 @@ module RuboCop
41
41
  end
42
42
  end
43
43
  end
44
+ alias on_csend on_send
44
45
 
45
46
  private
46
47
 
@@ -24,7 +24,7 @@ module RuboCop
24
24
  RESTRICT_ON_SEND = %i[first].freeze
25
25
 
26
26
  def_node_matcher :reverse_first_candidate?, <<~PATTERN
27
- (send $(send _ :reverse) :first (int _)?)
27
+ (send $(call _ :reverse) :first (int _)?)
28
28
  PATTERN
29
29
 
30
30
  def on_send(node)
@@ -39,11 +39,12 @@ module RuboCop
39
39
  end
40
40
  end
41
41
  end
42
+ alias on_csend on_send
42
43
 
43
44
  private
44
45
 
45
46
  def correction_range(receiver, node)
46
- range_between(receiver.loc.selector.begin_pos, node.loc.expression.end_pos)
47
+ range_between(receiver.loc.selector.begin_pos, node.source_range.end_pos)
47
48
  end
48
49
 
49
50
  def build_message(node)
@@ -38,6 +38,7 @@ module RuboCop
38
38
  range = offense_range(node, map_method)
39
39
  add_offense(range, message: format(MSG, method_name: node.method_name))
40
40
  end
41
+ alias on_csend on_send
41
42
 
42
43
  private
43
44
 
@@ -52,7 +53,7 @@ module RuboCop
52
53
  end
53
54
 
54
55
  def offense_range(node, map_method)
55
- range_between(node.loc.selector.begin_pos, map_method.loc.expression.end_pos)
56
+ range_between(node.loc.selector.begin_pos, map_method.source_range.end_pos)
56
57
  end
57
58
  end
58
59
  end
@@ -27,7 +27,7 @@ module RuboCop
27
27
  PREFERRED_METHODS = { gsub: :squeeze, gsub!: :squeeze! }.freeze
28
28
 
29
29
  def_node_matcher :squeeze_candidate?, <<~PATTERN
30
- (send
30
+ (call
31
31
  $!nil? ${:gsub :gsub!}
32
32
  (regexp
33
33
  (str $#repeating_literal?)
@@ -35,6 +35,7 @@ module RuboCop
35
35
  (str $_))
36
36
  PATTERN
37
37
 
38
+ # rubocop:disable Metrics/AbcSize
38
39
  def on_send(node)
39
40
  squeeze_candidate?(node) do |receiver, bad_method, regexp_str, replace_str|
40
41
  regexp_str = regexp_str[0..-2] # delete '+' from the end
@@ -46,12 +47,14 @@ module RuboCop
46
47
 
47
48
  add_offense(node.loc.selector, message: message) do |corrector|
48
49
  string_literal = to_string_literal(replace_str)
49
- new_code = "#{receiver.source}.#{good_method}(#{string_literal})"
50
+ new_code = "#{receiver.source}#{node.loc.dot.source}#{good_method}(#{string_literal})"
50
51
 
51
- corrector.replace(node.source_range, new_code)
52
+ corrector.replace(node, new_code)
52
53
  end
53
54
  end
54
55
  end
56
+ # rubocop:enable Metrics/AbcSize
57
+ alias on_csend on_send
55
58
 
56
59
  private
57
60
 
@@ -54,7 +54,7 @@ module RuboCop
54
54
  RESTRICT_ON_SEND = %i[match =~ match?].freeze
55
55
 
56
56
  def_node_matcher :redundant_regex?, <<~PATTERN
57
- {(send $!nil? {:match :=~ :match?} (regexp (str $#literal_at_start?) (regopt)))
57
+ {(call $!nil? {:match :=~ :match?} (regexp (str $#literal_at_start?) (regopt)))
58
58
  (send (regexp (str $#literal_at_start?) (regopt)) {:match :match?} $_)
59
59
  (match-with-lvasgn (regexp (str $#literal_at_start?) (regopt)) $_)}
60
60
  PATTERN
@@ -66,12 +66,14 @@ module RuboCop
66
66
  receiver, regex_str = regex_str, receiver if receiver.is_a?(String)
67
67
  regex_str = drop_start_metacharacter(regex_str)
68
68
  regex_str = interpret_string_escapes(regex_str)
69
+ dot = node.loc.dot ? node.loc.dot.source : '.'
69
70
 
70
- new_source = "#{receiver.source}.start_with?(#{to_string_literal(regex_str)})"
71
+ new_source = "#{receiver.source}#{dot}start_with?(#{to_string_literal(regex_str)})"
71
72
 
72
- corrector.replace(node.source_range, new_source)
73
+ corrector.replace(node, new_source)
73
74
  end
74
75
  end
76
+ alias on_csend on_send
75
77
  alias on_match_with_lvasgn on_send
76
78
  end
77
79
  end
@@ -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
 
@@ -26,11 +26,12 @@ module RuboCop
26
26
  RESTRICT_ON_SEND = %i[match =~ !~ match?].freeze
27
27
 
28
28
  def_node_matcher :redundant_regex?, <<~PATTERN
29
- {(send $!nil? {:match :=~ :!~ :match?} (regexp (str $#literal?) (regopt)))
29
+ {(call $!nil? {:match :=~ :!~ :match?} (regexp (str $#literal?) (regopt)))
30
30
  (send (regexp (str $#literal?) (regopt)) {:match :match?} $_)
31
31
  (match-with-lvasgn (regexp (str $#literal?) (regopt)) $_)}
32
32
  PATTERN
33
33
 
34
+ # rubocop:disable Metrics/AbcSize
34
35
  def on_send(node)
35
36
  return unless (receiver, regex_str = redundant_regex?(node))
36
37
 
@@ -40,12 +41,15 @@ module RuboCop
40
41
  add_offense(node, message: message) do |corrector|
41
42
  receiver, regex_str = regex_str, receiver if receiver.is_a?(String)
42
43
  regex_str = interpret_string_escapes(regex_str)
44
+ dot = node.loc.dot ? node.loc.dot.source : '.'
43
45
 
44
- new_source = "#{'!' if negation}#{receiver.source}.include?(#{to_string_literal(regex_str)})"
46
+ new_source = "#{'!' if negation}#{receiver.source}#{dot}include?(#{to_string_literal(regex_str)})"
45
47
 
46
- corrector.replace(node.source_range, new_source)
48
+ corrector.replace(node, new_source)
47
49
  end
48
50
  end
51
+ # rubocop:enable Metrics/AbcSize
52
+ alias on_csend on_send
49
53
  alias on_match_with_lvasgn on_send
50
54
 
51
55
  private
@@ -29,7 +29,7 @@ module RuboCop
29
29
  BANG = '!'
30
30
 
31
31
  def_node_matcher :string_replacement?, <<~PATTERN
32
- (send _ {:gsub :gsub!}
32
+ (call _ {:gsub :gsub!}
33
33
  ${regexp str (send (const nil? :Regexp) {:new :compile} _)}
34
34
  $str)
35
35
  PATTERN
@@ -42,6 +42,7 @@ module RuboCop
42
42
  offense(node, first_param, second_param)
43
43
  end
44
44
  end
45
+ alias on_csend on_send
45
46
 
46
47
  private
47
48
 
@@ -70,7 +71,7 @@ module RuboCop
70
71
  replacement_method = replacement_method(node, first_source, second_source)
71
72
 
72
73
  corrector.replace(node.loc.selector, replacement_method)
73
- corrector.replace(first_param.source_range, to_string_literal(first_source)) unless first_param.str_type?
74
+ corrector.replace(first_param, to_string_literal(first_source)) unless first_param.str_type?
74
75
 
75
76
  remove_second_param(corrector, node, first_param) if second_source.empty? && first_source.length == 1
76
77
  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
@@ -25,12 +25,12 @@ module RuboCop
25
25
  PATTERN
26
26
 
27
27
  def on_send(node)
28
- return unless uri_parser_new?(node) do |captured_value|
28
+ uri_parser_new?(node) do |captured_value|
29
29
  double_colon = captured_value ? '::' : ''
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
@@ -25,6 +25,7 @@ require_relative 'performance/fixed_size'
25
25
  require_relative 'performance/flat_map'
26
26
  require_relative 'performance/inefficient_hash_search'
27
27
  require_relative 'performance/map_compact'
28
+ require_relative 'performance/map_method_chain'
28
29
  require_relative 'performance/method_object_as_block'
29
30
  require_relative 'performance/open_struct'
30
31
  require_relative 'performance/range_include'
@@ -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.19.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.19.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-08-13 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rubocop
@@ -87,6 +87,7 @@ files:
87
87
  - lib/rubocop/cop/performance/inefficient_hash_search.rb
88
88
  - lib/rubocop/cop/performance/io_readlines.rb
89
89
  - lib/rubocop/cop/performance/map_compact.rb
90
+ - lib/rubocop/cop/performance/map_method_chain.rb
90
91
  - lib/rubocop/cop/performance/method_object_as_block.rb
91
92
  - lib/rubocop/cop/performance/open_struct.rb
92
93
  - lib/rubocop/cop/performance/range_include.rb
@@ -123,7 +124,7 @@ metadata:
123
124
  homepage_uri: https://docs.rubocop.org/rubocop-performance/
124
125
  changelog_uri: https://github.com/rubocop/rubocop-performance/blob/master/CHANGELOG.md
125
126
  source_code_uri: https://github.com/rubocop/rubocop-performance/
126
- documentation_uri: https://docs.rubocop.org/rubocop-performance/1.16/
127
+ documentation_uri: https://docs.rubocop.org/rubocop-performance/1.19/
127
128
  bug_tracker_uri: https://github.com/rubocop/rubocop-performance/issues
128
129
  rubygems_mfa_required: 'true'
129
130
  post_install_message:
@@ -134,14 +135,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
134
135
  requirements:
135
136
  - - ">="
136
137
  - !ruby/object:Gem::Version
137
- version: 2.6.0
138
+ version: 2.7.0
138
139
  required_rubygems_version: !ruby/object:Gem::Requirement
139
140
  requirements:
140
141
  - - ">="
141
142
  - !ruby/object:Gem::Version
142
143
  version: '0'
143
144
  requirements: []
144
- rubygems_version: 3.3.26
145
+ rubygems_version: 3.5.0.dev
145
146
  signing_key:
146
147
  specification_version: 4
147
148
  summary: Automatic performance checking tool for Ruby code.