rubocop-performance 1.23.1 → 1.24.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 +4 -4
- data/README.md +7 -4
- data/config/default.yml +6 -0
- data/lib/rubocop/cop/performance/array_semi_infinite_range_slice.rb +2 -2
- data/lib/rubocop/cop/performance/case_when_splat.rb +20 -6
- data/lib/rubocop/cop/performance/chain_array_allocation.rb +4 -2
- data/lib/rubocop/cop/performance/collection_literal_in_loop.rb +2 -0
- data/lib/rubocop/cop/performance/fixed_size.rb +1 -1
- data/lib/rubocop/cop/performance/range_include.rb +1 -1
- data/lib/rubocop/cop/performance/redundant_match.rb +1 -1
- data/lib/rubocop/cop/performance/regexp_match.rb +1 -1
- data/lib/rubocop/cop/performance/times_map.rb +8 -8
- data/lib/rubocop/cop/performance/zip_without_block.rb +56 -0
- data/lib/rubocop/cop/performance_cops.rb +1 -0
- data/lib/rubocop/performance/plugin.rb +31 -0
- data/lib/rubocop/performance/version.rb +1 -1
- data/lib/rubocop/performance.rb +1 -8
- data/lib/rubocop-performance.rb +1 -4
- metadata +28 -9
- data/lib/rubocop/performance/inject.rb +0 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1b4cdc2536f76691be677a1e203a886fae5e170f550424bed14d579f39a87e75
|
4
|
+
data.tar.gz: 6ea02935a50fcdeb0b07d1a5d67c4414c71115019cb02dae4746c207f798cad6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7bc4f69ef0a5ca779626b29d0a7c5333bf135b29d06d1be009acd4e9ffaa368873cb9977a94e9c5d5f50cb1c000d9fa243b8557badbab00756469a0b6a366662
|
7
|
+
data.tar.gz: 47e7f03cf61d57a3f9bd8e3cdb79f722fdaa279d300d2de5532435c1231fa06c28b1a148ab31c7b62775d1449a284fc43cee4bd36bbd16b1065145f022c8f729
|
data/README.md
CHANGED
@@ -30,13 +30,13 @@ ways to do this:
|
|
30
30
|
Put this into your `.rubocop.yml`.
|
31
31
|
|
32
32
|
```yaml
|
33
|
-
|
33
|
+
plugins: rubocop-performance
|
34
34
|
```
|
35
35
|
|
36
36
|
Alternatively, use the following array notation when specifying multiple extensions.
|
37
37
|
|
38
38
|
```yaml
|
39
|
-
|
39
|
+
plugins:
|
40
40
|
- rubocop-other-extension
|
41
41
|
- rubocop-performance
|
42
42
|
```
|
@@ -44,10 +44,13 @@ require:
|
|
44
44
|
Now you can run `rubocop` and it will automatically load the RuboCop Performance
|
45
45
|
cops together with the standard cops.
|
46
46
|
|
47
|
+
> [!NOTE]
|
48
|
+
> The plugin system is supported in RuboCop 1.72+. In earlier versions, use `require` instead of `plugins`.
|
49
|
+
|
47
50
|
### Command line
|
48
51
|
|
49
52
|
```sh
|
50
|
-
$ rubocop --
|
53
|
+
$ rubocop --plugin rubocop-performance
|
51
54
|
```
|
52
55
|
|
53
56
|
### Rake task
|
@@ -56,7 +59,7 @@ $ rubocop --require rubocop-performance
|
|
56
59
|
require 'rubocop/rake_task'
|
57
60
|
|
58
61
|
RuboCop::RakeTask.new do |task|
|
59
|
-
task.
|
62
|
+
task.plugins << 'rubocop-performance'
|
60
63
|
end
|
61
64
|
```
|
62
65
|
|
data/config/default.yml
CHANGED
@@ -381,3 +381,9 @@ Performance/UriDefaultParser:
|
|
381
381
|
Description: 'Use `URI::DEFAULT_PARSER` instead of `URI::Parser.new`.'
|
382
382
|
Enabled: true
|
383
383
|
VersionAdded: '0.50'
|
384
|
+
|
385
|
+
Performance/ZipWithoutBlock:
|
386
|
+
Description: 'Checks for `map { |id| [id] }` and suggests replacing it with `zip`.'
|
387
|
+
Enabled: pending
|
388
|
+
Safe: false
|
389
|
+
VersionAdded: '1.24'
|
@@ -58,6 +58,7 @@ module RuboCop
|
|
58
58
|
class CaseWhenSplat < Base
|
59
59
|
include Alignment
|
60
60
|
include RangeHelp
|
61
|
+
include CommentsHelp
|
61
62
|
extend AutoCorrector
|
62
63
|
|
63
64
|
MSG = 'Reordering `when` conditions with a splat to the end of the `when` branches can improve performance.'
|
@@ -116,11 +117,18 @@ module RuboCop
|
|
116
117
|
def reordering_correction(when_node)
|
117
118
|
new_condition = replacement(when_node.conditions)
|
118
119
|
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
120
|
+
condition =
|
121
|
+
if same_line?(when_node, when_node.body)
|
122
|
+
new_condition_with_then(when_node, new_condition)
|
123
|
+
else
|
124
|
+
new_branch_without_then(when_node, new_condition)
|
125
|
+
end
|
126
|
+
|
127
|
+
condition_comments = comments_in_range(when_node).map do |comment_node|
|
128
|
+
"#{indent_for(comment_node)}#{comment_node.source}"
|
129
|
+
end.join("\n")
|
130
|
+
|
131
|
+
"#{condition}#{condition_comments}"
|
124
132
|
end
|
125
133
|
|
126
134
|
def when_branch_range(when_node)
|
@@ -134,7 +142,13 @@ module RuboCop
|
|
134
142
|
end
|
135
143
|
|
136
144
|
def new_branch_without_then(node, new_condition)
|
137
|
-
"\n#{indent_for(node)}when #{new_condition}\n
|
145
|
+
new_branch = "\n#{indent_for(node)}when #{new_condition}\n"
|
146
|
+
|
147
|
+
if node.body
|
148
|
+
"#{new_branch}#{indent_for(node.body)}#{node.body.source}"
|
149
|
+
else
|
150
|
+
new_branch
|
151
|
+
end
|
138
152
|
end
|
139
153
|
|
140
154
|
def indent_for(node)
|
@@ -45,6 +45,8 @@ module RuboCop
|
|
45
45
|
|
46
46
|
RETURNS_NEW_ARRAY = (ALWAYS_RETURNS_NEW_ARRAY + RETURNS_NEW_ARRAY_WHEN_NO_BLOCK).freeze
|
47
47
|
|
48
|
+
RESTRICT_ON_SEND = RETURNS_NEW_ARRAY
|
49
|
+
|
48
50
|
MSG = 'Use unchained `%<method>s` and `%<second_method>s!` ' \
|
49
51
|
'(followed by `return array` if required) instead of chaining ' \
|
50
52
|
'`%<method>s...%<second_method>s`.'
|
@@ -52,7 +54,7 @@ module RuboCop
|
|
52
54
|
def_node_matcher :chain_array_allocation?, <<~PATTERN
|
53
55
|
(send {
|
54
56
|
(send _ $%RETURN_NEW_ARRAY_WHEN_ARGS {int lvar ivar cvar gvar send})
|
55
|
-
(
|
57
|
+
(any_block (send _ $%ALWAYS_RETURNS_NEW_ARRAY) ...)
|
56
58
|
(send _ $%RETURNS_NEW_ARRAY ...)
|
57
59
|
} $%HAS_MUTATION_ALTERNATIVE ...)
|
58
60
|
PATTERN
|
@@ -73,7 +75,7 @@ module RuboCop
|
|
73
75
|
def enumerable_select_method?(node)
|
74
76
|
# NOTE: `QueryMethods#select` in Rails accepts positional arguments, whereas `Enumerable#select` does not.
|
75
77
|
# This difference can be utilized to reduce the knowledge requirements related to `select`.
|
76
|
-
|
78
|
+
node.any_block_type? && node.send_node.arguments.empty?
|
77
79
|
end
|
78
80
|
end
|
79
81
|
end
|
@@ -38,7 +38,7 @@ module RuboCop
|
|
38
38
|
# (We don't even catch it if the Range is in double parens)
|
39
39
|
|
40
40
|
def_node_matcher :range_include, <<~PATTERN
|
41
|
-
(call {
|
41
|
+
(call {range (begin range)} ${:include? :member?} ...)
|
42
42
|
PATTERN
|
43
43
|
|
44
44
|
def on_send(node)
|
@@ -36,6 +36,13 @@ module RuboCop
|
|
36
36
|
MESSAGE_ONLY_IF = 'only if `%<count>s` is always 0 or more'
|
37
37
|
RESTRICT_ON_SEND = %i[map collect].freeze
|
38
38
|
|
39
|
+
def_node_matcher :times_map_call, <<~PATTERN
|
40
|
+
{
|
41
|
+
(any_block $(call (call $!nil? :times) {:map :collect}) ...)
|
42
|
+
$(call (call $!nil? :times) {:map :collect} (block_pass ...))
|
43
|
+
}
|
44
|
+
PATTERN
|
45
|
+
|
39
46
|
def on_send(node)
|
40
47
|
check(node)
|
41
48
|
end
|
@@ -62,7 +69,7 @@ module RuboCop
|
|
62
69
|
|
63
70
|
def handleable_receiver?(node)
|
64
71
|
receiver = node.receiver.receiver
|
65
|
-
return true if receiver.literal? &&
|
72
|
+
return true if receiver.literal? && receiver.type?(:int, :float)
|
66
73
|
|
67
74
|
node.receiver.dot?
|
68
75
|
end
|
@@ -75,13 +82,6 @@ module RuboCop
|
|
75
82
|
end
|
76
83
|
format(template, count: count.source, map_or_collect: map_or_collect.method_name)
|
77
84
|
end
|
78
|
-
|
79
|
-
def_node_matcher :times_map_call, <<~PATTERN
|
80
|
-
{
|
81
|
-
({block numblock} $(call (call $!nil? :times) {:map :collect}) ...)
|
82
|
-
$(call (call $!nil? :times) {:map :collect} (block_pass ...))
|
83
|
-
}
|
84
|
-
PATTERN
|
85
85
|
end
|
86
86
|
end
|
87
87
|
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Performance
|
6
|
+
# Checks for `map { |id| [id] }` and suggests replacing it with `zip`.
|
7
|
+
#
|
8
|
+
# @safety
|
9
|
+
# This cop is unsafe for novel definitions of `map` and `collect`
|
10
|
+
# on non-Enumerable objects that do not respond to `zip`.
|
11
|
+
# To make your object enumerable, define an `each` method
|
12
|
+
# as described in https://ruby-doc.org/core/Enumerable.html
|
13
|
+
#
|
14
|
+
# @example
|
15
|
+
# # bad
|
16
|
+
# [1, 2, 3].map { |id| [id] }
|
17
|
+
#
|
18
|
+
# # good
|
19
|
+
# [1, 2, 3].zip
|
20
|
+
class ZipWithoutBlock < Base
|
21
|
+
extend AutoCorrector
|
22
|
+
|
23
|
+
MSG = 'Use `zip` without a block argument instead.'
|
24
|
+
RESTRICT_ON_SEND = Set.new(%i[map collect]).freeze
|
25
|
+
|
26
|
+
# @!method map_with_array?(node)
|
27
|
+
def_node_matcher :map_with_array?, <<~PATTERN
|
28
|
+
{
|
29
|
+
(block (call !nil? RESTRICT_ON_SEND) (args (arg _)) (array (lvar _)))
|
30
|
+
(numblock (call !nil? RESTRICT_ON_SEND) 1 (array (lvar _)))
|
31
|
+
}
|
32
|
+
PATTERN
|
33
|
+
|
34
|
+
def on_send(node)
|
35
|
+
return unless map_with_array?(node.parent)
|
36
|
+
|
37
|
+
register_offense(node)
|
38
|
+
end
|
39
|
+
alias on_csend on_send
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def register_offense(node)
|
44
|
+
offense_range = offense_range(node)
|
45
|
+
add_offense(offense_range) do |corrector|
|
46
|
+
corrector.replace(offense_range, 'zip')
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def offense_range(node)
|
51
|
+
node.loc.selector.join(node.parent.loc.end)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'lint_roller'
|
4
|
+
|
5
|
+
module RuboCop
|
6
|
+
module Performance
|
7
|
+
# A plugin that integrates RuboCop Performance with RuboCop's plugin system.
|
8
|
+
class Plugin < LintRoller::Plugin
|
9
|
+
def about
|
10
|
+
LintRoller::About.new(
|
11
|
+
name: 'rubocop-performance',
|
12
|
+
version: Version::STRING,
|
13
|
+
homepage: 'https://github.com/rubocop/rubocop-performance',
|
14
|
+
description: 'A collection of RuboCop cops to check for performance optimizations in Ruby code.'
|
15
|
+
)
|
16
|
+
end
|
17
|
+
|
18
|
+
def supported?(context)
|
19
|
+
context.engine == :rubocop
|
20
|
+
end
|
21
|
+
|
22
|
+
def rules(_context)
|
23
|
+
project_root = Pathname.new(__dir__).join('../../..')
|
24
|
+
|
25
|
+
ConfigObsoletion.files << project_root.join('config', 'obsoletion.yml')
|
26
|
+
|
27
|
+
LintRoller::Rules.new(type: :path, config_format: :rubocop, value: project_root.join('config', 'default.yml'))
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/lib/rubocop/performance.rb
CHANGED
@@ -1,14 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module RuboCop
|
4
|
-
# RuboCop Performance project namespace
|
4
|
+
# RuboCop Performance project namespace.
|
5
5
|
module Performance
|
6
|
-
PROJECT_ROOT = Pathname.new(__dir__).parent.parent.expand_path.freeze
|
7
|
-
CONFIG_DEFAULT = PROJECT_ROOT.join('config', 'default.yml').freeze
|
8
|
-
CONFIG = YAML.safe_load(CONFIG_DEFAULT.read).freeze
|
9
|
-
|
10
|
-
private_constant(:CONFIG_DEFAULT, :PROJECT_ROOT)
|
11
|
-
|
12
|
-
::RuboCop::ConfigObsoletion.files << PROJECT_ROOT.join('config', 'obsoletion.yml')
|
13
6
|
end
|
14
7
|
end
|
data/lib/rubocop-performance.rb
CHANGED
@@ -4,10 +4,7 @@ require 'rubocop'
|
|
4
4
|
|
5
5
|
require_relative 'rubocop/performance'
|
6
6
|
require_relative 'rubocop/performance/version'
|
7
|
-
require_relative 'rubocop/performance/
|
8
|
-
|
9
|
-
RuboCop::Performance::Inject.defaults!
|
10
|
-
|
7
|
+
require_relative 'rubocop/performance/plugin'
|
11
8
|
require_relative 'rubocop/cop/performance_cops'
|
12
9
|
|
13
10
|
RuboCop::Cop::Lint::UnusedMethodArgument.singleton_class.prepend(
|
metadata
CHANGED
@@ -1,23 +1,38 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubocop-performance
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.24.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bozhidar Batsov
|
8
8
|
- Jonas Arvidsson
|
9
9
|
- Yuji Nakayama
|
10
|
+
autorequire:
|
10
11
|
bindir: bin
|
11
12
|
cert_chain: []
|
12
|
-
date: 2025-
|
13
|
+
date: 2025-02-15 00:00:00.000000000 Z
|
13
14
|
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: lint_roller
|
17
|
+
requirement: !ruby/object:Gem::Requirement
|
18
|
+
requirements:
|
19
|
+
- - "~>"
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '1.1'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
requirements:
|
26
|
+
- - "~>"
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
version: '1.1'
|
14
29
|
- !ruby/object:Gem::Dependency
|
15
30
|
name: rubocop
|
16
31
|
requirement: !ruby/object:Gem::Requirement
|
17
32
|
requirements:
|
18
33
|
- - ">="
|
19
34
|
- !ruby/object:Gem::Version
|
20
|
-
version: 1.
|
35
|
+
version: 1.72.1
|
21
36
|
- - "<"
|
22
37
|
- !ruby/object:Gem::Version
|
23
38
|
version: '2.0'
|
@@ -27,7 +42,7 @@ dependencies:
|
|
27
42
|
requirements:
|
28
43
|
- - ">="
|
29
44
|
- !ruby/object:Gem::Version
|
30
|
-
version: 1.
|
45
|
+
version: 1.72.1
|
31
46
|
- - "<"
|
32
47
|
- !ruby/object:Gem::Version
|
33
48
|
version: '2.0'
|
@@ -37,7 +52,7 @@ dependencies:
|
|
37
52
|
requirements:
|
38
53
|
- - ">="
|
39
54
|
- !ruby/object:Gem::Version
|
40
|
-
version: 1.
|
55
|
+
version: 1.38.0
|
41
56
|
- - "<"
|
42
57
|
- !ruby/object:Gem::Version
|
43
58
|
version: '2.0'
|
@@ -47,7 +62,7 @@ dependencies:
|
|
47
62
|
requirements:
|
48
63
|
- - ">="
|
49
64
|
- !ruby/object:Gem::Version
|
50
|
-
version: 1.
|
65
|
+
version: 1.38.0
|
51
66
|
- - "<"
|
52
67
|
- !ruby/object:Gem::Version
|
53
68
|
version: '2.0'
|
@@ -119,9 +134,10 @@ files:
|
|
119
134
|
- lib/rubocop/cop/performance/times_map.rb
|
120
135
|
- lib/rubocop/cop/performance/unfreeze_string.rb
|
121
136
|
- lib/rubocop/cop/performance/uri_default_parser.rb
|
137
|
+
- lib/rubocop/cop/performance/zip_without_block.rb
|
122
138
|
- lib/rubocop/cop/performance_cops.rb
|
123
139
|
- lib/rubocop/performance.rb
|
124
|
-
- lib/rubocop/performance/
|
140
|
+
- lib/rubocop/performance/plugin.rb
|
125
141
|
- lib/rubocop/performance/version.rb
|
126
142
|
homepage: https://github.com/rubocop/rubocop-performance
|
127
143
|
licenses:
|
@@ -130,9 +146,11 @@ metadata:
|
|
130
146
|
homepage_uri: https://docs.rubocop.org/rubocop-performance/
|
131
147
|
changelog_uri: https://github.com/rubocop/rubocop-performance/blob/master/CHANGELOG.md
|
132
148
|
source_code_uri: https://github.com/rubocop/rubocop-performance/
|
133
|
-
documentation_uri: https://docs.rubocop.org/rubocop-performance/1.
|
149
|
+
documentation_uri: https://docs.rubocop.org/rubocop-performance/1.24/
|
134
150
|
bug_tracker_uri: https://github.com/rubocop/rubocop-performance/issues
|
135
151
|
rubygems_mfa_required: 'true'
|
152
|
+
default_lint_roller_plugin: RuboCop::Performance::Plugin
|
153
|
+
post_install_message:
|
136
154
|
rdoc_options: []
|
137
155
|
require_paths:
|
138
156
|
- lib
|
@@ -147,7 +165,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
147
165
|
- !ruby/object:Gem::Version
|
148
166
|
version: '0'
|
149
167
|
requirements: []
|
150
|
-
rubygems_version: 3.6
|
168
|
+
rubygems_version: 3.1.6
|
169
|
+
signing_key:
|
151
170
|
specification_version: 4
|
152
171
|
summary: Automatic performance checking tool for Ruby code.
|
153
172
|
test_files: []
|
@@ -1,18 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module RuboCop
|
4
|
-
module Performance
|
5
|
-
# Because RuboCop doesn't yet support plugins, we have to monkey patch in a
|
6
|
-
# bit of our configuration.
|
7
|
-
module Inject
|
8
|
-
def self.defaults!
|
9
|
-
path = CONFIG_DEFAULT.to_s
|
10
|
-
hash = ConfigLoader.send(:load_yaml_configuration, path)
|
11
|
-
config = Config.new(hash, path).tap(&:make_excludes_absolute)
|
12
|
-
puts "configuration from #{path}" if ConfigLoader.debug?
|
13
|
-
config = ConfigLoader.merge_with_default(config, path)
|
14
|
-
ConfigLoader.instance_variable_set(:@default_configuration, config)
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|