rubocop 0.40.0 → 0.41.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of rubocop might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/README.md +7 -1014
- data/config/default.yml +61 -5
- data/config/disabled.yml +6 -0
- data/config/enabled.yml +63 -4
- data/lib/rubocop.rb +17 -1
- data/lib/rubocop/ast_node.rb +56 -42
- data/lib/rubocop/ast_node/traversal.rb +3 -3
- data/lib/rubocop/cli.rb +14 -9
- data/lib/rubocop/comment_config.rb +85 -32
- data/lib/rubocop/config.rb +29 -8
- data/lib/rubocop/config_loader.rb +1 -1
- data/lib/rubocop/cop/cop.rb +1 -1
- data/lib/rubocop/cop/corrector.rb +13 -0
- data/lib/rubocop/cop/lint/block_alignment.rb +25 -11
- data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +5 -2
- data/lib/rubocop/cop/lint/inherit_exception.rb +69 -0
- data/lib/rubocop/cop/lint/percent_string_array.rb +60 -0
- data/lib/rubocop/cop/lint/percent_symbol_array.rb +57 -0
- data/lib/rubocop/cop/lint/shadowed_exception.rb +95 -0
- data/lib/rubocop/cop/lint/useless_access_modifier.rb +28 -13
- data/lib/rubocop/cop/mixin/autocorrect_alignment.rb +25 -19
- data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +16 -8
- data/lib/rubocop/cop/mixin/if_node.rb +1 -2
- data/lib/rubocop/cop/mixin/integer_node.rb +13 -0
- data/lib/rubocop/cop/mixin/match_range.rb +26 -0
- data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +16 -7
- data/lib/rubocop/cop/mixin/multiline_literal_brace_layout.rb +18 -1
- data/lib/rubocop/cop/mixin/negative_conditional.rb +6 -4
- data/lib/rubocop/cop/mixin/percent_literal.rb +10 -0
- data/lib/rubocop/cop/mixin/space_after_punctuation.rb +24 -6
- data/lib/rubocop/cop/mixin/space_before_punctuation.rb +20 -7
- data/lib/rubocop/cop/mixin/string_literals_help.rb +2 -2
- data/lib/rubocop/cop/mixin/trailing_comma.rb +34 -20
- data/lib/rubocop/cop/performance/flat_map.rb +23 -10
- data/lib/rubocop/cop/performance/push_splat.rb +47 -0
- data/lib/rubocop/cop/performance/redundant_block_call.rb +24 -1
- data/lib/rubocop/cop/performance/redundant_merge.rb +3 -5
- data/lib/rubocop/cop/performance/sample.rb +15 -11
- data/lib/rubocop/cop/rails/exit.rb +62 -0
- data/lib/rubocop/cop/rails/output_safety.rb +45 -0
- data/lib/rubocop/cop/rails/pluralization_grammar.rb +12 -4
- data/lib/rubocop/cop/rails/request_referer.rb +40 -0
- data/lib/rubocop/cop/rails/uniq_before_pluck.rb +63 -28
- data/lib/rubocop/cop/rails/validation.rb +37 -23
- data/lib/rubocop/cop/style/alias.rb +10 -6
- data/lib/rubocop/cop/style/bare_percent_literals.rb +18 -7
- data/lib/rubocop/cop/style/block_delimiters.rb +15 -22
- data/lib/rubocop/cop/style/closing_parenthesis_indentation.rb +19 -8
- data/lib/rubocop/cop/style/comment_indentation.rb +13 -5
- data/lib/rubocop/cop/style/conditional_assignment.rb +111 -59
- data/lib/rubocop/cop/style/documentation.rb +7 -1
- data/lib/rubocop/cop/style/each_for_simple_loop.rb +43 -0
- data/lib/rubocop/cop/style/each_with_object.rb +25 -14
- data/lib/rubocop/cop/style/empty_else.rb +6 -10
- data/lib/rubocop/cop/style/extra_spacing.rb +20 -3
- data/lib/rubocop/cop/style/file_name.rb +16 -4
- data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +1 -1
- data/lib/rubocop/cop/style/hash_syntax.rb +9 -2
- data/lib/rubocop/cop/style/if_unless_modifier.rb +20 -13
- data/lib/rubocop/cop/style/implicit_runtime_error.rb +32 -0
- data/lib/rubocop/cop/style/infinite_loop.rb +42 -5
- data/lib/rubocop/cop/style/lambda.rb +22 -0
- data/lib/rubocop/cop/style/method_def_parentheses.rb +12 -4
- data/lib/rubocop/cop/style/module_function.rb +28 -6
- data/lib/rubocop/cop/style/multiline_method_call_indentation.rb +49 -12
- data/lib/rubocop/cop/style/mutable_constant.rb +8 -1
- data/lib/rubocop/cop/style/nested_modifier.rb +1 -1
- data/lib/rubocop/cop/style/next.rb +43 -31
- data/lib/rubocop/cop/style/not.rb +33 -13
- data/lib/rubocop/cop/style/numeric_literal_prefix.rb +92 -0
- data/lib/rubocop/cop/style/numeric_literals.rb +1 -4
- data/lib/rubocop/cop/style/parallel_assignment.rb +26 -8
- data/lib/rubocop/cop/style/{deprecated_hash_methods.rb → preferred_hash_methods.rb} +8 -8
- data/lib/rubocop/cop/style/redundant_parentheses.rb +29 -19
- data/lib/rubocop/cop/style/redundant_self.rb +13 -6
- data/lib/rubocop/cop/style/space_after_not.rb +7 -5
- data/lib/rubocop/cop/style/space_around_keyword.rb +6 -0
- data/lib/rubocop/cop/style/space_around_operators.rb +5 -1
- data/lib/rubocop/cop/style/space_before_first_arg.rb +21 -9
- data/lib/rubocop/cop/style/space_inside_array_percent_literal.rb +53 -0
- data/lib/rubocop/cop/style/space_inside_block_braces.rb +2 -2
- data/lib/rubocop/cop/style/space_inside_hash_literal_braces.rb +26 -6
- data/lib/rubocop/cop/style/space_inside_percent_literal_delimiters.rb +64 -0
- data/lib/rubocop/cop/style/string_literals.rb +37 -8
- data/lib/rubocop/cop/style/symbol_array.rb +21 -12
- data/lib/rubocop/cop/style/symbol_proc.rb +26 -19
- data/lib/rubocop/cop/style/word_array.rb +1 -5
- data/lib/rubocop/cop/style/zero_length_predicate.rb +6 -6
- data/lib/rubocop/cop/team.rb +40 -27
- data/lib/rubocop/cop/util.rb +13 -42
- data/lib/rubocop/formatter/disabled_config_formatter.rb +37 -14
- data/lib/rubocop/formatter/html_formatter.rb +3 -7
- data/lib/rubocop/result_cache.rb +18 -4
- data/{spec/support → lib/rubocop/rspec}/cop_helper.rb +3 -0
- data/lib/rubocop/rspec/host_environment_simulation_helper.rb +33 -0
- data/lib/rubocop/rspec/shared_contexts.rb +75 -0
- data/lib/rubocop/rspec/shared_examples.rb +101 -0
- data/lib/rubocop/rspec/support.rb +9 -0
- data/lib/rubocop/runner.rb +2 -2
- data/lib/rubocop/string_interpreter.rb +58 -0
- data/lib/rubocop/version.rb +1 -1
- metadata +27 -7
@@ -11,6 +11,7 @@ module RuboCop
|
|
11
11
|
def check_brace_layout(node)
|
12
12
|
return unless node.loc.begin # Ignore implicit literals.
|
13
13
|
return if children(node).empty? # Ignore empty literals.
|
14
|
+
return if node.single_line? # Ignore single-line literals.
|
14
15
|
|
15
16
|
# If the last node is or contains a conflicting HEREDOC, we don't want
|
16
17
|
# to adjust the brace layout because this will result in invalid code.
|
@@ -32,7 +33,8 @@ module RuboCop
|
|
32
33
|
lambda do |corrector|
|
33
34
|
corrector.remove(range_with_surrounding_space(node.loc.end,
|
34
35
|
:left))
|
35
|
-
|
36
|
+
|
37
|
+
corrector.insert_after(last_element_range_with_trailing_comma(node),
|
36
38
|
node.loc.end.source)
|
37
39
|
end
|
38
40
|
end
|
@@ -40,6 +42,21 @@ module RuboCop
|
|
40
42
|
|
41
43
|
private
|
42
44
|
|
45
|
+
def last_element_range_with_trailing_comma(node)
|
46
|
+
trailing_comma_range = last_element_trailing_comma_range(node)
|
47
|
+
if trailing_comma_range
|
48
|
+
children(node).last.source_range.join(trailing_comma_range)
|
49
|
+
else
|
50
|
+
children(node).last.source_range
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def last_element_trailing_comma_range(node)
|
55
|
+
range = range_with_surrounding_space(children(node).last.source_range,
|
56
|
+
:right).end.resize(1)
|
57
|
+
range.source == ',' ? range : nil
|
58
|
+
end
|
59
|
+
|
43
60
|
def handle_new_line(node)
|
44
61
|
return unless closing_brace_on_same_line?(node)
|
45
62
|
|
@@ -6,17 +6,19 @@ module RuboCop
|
|
6
6
|
# Some common code shared between FavorUnlessOverNegatedIf and
|
7
7
|
# FavorUntilOverNegatedWhile.
|
8
8
|
module NegativeConditional
|
9
|
+
def self.included(mod)
|
10
|
+
mod.def_node_matcher :single_negative?, '(send !(send _ :!) :!)'
|
11
|
+
end
|
12
|
+
|
9
13
|
def check_negative_conditional(node)
|
10
14
|
condition, _body, _rest = *node
|
11
15
|
|
12
16
|
# Look at last expression of contents if there are parentheses
|
13
17
|
# around condition.
|
14
18
|
condition = condition.children.last while condition.type == :begin
|
15
|
-
return unless condition.type == :send
|
16
19
|
|
17
|
-
|
18
|
-
|
19
|
-
node.loc.else)
|
20
|
+
return unless single_negative?(condition) &&
|
21
|
+
!(node.loc.respond_to?(:else) && node.loc.else)
|
20
22
|
|
21
23
|
add_offense(node, :expression)
|
22
24
|
end
|
@@ -22,6 +22,16 @@ module RuboCop
|
|
22
22
|
def type(node)
|
23
23
|
node.loc.begin.source[0..-2]
|
24
24
|
end
|
25
|
+
|
26
|
+
# A range containing only the contents of the percent literal (e.g. in
|
27
|
+
# %i{1 2 3} this will be the range covering '1 2 3' only)
|
28
|
+
def contents_range(node)
|
29
|
+
Parser::Source::Range.new(
|
30
|
+
node.loc.expression.source_buffer,
|
31
|
+
node.loc.begin.end_pos,
|
32
|
+
node.loc.end.begin_pos
|
33
|
+
)
|
34
|
+
end
|
25
35
|
end
|
26
36
|
end
|
27
37
|
end
|
@@ -9,16 +9,34 @@ module RuboCop
|
|
9
9
|
MSG = 'Space missing after %s.'.freeze
|
10
10
|
|
11
11
|
def investigate(processed_source)
|
12
|
-
processed_source.tokens
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
12
|
+
each_missing_space(processed_source.tokens) do |token|
|
13
|
+
add_offense(token, token.pos, format(MSG, kind(token)))
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def each_missing_space(tokens)
|
18
|
+
tokens.each_cons(2) do |t1, t2|
|
19
|
+
next unless kind(t1)
|
20
|
+
next unless space_missing?(t1, t2)
|
21
|
+
next unless space_required_before?(t2)
|
17
22
|
|
18
|
-
|
23
|
+
yield t1
|
19
24
|
end
|
20
25
|
end
|
21
26
|
|
27
|
+
def space_missing?(t1, t2)
|
28
|
+
t1.pos.line == t2.pos.line && t2.pos.column == t1.pos.column + offset
|
29
|
+
end
|
30
|
+
|
31
|
+
def space_required_before?(token)
|
32
|
+
!(allowed_type?(token) ||
|
33
|
+
(token.type == :tRCURLY && space_forbidden_before_rcurly?))
|
34
|
+
end
|
35
|
+
|
36
|
+
def allowed_type?(token)
|
37
|
+
[:tRPAREN, :tRBRACK, :tPIPE].include?(token.type)
|
38
|
+
end
|
39
|
+
|
22
40
|
def space_forbidden_before_rcurly?
|
23
41
|
style = space_style_before_rcurly
|
24
42
|
style == 'no_space'
|
@@ -9,21 +9,34 @@ module RuboCop
|
|
9
9
|
MSG = 'Space found before %s.'.freeze
|
10
10
|
|
11
11
|
def investigate(processed_source)
|
12
|
-
processed_source.tokens
|
13
|
-
|
14
|
-
|
15
|
-
|
12
|
+
each_missing_space(processed_source.tokens) do |token, pos_before|
|
13
|
+
add_offense(pos_before, pos_before, format(MSG, kind(token)))
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def each_missing_space(tokens)
|
18
|
+
tokens.each_cons(2) do |t1, t2|
|
19
|
+
next unless kind(t2)
|
20
|
+
next unless space_missing?(t1, t2)
|
21
|
+
next if space_required_after?(t1)
|
22
|
+
|
16
23
|
buffer = processed_source.buffer
|
17
24
|
pos_before_punctuation = Parser::Source::Range.new(buffer,
|
18
25
|
t1.pos.end_pos,
|
19
26
|
t2.pos.begin_pos)
|
20
27
|
|
21
|
-
|
22
|
-
pos_before_punctuation,
|
23
|
-
format(MSG, kind(t2)))
|
28
|
+
yield t2, pos_before_punctuation
|
24
29
|
end
|
25
30
|
end
|
26
31
|
|
32
|
+
def space_missing?(t1, t2)
|
33
|
+
t1.pos.line == t2.pos.line && t2.pos.begin_pos > t1.pos.end_pos
|
34
|
+
end
|
35
|
+
|
36
|
+
def space_required_after?(token)
|
37
|
+
token.type == :tLCURLY && space_required_after_lcurly?
|
38
|
+
end
|
39
|
+
|
27
40
|
def space_required_after_lcurly?
|
28
41
|
cfg = config.for_cop('Style/SpaceInsideBlockBraces')
|
29
42
|
style = cfg['EnforcedStyle'] || 'space'
|
@@ -11,9 +11,9 @@ module RuboCop
|
|
11
11
|
src = node.source
|
12
12
|
return false if src.start_with?('%', '?')
|
13
13
|
if style == :single_quotes
|
14
|
-
|
14
|
+
!double_quotes_required?(src)
|
15
15
|
else
|
16
|
-
src !~ /" | \\ |
|
16
|
+
src !~ /" | \\ | \#(@|\{)/x
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
@@ -23,26 +23,39 @@ module RuboCop
|
|
23
23
|
comma_offset = after_last_item.source =~ /,/
|
24
24
|
|
25
25
|
if comma_offset && !inside_comment?(after_last_item, comma_offset)
|
26
|
-
|
27
|
-
extra_info = case style
|
28
|
-
when :comma
|
29
|
-
', unless each item is on its own line'
|
30
|
-
when :consistent_comma
|
31
|
-
', unless items are split onto multiple lines'
|
32
|
-
else
|
33
|
-
''
|
34
|
-
end
|
35
|
-
avoid_comma(kind, after_last_item.begin_pos + comma_offset, sb,
|
36
|
-
extra_info)
|
37
|
-
end
|
26
|
+
check_comma(node, kind, after_last_item.begin_pos + comma_offset)
|
38
27
|
elsif should_have_comma?(style, node)
|
39
28
|
put_comma(node, items, kind, sb)
|
40
29
|
end
|
41
30
|
end
|
42
31
|
|
32
|
+
def check_comma(node, kind, comma_pos)
|
33
|
+
return if should_have_comma?(style, node)
|
34
|
+
|
35
|
+
avoid_comma(kind, comma_pos, node.source_range.source_buffer,
|
36
|
+
extra_avoid_comma_info)
|
37
|
+
end
|
38
|
+
|
39
|
+
def extra_avoid_comma_info
|
40
|
+
case style
|
41
|
+
when :comma
|
42
|
+
', unless each item is on its own line'
|
43
|
+
when :consistent_comma
|
44
|
+
', unless items are split onto multiple lines'
|
45
|
+
else
|
46
|
+
''
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
43
50
|
def should_have_comma?(style, node)
|
44
|
-
|
51
|
+
case style
|
52
|
+
when :comma
|
53
|
+
multiline?(node) && no_elements_on_same_line?(node)
|
54
|
+
when :consistent_comma
|
45
55
|
multiline?(node)
|
56
|
+
else
|
57
|
+
false
|
58
|
+
end
|
46
59
|
end
|
47
60
|
|
48
61
|
def inside_comment?(range, comma_offset)
|
@@ -73,13 +86,8 @@ module RuboCop
|
|
73
86
|
|
74
87
|
items = elements(node).map(&:source_range)
|
75
88
|
return false if items.empty?
|
76
|
-
|
77
|
-
|
78
|
-
# then comma is needed anytime for consistent_comma.
|
79
|
-
return true if style == :consistent_comma
|
80
|
-
|
81
|
-
items << node.loc.end
|
82
|
-
items.each_cons(2).all? { |a, b| !on_same_line?(a, b) }
|
89
|
+
items << node.loc.begin << node.loc.end
|
90
|
+
(items.map(&:first_line) + items.map(&:last_line)).uniq.count > 1
|
83
91
|
end
|
84
92
|
|
85
93
|
def elements(node)
|
@@ -99,6 +107,12 @@ module RuboCop
|
|
99
107
|
end
|
100
108
|
end
|
101
109
|
|
110
|
+
def no_elements_on_same_line?(node)
|
111
|
+
items = elements(node).map(&:source_range)
|
112
|
+
items << node.loc.end
|
113
|
+
items.each_cons(2).none? { |a, b| on_same_line?(a, b) }
|
114
|
+
end
|
115
|
+
|
102
116
|
def on_same_line?(a, b)
|
103
117
|
a.last_line == b.line
|
104
118
|
end
|
@@ -25,23 +25,17 @@ module RuboCop
|
|
25
25
|
def on_send(node)
|
26
26
|
left, second_method, flatten_param = *node
|
27
27
|
return unless FLATTEN.include?(second_method)
|
28
|
+
|
28
29
|
flatten_level, = *flatten_param
|
29
30
|
expression, = *left
|
30
31
|
_array, first_method = *expression
|
31
32
|
return unless first_method == :map || first_method == :collect
|
32
33
|
|
33
|
-
message = MSG
|
34
34
|
if cop_config['EnabledForFlattenWithoutParams'] && flatten_level.nil?
|
35
|
-
|
36
|
-
elsif flatten_level
|
37
|
-
|
35
|
+
offense_for_levels(node, expression, first_method, second_method)
|
36
|
+
elsif flatten_level == 1
|
37
|
+
offense_for_method(node, expression, first_method, second_method)
|
38
38
|
end
|
39
|
-
|
40
|
-
range = Parser::Source::Range.new(node.source_range.source_buffer,
|
41
|
-
expression.loc.selector.begin_pos,
|
42
|
-
node.loc.selector.end_pos)
|
43
|
-
|
44
|
-
add_offense(node, range, format(message, first_method, second_method))
|
45
39
|
end
|
46
40
|
|
47
41
|
def autocorrect(node)
|
@@ -60,6 +54,25 @@ module RuboCop
|
|
60
54
|
corrector.replace(array.loc.selector, 'flat_map')
|
61
55
|
end
|
62
56
|
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
def offense_for_levels(node, expression, first_method, second_method)
|
61
|
+
message = MSG + FLATTEN_MULTIPLE_LEVELS
|
62
|
+
offense(node, expression, first_method, second_method, message)
|
63
|
+
end
|
64
|
+
|
65
|
+
def offense_for_method(node, expression, first_method, second_method)
|
66
|
+
offense(node, expression, first_method, second_method, MSG)
|
67
|
+
end
|
68
|
+
|
69
|
+
def offense(node, expression, first_method, second_method, message)
|
70
|
+
range = Parser::Source::Range.new(node.source_range.source_buffer,
|
71
|
+
expression.loc.selector.begin_pos,
|
72
|
+
node.loc.selector.end_pos)
|
73
|
+
|
74
|
+
add_offense(node, range, format(message, first_method, second_method))
|
75
|
+
end
|
63
76
|
end
|
64
77
|
end
|
65
78
|
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module RuboCop
|
5
|
+
module Cop
|
6
|
+
module Performance
|
7
|
+
# This cop is used to identify usages of
|
8
|
+
#
|
9
|
+
# @example
|
10
|
+
# # bad
|
11
|
+
# [].push(*a)
|
12
|
+
#
|
13
|
+
# # good
|
14
|
+
# [].concat(a)
|
15
|
+
class PushSplat < Cop
|
16
|
+
include Parentheses
|
17
|
+
|
18
|
+
MSG = 'Use `concat` instead of `push(*)`.'.freeze
|
19
|
+
|
20
|
+
def_node_matcher :push_splat, <<-END
|
21
|
+
(send _ :push (splat ...))
|
22
|
+
END
|
23
|
+
|
24
|
+
def on_send(node)
|
25
|
+
push_splat(node) do
|
26
|
+
add_offense(node, :expression, MSG)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def autocorrect(node)
|
31
|
+
_receiver, _method, splat = *node
|
32
|
+
body, = *splat
|
33
|
+
lambda do |corrector|
|
34
|
+
corrector.replace(node.location.selector, 'concat')
|
35
|
+
|
36
|
+
source = if parens_required?(splat)
|
37
|
+
"(#{body.source})"
|
38
|
+
else
|
39
|
+
body.source
|
40
|
+
end
|
41
|
+
corrector.replace(splat.loc.expression, source)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -39,15 +39,38 @@ module RuboCop
|
|
39
39
|
(send (lvar %1) :call ...)
|
40
40
|
END
|
41
41
|
|
42
|
+
def_node_search :blockarg_assigned?, <<-END
|
43
|
+
(lvasgn %1 ...)
|
44
|
+
END
|
45
|
+
|
42
46
|
def on_def(node)
|
43
47
|
blockarg_def(node) do |argname, body|
|
44
48
|
next unless body
|
45
|
-
|
49
|
+
|
50
|
+
calls_to_report(argname, body).each do |blockcall|
|
46
51
|
add_offense(blockcall, :expression, format(MSG, argname))
|
47
52
|
end
|
48
53
|
end
|
49
54
|
end
|
50
55
|
|
56
|
+
private
|
57
|
+
|
58
|
+
def calls_to_report(argname, body)
|
59
|
+
return [] if blockarg_assigned?(body, argname)
|
60
|
+
|
61
|
+
calls = to_enum(:blockarg_calls, body, argname)
|
62
|
+
|
63
|
+
return [] if calls.any? { |call| args_include_block_pass?(call) }
|
64
|
+
|
65
|
+
calls
|
66
|
+
end
|
67
|
+
|
68
|
+
def args_include_block_pass?(blockcall)
|
69
|
+
_receiver, _call, *args = *blockcall
|
70
|
+
|
71
|
+
args.any?(&:block_pass_type?)
|
72
|
+
end
|
73
|
+
|
51
74
|
# offenses are registered on the `block.call` nodes
|
52
75
|
def autocorrect(node)
|
53
76
|
_receiver, _method, *args = *node
|
@@ -16,7 +16,9 @@ module RuboCop
|
|
16
16
|
MSG = 'Use `%s` instead of `%s`.'.freeze
|
17
17
|
|
18
18
|
def_node_matcher :redundant_merge, '(send $_ :merge! (hash $...))'
|
19
|
-
def_node_matcher :modifier_flow_control,
|
19
|
+
def_node_matcher :modifier_flow_control, <<-END
|
20
|
+
[{if while until} modifier_form?]
|
21
|
+
END
|
20
22
|
def_node_matcher :each_with_object_node, <<-END
|
21
23
|
(block (send _ :each_with_object _) (args _ $_) ...)
|
22
24
|
END
|
@@ -110,10 +112,6 @@ module RuboCop
|
|
110
112
|
@config.for_cop('IndentationWidth')['Width'] || 2
|
111
113
|
end
|
112
114
|
|
113
|
-
def modifier?(node)
|
114
|
-
node.loc.respond_to?(:end) && node.loc.end.nil?
|
115
|
-
end
|
116
|
-
|
117
115
|
def max_key_value_pairs
|
118
116
|
cop_config['MaxKeyValuePairs'].to_i
|
119
117
|
end
|
@@ -111,20 +111,24 @@ module RuboCop
|
|
111
111
|
def sample_size
|
112
112
|
_, _, *args = *method_node
|
113
113
|
case args.size
|
114
|
-
when 1
|
115
|
-
|
116
|
-
case arg.type
|
117
|
-
when :erange, :irange then range_size(arg)
|
118
|
-
when :int then arg.to_a.first.zero? ? nil : :unknown
|
119
|
-
else :unknown
|
120
|
-
end
|
121
|
-
when 2
|
122
|
-
first, second = *args
|
123
|
-
return :unknown unless first.int_type? && first.to_a.first.zero?
|
124
|
-
second.int_type? ? second.to_a.first : :unknown
|
114
|
+
when 1 then sample_size_for_one_arg(args.first)
|
115
|
+
when 2 then sample_size_for_two_args(*args)
|
125
116
|
end
|
126
117
|
end
|
127
118
|
|
119
|
+
def sample_size_for_one_arg(arg)
|
120
|
+
case arg.type
|
121
|
+
when :erange, :irange then range_size(arg)
|
122
|
+
when :int then arg.to_a.first.zero? ? nil : :unknown
|
123
|
+
else :unknown
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
def sample_size_for_two_args(first, second)
|
128
|
+
return :unknown unless first.int_type? && first.to_a.first.zero?
|
129
|
+
second.int_type? ? second.to_a.first : :unknown
|
130
|
+
end
|
131
|
+
|
128
132
|
def shuffle_arg
|
129
133
|
_, _, arg = *shuffle_node
|
130
134
|
arg.source if arg
|