rubocop 0.48.1 → 0.49.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/README.md +4 -3
- data/config/default.yml +397 -357
- data/config/disabled.yml +29 -29
- data/config/enabled.yml +366 -326
- data/lib/rubocop.rb +85 -70
- data/lib/rubocop/ast/builder.rb +4 -1
- data/lib/rubocop/ast/node.rb +2 -2
- data/lib/rubocop/ast/node/and_node.rb +1 -1
- data/lib/rubocop/ast/node/args_node.rb +24 -0
- data/lib/rubocop/ast/node/block_node.rb +107 -0
- data/lib/rubocop/ast/node/case_node.rb +1 -1
- data/lib/rubocop/ast/node/ensure_node.rb +1 -1
- data/lib/rubocop/ast/node/for_node.rb +1 -1
- data/lib/rubocop/ast/node/if_node.rb +1 -1
- data/lib/rubocop/ast/node/mixin/parameterized_node.rb +74 -0
- data/lib/rubocop/ast/node/or_node.rb +1 -1
- data/lib/rubocop/ast/node/pair_node.rb +1 -1
- data/lib/rubocop/ast/node/resbody_node.rb +1 -1
- data/lib/rubocop/ast/node/send_node.rb +36 -57
- data/lib/rubocop/ast/node/super_node.rb +42 -0
- data/lib/rubocop/ast/node/until_node.rb +1 -1
- data/lib/rubocop/ast/node/when_node.rb +1 -1
- data/lib/rubocop/ast/node/while_node.rb +1 -1
- data/lib/rubocop/cli.rb +10 -0
- data/lib/rubocop/config.rb +23 -7
- data/lib/rubocop/config_loader.rb +19 -3
- data/lib/rubocop/cop/badge.rb +1 -1
- data/lib/rubocop/cop/bundler/duplicated_gem.rb +2 -2
- data/lib/rubocop/cop/commissioner.rb +1 -1
- data/lib/rubocop/cop/cop.rb +10 -0
- data/lib/rubocop/cop/{style → layout}/access_modifier_indentation.rb +33 -3
- data/lib/rubocop/cop/{style → layout}/align_array.rb +16 -1
- data/lib/rubocop/cop/{style → layout}/align_hash.rb +1 -1
- data/lib/rubocop/cop/{style → layout}/align_parameters.rb +29 -1
- data/lib/rubocop/cop/{style → layout}/block_end_newline.rb +10 -5
- data/lib/rubocop/cop/{style → layout}/case_indentation.rb +64 -1
- data/lib/rubocop/cop/{style → layout}/closing_parenthesis_indentation.rb +2 -2
- data/lib/rubocop/cop/{style → layout}/comment_indentation.rb +1 -1
- data/lib/rubocop/cop/{style → layout}/dot_position.rb +1 -1
- data/lib/rubocop/cop/{style → layout}/else_alignment.rb +1 -1
- data/lib/rubocop/cop/{style → layout}/empty_line_after_magic_comment.rb +1 -1
- data/lib/rubocop/cop/{style → layout}/empty_line_between_defs.rb +1 -1
- data/lib/rubocop/cop/{style → layout}/empty_lines.rb +1 -1
- data/lib/rubocop/cop/{style → layout}/empty_lines_around_access_modifier.rb +2 -7
- data/lib/rubocop/cop/{style → layout}/empty_lines_around_begin_body.rb +1 -1
- data/lib/rubocop/cop/{style → layout}/empty_lines_around_block_body.rb +2 -4
- data/lib/rubocop/cop/{style → layout}/empty_lines_around_class_body.rb +1 -1
- data/lib/rubocop/cop/{style → layout}/empty_lines_around_exception_handling_keywords.rb +1 -1
- data/lib/rubocop/cop/{style → layout}/empty_lines_around_method_body.rb +1 -1
- data/lib/rubocop/cop/{style → layout}/empty_lines_around_module_body.rb +1 -1
- data/lib/rubocop/cop/{style → layout}/end_of_line.rb +1 -1
- data/lib/rubocop/cop/{style → layout}/extra_spacing.rb +1 -1
- data/lib/rubocop/cop/{style → layout}/first_array_element_line_break.rb +1 -1
- data/lib/rubocop/cop/{style → layout}/first_hash_element_line_break.rb +1 -1
- data/lib/rubocop/cop/{style → layout}/first_method_argument_line_break.rb +1 -1
- data/lib/rubocop/cop/{style → layout}/first_method_parameter_line_break.rb +1 -1
- data/lib/rubocop/cop/{style → layout}/first_parameter_indentation.rb +1 -1
- data/lib/rubocop/cop/{style → layout}/indent_array.rb +1 -1
- data/lib/rubocop/cop/{style → layout}/indent_assignment.rb +1 -1
- data/lib/rubocop/cop/{style → layout}/indent_hash.rb +2 -2
- data/lib/rubocop/cop/{style → layout}/indent_heredoc.rb +3 -3
- data/lib/rubocop/cop/{style → layout}/indentation_consistency.rb +1 -1
- data/lib/rubocop/cop/{style → layout}/indentation_width.rb +10 -12
- data/lib/rubocop/cop/{style → layout}/initial_indentation.rb +1 -1
- data/lib/rubocop/cop/{style → layout}/leading_comment_space.rb +1 -1
- data/lib/rubocop/cop/{style → layout}/multiline_array_brace_layout.rb +1 -1
- data/lib/rubocop/cop/{style → layout}/multiline_assignment_layout.rb +1 -1
- data/lib/rubocop/cop/{style → layout}/multiline_block_layout.rb +21 -36
- data/lib/rubocop/cop/{style → layout}/multiline_hash_brace_layout.rb +5 -1
- data/lib/rubocop/cop/{style → layout}/multiline_method_call_brace_layout.rb +1 -1
- data/lib/rubocop/cop/{style → layout}/multiline_method_call_indentation.rb +3 -3
- data/lib/rubocop/cop/{style → layout}/multiline_method_definition_brace_layout.rb +1 -1
- data/lib/rubocop/cop/{style → layout}/multiline_operation_indentation.rb +6 -5
- data/lib/rubocop/cop/{style → layout}/rescue_ensure_alignment.rb +1 -1
- data/lib/rubocop/cop/{style → layout}/space_after_colon.rb +2 -2
- data/lib/rubocop/cop/{style → layout}/space_after_comma.rb +2 -2
- data/lib/rubocop/cop/{style → layout}/space_after_method_name.rb +1 -1
- data/lib/rubocop/cop/{style → layout}/space_after_not.rb +1 -1
- data/lib/rubocop/cop/{style → layout}/space_after_semicolon.rb +2 -2
- data/lib/rubocop/cop/{style → layout}/space_around_block_parameters.rb +7 -5
- data/lib/rubocop/cop/{style → layout}/space_around_equals_in_parameter_default.rb +1 -1
- data/lib/rubocop/cop/{style → layout}/space_around_keyword.rb +1 -1
- data/lib/rubocop/cop/{style → layout}/space_around_operators.rb +6 -2
- data/lib/rubocop/cop/{style → layout}/space_before_block_braces.rb +6 -2
- data/lib/rubocop/cop/{style → layout}/space_before_comma.rb +1 -1
- data/lib/rubocop/cop/{style → layout}/space_before_comment.rb +1 -1
- data/lib/rubocop/cop/{style → layout}/space_before_first_arg.rb +4 -2
- data/lib/rubocop/cop/{style → layout}/space_before_semicolon.rb +1 -1
- data/lib/rubocop/cop/{style → layout}/space_in_lambda_literal.rb +1 -1
- data/lib/rubocop/cop/{style → layout}/space_inside_array_percent_literal.rb +1 -1
- data/lib/rubocop/cop/{style → layout}/space_inside_block_braces.rb +3 -4
- data/lib/rubocop/cop/{style → layout}/space_inside_brackets.rb +1 -1
- data/lib/rubocop/cop/{style → layout}/space_inside_hash_literal_braces.rb +1 -1
- data/lib/rubocop/cop/{style → layout}/space_inside_parens.rb +1 -1
- data/lib/rubocop/cop/{style → layout}/space_inside_percent_literal_delimiters.rb +8 -7
- data/lib/rubocop/cop/{style → layout}/space_inside_range_literal.rb +1 -1
- data/lib/rubocop/cop/{style → layout}/space_inside_string_interpolation.rb +1 -1
- data/lib/rubocop/cop/{style → layout}/tab.rb +1 -1
- data/lib/rubocop/cop/{style → layout}/trailing_blank_lines.rb +1 -1
- data/lib/rubocop/cop/{style → layout}/trailing_whitespace.rb +2 -2
- data/lib/rubocop/cop/lint/ambiguous_block_association.rb +1 -1
- data/lib/rubocop/cop/lint/ambiguous_operator.rb +4 -4
- data/lib/rubocop/cop/lint/debugger.rb +0 -15
- data/lib/rubocop/cop/lint/duplicate_methods.rb +2 -1
- data/lib/rubocop/cop/lint/rescue_type.rb +81 -0
- data/lib/rubocop/cop/lint/script_permission.rb +42 -0
- data/lib/rubocop/cop/lint/useless_access_modifier.rb +1 -1
- data/lib/rubocop/cop/message_annotator.rb +23 -13
- data/lib/rubocop/cop/metrics/block_length.rb +1 -1
- data/lib/rubocop/cop/mixin/array_min_size.rb +59 -0
- data/lib/rubocop/cop/mixin/configurable_enforced_style.rb +10 -11
- data/lib/rubocop/cop/mixin/def_node.rb +1 -1
- data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +1 -1
- data/lib/rubocop/cop/mixin/enforce_superclass.rb +36 -0
- data/lib/rubocop/cop/mixin/hash_alignment.rb +1 -1
- data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +7 -3
- data/lib/rubocop/cop/mixin/space_before_punctuation.rb +1 -1
- data/lib/rubocop/cop/performance/caller.rb +41 -0
- data/lib/rubocop/cop/performance/compare_with_block.rb +60 -14
- data/lib/rubocop/cop/performance/double_start_end_with.rb +2 -2
- data/lib/rubocop/cop/performance/redundant_merge.rb +2 -0
- data/lib/rubocop/cop/rails/action_filter.rb +1 -3
- data/lib/rubocop/cop/rails/application_job.rb +32 -0
- data/lib/rubocop/cop/rails/application_record.rb +32 -0
- data/lib/rubocop/cop/rails/blank.rb +9 -3
- data/lib/rubocop/cop/rails/output_safety.rb +59 -15
- data/lib/rubocop/cop/rails/present.rb +9 -3
- data/lib/rubocop/cop/rails/relative_date_constant.rb +35 -4
- data/lib/rubocop/cop/rails/reversible_migration.rb +82 -18
- data/lib/rubocop/cop/rails/save_bang.rb +7 -2
- data/lib/rubocop/cop/rails/skips_model_validations.rb +7 -0
- data/lib/rubocop/cop/registry.rb +4 -3
- data/lib/rubocop/cop/security/eval.rb +9 -3
- data/lib/rubocop/cop/style/and_or.rb +1 -1
- data/lib/rubocop/cop/style/block_delimiters.rb +11 -17
- data/lib/rubocop/cop/style/braces_around_hash_parameters.rb +1 -1
- data/lib/rubocop/cop/style/collection_methods.rb +1 -3
- data/lib/rubocop/cop/style/conditional_assignment.rb +1 -1
- data/lib/rubocop/cop/style/copyright.rb +2 -2
- data/lib/rubocop/cop/style/documentation_method.rb +1 -1
- data/lib/rubocop/cop/style/each_for_simple_loop.rb +2 -1
- data/lib/rubocop/cop/style/each_with_object.rb +10 -6
- data/lib/rubocop/cop/style/empty_case_condition.rb +2 -2
- data/lib/rubocop/cop/style/for.rb +4 -5
- data/lib/rubocop/cop/style/format_string.rb +49 -0
- data/lib/rubocop/cop/style/format_string_token.rb +141 -0
- data/lib/rubocop/cop/style/hash_syntax.rb +1 -1
- data/lib/rubocop/cop/style/identical_conditional_branches.rb +2 -2
- data/lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb +1 -1
- data/lib/rubocop/cop/style/inverse_methods.rb +10 -1
- data/lib/rubocop/cop/style/lambda.rb +9 -9
- data/lib/rubocop/cop/style/line_end_concatenation.rb +4 -0
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +3 -3
- data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +1 -2
- data/lib/rubocop/cop/style/method_name.rb +8 -2
- data/lib/rubocop/cop/style/mixin_grouping.rb +41 -3
- data/lib/rubocop/cop/style/multiline_block_chain.rb +7 -11
- data/lib/rubocop/cop/style/multiple_comparison.rb +77 -0
- data/lib/rubocop/cop/style/next.rb +11 -22
- data/lib/rubocop/cop/style/parallel_assignment.rb +10 -19
- data/lib/rubocop/cop/style/percent_literal_delimiters.rb +2 -2
- data/lib/rubocop/cop/style/self_assignment.rb +4 -0
- data/lib/rubocop/cop/style/single_line_block_params.rb +23 -17
- data/lib/rubocop/cop/style/symbol_array.rb +24 -13
- data/lib/rubocop/cop/style/symbol_proc.rb +4 -0
- data/lib/rubocop/cop/style/ternary_parentheses.rb +1 -1
- data/lib/rubocop/cop/style/unneeded_interpolation.rb +4 -0
- data/lib/rubocop/cop/style/word_array.rb +33 -53
- data/lib/rubocop/cop/style/yoda_condition.rb +78 -0
- data/lib/rubocop/cop/team.rb +1 -14
- data/lib/rubocop/cop/util.rb +16 -0
- data/lib/rubocop/formatter/simple_text_formatter.rb +0 -11
- data/lib/rubocop/node_pattern.rb +52 -52
- data/lib/rubocop/options.rb +25 -0
- data/lib/rubocop/path_util.rb +17 -1
- data/lib/rubocop/result_cache.rb +8 -7
- data/lib/rubocop/rspec/expect_offense.rb +167 -0
- data/lib/rubocop/rspec/shared_examples.rb +0 -8
- data/lib/rubocop/rspec/support.rb +1 -0
- data/lib/rubocop/runner.rb +12 -2
- data/lib/rubocop/target_finder.rb +5 -0
- data/lib/rubocop/version.rb +1 -1
- metadata +101 -72
@@ -12,7 +12,7 @@ module RuboCop
|
|
12
12
|
#
|
13
13
|
# The supported styles are:
|
14
14
|
#
|
15
|
-
# * ruby19 - forces use of the 1.9 syntax (e.g. {a: 1}) when hashes have
|
15
|
+
# * ruby19 - forces use of the 1.9 syntax (e.g. `{a: 1}`) when hashes have
|
16
16
|
# all symbols for keys
|
17
17
|
# * hash_rockets - forces use of hash rockets for all hashes
|
18
18
|
# * no_mixed_keys - simply checks for hashes with mixed syntaxes
|
@@ -26,8 +26,9 @@ module RuboCop
|
|
26
26
|
# foo.any? { |f| f.even? }
|
27
27
|
# foo != bar
|
28
28
|
# foo == bar
|
29
|
+
# !!('foo' =~ /^\w+$/)
|
29
30
|
class InverseMethods < Cop
|
30
|
-
MSG = 'Use
|
31
|
+
MSG = 'Use `%<inverse>s` instead of inverting `%<method>s`.'.freeze
|
31
32
|
EQUALITY_METHODS = %i[== != =~ !~ <= >= < >].freeze
|
32
33
|
|
33
34
|
def_node_matcher :inverse_candidate?, <<-PATTERN
|
@@ -49,6 +50,7 @@ module RuboCop
|
|
49
50
|
def on_send(node)
|
50
51
|
inverse_candidate?(node) do |_method_call, method|
|
51
52
|
return unless inverse_methods.key?(method)
|
53
|
+
return if negated?(node)
|
52
54
|
|
53
55
|
add_offense(node,
|
54
56
|
:expression,
|
@@ -60,6 +62,7 @@ module RuboCop
|
|
60
62
|
def on_block(node)
|
61
63
|
inverse_block?(node) do |_method_call, method, _block|
|
62
64
|
return unless inverse_blocks.key?(method)
|
65
|
+
return if negated?(node) && negated?(node.parent)
|
63
66
|
|
64
67
|
add_offense(node,
|
65
68
|
:expression,
|
@@ -103,6 +106,8 @@ module RuboCop
|
|
103
106
|
end
|
104
107
|
end
|
105
108
|
|
109
|
+
private
|
110
|
+
|
106
111
|
def inverse_methods
|
107
112
|
@inverse_methods ||= cop_config['InverseMethods']
|
108
113
|
.merge(cop_config['InverseMethods'].invert)
|
@@ -113,6 +118,10 @@ module RuboCop
|
|
113
118
|
.merge(cop_config['InverseBlocks'].invert)
|
114
119
|
end
|
115
120
|
|
121
|
+
def negated?(node)
|
122
|
+
node.parent.respond_to?(:method?) && node.parent.method?(:!)
|
123
|
+
end
|
124
|
+
|
116
125
|
def not_to_receiver(node, method_call)
|
117
126
|
Parser::Source::Range.new(node.loc.expression.source_buffer,
|
118
127
|
node.loc.selector.begin_pos,
|
@@ -73,15 +73,15 @@ module RuboCop
|
|
73
73
|
def_node_matcher :lambda_node?, '(block $(send nil :lambda) ...)'
|
74
74
|
|
75
75
|
def on_block(node)
|
76
|
-
|
77
|
-
selector = block_method.source
|
76
|
+
return unless node.lambda?
|
78
77
|
|
79
|
-
|
78
|
+
selector = node.send_node.source
|
80
79
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
80
|
+
return unless offending_selector?(node, selector)
|
81
|
+
|
82
|
+
add_offense(node,
|
83
|
+
node.send_node.source_range,
|
84
|
+
message(node, selector))
|
85
85
|
end
|
86
86
|
|
87
87
|
private
|
@@ -189,13 +189,13 @@ module RuboCop
|
|
189
189
|
def remove_unparenthesized_whitespaces(corrector, node)
|
190
190
|
block_method, args = *node
|
191
191
|
return unless unparenthesized_literal_args?(args)
|
192
|
-
# First, remove leading whitespaces (
|
192
|
+
# First, remove leading whitespaces (between arrow and args)
|
193
193
|
corrector.remove_preceding(
|
194
194
|
args.source_range,
|
195
195
|
args.source_range.begin_pos - block_method.source_range.end_pos
|
196
196
|
)
|
197
197
|
|
198
|
-
# Then, remove trailing whitespaces (
|
198
|
+
# Then, remove trailing whitespaces (between args and 'do')
|
199
199
|
delta = node.loc.begin.begin_pos - args.source_range.end_pos - 1
|
200
200
|
corrector.remove_preceding(node.loc.begin, delta)
|
201
201
|
end
|
@@ -29,6 +29,10 @@ module RuboCop
|
|
29
29
|
tLBRACK2].freeze
|
30
30
|
QUOTE_DELIMITERS = %w[' "].freeze
|
31
31
|
|
32
|
+
def self.autocorrect_incompatible_with
|
33
|
+
[Style::UnneededInterpolation]
|
34
|
+
end
|
35
|
+
|
32
36
|
def investigate(processed_source)
|
33
37
|
processed_source.tokens.each_index do |index|
|
34
38
|
check_token_set(index)
|
@@ -50,8 +50,7 @@ module RuboCop
|
|
50
50
|
end
|
51
51
|
|
52
52
|
def on_super(node)
|
53
|
-
|
54
|
-
return if parentheses?(node)
|
53
|
+
return if node.parenthesized?
|
55
54
|
|
56
55
|
add_offense(node, :keyword)
|
57
56
|
end
|
@@ -93,7 +92,8 @@ module RuboCop
|
|
93
92
|
|
94
93
|
def args_begin(node)
|
95
94
|
loc = node.loc
|
96
|
-
selector =
|
95
|
+
selector =
|
96
|
+
node.super_type? || node.yield_type? ? loc.keyword : loc.selector
|
97
97
|
selector.end.resize(1)
|
98
98
|
end
|
99
99
|
|
@@ -16,13 +16,12 @@ module RuboCop
|
|
16
16
|
MSG = 'Avoid chaining a method call on a do...end block.'.freeze
|
17
17
|
|
18
18
|
def on_block(node)
|
19
|
-
method, _args, _body = *node
|
20
19
|
# If the method that is chained on the do...end block is itself a
|
21
20
|
# method with a block, we allow it. It's pretty safe to assume that
|
22
21
|
# these calls are not missed by anyone reading code. We also want to
|
23
22
|
# avoid double reporting of offenses checked by the
|
24
23
|
# MultilineBlockChain cop.
|
25
|
-
ignore_node(
|
24
|
+
ignore_node(node.send_node)
|
26
25
|
end
|
27
26
|
|
28
27
|
def on_send(node)
|
@@ -11,17 +11,23 @@ module RuboCop
|
|
11
11
|
|
12
12
|
def on_def(node)
|
13
13
|
name, = *node
|
14
|
-
check_name(node, name, node.loc.name)
|
14
|
+
check_name(node, sanitize_name(name), node.loc.name)
|
15
15
|
end
|
16
16
|
|
17
17
|
def on_defs(node)
|
18
18
|
_object, name, = *node
|
19
|
-
check_name(node, name, node.loc.name)
|
19
|
+
check_name(node, sanitize_name(name), node.loc.name)
|
20
20
|
end
|
21
21
|
|
22
|
+
private
|
23
|
+
|
22
24
|
def message(style)
|
23
25
|
format('Use %s for method names.', style)
|
24
26
|
end
|
27
|
+
|
28
|
+
def sanitize_name(name)
|
29
|
+
name.to_s.delete('@').to_sym
|
30
|
+
end
|
25
31
|
end
|
26
32
|
end
|
27
33
|
end
|
@@ -46,6 +46,21 @@ module RuboCop
|
|
46
46
|
check(node)
|
47
47
|
end
|
48
48
|
|
49
|
+
def autocorrect(node)
|
50
|
+
if separated_style?
|
51
|
+
range = node.loc.expression
|
52
|
+
correction = separate_mixins(node)
|
53
|
+
else
|
54
|
+
mixins = sibling_mixins(node)
|
55
|
+
mixins.unshift(node)
|
56
|
+
|
57
|
+
range = node.loc.expression.join(mixins.last.loc.expression)
|
58
|
+
correction = group_mixins(node, mixins)
|
59
|
+
end
|
60
|
+
|
61
|
+
->(corrector) { corrector.replace(range, correction) }
|
62
|
+
end
|
63
|
+
|
49
64
|
private
|
50
65
|
|
51
66
|
def check(send_node)
|
@@ -57,7 +72,7 @@ module RuboCop
|
|
57
72
|
end
|
58
73
|
|
59
74
|
def check_grouped_style(send_node)
|
60
|
-
return
|
75
|
+
return if sibling_mixins(send_node).empty?
|
61
76
|
|
62
77
|
add_offense(send_node, :expression)
|
63
78
|
end
|
@@ -68,11 +83,11 @@ module RuboCop
|
|
68
83
|
add_offense(send_node, :expression)
|
69
84
|
end
|
70
85
|
|
71
|
-
def sibling_mixins
|
86
|
+
def sibling_mixins(send_node)
|
72
87
|
siblings = send_node.parent.each_child_node(:send)
|
73
88
|
.reject { |sibling| sibling == send_node }
|
74
89
|
|
75
|
-
siblings.
|
90
|
+
siblings.select do |sibling_node|
|
76
91
|
sibling_node.method_name == send_node.method_name
|
77
92
|
end
|
78
93
|
end
|
@@ -91,6 +106,29 @@ module RuboCop
|
|
91
106
|
def separated_style?
|
92
107
|
style == :separated
|
93
108
|
end
|
109
|
+
|
110
|
+
def separate_mixins(node)
|
111
|
+
_receiver, mixin, *args = *node
|
112
|
+
args.reverse!
|
113
|
+
first_mixin = String.new("#{mixin} #{args.first.source}")
|
114
|
+
|
115
|
+
args[1..-1].inject(first_mixin) do |replacement, arg|
|
116
|
+
replacement << "\n#{indent(node)}#{mixin} #{arg.source}"
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def group_mixins(node, mixins)
|
121
|
+
_receiver, mixin, *_args = *node
|
122
|
+
all_mixin_arguments = mixins.reverse.flat_map do |m|
|
123
|
+
m.arguments.map(&:source)
|
124
|
+
end
|
125
|
+
|
126
|
+
"#{mixin} #{all_mixin_arguments.join(', ')}"
|
127
|
+
end
|
128
|
+
|
129
|
+
def indent(node)
|
130
|
+
' ' * node.loc.column
|
131
|
+
end
|
94
132
|
end
|
95
133
|
end
|
96
134
|
end
|
@@ -17,20 +17,16 @@ module RuboCop
|
|
17
17
|
MSG = 'Avoid multi-line chains of blocks.'.freeze
|
18
18
|
|
19
19
|
def on_block(node)
|
20
|
-
|
21
|
-
|
22
|
-
receiver, _method_name, *_args = *send_node
|
23
|
-
next unless receiver && receiver.block_type?
|
20
|
+
node.send_node.each_node(:send) do |send_node|
|
21
|
+
receiver = send_node.receiver
|
24
22
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
next if do_kw_loc.line == end_kw_loc.line
|
23
|
+
next unless receiver && receiver.block_type? && receiver.multiline?
|
24
|
+
|
25
|
+
range = range_between(receiver.loc.end.begin_pos,
|
26
|
+
node.send_node.source_range.end_pos)
|
30
27
|
|
31
|
-
range = range_between(end_kw_loc.begin_pos,
|
32
|
-
method.source_range.end_pos)
|
33
28
|
add_offense(nil, range)
|
29
|
+
|
34
30
|
# Done. If there are more blocks in the chain, they will be
|
35
31
|
# found by subsequent calls to on_block.
|
36
32
|
break
|
@@ -0,0 +1,77 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Style
|
6
|
+
# This cop checks against comparing a variable with multiple items, where
|
7
|
+
# `Array#include?` could be used instead to avoid code repetition.
|
8
|
+
#
|
9
|
+
# @example
|
10
|
+
# # bad
|
11
|
+
# a = 'a'
|
12
|
+
# foo if a == 'a' || a == 'b' || a == 'c'
|
13
|
+
#
|
14
|
+
# # good
|
15
|
+
# a = 'a'
|
16
|
+
# foo if ['a', 'b', 'c'].include?(a)
|
17
|
+
class MultipleComparison < Cop
|
18
|
+
MSG = 'Avoid comparing a variable with multiple items' \
|
19
|
+
'in a conditional, use `Array#include?` instead.'.freeze
|
20
|
+
|
21
|
+
def on_if(node)
|
22
|
+
return unless nested_variable_comparison?(node.condition)
|
23
|
+
add_offense(node, :expression)
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def_node_matcher :simple_double_comparison?, '(send $lvar :== $lvar)'
|
29
|
+
def_node_matcher :simple_comparison?, <<-PATTERN
|
30
|
+
{(send $lvar :== _)
|
31
|
+
(send _ :== $lvar)}
|
32
|
+
PATTERN
|
33
|
+
|
34
|
+
def nested_variable_comparison?(node)
|
35
|
+
return false unless nested_comparison?(node)
|
36
|
+
variables_in_node(node).count == 1
|
37
|
+
end
|
38
|
+
|
39
|
+
def variables_in_node(node)
|
40
|
+
if node.or_type?
|
41
|
+
node.node_parts
|
42
|
+
.flat_map { |node_part| variables_in_node(node_part) }
|
43
|
+
.uniq
|
44
|
+
else
|
45
|
+
variables_in_simple_node(node)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def variables_in_simple_node(node)
|
50
|
+
simple_double_comparison?(node) do |var1, var2|
|
51
|
+
return [variable_name(var1), variable_name(var2)]
|
52
|
+
end
|
53
|
+
simple_comparison?(node) do |var|
|
54
|
+
return [variable_name(var)]
|
55
|
+
end
|
56
|
+
[]
|
57
|
+
end
|
58
|
+
|
59
|
+
def variable_name(node)
|
60
|
+
node.children[0]
|
61
|
+
end
|
62
|
+
|
63
|
+
def nested_comparison?(node)
|
64
|
+
if node.or_type?
|
65
|
+
node.node_parts.all? { |node_part| comparison? node_part }
|
66
|
+
else
|
67
|
+
false
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def comparison?(node)
|
72
|
+
simple_comparison?(node) || nested_comparison?(node)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -8,7 +8,7 @@ module RuboCop
|
|
8
8
|
# @example
|
9
9
|
# # bad
|
10
10
|
# [1, 2].each do |a|
|
11
|
-
# if a == 1
|
11
|
+
# if a == 1
|
12
12
|
# puts a
|
13
13
|
# end
|
14
14
|
# end
|
@@ -24,11 +24,6 @@ module RuboCop
|
|
24
24
|
|
25
25
|
MSG = 'Use `next` to skip iteration.'.freeze
|
26
26
|
EXIT_TYPES = %i[break return].freeze
|
27
|
-
EACH_ = 'each_'.freeze
|
28
|
-
ENUMERATORS = %i[collect collect_concat detect downto each
|
29
|
-
find find_all find_index inject loop map!
|
30
|
-
map reduce reject reject! reverse_each select
|
31
|
-
select! times upto].freeze
|
32
27
|
|
33
28
|
def investigate(_processed_source)
|
34
29
|
# When correcting nested offenses, we need to keep track of how much
|
@@ -37,32 +32,26 @@ module RuboCop
|
|
37
32
|
end
|
38
33
|
|
39
34
|
def on_block(node)
|
40
|
-
|
41
|
-
|
42
|
-
return unless body && ends_with_condition?(body)
|
35
|
+
return unless node.send_node.send_type? &&
|
36
|
+
node.send_node.enumerator_method?
|
43
37
|
|
44
|
-
|
45
|
-
return unless enumerator?(method_name)
|
46
|
-
|
47
|
-
offense_node = offense_node(body)
|
48
|
-
add_offense(offense_node, offense_location(offense_node), MSG)
|
38
|
+
check(node)
|
49
39
|
end
|
50
40
|
|
51
41
|
def on_while(node)
|
52
|
-
|
53
|
-
|
54
|
-
offending_node = offense_node(node.body)
|
55
|
-
|
56
|
-
add_offense(offending_node, offense_location(offending_node), MSG)
|
42
|
+
check(node)
|
57
43
|
end
|
58
44
|
alias on_until on_while
|
59
45
|
alias on_for on_while
|
60
46
|
|
61
47
|
private
|
62
48
|
|
63
|
-
def
|
64
|
-
|
65
|
-
|
49
|
+
def check(node)
|
50
|
+
return unless node.body && ends_with_condition?(node.body)
|
51
|
+
|
52
|
+
offending_node = offense_node(node.body)
|
53
|
+
|
54
|
+
add_offense(offending_node, offense_location(offending_node))
|
66
55
|
end
|
67
56
|
|
68
57
|
def ends_with_condition?(body)
|
@@ -142,13 +142,18 @@ module RuboCop
|
|
142
142
|
|
143
143
|
@assignments.each do |other|
|
144
144
|
_other_lhs, other_rhs = *other
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
145
|
+
|
146
|
+
next unless dependency?(my_lhs, other_rhs)
|
147
|
+
|
148
|
+
yield other
|
149
149
|
end
|
150
150
|
end
|
151
151
|
|
152
|
+
def dependency?(lhs, rhs)
|
153
|
+
uses_var?(rhs, var_name(lhs)) ||
|
154
|
+
lhs.send_type? && lhs.assignment_method? && accesses?(rhs, lhs)
|
155
|
+
end
|
156
|
+
|
152
157
|
# `lhs` is an assignment method call like `obj.attr=` or `ary[idx]=`.
|
153
158
|
# Does `rhs` access the same value which is assigned by `lhs`?
|
154
159
|
def accesses?(rhs, lhs)
|
@@ -164,21 +169,7 @@ module RuboCop
|
|
164
169
|
end
|
165
170
|
|
166
171
|
def modifier_statement?(node)
|
167
|
-
node &&
|
168
|
-
((node.if_type? && node.modifier_form?) ||
|
169
|
-
((node.while_type? || node.until_type?) && modifier_while?(node)))
|
170
|
-
end
|
171
|
-
|
172
|
-
def modifier_while?(node)
|
173
|
-
node.loc.respond_to?(:keyword) &&
|
174
|
-
%w[while until].include?(node.loc.keyword.source) &&
|
175
|
-
node.modifier_form?
|
176
|
-
end
|
177
|
-
|
178
|
-
def rescue_modifier_old?(node)
|
179
|
-
node && node.rescue_type? &&
|
180
|
-
(node.parent.nil? || !(node.parent.kwbegin_type? ||
|
181
|
-
node.parent.ensure_type?))
|
172
|
+
node && %i[if while until].include?(node.type) && node.modifier_form?
|
182
173
|
end
|
183
174
|
|
184
175
|
# An internal class for correcting parallel assignment
|