rubocop-performance 1.5.2 → 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/LICENSE.txt +1 -1
- data/README.md +5 -1
- data/config/default.yml +96 -13
- data/lib/rubocop/cop/mixin/regexp_metacharacter.rb +76 -0
- data/lib/rubocop/cop/mixin/sort_block.rb +28 -0
- data/lib/rubocop/cop/performance/ancestors_include.rb +48 -0
- data/lib/rubocop/cop/performance/big_decimal_with_numeric_argument.rb +45 -0
- data/lib/rubocop/cop/performance/bind_call.rb +77 -0
- data/lib/rubocop/cop/performance/caller.rb +5 -4
- data/lib/rubocop/cop/performance/case_when_splat.rb +18 -11
- data/lib/rubocop/cop/performance/casecmp.rb +17 -23
- data/lib/rubocop/cop/performance/chain_array_allocation.rb +5 -11
- data/lib/rubocop/cop/performance/collection_literal_in_loop.rb +140 -0
- data/lib/rubocop/cop/performance/compare_with_block.rb +12 -23
- data/lib/rubocop/cop/performance/count.rb +14 -17
- data/lib/rubocop/cop/performance/delete_prefix.rb +87 -0
- data/lib/rubocop/cop/performance/delete_suffix.rb +87 -0
- data/lib/rubocop/cop/performance/detect.rb +30 -27
- data/lib/rubocop/cop/performance/double_start_end_with.rb +18 -26
- data/lib/rubocop/cop/performance/end_with.rb +38 -25
- data/lib/rubocop/cop/performance/fixed_size.rb +2 -2
- data/lib/rubocop/cop/performance/flat_map.rb +21 -23
- data/lib/rubocop/cop/performance/inefficient_hash_search.rb +14 -15
- data/lib/rubocop/cop/performance/io_readlines.rb +116 -0
- data/lib/rubocop/cop/performance/open_struct.rb +3 -3
- data/lib/rubocop/cop/performance/range_include.rb +15 -12
- data/lib/rubocop/cop/performance/redundant_block_call.rb +14 -9
- data/lib/rubocop/cop/performance/redundant_match.rb +13 -8
- data/lib/rubocop/cop/performance/redundant_merge.rb +36 -23
- data/lib/rubocop/cop/performance/redundant_sort_block.rb +43 -0
- data/lib/rubocop/cop/performance/redundant_string_chars.rb +133 -0
- data/lib/rubocop/cop/performance/regexp_match.rb +32 -32
- data/lib/rubocop/cop/performance/reverse_each.rb +10 -5
- data/lib/rubocop/cop/performance/reverse_first.rb +72 -0
- data/lib/rubocop/cop/performance/size.rb +41 -43
- data/lib/rubocop/cop/performance/sort_reverse.rb +45 -0
- data/lib/rubocop/cop/performance/squeeze.rb +66 -0
- data/lib/rubocop/cop/performance/start_with.rb +38 -28
- data/lib/rubocop/cop/performance/string_include.rb +55 -0
- data/lib/rubocop/cop/performance/string_replacement.rb +25 -36
- data/lib/rubocop/cop/performance/sum.rb +129 -0
- data/lib/rubocop/cop/performance/times_map.rb +12 -19
- data/lib/rubocop/cop/performance/unfreeze_string.rb +4 -8
- data/lib/rubocop/cop/performance/uri_default_parser.rb +7 -13
- data/lib/rubocop/cop/performance_cops.rb +17 -0
- data/lib/rubocop/performance/inject.rb +1 -1
- data/lib/rubocop/performance/version.rb +1 -1
- metadata +27 -11
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Performance
|
6
|
+
# This cop identifies places where `sort { |a, b| b <=> a }`
|
7
|
+
# can be replaced by a faster `sort.reverse`.
|
8
|
+
#
|
9
|
+
# @example
|
10
|
+
# # bad
|
11
|
+
# array.sort { |a, b| b <=> a }
|
12
|
+
#
|
13
|
+
# # good
|
14
|
+
# array.sort.reverse
|
15
|
+
#
|
16
|
+
class SortReverse < Base
|
17
|
+
include SortBlock
|
18
|
+
extend AutoCorrector
|
19
|
+
|
20
|
+
MSG = 'Use `sort.reverse` instead of `%<bad_method>s`.'
|
21
|
+
|
22
|
+
def on_block(node)
|
23
|
+
sort_with_block?(node) do |send, var_a, var_b, body|
|
24
|
+
replaceable_body?(body, var_b, var_a) do
|
25
|
+
range = sort_range(send, node)
|
26
|
+
|
27
|
+
add_offense(range, message: message(var_a, var_b)) do |corrector|
|
28
|
+
replacement = 'sort.reverse'
|
29
|
+
|
30
|
+
corrector.replace(range, replacement)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def message(var_a, var_b)
|
39
|
+
bad_method = "sort { |#{var_a}, #{var_b}| #{var_b} <=> #{var_a} }"
|
40
|
+
format(MSG, bad_method: bad_method)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Performance
|
6
|
+
# This cop identifies places where `gsub(/a+/, 'a')` and `gsub!(/a+/, 'a')`
|
7
|
+
# can be replaced by `squeeze('a')` and `squeeze!('a')`.
|
8
|
+
#
|
9
|
+
# The `squeeze('a')` method is faster than `gsub(/a+/, 'a')`.
|
10
|
+
#
|
11
|
+
# @example
|
12
|
+
#
|
13
|
+
# # bad
|
14
|
+
# str.gsub(/a+/, 'a')
|
15
|
+
# str.gsub!(/a+/, 'a')
|
16
|
+
#
|
17
|
+
# # good
|
18
|
+
# str.squeeze('a')
|
19
|
+
# str.squeeze!('a')
|
20
|
+
#
|
21
|
+
class Squeeze < Base
|
22
|
+
extend AutoCorrector
|
23
|
+
|
24
|
+
MSG = 'Use `%<prefer>s` instead of `%<current>s`.'
|
25
|
+
|
26
|
+
PREFERRED_METHODS = {
|
27
|
+
gsub: :squeeze,
|
28
|
+
gsub!: :squeeze!
|
29
|
+
}.freeze
|
30
|
+
|
31
|
+
def_node_matcher :squeeze_candidate?, <<~PATTERN
|
32
|
+
(send
|
33
|
+
$!nil? ${:gsub :gsub!}
|
34
|
+
(regexp
|
35
|
+
(str $#repeating_literal?)
|
36
|
+
(regopt))
|
37
|
+
(str $_))
|
38
|
+
PATTERN
|
39
|
+
|
40
|
+
def on_send(node)
|
41
|
+
squeeze_candidate?(node) do |receiver, bad_method, regexp_str, replace_str|
|
42
|
+
regexp_str = regexp_str[0..-2] # delete '+' from the end
|
43
|
+
regexp_str = interpret_string_escapes(regexp_str)
|
44
|
+
return unless replace_str == regexp_str
|
45
|
+
|
46
|
+
good_method = PREFERRED_METHODS[bad_method]
|
47
|
+
message = format(MSG, current: bad_method, prefer: good_method)
|
48
|
+
|
49
|
+
add_offense(node.loc.selector, message: message) do |corrector|
|
50
|
+
string_literal = to_string_literal(replace_str)
|
51
|
+
new_code = "#{receiver.source}.#{good_method}(#{string_literal})"
|
52
|
+
|
53
|
+
corrector.replace(node.source_range, new_code)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
def repeating_literal?(regex_str)
|
61
|
+
regex_str.match?(/\A(?:#{Util::LITERAL_REGEX})\+\z/)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -3,8 +3,11 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module Performance
|
6
|
-
# This cop identifies unnecessary use of a regex where
|
7
|
-
#
|
6
|
+
# This cop identifies unnecessary use of a regex where `String#start_with?` would suffice.
|
7
|
+
#
|
8
|
+
# This cop has `SafeMultiline` configuration option that `true` by default because
|
9
|
+
# `^start` is unsafe as it will behave incompatible with `start_with?`
|
10
|
+
# for receiver is multiline string.
|
8
11
|
#
|
9
12
|
# @example
|
10
13
|
# # bad
|
@@ -17,47 +20,54 @@ module RuboCop
|
|
17
20
|
#
|
18
21
|
# # good
|
19
22
|
# 'abc'.start_with?('ab')
|
20
|
-
|
23
|
+
#
|
24
|
+
# @example SafeMultiline: true (default)
|
25
|
+
#
|
26
|
+
# # good
|
27
|
+
# 'abc'.match?(/^ab/)
|
28
|
+
# /^ab/.match?('abc')
|
29
|
+
# 'abc' =~ /^ab/
|
30
|
+
# /^ab/ =~ 'abc'
|
31
|
+
# 'abc'.match(/^ab/)
|
32
|
+
# /^ab/.match('abc')
|
33
|
+
#
|
34
|
+
# @example SafeMultiline: false
|
35
|
+
#
|
36
|
+
# # bad
|
37
|
+
# 'abc'.match?(/^ab/)
|
38
|
+
# /^ab/.match?('abc')
|
39
|
+
# 'abc' =~ /^ab/
|
40
|
+
# /^ab/ =~ 'abc'
|
41
|
+
# 'abc'.match(/^ab/)
|
42
|
+
# /^ab/.match('abc')
|
43
|
+
#
|
44
|
+
class StartWith < Base
|
45
|
+
include RegexpMetacharacter
|
46
|
+
extend AutoCorrector
|
47
|
+
|
21
48
|
MSG = 'Use `String#start_with?` instead of a regex match anchored to ' \
|
22
49
|
'the beginning of the string.'
|
23
|
-
SINGLE_QUOTE = "'"
|
24
50
|
|
25
|
-
def_node_matcher :redundant_regex?,
|
51
|
+
def_node_matcher :redundant_regex?, <<~PATTERN
|
26
52
|
{(send $!nil? {:match :=~ :match?} (regexp (str $#literal_at_start?) (regopt)))
|
27
53
|
(send (regexp (str $#literal_at_start?) (regopt)) {:match :match?} $_)
|
28
54
|
(match-with-lvasgn (regexp (str $#literal_at_start?) (regopt)) $_)}
|
29
55
|
PATTERN
|
30
56
|
|
31
|
-
def literal_at_start?(regex_str)
|
32
|
-
# is this regexp 'literal' in the sense of only matching literal
|
33
|
-
# chars, rather than using metachars like `.` and `*` and so on?
|
34
|
-
# also, is it anchored at the start of the string?
|
35
|
-
# (tricky: \s, \d, and so on are metacharacters, but other characters
|
36
|
-
# escaped with a slash are just literals. LITERAL_REGEX takes all
|
37
|
-
# that into account.)
|
38
|
-
regex_str =~ /\A\\A(?:#{LITERAL_REGEX})+\z/
|
39
|
-
end
|
40
|
-
|
41
57
|
def on_send(node)
|
42
|
-
return unless redundant_regex?(node)
|
43
|
-
|
44
|
-
add_offense(node)
|
45
|
-
end
|
46
|
-
alias on_match_with_lvasgn on_send
|
58
|
+
return unless (receiver, regex_str = redundant_regex?(node))
|
47
59
|
|
48
|
-
|
49
|
-
redundant_regex?(node) do |receiver, regex_str|
|
60
|
+
add_offense(node) do |corrector|
|
50
61
|
receiver, regex_str = regex_str, receiver if receiver.is_a?(String)
|
51
|
-
regex_str = regex_str
|
62
|
+
regex_str = drop_start_metacharacter(regex_str)
|
52
63
|
regex_str = interpret_string_escapes(regex_str)
|
53
64
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
corrector.replace(node.source_range, new_source)
|
58
|
-
end
|
65
|
+
new_source = "#{receiver.source}.start_with?(#{to_string_literal(regex_str)})"
|
66
|
+
|
67
|
+
corrector.replace(node.source_range, new_source)
|
59
68
|
end
|
60
69
|
end
|
70
|
+
alias on_match_with_lvasgn on_send
|
61
71
|
end
|
62
72
|
end
|
63
73
|
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Performance
|
6
|
+
# This cop identifies unnecessary use of a regex where
|
7
|
+
# `String#include?` would suffice.
|
8
|
+
#
|
9
|
+
# This cop's offenses are not safe to auto-correct if a receiver is nil.
|
10
|
+
#
|
11
|
+
# @example
|
12
|
+
# # bad
|
13
|
+
# 'abc'.match?(/ab/)
|
14
|
+
# /ab/.match?('abc')
|
15
|
+
# 'abc' =~ /ab/
|
16
|
+
# /ab/ =~ 'abc'
|
17
|
+
# 'abc'.match(/ab/)
|
18
|
+
# /ab/.match('abc')
|
19
|
+
#
|
20
|
+
# # good
|
21
|
+
# 'abc'.include?('ab')
|
22
|
+
class StringInclude < Base
|
23
|
+
extend AutoCorrector
|
24
|
+
|
25
|
+
MSG = 'Use `String#include?` instead of a regex match with literal-only pattern.'
|
26
|
+
|
27
|
+
def_node_matcher :redundant_regex?, <<~PATTERN
|
28
|
+
{(send $!nil? {:match :=~ :match?} (regexp (str $#literal?) (regopt)))
|
29
|
+
(send (regexp (str $#literal?) (regopt)) {:match :match?} $str)
|
30
|
+
(match-with-lvasgn (regexp (str $#literal?) (regopt)) $_)}
|
31
|
+
PATTERN
|
32
|
+
|
33
|
+
def on_send(node)
|
34
|
+
return unless (receiver, regex_str = redundant_regex?(node))
|
35
|
+
|
36
|
+
add_offense(node) do |corrector|
|
37
|
+
receiver, regex_str = regex_str, receiver if receiver.is_a?(String)
|
38
|
+
regex_str = interpret_string_escapes(regex_str)
|
39
|
+
|
40
|
+
new_source = "#{receiver.source}.include?(#{to_string_literal(regex_str)})"
|
41
|
+
|
42
|
+
corrector.replace(node.source_range, new_source)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
alias on_match_with_lvasgn on_send
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def literal?(regex_str)
|
50
|
+
regex_str.match?(/\A#{Util::LITERAL_REGEX}+\z/)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -18,17 +18,17 @@ 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`.'
|
25
26
|
DETERMINISTIC_REGEX = /\A(?:#{LITERAL_REGEX})+\Z/.freeze
|
26
27
|
DELETE = 'delete'
|
27
28
|
TR = 'tr'
|
28
29
|
BANG = '!'
|
29
|
-
SINGLE_QUOTE = "'"
|
30
30
|
|
31
|
-
def_node_matcher :string_replacement?,
|
31
|
+
def_node_matcher :string_replacement?, <<~PATTERN
|
32
32
|
(send _ {:gsub :gsub!}
|
33
33
|
${regexp str (send (const nil? :Regexp) {:new :compile} _)}
|
34
34
|
$str)
|
@@ -43,37 +43,37 @@ module RuboCop
|
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
46
|
-
|
47
|
-
|
46
|
+
private
|
47
|
+
|
48
|
+
def offense(node, first_param, second_param)
|
48
49
|
first_source, = first_source(first_param)
|
50
|
+
first_source = interpret_string_escapes(first_source) unless first_param.str_type?
|
49
51
|
second_source, = *second_param
|
52
|
+
message = message(node, first_source, second_source)
|
50
53
|
|
51
|
-
|
52
|
-
|
54
|
+
add_offense(range(node), message: message) do |corrector|
|
55
|
+
autocorrect(corrector, node)
|
53
56
|
end
|
57
|
+
end
|
54
58
|
|
55
|
-
|
56
|
-
|
59
|
+
def autocorrect(corrector, node)
|
60
|
+
_string, _method, first_param, second_param = *node
|
61
|
+
first_source, = first_source(first_param)
|
62
|
+
second_source, = *second_param
|
57
63
|
|
58
|
-
|
59
|
-
replacement_method)
|
60
|
-
end
|
64
|
+
first_source = interpret_string_escapes(first_source) unless first_param.str_type?
|
61
65
|
|
62
|
-
|
63
|
-
lambda do |corrector|
|
64
|
-
corrector.replace(node.loc.selector, replacement)
|
65
|
-
unless first_param.str_type?
|
66
|
-
corrector.replace(first_param.source_range,
|
67
|
-
to_string_literal(first))
|
68
|
-
end
|
69
|
-
|
70
|
-
if second.empty? && first.length == 1
|
71
|
-
remove_second_param(corrector, node, first_param)
|
72
|
-
end
|
73
|
-
end
|
66
|
+
replace_method(corrector, node, first_source, second_source, first_param)
|
74
67
|
end
|
75
68
|
|
76
|
-
|
69
|
+
def replace_method(corrector, node, first_source, second_source, first_param)
|
70
|
+
replacement_method = replacement_method(node, first_source, second_source)
|
71
|
+
|
72
|
+
corrector.replace(node.loc.selector, replacement_method)
|
73
|
+
corrector.replace(first_param.source_range, to_string_literal(first_source)) unless first_param.str_type?
|
74
|
+
|
75
|
+
remove_second_param(corrector, node, first_param) if second_source.empty? && first_source.length == 1
|
76
|
+
end
|
77
77
|
|
78
78
|
def accept_second_param?(second_param)
|
79
79
|
second_source, = *second_param
|
@@ -97,17 +97,6 @@ module RuboCop
|
|
97
97
|
first_source.length != 1
|
98
98
|
end
|
99
99
|
|
100
|
-
def offense(node, first_param, second_param)
|
101
|
-
first_source, = first_source(first_param)
|
102
|
-
unless first_param.str_type?
|
103
|
-
first_source = interpret_string_escapes(first_source)
|
104
|
-
end
|
105
|
-
second_source, = *second_param
|
106
|
-
message = message(node, first_source, second_source)
|
107
|
-
|
108
|
-
add_offense(node, location: range(node), message: message)
|
109
|
-
end
|
110
|
-
|
111
100
|
def first_source(first_param)
|
112
101
|
case first_param.type
|
113
102
|
when :regexp
|
@@ -0,0 +1,129 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Performance
|
6
|
+
# This cop identifies places where custom code finding the sum of elements
|
7
|
+
# in some Enumerable object can be replaced by `Enumerable#sum` method.
|
8
|
+
#
|
9
|
+
# @example
|
10
|
+
# # bad
|
11
|
+
# [1, 2, 3].inject(:+)
|
12
|
+
# [1, 2, 3].reduce(10, :+)
|
13
|
+
# [1, 2, 3].reduce { |acc, elem| acc + elem }
|
14
|
+
#
|
15
|
+
# # good
|
16
|
+
# [1, 2, 3].sum
|
17
|
+
# [1, 2, 3].sum(10)
|
18
|
+
# [1, 2, 3].sum
|
19
|
+
#
|
20
|
+
class Sum < Base
|
21
|
+
include RangeHelp
|
22
|
+
extend AutoCorrector
|
23
|
+
|
24
|
+
MSG = 'Use `%<good_method>s` instead of `%<bad_method>s`.'
|
25
|
+
|
26
|
+
def_node_matcher :sum_candidate?, <<~PATTERN
|
27
|
+
(send _ ${:inject :reduce} $_init ? (sym :+))
|
28
|
+
PATTERN
|
29
|
+
|
30
|
+
def_node_matcher :sum_with_block_candidate?, <<~PATTERN
|
31
|
+
(block
|
32
|
+
$(send _ {:inject :reduce} $_init ?)
|
33
|
+
(args (arg $_acc) (arg $_elem))
|
34
|
+
$send)
|
35
|
+
PATTERN
|
36
|
+
|
37
|
+
def_node_matcher :acc_plus_elem?, <<~PATTERN
|
38
|
+
(send (lvar %1) :+ (lvar %2))
|
39
|
+
PATTERN
|
40
|
+
alias elem_plus_acc? acc_plus_elem?
|
41
|
+
|
42
|
+
def on_send(node)
|
43
|
+
sum_candidate?(node) do |method, init|
|
44
|
+
range = sum_method_range(node)
|
45
|
+
message = build_method_message(method, init)
|
46
|
+
|
47
|
+
add_offense(range, message: message) do |corrector|
|
48
|
+
autocorrect(corrector, init, range)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def on_block(node)
|
54
|
+
sum_with_block_candidate?(node) do |send, init, var_acc, var_elem, body|
|
55
|
+
if acc_plus_elem?(body, var_acc, var_elem) || elem_plus_acc?(body, var_elem, var_acc)
|
56
|
+
range = sum_block_range(send, node)
|
57
|
+
message = build_block_message(send, init, var_acc, var_elem, body)
|
58
|
+
|
59
|
+
add_offense(range, message: message) do |corrector|
|
60
|
+
autocorrect(corrector, init, range)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
|
68
|
+
def autocorrect(corrector, init, range)
|
69
|
+
return if init.empty?
|
70
|
+
|
71
|
+
replacement = build_good_method(init)
|
72
|
+
|
73
|
+
corrector.replace(range, replacement)
|
74
|
+
end
|
75
|
+
|
76
|
+
def sum_method_range(node)
|
77
|
+
range_between(node.loc.selector.begin_pos, node.loc.end.end_pos)
|
78
|
+
end
|
79
|
+
|
80
|
+
def sum_block_range(send, node)
|
81
|
+
range_between(send.loc.selector.begin_pos, node.loc.end.end_pos)
|
82
|
+
end
|
83
|
+
|
84
|
+
def build_method_message(method, init)
|
85
|
+
good_method = build_good_method(init)
|
86
|
+
bad_method = build_method_bad_method(init, method)
|
87
|
+
format(MSG, good_method: good_method, bad_method: bad_method)
|
88
|
+
end
|
89
|
+
|
90
|
+
def build_block_message(send, init, var_acc, var_elem, body)
|
91
|
+
good_method = build_good_method(init)
|
92
|
+
bad_method = build_block_bad_method(send.method_name, init, var_acc, var_elem, body)
|
93
|
+
format(MSG, good_method: good_method, bad_method: bad_method)
|
94
|
+
end
|
95
|
+
|
96
|
+
def build_good_method(init)
|
97
|
+
good_method = 'sum'
|
98
|
+
|
99
|
+
unless init.empty?
|
100
|
+
init = init.first
|
101
|
+
good_method += "(#{init.source})" if init.source.to_i != 0
|
102
|
+
end
|
103
|
+
good_method
|
104
|
+
end
|
105
|
+
|
106
|
+
def build_method_bad_method(init, method)
|
107
|
+
bad_method = "#{method}("
|
108
|
+
unless init.empty?
|
109
|
+
init = init.first
|
110
|
+
bad_method += "#{init.source}, "
|
111
|
+
end
|
112
|
+
bad_method += ':+)'
|
113
|
+
bad_method
|
114
|
+
end
|
115
|
+
|
116
|
+
def build_block_bad_method(method, init, var_acc, var_elem, body)
|
117
|
+
bad_method = method.to_s
|
118
|
+
|
119
|
+
unless init.empty?
|
120
|
+
init = init.first
|
121
|
+
bad_method += "(#{init.source})"
|
122
|
+
end
|
123
|
+
bad_method += " { |#{var_acc}, #{var_elem}| #{body.source} }"
|
124
|
+
bad_method
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|