rubocop-performance 1.11.1 → 1.11.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0fddb9566bda412ba7ab8f26966cca63207064468d2c2da5796a81cd84da1c69
4
- data.tar.gz: f49da21e50225a0f35fe6959ad3a37a2c26ff73e64df03f5a94025811d380b02
3
+ metadata.gz: 4fffd38c1ed7da6f4ff4f67b3f1d7d08bc60e8871dc22d4ac266de6facc04fcf
4
+ data.tar.gz: e0de1a9ec946e37b2654390d4b46a0b9f0e1afbc37fec464c6fd78001ad5e509
5
5
  SHA512:
6
- metadata.gz: a70fd0b8cf0778f410098e889dc52c828202f0d197a10a9fb4edff36991204cad23cfba361039b9b80952c7f5f814679d7277e2f9c533fe29fd55e708c4d1bb9
7
- data.tar.gz: a2ce3b7915ed3c3bc208ef020f031646e3350d46397759eb0c5a772e826dc30ad8d72d75c009b385358ef015be4b6af4c7cd1b6f337b6f34c583432bef608a65
6
+ metadata.gz: 4225a879e2e0421438be5d17bb38d982901709c809ed7ccda3a0095affaf77a707c5fb5657ee61b123546860f1e9f0bcf783ed706b8b17fba9114588a16b4653
7
+ data.tar.gz: 3af998bbda7046ae5a55f06bb1ecc941dff48901d94a791fd81963cc1d76adf39524600c7ff4633c3dc06f925a2d8ea7f57716f51de2079e971c10b6194e40bb
data/config/default.yml CHANGED
@@ -96,14 +96,18 @@ Performance/Count:
96
96
  Performance/DeletePrefix:
97
97
  Description: 'Use `delete_prefix` instead of `gsub`.'
98
98
  Enabled: true
99
+ Safe: false
99
100
  SafeMultiline: true
100
101
  VersionAdded: '1.6'
102
+ VersionChanged: '1.11'
101
103
 
102
104
  Performance/DeleteSuffix:
103
105
  Description: 'Use `delete_suffix` instead of `gsub`.'
104
106
  Enabled: true
107
+ Safe: false
105
108
  SafeMultiline: true
106
109
  VersionAdded: '1.6'
110
+ VersionChanged: '1.11'
107
111
 
108
112
  Performance/Detect:
109
113
  Description: >-
@@ -11,11 +11,11 @@ module RuboCop
11
11
  #
12
12
  # @example
13
13
  # # bad
14
- # # array[..2]
15
- # # array[...2]
16
- # # array[2..]
17
- # # array[2...]
18
- # # array.slice(..2)
14
+ # array[..2]
15
+ # array[...2]
16
+ # array[2..]
17
+ # array[2...]
18
+ # array.slice(..2)
19
19
  #
20
20
  # # good
21
21
  # array.take(3)
@@ -58,10 +58,8 @@ module RuboCop
58
58
  include RangeHelp
59
59
  extend AutoCorrector
60
60
 
61
- MSG = 'Reordering `when` conditions with a splat to the end ' \
62
- 'of the `when` branches can improve performance.'
63
- ARRAY_MSG = 'Pass the contents of array literals ' \
64
- 'directly to `when` conditions.'
61
+ MSG = 'Reordering `when` conditions with a splat to the end of the `when` branches can improve performance.'
62
+ ARRAY_MSG = 'Pass the contents of array literals directly to `when` conditions.'
65
63
 
66
64
  def on_case(case_node)
67
65
  when_conditions = case_node.when_branches.flat_map(&:conditions)
@@ -134,13 +132,11 @@ module RuboCop
134
132
  end
135
133
 
136
134
  def new_condition_with_then(node, new_condition)
137
- "\n#{indent_for(node)}when " \
138
- "#{new_condition} then #{node.body.source}"
135
+ "\n#{indent_for(node)}when #{new_condition} then #{node.body.source}"
139
136
  end
140
137
 
141
138
  def new_branch_without_then(node, new_condition)
142
- "\n#{indent_for(node)}when #{new_condition}" \
143
- "\n#{indent_for(node.body)}#{node.body.source}"
139
+ "\n#{indent_for(node)}when #{new_condition}\n#{indent_for(node.body)}#{node.body.source}"
144
140
  end
145
141
 
146
142
  def indent_for(node)
@@ -33,7 +33,7 @@ module RuboCop
33
33
  #
34
34
  class CollectionLiteralInLoop < Base
35
35
  MSG = 'Avoid immutable %<literal_class>s literals in loops. '\
36
- 'It is better to extract it into a local variable or a constant.'
36
+ 'It is better to extract it into a local variable or a constant.'
37
37
 
38
38
  POST_CONDITION_LOOP_TYPES = %i[while_post until_post].freeze
39
39
  LOOP_TYPES = (POST_CONDITION_LOOP_TYPES + %i[while until for]).freeze
@@ -7,6 +7,7 @@ module RuboCop
7
7
  #
8
8
  # This cop identifies places where `gsub(/\Aprefix/, '')` and `sub(/\Aprefix/, '')`
