rubocop-performance 1.21.1 → 1.23.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 +4 -4
- data/LICENSE.txt +1 -1
- data/config/default.yml +10 -1
- data/lib/rubocop/cop/performance/big_decimal_with_numeric_argument.rb +43 -19
- data/lib/rubocop/cop/performance/block_given_with_explicit_block.rb +3 -0
- data/lib/rubocop/cop/performance/count.rb +2 -2
- data/lib/rubocop/cop/performance/double_start_end_with.rb +10 -10
- data/lib/rubocop/cop/performance/redundant_match.rb +1 -1
- data/lib/rubocop/cop/performance/redundant_merge.rb +1 -3
- data/lib/rubocop/cop/performance/redundant_string_chars.rb +1 -1
- data/lib/rubocop/cop/performance/squeeze.rb +5 -1
- data/lib/rubocop/cop/performance/string_bytesize.rb +45 -0
- data/lib/rubocop/cop/performance/sum.rb +1 -1
- data/lib/rubocop/cop/performance_cops.rb +1 -0
- data/lib/rubocop/performance/version.rb +1 -1
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 332ca643753a81ff66c4a6050117f7a479bd3aaa3f186c361a596d06b16aa9b5
|
4
|
+
data.tar.gz: 2fb149f85f986d9d0302e6fbe4c7389f312bb93a15a93cec49ffd74495853c78
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e03b8e178f4cde75ef5d82aa7483da512f2816afd82c97b414a4bfcd7afacf589ebb033d6bed40d0968217ec0ff24cb69e2a6c4f28a52ecbdb31cef5599e5386
|
7
|
+
data.tar.gz: 410a72e5e85fe6cdc8002b51c8b185dc4d2a1dea5f3a5889c146364c2a20b5b50256c2a90fef59604137dd75d83f20c17ec65991eac6b8dab15e046184e1f006
|
data/LICENSE.txt
CHANGED
data/config/default.yml
CHANGED
@@ -32,8 +32,11 @@ Performance/BindCall:
|
|
32
32
|
|
33
33
|
Performance/BlockGivenWithExplicitBlock:
|
34
34
|
Description: 'Check block argument explicitly instead of using `block_given?`.'
|
35
|
-
|
35
|
+
# This cop was created due to a mistake in microbenchmark.
|
36
|
+
# https://github.com/rubocop/rubocop-performance/issues/385
|
37
|
+
Enabled: false
|
36
38
|
VersionAdded: '1.9'
|
39
|
+
VersionChanged: '1.22'
|
37
40
|
|
38
41
|
Performance/Caller:
|
39
42
|
Description: >-
|
@@ -323,6 +326,12 @@ Performance/StartWith:
|
|
323
326
|
VersionAdded: '0.36'
|
324
327
|
VersionChanged: '1.10'
|
325
328
|
|
329
|
+
Performance/StringBytesize:
|
330
|
+
Description: "Use `String#bytesize` instead of calculating the size of the bytes array."
|
331
|
+
Safe: false
|
332
|
+
Enabled: 'pending'
|
333
|
+
VersionAdded: '1.23'
|
334
|
+
|
326
335
|
Performance/StringIdentifierArgument:
|
327
336
|
Description: 'Use symbol identifier argument instead of string identifier argument.'
|
328
337
|
Enabled: pending
|
@@ -3,50 +3,74 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module Performance
|
6
|
-
# Identifies places where
|
7
|
-
#
|
8
|
-
#
|
6
|
+
# Identifies places where a float argument to BigDecimal should be converted to a string.
|
7
|
+
# Initializing from String is faster than from Float for BigDecimal.
|
8
|
+
#
|
9
|
+
# Also identifies places where an integer string argument to BigDecimal should be converted to
|
10
|
+
# an integer. Initializing from Integer is faster than from String for BigDecimal.
|
9
11
|
#
|
10
12
|
# @example
|
11
13
|
# # bad
|
12
|
-
# BigDecimal(1, 2)
|
13
|
-
# 4.to_d(6)
|
14
14
|
# BigDecimal(1.2, 3, exception: true)
|
15
15
|
# 4.5.to_d(6, exception: true)
|
16
16
|
#
|
17
17
|
# # good
|
18
|
-
# BigDecimal('1', 2)
|
19
|
-
# BigDecimal('4', 6)
|
20
18
|
# BigDecimal('1.2', 3, exception: true)
|
21
19
|
# BigDecimal('4.5', 6, exception: true)
|
22
20
|
#
|
21
|
+
# # bad
|
22
|
+
# BigDecimal('1', 2)
|
23
|
+
# BigDecimal('4', 6)
|
24
|
+
#
|
25
|
+
# # good
|
26
|
+
# BigDecimal(1, 2)
|
27
|
+
# 4.to_d(6)
|
28
|
+
#
|
23
29
|
class BigDecimalWithNumericArgument < Base
|
24
30
|
extend AutoCorrector
|
31
|
+
extend TargetRubyVersion
|
32
|
+
|
33
|
+
minimum_target_ruby_version 3.1
|
25
34
|
|
26
|
-
|
35
|
+
MSG_FROM_FLOAT_TO_STRING = 'Convert float literal to string and pass it to `BigDecimal`.'
|
36
|
+
MSG_FROM_INTEGER_TO_STRING = 'Convert string literal to integer and pass it to `BigDecimal`.'
|
27
37
|
RESTRICT_ON_SEND = %i[BigDecimal to_d].freeze
|
28
38
|
|
29
|
-
def_node_matcher :big_decimal_with_numeric_argument
|
30
|
-
(send nil? :BigDecimal $
|
39
|
+
def_node_matcher :big_decimal_with_numeric_argument, <<~PATTERN
|
40
|
+
(send nil? :BigDecimal ${float_type? str_type?} ...)
|
31
41
|
PATTERN
|
32
42
|
|
33
|
-
def_node_matcher :to_d
|
34
|
-
(send [!nil? $
|
43
|
+
def_node_matcher :to_d, <<~PATTERN
|
44
|
+
(send [!nil? ${float_type? str_type?}] :to_d ...)
|
35
45
|
PATTERN
|
36
46
|
|
47
|
+
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/MethodLength
|
37
48
|
def on_send(node)
|
38
|
-
if (numeric = big_decimal_with_numeric_argument
|
39
|
-
|
40
|
-
|
49
|
+
if (numeric = big_decimal_with_numeric_argument(node))
|
50
|
+
if numeric.numeric_type?
|
51
|
+
add_offense(numeric, message: MSG_FROM_FLOAT_TO_STRING) do |corrector|
|
52
|
+
corrector.wrap(numeric, "'", "'")
|
53
|
+
end
|
54
|
+
elsif numeric.value.match?(/\A\d+\z/)
|
55
|
+
add_offense(numeric, message: MSG_FROM_INTEGER_TO_STRING) do |corrector|
|
56
|
+
corrector.replace(numeric, numeric.value)
|
57
|
+
end
|
41
58
|
end
|
42
|
-
elsif (numeric_to_d = to_d
|
43
|
-
|
44
|
-
|
59
|
+
elsif (numeric_to_d = to_d(node))
|
60
|
+
if numeric_to_d.numeric_type?
|
61
|
+
add_offense(numeric_to_d, message: MSG_FROM_FLOAT_TO_STRING) do |corrector|
|
62
|
+
big_decimal_args = node.arguments.map(&:source).unshift("'#{numeric_to_d.source}'").join(', ')
|
45
63
|
|
46
|
-
|
64
|
+
corrector.replace(node, "BigDecimal(#{big_decimal_args})")
|
65
|
+
end
|
66
|
+
elsif numeric_to_d.value.match?(/\A\d+\z/)
|
67
|
+
add_offense(numeric_to_d, message: MSG_FROM_INTEGER_TO_STRING) do |corrector|
|
68
|
+
corrector.replace(node, "#{numeric_to_d.value}.to_d")
|
69
|
+
end
|
47
70
|
end
|
48
71
|
end
|
49
72
|
end
|
73
|
+
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/MethodLength
|
50
74
|
end
|
51
75
|
end
|
52
76
|
end
|
@@ -6,6 +6,9 @@ module RuboCop
|
|
6
6
|
# Identifies unnecessary use of a `block_given?` where explicit check
|
7
7
|
# of block argument would suffice.
|
8
8
|
#
|
9
|
+
# NOTE: This cop produces code with significantly worse performance when a
|
10
|
+
# block is being passed to the method and as such should not be enabled.
|
11
|
+
#
|
9
12
|
# @example
|
10
13
|
# # bad
|
11
14
|
# def method(&block)
|
@@ -18,14 +18,14 @@ module RuboCop
|
|
18
18
|
#
|
19
19
|
# [source,ruby]
|
20
20
|
# ----
|
21
|
-
#
|
21
|
+
# Model.where(id: [1, 2, 3]).select { |m| m.method == true }.size
|
22
22
|
# ----
|
23
23
|
#
|
24
24
|
# becomes:
|
25
25
|
#
|
26
26
|
# [source,ruby]
|
27
27
|
# ----
|
28
|
-
#
|
28
|
+
# Model.where(id: [1, 2, 3]).to_a.count { |m| m.method == true }
|
29
29
|
# ----
|
30
30
|
#
|
31
31
|
# @example
|
@@ -41,7 +41,7 @@ module RuboCop
|
|
41
41
|
class DoubleStartEndWith < Base
|
42
42
|
extend AutoCorrector
|
43
43
|
|
44
|
-
MSG = 'Use `%<
|
44
|
+
MSG = 'Use `%<replacement>s` instead of `%<original_code>s`.'
|
45
45
|
|
46
46
|
def on_or(node)
|
47
47
|
receiver, method, first_call_args, second_call_args = process_source(node)
|
@@ -50,7 +50,7 @@ module RuboCop
|
|
50
50
|
|
51
51
|
combined_args = combine_args(first_call_args, second_call_args)
|
52
52
|
|
53
|
-
add_offense(node, message: message(node, receiver, method, combined_args)) do |corrector|
|
53
|
+
add_offense(node, message: message(node, receiver, first_call_args, method, combined_args)) do |corrector|
|
54
54
|
autocorrect(corrector, first_call_args, second_call_args, combined_args)
|
55
55
|
end
|
56
56
|
end
|
@@ -73,10 +73,10 @@ module RuboCop
|
|
73
73
|
end
|
74
74
|
end
|
75
75
|
|
76
|
-
def message(node, receiver, method, combined_args)
|
77
|
-
|
78
|
-
|
79
|
-
)
|
76
|
+
def message(node, receiver, first_call_args, method, combined_args)
|
77
|
+
dot = first_call_args.first.parent.send_type? ? '.' : '&.'
|
78
|
+
replacement = "#{receiver.source}#{dot}#{method}(#{combined_args})"
|
79
|
+
format(MSG, replacement: replacement, original_code: node.source)
|
80
80
|
end
|
81
81
|
|
82
82
|
def combine_args(first_call_args, second_call_args)
|
@@ -89,16 +89,16 @@ module RuboCop
|
|
89
89
|
|
90
90
|
def_node_matcher :two_start_end_with_calls, <<~PATTERN
|
91
91
|
(or
|
92
|
-
(
|
93
|
-
(
|
92
|
+
(call $_recv [{:start_with? :end_with?} $_method] $...)
|
93
|
+
(call _recv _method $...))
|
94
94
|
PATTERN
|
95
95
|
|
96
96
|
def_node_matcher :check_with_active_support_aliases, <<~PATTERN
|
97
97
|
(or
|
98
|
-
(
|
98
|
+
(call $_recv
|
99
99
|
[{:start_with? :starts_with? :end_with? :ends_with?} $_method]
|
100
100
|
$...)
|
101
|
-
(
|
101
|
+
(call _recv _method $...))
|
102
102
|
PATTERN
|
103
103
|
end
|
104
104
|
end
|
@@ -72,7 +72,7 @@ module RuboCop
|
|
72
72
|
|
73
73
|
def requires_parentheses?(arg)
|
74
74
|
return true if arg.if_type? && arg.ternary?
|
75
|
-
return true if arg.
|
75
|
+
return true if arg.operator_keyword? || arg.range_type?
|
76
76
|
|
77
77
|
call_like?(arg) && requires_parentheses_for_call_like?(arg)
|
78
78
|
end
|
@@ -130,9 +130,7 @@ module RuboCop
|
|
130
130
|
end
|
131
131
|
|
132
132
|
def rewrite_with_modifier(node, parent, new_source)
|
133
|
-
|
134
|
-
# https://github.com/rubocop/rubocop/commit/02d1e5b
|
135
|
-
indent = ' ' * (configured_indentation_width || 2)
|
133
|
+
indent = ' ' * configured_indentation_width
|
136
134
|
padding = "\n#{indent + leading_spaces(node)}"
|
137
135
|
new_source.gsub!("\n", padding)
|
138
136
|
|
@@ -46,7 +46,11 @@ module RuboCop
|
|
46
46
|
message = format(MSG, current: bad_method, prefer: good_method)
|
47
47
|
|
48
48
|
add_offense(node.loc.selector, message: message) do |corrector|
|
49
|
-
|
49
|
+
# FIXME: When requiring only RuboCop 1.70.0 and above,
|
50
|
+
# `dup` in `replace_str.dup` becomes unnecessary, as
|
51
|
+
# frozen strings are handled in the `to_string_literal`
|
52
|
+
# implementation. Please remove it.
|
53
|
+
string_literal = to_string_literal(replace_str.dup)
|
50
54
|
new_code = "#{receiver.source}#{node.loc.dot.source}#{good_method}(#{string_literal})"
|
51
55
|
|
52
56
|
corrector.replace(node, new_code)
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Performance
|
6
|
+
# Checks for calls to `#bytes` counting method and suggests using `bytesize` instead.
|
7
|
+
# The `bytesize` method is more efficient and directly returns the size in bytes,
|
8
|
+
# avoiding the intermediate array allocation that `bytes.size` incurs.
|
9
|
+
#
|
10
|
+
# @safety
|
11
|
+
# This cop is unsafe because it assumes that the receiver
|
12
|
+
# responds to `#bytesize` method.
|
13
|
+
#
|
14
|
+
# @example
|
15
|
+
# # bad
|
16
|
+
# string_var.bytes.count
|
17
|
+
# "foobar".bytes.size
|
18
|
+
#
|
19
|
+
# # good
|
20
|
+
# string_var.bytesize
|
21
|
+
# "foobar".bytesize
|
22
|
+
class StringBytesize < Base
|
23
|
+
extend AutoCorrector
|
24
|
+
|
25
|
+
MSG = 'Use `String#bytesize` instead of calculating the size of the bytes array.'
|
26
|
+
RESTRICT_ON_SEND = %i[size length count].freeze
|
27
|
+
|
28
|
+
def_node_matcher :string_bytes_method?, <<~MATCHER
|
29
|
+
(call (call !{nil? int} :bytes) {:size :length :count})
|
30
|
+
MATCHER
|
31
|
+
|
32
|
+
def on_send(node)
|
33
|
+
string_bytes_method?(node) do
|
34
|
+
range = node.receiver.loc.selector.begin.join(node.source_range.end)
|
35
|
+
|
36
|
+
add_offense(range) do |corrector|
|
37
|
+
corrector.replace(range, 'bytesize')
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
alias on_csend on_send
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -44,6 +44,7 @@ require_relative 'performance/select_map'
|
|
44
44
|
require_relative 'performance/size'
|
45
45
|
require_relative 'performance/sort_reverse'
|
46
46
|
require_relative 'performance/squeeze'
|
47
|
+
require_relative 'performance/string_bytesize'
|
47
48
|
require_relative 'performance/start_with'
|
48
49
|
require_relative 'performance/string_identifier_argument'
|
49
50
|
require_relative 'performance/string_include'
|
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.
|
4
|
+
version: 1.23.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bozhidar Batsov
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
- Yuji Nakayama
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2025-01-04 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rubocop
|
@@ -111,6 +111,7 @@ files:
|
|
111
111
|
- lib/rubocop/cop/performance/sort_reverse.rb
|
112
112
|
- lib/rubocop/cop/performance/squeeze.rb
|
113
113
|
- lib/rubocop/cop/performance/start_with.rb
|
114
|
+
- lib/rubocop/cop/performance/string_bytesize.rb
|
114
115
|
- lib/rubocop/cop/performance/string_identifier_argument.rb
|
115
116
|
- lib/rubocop/cop/performance/string_include.rb
|
116
117
|
- lib/rubocop/cop/performance/string_replacement.rb
|
@@ -129,7 +130,7 @@ metadata:
|
|
129
130
|
homepage_uri: https://docs.rubocop.org/rubocop-performance/
|
130
131
|
changelog_uri: https://github.com/rubocop/rubocop-performance/blob/master/CHANGELOG.md
|
131
132
|
source_code_uri: https://github.com/rubocop/rubocop-performance/
|
132
|
-
documentation_uri: https://docs.rubocop.org/rubocop-performance/1.
|
133
|
+
documentation_uri: https://docs.rubocop.org/rubocop-performance/1.23/
|
133
134
|
bug_tracker_uri: https://github.com/rubocop/rubocop-performance/issues
|
134
135
|
rubygems_mfa_required: 'true'
|
135
136
|
rdoc_options: []
|
@@ -146,7 +147,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
146
147
|
- !ruby/object:Gem::Version
|
147
148
|
version: '0'
|
148
149
|
requirements: []
|
149
|
-
rubygems_version: 3.6.
|
150
|
+
rubygems_version: 3.6.1
|
150
151
|
specification_version: 4
|
151
152
|
summary: Automatic performance checking tool for Ruby code.
|
152
153
|
test_files: []
|