rubocop-performance 1.11.5 → 1.12.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4fffd38c1ed7da6f4ff4f67b3f1d7d08bc60e8871dc22d4ac266de6facc04fcf
4
- data.tar.gz: e0de1a9ec946e37b2654390d4b46a0b9f0e1afbc37fec464c6fd78001ad5e509
3
+ metadata.gz: c98065b3a22d03c0e9290990288d6b8a82a87d956bdf4165d94d3cd326ae7bf5
4
+ data.tar.gz: a9ee1493235e6584ad381941423c0cac234bfc36fb4a2417433e667a16bec054
5
5
  SHA512:
6
- metadata.gz: 4225a879e2e0421438be5d17bb38d982901709c809ed7ccda3a0095affaf77a707c5fb5657ee61b123546860f1e9f0bcf783ed706b8b17fba9114588a16b4653
7
- data.tar.gz: 3af998bbda7046ae5a55f06bb1ecc941dff48901d94a791fd81963cc1d76adf39524600c7ff4633c3dc06f925a2d8ea7f57716f51de2079e971c10b6194e40bb
6
+ metadata.gz: 35f36bff7bfe1b19496bfea773e7d0f7892731e57b06bb523ac192324a817f401207750abab20892ea58ec54595d1bdfd454bf250a4a00baf6ef0f4ac3f7b030
7
+ data.tar.gz: 84a6ebc3e13d7c24aa6f1219443ce2c6cf6cd6c6253d4f09c78056fb3906f08bcb44db5365b03231aae55170a653e504b4a3433b4ed4a4dea1ee21b23d7a1387
data/config/default.yml CHANGED
@@ -76,6 +76,12 @@ Performance/CompareWithBlock:
76
76
  Enabled: true
77
77
  VersionAdded: '0.46'
78
78
 
79
+ Performance/ConcurrentMonotonicTime:
80
+ Description: 'Use `Process.clock_gettime(Process::CLOCK_MONOTONIC)` instead of `Concurrent.monotonic_time`.'
81
+ Reference: 'https://github.com/rails/rails/pull/43502'
82
+ Enabled: pending
83
+ VersionAdded: '1.12'
84
+
79
85
  Performance/ConstantRegexp:
80
86
  Description: 'Finds regular expressions with dynamic components that are all constants.'
81
87
  Enabled: pending
@@ -309,9 +315,9 @@ Performance/StartWith:
309
315
  Performance/StringInclude:
310
316
  Description: 'Use `String#include?` instead of a regex match with literal-only pattern.'
311
317
  Enabled: 'pending'
312
- AutoCorrect: false
313
318
  SafeAutoCorrect: false
314
319
  VersionAdded: '1.7'
320
+ VersionChanged: '1.12'
315
321
 
316
322
  Performance/StringReplacement:
317
323
  Description: >-
@@ -6,6 +6,10 @@ module RuboCop
6
6
  # This cop is used to identify usages of `ancestors.include?` and
7
7
  # change them to use `<=` instead.
8
8
  #
9
+ # @safety
10
+ # This cop is unsafe because it can't tell whether the receiver is a class or an object.
11
+ # e.g. the false positive was for `Nokogiri::XML::Node#ancestors`.
12
+ #
9
13
  # @example
10
14
  # # bad
11
15
  # A.ancestors.include?(B)
@@ -7,7 +7,9 @@ module RuboCop
7
7
  # can be replaced by `Array#take` and `Array#drop`.
8
8
  # This cop was created due to a mistake in microbenchmark and hence is disabled by default.
9
9
  # Refer https://github.com/rubocop/rubocop-performance/pull/175#issuecomment-731892717
10
- # This cop is also unsafe for string slices because strings do not have `#take` and `#drop` methods.
10
+ #
11
+ # @safety
12
+ # This cop is unsafe for string slices because strings do not have `#take` and `#drop` methods.
11
13
  #
12
14
  # @example
13
15
  # # bad
@@ -17,11 +17,13 @@ module RuboCop
17
17
  # this defining a higher level when condition to override a condition
18
18
  # that is inside of the splat expansion.
19
19
  #
20
- # This is not a guaranteed performance improvement. If the data being
21
- # processed by the `case` condition is normalized in a manner that favors
22
- # hitting a condition in the splat expansion, it is possible that
23
- # moving the splat condition to the end will use more memory,
24
- # and run slightly slower.
20
+ # @safety
21
+ # This cop is not unsafe auto-correction because it is not a guaranteed
22
+ # performance improvement. If the data being processed by the `case` condition is
23
+ # normalized in a manner that favors hitting a condition in the splat expansion,
24
+ # it is possible that moving the splat condition to the end will use more memory,
25
+ # and run slightly slower.
26
+ # See for more details: https://github.com/rubocop/rubocop/pull/6163
25
27
  #
