rubocop-performance 1.6.0 → 1.6.1
Sign up to get free protection for your applications and to get access to all the features.
- 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.
|