rubocop-performance 1.6.0 → 1.6.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 +5 -5
- data/README.md +1 -1
- data/config/default.yml +6 -2
- data/lib/rubocop/cop/mixin/regexp_metacharacter.rb +39 -4
- data/lib/rubocop/cop/performance/delete_prefix.rb +35 -11
- data/lib/rubocop/cop/performance/delete_suffix.rb +35 -11
- data/lib/rubocop/cop/performance/end_with.rb +21 -4
- data/lib/rubocop/cop/performance/start_with.rb +21 -4
- data/lib/rubocop/cop/performance/unfreeze_string.rb +1 -1
- data/lib/rubocop/performance/version.rb +1 -1
- metadata +5 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 111d420207542c8522d9f34b5b8bf24356572b5fbcf0c11dfcb1e7f738a4c76f
|
4
|
+
data.tar.gz: 97632031f51e154320bc3d585da448740596436882b67277f1b5d26ddfe55fba
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a36e6950e6fe7847303c87862df76767d32c4f68640c229ad4ceb6115d4ae2093be18a8296c2e49324c67e8eb06dd99db42f8823586f1b572e10a74693b831d1
|
7
|
+
data.tar.gz: 782352b1a7c420ac3c5498aeff749577e6280fb35d6e36844ae875511e9b6b44becfd9a2789d1b4c672cb71a91b8ab1cc63c89ec41abda8d1f34f1dacd26a07c
|
data/README.md
CHANGED
@@ -74,7 +74,7 @@ Performance/Size:
|
|
74
74
|
|
75
75
|
## Documentation
|
76
76
|
|
77
|
-
You can read a lot more about RuboCop Performance in its [official docs](https://docs.rubocop.org/
|
77
|
+
You can read a lot more about RuboCop Performance in its [official docs](https://docs.rubocop.org/rubocop-performance/).
|
78
78
|
|
79
79
|
## Contributing
|
80
80
|
|
data/config/default.yml
CHANGED
@@ -58,11 +58,13 @@ Performance/Count:
|
|
58
58
|
Performance/DeletePrefix:
|
59
59
|
Description: 'Use `delete_prefix` instead of `gsub`.'
|
60
60
|
Enabled: true
|
61
|
+
SafeMultiline: true
|
61
62
|
VersionAdded: '1.6'
|
62
63
|
|
63
64
|
Performance/DeleteSuffix:
|
64
65
|
Description: 'Use `delete_suffix` instead of `gsub`.'
|
65
66
|
Enabled: true
|
67
|
+
SafeMultiline: true
|
66
68
|
VersionAdded: '1.6'
|
67
69
|
|
68
70
|
Performance/Detect:
|
@@ -99,8 +101,9 @@ Performance/EndWith:
|
|
99
101
|
SafeAutoCorrect: false
|
100
102
|
AutoCorrect: false
|
101
103
|
Enabled: true
|
104
|
+
SafeMultiline: true
|
102
105
|
VersionAdded: '0.36'
|
103
|
-
VersionChanged: '
|
106
|
+
VersionChanged: '1.6'
|
104
107
|
|
105
108
|
Performance/FixedSize:
|
106
109
|
Description: 'Do not compute the size of statically sized objects except in constants.'
|
@@ -193,8 +196,9 @@ Performance/StartWith:
|
|
193
196
|
SafeAutoCorrect: false
|
194
197
|
AutoCorrect: false
|
195
198
|
Enabled: true
|
199
|
+
SafeMultiline: true
|
196
200
|
VersionAdded: '0.36'
|
197
|
-
VersionChanged: '
|
201
|
+
VersionChanged: '1.6'
|
198
202
|
|
199
203
|
Performance/StringReplacement:
|
200
204
|
Description: >-
|
@@ -4,21 +4,52 @@ module RuboCop
|
|
4
4
|
module Cop
|
5
5
|
# Common functionality for handling regexp metacharacters.
|
6
6
|
module RegexpMetacharacter
|
7
|
-
|
7
|
+
private
|
8
|
+
|
9
|
+
def literal_at_start?(regexp)
|
10
|
+
return true if literal_at_start_with_backslash_a?(regexp)
|
11
|
+
|
12
|
+
!safe_multiline? && literal_at_start_with_caret?(regexp)
|
13
|
+
end
|
14
|
+
|
15
|
+
def literal_at_end?(regexp)
|
16
|
+
return true if literal_at_end_with_backslash_z?(regexp)
|
17
|
+
|
18
|
+
!safe_multiline? && literal_at_end_with_dollar?(regexp)
|
19
|
+
end
|
20
|
+
|
21
|
+
def literal_at_start_with_backslash_a?(regex_str)
|
22
|
+
# is this regexp 'literal' in the sense of only matching literal
|
23
|
+
# chars, rather than using metachars like `.` and `*` and so on?
|
24
|
+
# also, is it anchored at the start of the string?
|
25
|
+
# (tricky: \s, \d, and so on are metacharacters, but other characters
|
26
|
+
# escaped with a slash are just literals. LITERAL_REGEX takes all
|
27
|
+
# that into account.)
|
28
|
+
/\A\\A(?:#{Util::LITERAL_REGEX})+\z/.match?(regex_str)
|
29
|
+
end
|
30
|
+
|
31
|
+
def literal_at_start_with_caret?(regex_str)
|
8
32
|
# is this regexp 'literal' in the sense of only matching literal
|
9
33
|
# chars, rather than using metachars like `.` and `*` and so on?
|
10
34
|
# also, is it anchored at the start of the string?
|
11
35
|
# (tricky: \s, \d, and so on are metacharacters, but other characters
|
12
36
|
# escaped with a slash are just literals. LITERAL_REGEX takes all
|
13
37
|
# that into account.)
|
14
|
-
|
38
|
+
/\A\^(?:#{Util::LITERAL_REGEX})+\z/.match?(regex_str)
|
15
39
|
end
|
16
40
|
|
17
|
-
def
|
41
|
+
def literal_at_end_with_backslash_z?(regex_str)
|
18
42
|
# is this regexp 'literal' in the sense of only matching literal
|
19
43
|
# chars, rather than using metachars like . and * and so on?
|
20
44
|
# also, is it anchored at the end of the string?
|
21
|
-
|
45
|
+
/\A(?:#{Util::LITERAL_REGEX})+\\z\z/.match?(regex_str)
|
46
|
+
end
|
47
|
+
|
48
|
+
def literal_at_end_with_dollar?(regex_str)
|
49
|
+
# is this regexp 'literal' in the sense of only matching literal
|
50
|
+
# chars, rather than using metachars like . and * and so on?
|
51
|
+
# also, is it anchored at the end of the string?
|
52
|
+
/\A(?:#{Util::LITERAL_REGEX})+\$\z/.match?(regex_str)
|
22
53
|
end
|
23
54
|
|
24
55
|
def drop_start_metacharacter(regexp_string)
|
@@ -36,6 +67,10 @@ module RuboCop
|
|
36
67
|
regexp_string.chop # drop `$` anchor
|
37
68
|
end
|
38
69
|
end
|
70
|
+
|
71
|
+
def safe_multiline?
|
72
|
+
cop_config.fetch('SafeMultiline', true)
|
73
|
+
end
|
39
74
|
end
|
40
75
|
end
|
41
76
|
end
|
@@ -5,24 +5,44 @@ module RuboCop
|
|
5
5
|
module Performance
|
6
6
|
# In Ruby 2.5, `String#delete_prefix` has been added.
|
7
7
|
#
|
8
|
-
# This cop identifies places where `gsub(/\Aprefix/, '')`
|
8
|
+
# This cop identifies places where `gsub(/\Aprefix/, '')` and `sub(/\Aprefix/, '')`
|
9
9
|
# can be replaced by `delete_prefix('prefix')`.
|
10
10
|
#
|
11
|
-
#
|
12
|
-
# `
|
11
|
+
# This cop has `SafeMultiline` configuration option that `true` by default because
|
12
|
+
# `^prefix` is unsafe as it will behave incompatible with `delete_prefix`
|
13
|
+
# for receiver is multiline string.
|
14
|
+
#
|
15
|
+
# The `delete_prefix('prefix')` method is faster than `gsub(/\Aprefix/, '')`.
|
13
16
|
#
|
14
17
|
# @example
|
15
18
|
#
|
16
19
|
# # bad
|
17
20
|
# str.gsub(/\Aprefix/, '')
|
18
21
|
# str.gsub!(/\Aprefix/, '')
|
19
|
-
#
|
20
|
-
# str.
|
22
|
+
#
|
23
|
+
# str.sub(/\Aprefix/, '')
|
24
|
+
# str.sub!(/\Aprefix/, '')
|
21
25
|
#
|
22
26
|
# # good
|
23
27
|
# str.delete_prefix('prefix')
|
24
28
|
# str.delete_prefix!('prefix')
|
25
29
|
#
|
30
|
+
# @example SafeMultiline: true (default)
|
31
|
+
#
|
32
|
+
# # good
|
33
|
+
# str.gsub(/^prefix/, '')
|
34
|
+
# str.gsub!(/^prefix/, '')
|
35
|
+
# str.sub(/^prefix/, '')
|
36
|
+
# str.sub!(/^prefix/, '')
|
37
|
+
#
|
38
|
+
# @example SafeMultiline: false
|
39
|
+
#
|
40
|
+
# # bad
|
41
|
+
# str.gsub(/^prefix/, '')
|
42
|
+
# str.gsub!(/^prefix/, '')
|
43
|
+
# str.sub(/^prefix/, '')
|
44
|
+
# str.sub!(/^prefix/, '')
|
45
|
+
#
|
26
46
|
class DeletePrefix < Cop
|
27
47
|
extend TargetRubyVersion
|
28
48
|
include RegexpMetacharacter
|
@@ -33,15 +53,17 @@ module RuboCop
|
|
33
53
|
|
34
54
|
PREFERRED_METHODS = {
|
35
55
|
gsub: :delete_prefix,
|
36
|
-
gsub!: :delete_prefix
|
56
|
+
gsub!: :delete_prefix!,
|
57
|
+
sub: :delete_prefix,
|
58
|
+
sub!: :delete_prefix!
|
37
59
|
}.freeze
|
38
60
|
|
39
|
-
def_node_matcher :
|
40
|
-
(send $!nil? ${:gsub :gsub!} (regexp (str $#literal_at_start?) (regopt)) (str $_))
|
61
|
+
def_node_matcher :delete_prefix_candidate?, <<~PATTERN
|
62
|
+
(send $!nil? ${:gsub :gsub! :sub :sub!} (regexp (str $#literal_at_start?) (regopt)) (str $_))
|
41
63
|
PATTERN
|
42
64
|
|
43
65
|
def on_send(node)
|
44
|
-
|
66
|
+
delete_prefix_candidate?(node) do |_, bad_method, _, replace_string|
|
45
67
|
return unless replace_string.blank?
|
46
68
|
|
47
69
|
good_method = PREFERRED_METHODS[bad_method]
|
@@ -53,7 +75,7 @@ module RuboCop
|
|
53
75
|
end
|
54
76
|
|
55
77
|
def autocorrect(node)
|
56
|
-
|
78
|
+
delete_prefix_candidate?(node) do |receiver, bad_method, regexp_str, _|
|
57
79
|
lambda do |corrector|
|
58
80
|
good_method = PREFERRED_METHODS[bad_method]
|
59
81
|
regexp_str = drop_start_metacharacter(regexp_str)
|
@@ -62,7 +84,9 @@ module RuboCop
|
|
62
84
|
|
63
85
|
new_code = "#{receiver.source}.#{good_method}(#{string_literal})"
|
64
86
|
|
65
|
-
|
87
|
+
# TODO: `source_range` is no longer required when RuboCop 0.81 or lower support will be dropped.
|
88
|
+
# https://github.com/rubocop-hq/rubocop/commit/82eb350d2cba16
|
89
|
+
corrector.replace(node.source_range, new_code)
|
66
90
|
end
|
67
91
|
end
|
68
92
|
end
|
@@ -5,24 +5,44 @@ module RuboCop
|
|
5
5
|
module Performance
|
6
6
|
# In Ruby 2.5, `String#delete_suffix` has been added.
|
7
7
|
#
|
8
|
-
# This cop identifies places where `gsub(/suffix\z/, '')`
|
8
|
+
# This cop identifies places where `gsub(/suffix\z/, '')` and `sub(/suffix\z/, '')`
|
9
9
|
# can be replaced by `delete_suffix('suffix')`.
|
10
10
|
#
|
11
|
-
#
|
12
|
-
# `
|
11
|
+
# This cop has `SafeMultiline` configuration option that `true` by default because
|
12
|
+
# `suffix$` is unsafe as it will behave incompatible with `delete_suffix?`
|
13
|
+
# for receiver is multiline string.
|
14
|
+
#
|
15
|
+
# The `delete_suffix('suffix')` method is faster than `gsub(/suffix\z/, '')`.
|
13
16
|
#
|
14
17
|
# @example
|
15
18
|
#
|
16
19
|
# # bad
|
17
20
|
# str.gsub(/suffix\z/, '')
|
18
21
|
# str.gsub!(/suffix\z/, '')
|
19
|
-
#
|
20
|
-
# str.
|
22
|
+
#
|
23
|
+
# str.sub(/suffix\z/, '')
|
24
|
+
# str.sub!(/suffix\z/, '')
|
21
25
|
#
|
22
26
|
# # good
|
23
27
|
# str.delete_suffix('suffix')
|
24
28
|
# str.delete_suffix!('suffix')
|
25
29
|
#
|
30
|
+
# @example SafeMultiline: true (default)
|
31
|
+
#
|
32
|
+
# # good
|
33
|
+
# str.gsub(/suffix$/, '')
|
34
|
+
# str.gsub!(/suffix$/, '')
|
35
|
+
# str.sub(/suffix$/, '')
|
36
|
+
# str.sub!(/suffix$/, '')
|
37
|
+
#
|
38
|
+
# @example SafeMultiline: false
|
39
|
+
#
|
40
|
+
# # bad
|
41
|
+
# str.gsub(/suffix$/, '')
|
42
|
+
# str.gsub!(/suffix$/, '')
|
43
|
+
# str.sub(/suffix$/, '')
|
44
|
+
# str.sub!(/suffix$/, '')
|
45
|
+
#
|
26
46
|
class DeleteSuffix < Cop
|
27
47
|
extend TargetRubyVersion
|
28
48
|
include RegexpMetacharacter
|
@@ -33,15 +53,17 @@ module RuboCop
|
|
33
53
|
|
34
54
|
PREFERRED_METHODS = {
|
35
55
|
gsub: :delete_suffix,
|
36
|
-
gsub!: :delete_suffix
|
56
|
+
gsub!: :delete_suffix!,
|
57
|
+
sub: :delete_suffix,
|
58
|
+
sub!: :delete_suffix!
|
37
59
|
}.freeze
|
38
60
|
|
39
|
-
def_node_matcher :
|
40
|
-
(send $!nil? ${:gsub :gsub!} (regexp (str $#literal_at_end?) (regopt)) (str $_))
|
61
|
+
def_node_matcher :delete_suffix_candidate?, <<~PATTERN
|
62
|
+
(send $!nil? ${:gsub :gsub! :sub :sub!} (regexp (str $#literal_at_end?) (regopt)) (str $_))
|
41
63
|
PATTERN
|
42
64
|
|
43
65
|
def on_send(node)
|
44
|
-
|
66
|
+
delete_suffix_candidate?(node) do |_, bad_method, _, replace_string|
|
45
67
|
return unless replace_string.blank?
|
46
68
|
|
47
69
|
good_method = PREFERRED_METHODS[bad_method]
|
@@ -53,7 +75,7 @@ module RuboCop
|
|
53
75
|
end
|
54
76
|
|
55
77
|
def autocorrect(node)
|
56
|
-
|
78
|
+
delete_suffix_candidate?(node) do |receiver, bad_method, regexp_str, _|
|
57
79
|
lambda do |corrector|
|
58
80
|
good_method = PREFERRED_METHODS[bad_method]
|
59
81
|
regexp_str = drop_end_metacharacter(regexp_str)
|
@@ -62,7 +84,9 @@ module RuboCop
|
|
62
84
|
|
63
85
|
new_code = "#{receiver.source}.#{good_method}(#{string_literal})"
|
64
86
|
|
65
|
-
|
87
|
+
# TODO: `source_range` is no longer required when RuboCop 0.81 or lower support will be dropped.
|
88
|
+
# https://github.com/rubocop-hq/rubocop/commit/82eb350d2cba16
|
89
|
+
corrector.replace(node.source_range, new_code)
|
66
90
|
end
|
67
91
|
end
|
68
92
|
end
|
@@ -3,8 +3,11 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module Performance
|
6
|
-
# This cop identifies unnecessary use of a regex where `String#end_with?`
|
7
|
-
#
|
6
|
+
# This cop identifies unnecessary use of a regex where `String#end_with?` would suffice.
|
7
|
+
#
|
8
|
+
# This cop has `SafeMultiline` configuration option that `true` by default because
|
9
|
+
# `end$` is unsafe as it will behave incompatible with `end_with?`
|
10
|
+
# for receiver is multiline string.
|
8
11
|
#
|
9
12
|
# @example
|
10
13
|
# # bad
|
@@ -15,6 +18,22 @@ module RuboCop
|
|
15
18
|
# 'abc'.match(/bc\Z/)
|
16
19
|
# /bc\Z/.match('abc')
|
17
20
|
#
|
21
|
+
# # good
|
22
|
+
# 'abc'.end_with?('bc')
|
23
|
+
#
|
24
|
+
# @example SafeMultiline: true (default)
|
25
|
+
#
|
26
|
+
# # good
|
27
|
+
# 'abc'.match?(/bc$/)
|
28
|
+
# /bc$/.match?('abc')
|
29
|
+
# 'abc' =~ /bc$/
|
30
|
+
# /bc$/ =~ 'abc'
|
31
|
+
# 'abc'.match(/bc$/)
|
32
|
+
# /bc$/.match('abc')
|
33
|
+
#
|
34
|
+
# @example SafeMultiline: false
|
35
|
+
#
|
36
|
+
# # bad
|
18
37
|
# 'abc'.match?(/bc$/)
|
19
38
|
# /bc$/.match?('abc')
|
20
39
|
# 'abc' =~ /bc$/
|
@@ -22,8 +41,6 @@ module RuboCop
|
|
22
41
|
# 'abc'.match(/bc$/)
|
23
42
|
# /bc$/.match('abc')
|
24
43
|
#
|
25
|
-
# # good
|
26
|
-
# 'abc'.end_with?('bc')
|
27
44
|
class EndWith < Cop
|
28
45
|
include RegexpMetacharacter
|
29
46
|
|
@@ -3,8 +3,11 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module Performance
|
6
|
-
# This cop identifies unnecessary use of a regex where
|
7
|
-
#
|
6
|
+
# This cop identifies unnecessary use of a regex where `String#start_with?` would suffice.
|
7
|
+
#
|
8
|
+
# This cop has `SafeMultiline` configuration option that `true` by default because
|
9
|
+
# `^start` is unsafe as it will behave incompatible with `start_with?`
|
10
|
+
# for receiver is multiline string.
|
8
11
|
#
|
9
12
|
# @example
|
10
13
|
# # bad
|
@@ -15,6 +18,22 @@ module RuboCop
|
|
15
18
|
# 'abc'.match(/\Aab/)
|
16
19
|
# /\Aab/.match('abc')
|
17
20
|
#
|
21
|
+
# # good
|
22
|
+
# 'abc'.start_with?('ab')
|
23
|
+
#
|
24
|
+
# @example SafeMultiline: true (default)
|
25
|
+
#
|
26
|
+
# # good
|
27
|
+
# 'abc'.match?(/^ab/)
|
28
|
+
# /^ab/.match?('abc')
|
29
|
+
# 'abc' =~ /^ab/
|
30
|
+
# /^ab/ =~ 'abc'
|
31
|
+
# 'abc'.match(/^ab/)
|
32
|
+
# /^ab/.match('abc')
|
33
|
+
#
|
34
|
+
# @example SafeMultiline: false
|
35
|
+
#
|
36
|
+
# # bad
|
18
37
|
# 'abc'.match?(/^ab/)
|
19
38
|
# /^ab/.match?('abc')
|
20
39
|
# 'abc' =~ /^ab/
|
@@ -22,8 +41,6 @@ module RuboCop
|
|
22
41
|
# 'abc'.match(/^ab/)
|
23
42
|
# /^ab/.match('abc')
|
24
43
|
#
|
25
|
-
# # good
|
26
|
-
# 'abc'.start_with?('ab')
|
27
44
|
class StartWith < Cop
|
28
45
|
include RegexpMetacharacter
|
29
46
|
|
@@ -7,7 +7,7 @@ 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
|
-
#
|
10
|
+
# NOTE: `String.new` (without operator) is not exactly the same as `+''`.
|
11
11
|
# These differ in encoding. `String.new.encoding` is always `ASCII-8BIT`.
|
12
12
|
# However, `(+'').encoding` is the same as script encoding(e.g. `UTF-8`).
|
13
13
|
# So, if you expect `ASCII-8BIT` encoding, disable this cop.
|
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.6.
|
4
|
+
version: 1.6.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: 2020-05
|
13
|
+
date: 2020-06-05 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rubocop
|
@@ -91,10 +91,10 @@ homepage: https://github.com/rubocop-hq/rubocop-performance
|
|
91
91
|
licenses:
|
92
92
|
- MIT
|
93
93
|
metadata:
|
94
|
-
homepage_uri: https://docs.rubocop.org/
|
94
|
+
homepage_uri: https://docs.rubocop.org/rubocop-performance/
|
95
95
|
changelog_uri: https://github.com/rubocop-hq/rubocop-performance/blob/master/CHANGELOG.md
|
96
96
|
source_code_uri: https://github.com/rubocop-hq/rubocop-performance/
|
97
|
-
documentation_uri: https://docs.rubocop.org/
|
97
|
+
documentation_uri: https://docs.rubocop.org/rubocop-performance/
|
98
98
|
bug_tracker_uri: https://github.com/rubocop-hq/rubocop-performance/issues
|
99
99
|
post_install_message:
|
100
100
|
rdoc_options: []
|
@@ -111,8 +111,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
111
111
|
- !ruby/object:Gem::Version
|
112
112
|
version: '0'
|
113
113
|
requirements: []
|
114
|
-
|
115
|
-
rubygems_version: 2.6.14.4
|
114
|
+
rubygems_version: 3.1.3
|
116
115
|
signing_key:
|
117
116
|
specification_version: 4
|
118
117
|
summary: Automatic performance checking tool for Ruby code.
|