26
28
  # @example
27
29
  # # bad
@@ -5,8 +5,10 @@ module RuboCop
5
5
  module Performance
6
6
  # This cop identifies places where a case-insensitive string comparison
7
7
  # can better be implemented using `casecmp`.
8
- # This cop is unsafe because `String#casecmp` and `String#casecmp?` behave
9
- # differently when using Non-ASCII characters.
8
+ #
9
+ # @safety
10
+ # This cop is unsafe because `String#casecmp` and `String#casecmp?` behave
11
+ # differently when using Non-ASCII characters.
10
12
  #
11
13
  # @example
12
14
  # # bad
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Performance
6
+ # This cop identifies places where `Concurrent.monotonic_time`
7
+ # can be replaced by `Process.clock_gettime(Process::CLOCK_MONOTONIC)`.
8
+ #
9
+ # @example
10
+ #
11
+ # # bad
12
+ # Concurrent.monotonic_time
13
+ #
14
+ # # good
15
+ # Process.clock_gettime(Process::CLOCK_MONOTONIC)
16
+ #
17
+ class ConcurrentMonotonicTime < Base
18
+ extend AutoCorrector
19
+
20
+ MSG = 'Use `%<prefer>s` instead of `%<current>s`.'
21
+ RESTRICT_ON_SEND = %i[monotonic_time].freeze
22
+
23
+ def_node_matcher :concurrent_monotonic_time?, <<~PATTERN
24
+ (send
25
+ (const {nil? cbase} :Concurrent) :monotonic_time ...)
26
+ PATTERN
27
+
28
+ def on_send(node)
29
+ return unless concurrent_monotonic_time?(node)
30
+
31
+ optional_unit_parameter = ", #{node.first_argument.source}" if node.first_argument
32
+ prefer = "Process.clock_gettime(Process::CLOCK_MONOTONIC#{optional_unit_parameter})"
33
+ message = format(MSG, prefer: prefer, current: node.source)
34
+
35
+ add_offense(node, message: message) do |corrector|
36
+ corrector.replace(node, prefer)
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -7,6 +7,28 @@ module RuboCop
7
7
  # follow calls to `select`, `find_all`, `filter` or `reject`. Querying logic can instead be
8
8
  # passed to the `count` call.
9
9
  #
10
+ # @safety
11
+ # This cop is unsafe because it has known compatibility issues with `ActiveRecord` and other
12
+ # frameworks. ActiveRecord's `count` ignores the block that is passed to it.
13
+ # `ActiveRecord` will ignore the block that is passed to `count`.
14
+ # Other methods, such as `select`, will convert the association to an
15
+ # array and then run the block on the array. A simple work around to
16
+ # make `count` work with a block is to call `to_a.count {...}`.
17
+ #
18
+ # For example:
19
+ #
20
+ # [source,ruby]
21
+ # ----
22
+ # `Model.where(id: [1, 2, 3]).select { |m| m.method == true }.size`
23
+ # ----
24
+ #
25
+ # becomes:
26
+ #
27
+ # [source,ruby]
28
+ # ----
29
+ # `Model.where(id: [1, 2, 3]).to_a.count { |m| m.method == true }`
30
+ # ----
31
+ #
10
32
  # @example
11
33
  # # bad
12
34
  # [1, 2, 3].select { |e| e > 2 }.size
@@ -24,19 +46,6 @@ module RuboCop
24
46
  # [1, 2, 3].count { |e| e < 2 && e.even? }
25
47
  # Model.select('field AS field_one').count
26
48
  # Model.select(:value).count
27
- #
28
- # `ActiveRecord` compatibility:
29
- # `ActiveRecord` will ignore the block that is passed to `count`.
30
- # Other methods, such as `select`, will convert the association to an
31
- # array and then run the block on the array. A simple work around to
32
- # make `count` work with a block is to call `to_a.count {...}`.
33
- #
34
- # Example:
35
- # `Model.where(id: [1, 2, 3]).select { |m| m.method == true }.size`
36
- #
37
- # becomes:
38
- #
39
- # `Model.where(id: [1, 2, 3]).to_a.count { |m| m.method == true }`
40
49
  class Count < Base
