rubocop 0.42.0 → 0.43.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 +1 -1
- data/assets/output.html.erb +21 -10
- data/config/default.yml +32 -2
- data/config/disabled.yml +8 -1
- data/config/enabled.yml +40 -12
- data/lib/rubocop.rb +14 -2
- data/lib/rubocop/ast_node.rb +2 -0
- data/lib/rubocop/cached_data.rb +13 -11
- data/lib/rubocop/cli.rb +5 -5
- data/lib/rubocop/config.rb +68 -24
- data/lib/rubocop/config_loader.rb +13 -11
- data/lib/rubocop/config_loader_resolver.rb +4 -2
- data/lib/rubocop/cop/cop.rb +16 -5
- data/lib/rubocop/cop/lint/assignment_in_condition.rb +21 -20
- data/lib/rubocop/cop/lint/block_alignment.rb +3 -4
- data/lib/rubocop/cop/lint/def_end_alignment.rb +2 -3
- data/lib/rubocop/cop/lint/duplicate_methods.rb +16 -6
- data/lib/rubocop/cop/lint/else_layout.rb +1 -1
- data/lib/rubocop/cop/lint/empty_interpolation.rb +1 -1
- data/lib/rubocop/cop/lint/end_alignment.rb +4 -6
- data/lib/rubocop/cop/lint/eval.rb +1 -1
- data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +1 -1
- data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +8 -8
- data/lib/rubocop/cop/lint/inherit_exception.rb +22 -7
- data/lib/rubocop/cop/lint/literal_in_condition.rb +5 -5
- data/lib/rubocop/cop/lint/literal_in_interpolation.rb +3 -5
- data/lib/rubocop/cop/lint/next_without_accumulator.rb +1 -1
- data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +9 -8
- data/lib/rubocop/cop/lint/percent_string_array.rb +17 -6
- data/lib/rubocop/cop/lint/percent_symbol_array.rb +4 -4
- data/lib/rubocop/cop/lint/rand_one.rb +3 -3
- data/lib/rubocop/cop/lint/require_parentheses.rb +1 -3
- data/lib/rubocop/cop/lint/shadowed_exception.rb +39 -44
- data/lib/rubocop/cop/lint/string_conversion_in_interpolation.rb +2 -2
- data/lib/rubocop/cop/lint/underscore_prefixed_variable_name.rb +1 -2
- data/lib/rubocop/cop/lint/unified_integer.rb +38 -0
- data/lib/rubocop/cop/lint/unneeded_disable.rb +51 -38
- data/lib/rubocop/cop/lint/unneeded_splat_expansion.rb +114 -0
- data/lib/rubocop/cop/lint/useless_assignment.rb +25 -12
- data/lib/rubocop/cop/lint/useless_setter_call.rb +27 -28
- data/lib/rubocop/cop/lint/void.rb +2 -4
- data/lib/rubocop/cop/mixin/access_modifier_node.rb +5 -5
- data/lib/rubocop/cop/mixin/array_hash_indentation.rb +19 -17
- data/lib/rubocop/cop/mixin/autocorrect_alignment.rb +3 -5
- data/lib/rubocop/cop/mixin/configurable_naming.rb +4 -5
- data/lib/rubocop/cop/mixin/configurable_numbering.rb +52 -0
- data/lib/rubocop/cop/mixin/def_node.rb +28 -0
- data/lib/rubocop/cop/mixin/documentation_comment.rb +41 -0
- data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +18 -13
- data/lib/rubocop/cop/mixin/if_node.rb +6 -0
- data/lib/rubocop/cop/mixin/match_range.rb +2 -5
- data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +2 -2
- data/lib/rubocop/cop/mixin/multiline_literal_brace_layout.rb +40 -28
- data/lib/rubocop/cop/mixin/negative_conditional.rb +6 -6
- data/lib/rubocop/cop/mixin/percent_literal.rb +1 -5
- data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +14 -4
- data/lib/rubocop/cop/mixin/safe_mode.rb +23 -0
- data/lib/rubocop/cop/mixin/space_before_punctuation.rb +2 -4
- data/lib/rubocop/cop/mixin/space_inside.rb +1 -3
- data/lib/rubocop/cop/mixin/statement_modifier.rb +30 -20
- data/lib/rubocop/cop/mixin/trailing_comma.rb +19 -17
- data/lib/rubocop/cop/performance/case_when_splat.rb +16 -41
- data/lib/rubocop/cop/performance/casecmp.rb +28 -16
- data/lib/rubocop/cop/performance/count.rb +58 -34
- data/lib/rubocop/cop/performance/detect.rb +3 -7
- data/lib/rubocop/cop/performance/double_start_end_with.rb +17 -13
- data/lib/rubocop/cop/performance/fixed_size.rb +19 -14
- data/lib/rubocop/cop/performance/flat_map.rb +16 -9
- data/lib/rubocop/cop/performance/hash_each.rb +2 -3
- data/lib/rubocop/cop/performance/lstrip_rstrip.rb +4 -6
- data/lib/rubocop/cop/performance/redundant_match.rb +4 -1
- data/lib/rubocop/cop/performance/redundant_merge.rb +63 -32
- data/lib/rubocop/cop/performance/redundant_sort_by.rb +8 -7
- data/lib/rubocop/cop/performance/reverse_each.rb +1 -4
- data/lib/rubocop/cop/performance/size.rb +21 -8
- data/lib/rubocop/cop/performance/sort_with_block.rb +54 -0
- data/lib/rubocop/cop/performance/string_replacement.rb +3 -7
- data/lib/rubocop/cop/rails/delegate.rb +2 -3
- data/lib/rubocop/cop/rails/find_by.rb +4 -8
- data/lib/rubocop/cop/rails/not_null_column.rb +45 -0
- data/lib/rubocop/cop/rails/request_referer.rb +3 -3
- data/lib/rubocop/cop/rails/safe_navigation.rb +89 -0
- data/lib/rubocop/cop/rails/save_bang.rb +78 -9
- data/lib/rubocop/cop/rails/scope_args.rb +3 -1
- data/lib/rubocop/cop/rails/uniq_before_pluck.rb +2 -3
- data/lib/rubocop/cop/rails/validation.rb +1 -1
- data/lib/rubocop/cop/security/json_load.rb +36 -0
- data/lib/rubocop/cop/style/alias.rb +1 -1
- data/lib/rubocop/cop/style/align_hash.rb +25 -14
- data/lib/rubocop/cop/style/and_or.rb +13 -3
- data/lib/rubocop/cop/style/array_join.rb +3 -3
- data/lib/rubocop/cop/style/ascii_comments.rb +1 -2
- data/lib/rubocop/cop/style/ascii_identifiers.rb +1 -2
- data/lib/rubocop/cop/style/attr.rb +1 -3
- data/lib/rubocop/cop/style/block_comments.rb +2 -6
- data/lib/rubocop/cop/style/block_delimiters.rb +35 -21
- data/lib/rubocop/cop/style/braces_around_hash_parameters.rb +4 -4
- data/lib/rubocop/cop/style/case_indentation.rb +1 -3
- data/lib/rubocop/cop/style/class_methods.rb +3 -4
- data/lib/rubocop/cop/style/collection_methods.rb +1 -1
- data/lib/rubocop/cop/style/command_literal.rb +15 -8
- data/lib/rubocop/cop/style/comment_annotation.rb +1 -2
- data/lib/rubocop/cop/style/conditional_assignment.rb +68 -36
- data/lib/rubocop/cop/style/copyright.rb +1 -5
- data/lib/rubocop/cop/style/def_with_parentheses.rb +3 -5
- data/lib/rubocop/cop/style/documentation.rb +28 -56
- data/lib/rubocop/cop/style/documentation_method.rb +80 -0
- data/lib/rubocop/cop/style/each_for_simple_loop.rb +6 -5
- data/lib/rubocop/cop/style/each_with_object.rb +2 -2
- data/lib/rubocop/cop/style/else_alignment.rb +10 -9
- data/lib/rubocop/cop/style/empty_case_condition.rb +2 -4
- data/lib/rubocop/cop/style/empty_else.rb +1 -4
- data/lib/rubocop/cop/style/empty_line_between_defs.rb +1 -3
- data/lib/rubocop/cop/style/empty_lines_around_access_modifier.rb +2 -5
- data/lib/rubocop/cop/style/encoding.rb +28 -14
- data/lib/rubocop/cop/style/even_odd.rb +28 -17
- data/lib/rubocop/cop/style/extra_spacing.rb +36 -25
- data/lib/rubocop/cop/style/file_name.rb +19 -10
- data/lib/rubocop/cop/style/first_parameter_indentation.rb +2 -3
- data/lib/rubocop/cop/style/for.rb +12 -8
- data/lib/rubocop/cop/style/format_string.rb +1 -1
- data/lib/rubocop/cop/style/guard_clause.rb +22 -56
- data/lib/rubocop/cop/style/hash_syntax.rb +72 -7
- data/lib/rubocop/cop/style/if_unless_modifier.rb +23 -19
- data/lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb +3 -3
- data/lib/rubocop/cop/style/indentation_width.rb +30 -16
- data/lib/rubocop/cop/style/infinite_loop.rb +16 -13
- data/lib/rubocop/cop/style/initial_indentation.rb +23 -18
- data/lib/rubocop/cop/style/inline_comment.rb +16 -3
- data/lib/rubocop/cop/style/lambda.rb +22 -10
- data/lib/rubocop/cop/style/leading_comment_space.rb +12 -1
- data/lib/rubocop/cop/style/line_end_concatenation.rb +24 -6
- data/lib/rubocop/cop/style/method_call_parentheses.rb +18 -9
- data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +3 -4
- data/lib/rubocop/cop/style/method_def_parentheses.rb +3 -4
- data/lib/rubocop/cop/style/method_missing.rb +10 -2
- data/lib/rubocop/cop/style/module_function.rb +14 -6
- data/lib/rubocop/cop/style/multiline_assignment_layout.rb +2 -5
- data/lib/rubocop/cop/style/multiline_block_chain.rb +3 -5
- data/lib/rubocop/cop/style/multiline_block_layout.rb +22 -15
- data/lib/rubocop/cop/style/multiline_method_call_brace_layout.rb +9 -0
- data/lib/rubocop/cop/style/multiline_method_call_indentation.rb +41 -20
- data/lib/rubocop/cop/style/multiline_operation_indentation.rb +6 -6
- data/lib/rubocop/cop/style/multiline_ternary_operator.rb +3 -5
- data/lib/rubocop/cop/style/mutable_constant.rb +21 -13
- data/lib/rubocop/cop/style/negated_if.rb +1 -1
- data/lib/rubocop/cop/style/negated_while.rb +3 -3
- data/lib/rubocop/cop/style/nested_modifier.rb +2 -4
- data/lib/rubocop/cop/style/next.rb +4 -4
- data/lib/rubocop/cop/style/non_nil_check.rb +18 -10
- data/lib/rubocop/cop/style/numeric_literal_prefix.rb +8 -0
- data/lib/rubocop/cop/style/numeric_predicate.rb +9 -9
- data/lib/rubocop/cop/style/one_line_conditional.rb +11 -1
- data/lib/rubocop/cop/style/op_method.rb +1 -1
- data/lib/rubocop/cop/style/option_hash.rb +8 -8
- data/lib/rubocop/cop/style/optional_arguments.rb +21 -8
- data/lib/rubocop/cop/style/parallel_assignment.rb +51 -35
- data/lib/rubocop/cop/style/parentheses_around_condition.rb +2 -2
- data/lib/rubocop/cop/style/percent_literal_delimiters.rb +1 -1
- data/lib/rubocop/cop/style/raise_args.rb +2 -2
- data/lib/rubocop/cop/style/redundant_begin.rb +1 -1
- data/lib/rubocop/cop/style/redundant_parentheses.rb +26 -15
- data/lib/rubocop/cop/style/redundant_return.rb +5 -5
- data/lib/rubocop/cop/style/redundant_self.rb +20 -11
- data/lib/rubocop/cop/style/regexp_literal.rb +16 -10
- data/lib/rubocop/cop/style/rescue_ensure_alignment.rb +8 -6
- data/lib/rubocop/cop/style/safe_navigation.rb +125 -0
- data/lib/rubocop/cop/style/self_assignment.rb +2 -2
- data/lib/rubocop/cop/style/semicolon.rb +9 -10
- data/lib/rubocop/cop/style/signal_exception.rb +2 -4
- data/lib/rubocop/cop/style/single_line_block_params.rb +1 -1
- data/lib/rubocop/cop/style/single_line_methods.rb +18 -11
- data/lib/rubocop/cop/style/space_after_method_name.rb +2 -3
- data/lib/rubocop/cop/style/space_after_not.rb +4 -6
- data/lib/rubocop/cop/style/space_around_block_parameters.rb +1 -2
- data/lib/rubocop/cop/style/space_around_equals_in_parameter_default.rb +1 -3
- data/lib/rubocop/cop/style/space_around_operators.rb +21 -16
- data/lib/rubocop/cop/style/space_before_block_braces.rb +2 -12
- data/lib/rubocop/cop/style/space_before_first_arg.rb +1 -3
- data/lib/rubocop/cop/style/space_inside_array_percent_literal.rb +1 -1
- data/lib/rubocop/cop/style/space_inside_block_braces.rb +33 -40
- data/lib/rubocop/cop/style/space_inside_hash_literal_braces.rb +38 -23
- data/lib/rubocop/cop/style/space_inside_percent_literal_delimiters.rb +1 -1
- data/lib/rubocop/cop/style/space_inside_string_interpolation.rb +26 -12
- data/lib/rubocop/cop/style/stabby_lambda_parentheses.rb +2 -4
- data/lib/rubocop/cop/style/symbol_array.rb +10 -10
- data/lib/rubocop/cop/style/symbol_proc.rb +28 -13
- data/lib/rubocop/cop/style/ternary_parentheses.rb +35 -5
- data/lib/rubocop/cop/style/trailing_blank_lines.rb +2 -4
- data/lib/rubocop/cop/style/trailing_underscore_variable.rb +29 -17
- data/lib/rubocop/cop/style/trivial_accessors.rb +6 -6
- data/lib/rubocop/cop/style/unless_else.rb +2 -6
- data/lib/rubocop/cop/style/unneeded_capital_w.rb +8 -4
- data/lib/rubocop/cop/style/unneeded_interpolation.rb +4 -5
- data/lib/rubocop/cop/style/unneeded_percent_q.rb +13 -7
- data/lib/rubocop/cop/style/variable_number.rb +79 -0
- data/lib/rubocop/cop/style/while_until_modifier.rb +1 -1
- data/lib/rubocop/cop/style/word_array.rb +25 -15
- data/lib/rubocop/cop/style/zero_length_predicate.rb +2 -0
- data/lib/rubocop/cop/util.rb +23 -4
- data/lib/rubocop/cop/variable_force.rb +59 -25
- data/lib/rubocop/cop/variable_force/locatable.rb +8 -6
- data/lib/rubocop/cop/variable_force/variable.rb +2 -2
- data/lib/rubocop/cop/variable_force/variable_table.rb +3 -3
- data/lib/rubocop/formatter/disabled_config_formatter.rb +16 -11
- data/lib/rubocop/formatter/formatter_set.rb +12 -10
- data/lib/rubocop/formatter/worst_offenders_formatter.rb +4 -4
- data/lib/rubocop/node_pattern.rb +79 -35
- data/lib/rubocop/options.rb +4 -4
- data/lib/rubocop/processed_source.rb +9 -5
- data/lib/rubocop/remote_config.rb +14 -10
- data/lib/rubocop/result_cache.rb +14 -6
- data/lib/rubocop/runner.rb +55 -34
- data/lib/rubocop/string_util.rb +9 -5
- data/lib/rubocop/target_finder.rb +1 -1
- data/lib/rubocop/token.rb +1 -1
- data/lib/rubocop/version.rb +1 -1
- metadata +15 -4
- data/lib/rubocop/cop/lint/useless_array_splat.rb +0 -56
- data/lib/rubocop/cop/performance/push_splat.rb +0 -47
@@ -26,11 +26,7 @@ module RuboCop
|
|
26
26
|
# A range containing only the contents of the percent literal (e.g. in
|
27
27
|
# %i{1 2 3} this will be the range covering '1 2 3' only)
|
28
28
|
def contents_range(node)
|
29
|
-
|
30
|
-
node.loc.expression.source_buffer,
|
31
|
-
node.loc.begin.end_pos,
|
32
|
-
node.loc.end.begin_pos
|
33
|
-
)
|
29
|
+
range_between(node.loc.begin.end_pos, node.loc.end.begin_pos)
|
34
30
|
end
|
35
31
|
end
|
36
32
|
end
|
@@ -22,14 +22,24 @@ module RuboCop
|
|
22
22
|
# minus 2 because node.loc.line is zero-based
|
23
23
|
pre = (range.line - 2).downto(0)
|
24
24
|
post = range.line.upto(processed_source.lines.size - 1)
|
25
|
-
|
26
|
-
|
25
|
+
|
26
|
+
aligned_with_any_line_range?([pre, post], range, &predicate)
|
27
|
+
end
|
28
|
+
|
29
|
+
def aligned_with_any_line_range?(line_ranges, range, &predicate)
|
30
|
+
return true if aligned_with_any_line?(line_ranges, range, &predicate)
|
27
31
|
|
28
32
|
# If no aligned token was found, search for an aligned token on the
|
29
33
|
# nearest line with the same indentation as the checked line.
|
30
34
|
base_indentation = processed_source.lines[range.line - 1] =~ /\S/
|
31
|
-
|
32
|
-
|
35
|
+
|
36
|
+
aligned_with_any_line?(line_ranges, range, base_indentation, &predicate)
|
37
|
+
end
|
38
|
+
|
39
|
+
def aligned_with_any_line?(line_ranges, range, indent = nil, &predicate)
|
40
|
+
line_ranges.any? do |line_nos|
|
41
|
+
aligned_with_line?(line_nos, range, indent, &predicate)
|
42
|
+
end
|
33
43
|
end
|
34
44
|
|
35
45
|
def aligned_with_line?(line_nos, range, indent = nil)
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module RuboCop
|
5
|
+
module Cop
|
6
|
+
# Common functionality for Rails safe mode.
|
7
|
+
module SafeMode
|
8
|
+
private
|
9
|
+
|
10
|
+
def rails_safe_mode?
|
11
|
+
safe_mode? || rails?
|
12
|
+
end
|
13
|
+
|
14
|
+
def safe_mode?
|
15
|
+
cop_config['SafeMode']
|
16
|
+
end
|
17
|
+
|
18
|
+
def rails?
|
19
|
+
config['Rails'] && config['Rails']['Enabled']
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -20,10 +20,8 @@ module RuboCop
|
|
20
20
|
next unless space_missing?(t1, t2)
|
21
21
|
next if space_required_after?(t1)
|
22
22
|
|
23
|
-
|
24
|
-
|
25
|
-
t1.pos.end_pos,
|
26
|
-
t2.pos.begin_pos)
|
23
|
+
pos_before_punctuation = range_between(t1.pos.end_pos,
|
24
|
+
t2.pos.begin_pos)
|
27
25
|
|
28
26
|
yield t2, pos_before_punctuation
|
29
27
|
end
|
@@ -41,9 +41,7 @@ module RuboCop
|
|
41
41
|
end
|
42
42
|
|
43
43
|
def range_between_tokens(t1, t2)
|
44
|
-
|
45
|
-
t1.pos.end_pos,
|
46
|
-
t2.pos.begin_pos)
|
44
|
+
range_between(t1.pos.end_pos, t2.pos.begin_pos)
|
47
45
|
end
|
48
46
|
|
49
47
|
# Wraps info about the brackets. Makes it easy to check whether a token
|
@@ -7,18 +7,32 @@ module RuboCop
|
|
7
7
|
module StatementModifier
|
8
8
|
include IfNode
|
9
9
|
|
10
|
-
def
|
11
|
-
cond, body,
|
10
|
+
def single_line_as_modifier?(node)
|
11
|
+
cond, body, = if_node_parts(node)
|
12
12
|
|
13
|
-
return false if
|
14
|
-
|
13
|
+
return false if non_eligible_node?(node) || non_eligible_body?(body) ||
|
14
|
+
non_eligible_condition?(cond)
|
15
15
|
|
16
|
-
|
16
|
+
modifier_fits_on_single_line?(node)
|
17
|
+
end
|
18
|
+
|
19
|
+
def non_eligible_node?(node)
|
20
|
+
line_count(node) > 3 || commented?(node.loc.end)
|
21
|
+
end
|
22
|
+
|
23
|
+
def non_eligible_body?(body)
|
24
|
+
return true unless body
|
25
|
+
|
26
|
+
body.begin_type? || empty_body?(body) || commented?(body.source_range)
|
27
|
+
end
|
28
|
+
|
29
|
+
def non_eligible_condition?(condition)
|
30
|
+
condition.each_node.any?(&:lvasgn_type?)
|
31
|
+
end
|
17
32
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
return false if end_keyword_has_comment?(node)
|
33
|
+
def modifier_fits_on_single_line?(node)
|
34
|
+
cond, body, = if_node_parts(node)
|
35
|
+
body_length = body_length(body)
|
22
36
|
|
23
37
|
length_in_modifier_form(node, cond, body_length) <= max_line_length
|
24
38
|
end
|
@@ -36,24 +50,20 @@ module RuboCop
|
|
36
50
|
config.for_cop('Metrics/LineLength')['Max']
|
37
51
|
end
|
38
52
|
|
39
|
-
def
|
53
|
+
def line_count(node)
|
40
54
|
node.source.lines.grep(/\S/).size
|
41
55
|
end
|
42
56
|
|
43
|
-
def
|
44
|
-
|
45
|
-
body.source_range.size
|
46
|
-
else
|
47
|
-
0
|
48
|
-
end
|
57
|
+
def empty_body?(body)
|
58
|
+
body_length(body).zero?
|
49
59
|
end
|
50
60
|
|
51
|
-
def
|
52
|
-
|
61
|
+
def body_length(body)
|
62
|
+
body.source_range ? body.source_range.size : 0
|
53
63
|
end
|
54
64
|
|
55
|
-
def
|
56
|
-
comment_lines.include?(
|
65
|
+
def commented?(source)
|
66
|
+
comment_lines.include?(source.line)
|
57
67
|
end
|
58
68
|
|
59
69
|
def comment_lines
|
@@ -15,8 +15,7 @@ module RuboCop
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def check(node, items, kind, begin_pos, end_pos)
|
18
|
-
|
19
|
-
after_last_item = Parser::Source::Range.new(sb, begin_pos, end_pos)
|
18
|
+
after_last_item = range_between(begin_pos, end_pos)
|
20
19
|
|
21
20
|
return if heredoc?(after_last_item.source)
|
22
21
|
|
@@ -25,15 +24,14 @@ module RuboCop
|
|
25
24
|
if comma_offset && !inside_comment?(after_last_item, comma_offset)
|
26
25
|
check_comma(node, kind, after_last_item.begin_pos + comma_offset)
|
27
26
|
elsif should_have_comma?(style, node)
|
28
|
-
put_comma(node, items, kind
|
27
|
+
put_comma(node, items, kind)
|
29
28
|
end
|
30
29
|
end
|
31
30
|
|
32
31
|
def check_comma(node, kind, comma_pos)
|
33
32
|
return if should_have_comma?(style, node)
|
34
33
|
|
35
|
-
avoid_comma(kind, comma_pos,
|
36
|
-
extra_avoid_comma_info)
|
34
|
+
avoid_comma(kind, comma_pos, extra_avoid_comma_info)
|
37
35
|
end
|
38
36
|
|
39
37
|
def extra_avoid_comma_info
|
@@ -117,30 +115,34 @@ module RuboCop
|
|
117
115
|
a.last_line == b.line
|
118
116
|
end
|
119
117
|
|
120
|
-
def avoid_comma(kind, comma_begin_pos,
|
121
|
-
range =
|
122
|
-
comma_begin_pos + 1)
|
118
|
+
def avoid_comma(kind, comma_begin_pos, extra_info)
|
119
|
+
range = range_between(comma_begin_pos, comma_begin_pos + 1)
|
123
120
|
article = kind =~ /array/ ? 'an' : 'a'
|
124
121
|
add_offense(range, range,
|
125
122
|
format(MSG, 'Avoid', format(kind, article)) +
|
126
123
|
"#{extra_info}.")
|
127
124
|
end
|
128
125
|
|
129
|
-
def put_comma(node, items, kind
|
126
|
+
def put_comma(node, items, kind)
|
127
|
+
return if avoid_autocorrect?(elements(node))
|
128
|
+
|
130
129
|
last_item = items.last
|
131
|
-
return if last_item.
|
130
|
+
return if last_item.block_pass_type?
|
132
131
|
|
133
|
-
|
134
|
-
ix = last_expr.source.rindex("\n") || 0
|
135
|
-
ix += last_expr.source[ix..-1] =~ /\S/
|
136
|
-
range = Parser::Source::Range.new(sb, last_expr.begin_pos + ix,
|
137
|
-
last_expr.end_pos)
|
138
|
-
autocorrect_range = avoid_autocorrect?(elements(node)) ? nil : range
|
132
|
+
range = autocorrect_range(last_item)
|
139
133
|
|
140
|
-
add_offense(
|
134
|
+
add_offense(range, range,
|
141
135
|
format(MSG, 'Put a', format(kind, 'a multiline') + '.'))
|
142
136
|
end
|
143
137
|
|
138
|
+
def autocorrect_range(item)
|
139
|
+
expr = item.source_range
|
140
|
+
ix = expr.source.rindex("\n") || 0
|
141
|
+
ix += expr.source[ix..-1] =~ /\S/
|
142
|
+
|
143
|
+
range_between(expr.begin_pos + ix, expr.end_pos)
|
144
|
+
end
|
145
|
+
|
144
146
|
# By default, there's no reason to avoid auto-correct.
|
145
147
|
def avoid_autocorrect?(_)
|
146
148
|
false
|
@@ -94,37 +94,20 @@ module RuboCop
|
|
94
94
|
private
|
95
95
|
|
96
96
|
def replacement(conditions)
|
97
|
-
new_condition = conditions.map
|
98
|
-
variable, = *condition
|
99
|
-
if variable.respond_to?(:array_type?) && variable.array_type?
|
100
|
-
expand_percent_array(variable)
|
101
|
-
else
|
102
|
-
condition.source
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
97
|
+
new_condition = conditions.map(&:source)
|
106
98
|
new_condition.join(', ')
|
107
99
|
end
|
108
100
|
|
109
|
-
def inline_fix_branch(corrector,
|
110
|
-
range =
|
111
|
-
|
112
|
-
conditions[0].loc.expression.begin_pos,
|
113
|
-
conditions[-1].loc.expression.end_pos)
|
101
|
+
def inline_fix_branch(corrector, _node, conditions, new_condition)
|
102
|
+
range = range_between(conditions[0].loc.expression.begin_pos,
|
103
|
+
conditions[-1].loc.expression.end_pos)
|
114
104
|
corrector.replace(range, new_condition)
|
115
105
|
end
|
116
106
|
|
117
107
|
def reorder_condition(corrector, node, new_condition)
|
118
108
|
*_conditions, body = *node
|
119
|
-
|
120
|
-
|
121
|
-
current_index = when_branches.index { |branch| branch == node }
|
122
|
-
next_branch = when_branches[current_index + 1]
|
123
|
-
range = Parser::Source::Range.new(parent,
|
124
|
-
node.source_range.begin_pos,
|
125
|
-
next_branch.source_range.begin_pos)
|
126
|
-
|
127
|
-
corrector.remove(range)
|
109
|
+
_case_branch, *when_branches, _else_branch = *node.parent
|
110
|
+
corrector.remove(when_branch_range(node, when_branches))
|
128
111
|
|
129
112
|
correction = if same_line?(node, body)
|
130
113
|
new_condition_with_then(node, new_condition)
|
@@ -135,6 +118,14 @@ module RuboCop
|
|
135
118
|
corrector.insert_after(when_branches.last.source_range, correction)
|
136
119
|
end
|
137
120
|
|
121
|
+
def when_branch_range(node, when_branches)
|
122
|
+
current_index = when_branches.index { |branch| branch == node }
|
123
|
+
next_branch = when_branches[current_index + 1]
|
124
|
+
|
125
|
+
range_between(node.source_range.begin_pos,
|
126
|
+
next_branch.source_range.begin_pos)
|
127
|
+
end
|
128
|
+
|
138
129
|
def same_line?(node, other)
|
139
130
|
node.loc.first_line == other.loc.first_line
|
140
131
|
end
|
@@ -155,6 +146,8 @@ module RuboCop
|
|
155
146
|
found_non_splat ||= error_condition?(condition)
|
156
147
|
|
157
148
|
next unless condition.splat_type?
|
149
|
+
variable, = *condition
|
150
|
+
next if variable.array_type?
|
158
151
|
result << condition if found_non_splat
|
159
152
|
end
|
160
153
|
end
|
@@ -172,24 +165,6 @@ module RuboCop
|
|
172
165
|
condition.splat_type? && !(variable && variable.array_type?)
|
173
166
|
end
|
174
167
|
end
|
175
|
-
|
176
|
-
def expand_percent_array(array)
|
177
|
-
array_start = array.loc.begin.source
|
178
|
-
elements = *array
|
179
|
-
elements = elements.map(&:source)
|
180
|
-
|
181
|
-
if array_start.start_with?(PERCENT_W)
|
182
|
-
"'#{elements.join("', '")}'"
|
183
|
-
elsif array_start.start_with?(PERCENT_CAPITAL_W)
|
184
|
-
%("#{elements.join('", "')}")
|
185
|
-
elsif array_start.start_with?(PERCENT_I)
|
186
|
-
":#{elements.join(', :')}"
|
187
|
-
elsif array_start.start_with?(PERCENT_CAPITAL_I)
|
188
|
-
%(:"#{elements.join('", :"')}")
|
189
|
-
else
|
190
|
-
elements.join(', ')
|
191
|
-
end
|
192
|
-
end
|
193
168
|
end
|
194
169
|
end
|
195
170
|
end
|
@@ -39,22 +39,9 @@ module RuboCop
|
|
39
39
|
def on_send(node)
|
40
40
|
return if part_of_ignored_node?(node)
|
41
41
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
range = node.loc.expression
|
46
|
-
ignore_node(node)
|
47
|
-
else
|
48
|
-
range = node.loc.selector.join(send_downcase.loc.selector)
|
49
|
-
end
|
50
|
-
|
51
|
-
add_offense(node, range, format(MSG, case_method, eq_method))
|
52
|
-
return
|
53
|
-
end
|
54
|
-
|
55
|
-
eq_downcase(node) do |eq_method, send_downcase, case_method|
|
56
|
-
range = node.loc.selector.join(send_downcase.loc.selector)
|
57
|
-
add_offense(node, range, format(MSG, eq_method, case_method))
|
42
|
+
inefficient_comparison(node) do |range, is_other_part, *methods|
|
43
|
+
ignore_node(node) if is_other_part
|
44
|
+
add_offense(node, range, format(MSG, *methods))
|
58
45
|
end
|
59
46
|
end
|
60
47
|
|
@@ -74,6 +61,31 @@ module RuboCop
|
|
74
61
|
|
75
62
|
private
|
76
63
|
|
64
|
+
def inefficient_comparison(node)
|
65
|
+
loc = node.loc
|
66
|
+
|
67
|
+
downcase_eq(node) do |send_downcase, case_method, eq_method, other|
|
68
|
+
*_, method = *other
|
69
|
+
range, is_other_part = downcase_eq_range(method, loc, send_downcase)
|
70
|
+
|
71
|
+
yield range, is_other_part, case_method, eq_method
|
72
|
+
return
|
73
|
+
end
|
74
|
+
|
75
|
+
eq_downcase(node) do |eq_method, send_downcase, case_method|
|
76
|
+
range = loc.selector.join(send_downcase.loc.selector)
|
77
|
+
yield range, false, eq_method, case_method
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def downcase_eq_range(method, loc, send_downcase)
|
82
|
+
if CASE_METHODS.include?(method)
|
83
|
+
[loc.expression, true]
|
84
|
+
else
|
85
|
+
[loc.selector.join(send_downcase.loc.selector), false]
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
77
89
|
def correction(node, _receiver, method, arg, variable)
|
78
90
|
lambda do |corrector|
|
79
91
|
corrector.insert_before(node.loc.expression, '!') if method == :!=
|
@@ -39,24 +39,32 @@ module RuboCop
|
|
39
39
|
#
|
40
40
|
# Model.where(id: [1, 2, 3]).to_a.count { |m| m.method == true }
|
41
41
|
class Count < Cop
|
42
|
+
include SafeMode
|
43
|
+
|
42
44
|
MSG = 'Use `count` instead of `%s...%s`.'.freeze
|
43
45
|
|
44
46
|
SELECTORS = [:reject, :select].freeze
|
45
47
|
COUNTERS = [:count, :length, :size].freeze
|
46
48
|
|
47
49
|
def on_send(node)
|
48
|
-
return
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
50
|
+
return if rails_safe_mode?
|
51
|
+
|
52
|
+
@selector, @selector_loc, @params, @counter = parse(node)
|
53
|
+
|
54
|
+
check(node)
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
attr_reader :selector, :selector_loc, :params, :counter
|
60
|
+
|
61
|
+
def check(node)
|
62
|
+
return unless eligible_node?(node) && eligible_params? &&
|
63
|
+
eligible_method_chain?
|
64
|
+
|
65
|
+
range = source_starting_at(node) { @selector_loc.begin_pos }
|
66
|
+
|
67
|
+
add_offense(node, range, format(MSG, @selector, @counter))
|
60
68
|
end
|
61
69
|
|
62
70
|
def autocorrect(node)
|
@@ -64,9 +72,7 @@ module RuboCop
|
|
64
72
|
|
65
73
|
return if selector == :reject
|
66
74
|
|
67
|
-
range =
|
68
|
-
node.loc.dot.begin_pos,
|
69
|
-
node.source_range.end_pos)
|
75
|
+
range = source_starting_at(node) { |n| n.loc.dot.begin_pos }
|
70
76
|
|
71
77
|
lambda do |corrector|
|
72
78
|
corrector.remove(range)
|
@@ -74,37 +80,55 @@ module RuboCop
|
|
74
80
|
end
|
75
81
|
end
|
76
82
|
|
77
|
-
|
83
|
+
def eligible_node?(node)
|
84
|
+
!(node.parent && node.parent.block_type?)
|
85
|
+
end
|
78
86
|
|
79
|
-
def
|
80
|
-
!(
|
81
|
-
config['Rails'.freeze] &&
|
82
|
-
config['Rails'.freeze]['Enabled'.freeze])
|
87
|
+
def eligible_params?
|
88
|
+
!(params && !params.block_pass_type?)
|
83
89
|
end
|
84
90
|
|
85
|
-
def
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
selector_loc =
|
90
|
-
if selector.is_a?(Symbol)
|
91
|
-
if expression && expression.parent.loc.respond_to?(:selector)
|
92
|
-
expression.parent.loc.selector
|
93
|
-
elsif left.loc.respond_to?(:selector)
|
94
|
-
left.loc.selector
|
95
|
-
end
|
96
|
-
else
|
97
|
-
_enumerable, selector, params = *expression
|
91
|
+
def eligible_method_chain?
|
92
|
+
COUNTERS.include?(counter) && SELECTORS.include?(selector)
|
93
|
+
end
|
98
94
|
|
99
|
-
|
95
|
+
def parse(node)
|
96
|
+
head, counter = *node
|
97
|
+
expression, selector, params = *head
|
98
|
+
if selector.is_a?(Symbol)
|
99
|
+
selector_loc = selector_location(expression, head.loc)
|
100
|
+
else
|
101
|
+
_, selector, params = *expression
|
102
|
+
if contains_selector?(expression)
|
103
|
+
selector_loc = expression.loc.selector
|
100
104
|
end
|
105
|
+
end
|
101
106
|
|
102
107
|
[selector, selector_loc, params, counter]
|
103
108
|
end
|
104
109
|
|
110
|
+
def selector_location(expression, head_loc)
|
111
|
+
if expression && expression.parent.loc.respond_to?(:selector)
|
112
|
+
expression.parent.loc.selector
|
113
|
+
elsif head_loc.respond_to?(:selector)
|
114
|
+
head_loc.selector
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
105
118
|
def contains_selector?(node)
|
106
119
|
node.respond_to?(:loc) && node.loc.respond_to?(:selector)
|
107
120
|
end
|
121
|
+
|
122
|
+
def source_starting_at(node)
|
123
|
+
begin_pos =
|
124
|
+
if block_given?
|
125
|
+
yield node
|
126
|
+
else
|
127
|
+
node.source_range.begin_pos
|
128
|
+
end
|
129
|
+
|
130
|
+
range_between(begin_pos, node.source_range.end_pos)
|
131
|
+
end
|
108
132
|
end
|
109
133
|
end
|
110
134
|
end
|