rubocop-performance 1.7.1 → 1.8.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/config/default.yml +18 -7
- data/lib/rubocop/cop/performance/ancestors_include.rb +14 -13
- data/lib/rubocop/cop/performance/big_decimal_with_numeric_argument.rb +7 -12
- data/lib/rubocop/cop/performance/bind_call.rb +8 -18
- data/lib/rubocop/cop/performance/caller.rb +3 -2
- data/lib/rubocop/cop/performance/case_when_splat.rb +18 -11
- data/lib/rubocop/cop/performance/casecmp.rb +12 -20
- data/lib/rubocop/cop/performance/chain_array_allocation.rb +4 -10
- 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/count.rb +13 -16
- data/lib/rubocop/cop/performance/delete_prefix.rb +13 -22
- data/lib/rubocop/cop/performance/delete_suffix.rb +13 -22
- data/lib/rubocop/cop/performance/detect.rb +29 -26
- data/lib/rubocop/cop/performance/double_start_end_with.rb +16 -24
- data/lib/rubocop/cop/performance/end_with.rb +8 -13
- data/lib/rubocop/cop/performance/fixed_size.rb +1 -1
- data/lib/rubocop/cop/performance/flat_map.rb +20 -22
- data/lib/rubocop/cop/performance/inefficient_hash_search.rb +13 -14
- data/lib/rubocop/cop/performance/io_readlines.rb +25 -36
- data/lib/rubocop/cop/performance/open_struct.rb +2 -2
- data/lib/rubocop/cop/performance/range_include.rb +7 -6
- data/lib/rubocop/cop/performance/redundant_block_call.rb +11 -6
- data/lib/rubocop/cop/performance/redundant_match.rb +11 -6
- data/lib/rubocop/cop/performance/redundant_merge.rb +18 -17
- data/lib/rubocop/cop/performance/redundant_sort_block.rb +6 -16
- data/lib/rubocop/cop/performance/redundant_string_chars.rb +8 -12
- data/lib/rubocop/cop/performance/regexp_match.rb +20 -20
- data/lib/rubocop/cop/performance/reverse_each.rb +9 -5
- data/lib/rubocop/cop/performance/reverse_first.rb +4 -10
- data/lib/rubocop/cop/performance/size.rb +6 -6
- data/lib/rubocop/cop/performance/sort_reverse.rb +6 -15
- data/lib/rubocop/cop/performance/squeeze.rb +6 -10
- data/lib/rubocop/cop/performance/start_with.rb +8 -13
- data/lib/rubocop/cop/performance/string_include.rb +9 -13
- data/lib/rubocop/cop/performance/string_replacement.rb +23 -27
- data/lib/rubocop/cop/performance/sum.rb +129 -0
- data/lib/rubocop/cop/performance/times_map.rb +11 -18
- data/lib/rubocop/cop/performance/unfreeze_string.rb +1 -1
- data/lib/rubocop/cop/performance/uri_default_parser.rb +6 -12
- data/lib/rubocop/cop/performance_cops.rb +2 -0
- data/lib/rubocop/performance/version.rb +1 -1
- metadata +6 -4
@@ -23,8 +23,9 @@ module RuboCop
|
|
23
23
|
# array.max_by(&:foo)
|
24
24
|
# array.min_by(&:foo)
|
25
25
|
# array.sort_by { |a| a[:foo] }
|
26
|
-
class CompareWithBlock <
|
26
|
+
class CompareWithBlock < Base
|
27
27
|
include RangeHelp
|
28
|
+
extend AutoCorrector
|
28
29
|
|
29
30
|
MSG = 'Use `%<compare_method>s_by%<instead>s` instead of ' \
|
30
31
|
'`%<compare_method>s { |%<var_a>s, %<var_b>s| %<str_a>s ' \
|
@@ -51,27 +52,15 @@ module RuboCop
|
|
51
52
|
|
52
53
|
range = compare_range(send, node)
|
53
54
|
|
54
|
-
add_offense(
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
end
|
62
|
-
|
63
|
-
def autocorrect(node)
|
64
|
-
lambda do |corrector|
|
65
|
-
send, var_a, var_b, body = compare?(node)
|
66
|
-
method, arg, = replaceable_body?(body, var_a, var_b)
|
67
|
-
replacement =
|
68
|
-
if method == :[]
|
69
|
-
"#{send.method_name}_by { |a| a[#{arg.first.source}] }"
|
70
|
-
else
|
71
|
-
"#{send.method_name}_by(&:#{method})"
|
55
|
+
add_offense(range, message: message(send, method, var_a, var_b, args_a)) do |corrector|
|
56
|
+
replacement = if method == :[]
|
57
|
+
"#{send.method_name}_by { |a| a[#{args_a.first.source}] }"
|
58
|
+
else
|
59
|
+
"#{send.method_name}_by(&:#{method})"
|
60
|
+
end
|
61
|
+
corrector.replace(range, replacement)
|
72
62
|
end
|
73
|
-
|
74
|
-
replacement)
|
63
|
+
end
|
75
64
|
end
|
76
65
|
end
|
77
66
|
|
@@ -4,7 +4,7 @@ module RuboCop
|
|
4
4
|
module Cop
|
5
5
|
module Performance
|
6
6
|
# This cop is used to identify usages of `count` on an `Enumerable` that
|
7
|
-
# follow calls to `select` or `reject`. Querying logic can instead be
|
7
|
+
# follow calls to `select`, `find_all`, `filter` or `reject`. Querying logic can instead be
|
8
8
|
# passed to the `count` call.
|
9
9
|
#
|
10
10
|
# @example
|
@@ -37,15 +37,16 @@ module RuboCop
|
|
37
37
|
# becomes:
|
38
38
|
#
|
39
39
|
# `Model.where(id: [1, 2, 3]).to_a.count { |m| m.method == true }`
|
40
|
-
class Count <
|
40
|
+
class Count < Base
|
41
41
|
include RangeHelp
|
42
|
+
extend AutoCorrector
|
42
43
|
|
43
44
|
MSG = 'Use `count` instead of `%<selector>s...%<counter>s`.'
|
44
45
|
|
45
46
|
def_node_matcher :count_candidate?, <<~PATTERN
|
46
47
|
{
|
47
|
-
(send (block $(send _ ${:select :reject}) ...) ${:count :length :size})
|
48
|
-
(send $(send _ ${:select :reject} (:block_pass _)) ${:count :length :size})
|
48
|
+
(send (block $(send _ ${:select :filter :find_all :reject}) ...) ${:count :length :size})
|
49
|
+
(send $(send _ ${:select :filter :find_all :reject} (:block_pass _)) ${:count :length :size})
|
49
50
|
}
|
50
51
|
PATTERN
|
51
52
|
|
@@ -57,29 +58,25 @@ module RuboCop
|
|
57
58
|
selector_node.loc.selector.begin_pos
|
58
59
|
end
|
59
60
|
|
60
|
-
add_offense(
|
61
|
-
|
62
|
-
|
63
|
-
counter: counter))
|
61
|
+
add_offense(range, message: format(MSG, selector: selector, counter: counter)) do |corrector|
|
62
|
+
autocorrect(corrector, node, selector_node, selector)
|
63
|
+
end
|
64
64
|
end
|
65
65
|
end
|
66
66
|
|
67
|
-
|
68
|
-
|
67
|
+
private
|
68
|
+
|
69
|
+
def autocorrect(corrector, node, selector_node, selector)
|
69
70
|
selector_loc = selector_node.loc.selector
|
70
71
|
|
71
72
|
return if selector == :reject
|
72
73
|
|
73
74
|
range = source_starting_at(node) { |n| n.loc.dot.begin_pos }
|
74
75
|
|
75
|
-
|
76
|
-
|
77
|
-
corrector.replace(selector_loc, 'count')
|
78
|
-
end
|
76
|
+
corrector.remove(range)
|
77
|
+
corrector.replace(selector_loc, 'count')
|
79
78
|
end
|
80
79
|
|
81
|
-
private
|
82
|
-
|
83
80
|
def eligible_node?(node)
|
84
81
|
!(node.parent && node.parent.block_type?)
|
85
82
|
end
|
@@ -43,9 +43,10 @@ module RuboCop
|
|
43
43
|
# str.sub(/^prefix/, '')
|
44
44
|
# str.sub!(/^prefix/, '')
|
45
45
|
#
|
46
|
-
class DeletePrefix <
|
47
|
-
extend TargetRubyVersion
|
46
|
+
class DeletePrefix < Base
|
48
47
|
include RegexpMetacharacter
|
48
|
+
extend AutoCorrector
|
49
|
+
extend TargetRubyVersion
|
49
50
|
|
50
51
|
minimum_target_ruby_version 2.5
|
51
52
|
|
@@ -63,31 +64,21 @@ module RuboCop
|
|
63
64
|
PATTERN
|
64
65
|
|
65
66
|
def on_send(node)
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
good_method = PREFERRED_METHODS[bad_method]
|
67
|
+
return unless (receiver, bad_method, regexp_str, replace_string = delete_prefix_candidate?(node))
|
68
|
+
return unless replace_string.blank?
|
70
69
|
|
71
|
-
|
70
|
+
good_method = PREFERRED_METHODS[bad_method]
|
72
71
|
|
73
|
-
|
74
|
-
end
|
75
|
-
end
|
72
|
+
message = format(MSG, current: bad_method, prefer: good_method)
|
76
73
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
regexp_str = drop_start_metacharacter(regexp_str)
|
82
|
-
regexp_str = interpret_string_escapes(regexp_str)
|
83
|
-
string_literal = to_string_literal(regexp_str)
|
74
|
+
add_offense(node.loc.selector, message: message) do |corrector|
|
75
|
+
regexp_str = drop_start_metacharacter(regexp_str)
|
76
|
+
regexp_str = interpret_string_escapes(regexp_str)
|
77
|
+
string_literal = to_string_literal(regexp_str)
|
84
78
|
|
85
|
-
|
79
|
+
new_code = "#{receiver.source}.#{good_method}(#{string_literal})"
|
86
80
|
|
87
|
-
|
88
|
-
# https://github.com/rubocop-hq/rubocop/commit/82eb350d2cba16
|
89
|
-
corrector.replace(node.source_range, new_code)
|
90
|
-
end
|
81
|
+
corrector.replace(node, new_code)
|
91
82
|
end
|
92
83
|
end
|
93
84
|
end
|
@@ -43,9 +43,10 @@ module RuboCop
|
|
43
43
|
# str.sub(/suffix$/, '')
|
44
44
|
# str.sub!(/suffix$/, '')
|
45
45
|
#
|
46
|
-
class DeleteSuffix <
|
47
|
-
extend TargetRubyVersion
|
46
|
+
class DeleteSuffix < Base
|
48
47
|
include RegexpMetacharacter
|
48
|
+
extend AutoCorrector
|
49
|
+
extend TargetRubyVersion
|
49
50
|
|
50
51
|
minimum_target_ruby_version 2.5
|
51
52
|
|
@@ -63,31 +64,21 @@ module RuboCop
|
|
63
64
|
PATTERN
|
64
65
|
|
65
66
|
def on_send(node)
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
good_method = PREFERRED_METHODS[bad_method]
|
67
|
+
return unless (receiver, bad_method, regexp_str, replace_string = delete_suffix_candidate?(node))
|
68
|
+
return unless replace_string.blank?
|
70
69
|
|
71
|
-
|
70
|
+
good_method = PREFERRED_METHODS[bad_method]
|
72
71
|
|
73
|
-
|
74
|
-
end
|
75
|
-
end
|
72
|
+
message = format(MSG, current: bad_method, prefer: good_method)
|
76
73
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
regexp_str = drop_end_metacharacter(regexp_str)
|
82
|
-
regexp_str = interpret_string_escapes(regexp_str)
|
83
|
-
string_literal = to_string_literal(regexp_str)
|
74
|
+
add_offense(node.loc.selector, message: message) do |corrector|
|
75
|
+
regexp_str = drop_end_metacharacter(regexp_str)
|
76
|
+
regexp_str = interpret_string_escapes(regexp_str)
|
77
|
+
string_literal = to_string_literal(regexp_str)
|
84
78
|
|
85
|
-
|
79
|
+
new_code = "#{receiver.source}.#{good_method}(#{string_literal})"
|
86
80
|
|
87
|
-
|
88
|
-
# https://github.com/rubocop-hq/rubocop/commit/82eb350d2cba16
|
89
|
-
corrector.replace(node.source_range, new_code)
|
90
|
-
end
|
81
|
+
corrector.replace(node, new_code)
|
91
82
|
end
|
92
83
|
end
|
93
84
|
end
|
@@ -4,7 +4,7 @@ module RuboCop
|
|
4
4
|
module Cop
|
5
5
|
module Performance
|
6
6
|
# This cop is used to identify usages of
|
7
|
-
# `select.first`, `select.last`, `find_all.first`, and `
|
7
|
+
# `select.first`, `select.last`, `find_all.first`, `find_all.last`, `filter.first`, and `filter.last`
|
8
8
|
# and change them to use `detect` instead.
|
9
9
|
#
|
10
10
|
# @example
|
@@ -13,6 +13,8 @@ module RuboCop
|
|
13
13
|
# [].select { |item| true }.last
|
14
14
|
# [].find_all { |item| true }.first
|
15
15
|
# [].find_all { |item| true }.last
|
16
|
+
# [].filter { |item| true }.first
|
17
|
+
# [].filter { |item| true }.last
|
16
18
|
#
|
17
19
|
# # good
|
18
20
|
# [].detect { |item| true }
|
@@ -22,7 +24,9 @@ module RuboCop
|
|
22
24
|
# `ActiveRecord` does not implement a `detect` method and `find` has its
|
23
25
|
# own meaning. Correcting ActiveRecord methods with this cop should be
|
24
26
|
# considered unsafe.
|
25
|
-
class Detect <
|
27
|
+
class Detect < Base
|
28
|
+
extend AutoCorrector
|
29
|
+
|
26
30
|
MSG = 'Use `%<prefer>s` instead of ' \
|
27
31
|
'`%<first_method>s.%<second_method>s`.'
|
28
32
|
REVERSE_MSG = 'Use `reverse.%<prefer>s` instead of ' \
|
@@ -30,8 +34,8 @@ module RuboCop
|
|
30
34
|
|
31
35
|
def_node_matcher :detect_candidate?, <<~PATTERN
|
32
36
|
{
|
33
|
-
(send $(block (send _ {:select :find_all}) ...) ${:first :last} $...)
|
34
|
-
(send $(send _ {:select :find_all} ...) ${:first :last} $...)
|
37
|
+
(send $(block (send _ {:select :find_all :filter}) ...) ${:first :last} $...)
|
38
|
+
(send $(send _ {:select :find_all :filter} ...) ${:first :last} $...)
|
35
39
|
}
|
36
40
|
PATTERN
|
37
41
|
|
@@ -47,25 +51,6 @@ module RuboCop
|
|
47
51
|
end
|
48
52
|
end
|
49
53
|
|
50
|
-
def autocorrect(node)
|
51
|
-
receiver, first_method = *node
|
52
|
-
|
53
|
-
replacement = if first_method == :last
|
54
|
-
"reverse.#{preferred_method}"
|
55
|
-
else
|
56
|
-
preferred_method
|
57
|
-
end
|
58
|
-
|
59
|
-
first_range = receiver.source_range.end.join(node.loc.selector)
|
60
|
-
|
61
|
-
receiver, _args, _body = *receiver if receiver.block_type?
|
62
|
-
|
63
|
-
lambda do |corrector|
|
64
|
-
corrector.remove(first_range)
|
65
|
-
corrector.replace(receiver.loc.selector, replacement)
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
54
|
private
|
70
55
|
|
71
56
|
def accept_first_call?(receiver, body)
|
@@ -86,12 +71,30 @@ module RuboCop
|
|
86
71
|
first_method: first_method,
|
87
72
|
second_method: second_method)
|
88
73
|
|
89
|
-
add_offense(
|
74
|
+
add_offense(range, message: formatted_message) do |corrector|
|
75
|
+
autocorrect(corrector, node)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def autocorrect(corrector, node)
|
80
|
+
receiver, first_method = *node
|
81
|
+
|
82
|
+
replacement = if first_method == :last
|
83
|
+
"reverse.#{preferred_method}"
|
84
|
+
else
|
85
|
+
preferred_method
|
86
|
+
end
|
87
|
+
|
88
|
+
first_range = receiver.source_range.end.join(node.loc.selector)
|
89
|
+
|
90
|
+
receiver, _args, _body = *receiver if receiver.block_type?
|
91
|
+
|
92
|
+
corrector.remove(first_range)
|
93
|
+
corrector.replace(receiver.loc.selector, replacement)
|
90
94
|
end
|
91
95
|
|
92
96
|
def preferred_method
|
93
|
-
config.for_cop('Style/CollectionMethods')
|
94
|
-
['PreferredMethods']['detect'] || 'detect'
|
97
|
+
config.for_cop('Style/CollectionMethods')['PreferredMethods']['detect'] || 'detect'
|
95
98
|
end
|
96
99
|
|
97
100
|
def lazy?(node)
|
@@ -17,39 +17,34 @@ module RuboCop
|
|
17
17
|
# str.start_with?("a", Some::CONST)
|
18
18
|
# str.start_with?("a", "b", "c")
|
19
19
|
# str.end_with?(var1, var2)
|
20
|
-
class DoubleStartEndWith <
|
20
|
+
class DoubleStartEndWith < Base
|
21
|
+
extend AutoCorrector
|
22
|
+
|
21
23
|
MSG = 'Use `%<receiver>s.%<method>s(%<combined_args>s)` ' \
|
22
24
|
'instead of `%<original_code>s`.'
|
23
25
|
|
24
26
|
def on_or(node)
|
25
|
-
receiver,
|
26
|
-
method,
|
27
|
-
first_call_args,
|
28
|
-
second_call_args = process_source(node)
|
27
|
+
receiver, method, first_call_args, second_call_args = process_source(node)
|
29
28
|
|
30
29
|
return unless receiver && second_call_args.all?(&:pure?)
|
31
30
|
|
32
31
|
combined_args = combine_args(first_call_args, second_call_args)
|
33
32
|
|
34
|
-
|
33
|
+
add_offense(node, message: message(node, receiver, method, combined_args)) do |corrector|
|
34
|
+
autocorrect(corrector, first_call_args, second_call_args, combined_args)
|
35
|
+
end
|
35
36
|
end
|
36
37
|
|
37
|
-
|
38
|
-
_receiver, _method,
|
39
|
-
first_call_args, second_call_args = process_source(node)
|
38
|
+
private
|
40
39
|
|
41
|
-
|
40
|
+
def autocorrect(corrector, first_call_args, second_call_args, combined_args)
|
42
41
|
first_argument = first_call_args.first.loc.expression
|
43
42
|
last_argument = second_call_args.last.loc.expression
|
44
43
|
range = first_argument.join(last_argument)
|
45
44
|
|
46
|
-
|
47
|
-
corrector.replace(range, combined_args)
|
48
|
-
end
|
45
|
+
corrector.replace(range, combined_args)
|
49
46
|
end
|
50
47
|
|
51
|
-
private
|
52
|
-
|
53
48
|
def process_source(node)
|
54
49
|
if check_for_active_support_aliases?
|
55
50
|
check_with_active_support_aliases(node)
|
@@ -58,17 +53,14 @@ module RuboCop
|
|
58
53
|
end
|
59
54
|
end
|
60
55
|
|
61
|
-
def
|
62
|
-
(
|
56
|
+
def message(node, receiver, method, combined_args)
|
57
|
+
format(
|
58
|
+
MSG, receiver: receiver.source, method: method, combined_args: combined_args, original_code: node.source
|
59
|
+
)
|
63
60
|
end
|
64
61
|
|
65
|
-
def
|
66
|
-
|
67
|
-
method: method,
|
68
|
-
combined_args: combined_args,
|
69
|
-
original_code: node.source)
|
70
|
-
|
71
|
-
add_offense(node, message: msg)
|
62
|
+
def combine_args(first_call_args, second_call_args)
|
63
|
+
(first_call_args + second_call_args).map(&:source).join(', ')
|
72
64
|
end
|
73
65
|
|
74
66
|
def check_for_active_support_aliases?
|
@@ -41,8 +41,9 @@ module RuboCop
|
|
41
41
|
# 'abc'.match(/bc$/)
|
42
42
|
# /bc$/.match('abc')
|
43
43
|
#
|
44
|
-
class EndWith <
|
44
|
+
class EndWith < Base
|
45
45
|
include RegexpMetacharacter
|
46
|
+
extend AutoCorrector
|
46
47
|
|
47
48
|
MSG = 'Use `String#end_with?` instead of a regex match anchored to ' \
|
48
49
|
'the end of the string.'
|
@@ -54,25 +55,19 @@ module RuboCop
|
|
54
55
|
PATTERN
|
55
56
|
|
56
57
|
def on_send(node)
|
57
|
-
return unless redundant_regex?(node)
|
58
|
+
return unless (receiver, regex_str = redundant_regex?(node))
|
58
59
|
|
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|
|
60
|
+
add_offense(node) do |corrector|
|
65
61
|
receiver, regex_str = regex_str, receiver if receiver.is_a?(String)
|
66
62
|
regex_str = drop_end_metacharacter(regex_str)
|
67
63
|
regex_str = interpret_string_escapes(regex_str)
|
68
64
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
corrector.replace(node.source_range, new_source)
|
73
|
-
end
|
65
|
+
new_source = "#{receiver.source}.end_with?(#{to_string_literal(regex_str)})"
|
66
|
+
|
67
|
+
corrector.replace(node.source_range, new_source)
|
74
68
|
end
|
75
69
|
end
|
70
|
+
alias on_match_with_lvasgn on_send
|
76
71
|
end
|
77
72
|
end
|
78
73
|
end
|
@@ -14,8 +14,9 @@ module RuboCop
|
|
14
14
|
# [1, 2, 3, 4].flat_map { |e| [e, e] }
|
15
15
|
# [1, 2, 3, 4].map { |e| [e, e] }.flatten
|
16
16
|
# [1, 2, 3, 4].collect { |e| [e, e] }.flatten
|
17
|
-
class FlatMap <
|
17
|
+
class FlatMap < Base
|
18
18
|
include RangeHelp
|
19
|
+
extend AutoCorrector
|
19
20
|
|
20
21
|
MSG = 'Use `flat_map` instead of `%<method>s...%<flatten>s`.'
|
21
22
|
FLATTEN_MULTIPLE_LEVELS = ' Beware, `flat_map` only flattens 1 level ' \
|
@@ -44,25 +45,11 @@ module RuboCop
|
|
44
45
|
end
|
45
46
|
end
|
46
47
|
|
47
|
-
def autocorrect(node)
|
48
|
-
map_node, _first_method, _flatten, params = flat_map_candidate?(node)
|
49
|
-
flatten_level, = *params.first
|
50
|
-
|
51
|
-
return unless flatten_level
|
52
|
-
|
53
|
-
range = range_between(node.loc.dot.begin_pos,
|
54
|
-
node.source_range.end_pos)
|
55
|
-
|
56
|
-
lambda do |corrector|
|
57
|
-
corrector.remove(range)
|
58
|
-
corrector.replace(map_node.loc.selector, 'flat_map')
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
48
|
private
|
63
49
|
|
64
50
|
def offense_for_levels(node, map_node, first_method, flatten)
|
65
51
|
message = MSG + FLATTEN_MULTIPLE_LEVELS
|
52
|
+
|
66
53
|
register_offense(node, map_node, first_method, flatten, message)
|
67
54
|
end
|
68
55
|
|
@@ -71,13 +58,24 @@ module RuboCop
|
|
71
58
|
end
|
72
59
|
|
73
60
|
def register_offense(node, map_node, first_method, flatten, message)
|
74
|
-
range = range_between(map_node.loc.selector.begin_pos,
|
75
|
-
|
61
|
+
range = range_between(map_node.loc.selector.begin_pos, node.loc.expression.end_pos)
|
62
|
+
message = format(message, method: first_method, flatten: flatten)
|
63
|
+
|
64
|
+
add_offense(range, message: message) do |corrector|
|
65
|
+
autocorrect(corrector, node)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def autocorrect(corrector, node)
|
70
|
+
map_node, _first_method, _flatten, params = flat_map_candidate?(node)
|
71
|
+
flatten_level, = *params.first
|
72
|
+
|
73
|
+
return unless flatten_level
|
74
|
+
|
75
|
+
range = range_between(node.loc.dot.begin_pos, node.source_range.end_pos)
|
76
76
|
|
77
|
-
|
78
|
-
|
79
|
-
message: format(message, method: first_method,
|
80
|
-
flatten: flatten))
|
77
|
+
corrector.remove(range)
|
78
|
+
corrector.replace(map_node.loc.selector, 'flat_map')
|
81
79
|
end
|
82
80
|
end
|
83
81
|
end
|