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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 30b8495304f86e7ef0e9a7f11e12a30ab7986fb4b12cb1921870f31a1b37a42f
4
- data.tar.gz: 1863b8766efff5dd99b2e4f2dbb4e16191f223d12dbfd51826a837f1f75eef08
3
+ metadata.gz: 026fa40bed33c9e7867599f1024ddf6c1ab430b00beae5f5ec52d9b32f5adef9
4
+ data.tar.gz: d0997dd1a5255e217f5faf2adc4f27b64a43266ff24264aa80307b474cbfa936
5
5
  SHA512:
6
- metadata.gz: a6071b0e37b9a9683f1992b88b36e0911004e0ec8fc4b41f78ba569ce396d96840acb0eff937d519d132917dec1b0a5af9fe4d1563d743e293ee78239a59b13f
7
- data.tar.gz: 74c457f9d7f7ef240a2fa483100ff1120fc4edba7bb64e999f78a85e106621cba4ddef1a2dae7f375f9541d021a0fa08f054edf83ebd1646423d214b4677e212
6
+ metadata.gz: 7a09ace7478bf3d87dc35897bb677c802c6b191ce0206e1b94e04826091ce8075ad9f267cd7805cd68ba3476c679e3cdb59c219fd71760ac4756c26a209c51bc
7
+ data.tar.gz: f9ccef454d4c9ff9a8d67db5276d2249d03a2882b169abfc5d4bacc28f9f09391edb15100750480c354fe9cc161463156169f216d482c9504f7d6a17da524a0c
data/LICENSE.txt CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2012-20 Bozhidar Batsov
1
+ Copyright (c) 2012-21 Bozhidar Batsov
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -1,9 +1,9 @@
1
1
  # RuboCop Performance
2
2
 
3
3
  [![Gem Version](https://badge.fury.io/rb/rubocop-performance.svg)](https://badge.fury.io/rb/rubocop-performance)
4
- [![CircleCI](https://circleci.com/gh/rubocop-hq/rubocop-performance.svg?style=svg)](https://circleci.com/gh/rubocop-hq/rubocop-performance)
4
+ [![CircleCI](https://circleci.com/gh/rubocop/rubocop-performance.svg?style=svg)](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-hq/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-hq/rubocop-performance/pull/175#issuecomment-731892717
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.6'
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.6'
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-hq/rubocop/issues/4658
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-hq/rubocop-performance/pull/175#issuecomment-731892717
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
- (send nil? _) :bind
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.loc.end.end_pos
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 reuse that
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 within_const_assignment?(node) ||
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 within_const_assignment?(node)
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
- corrector.replace(map_range, ".#{replacement}")
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.source_range.end.join(node.source_range.end)
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'
@@ -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.9.2'
7
+ STRING = '1.10.1'
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.9.2
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-01-01 00:00:00.000000000 Z
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-hq/rubocop-performance
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-hq/rubocop-performance/blob/master/CHANGELOG.md
118
- source_code_uri: https://github.com/rubocop-hq/rubocop-performance/
119
- documentation_uri: https://docs.rubocop.org/rubocop-performance/1.9/
120
- bug_tracker_uri: https://github.com/rubocop-hq/rubocop-performance/issues
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.3
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.