rubocop-performance 1.10.2 → 1.11.0

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
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
  - - ">="