41
50
  include RangeHelp
42
51
  extend AutoCorrector
@@ -7,7 +7,6 @@ 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`.
11
10
  #
12
11
  # This cop has `SafeMultiline` configuration option that `true` by default because
13
12
  # `^prefix` is unsafe as it will behave incompatible with `delete_prefix`
@@ -15,6 +14,9 @@ module RuboCop
15
14
  #
16
15
  # The `delete_prefix('prefix')` method is faster than `gsub(/\Aprefix/, '')`.
17
16
  #
17
+ # @safety
18
+ # This cop is unsafe because `Pathname` has `sub` but not `delete_prefix`.
19
+ #
18
20
  # @example
19
21
  #
20
22
  # # bad
@@ -47,9 +49,6 @@ module RuboCop
47
49
  class DeletePrefix < Base
48
50
  include RegexpMetacharacter
49
51
  extend AutoCorrector
50
- extend TargetRubyVersion
51
-
52
- minimum_target_ruby_version 2.5
53
52
 
54
53
  MSG = 'Use `%<prefer>s` instead of `%<current>s`.'
55
54
  RESTRICT_ON_SEND = %i[gsub gsub! sub sub!].freeze
@@ -7,7 +7,6 @@ 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`.
11
10
  #
12
11
  # This cop has `SafeMultiline` configuration option that `true` by default because
13
12
  # `suffix$` is unsafe as it will behave incompatible with `delete_suffix?`
@@ -15,6 +14,9 @@ module RuboCop
15
14
  #
16
15
  # The `delete_suffix('suffix')` method is faster than `gsub(/suffix\z/, '')`.
17
16
  #
17
+ # @safety
18
+ # This cop is unsafe because `Pathname` has `sub` but not `delete_suffix`.
19
+ #
18
20
  # @example
19
21
  #
20
22
  # # bad
@@ -47,9 +49,6 @@ module RuboCop
47
49
  class DeleteSuffix < Base
48
50
  include RegexpMetacharacter
49
51
  extend AutoCorrector
50
- extend TargetRubyVersion
51
-
52
- minimum_target_ruby_version 2.5
53
52
 
54
53
  MSG = 'Use `%<prefer>s` instead of `%<current>s`.'
55
54
  RESTRICT_ON_SEND = %i[gsub gsub! sub sub!].freeze
@@ -7,6 +7,11 @@ module RuboCop
7
7
  # chained to `select`, `find_all` or `filter` and change them to use
8
8
  # `detect` instead.
9
9
  #
10
+ # @safety
11
+ # This cop is unsafe because is has known compatibility issues with `ActiveRecord` and other
12
+ # frameworks. `ActiveRecord` does not implement a `detect` method and `find` has its own
13
+ # meaning. Correcting `ActiveRecord` methods with this cop should be considered unsafe.
14
+ #
10
15
  # @example
11
16
  # # bad
12
17
  # [].select { |item| true }.first
@@ -90,7 +95,7 @@ module RuboCop
90
95
  end
91
96
 
92
97
  def replacement(method, index)
93
- if method == :last || method == :[] && index == -1
98
+ if method == :last || (method == :[] && index == -1)
94
99
  "reverse.#{preferred_method}"
95
100
  else
96
101
  preferred_method
@@ -9,6 +9,11 @@ module RuboCop
9
9
  # `end$` is unsafe as it will behave incompatible with `end_with?`
10
10
  # for receiver is multiline string.
11
11
  #
12
+ # @safety
13
+ # This will change to a new method call which isn't guaranteed to be on the
14
+ # object. Switching these methods has to be done with knowledge of the types
15
+ # of the variables which rubocop doesn't have.
16
+ #
12
17
  # @example
13
18
  # # bad
14
19
  # 'abc'.match?(/bc\Z/)
@@ -15,6 +15,9 @@ module RuboCop
15
15
  # both perform an O(n) search through all of the values, calling `values`
16
16
  # allocates a new array while using `value?` does not.
17
17
  #
18
+ # @safety
19
+ # This cop is unsafe because it can't tell whether the receiver is a hash object.
20
+ #
18
21
  # @example
19
22
  # # bad
20
23
  # { a: 1, b: 2 }.keys.include?(:a)
@@ -6,8 +6,10 @@ module RuboCop
6
6
  # In Ruby 2.7, `Enumerable#filter_map` has been added.
7
7
  #
