rubocop-performance 1.9.2 → 1.10.1
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 +4 -4
- data/LICENSE.txt +1 -1
- data/README.md +2 -2
- data/config/default.yml +19 -6
- data/lib/rubocop/cop/performance/array_semi_infinite_range_slice.rb +1 -1
- data/lib/rubocop/cop/performance/bind_call.rb +2 -2
- data/lib/rubocop/cop/performance/constant_regexp.rb +12 -7
- data/lib/rubocop/cop/performance/redundant_equality_comparison_block.rb +80 -0
- data/lib/rubocop/cop/performance/redundant_split_regexp_argument.rb +64 -0
- data/lib/rubocop/cop/performance/sum.rb +8 -2
- data/lib/rubocop/cop/performance_cops.rb +2 -0
- data/lib/rubocop/performance/version.rb +1 -1
- metadata +10 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 026fa40bed33c9e7867599f1024ddf6c1ab430b00beae5f5ec52d9b32f5adef9
|
4
|
+
data.tar.gz: d0997dd1a5255e217f5faf2adc4f27b64a43266ff24264aa80307b474cbfa936
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7a09ace7478bf3d87dc35897bb677c802c6b191ce0206e1b94e04826091ce8075ad9f267cd7805cd68ba3476c679e3cdb59c219fd71760ac4756c26a209c51bc
|
7
|
+
data.tar.gz: f9ccef454d4c9ff9a8d67db5276d2249d03a2882b169abfc5d4bacc28f9f09391edb15100750480c354fe9cc161463156169f216d482c9504f7d6a17da524a0c
|
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
# RuboCop Performance
|
2
2
|
|
3
3
|
[](https://badge.fury.io/rb/rubocop-performance)
|
4
|
-
[](https://circleci.com/gh/rubocop/rubocop-performance)
|
5
5
|
|
6
|
-
Performance optimization analysis for your projects, as an extension to [RuboCop](https://github.com/rubocop
|
6
|
+
Performance optimization analysis for your projects, as an extension to [RuboCop](https://github.com/rubocop/rubocop).
|
7
7
|
|
8
8
|
## Installation
|
9
9
|
|
data/config/default.yml
CHANGED
@@ -10,7 +10,7 @@ Performance/AncestorsInclude:
|
|
10
10
|
Performance/ArraySemiInfiniteRangeSlice:
|
11
11
|
Description: 'Identifies places where slicing arrays with semi-infinite ranges can be replaced by `Array#take` and `Array#drop`.'
|
12
12
|
# This cop was created due to a mistake in microbenchmark.
|
13
|
-
# Refer https://github.com/rubocop
|
13
|
+
# Refer https://github.com/rubocop/rubocop-performance/pull/175#issuecomment-731892717
|
14
14
|
Enabled: false
|
15
15
|
# Unsafe for string slices because strings do not have `#take` and `#drop` methods.
|
16
16
|
Safe: false
|
@@ -80,6 +80,7 @@ Performance/ConstantRegexp:
|
|
80
80
|
Description: 'Finds regular expressions with dynamic components that are all constants.'
|
81
81
|
Enabled: pending
|
82
82
|
VersionAdded: '1.9'
|
83
|
+
VersionChanged: '1.10'
|
83
84
|
|
84
85
|
Performance/Count:
|
85
86
|
Description: >-
|
@@ -136,11 +137,10 @@ Performance/EndWith:
|
|
136
137
|
# object. Switching these methods has to be done with knowledge of the types
|
137
138
|
# of the variables which rubocop doesn't have.
|
138
139
|
SafeAutoCorrect: false
|
139
|
-
AutoCorrect: false
|
140
140
|
Enabled: true
|
141
141
|
SafeMultiline: true
|
142
142
|
VersionAdded: '0.36'
|
143
|
-
VersionChanged: '1.
|
143
|
+
VersionChanged: '1.10'
|
144
144
|
|
145
145
|
Performance/FixedSize:
|
146
146
|
Description: 'Do not compute the size of statically sized objects except in constants.'
|
@@ -200,6 +200,15 @@ Performance/RedundantBlockCall:
|
|
200
200
|
Enabled: true
|
201
201
|
VersionAdded: '0.36'
|
202
202
|
|
203
|
+
Performance/RedundantEqualityComparisonBlock:
|
204
|
+
Description: >-
|
205
|
+
Checks for uses `Enumerable#all?`, `Enumerable#any?`, `Enumerable#one?`,
|
206
|
+
or `Enumerable#none?` are compared with `===` or similar methods in block.
|
207
|
+
Reference: 'https://github.com/rails/rails/pull/41363'
|
208
|
+
Enabled: pending
|
209
|
+
Safe: false
|
210
|
+
VersionAdded: '1.10'
|
211
|
+
|
203
212
|
Performance/RedundantMatch:
|
204
213
|
Description: >-
|
205
214
|
Use `=~` instead of `String#match` or `Regexp#match` in a context where the
|
@@ -220,6 +229,11 @@ Performance/RedundantSortBlock:
|
|
220
229
|
Enabled: 'pending'
|
221
230
|
VersionAdded: '1.7'
|
222
231
|
|
232
|
+
Performance/RedundantSplitRegexpArgument:
|
233
|
+
Description: 'This cop identifies places where `split` argument can be replaced from a deterministic regexp to a string.'
|
234
|
+
Enabled: pending
|
235
|
+
VersionAdded: '1.10'
|
236
|
+
|
223
237
|
Performance/RedundantStringChars:
|
224
238
|
Description: 'Checks for redundant `String#chars`.'
|
225
239
|
Enabled: 'pending'
|
@@ -270,11 +284,10 @@ Performance/StartWith:
|
|
270
284
|
# object. Switching these methods has to be done with knowledge of the types
|
271
285
|
# of the variables which rubocop doesn't have.
|
272
286
|
SafeAutoCorrect: false
|
273
|
-
AutoCorrect: false
|
274
287
|
Enabled: true
|
275
288
|
SafeMultiline: true
|
276
289
|
VersionAdded: '0.36'
|
277
|
-
VersionChanged: '1.
|
290
|
+
VersionChanged: '1.10'
|
278
291
|
|
279
292
|
Performance/StringInclude:
|
280
293
|
Description: 'Use `String#include?` instead of a regex match with literal-only pattern.'
|
@@ -304,7 +317,7 @@ Performance/TimesMap:
|
|
304
317
|
Enabled: true
|
305
318
|
VersionAdded: '0.36'
|
306
319
|
VersionChanged: '0.50'
|
307
|
-
SafeAutoCorrect: false # see https://github.com/rubocop
|
320
|
+
SafeAutoCorrect: false # see https://github.com/rubocop/rubocop/issues/4658
|
308
321
|
|
309
322
|
Performance/UnfreezeString:
|
310
323
|
Description: 'Use unary plus to get an unfrozen string literal.'
|
@@ -6,7 +6,7 @@ module RuboCop
|
|
6
6
|
# This cop identifies places where slicing arrays with semi-infinite ranges
|
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
|
-
# Refer https://github.com/rubocop
|
9
|
+
# Refer https://github.com/rubocop/rubocop-performance/pull/175#issuecomment-731892717
|
10
10
|
# This cop is also unsafe for string slices because strings do not have `#take` and `#drop` methods.
|
11
11
|
#
|
12
12
|
# @example
|
@@ -33,7 +33,7 @@ module RuboCop
|
|
33
33
|
def_node_matcher :bind_with_call_method?, <<~PATTERN
|
34
34
|
(send
|
35
35
|
$(send
|
36
|
-
|
36
|
+
_ :bind
|
37
37
|
$(...)) :call
|
38
38
|
$...)
|
39
39
|
PATTERN
|
@@ -64,7 +64,7 @@ module RuboCop
|
|
64
64
|
|
65
65
|
def correction_range(receiver, node)
|
66
66
|
location_of_bind = receiver.loc.selector.begin_pos
|
67
|
-
location_of_call = node.
|
67
|
+
location_of_call = node.source_range.end.end_pos
|
68
68
|
|
69
69
|
range_between(location_of_bind, location_of_call)
|
70
70
|
end
|
@@ -6,9 +6,9 @@ module RuboCop
|
|
6
6
|
# This cop finds regular expressions with dynamic components that are all constants.
|
7
7
|
#
|
8
8
|
# Ruby allocates a new Regexp object every time it executes a code containing such
|
9
|
-
# a regular expression. It is more efficient to extract it into a constant
|
10
|
-
# or add an `/o` option to perform `#{}` interpolation only once and
|
11
|
-
# Regexp object.
|
9
|
+
# a regular expression. It is more efficient to extract it into a constant,
|
10
|
+
# memoize it, or add an `/o` option to perform `#{}` interpolation only once and
|
11
|
+
# reuse that Regexp object.
|
12
12
|
#
|
13
13
|
# @example
|
14
14
|
#
|
@@ -28,13 +28,18 @@ module RuboCop
|
|
28
28
|
# pattern.scan(TOKEN).reject { |token| token.match?(/\A#{SEPARATORS}\Z/o) }
|
29
29
|
# end
|
30
30
|
#
|
31
|
+
# # good
|
32
|
+
# def separators
|
33
|
+
# @separators ||= /\A#{SEPARATORS}\Z/
|
34
|
+
# end
|
35
|
+
#
|
31
36
|
class ConstantRegexp < Base
|
32
37
|
extend AutoCorrector
|
33
38
|
|
34
|
-
MSG = 'Extract this regexp into a constant or append an `/o` option to its options.'
|
39
|
+
MSG = 'Extract this regexp into a constant, memoize it, or append an `/o` option to its options.'
|
35
40
|
|
36
41
|
def on_regexp(node)
|
37
|
-
return if
|
42
|
+
return if within_allowed_assignment?(node) ||
|
38
43
|
!include_interpolated_const?(node) ||
|
39
44
|
node.single_interpolation?
|
40
45
|
|
@@ -45,8 +50,8 @@ module RuboCop
|
|
45
50
|
|
46
51
|
private
|
47
52
|
|
48
|
-
def
|
49
|
-
node.each_ancestor(:casgn).any?
|
53
|
+
def within_allowed_assignment?(node)
|
54
|
+
node.each_ancestor(:casgn, :or_asgn).any?
|
50
55
|
end
|
51
56
|
|
52
57
|
def_node_matcher :regexp_escape?, <<~PATTERN
|
@@ -0,0 +1,80 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Performance
|
6
|
+
# This cop checks for uses `Enumerable#all?`, `Enumerable#any?`, `Enumerable#one?`,
|
7
|
+
# and `Enumerable#none?` are compared with `===` or similar methods in block.
|
8
|
+
#
|
9
|
+
# By default, `Object#===` behaves the same as `Object#==`, but this
|
10
|
+
# behavior is appropriately overridden in subclass. For example,
|
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.
|
14
|
+
#
|
15
|
+
# @example
|
16
|
+
# # bad
|
17
|
+
# items.all? { |item| pattern === item }
|
18
|
+
# items.all? { |item| item == other }
|
19
|
+
# items.all? { |item| item.is_a?(Klass) }
|
20
|
+
# items.all? { |item| item.kind_of?(Klass) }
|
21
|
+
#
|
22
|
+
# # good
|
23
|
+
# items.all?(pattern)
|
24
|
+
#
|
25
|
+
class RedundantEqualityComparisonBlock < Base
|
26
|
+
extend AutoCorrector
|
27
|
+
extend TargetRubyVersion
|
28
|
+
|
29
|
+
minimum_target_ruby_version 2.5
|
30
|
+
|
31
|
+
MSG = 'Use `%<prefer>s` instead of block.'
|
32
|
+
|
33
|
+
TARGET_METHODS = %i[all? any? one? none?].freeze
|
34
|
+
COMPARISON_METHODS = %i[== === is_a? kind_of?].freeze
|
35
|
+
IS_A_METHODS = %i[is_a? kind_of?].freeze
|
36
|
+
|
37
|
+
def on_block(node)
|
38
|
+
return unless TARGET_METHODS.include?(node.method_name) && node.arguments.one?
|
39
|
+
|
40
|
+
block_argument = node.arguments.first
|
41
|
+
block_body = node.body
|
42
|
+
return unless use_equality_comparison_block?(block_body)
|
43
|
+
return if same_block_argument_and_is_a_argument?(block_body, block_argument)
|
44
|
+
return unless (new_argument = new_argument(block_argument, block_body))
|
45
|
+
|
46
|
+
range = offense_range(node)
|
47
|
+
prefer = "#{node.method_name}(#{new_argument})"
|
48
|
+
|
49
|
+
add_offense(range, message: format(MSG, prefer: prefer)) do |corrector|
|
50
|
+
corrector.replace(range, prefer)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
def use_equality_comparison_block?(block_body)
|
57
|
+
block_body.send_type? && COMPARISON_METHODS.include?(block_body.method_name)
|
58
|
+
end
|
59
|
+
|
60
|
+
def same_block_argument_and_is_a_argument?(block_body, block_argument)
|
61
|
+
return false unless IS_A_METHODS.include?(block_body.method_name)
|
62
|
+
|
63
|
+
block_argument.source == block_body.first_argument.source
|
64
|
+
end
|
65
|
+
|
66
|
+
def new_argument(block_argument, block_body)
|
67
|
+
if block_argument.source == block_body.receiver.source
|
68
|
+
block_body.first_argument.source
|
69
|
+
elsif block_argument.source == block_body.first_argument.source
|
70
|
+
block_body.receiver.source
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def offense_range(node)
|
75
|
+
node.send_node.loc.selector.join(node.source_range.end)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Performance
|
6
|
+
# This cop identifies places where `split` argument can be replaced from
|
7
|
+
# a deterministic regexp to a string.
|
8
|
+
#
|
9
|
+
# @example
|
10
|
+
# # bad
|
11
|
+
# 'a,b,c'.split(/,/)
|
12
|
+
#
|
13
|
+
# # good
|
14
|
+
# 'a,b,c'.split(',')
|
15
|
+
class RedundantSplitRegexpArgument < Base
|
16
|
+
extend AutoCorrector
|
17
|
+
|
18
|
+
MSG = 'Use string as argument instead of regexp.'
|
19
|
+
RESTRICT_ON_SEND = %i[split].freeze
|
20
|
+
DETERMINISTIC_REGEX = /\A(?:#{LITERAL_REGEX})+\Z/.freeze
|
21
|
+
STR_SPECIAL_CHARS = %w[\n \" \' \\\\ \t \b \f \r].freeze
|
22
|
+
|
23
|
+
def_node_matcher :split_call_with_regexp?, <<~PATTERN
|
24
|
+
{(send !nil? :split $regexp)}
|
25
|
+
PATTERN
|
26
|
+
|
27
|
+
def on_send(node)
|
28
|
+
return unless (regexp_node = split_call_with_regexp?(node))
|
29
|
+
return if regexp_node.ignore_case?
|
30
|
+
return unless determinist_regexp?(regexp_node)
|
31
|
+
|
32
|
+
add_offense(regexp_node) do |corrector|
|
33
|
+
new_argument = replacement(regexp_node)
|
34
|
+
|
35
|
+
corrector.replace(regexp_node, "\"#{new_argument}\"")
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def determinist_regexp?(regexp_node)
|
42
|
+
DETERMINISTIC_REGEX.match?(regexp_node.source)
|
43
|
+
end
|
44
|
+
|
45
|
+
def replacement(regexp_node)
|
46
|
+
regexp_content = regexp_node.content
|
47
|
+
stack = []
|
48
|
+
chars = regexp_content.chars.each_with_object([]) do |char, strings|
|
49
|
+
if stack.empty? && char == '\\'
|
50
|
+
stack.push(char)
|
51
|
+
else
|
52
|
+
strings << "#{stack.pop}#{char}"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
chars.map do |char|
|
56
|
+
char = char.dup
|
57
|
+
char.delete!('\\') unless STR_SPECIAL_CHARS.include?(char)
|
58
|
+
char
|
59
|
+
end.join
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -150,7 +150,9 @@ module RuboCop
|
|
150
150
|
replacement = build_good_method(init, block_pass)
|
151
151
|
|
152
152
|
corrector.remove(sum_range)
|
153
|
-
|
153
|
+
|
154
|
+
dot = '.' if map.receiver
|
155
|
+
corrector.replace(map_range, "#{dot}#{replacement}")
|
154
156
|
end
|
155
157
|
|
156
158
|
def sum_method_range(node)
|
@@ -228,7 +230,11 @@ module RuboCop
|
|
228
230
|
end
|
229
231
|
|
230
232
|
def method_call_with_args_range(node)
|
231
|
-
node.receiver
|
233
|
+
if (receiver = node.receiver)
|
234
|
+
receiver.source_range.end.join(node.source_range.end)
|
235
|
+
else
|
236
|
+
node.source_range
|
237
|
+
end
|
232
238
|
end
|
233
239
|
end
|
234
240
|
end
|
@@ -28,9 +28,11 @@ require_relative 'performance/open_struct'
|
|
28
28
|
require_relative 'performance/range_include'
|
29
29
|
require_relative 'performance/io_readlines'
|
30
30
|
require_relative 'performance/redundant_block_call'
|
31
|
+
require_relative 'performance/redundant_equality_comparison_block'
|
31
32
|
require_relative 'performance/redundant_match'
|
32
33
|
require_relative 'performance/redundant_merge'
|
33
34
|
require_relative 'performance/redundant_sort_block'
|
35
|
+
require_relative 'performance/redundant_split_regexp_argument'
|
34
36
|
require_relative 'performance/redundant_string_chars'
|
35
37
|
require_relative 'performance/regexp_match'
|
36
38
|
require_relative 'performance/reverse_each'
|
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.
|
4
|
+
version: 1.10.1
|
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-
|
13
|
+
date: 2021-03-01 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rubocop
|
@@ -88,9 +88,11 @@ files:
|
|
88
88
|
- lib/rubocop/cop/performance/open_struct.rb
|
89
89
|
- lib/rubocop/cop/performance/range_include.rb
|
90
90
|
- lib/rubocop/cop/performance/redundant_block_call.rb
|
91
|
+
- lib/rubocop/cop/performance/redundant_equality_comparison_block.rb
|
91
92
|
- lib/rubocop/cop/performance/redundant_match.rb
|
92
93
|
- lib/rubocop/cop/performance/redundant_merge.rb
|
93
94
|
- lib/rubocop/cop/performance/redundant_sort_block.rb
|
95
|
+
- lib/rubocop/cop/performance/redundant_split_regexp_argument.rb
|
94
96
|
- lib/rubocop/cop/performance/redundant_string_chars.rb
|
95
97
|
- lib/rubocop/cop/performance/regexp_match.rb
|
96
98
|
- lib/rubocop/cop/performance/reverse_each.rb
|
@@ -109,15 +111,15 @@ files:
|
|
109
111
|
- lib/rubocop/performance.rb
|
110
112
|
- lib/rubocop/performance/inject.rb
|
111
113
|
- lib/rubocop/performance/version.rb
|
112
|
-
homepage: https://github.com/rubocop
|
114
|
+
homepage: https://github.com/rubocop/rubocop-performance
|
113
115
|
licenses:
|
114
116
|
- MIT
|
115
117
|
metadata:
|
116
118
|
homepage_uri: https://docs.rubocop.org/rubocop-performance/
|
117
|
-
changelog_uri: https://github.com/rubocop
|
118
|
-
source_code_uri: https://github.com/rubocop
|
119
|
-
documentation_uri: https://docs.rubocop.org/rubocop-performance/1.
|
120
|
-
bug_tracker_uri: https://github.com/rubocop
|
119
|
+
changelog_uri: https://github.com/rubocop/rubocop-performance/blob/master/CHANGELOG.md
|
120
|
+
source_code_uri: https://github.com/rubocop/rubocop-performance/
|
121
|
+
documentation_uri: https://docs.rubocop.org/rubocop-performance/1.10/
|
122
|
+
bug_tracker_uri: https://github.com/rubocop/rubocop-performance/issues
|
121
123
|
post_install_message:
|
122
124
|
rdoc_options: []
|
123
125
|
require_paths:
|
@@ -133,7 +135,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
133
135
|
- !ruby/object:Gem::Version
|
134
136
|
version: '0'
|
135
137
|
requirements: []
|
136
|
-
rubygems_version: 3.2.
|
138
|
+
rubygems_version: 3.2.12
|
137
139
|
signing_key:
|
138
140
|
specification_version: 4
|
139
141
|
summary: Automatic performance checking tool for Ruby code.
|