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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 5e13aa59742e803b8445a8149c382c50fdbaab1d
4
- data.tar.gz: 55d59fd7bb03179a9055e46613a3d1f2d2888967
2
+ SHA256:
3
+ metadata.gz: 111d420207542c8522d9f34b5b8bf24356572b5fbcf0c11dfcb1e7f738a4c76f
4
+ data.tar.gz: 97632031f51e154320bc3d585da448740596436882b67277f1b5d26ddfe55fba
5
5
  SHA512:
6
- metadata.gz: 01a28951033ec2b751828d6df2a80f63a5a2d9e9d9576a2228c12b645087b2a631c3676757bd5037e3eecc22d89a7ef28765194545393210a9068da92931d065
7
- data.tar.gz: 79b46ec046a4c1bade7e1e9dd07a5fd892f25280565adb6a91d8dddcce3931722cecf93fb72d4d0e32b7d40441829d26883973b11b5139389b6cebf91bdca435
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/projects/performance/).
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
 
@@ -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: '0.44'
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: '0.44'
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
- def literal_at_start?(regex_str)
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
- regex_str =~ /\A(\\A|\^)(?:#{Util::LITERAL_REGEX})+\z/
38
+ /\A\^(?:#{Util::LITERAL_REGEX})+\z/.match?(regex_str)
15
39
  end
16
40
 
17
- def literal_at_end?(regex_str)
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
- regex_str =~ /\A(?:#{Util::LITERAL_REGEX})+(\\z|\$)\z/
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
- # The `delete_prefix('prefix')` method is faster than
12
- # `gsub(/\Aprefix/, '')`.
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
- # str.gsub(/^prefix/, '')
20
- # str.gsub!(/^prefix/, '')
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 :gsub_method?, <<~PATTERN
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
- gsub_method?(node) do |_, bad_method, _, replace_string|
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
- gsub_method?(node) do |receiver, bad_method, regexp_str, _|
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
- corrector.replace(node, new_code)
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
- # The `delete_suffix('suffix')` method is faster than
12
- # `gsub(/suffix\z/, '')`.
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
- # str.gsub(/suffix$/, '')
20
- # str.gsub!(/suffix$/, '')
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 :gsub_method?, <<~PATTERN
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
- gsub_method?(node) do |_, bad_method, _, replace_string|
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
- gsub_method?(node) do |receiver, bad_method, regexp_str, _|
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
- corrector.replace(node, new_code)
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
- # would suffice.
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
- # `String#start_with?` would suffice.
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
- # Note: `String.new` (without operator) is not exactly the same as `+''`.
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.
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Performance
5
5
  module Version
6
- STRING = '1.6.0'
6
+ STRING = '1.6.1'
7
7
  end
8
8
  end
9
9
  end
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.0
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-21 00:00:00.000000000 Z
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/projects/performance/
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/projects/performance/
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
- rubyforge_project:
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.