8
8
  # This cop identifies places where `map { ... }.compact` can be replaced by `filter_map`.
9
- # It is marked as unsafe auto-correction by default because `map { ... }.compact`
10
- # that is not compatible with `filter_map`.
9
+ #
10
+ # @safety
11
+ # This cop's autocorrection is unsafe because `map { ... }.compact` that is not
12
+ # compatible with `filter_map`.
11
13
  #
12
14
  # [source,ruby]
13
15
  # ----
@@ -11,6 +11,10 @@ module RuboCop
11
11
  # especially in case of single-threaded
12
12
  # applications with multiple `OpenStruct` instantiations.
13
13
  #
14
+ # @safety
15
+ # This cop is unsafe because `OpenStruct.new` and `Struct.new`
16
+ # are not equivalent.
17
+ #
14
18
  # @example
15
19
  # # bad
16
20
  # class MyClass
@@ -9,8 +9,9 @@ module RuboCop
9
9
  # end points of the `Range`. In a great majority of cases, this is what
10
10
  # is wanted.
11
11
  #
12
- # This cop is `Safe: false` by default because `Range#include?` (or `Range#member?`) and
13
- # `Range#cover?` are not equivalent behaviour.
12
+ # @safety
13
+ # This cop is unsafe because `Range#include?` (or `Range#member?`) and `Range#cover?`
14
+ # are not equivalent behaviour.
14
15
  #
15
16
  # @example
16
17
  # # bad
@@ -55,6 +55,7 @@ module RuboCop
55
55
  end
56
56
  end
57
57
  end
58
+ alias on_defs on_def
58
59
 
59
60
  private
60
61
 
@@ -9,8 +9,9 @@ module RuboCop
9
9
  # By default, `Object#===` behaves the same as `Object#==`, but this
10
10
  # behavior is appropriately overridden in subclass. For example,
11
11
  # `Range#===` returns `true` when argument is within the range.
12
- # Therefore, It is marked as unsafe by default because `===` and `==`
13
- # do not always behave the same.
12
+ #
13
+ # @safety
14
+ # This cop is unsafe because `===` and `==` do not always behave the same.
14
15
  #
15
16
  # @example
16
17
  # # bad
@@ -24,9 +25,6 @@ module RuboCop
24
25
  #
25
26
  class RedundantEqualityComparisonBlock < Base
26
27
  extend AutoCorrector
27
- extend TargetRubyVersion
28
-
29
- minimum_target_ruby_version 2.5
30
28
 
31
29
  MSG = 'Use `%<prefer>s` instead of block.'
32
30
 
@@ -8,8 +8,9 @@ module RuboCop
8
8
  # You can set the maximum number of key-value pairs to consider
9
9
  # an offense with `MaxKeyValuePairs`.
10
10
  #
11
- # This cop is marked as unsafe because RuboCop cannot determine if the
12
- # receiver of `merge!` is actually a hash or not.
11
+ # @safety
12
+ # This cop is unsafe because RuboCop cannot determine if the
13
+ # receiver of `merge!` is actually a hash or not.
13
14
  #
14
15
  # @example
15
16
  # # bad
@@ -91,7 +92,7 @@ module RuboCop
91
92
  end
92
93
 
93
94
  def non_redundant_pairs?(receiver, pairs)
94
- pairs.size > 1 && !receiver.pure? || pairs.size > max_key_value_pairs
95
+ (pairs.size > 1 && !receiver.pure?) || pairs.size > max_key_value_pairs
95
96
  end
96
97
 
97
98
  def kwsplat_used?(pairs)
@@ -9,6 +9,11 @@ module RuboCop
9
9
  # `^start` is unsafe as it will behave incompatible with `start_with?`
10
10
  # for receiver is multiline string.
11
11
  #
12
+ # @safety
13
+ # This will change to a new method call which isn't guaranteed to be on the
14
+ # object. Switching these methods has to be done with knowledge of the types
15
+ # of the variables which rubocop doesn't have.
16
+ #
12
17
  # @example
13
18
  # # bad
14
19
  # 'abc'.match?(/\Aab/)
@@ -6,7 +6,8 @@ module RuboCop
6
6
  # This cop identifies unnecessary use of a regex where
7
7
  # `String#include?` would suffice.
8
8
  #
9
- # This cop's offenses are not safe to auto-correct if a receiver is nil.
9
+ # @safety
10
+ # This cop's offenses are not safe to auto-correct if a receiver is nil.
10
11
  #
11
12
  # @example
12
13
  # # bad
