rubocop-performance 1.10.2 → 1.11.0

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: 739dfb0dfbef0fa9962b144cb8cb3c600b801a86adc11877898a8eba957a2f39
4
- data.tar.gz: 0c5f89ad71bbe81a9c9e42c418401039c9dc0f2ede40fd54c3ba1bc4955011f9
3
+ metadata.gz: f7398f6e66937ee06d17e56c52ebe2858d26fcaf0a91d00d0c90caccbd1722b6
4
+ data.tar.gz: ab180bb4e81913bdabd470b04264e91b9687edde72f6f6d126e9918a11f361ca
5
5
  SHA512:
6
- metadata.gz: 07cb8c4fc7d80cac74841d9c8bdde26397c4e4273d2ef80b805388020c17cf6820c497a8ea4bfc4a39ca93f538fc2b642399e9fdb1acc401e2e0dad1bf5596d8
7
- data.tar.gz: 74696267b3ad0b9ab49aeacfab1de661ab22140a5cea173caa82ddd206159dadc214b996812a5521d1f912c44dfa84cca822d5159c2d8b45426fe1aa55d00896
6
+ metadata.gz: 5ae6caa06f44418aab93a55378a7727e48dde52eaf49c0e70e6e84ed01c62210048dc9c5cbe826bffbc0b7b85a779084517828350f50f76f88759f291385bdef
7
+ data.tar.gz: e9a63b027c140d453648376871ab24f5192004971239aa8b06ad5f73b3da917a7b70923d8ac161fc3a10d352a167ac55577136c05f8dfd12a78e4c0c08acfbc3
data/README.md CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  [![Gem Version](https://badge.fury.io/rb/rubocop-performance.svg)](https://badge.fury.io/rb/rubocop-performance)
4
4
  [![CircleCI](https://circleci.com/gh/rubocop/rubocop-performance.svg?style=svg)](https://circleci.com/gh/rubocop/rubocop-performance)
5
+ [![Discord](https://img.shields.io/badge/chat-on%20discord-7289da.svg?sanitize=true)](https://discord.gg/wJjWvGRDmm)
5
6
 
6
7
  Performance optimization analysis for your projects, as an extension to [RuboCop](https://github.com/rubocop/rubocop).
7
8
 
data/config/default.yml CHANGED
@@ -174,6 +174,12 @@ Performance/IoReadlines:
174
174
  Enabled: false
175
175
  VersionAdded: '1.7'
176
176
 
177
+ Performance/MapCompact:
178
+ Description: 'Use `filter_map` instead of `collection.map(&:do_something).compact`.'
179
+ Enabled: pending
180
+ SafeAutoCorrect: false
181
+ VersionAdded: '1.11'
182
+
177
183
  Performance/MethodObjectAsBlock:
178
184
  Description: 'Use block explicitly instead of block-passing a method object.'
179
185
  Reference: 'https://github.com/JuanitoFatas/fast-ruby#normal-way-to-apply-method-vs-method-code'
@@ -220,7 +226,9 @@ Performance/RedundantMerge:
220
226
  Description: 'Use Hash#[]=, rather than Hash#merge! with a single key-value pair.'
221
227
  Reference: 'https://github.com/JuanitoFatas/fast-ruby#hashmerge-vs-hash-code'
222
228
  Enabled: true
229
+ Safe: false
223
230
  VersionAdded: '0.36'
231
+ VersionChanged: '1.11'
224
232
  # Max number of key-value pairs to consider an offense
225
233
  MaxKeyValuePairs: 2
226
234
 
@@ -258,6 +266,11 @@ Performance/ReverseFirst:
258
266
  Enabled: 'pending'
259
267
  VersionAdded: '1.7'
260
268
 
269
+ Performance/SelectMap:
270
+ Description: 'Use `filter_map` instead of `ary.select(&:foo).map(&:bar)`.'
271
+ Enabled: false
272
+ VersionAdded: '1.11'
273
+
261
274
  Performance/Size:
262
275
  Description: >-
263
276
  Use `size` instead of `count` for counting
@@ -0,0 +1,7 @@
1
+ #
2
+ # Configuration for obsoletion.
3
+ #
4
+ # See: https://docs.rubocop.org/rubocop/extensions.html#config-obsoletions
5
+ #
6
+ extracted:
7
+ Performance/*: ~
@@ -63,6 +63,8 @@ module RuboCop
63
63
 
64
64
  def on_send(node)
65
65
  chain_array_allocation?(node) do |fm, sm|
66
+ return if node.each_descendant(:send).any? { |descendant| descendant.method?(:lazy) }
67
+
66
68
  range = range_between(node.loc.dot.begin_pos, node.source_range.end_pos)
67
69
 
68
70
  add_offense(range, message: format(MSG, method: fm, second_method: sm))
@@ -3,7 +3,8 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Performance
6
- # This cop is used to identify usages of
6
+ # This cop is used to identify usages of `map { ... }.flatten` and
7
+ # change them to use `flat_map { ... }` instead.
7
8
  #
8
9
  # @example
9
10
  # # bad
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Performance
6
+ # In Ruby 2.7, `Enumerable#filter_map` has been added.
7
+ #
8
+ # This cop identifies places where `map { ... }.compact` can be replaced by `filter_map`.
9
+ # It is marked as unsafe auto-correction by default because `map { ... }.compact`
10
+ # that is not compatible with `filter_map`.
11
+ #
12
+ # [source,ruby]
13
+ # ----
14
+ # [true, false, nil].compact #=> [true, false]
15
+ # [true, false, nil].filter_map(&:itself) #=> [true]
16
+ # ----
17
+ #
18
+ # @example
19
+ # # bad
20
+ # ary.map(&:foo).compact
21
+ # ary.collect(&:foo).compact
22
+ #
23
+ # # good
24
+ # ary.filter_map(&:foo)
25
+ # ary.map(&:foo).compact!
26
+ #
27
+ class MapCompact < Base
28
+ include RangeHelp
29
+ extend AutoCorrector
30
+ extend TargetRubyVersion
31
+
32
+ MSG = 'Use `filter_map` instead.'
33
+ RESTRICT_ON_SEND = %i[compact].freeze
34
+
35
+ minimum_target_ruby_version 2.7
36
+
37
+ def_node_matcher :map_compact, <<~PATTERN
38
+ {
39
+ (send
40
+ $(send _ {:map :collect}
41
+ (block_pass
42
+ (sym _))) _)
43
+ (send
44
+ (block
45
+ $(send _ {:map :collect})
46
+ (args ...) _) _)
47
+ }
48
+ PATTERN
49
+
50
+ def on_send(node)
51
+ return unless (map_node = map_compact(node))
52
+
53
+ compact_loc = node.loc
54
+ range = range_between(map_node.loc.selector.begin_pos, compact_loc.selector.end_pos)
55
+
56
+ add_offense(range) do |corrector|
57
+ corrector.replace(map_node.loc.selector, 'filter_map')
58
+ corrector.remove(compact_loc.dot)
59
+ corrector.remove(compact_loc.selector)
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
@@ -8,6 +8,9 @@ module RuboCop
8
8
  # You can set the maximum number of key-value pairs to consider
9
9
  # an offense with `MaxKeyValuePairs`.
10
10
  #
11
+ # This cop is marked as unsafe because RuboCop cannot determine if the
12
+ # receiver of `merge!` is actually a hash or not.
13
+ #
11
14
  # @example
12
15
  # # bad
13
16
  # hash.merge!(a: 1)
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Performance
6
+ # In Ruby 2.7, `Enumerable#filter_map` has been added.
7
+ #
8
+ # This cop identifies places where `select.map` can be replaced by `filter_map`.
9
+ #
10
+ # @example
11
+ # # bad
12
+ # ary.select(&:foo).map(&:bar)
13
+ # ary.filter(&:foo).map(&:bar)
14
+ #
15
+ # # good
16
+ # ary.filter_map { |o| o.bar if o.foo }
17
+ #
18
+ class SelectMap < Base
19
+ include RangeHelp
20
+ extend TargetRubyVersion
21
+
22
+ minimum_target_ruby_version 2.7
23
+
24
+ MSG = 'Use `filter_map` instead of `%<method_name>s.map`.'
25
+ RESTRICT_ON_SEND = %i[select filter].freeze
26
+
27
+ def_node_matcher :bad_method?, <<~PATTERN
28
+ (send nil? :bad_method ...)
29
+ PATTERN
30
+
31
+ def on_send(node)
32
+ return if (first_argument = node.first_argument) && !first_argument.block_pass_type?
33
+ return unless (send_node = map_method_candidate(node))
34
+ return unless send_node.method?(:map)
35
+
36
+ map_method = send_node.parent&.block_type? ? send_node.parent : send_node
37
+
38
+ range = offense_range(node, map_method)
39
+ add_offense(range, message: format(MSG, method_name: node.method_name))
40
+ end
41
+
42
+ private
43
+
44
+ def map_method_candidate(node)
45
+ return unless (parent = node.parent)
46
+
47
+ if parent.block_type? && parent.parent&.send_type?
48
+ parent.parent
49
+ elsif parent.send_type?
50
+ parent
51
+ end
52
+ end
53
+
54
+ def offense_range(node, map_method)
55
+ range_between(node.loc.selector.begin_pos, map_method.loc.expression.end_pos)
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -23,6 +23,7 @@ require_relative 'performance/end_with'
23
23
  require_relative 'performance/fixed_size'
24
24
  require_relative 'performance/flat_map'
25
25
  require_relative 'performance/inefficient_hash_search'
26
+ require_relative 'performance/map_compact'
26
27
  require_relative 'performance/method_object_as_block'
27
28
  require_relative 'performance/open_struct'
28
29
  require_relative 'performance/range_include'
@@ -37,6 +38,7 @@ require_relative 'performance/redundant_string_chars'
37
38
  require_relative 'performance/regexp_match'
38
39
  require_relative 'performance/reverse_each'
39
40
  require_relative 'performance/reverse_first'
41
+ require_relative 'performance/select_map'
40
42
  require_relative 'performance/size'
41
43
  require_relative 'performance/sort_reverse'
42
44
  require_relative 'performance/squeeze'
@@ -8,5 +8,7 @@ module RuboCop
8
8
  CONFIG = YAML.safe_load(CONFIG_DEFAULT.read).freeze
9
9
 
10
10
  private_constant(:CONFIG_DEFAULT, :PROJECT_ROOT)
11
+
12
+ ::RuboCop::ConfigObsoletion.files << PROJECT_ROOT.join('config', 'obsoletion.yml')
11
13
  end
12
14
  end
@@ -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.10.2'
7
+ STRING = '1.11.0'
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.10.2
4
+ version: 1.11.0
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-03-22 00:00:00.000000000 Z
13
+ date: 2021-04-21 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rubocop
@@ -18,7 +18,7 @@ dependencies:
18
18
  requirements:
19
19
  - - ">="
20
20
  - !ruby/object:Gem::Version
21
- version: 0.90.0
21
+ version: 1.7.0
22
22
  - - "<"
23
23
  - !ruby/object:Gem::Version
24
24
  version: '2.0'
@@ -28,7 +28,7 @@ dependencies:
28
28
  requirements:
29
29
  - - ">="
30
30
  - !ruby/object:Gem::Version
31
- version: 0.90.0
31
+ version: 1.7.0
32
32
  - - "<"
33
33
  - !ruby/object:Gem::Version
34
34
  version: '2.0'
@@ -59,6 +59,7 @@ files:
59
59
  - LICENSE.txt
60
60
  - README.md
61
61
  - config/default.yml
62
+ - config/obsoletion.yml
62
63
  - lib/rubocop-performance.rb
63
64
  - lib/rubocop/cop/mixin/regexp_metacharacter.rb
64
65
  - lib/rubocop/cop/mixin/sort_block.rb
@@ -84,6 +85,7 @@ files:
84
85
  - lib/rubocop/cop/performance/flat_map.rb
85
86
  - lib/rubocop/cop/performance/inefficient_hash_search.rb
86
87
  - lib/rubocop/cop/performance/io_readlines.rb
88
+ - lib/rubocop/cop/performance/map_compact.rb
87
89
  - lib/rubocop/cop/performance/method_object_as_block.rb
88
90
  - lib/rubocop/cop/performance/open_struct.rb
89
91
  - lib/rubocop/cop/performance/range_include.rb
@@ -97,6 +99,7 @@ files:
97
99
  - lib/rubocop/cop/performance/regexp_match.rb
98
100
  - lib/rubocop/cop/performance/reverse_each.rb
99
101
  - lib/rubocop/cop/performance/reverse_first.rb
102
+ - lib/rubocop/cop/performance/select_map.rb
100
103
  - lib/rubocop/cop/performance/size.rb
101
104
  - lib/rubocop/cop/performance/sort_reverse.rb
102
105
  - lib/rubocop/cop/performance/squeeze.rb
@@ -118,7 +121,7 @@ metadata:
118
121
  homepage_uri: https://docs.rubocop.org/rubocop-performance/
119
122
  changelog_uri: https://github.com/rubocop/rubocop-performance/blob/master/CHANGELOG.md
120
123
  source_code_uri: https://github.com/rubocop/rubocop-performance/
121
- documentation_uri: https://docs.rubocop.org/rubocop-performance/1.10/
124
+ documentation_uri: https://docs.rubocop.org/rubocop-performance/1.11/
122
125
  bug_tracker_uri: https://github.com/rubocop/rubocop-performance/issues
123
126
  post_install_message:
124
127
  rdoc_options: []
@@ -128,7 +131,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
128
131
  requirements:
129
132
  - - ">="
130
133
  - !ruby/object:Gem::Version
131
- version: 2.4.0
134
+ version: 2.5.0
132
135
  required_rubygems_version: !ruby/object:Gem::Requirement
133
136
  requirements:
134
137
  - - ">="