9
9
  # can be replaced by `delete_prefix('prefix')`.
10
+ # It is marked as unsafe by default because `Pathname` has `sub` but not `delete_prefix`.
10
11
  #
11
12
  # This cop has `SafeMultiline` configuration option that `true` by default because
12
13
  # `^prefix` is unsafe as it will behave incompatible with `delete_prefix`
@@ -66,7 +67,7 @@ module RuboCop
66
67
 
67
68
  def on_send(node)
68
69
  return unless (receiver, bad_method, regexp_str, replace_string = delete_prefix_candidate?(node))
69
- return unless replace_string.blank?
70
+ return unless replace_string.empty?
70
71
 
71
72
  good_method = PREFERRED_METHODS[bad_method]
72
73
 
@@ -7,6 +7,7 @@ module RuboCop
7
7
  #
8
8
  # This cop identifies places where `gsub(/suffix\z/, '')` and `sub(/suffix\z/, '')`
9
9
  # can be replaced by `delete_suffix('suffix')`.
10
+ # It is marked as unsafe by default because `Pathname` has `sub` but not `delete_suffix`.
10
11
  #
11
12
  # This cop has `SafeMultiline` configuration option that `true` by default because
12
13
  # `suffix$` is unsafe as it will behave incompatible with `delete_suffix?`
@@ -66,7 +67,7 @@ module RuboCop
66
67
 
67
68
  def on_send(node)
68
69
  return unless (receiver, bad_method, regexp_str, replace_string = delete_suffix_candidate?(node))
69
- return unless replace_string.blank?
70
+ return unless replace_string.empty?
70
71
 
71
72
  good_method = PREFERRED_METHODS[bad_method]
72
73
 
@@ -31,14 +31,10 @@ module RuboCop
31
31
 
32
32
  CANDIDATE_METHODS = Set[:select, :find_all, :filter].freeze
33
33
 
34
- MSG = 'Use `%<prefer>s` instead of ' \
35
- '`%<first_method>s.%<second_method>s`.'
36
- REVERSE_MSG = 'Use `reverse.%<prefer>s` instead of ' \
37
- '`%<first_method>s.%<second_method>s`.'
38
- INDEX_MSG = 'Use `%<prefer>s` instead of ' \
39
- '`%<first_method>s[%<index>i]`.'
40
- INDEX_REVERSE_MSG = 'Use `reverse.%<prefer>s` instead of ' \
41
- '`%<first_method>s[%<index>i]`.'
34
+ MSG = 'Use `%<prefer>s` instead of `%<first_method>s.%<second_method>s`.'
35
+ REVERSE_MSG = 'Use `reverse.%<prefer>s` instead of `%<first_method>s.%<second_method>s`.'
36
+ INDEX_MSG = 'Use `%<prefer>s` instead of `%<first_method>s[%<index>i]`.'
37
+ INDEX_REVERSE_MSG = 'Use `reverse.%<prefer>s` instead of `%<first_method>s[%<index>i]`.'
42
38
  RESTRICT_ON_SEND = %i[first last []].freeze
43
39
 
44
40
  def_node_matcher :detect_candidate?, <<~PATTERN
@@ -23,6 +23,7 @@ module RuboCop
23
23
  # # good
24
24
  # ary.filter_map(&:foo)
25
25
  # ary.map(&:foo).compact!
26
+ # ary.compact.map(&:foo)
26
27
  #
27
28
  class MapCompact < Base
28
29
  include RangeHelp
@@ -55,21 +56,28 @@ module RuboCop
55
56
 
56
57
  add_offense(range) do |corrector|
57
58
  corrector.replace(map_node.loc.selector, 'filter_map')
58
- corrector.remove(compact_loc.dot)
59
- corrector.remove(compact_method_range(node))
59
+ remove_compact_method(corrector, node)
60
60
  end
61
61
  end
62
62
 
63
63
  private
64
64
 
65
- def compact_method_range(compact_node)
65
+ def remove_compact_method(corrector, compact_node)
66
+ chained_method = compact_node.parent
66
67
  compact_method_range = compact_node.loc.selector
67
68
 
68
- if compact_node.multiline?
69
- range_by_whole_lines(compact_method_range, include_final_newline: true)
69
+ if compact_node.multiline? && chained_method&.loc.respond_to?(:selector) && chained_method.dot? &&
70
+ !invoke_method_after_map_compact_on_same_line?(compact_node, chained_method)
71
+ compact_method_range = range_by_whole_lines(compact_method_range, include_final_newline: true)
70
72
  else
71
- compact_method_range
73
+ corrector.remove(compact_node.loc.dot)
72
74
  end
75
+
76
+ corrector.remove(compact_method_range)
77
+ end
78
+
79
+ def invoke_method_after_map_compact_on_same_line?(compact_node, chained_method)
80
+ compact_node.loc.selector.line == chained_method.loc.selector.line
73
81
  end
74
82
  end
75
83
  end
@@ -74,12 +74,27 @@ module RuboCop
74
74
 
75
75
  def new_argument(block_argument, block_body)
76
76
  if block_argument.source == block_body.receiver.source
