rubocop-performance 1.7.0 → 1.9.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/README.md +8 -0
- data/config/default.yml +49 -7
- data/lib/rubocop/cop/mixin/regexp_metacharacter.rb +4 -4
- data/lib/rubocop/cop/performance/ancestors_include.rb +16 -12
- data/lib/rubocop/cop/performance/array_semi_infinite_range_slice.rb +77 -0
- data/lib/rubocop/cop/performance/big_decimal_with_numeric_argument.rb +17 -14
- data/lib/rubocop/cop/performance/bind_call.rb +9 -18
- data/lib/rubocop/cop/performance/block_given_with_explicit_block.rb +52 -0
- data/lib/rubocop/cop/performance/caller.rb +14 -15
- data/lib/rubocop/cop/performance/case_when_splat.rb +18 -11
- data/lib/rubocop/cop/performance/casecmp.rb +13 -20
- data/lib/rubocop/cop/performance/chain_array_allocation.rb +24 -28
- data/lib/rubocop/cop/performance/collection_literal_in_loop.rb +140 -0
- data/lib/rubocop/cop/performance/compare_with_block.rb +10 -21
- data/lib/rubocop/cop/performance/constant_regexp.rb +68 -0
- data/lib/rubocop/cop/performance/count.rb +14 -16
- data/lib/rubocop/cop/performance/delete_prefix.rb +14 -22
- data/lib/rubocop/cop/performance/delete_suffix.rb +14 -22
- data/lib/rubocop/cop/performance/detect.rb +65 -32
- data/lib/rubocop/cop/performance/double_start_end_with.rb +16 -24
- data/lib/rubocop/cop/performance/end_with.rb +9 -13
- data/lib/rubocop/cop/performance/fixed_size.rb +2 -1
- data/lib/rubocop/cop/performance/flat_map.rb +21 -22
- data/lib/rubocop/cop/performance/inefficient_hash_search.rb +15 -14
- data/lib/rubocop/cop/performance/io_readlines.rb +27 -42
- data/lib/rubocop/cop/performance/method_object_as_block.rb +32 -0
- data/lib/rubocop/cop/performance/open_struct.rb +3 -2
- data/lib/rubocop/cop/performance/range_include.rb +8 -6
- data/lib/rubocop/cop/performance/redundant_block_call.rb +15 -10
- data/lib/rubocop/cop/performance/redundant_match.rb +12 -6
- data/lib/rubocop/cop/performance/redundant_merge.rb +19 -17
- data/lib/rubocop/cop/performance/redundant_sort_block.rb +6 -16
- data/lib/rubocop/cop/performance/redundant_string_chars.rb +10 -18
- data/lib/rubocop/cop/performance/regexp_match.rb +20 -20
- data/lib/rubocop/cop/performance/reverse_each.rb +10 -5
- data/lib/rubocop/cop/performance/reverse_first.rb +5 -10
- data/lib/rubocop/cop/performance/size.rb +7 -6
- data/lib/rubocop/cop/performance/sort_reverse.rb +6 -15
- data/lib/rubocop/cop/performance/squeeze.rb +8 -11
- data/lib/rubocop/cop/performance/start_with.rb +9 -13
- data/lib/rubocop/cop/performance/string_include.rb +13 -14
- data/lib/rubocop/cop/performance/string_replacement.rb +24 -27
- data/lib/rubocop/cop/performance/sum.rb +236 -0
- data/lib/rubocop/cop/performance/times_map.rb +12 -18
- data/lib/rubocop/cop/performance/unfreeze_string.rb +20 -2
- data/lib/rubocop/cop/performance/uri_default_parser.rb +7 -12
- data/lib/rubocop/cop/performance_cops.rb +6 -0
- data/lib/rubocop/performance/version.rb +6 -1
- metadata +25 -13
@@ -13,29 +13,19 @@ module RuboCop
|
|
13
13
|
# # good
|
14
14
|
# array.sort
|
15
15
|
#
|
16
|
-
class RedundantSortBlock <
|
16
|
+
class RedundantSortBlock < Base
|
17
17
|
include SortBlock
|
18
|
+
extend AutoCorrector
|
18
19
|
|
19
20
|
MSG = 'Use `sort` instead of `%<bad_method>s`.'
|
20
21
|
|
21
22
|
def on_block(node)
|
22
|
-
|
23
|
-
replaceable_body?(body, var_a, var_b) do
|
24
|
-
range = sort_range(send, node)
|
23
|
+
return unless (send, var_a, var_b, body = sort_with_block?(node))
|
25
24
|
|
26
|
-
|
27
|
-
|
28
|
-
location: range,
|
29
|
-
message: message(var_a, var_b)
|
30
|
-
)
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
25
|
+
replaceable_body?(body, var_a, var_b) do
|
26
|
+
range = sort_range(send, node)
|
34
27
|
|
35
|
-
|
36
|
-
sort_with_block?(node) do |send, _var_a, _var_b, _body|
|
37
|
-
lambda do |corrector|
|
38
|
-
range = sort_range(send, node)
|
28
|
+
add_offense(range, message: message(var_a, var_b)) do |corrector|
|
39
29
|
corrector.replace(range, 'sort')
|
40
30
|
end
|
41
31
|
end
|
@@ -39,41 +39,33 @@ module RuboCop
|
|
39
39
|
# str.size
|
40
40
|
# str.empty?
|
41
41
|
#
|
42
|
-
class RedundantStringChars <
|
42
|
+
class RedundantStringChars < Base
|
43
43
|
include RangeHelp
|
44
|
+
extend AutoCorrector
|
44
45
|
|
45
46
|
MSG = 'Use `%<good_method>s` instead of `%<bad_method>s`.'
|
46
|
-
|
47
|
+
RESTRICT_ON_SEND = %i[[] slice first last take drop length size empty?].freeze
|
47
48
|
|
48
49
|
def_node_matcher :redundant_chars_call?, <<~PATTERN
|
49
|
-
(send $(send _ :chars)
|
50
|
+
(send $(send _ :chars) $_ $...)
|
50
51
|
PATTERN
|
51
52
|
|
52
53
|
def on_send(node)
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
end
|
58
|
-
end
|
54
|
+
return unless (receiver, method, args = redundant_chars_call?(node))
|
55
|
+
|
56
|
+
range = offense_range(receiver, node)
|
57
|
+
message = build_message(method, args)
|
59
58
|
|
60
|
-
|
61
|
-
redundant_chars_call?(node) do |receiver, method, args|
|
59
|
+
add_offense(range, message: message) do |corrector|
|
62
60
|
range = correction_range(receiver, node)
|
63
61
|
replacement = build_good_method(method, args)
|
64
62
|
|
65
|
-
|
66
|
-
corrector.replace(range, replacement)
|
67
|
-
end
|
63
|
+
corrector.replace(range, replacement)
|
68
64
|
end
|
69
65
|
end
|
70
66
|
|
71
67
|
private
|
72
68
|
|
73
|
-
def replaceable_method?(method_name)
|
74
|
-
REPLACEABLE_METHODS.include?(method_name)
|
75
|
-
end
|
76
|
-
|
77
69
|
def offense_range(receiver, node)
|
78
70
|
range_between(receiver.loc.selector.begin_pos, node.loc.expression.end_pos)
|
79
71
|
end
|
@@ -72,7 +72,9 @@ module RuboCop
|
|
72
72
|
# do_something($~)
|
73
73
|
# end
|
74
74
|
# end
|
75
|
-
class RegexpMatch <
|
75
|
+
class RegexpMatch < Base
|
76
|
+
extend AutoCorrector
|
77
|
+
|
76
78
|
# Constants are included in this list because it is unlikely that
|
77
79
|
# someone will store `nil` as a constant and then use it for comparison
|
78
80
|
TYPES_IMPLEMENTING_MATCH = %i[const regexp str sym].freeze
|
@@ -141,27 +143,28 @@ module RuboCop
|
|
141
143
|
end
|
142
144
|
end
|
143
145
|
|
144
|
-
def autocorrect(node)
|
145
|
-
lambda do |corrector|
|
146
|
-
if match_method?(node) || match_with_int_arg_method?(node)
|
147
|
-
corrector.replace(node.loc.selector, 'match?')
|
148
|
-
elsif match_operator?(node) || match_threequals?(node)
|
149
|
-
recv, oper, arg = *node
|
150
|
-
correct_operator(corrector, recv, arg, oper)
|
151
|
-
elsif match_with_lvasgn?(node)
|
152
|
-
recv, arg = *node
|
153
|
-
correct_operator(corrector, recv, arg)
|
154
|
-
end
|
155
|
-
end
|
156
|
-
end
|
157
|
-
|
158
146
|
private
|
159
147
|
|
160
148
|
def check_condition(cond)
|
161
149
|
match_node?(cond) do
|
162
150
|
return if last_match_used?(cond)
|
163
151
|
|
164
|
-
|
152
|
+
message = message(cond)
|
153
|
+
add_offense(cond, message: message) do |corrector|
|
154
|
+
autocorrect(corrector, cond)
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
def autocorrect(corrector, node)
|
160
|
+
if match_method?(node) || match_with_int_arg_method?(node)
|
161
|
+
corrector.replace(node.loc.selector, 'match?')
|
162
|
+
elsif match_operator?(node) || match_threequals?(node)
|
163
|
+
recv, oper, arg = *node
|
164
|
+
correct_operator(corrector, recv, arg, oper)
|
165
|
+
elsif match_with_lvasgn?(node)
|
166
|
+
recv, arg = *node
|
167
|
+
correct_operator(corrector, recv, arg)
|
165
168
|
end
|
166
169
|
end
|
167
170
|
|
@@ -231,10 +234,7 @@ module RuboCop
|
|
231
234
|
|
232
235
|
def scope_root(node)
|
233
236
|
node.each_ancestor.find do |ancestor|
|
234
|
-
ancestor.def_type? ||
|
235
|
-
ancestor.defs_type? ||
|
236
|
-
ancestor.class_type? ||
|
237
|
-
ancestor.module_type?
|
237
|
+
ancestor.def_type? || ancestor.defs_type? || ancestor.class_type? || ancestor.module_type?
|
238
238
|
end
|
239
239
|
end
|
240
240
|
|
@@ -12,10 +12,12 @@ module RuboCop
|
|
12
12
|
#
|
13
13
|
# # good
|
14
14
|
# [].reverse_each
|
15
|
-
class ReverseEach <
|
15
|
+
class ReverseEach < Base
|
16
16
|
include RangeHelp
|
17
|
+
extend AutoCorrector
|
17
18
|
|
18
19
|
MSG = 'Use `reverse_each` instead of `reverse.each`.'
|
20
|
+
RESTRICT_ON_SEND = %i[each].freeze
|
19
21
|
UNDERSCORE = '_'
|
20
22
|
|
21
23
|
def_node_matcher :reverse_each?, <<~MATCHER
|
@@ -29,13 +31,16 @@ module RuboCop
|
|
29
31
|
|
30
32
|
range = range_between(location_of_reverse, end_location)
|
31
33
|
|
32
|
-
add_offense(
|
34
|
+
add_offense(range) do |corrector|
|
35
|
+
corrector.replace(replacement_range(node), UNDERSCORE)
|
36
|
+
end
|
33
37
|
end
|
34
38
|
end
|
35
39
|
|
36
|
-
|
37
|
-
|
38
|
-
|
40
|
+
private
|
41
|
+
|
42
|
+
def replacement_range(node)
|
43
|
+
range_between(node.loc.dot.begin_pos, node.loc.selector.begin_pos)
|
39
44
|
end
|
40
45
|
end
|
41
46
|
end
|
@@ -16,10 +16,12 @@ module RuboCop
|
|
16
16
|
# array.last(5).reverse
|
17
17
|
# array.last
|
18
18
|
#
|
19
|
-
class ReverseFirst <
|
19
|
+
class ReverseFirst < Base
|
20
20
|
include RangeHelp
|
21
|
+
extend AutoCorrector
|
21
22
|
|
22
23
|
MSG = 'Use `%<good_method>s` instead of `%<bad_method>s`.'
|
24
|
+
RESTRICT_ON_SEND = %i[first].freeze
|
23
25
|
|
24
26
|
def_node_matcher :reverse_first_candidate?, <<~PATTERN
|
25
27
|
(send $(send _ :reverse) :first (int _)?)
|
@@ -30,16 +32,9 @@ module RuboCop
|
|
30
32
|
range = correction_range(receiver, node)
|
31
33
|
message = build_message(node)
|
32
34
|
|
33
|
-
add_offense(
|
34
|
-
|
35
|
-
end
|
36
|
-
|
37
|
-
def autocorrect(node)
|
38
|
-
reverse_first_candidate?(node) do |receiver|
|
39
|
-
range = correction_range(receiver, node)
|
40
|
-
replacement = build_good_method(node)
|
35
|
+
add_offense(range, message: message) do |corrector|
|
36
|
+
replacement = build_good_method(node)
|
41
37
|
|
42
|
-
lambda do |corrector|
|
43
38
|
corrector.replace(range, replacement)
|
44
39
|
end
|
45
40
|
end
|
@@ -35,8 +35,11 @@ module RuboCop
|
|
35
35
|
# [1, 2, 3].count { |e| e > 2 }
|
36
36
|
# TODO: Add advanced detection of variables that could
|
37
37
|
# have been assigned to an array or a hash.
|
38
|
-
class Size <
|
38
|
+
class Size < Base
|
39
|
+
extend AutoCorrector
|
40
|
+
|
39
41
|
MSG = 'Use `size` instead of `count`.'
|
42
|
+
RESTRICT_ON_SEND = %i[count].freeze
|
40
43
|
|
41
44
|
def_node_matcher :array?, <<~PATTERN
|
42
45
|
{
|
@@ -63,11 +66,9 @@ module RuboCop
|
|
63
66
|
def on_send(node)
|
64
67
|
return if node.parent&.block_type? || !count?(node)
|
65
68
|
|
66
|
-
add_offense(node
|
67
|
-
|
68
|
-
|
69
|
-
def autocorrect(node)
|
70
|
-
->(corrector) { corrector.replace(node.loc.selector, 'size') }
|
69
|
+
add_offense(node.loc.selector) do |corrector|
|
70
|
+
corrector.replace(node.loc.selector, 'size')
|
71
|
+
end
|
71
72
|
end
|
72
73
|
end
|
73
74
|
end
|
@@ -13,8 +13,9 @@ module RuboCop
|
|
13
13
|
# # good
|
14
14
|
# array.sort.reverse
|
15
15
|
#
|
16
|
-
class SortReverse <
|
16
|
+
class SortReverse < Base
|
17
17
|
include SortBlock
|
18
|
+
extend AutoCorrector
|
18
19
|
|
19
20
|
MSG = 'Use `sort.reverse` instead of `%<bad_method>s`.'
|
20
21
|
|
@@ -23,21 +24,11 @@ module RuboCop
|
|
23
24
|
replaceable_body?(body, var_b, var_a) do
|
24
25
|
range = sort_range(send, node)
|
25
26
|
|
26
|
-
add_offense(
|
27
|
-
|
28
|
-
location: range,
|
29
|
-
message: message(var_a, var_b)
|
30
|
-
)
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
27
|
+
add_offense(range, message: message(var_a, var_b)) do |corrector|
|
28
|
+
replacement = 'sort.reverse'
|
34
29
|
|
35
|
-
|
36
|
-
|
37
|
-
lambda do |corrector|
|
38
|
-
range = sort_range(send, node)
|
39
|
-
replacement = 'sort.reverse'
|
40
|
-
corrector.replace(range, replacement)
|
30
|
+
corrector.replace(range, replacement)
|
31
|
+
end
|
41
32
|
end
|
42
33
|
end
|
43
34
|
end
|
@@ -18,8 +18,11 @@ module RuboCop
|
|
18
18
|
# str.squeeze('a')
|
19
19
|
# str.squeeze!('a')
|
20
20
|
#
|
21
|
-
class Squeeze <
|
21
|
+
class Squeeze < Base
|
22
|
+
extend AutoCorrector
|
23
|
+
|
22
24
|
MSG = 'Use `%<prefer>s` instead of `%<current>s`.'
|
25
|
+
RESTRICT_ON_SEND = %i[gsub gsub!].freeze
|
23
26
|
|
24
27
|
PREFERRED_METHODS = {
|
25
28
|
gsub: :squeeze,
|
@@ -36,24 +39,18 @@ module RuboCop
|
|
36
39
|
PATTERN
|
37
40
|
|
38
41
|
def on_send(node)
|
39
|
-
squeeze_candidate?(node) do |
|
42
|
+
squeeze_candidate?(node) do |receiver, bad_method, regexp_str, replace_str|
|
40
43
|
regexp_str = regexp_str[0..-2] # delete '+' from the end
|
41
44
|
regexp_str = interpret_string_escapes(regexp_str)
|
42
45
|
return unless replace_str == regexp_str
|
43
46
|
|
44
47
|
good_method = PREFERRED_METHODS[bad_method]
|
45
48
|
message = format(MSG, current: bad_method, prefer: good_method)
|
46
|
-
add_offense(node, location: :selector, message: message)
|
47
|
-
end
|
48
|
-
end
|
49
49
|
|
50
|
-
|
51
|
-
squeeze_candidate?(node) do |receiver, bad_method, _regexp_str, replace_str|
|
52
|
-
lambda do |corrector|
|
53
|
-
good_method = PREFERRED_METHODS[bad_method]
|
50
|
+
add_offense(node.loc.selector, message: message) do |corrector|
|
54
51
|
string_literal = to_string_literal(replace_str)
|
55
|
-
|
56
52
|
new_code = "#{receiver.source}.#{good_method}(#{string_literal})"
|
53
|
+
|
57
54
|
corrector.replace(node.source_range, new_code)
|
58
55
|
end
|
59
56
|
end
|
@@ -62,7 +59,7 @@ module RuboCop
|
|
62
59
|
private
|
63
60
|
|
64
61
|
def repeating_literal?(regex_str)
|
65
|
-
regex_str.match?(/\A(?:#{Util::LITERAL_REGEX})\+\z/)
|
62
|
+
regex_str.match?(/\A(?:#{Util::LITERAL_REGEX})\+\z/o)
|
66
63
|
end
|
67
64
|
end
|
68
65
|
end
|
@@ -41,11 +41,13 @@ module RuboCop
|
|
41
41
|
# 'abc'.match(/^ab/)
|
42
42
|
# /^ab/.match('abc')
|
43
43
|
#
|
44
|
-
class StartWith <
|
44
|
+
class StartWith < Base
|
45
45
|
include RegexpMetacharacter
|
46
|
+
extend AutoCorrector
|
46
47
|
|
47
48
|
MSG = 'Use `String#start_with?` instead of a regex match anchored to ' \
|
48
49
|
'the beginning of the string.'
|
50
|
+
RESTRICT_ON_SEND = %i[match =~ match?].freeze
|
49
51
|
|
50
52
|
def_node_matcher :redundant_regex?, <<~PATTERN
|
51
53
|
{(send $!nil? {:match :=~ :match?} (regexp (str $#literal_at_start?) (regopt)))
|
@@ -54,25 +56,19 @@ module RuboCop
|
|
54
56
|
PATTERN
|
55
57
|
|
56
58
|
def on_send(node)
|
57
|
-
return unless redundant_regex?(node)
|
59
|
+
return unless (receiver, regex_str = redundant_regex?(node))
|
58
60
|
|
59
|
-
add_offense(node)
|
60
|
-
end
|
61
|
-
alias on_match_with_lvasgn on_send
|
62
|
-
|
63
|
-
def autocorrect(node)
|
64
|
-
redundant_regex?(node) do |receiver, regex_str|
|
61
|
+
add_offense(node) do |corrector|
|
65
62
|
receiver, regex_str = regex_str, receiver if receiver.is_a?(String)
|
66
63
|
regex_str = drop_start_metacharacter(regex_str)
|
67
64
|
regex_str = interpret_string_escapes(regex_str)
|
68
65
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
corrector.replace(node.source_range, new_source)
|
73
|
-
end
|
66
|
+
new_source = "#{receiver.source}.start_with?(#{to_string_literal(regex_str)})"
|
67
|
+
|
68
|
+
corrector.replace(node.source_range, new_source)
|
74
69
|
end
|
75
70
|
end
|
71
|
+
alias on_match_with_lvasgn on_send
|
76
72
|
end
|
77
73
|
end
|
78
74
|
end
|
@@ -6,6 +6,8 @@ module RuboCop
|
|
6
6
|
# This cop identifies unnecessary use of a regex where
|
7
7
|
# `String#include?` would suffice.
|
8
8
|
#
|
9
|
+
# This cop's offenses are not safe to auto-correct if a receiver is nil.
|
10
|
+
#
|
9
11
|
# @example
|
10
12
|
# # bad
|
11
13
|
# 'abc'.match?(/ab/)
|
@@ -17,8 +19,11 @@ module RuboCop
|
|
17
19
|
#
|
18
20
|
# # good
|
19
21
|
# 'abc'.include?('ab')
|
20
|
-
class StringInclude <
|
22
|
+
class StringInclude < Base
|
23
|
+
extend AutoCorrector
|
24
|
+
|
21
25
|
MSG = 'Use `String#include?` instead of a regex match with literal-only pattern.'
|
26
|
+
RESTRICT_ON_SEND = %i[match =~ match?].freeze
|
22
27
|
|
23
28
|
def_node_matcher :redundant_regex?, <<~PATTERN
|
24
29
|
{(send $!nil? {:match :=~ :match?} (regexp (str $#literal?) (regopt)))
|
@@ -27,29 +32,23 @@ module RuboCop
|
|
27
32
|
PATTERN
|
28
33
|
|
29
34
|
def on_send(node)
|
30
|
-
return unless redundant_regex?(node)
|
35
|
+
return unless (receiver, regex_str = redundant_regex?(node))
|
31
36
|
|
32
|
-
add_offense(node)
|
33
|
-
end
|
34
|
-
alias on_match_with_lvasgn on_send
|
35
|
-
|
36
|
-
def autocorrect(node)
|
37
|
-
redundant_regex?(node) do |receiver, regex_str|
|
37
|
+
add_offense(node) do |corrector|
|
38
38
|
receiver, regex_str = regex_str, receiver if receiver.is_a?(String)
|
39
39
|
regex_str = interpret_string_escapes(regex_str)
|
40
40
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
corrector.replace(node.source_range, new_source)
|
45
|
-
end
|
41
|
+
new_source = "#{receiver.source}.include?(#{to_string_literal(regex_str)})"
|
42
|
+
|
43
|
+
corrector.replace(node.source_range, new_source)
|
46
44
|
end
|
47
45
|
end
|
46
|
+
alias on_match_with_lvasgn on_send
|
48
47
|
|
49
48
|
private
|
50
49
|
|
51
50
|
def literal?(regex_str)
|
52
|
-
regex_str.match?(/\A#{Util::LITERAL_REGEX}+\z/)
|
51
|
+
regex_str.match?(/\A#{Util::LITERAL_REGEX}+\z/o)
|
53
52
|
end
|
54
53
|
end
|
55
54
|
end
|
@@ -18,10 +18,12 @@ module RuboCop
|
|
18
18
|
# 'abc'.gsub(/a+/, 'd')
|
19
19
|
# 'abc'.tr('b', 'd')
|
20
20
|
# 'a b c'.delete(' ')
|
21
|
-
class StringReplacement <
|
21
|
+
class StringReplacement < Base
|
22
22
|
include RangeHelp
|
23
|
+
extend AutoCorrector
|
23
24
|
|
24
25
|
MSG = 'Use `%<prefer>s` instead of `%<current>s`.'
|
26
|
+
RESTRICT_ON_SEND = %i[gsub gsub!].freeze
|
25
27
|
DETERMINISTIC_REGEX = /\A(?:#{LITERAL_REGEX})+\Z/.freeze
|
26
28
|
DELETE = 'delete'
|
27
29
|
TR = 'tr'
|
@@ -42,33 +44,37 @@ module RuboCop
|
|
42
44
|
end
|
43
45
|
end
|
44
46
|
|
45
|
-
|
47
|
+
private
|
48
|
+
|
49
|
+
def offense(node, first_param, second_param)
|
50
|
+
first_source, = first_source(first_param)
|
51
|
+
first_source = interpret_string_escapes(first_source) unless first_param.str_type?
|
52
|
+
second_source, = *second_param
|
53
|
+
message = message(node, first_source, second_source)
|
54
|
+
|
55
|
+
add_offense(range(node), message: message) do |corrector|
|
56
|
+
autocorrect(corrector, node)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def autocorrect(corrector, node)
|
46
61
|
_string, _method, first_param, second_param = *node
|
47
62
|
first_source, = first_source(first_param)
|
48
63
|
second_source, = *second_param
|
49
64
|
|
50
65
|
first_source = interpret_string_escapes(first_source) unless first_param.str_type?
|
51
66
|
|
52
|
-
|
53
|
-
replacement_method(node, first_source, second_source)
|
54
|
-
|
55
|
-
replace_method(node, first_source, second_source, first_param,
|
56
|
-
replacement_method)
|
67
|
+
replace_method(corrector, node, first_source, second_source, first_param)
|
57
68
|
end
|
58
69
|
|
59
|
-
def replace_method(node,
|
60
|
-
|
61
|
-
corrector.replace(node.loc.selector, replacement)
|
62
|
-
unless first_param.str_type?
|
63
|
-
corrector.replace(first_param.source_range,
|
64
|
-
to_string_literal(first))
|
65
|
-
end
|
70
|
+
def replace_method(corrector, node, first_source, second_source, first_param)
|
71
|
+
replacement_method = replacement_method(node, first_source, second_source)
|
66
72
|
|
67
|
-
|
68
|
-
|
69
|
-
end
|
73
|
+
corrector.replace(node.loc.selector, replacement_method)
|
74
|
+
corrector.replace(first_param.source_range, to_string_literal(first_source)) unless first_param.str_type?
|
70
75
|
|
71
|
-
|
76
|
+
remove_second_param(corrector, node, first_param) if second_source.empty? && first_source.length == 1
|
77
|
+
end
|
72
78
|
|
73
79
|
def accept_second_param?(second_param)
|
74
80
|
second_source, = *second_param
|
@@ -92,15 +98,6 @@ module RuboCop
|
|
92
98
|
first_source.length != 1
|
93
99
|
end
|
94
100
|
|
95
|
-
def offense(node, first_param, second_param)
|
96
|
-
first_source, = first_source(first_param)
|
97
|
-
first_source = interpret_string_escapes(first_source) unless first_param.str_type?
|
98
|
-
second_source, = *second_param
|
99
|
-
message = message(node, first_source, second_source)
|
100
|
-
|
101
|
-
add_offense(node, location: range(node), message: message)
|
102
|
-
end
|
103
|
-
|
104
101
|
def first_source(first_param)
|
105
102
|
case first_param.type
|
106
103
|
when :regexp
|