@@ -156,7 +156,7 @@ module RuboCop
156
156
  end
157
157
 
158
158
  def sum_method_range(node)
159
- range_between(node.loc.selector.begin_pos, node.loc.end.end_pos)
159
+ range_between(node.loc.selector.begin_pos, node.loc.expression.end_pos)
160
160
  end
161
161
 
162
162
  def sum_map_range(map, sum)
@@ -7,6 +7,18 @@ module RuboCop
7
7
  # In most cases such calls can be replaced
8
8
  # with an explicit array creation.
9
9
  #
10
+ # @safety
11
+ # This cop's autocorrection is unsafe because `Integer#times` does nothing if receiver is 0
12
+ # or less. However, `Array.new` raises an error if argument is less than 0.
13
+ #
14
+ # For example:
15
+ #
16
+ # [source,ruby]
17
+ # ----
18
+ # -1.times{} # does nothing
19
+ # Array.new(-1) # ArgumentError: negative array size
20
+ # ----
21
+ #
10
22
  # @example
11
23
  # # bad
12
24
  # 9.times.map do |i|
@@ -7,11 +7,11 @@ module RuboCop
7
7
  # literal instead of `String#dup` and `String.new`.
8
8
  # Unary plus operator is faster than `String#dup`.
9
9
  #
10
- # NOTE: `String.new` (without operator) is not exactly the same as `+''`.
11
- # These differ in encoding. `String.new.encoding` is always `ASCII-8BIT`.
12
- # However, `(+'').encoding` is the same as script encoding(e.g. `UTF-8`).
13
- # Therefore, auto-correction is unsafe.
14
- # So, if you expect `ASCII-8BIT` encoding, disable this cop.
10
+ # @safety
11
+ # This cop's autocorrection is unsafe because `String.new` (without operator) is not
12
+ # exactly the same as `+''`. These differ in encoding. `String.new.encoding` is always
13
+ # `ASCII-8BIT`. However, `(+'').encoding` is the same as script encoding(e.g. `UTF-8`).
14
+ # if you expect `ASCII-8BIT` encoding, disable this cop.
15
15
  #
16
16
  # @example
17
17
  # # bad
@@ -13,6 +13,7 @@ require_relative 'performance/case_when_splat'
13
13
  require_relative 'performance/casecmp'
14
14
  require_relative 'performance/collection_literal_in_loop'
15
15
  require_relative 'performance/compare_with_block'
16
+ require_relative 'performance/concurrent_monotonic_time'
16
17
  require_relative 'performance/constant_regexp'
17
18
  require_relative 'performance/count'
18
19
  require_relative 'performance/delete_prefix'
@@ -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.5'
7
+ STRING = '1.12.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.11.5
4
+ version: 1.12.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: 2021-08-18 00:00:00.000000000 Z
13
+ date: 2021-10-31 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rubocop
@@ -74,6 +74,7 @@ files:
74
74
  - lib/rubocop/cop/performance/chain_array_allocation.rb
75
75
  - lib/rubocop/cop/performance/collection_literal_in_loop.rb
76
76
  - lib/rubocop/cop/performance/compare_with_block.rb
77
+ - lib/rubocop/cop/performance/concurrent_monotonic_time.rb
77
78
  - lib/rubocop/cop/performance/constant_regexp.rb
78
79
  - lib/rubocop/cop/performance/count.rb
79
80
  - lib/rubocop/cop/performance/delete_prefix.rb
@@ -121,7 +122,7 @@ metadata:
121
122
  homepage_uri: https://docs.rubocop.org/rubocop-performance/
122
123
  changelog_uri: https://github.com/rubocop/rubocop-performance/blob/master/CHANGELOG.md
123
124
  source_code_uri: https://github.com/rubocop/rubocop-performance/
124
- documentation_uri: https://docs.rubocop.org/rubocop-performance/1.11/
125
+ documentation_uri: https://docs.rubocop.org/rubocop-performance/1.12/
125
126
  bug_tracker_uri: https://github.com/rubocop/rubocop-performance/issues
126
127
  post_install_message:
127
128
  rdoc_options: []
@@ -138,7 +139,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
138
139
  - !ruby/object:Gem::Version
139
140
  version: '0'
140
141
  requirements: []
141
- rubygems_version: 3.2.12
142
+ rubygems_version: 3.3.0.dev
142
143
  signing_key:
143
144
  specification_version: 4
144
145
  summary: Automatic performance checking tool for Ruby code.