77
- block_body.first_argument.source
77
+ rhs = block_body.first_argument
78
+ return if use_block_argument_in_method_argument_of_operand?(block_argument, rhs)
79
+
80
+ rhs.source
78
81
  elsif block_argument.source == block_body.first_argument.source
79
- block_body.receiver.source
82
+ lhs = block_body.receiver
83
+ return if use_block_argument_in_method_argument_of_operand?(block_argument, lhs)
84
+
85
+ lhs.source
80
86
  end
81
87
  end
82
88
 
89
+ def use_block_argument_in_method_argument_of_operand?(block_argument, operand)
90
+ return false unless operand.send_type?
91
+
92
+ arguments = operand.arguments
93
+ arguments.inject(arguments.map(&:source)) do |operand_sources, argument|
94
+ operand_sources + argument.each_descendant(:lvar).map(&:source)
95
+ end.any?(block_argument.source)
96
+ end
97
+
83
98
  def offense_range(node)
84
99
  node.send_node.loc.selector.join(node.source_range.end)
85
100
  end
@@ -16,35 +16,35 @@ module RuboCop
16
16
  # # bad
17
17
  # str.chars.first
18
18
  # str.chars.first(2)
19
- # str.chars.last
20
- # str.chars.last(2)
21
19
  #
22
20
  # # good
23
21
  # str[0]
24
22
  # str[0...2].chars
25
- # str[-1]
26
- # str[-2..-1].chars
27
23
  #
28
24
  # # bad
29
25
  # str.chars.take(2)
30
- # str.chars.drop(2)
31
26
  # str.chars.length
32
27
  # str.chars.size
33
28
  # str.chars.empty?
34
29
  #
35
30
  # # good
36
31
  # str[0...2].chars
37
- # str[2..-1].chars
38
32
  # str.length
39
33
  # str.size
40
34
  # str.empty?
41
35
  #
36
+ # # For example, if the receiver is a blank string, it will be incompatible.
37
+ # # If a negative value is specified for the receiver, `nil` is returned.
38
+ # str.chars.last # Incompatible with `str[-1]`.
39
+ # str.chars.last(2) # Incompatible with `str[-2..-1].chars`.
40
+ # str.chars.drop(2) # Incompatible with `str[2..-1].chars`.
41
+ #
42
42
  class RedundantStringChars < Base
43
43
  include RangeHelp
44
44
  extend AutoCorrector
45
45
 
46
46
  MSG = 'Use `%<good_method>s` instead of `%<bad_method>s`.'
47
- RESTRICT_ON_SEND = %i[[] slice first last take drop length size empty?].freeze
47
+ RESTRICT_ON_SEND = %i[[] slice first take length size empty?].freeze
48
48
 
49
49
  def_node_matcher :redundant_chars_call?, <<~PATTERN
50
50
  (send $(send _ :chars) $_ $...)
@@ -80,7 +80,6 @@ module RuboCop
80
80
  format(MSG, good_method: good_method, bad_method: bad_method)
81
81
  end
82
82
 
83
- # rubocop:disable Metrics/CyclomaticComplexity, Metrics/MethodLength
84
83
  def build_good_method(method, args)
85
84
  case method
86
85
  when :[], :slice
@@ -91,21 +90,12 @@ module RuboCop
91
90
  else
92
91
  '[0]'
93
92
  end
94
- when :last
95
- if args.any?
96
- "[-#{args.first.source}..-1].chars"
97
- else
98
- '[-1]'
99
- end
100
93
  when :take
101
94
  "[0...#{args.first.source}].chars"
102
- when :drop
103
- "[#{args.first.source}..-1].chars"
104
95
  else
105
96
  ".#{method}"
106
97
  end
107
98
  end
108
- # rubocop:enable Metrics/CyclomaticComplexity, Metrics/MethodLength
109
99
 
110
100
  def build_bad_method(method, args)
111
101
  case method
@@ -78,8 +78,7 @@ module RuboCop
78
78
  # Constants are included in this list because it is unlikely that
79
79
  # someone will store `nil` as a constant and then use it for comparison
80
80
  TYPES_IMPLEMENTING_MATCH = %i[const regexp str sym].freeze
81
- MSG = 'Use `match?` instead of `%<current>s` when `MatchData` ' \
82
- 'is not used.'
81
+ MSG = 'Use `match?` instead of `%<current>s` when `MatchData` is not used.'
83
82
 
84
83
  def_node_matcher :match_method?, <<~PATTERN
85
84
  {
@@ -45,7 +45,10 @@ module RuboCop
45
45
  return unless dup_string?(node) || string_new?(node)
46
46
 
47
47
  add_offense(node) do |corrector|
48
- corrector.replace(node, "+#{string_value(node)}")
48
+ string_value = "+#{string_value(node)}"
49
+ string_value = "(#{string_value})" if node.parent&.send_type?
50
+
51
+ corrector.replace(node, string_value)
49
52
  end
50
53
  end
51
54
 
@@ -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.11.1'
7
+ STRING = '1.11.5'
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.11.1
4
+ version: 1.11.5
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: 2021-05-01 00:00:00.000000000 Z
13
+ date: 2021-08-18 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rubocop