rubocop-performance 1.8.1 → 1.9.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 +8 -0
- data/config/default.yml +25 -1
- data/lib/rubocop/cop/mixin/regexp_metacharacter.rb +4 -4
- data/lib/rubocop/cop/performance/ancestors_include.rb +1 -0
- data/lib/rubocop/cop/performance/array_semi_infinite_range_slice.rb +74 -0
- data/lib/rubocop/cop/performance/big_decimal_with_numeric_argument.rb +1 -0
- data/lib/rubocop/cop/performance/bind_call.rb +1 -0
- data/lib/rubocop/cop/performance/block_given_with_explicit_block.rb +52 -0
- data/lib/rubocop/cop/performance/caller.rb +13 -15
- data/lib/rubocop/cop/performance/casecmp.rb +1 -0
- data/lib/rubocop/cop/performance/constant_regexp.rb +68 -0
- data/lib/rubocop/cop/performance/count.rb +1 -0
- data/lib/rubocop/cop/performance/delete_prefix.rb +1 -0
- data/lib/rubocop/cop/performance/delete_suffix.rb +1 -0
- data/lib/rubocop/cop/performance/detect.rb +3 -2
- data/lib/rubocop/cop/performance/end_with.rb +1 -0
- data/lib/rubocop/cop/performance/fixed_size.rb +1 -0
- data/lib/rubocop/cop/performance/flat_map.rb +1 -0
- data/lib/rubocop/cop/performance/inefficient_hash_search.rb +2 -0
- data/lib/rubocop/cop/performance/io_readlines.rb +3 -7
- data/lib/rubocop/cop/performance/method_object_as_block.rb +32 -0
- data/lib/rubocop/cop/performance/open_struct.rb +1 -0
- data/lib/rubocop/cop/performance/range_include.rb +1 -0
- data/lib/rubocop/cop/performance/redundant_block_call.rb +4 -4
- data/lib/rubocop/cop/performance/redundant_match.rb +1 -0
- data/lib/rubocop/cop/performance/redundant_merge.rb +1 -0
- data/lib/rubocop/cop/performance/redundant_string_chars.rb +2 -6
- data/lib/rubocop/cop/performance/reverse_each.rb +1 -0
- data/lib/rubocop/cop/performance/reverse_first.rb +1 -0
- data/lib/rubocop/cop/performance/size.rb +1 -0
- data/lib/rubocop/cop/performance/squeeze.rb +2 -1
- data/lib/rubocop/cop/performance/start_with.rb +1 -0
- data/lib/rubocop/cop/performance/string_include.rb +2 -1
- data/lib/rubocop/cop/performance/string_replacement.rb +1 -0
- data/lib/rubocop/cop/performance/sum.rb +117 -15
- data/lib/rubocop/cop/performance/times_map.rb +1 -0
- data/lib/rubocop/cop/performance/unfreeze_string.rb +19 -1
- data/lib/rubocop/cop/performance/uri_default_parser.rb +1 -0
- data/lib/rubocop/cop/performance_cops.rb +4 -0
- data/lib/rubocop/performance/version.rb +6 -1
- metadata +19 -23
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9b44c147120a9f64f16a0bf21782f1dbe0a51c64170c3a5c217e548eded4e106
|
4
|
+
data.tar.gz: 7b4e6e464ee3631071f3bd3f447acde2a59763d326a86658412f4ec9527850a6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e450740a348bd17e276af8393f4e8225521afc4c9fac5816c9a3bbd9883d16a15f28a1044e24b89c9037593f4d2931cf3dc900385d42d7ad035dbb1dd461a306
|
7
|
+
data.tar.gz: feef1ae1d9735d3abadf17799ecfb4840ce359fa932902387633e67dc15e1eeb62573ae0a2832c050a8722e004f614c109483a9d8857143f28c866dbd65bc5bf
|
data/README.md
CHANGED
@@ -76,6 +76,14 @@ Performance/Size:
|
|
76
76
|
|
77
77
|
You can read a lot more about RuboCop Performance in its [official docs](https://docs.rubocop.org/rubocop-performance/).
|
78
78
|
|
79
|
+
## Compatibility
|
80
|
+
|
81
|
+
RuboCop Performance complies with the RuboCop core compatibility.
|
82
|
+
|
83
|
+
See the [compatibility documentation](https://docs.rubocop.org/rubocop/compatibility.html) for further details.
|
84
|
+
|
85
|
+
**Note:** Performance cops are all MRI focused and are highly dependent of the version of MRI you're using.
|
86
|
+
|
79
87
|
## Contributing
|
80
88
|
|
81
89
|
Checkout the [contribution guidelines](CONTRIBUTING.md).
|
data/config/default.yml
CHANGED
@@ -7,6 +7,11 @@ Performance/AncestorsInclude:
|
|
7
7
|
Safe: false
|
8
8
|
VersionAdded: '1.7'
|
9
9
|
|
10
|
+
Performance/ArraySemiInfiniteRangeSlice:
|
11
|
+
Description: 'Identifies places where slicing arrays with semi-infinite ranges can be replaced by `Array#take` and `Array#drop`.'
|
12
|
+
Enabled: pending
|
13
|
+
VersionAdded: '1.9'
|
14
|
+
|
10
15
|
Performance/BigDecimalWithNumericArgument:
|
11
16
|
Description: 'Convert numeric argument to string before passing to BigDecimal.'
|
12
17
|
Enabled: 'pending'
|
@@ -17,11 +22,17 @@ Performance/BindCall:
|
|
17
22
|
Enabled: true
|
18
23
|
VersionAdded: '1.6'
|
19
24
|
|
25
|
+
Performance/BlockGivenWithExplicitBlock:
|
26
|
+
Description: 'Check block argument explicitly instead of using `block_given?`.'
|
27
|
+
Enabled: pending
|
28
|
+
VersionAdded: '1.9'
|
29
|
+
|
20
30
|
Performance/Caller:
|
21
31
|
Description: >-
|
22
32
|
Use `caller(n..n)` instead of `caller`.
|
23
33
|
Enabled: true
|
24
34
|
VersionAdded: '0.49'
|
35
|
+
VersionChanged: '1.9'
|
25
36
|
|
26
37
|
Performance/CaseWhenSplat:
|
27
38
|
Description: >-
|
@@ -51,7 +62,7 @@ Performance/ChainArrayAllocation:
|
|
51
62
|
|
52
63
|
Performance/CollectionLiteralInLoop:
|
53
64
|
Description: 'Extract Array and Hash literals outside of loops into local variables or constants.'
|
54
|
-
Enabled:
|
65
|
+
Enabled: 'pending'
|
55
66
|
VersionAdded: '1.8'
|
56
67
|
# Min number of elements to consider an offense
|
57
68
|
MinSize: 1
|
@@ -61,6 +72,11 @@ Performance/CompareWithBlock:
|
|
61
72
|
Enabled: true
|
62
73
|
VersionAdded: '0.46'
|
63
74
|
|
75
|
+
Performance/ConstantRegexp:
|
76
|
+
Description: 'Finds regular expressions with dynamic components that are all constants.'
|
77
|
+
Enabled: pending
|
78
|
+
VersionAdded: '1.9'
|
79
|
+
|
64
80
|
Performance/Count:
|
65
81
|
Description: >-
|
66
82
|
Use `count` instead of `{select,find_all,filter,reject}...{size,count,length}`.
|
@@ -154,6 +170,12 @@ Performance/IoReadlines:
|
|
154
170
|
Enabled: false
|
155
171
|
VersionAdded: '1.7'
|
156
172
|
|
173
|
+
Performance/MethodObjectAsBlock:
|
174
|
+
Description: 'Use block explicitly instead of block-passing a method object.'
|
175
|
+
Reference: 'https://github.com/JuanitoFatas/fast-ruby#normal-way-to-apply-method-vs-method-code'
|
176
|
+
Enabled: pending
|
177
|
+
VersionAdded: '1.9'
|
178
|
+
|
157
179
|
Performance/OpenStruct:
|
158
180
|
Description: 'Use `Struct` instead of `OpenStruct`.'
|
159
181
|
Enabled: false
|
@@ -283,7 +305,9 @@ Performance/TimesMap:
|
|
283
305
|
Performance/UnfreezeString:
|
284
306
|
Description: 'Use unary plus to get an unfrozen string literal.'
|
285
307
|
Enabled: true
|
308
|
+
SafeAutoCorrect: false
|
286
309
|
VersionAdded: '0.50'
|
310
|
+
VersionChanged: '1.9'
|
287
311
|
|
288
312
|
Performance/UriDefaultParser:
|
289
313
|
Description: 'Use `URI::DEFAULT_PARSER` instead of `URI::Parser.new`.'
|
@@ -25,7 +25,7 @@ module RuboCop
|
|
25
25
|
# (tricky: \s, \d, and so on are metacharacters, but other characters
|
26
26
|
# escaped with a slash are just literals. LITERAL_REGEX takes all
|
27
27
|
# that into account.)
|
28
|
-
/\A\\A(?:#{Util::LITERAL_REGEX})+\z
|
28
|
+
/\A\\A(?:#{Util::LITERAL_REGEX})+\z/o.match?(regex_str)
|
29
29
|
end
|
30
30
|
|
31
31
|
def literal_at_start_with_caret?(regex_str)
|
@@ -35,21 +35,21 @@ module RuboCop
|
|
35
35
|
# (tricky: \s, \d, and so on are metacharacters, but other characters
|
36
36
|
# escaped with a slash are just literals. LITERAL_REGEX takes all
|
37
37
|
# that into account.)
|
38
|
-
/\A\^(?:#{Util::LITERAL_REGEX})+\z
|
38
|
+
/\A\^(?:#{Util::LITERAL_REGEX})+\z/o.match?(regex_str)
|
39
39
|
end
|
40
40
|
|
41
41
|
def literal_at_end_with_backslash_z?(regex_str)
|
42
42
|
# is this regexp 'literal' in the sense of only matching literal
|
43
43
|
# chars, rather than using metachars like . and * and so on?
|
44
44
|
# also, is it anchored at the end of the string?
|
45
|
-
/\A(?:#{Util::LITERAL_REGEX})+\\z\z
|
45
|
+
/\A(?:#{Util::LITERAL_REGEX})+\\z\z/o.match?(regex_str)
|
46
46
|
end
|
47
47
|
|
48
48
|
def literal_at_end_with_dollar?(regex_str)
|
49
49
|
# is this regexp 'literal' in the sense of only matching literal
|
50
50
|
# chars, rather than using metachars like . and * and so on?
|
51
51
|
# also, is it anchored at the end of the string?
|
52
|
-
/\A(?:#{Util::LITERAL_REGEX})+\$\z
|
52
|
+
/\A(?:#{Util::LITERAL_REGEX})+\$\z/o.match?(regex_str)
|
53
53
|
end
|
54
54
|
|
55
55
|
def drop_start_metacharacter(regexp_string)
|
@@ -18,6 +18,7 @@ module RuboCop
|
|
18
18
|
extend AutoCorrector
|
19
19
|
|
20
20
|
MSG = 'Use `<=` instead of `ancestors.include?`.'
|
21
|
+
RESTRICT_ON_SEND = %i[include?].freeze
|
21
22
|
|
22
23
|
def_node_matcher :ancestors_include_candidate?, <<~PATTERN
|
23
24
|
(send (send $_subclass :ancestors) :include? $_superclass)
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Performance
|
6
|
+
# This cop identifies places where slicing arrays with semi-infinite ranges
|
7
|
+
# can be replaced by `Array#take` and `Array#drop`.
|
8
|
+
#
|
9
|
+
# @example
|
10
|
+
# # bad
|
11
|
+
# # array[..2]
|
12
|
+
# # array[...2]
|
13
|
+
# # array[2..]
|
14
|
+
# # array[2...]
|
15
|
+
# # array.slice(..2)
|
16
|
+
#
|
17
|
+
# # good
|
18
|
+
# array.take(3)
|
19
|
+
# array.take(2)
|
20
|
+
# array.drop(2)
|
21
|
+
# array.drop(2)
|
22
|
+
# array.take(3)
|
23
|
+
#
|
24
|
+
class ArraySemiInfiniteRangeSlice < Base
|
25
|
+
include RangeHelp
|
26
|
+
extend AutoCorrector
|
27
|
+
extend TargetRubyVersion
|
28
|
+
|
29
|
+
minimum_target_ruby_version 2.7
|
30
|
+
|
31
|
+
MSG = 'Use `%<prefer>s` instead of `%<current>s` with semi-infinite range.'
|
32
|
+
|
33
|
+
SLICE_METHODS = Set[:[], :slice].freeze
|
34
|
+
RESTRICT_ON_SEND = SLICE_METHODS
|
35
|
+
|
36
|
+
def_node_matcher :endless_range_slice?, <<~PATTERN
|
37
|
+
(send $_ $%SLICE_METHODS $#endless_range?)
|
38
|
+
PATTERN
|
39
|
+
|
40
|
+
def_node_matcher :endless_range?, <<~PATTERN
|
41
|
+
{
|
42
|
+
({irange erange} nil? (int positive?))
|
43
|
+
({irange erange} (int positive?) nil?)
|
44
|
+
}
|
45
|
+
PATTERN
|
46
|
+
|
47
|
+
def on_send(node)
|
48
|
+
endless_range_slice?(node) do |receiver, method_name, range_node|
|
49
|
+
prefer = range_node.begin ? :drop : :take
|
50
|
+
message = format(MSG, prefer: prefer, current: method_name)
|
51
|
+
|
52
|
+
add_offense(node, message: message) do |corrector|
|
53
|
+
corrector.replace(node, correction(receiver, range_node))
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
def correction(receiver, range_node)
|
61
|
+
method_call = if range_node.begin
|
62
|
+
"drop(#{range_node.begin.value})"
|
63
|
+
elsif range_node.irange_type?
|
64
|
+
"take(#{range_node.end.value + 1})"
|
65
|
+
else
|
66
|
+
"take(#{range_node.end.value})"
|
67
|
+
end
|
68
|
+
|
69
|
+
"#{receiver.source}.#{method_call}"
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -20,6 +20,7 @@ module RuboCop
|
|
20
20
|
extend AutoCorrector
|
21
21
|
|
22
22
|
MSG = 'Convert numeric argument to string before passing to `BigDecimal`.'
|
23
|
+
RESTRICT_ON_SEND = %i[BigDecimal].freeze
|
23
24
|
|
24
25
|
def_node_matcher :big_decimal_with_numeric_argument?, <<~PATTERN
|
25
26
|
(send nil? :BigDecimal $numeric_type? ...)
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Performance
|
6
|
+
# This cop identifies unnecessary use of a `block_given?` where explicit check
|
7
|
+
# of block argument would suffice.
|
8
|
+
#
|
9
|
+
# @example
|
10
|
+
# # bad
|
11
|
+
# def method(&block)
|
12
|
+
# do_something if block_given?
|
13
|
+
# end
|
14
|
+
#
|
15
|
+
# # good
|
16
|
+
# def method(&block)
|
17
|
+
# do_something if block
|
18
|
+
# end
|
19
|
+
#
|
20
|
+
# # good - block is reassigned
|
21
|
+
# def method(&block)
|
22
|
+
# block ||= -> { do_something }
|
23
|
+
# warn "Using default ..." unless block_given?
|
24
|
+
# # ...
|
25
|
+
# end
|
26
|
+
#
|
27
|
+
class BlockGivenWithExplicitBlock < Base
|
28
|
+
extend AutoCorrector
|
29
|
+
|
30
|
+
RESTRICT_ON_SEND = %i[block_given?].freeze
|
31
|
+
MSG = 'Check block argument explicitly instead of using `block_given?`.'
|
32
|
+
|
33
|
+
def_node_matcher :reassigns_block_arg?, '`(lvasgn %1 ...)'
|
34
|
+
|
35
|
+
def on_send(node)
|
36
|
+
def_node = node.each_ancestor(:def, :defs).first
|
37
|
+
return unless def_node
|
38
|
+
|
39
|
+
block_arg = def_node.arguments.find(&:blockarg_type?)
|
40
|
+
return unless block_arg
|
41
|
+
|
42
|
+
block_arg_name = block_arg.loc.name.source.to_sym
|
43
|
+
return if reassigns_block_arg?(def_node, block_arg_name)
|
44
|
+
|
45
|
+
add_offense(node) do |corrector|
|
46
|
+
corrector.replace(node, block_arg_name)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -19,10 +19,10 @@ module RuboCop
|
|
19
19
|
# caller_locations(2..2).first
|
20
20
|
# caller_locations(1..1).first
|
21
21
|
class Caller < Base
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
22
|
+
extend AutoCorrector
|
23
|
+
|
24
|
+
MSG = 'Use `%<preferred_method>s` instead of `%<current_method>s`.'
|
25
|
+
RESTRICT_ON_SEND = %i[first []].freeze
|
26
26
|
|
27
27
|
def_node_matcher :slow_caller?, <<~PATTERN
|
28
28
|
{
|
@@ -41,26 +41,24 @@ module RuboCop
|
|
41
41
|
def on_send(node)
|
42
42
|
return unless caller_with_scope_method?(node)
|
43
43
|
|
44
|
-
message = message(node)
|
45
|
-
add_offense(node, message: message)
|
46
|
-
end
|
47
|
-
|
48
|
-
private
|
49
|
-
|
50
|
-
def message(node)
|
51
44
|
method_name = node.receiver.method_name
|
52
45
|
caller_arg = node.receiver.first_argument
|
53
46
|
n = caller_arg ? int_value(caller_arg) : 1
|
54
|
-
|
55
47
|
if node.method?(:[])
|
56
48
|
m = int_value(node.first_argument)
|
57
49
|
n += m
|
58
|
-
|
59
|
-
|
60
|
-
|
50
|
+
end
|
51
|
+
|
52
|
+
preferred_method = "#{method_name}(#{n}..#{n}).first"
|
53
|
+
|
54
|
+
message = format(MSG, preferred_method: preferred_method, current_method: node.source)
|
55
|
+
add_offense(node, message: message) do |corrector|
|
56
|
+
corrector.replace(node, preferred_method)
|
61
57
|
end
|
62
58
|
end
|
63
59
|
|
60
|
+
private
|
61
|
+
|
64
62
|
def int_value(node)
|
65
63
|
node.children[0]
|
66
64
|
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Performance
|
6
|
+
# This cop finds regular expressions with dynamic components that are all constants.
|
7
|
+
#
|
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.
|
12
|
+
#
|
13
|
+
# @example
|
14
|
+
#
|
15
|
+
# # bad
|
16
|
+
# def tokens(pattern)
|
17
|
+
# pattern.scan(TOKEN).reject { |token| token.match?(/\A#{SEPARATORS}\Z/) }
|
18
|
+
# end
|
19
|
+
#
|
20
|
+
# # good
|
21
|
+
# ALL_SEPARATORS = /\A#{SEPARATORS}\Z/
|
22
|
+
# def tokens(pattern)
|
23
|
+
# pattern.scan(TOKEN).reject { |token| token.match?(ALL_SEPARATORS) }
|
24
|
+
# end
|
25
|
+
#
|
26
|
+
# # good
|
27
|
+
# def tokens(pattern)
|
28
|
+
# pattern.scan(TOKEN).reject { |token| token.match?(/\A#{SEPARATORS}\Z/o) }
|
29
|
+
# end
|
30
|
+
#
|
31
|
+
class ConstantRegexp < Base
|
32
|
+
extend AutoCorrector
|
33
|
+
|
34
|
+
MSG = 'Extract this regexp into a constant or append an `/o` option to its options.'
|
35
|
+
|
36
|
+
def on_regexp(node)
|
37
|
+
return if within_const_assignment?(node) ||
|
38
|
+
!include_interpolated_const?(node) ||
|
39
|
+
node.single_interpolation?
|
40
|
+
|
41
|
+
add_offense(node) do |corrector|
|
42
|
+
corrector.insert_after(node, 'o')
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def within_const_assignment?(node)
|
49
|
+
node.each_ancestor(:casgn).any?
|
50
|
+
end
|
51
|
+
|
52
|
+
def_node_matcher :regexp_escape?, <<~PATTERN
|
53
|
+
(send
|
54
|
+
(const nil? :Regexp) :escape const_type?)
|
55
|
+
PATTERN
|
56
|
+
|
57
|
+
def include_interpolated_const?(node)
|
58
|
+
return false unless node.interpolation?
|
59
|
+
|
60
|
+
node.each_child_node(:begin).all? do |begin_node|
|
61
|
+
inner_node = begin_node.children.first
|
62
|
+
inner_node && (inner_node.const_type? || regexp_escape?(inner_node))
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -4,8 +4,8 @@ module RuboCop
|
|
4
4
|
module Cop
|
5
5
|
module Performance
|
6
6
|
# This cop is used to identify usages of `first`, `last`, `[0]` or `[-1]`
|
7
|
-
# chained to `select`, `find_all
|
8
|
-
#
|
7
|
+
# chained to `select`, `find_all` or `filter` and change them to use
|
8
|
+
# `detect` instead.
|
9
9
|
#
|
10
10
|
# @example
|
11
11
|
# # bad
|
@@ -39,6 +39,7 @@ module RuboCop
|
|
39
39
|
'`%<first_method>s[%<index>i]`.'
|
40
40
|
INDEX_REVERSE_MSG = 'Use `reverse.%<prefer>s` instead of ' \
|
41
41
|
'`%<first_method>s[%<index>i]`.'
|
42
|
+
RESTRICT_ON_SEND = %i[first last []].freeze
|
42
43
|
|
43
44
|
def_node_matcher :detect_candidate?, <<~PATTERN
|
44
45
|
{
|
@@ -47,6 +47,7 @@ module RuboCop
|
|
47
47
|
|
48
48
|
MSG = 'Use `String#end_with?` instead of a regex match anchored to ' \
|
49
49
|
'the end of the string.'
|
50
|
+
RESTRICT_ON_SEND = %i[match =~ match?].freeze
|
50
51
|
|
51
52
|
def_node_matcher :redundant_regex?, <<~PATTERN
|
52
53
|
{(send $!nil? {:match :=~ :match?} (regexp (str $#literal_at_end?) (regopt)))
|
@@ -47,6 +47,7 @@ module RuboCop
|
|
47
47
|
#
|
48
48
|
class FixedSize < Base
|
49
49
|
MSG = 'Do not compute the size of statically sized objects.'
|
50
|
+
RESTRICT_ON_SEND = %i[count length size].freeze
|
50
51
|
|
51
52
|
def_node_matcher :counter, <<~MATCHER
|
52
53
|
(send ${array hash str sym} {:count :length :size} $...)
|
@@ -19,6 +19,7 @@ module RuboCop
|
|
19
19
|
extend AutoCorrector
|
20
20
|
|
21
21
|
MSG = 'Use `flat_map` instead of `%<method>s...%<flatten>s`.'
|
22
|
+
RESTRICT_ON_SEND = %i[flatten flatten!].freeze
|
22
23
|
FLATTEN_MULTIPLE_LEVELS = ' Beware, `flat_map` only flattens 1 level ' \
|
23
24
|
'and `flatten` can be used to flatten ' \
|
24
25
|
'multiple levels.'
|
@@ -29,14 +29,14 @@ module RuboCop
|
|
29
29
|
extend AutoCorrector
|
30
30
|
|
31
31
|
MSG = 'Use `%<good>s` instead of `%<bad>s`.'
|
32
|
-
|
32
|
+
RESTRICT_ON_SEND = (Enumerable.instance_methods + [:each]).freeze
|
33
33
|
|
34
34
|
def_node_matcher :readlines_on_class?, <<~PATTERN
|
35
|
-
$(send $(send (const nil? {:IO :File}) :readlines ...)
|
35
|
+
$(send $(send (const nil? {:IO :File}) :readlines ...) _)
|
36
36
|
PATTERN
|
37
37
|
|
38
38
|
def_node_matcher :readlines_on_instance?, <<~PATTERN
|
39
|
-
$(send $(send ${nil? !const_type?} :readlines ...)
|
39
|
+
$(send $(send ${nil? !const_type?} :readlines ...) _ ...)
|
40
40
|
PATTERN
|
41
41
|
|
42
42
|
def on_send(node)
|
@@ -55,10 +55,6 @@ module RuboCop
|
|
55
55
|
|
56
56
|
private
|
57
57
|
|
58
|
-
def enumerable_method?(node)
|
59
|
-
ENUMERABLE_METHODS.include?(node.to_sym)
|
60
|
-
end
|
61
|
-
|
62
58
|
def autocorrect(corrector, enumerable_call, readlines_call, receiver)
|
63
59
|
# We cannot safely correct `.readlines` method called on IO/File classes
|
64
60
|
# due to its signature and we are not sure with implicit receiver
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Performance
|
6
|
+
# This cop identifies places where methods are converted to blocks, with the
|
7
|
+
# use of `&method`, and passed as arguments to method calls.
|
8
|
+
# It is faster to replace those with explicit blocks, calling those methods inside.
|
9
|
+
#
|
10
|
+
# @example
|
11
|
+
# # bad
|
12
|
+
# array.map(&method(:do_something))
|
13
|
+
# [1, 2, 3].each(&out.method(:puts))
|
14
|
+
#
|
15
|
+
# # good
|
16
|
+
# array.map { |x| do_something(x) }
|
17
|
+
# [1, 2, 3].each { |x| out.puts(x) }
|
18
|
+
#
|
19
|
+
class MethodObjectAsBlock < Base
|
20
|
+
MSG = 'Use block explicitly instead of block-passing a method object.'
|
21
|
+
|
22
|
+
def_node_matcher :method_object_as_argument?, <<~PATTERN
|
23
|
+
(^send (send _ :method sym))
|
24
|
+
PATTERN
|
25
|
+
|
26
|
+
def on_block_pass(node)
|
27
|
+
add_offense(node) if method_object_as_argument?(node)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -30,6 +30,7 @@ module RuboCop
|
|
30
30
|
class OpenStruct < Base
|
31
31
|
MSG = 'Consider using `Struct` over `OpenStruct` ' \
|
32
32
|
'to optimize the performance.'
|
33
|
+
RESTRICT_ON_SEND = %i[new].freeze
|
33
34
|
|
34
35
|
def_node_matcher :open_struct, <<~PATTERN
|
35
36
|
(send (const {nil? cbase} :OpenStruct) :new ...)
|
@@ -28,6 +28,7 @@ module RuboCop
|
|
28
28
|
extend AutoCorrector
|
29
29
|
|
30
30
|
MSG = 'Use `Range#cover?` instead of `Range#%<bad_method>s`.'
|
31
|
+
RESTRICT_ON_SEND = %i[include? member?].freeze
|
31
32
|
|
32
33
|
# TODO: If we traced out assignments of variables to their uses, we
|
33
34
|
# might pick up on a few more instances of this issue
|
@@ -80,11 +80,11 @@ module RuboCop
|
|
80
80
|
def calls_to_report(argname, body)
|
81
81
|
return [] if blockarg_assigned?(body, argname)
|
82
82
|
|
83
|
-
|
83
|
+
blockarg_calls(body, argname).map do |call|
|
84
|
+
return [] if args_include_block_pass?(call)
|
84
85
|
|
85
|
-
|
86
|
-
|
87
|
-
calls
|
86
|
+
call
|
87
|
+
end
|
88
88
|
end
|
89
89
|
|
90
90
|
def args_include_block_pass?(blockcall)
|
@@ -22,6 +22,7 @@ module RuboCop
|
|
22
22
|
|
23
23
|
MSG = 'Use `=~` in places where the `MatchData` returned by ' \
|
24
24
|
'`#match` will not be used.'
|
25
|
+
RESTRICT_ON_SEND = %i[match].freeze
|
25
26
|
|
26
27
|
# 'match' is a fairly generic name, so we don't flag it unless we see
|
27
28
|
# a string or regexp literal on one side or the other
|
@@ -44,10 +44,10 @@ module RuboCop
|
|
44
44
|
extend AutoCorrector
|
45
45
|
|
46
46
|
MSG = 'Use `%<good_method>s` instead of `%<bad_method>s`.'
|
47
|
-
|
47
|
+
RESTRICT_ON_SEND = %i[[] slice first last take drop length size empty?].freeze
|
48
48
|
|
49
49
|
def_node_matcher :redundant_chars_call?, <<~PATTERN
|
50
|
-
(send $(send _ :chars)
|
50
|
+
(send $(send _ :chars) $_ $...)
|
51
51
|
PATTERN
|
52
52
|
|
53
53
|
def on_send(node)
|
@@ -66,10 +66,6 @@ module RuboCop
|
|
66
66
|
|
67
67
|
private
|
68
68
|
|
69
|
-
def replaceable_method?(method_name)
|
70
|
-
REPLACEABLE_METHODS.include?(method_name)
|
71
|
-
end
|
72
|
-
|
73
69
|
def offense_range(receiver, node)
|
74
70
|
range_between(receiver.loc.selector.begin_pos, node.loc.expression.end_pos)
|
75
71
|
end
|
@@ -22,6 +22,7 @@ module RuboCop
|
|
22
22
|
extend AutoCorrector
|
23
23
|
|
24
24
|
MSG = 'Use `%<prefer>s` instead of `%<current>s`.'
|
25
|
+
RESTRICT_ON_SEND = %i[gsub gsub!].freeze
|
25
26
|
|
26
27
|
PREFERRED_METHODS = {
|
27
28
|
gsub: :squeeze,
|
@@ -58,7 +59,7 @@ module RuboCop
|
|
58
59
|
private
|
59
60
|
|
60
61
|
def repeating_literal?(regex_str)
|
61
|
-
regex_str.match?(/\A(?:#{Util::LITERAL_REGEX})\+\z/)
|
62
|
+
regex_str.match?(/\A(?:#{Util::LITERAL_REGEX})\+\z/o)
|
62
63
|
end
|
63
64
|
end
|
64
65
|
end
|
@@ -47,6 +47,7 @@ module RuboCop
|
|
47
47
|
|
48
48
|
MSG = 'Use `String#start_with?` instead of a regex match anchored to ' \
|
49
49
|
'the beginning of the string.'
|
50
|
+
RESTRICT_ON_SEND = %i[match =~ match?].freeze
|
50
51
|
|
51
52
|
def_node_matcher :redundant_regex?, <<~PATTERN
|
52
53
|
{(send $!nil? {:match :=~ :match?} (regexp (str $#literal_at_start?) (regopt)))
|
@@ -23,6 +23,7 @@ module RuboCop
|
|
23
23
|
extend AutoCorrector
|
24
24
|
|
25
25
|
MSG = 'Use `String#include?` instead of a regex match with literal-only pattern.'
|
26
|
+
RESTRICT_ON_SEND = %i[match =~ match?].freeze
|
26
27
|
|
27
28
|
def_node_matcher :redundant_regex?, <<~PATTERN
|
28
29
|
{(send $!nil? {:match :=~ :match?} (regexp (str $#literal?) (regopt)))
|
@@ -47,7 +48,7 @@ module RuboCop
|
|
47
48
|
private
|
48
49
|
|
49
50
|
def literal?(regex_str)
|
50
|
-
regex_str.match?(/\A#{Util::LITERAL_REGEX}+\z/)
|
51
|
+
regex_str.match?(/\A#{Util::LITERAL_REGEX}+\z/o)
|
51
52
|
end
|
52
53
|
end
|
53
54
|
end
|
@@ -6,28 +6,67 @@ module RuboCop
|
|
6
6
|
# This cop identifies places where custom code finding the sum of elements
|
7
7
|
# in some Enumerable object can be replaced by `Enumerable#sum` method.
|
8
8
|
#
|
9
|
+
# This cop can change auto-correction scope depending on the value of
|
10
|
+
# `SafeAutoCorrect`.
|
11
|
+
# Its auto-correction is marked as safe by default (`SafeAutoCorrect: true`)
|
12
|
+
# to prevent `TypeError` in auto-correced code when initial value is not
|
13
|
+
# specified as shown below:
|
14
|
+
#
|
15
|
+
# [source,ruby]
|
16
|
+
# ----
|
17
|
+
# ['a', 'b'].sum # => (String can't be coerced into Integer)
|
18
|
+
# ----
|
19
|
+
#
|
20
|
+
# Therefore if initial value is not specified, unsafe auto-corrected will not occur.
|
21
|
+
#
|
22
|
+
# If you always want to enable auto-correction, you can set `SafeAutoCorrect: false`.
|
23
|
+
#
|
24
|
+
# [source,yaml]
|
25
|
+
# ----
|
26
|
+
# Performance/Sum:
|
27
|
+
# SafeAutoCorrect: false
|
28
|
+
# ----
|
29
|
+
#
|
30
|
+
# Please note that the auto-correction command line option will be changed from
|
31
|
+
# `rubocop -a` to `rubocop -A`, which includes unsafe auto-correction.
|
32
|
+
#
|
9
33
|
# @example
|
10
34
|
# # bad
|
11
|
-
# [1, 2, 3].inject(:+)
|
35
|
+
# [1, 2, 3].inject(:+) # These bad cases with no initial value are unsafe and
|
36
|
+
# [1, 2, 3].inject(&:+) # will not be auto-correced by default. If you want to
|
37
|
+
# [1, 2, 3].reduce { |acc, elem| acc + elem } # auto-corrected, you can set `SafeAutoCorrect: false`.
|
12
38
|
# [1, 2, 3].reduce(10, :+)
|
13
|
-
# [1, 2, 3].
|
14
|
-
# [1, 2, 3].
|
39
|
+
# [1, 2, 3].map { |elem| elem ** 2 }.sum
|
40
|
+
# [1, 2, 3].collect(&:count).sum(10)
|
15
41
|
#
|
16
42
|
# # good
|
17
43
|
# [1, 2, 3].sum
|
18
44
|
# [1, 2, 3].sum(10)
|
19
|
-
# [1, 2, 3].sum
|
45
|
+
# [1, 2, 3].sum { |elem| elem ** 2 }
|
46
|
+
# [1, 2, 3].sum(10, &:count)
|
20
47
|
#
|
21
48
|
class Sum < Base
|
22
49
|
include RangeHelp
|
23
50
|
extend AutoCorrector
|
24
51
|
|
25
52
|
MSG = 'Use `%<good_method>s` instead of `%<bad_method>s`.'
|
53
|
+
MSG_IF_NO_INIT_VALUE =
|
54
|
+
'Use `%<good_method>s` instead of `%<bad_method>s`, unless calling `%<bad_method>s` on an empty array.'
|
55
|
+
RESTRICT_ON_SEND = %i[inject reduce sum].freeze
|
26
56
|
|
27
57
|
def_node_matcher :sum_candidate?, <<~PATTERN
|
28
58
|
(send _ ${:inject :reduce} $_init ? ${(sym :+) (block_pass (sym :+))})
|
29
59
|
PATTERN
|
30
60
|
|
61
|
+
def_node_matcher :sum_map_candidate?, <<~PATTERN
|
62
|
+
(send
|
63
|
+
{
|
64
|
+
(block $(send _ {:map :collect}) ...)
|
65
|
+
$(send _ {:map :collect} (block_pass _))
|
66
|
+
}
|
67
|
+
:sum $_init ?)
|
68
|
+
PATTERN
|
69
|
+
|
31
70
|
def_node_matcher :sum_with_block_candidate?, <<~PATTERN
|
32
71
|
(block
|
33
72
|
$(send _ {:inject :reduce} $_init ?)
|
@@ -41,14 +80,10 @@ module RuboCop
|
|
41
80
|
alias elem_plus_acc? acc_plus_elem?
|
42
81
|
|
43
82
|
def on_send(node)
|
44
|
-
|
45
|
-
range = sum_method_range(node)
|
46
|
-
message = build_method_message(method, init, operation)
|
83
|
+
return if empty_array_literal?(node)
|
47
84
|
|
48
|
-
|
49
|
-
|
50
|
-
end
|
51
|
-
end
|
85
|
+
handle_sum_candidate(node)
|
86
|
+
handle_sum_map_candidate(node)
|
52
87
|
end
|
53
88
|
|
54
89
|
def on_block(node)
|
@@ -66,25 +101,85 @@ module RuboCop
|
|
66
101
|
|
67
102
|
private
|
68
103
|
|
104
|
+
def handle_sum_candidate(node)
|
105
|
+
sum_candidate?(node) do |method, init, operation|
|
106
|
+
range = sum_method_range(node)
|
107
|
+
message = build_method_message(node, method, init, operation)
|
108
|
+
|
109
|
+
add_offense(range, message: message) do |corrector|
|
110
|
+
autocorrect(corrector, init, range)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def handle_sum_map_candidate(node)
|
116
|
+
sum_map_candidate?(node) do |map, init|
|
117
|
+
next if node.block_literal? || node.block_argument?
|
118
|
+
|
119
|
+
message = build_sum_map_message(map.method_name, init)
|
120
|
+
|
121
|
+
add_offense(sum_map_range(map, node), message: message) do |corrector|
|
122
|
+
autocorrect_sum_map(corrector, node, map, init)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
def empty_array_literal?(node)
|
128
|
+
receiver = node.children.first
|
129
|
+
array_literal?(node) && receiver && receiver.children.empty?
|
130
|
+
end
|
131
|
+
|
132
|
+
def array_literal?(node)
|
133
|
+
receiver = node.children.first
|
134
|
+
receiver&.literal? && receiver&.array_type?
|
135
|
+
end
|
136
|
+
|
69
137
|
def autocorrect(corrector, init, range)
|
70
|
-
return if init.empty?
|
138
|
+
return if init.empty? && safe_autocorrect?
|
71
139
|
|
72
140
|
replacement = build_good_method(init)
|
73
141
|
|
74
142
|
corrector.replace(range, replacement)
|
75
143
|
end
|
76
144
|
|
145
|
+
def autocorrect_sum_map(corrector, sum, map, init)
|
146
|
+
sum_range = method_call_with_args_range(sum)
|
147
|
+
map_range = method_call_with_args_range(map)
|
148
|
+
|
149
|
+
block_pass = map.last_argument if map.last_argument&.block_pass_type?
|
150
|
+
replacement = build_good_method(init, block_pass)
|
151
|
+
|
152
|
+
corrector.remove(sum_range)
|
153
|
+
corrector.replace(map_range, ".#{replacement}")
|
154
|
+
end
|
155
|
+
|
77
156
|
def sum_method_range(node)
|
78
157
|
range_between(node.loc.selector.begin_pos, node.loc.end.end_pos)
|
79
158
|
end
|
80
159
|
|
160
|
+
def sum_map_range(map, sum)
|
161
|
+
range_between(map.loc.selector.begin_pos, sum.source_range.end.end_pos)
|
162
|
+
end
|
163
|
+
|
81
164
|
def sum_block_range(send, node)
|
82
165
|
range_between(send.loc.selector.begin_pos, node.loc.end.end_pos)
|
83
166
|
end
|
84
167
|
|
85
|
-
def build_method_message(method, init, operation)
|
168
|
+
def build_method_message(node, method, init, operation)
|
86
169
|
good_method = build_good_method(init)
|
87
170
|
bad_method = build_method_bad_method(init, method, operation)
|
171
|
+
msg = if init.empty? && !array_literal?(node)
|
172
|
+
MSG_IF_NO_INIT_VALUE
|
173
|
+
else
|
174
|
+
MSG
|
175
|
+
end
|
176
|
+
format(msg, good_method: good_method, bad_method: bad_method)
|
177
|
+
end
|
178
|
+
|
179
|
+
def build_sum_map_message(method, init)
|
180
|
+
sum_method = build_good_method(init)
|
181
|
+
good_method = "#{sum_method} { ... }"
|
182
|
+
bad_method = "#{method} { ... }.#{sum_method}"
|
88
183
|
format(MSG, good_method: good_method, bad_method: bad_method)
|
89
184
|
end
|
90
185
|
|
@@ -94,13 +189,16 @@ module RuboCop
|
|
94
189
|
format(MSG, good_method: good_method, bad_method: bad_method)
|
95
190
|
end
|
96
191
|
|
97
|
-
def build_good_method(init)
|
192
|
+
def build_good_method(init, block_pass = nil)
|
98
193
|
good_method = 'sum'
|
99
194
|
|
195
|
+
args = []
|
100
196
|
unless init.empty?
|
101
197
|
init = init.first
|
102
|
-
|
198
|
+
args << init.source unless init.int_type? && init.value.zero?
|
103
199
|
end
|
200
|
+
args << block_pass.source if block_pass
|
201
|
+
good_method += "(#{args.join(', ')})" unless args.empty?
|
104
202
|
good_method
|
105
203
|
end
|
106
204
|
|
@@ -128,6 +226,10 @@ module RuboCop
|
|
128
226
|
bad_method += " { |#{var_acc}, #{var_elem}| #{body.source} }"
|
129
227
|
bad_method
|
130
228
|
end
|
229
|
+
|
230
|
+
def method_call_with_args_range(node)
|
231
|
+
node.receiver.source_range.end.join(node.source_range.end)
|
232
|
+
end
|
131
233
|
end
|
132
234
|
end
|
133
235
|
end
|
@@ -23,6 +23,7 @@ module RuboCop
|
|
23
23
|
MESSAGE = 'Use `Array.new(%<count>s)` with a block ' \
|
24
24
|
'instead of `.times.%<map_or_collect>s`'
|
25
25
|
MESSAGE_ONLY_IF = 'only if `%<count>s` is always 0 or more'
|
26
|
+
RESTRICT_ON_SEND = %i[map collect].freeze
|
26
27
|
|
27
28
|
def on_send(node)
|
28
29
|
check(node)
|
@@ -10,6 +10,7 @@ module RuboCop
|
|
10
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
|
+
# Therefore, auto-correction is unsafe.
|
13
14
|
# So, if you expect `ASCII-8BIT` encoding, disable this cop.
|
14
15
|
#
|
15
16
|
# @example
|
@@ -24,7 +25,10 @@ module RuboCop
|
|
24
25
|
# +'something'
|
25
26
|
# +''
|
26
27
|
class UnfreezeString < Base
|
28
|
+
extend AutoCorrector
|
29
|
+
|
27
30
|
MSG = 'Use unary plus to get an unfrozen string literal.'
|
31
|
+
RESTRICT_ON_SEND = %i[dup new].freeze
|
28
32
|
|
29
33
|
def_node_matcher :dup_string?, <<~PATTERN
|
30
34
|
(send {str dstr} :dup)
|
@@ -38,7 +42,21 @@ module RuboCop
|
|
38
42
|
PATTERN
|
39
43
|
|
40
44
|
def on_send(node)
|
41
|
-
|
45
|
+
return unless dup_string?(node) || string_new?(node)
|
46
|
+
|
47
|
+
add_offense(node) do |corrector|
|
48
|
+
corrector.replace(node, "+#{string_value(node)}")
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
def string_value(node)
|
55
|
+
if node.receiver.source == 'String' && node.method?(:new)
|
56
|
+
node.arguments.empty? ? "''" : node.first_argument.source
|
57
|
+
else
|
58
|
+
node.receiver.source
|
59
|
+
end
|
42
60
|
end
|
43
61
|
end
|
44
62
|
end
|
@@ -4,13 +4,16 @@ require_relative 'mixin/regexp_metacharacter'
|
|
4
4
|
require_relative 'mixin/sort_block'
|
5
5
|
|
6
6
|
require_relative 'performance/ancestors_include'
|
7
|
+
require_relative 'performance/array_semi_infinite_range_slice'
|
7
8
|
require_relative 'performance/big_decimal_with_numeric_argument'
|
8
9
|
require_relative 'performance/bind_call'
|
10
|
+
require_relative 'performance/block_given_with_explicit_block'
|
9
11
|
require_relative 'performance/caller'
|
10
12
|
require_relative 'performance/case_when_splat'
|
11
13
|
require_relative 'performance/casecmp'
|
12
14
|
require_relative 'performance/collection_literal_in_loop'
|
13
15
|
require_relative 'performance/compare_with_block'
|
16
|
+
require_relative 'performance/constant_regexp'
|
14
17
|
require_relative 'performance/count'
|
15
18
|
require_relative 'performance/delete_prefix'
|
16
19
|
require_relative 'performance/delete_suffix'
|
@@ -20,6 +23,7 @@ require_relative 'performance/end_with'
|
|
20
23
|
require_relative 'performance/fixed_size'
|
21
24
|
require_relative 'performance/flat_map'
|
22
25
|
require_relative 'performance/inefficient_hash_search'
|
26
|
+
require_relative 'performance/method_object_as_block'
|
23
27
|
require_relative 'performance/open_struct'
|
24
28
|
require_relative 'performance/range_include'
|
25
29
|
require_relative 'performance/io_readlines'
|
metadata
CHANGED
@@ -1,16 +1,16 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubocop-performance
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.9.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bozhidar Batsov
|
8
8
|
- Jonas Arvidsson
|
9
9
|
- Yuji Nakayama
|
10
|
-
autorequire:
|
10
|
+
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2020-
|
13
|
+
date: 2020-11-16 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rubocop
|
@@ -18,14 +18,20 @@ dependencies:
|
|
18
18
|
requirements:
|
19
19
|
- - ">="
|
20
20
|
- !ruby/object:Gem::Version
|
21
|
-
version: 0.
|
21
|
+
version: 0.90.0
|
22
|
+
- - "<"
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: '2.0'
|
22
25
|
type: :runtime
|
23
26
|
prerelease: false
|
24
27
|
version_requirements: !ruby/object:Gem::Requirement
|
25
28
|
requirements:
|
26
29
|
- - ">="
|
27
30
|
- !ruby/object:Gem::Version
|
28
|
-
version: 0.
|
31
|
+
version: 0.90.0
|
32
|
+
- - "<"
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '2.0'
|
29
35
|
- !ruby/object:Gem::Dependency
|
30
36
|
name: rubocop-ast
|
31
37
|
requirement: !ruby/object:Gem::Requirement
|
@@ -40,20 +46,6 @@ dependencies:
|
|
40
46
|
- - ">="
|
41
47
|
- !ruby/object:Gem::Version
|
42
48
|
version: 0.4.0
|
43
|
-
- !ruby/object:Gem::Dependency
|
44
|
-
name: simplecov
|
45
|
-
requirement: !ruby/object:Gem::Requirement
|
46
|
-
requirements:
|
47
|
-
- - ">="
|
48
|
-
- !ruby/object:Gem::Version
|
49
|
-
version: '0'
|
50
|
-
type: :development
|
51
|
-
prerelease: false
|
52
|
-
version_requirements: !ruby/object:Gem::Requirement
|
53
|
-
requirements:
|
54
|
-
- - ">="
|
55
|
-
- !ruby/object:Gem::Version
|
56
|
-
version: '0'
|
57
49
|
description: |
|
58
50
|
A collection of RuboCop cops to check for performance optimizations
|
59
51
|
in Ruby code.
|
@@ -71,14 +63,17 @@ files:
|
|
71
63
|
- lib/rubocop/cop/mixin/regexp_metacharacter.rb
|
72
64
|
- lib/rubocop/cop/mixin/sort_block.rb
|
73
65
|
- lib/rubocop/cop/performance/ancestors_include.rb
|
66
|
+
- lib/rubocop/cop/performance/array_semi_infinite_range_slice.rb
|
74
67
|
- lib/rubocop/cop/performance/big_decimal_with_numeric_argument.rb
|
75
68
|
- lib/rubocop/cop/performance/bind_call.rb
|
69
|
+
- lib/rubocop/cop/performance/block_given_with_explicit_block.rb
|
76
70
|
- lib/rubocop/cop/performance/caller.rb
|
77
71
|
- lib/rubocop/cop/performance/case_when_splat.rb
|
78
72
|
- lib/rubocop/cop/performance/casecmp.rb
|
79
73
|
- lib/rubocop/cop/performance/chain_array_allocation.rb
|
80
74
|
- lib/rubocop/cop/performance/collection_literal_in_loop.rb
|
81
75
|
- lib/rubocop/cop/performance/compare_with_block.rb
|
76
|
+
- lib/rubocop/cop/performance/constant_regexp.rb
|
82
77
|
- lib/rubocop/cop/performance/count.rb
|
83
78
|
- lib/rubocop/cop/performance/delete_prefix.rb
|
84
79
|
- lib/rubocop/cop/performance/delete_suffix.rb
|
@@ -89,6 +84,7 @@ files:
|
|
89
84
|
- lib/rubocop/cop/performance/flat_map.rb
|
90
85
|
- lib/rubocop/cop/performance/inefficient_hash_search.rb
|
91
86
|
- lib/rubocop/cop/performance/io_readlines.rb
|
87
|
+
- lib/rubocop/cop/performance/method_object_as_block.rb
|
92
88
|
- lib/rubocop/cop/performance/open_struct.rb
|
93
89
|
- lib/rubocop/cop/performance/range_include.rb
|
94
90
|
- lib/rubocop/cop/performance/redundant_block_call.rb
|
@@ -120,9 +116,9 @@ metadata:
|
|
120
116
|
homepage_uri: https://docs.rubocop.org/rubocop-performance/
|
121
117
|
changelog_uri: https://github.com/rubocop-hq/rubocop-performance/blob/master/CHANGELOG.md
|
122
118
|
source_code_uri: https://github.com/rubocop-hq/rubocop-performance/
|
123
|
-
documentation_uri: https://docs.rubocop.org/rubocop-performance/
|
119
|
+
documentation_uri: https://docs.rubocop.org/rubocop-performance/1.9/
|
124
120
|
bug_tracker_uri: https://github.com/rubocop-hq/rubocop-performance/issues
|
125
|
-
post_install_message:
|
121
|
+
post_install_message:
|
126
122
|
rdoc_options: []
|
127
123
|
require_paths:
|
128
124
|
- lib
|
@@ -137,8 +133,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
137
133
|
- !ruby/object:Gem::Version
|
138
134
|
version: '0'
|
139
135
|
requirements: []
|
140
|
-
rubygems_version: 3.
|
141
|
-
signing_key:
|
136
|
+
rubygems_version: 3.2.0.rc.2
|
137
|
+
signing_key:
|
142
138
|
specification_version: 4
|
143
139
|
summary: Automatic performance checking tool for Ruby code.
|
144
140
|
test_files: []
|