rubocop 0.21.0 → 0.22.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/.rubocop.yml +1 -1
- data/{rubocop-todo.yml → .rubocop_todo.yml} +5 -5
- data/CHANGELOG.md +41 -0
- data/README.md +21 -11
- data/config/default.yml +33 -10
- data/config/disabled.yml +0 -4
- data/config/enabled.yml +27 -1
- data/lib/rubocop.rb +17 -1
- data/lib/rubocop/config.rb +32 -27
- data/lib/rubocop/config_loader.rb +21 -8
- data/lib/rubocop/cop/cop.rb +8 -8
- data/lib/rubocop/cop/lint/block_alignment.rb +22 -22
- data/lib/rubocop/cop/lint/condition_position.rb +3 -5
- data/lib/rubocop/cop/lint/debugger.rb +4 -5
- data/lib/rubocop/cop/lint/end_alignment.rb +11 -10
- data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +10 -11
- data/lib/rubocop/cop/lint/require_parentheses.rb +7 -7
- data/lib/rubocop/cop/lint/rescue_exception.rb +3 -3
- data/lib/rubocop/cop/lint/string_conversion_in_interpolation.rb +6 -7
- data/lib/rubocop/cop/lint/unreachable_code.rb +2 -3
- data/lib/rubocop/cop/lint/unused_block_argument.rb +2 -15
- data/lib/rubocop/cop/lint/unused_method_argument.rb +2 -14
- data/lib/rubocop/cop/lint/useless_comparison.rb +4 -5
- data/lib/rubocop/cop/lint/void.rb +6 -8
- data/lib/rubocop/cop/mixin/autocorrect_alignment.rb +4 -2
- data/lib/rubocop/cop/mixin/autocorrect_unless_changing_ast.rb +1 -3
- data/lib/rubocop/cop/mixin/code_length.rb +5 -5
- data/lib/rubocop/cop/mixin/negative_conditional.rb +6 -6
- data/lib/rubocop/cop/mixin/percent_literal.rb +2 -3
- data/lib/rubocop/cop/mixin/space_after_punctuation.rb +5 -5
- data/lib/rubocop/cop/mixin/space_inside.rb +10 -11
- data/lib/rubocop/cop/mixin/unused_argument.rb +35 -0
- data/lib/rubocop/cop/offense.rb +1 -1
- data/lib/rubocop/cop/rails/action_filter.rb +6 -8
- data/lib/rubocop/cop/rails/default_scope.rb +2 -4
- data/lib/rubocop/cop/rails/delegate.rb +2 -0
- data/lib/rubocop/cop/rails/has_and_belongs_to_many.rb +2 -3
- data/lib/rubocop/cop/rails/output.rb +2 -3
- data/lib/rubocop/cop/rails/read_write_attribute.rb +3 -4
- data/lib/rubocop/cop/rails/validation.rb +2 -3
- data/lib/rubocop/cop/style/alias.rb +3 -3
- data/lib/rubocop/cop/style/align_hash.rb +4 -4
- data/lib/rubocop/cop/style/align_parameters.rb +13 -1
- data/lib/rubocop/cop/style/and_or.rb +2 -5
- data/lib/rubocop/cop/style/array_join.rb +3 -4
- data/lib/rubocop/cop/style/ascii_identifiers.rb +2 -3
- data/lib/rubocop/cop/style/block_comments.rb +2 -3
- data/lib/rubocop/cop/style/block_nesting.rb +2 -3
- data/lib/rubocop/cop/style/blocks.rb +9 -9
- data/lib/rubocop/cop/style/braces_around_hash_parameters.rb +5 -5
- data/lib/rubocop/cop/style/class_and_module_children.rb +1 -1
- data/lib/rubocop/cop/style/class_methods.rb +3 -5
- data/lib/rubocop/cop/style/collection_methods.rb +8 -11
- data/lib/rubocop/cop/style/comment_annotation.rb +9 -9
- data/lib/rubocop/cop/style/comment_indentation.rb +66 -0
- data/lib/rubocop/cop/style/constant_name.rb +3 -3
- data/lib/rubocop/cop/style/cyclomatic_complexity.rb +5 -5
- data/lib/rubocop/cop/style/deprecated_hash_methods.rb +6 -6
- data/lib/rubocop/cop/style/each_with_object.rb +38 -0
- data/lib/rubocop/cop/style/empty_lines.rb +8 -8
- data/lib/rubocop/cop/style/empty_lines_around_body.rb +7 -7
- data/lib/rubocop/cop/style/encoding.rb +6 -7
- data/lib/rubocop/cop/style/end_of_line.rb +10 -10
- data/lib/rubocop/cop/style/file_name.rb +11 -7
- data/lib/rubocop/cop/style/guard_clause.rb +32 -22
- data/lib/rubocop/cop/style/indentation_width.rb +25 -26
- data/lib/rubocop/cop/style/lambda.rb +8 -9
- data/lib/rubocop/cop/style/leading_comment_space.rb +4 -5
- data/lib/rubocop/cop/style/line_end_concatenation.rb +29 -6
- data/lib/rubocop/cop/style/line_length.rb +9 -9
- data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +7 -6
- data/lib/rubocop/cop/style/module_function.rb +3 -4
- data/lib/rubocop/cop/style/multiline_if_then.rb +3 -3
- data/lib/rubocop/cop/style/negated_if.rb +2 -0
- data/lib/rubocop/cop/style/next.rb +80 -0
- data/lib/rubocop/cop/style/nil_comparison.rb +2 -3
- data/lib/rubocop/cop/style/non_nil_check.rb +15 -3
- data/lib/rubocop/cop/style/not.rb +4 -4
- data/lib/rubocop/cop/style/numeric_literals.rb +7 -8
- data/lib/rubocop/cop/style/op_method.rb +3 -5
- data/lib/rubocop/cop/style/parameter_lists.rb +4 -4
- data/lib/rubocop/cop/style/parentheses_around_condition.rb +5 -6
- data/lib/rubocop/cop/style/percent_literal_delimiters.rb +5 -5
- data/lib/rubocop/cop/style/predicate_name.rb +2 -4
- data/lib/rubocop/cop/style/redundant_self.rb +11 -12
- data/lib/rubocop/cop/style/self_assignment.rb +8 -13
- data/lib/rubocop/cop/style/semicolon.rb +16 -19
- data/lib/rubocop/cop/style/signal_exception.rb +10 -11
- data/lib/rubocop/cop/style/single_line_block_params.rb +2 -3
- data/lib/rubocop/cop/style/single_line_methods.rb +3 -4
- data/lib/rubocop/cop/style/space_after_colon.rb +9 -9
- data/lib/rubocop/cop/style/space_after_control_keyword.rb +3 -3
- data/lib/rubocop/cop/style/space_after_method_name.rb +3 -3
- data/lib/rubocop/cop/style/space_after_not.rb +3 -4
- data/lib/rubocop/cop/style/space_around_operators.rb +5 -4
- data/lib/rubocop/cop/style/space_before_comment.rb +29 -0
- data/lib/rubocop/cop/style/space_before_modifier_keyword.rb +6 -7
- data/lib/rubocop/cop/style/symbol_array.rb +2 -3
- data/lib/rubocop/cop/style/tab.rb +8 -8
- data/lib/rubocop/cop/style/trailing_blank_lines.rb +10 -10
- data/lib/rubocop/cop/style/trailing_whitespace.rb +6 -7
- data/lib/rubocop/cop/style/trivial_accessors.rb +3 -4
- data/lib/rubocop/cop/style/unless_else.rb +2 -3
- data/lib/rubocop/cop/style/unneeded_capital_w.rb +3 -3
- data/lib/rubocop/cop/style/unneeded_percent_x.rb +26 -0
- data/lib/rubocop/cop/style/when_then.rb +3 -3
- data/lib/rubocop/cop/style/while_until_do.rb +3 -6
- data/lib/rubocop/cop/style/word_array.rb +8 -7
- data/lib/rubocop/cop/team.rb +9 -11
- data/lib/rubocop/cop/util.rb +2 -3
- data/lib/rubocop/cop/variable_force.rb +2 -3
- data/lib/rubocop/cop/variable_force/variable_table.rb +1 -2
- data/lib/rubocop/file_inspector.rb +5 -0
- data/lib/rubocop/formatter/clang_style_formatter.rb +3 -4
- data/lib/rubocop/formatter/disabled_config_formatter.rb +6 -6
- data/lib/rubocop/options.rb +14 -11
- data/lib/rubocop/target_finder.rb +12 -1
- data/lib/rubocop/version.rb +1 -1
- data/relnotes/v0.21.0.md +11 -0
- data/relnotes/v0.22.0.md +77 -0
- data/spec/rubocop/cli_spec.rb +86 -40
- data/spec/rubocop/comment_config_spec.rb +1 -1
- data/spec/rubocop/config_loader_spec.rb +3 -3
- data/spec/rubocop/config_spec.rb +14 -3
- data/spec/rubocop/cop/force_spec.rb +1 -1
- data/spec/rubocop/cop/lint/unused_block_argument_spec.rb +164 -99
- data/spec/rubocop/cop/lint/unused_method_argument_spec.rb +195 -85
- data/spec/rubocop/cop/lint/void_spec.rb +8 -0
- data/spec/rubocop/cop/rails/delegate_spec.rb +17 -0
- data/spec/rubocop/cop/rails/output_spec.rb +3 -3
- data/spec/rubocop/cop/severity_spec.rb +5 -5
- data/spec/rubocop/cop/style/align_parameters_spec.rb +108 -0
- data/spec/rubocop/cop/style/block_nesting_spec.rb +3 -3
- data/spec/rubocop/cop/style/class_and_module_children_spec.rb +12 -10
- data/spec/rubocop/cop/style/comment_indentation_spec.rb +174 -0
- data/spec/rubocop/cop/style/each_with_object_spec.rb +44 -0
- data/spec/rubocop/cop/style/end_of_line_spec.rb +3 -5
- data/spec/rubocop/cop/style/guard_clause_spec.rb +135 -57
- data/spec/rubocop/cop/style/if_unless_modifier_spec.rb +7 -7
- data/spec/rubocop/cop/style/line_end_concatenation_spec.rb +75 -1
- data/spec/rubocop/cop/style/line_length_spec.rb +7 -7
- data/spec/rubocop/cop/style/negated_if_spec.rb +5 -1
- data/spec/rubocop/cop/style/next_spec.rb +210 -0
- data/spec/rubocop/cop/style/non_nil_check_spec.rb +44 -13
- data/spec/rubocop/cop/style/self_assignment_spec.rb +1 -1
- data/spec/rubocop/cop/style/space_around_operators_spec.rb +1 -0
- data/spec/rubocop/cop/style/space_before_comment_spec.rb +34 -0
- data/spec/rubocop/cop/style/unneeded_percent_x_spec.rb +34 -0
- data/spec/rubocop/cop/style/while_until_modifier_spec.rb +2 -2
- data/spec/rubocop/cop/util_spec.rb +2 -2
- data/spec/rubocop/cop/variable_force_spec.rb +1 -1
- data/spec/rubocop/formatter/disabled_config_formatter_spec.rb +4 -4
- data/spec/rubocop/formatter/disabled_lines_formatter_spec.rb +2 -2
- data/spec/rubocop/formatter/offense_count_formatter_spec.rb +2 -2
- data/spec/rubocop/options_spec.rb +3 -0
- data/spec/support/shared_context.rb +1 -3
- data/spec/support/statement_modifier_helper.rb +2 -2
- metadata +20 -3
@@ -20,10 +20,9 @@ module Rubocop
|
|
20
20
|
|
21
21
|
def on_send(node)
|
22
22
|
_receiver, _method_name, *args = *node
|
23
|
+
return unless args.size == 1 && args.first.type == :block_pass
|
23
24
|
|
24
|
-
|
25
|
-
check_method_node(node)
|
26
|
-
end
|
25
|
+
check_method_node(node)
|
27
26
|
end
|
28
27
|
|
29
28
|
def autocorrect(node)
|
@@ -38,14 +37,12 @@ module Rubocop
|
|
38
37
|
def check_method_node(node)
|
39
38
|
_receiver, method_name, *_args = *node
|
40
39
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
)
|
48
|
-
end
|
40
|
+
return unless preferred_methods[method_name]
|
41
|
+
add_offense(node, :selector,
|
42
|
+
format(MSG,
|
43
|
+
preferred_method(method_name),
|
44
|
+
method_name)
|
45
|
+
)
|
49
46
|
end
|
50
47
|
|
51
48
|
def preferred_method(method)
|
@@ -14,15 +14,15 @@ module Rubocop
|
|
14
14
|
def investigate(processed_source)
|
15
15
|
processed_source.comments.each do |comment|
|
16
16
|
margin, first_word, colon, space, note = split_comment(comment)
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
17
|
+
next unless annotation?(comment) &&
|
18
|
+
!correct_annotation?(first_word, colon, space, note)
|
19
|
+
|
20
|
+
start = comment.loc.expression.begin_pos + margin.length
|
21
|
+
length = first_word.length + (colon || '').length
|
22
|
+
range = Parser::Source::Range.new(processed_source.buffer,
|
23
|
+
start,
|
24
|
+
start + length)
|
25
|
+
add_offense(nil, range)
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Rubocop
|
4
|
+
module Cop
|
5
|
+
module Style
|
6
|
+
# This cops checks the indentation of comments.
|
7
|
+
class CommentIndentation < Cop
|
8
|
+
include AutocorrectAlignment
|
9
|
+
|
10
|
+
MSG = 'Incorrect indentation detected (column %d instead of %d).'
|
11
|
+
|
12
|
+
def investigate(processed_source)
|
13
|
+
processed_source.comments.each do |comment|
|
14
|
+
lines = processed_source.lines
|
15
|
+
own_line = lines[comment.loc.line - 1]
|
16
|
+
next unless own_line =~ /\A\s*#/
|
17
|
+
|
18
|
+
next_line =
|
19
|
+
lines[comment.loc.line..-1].find { |line| !line.blank? }
|
20
|
+
|
21
|
+
correct_comment_indentation = correct_indentation(next_line)
|
22
|
+
column = comment.loc.column
|
23
|
+
|
24
|
+
@column_delta = correct_comment_indentation - column
|
25
|
+
next if @column_delta == 0
|
26
|
+
|
27
|
+
if two_alternatives?(next_line)
|
28
|
+
correct_comment_indentation +=
|
29
|
+
IndentationWidth::CORRECT_INDENTATION # Try the other
|
30
|
+
# We keep @column_delta unchanged so that autocorrect changes to
|
31
|
+
# the preferred style of aligning the comment with the keyword.
|
32
|
+
end
|
33
|
+
|
34
|
+
next if column == correct_comment_indentation
|
35
|
+
add_offense(comment, comment.loc.expression,
|
36
|
+
format(MSG, column, correct_comment_indentation))
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def correct_indentation(next_line)
|
43
|
+
return 0 unless next_line
|
44
|
+
|
45
|
+
indentation_of_next_line = next_line =~ /\S/
|
46
|
+
indentation_of_next_line + if less_indented?(next_line)
|
47
|
+
IndentationWidth::CORRECT_INDENTATION
|
48
|
+
else
|
49
|
+
0
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def less_indented?(line)
|
54
|
+
keyword = 'end\b'
|
55
|
+
bracket = '[}\]]'
|
56
|
+
line =~ /^\s*(#{keyword}|#{bracket})/
|
57
|
+
end
|
58
|
+
|
59
|
+
def two_alternatives?(line)
|
60
|
+
keyword = '(else|elsif|when|rescue|ensure)\b'
|
61
|
+
line =~ /^\s*#{keyword}/
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -19,9 +19,9 @@ module Rubocop
|
|
19
19
|
# NewClass = something_that_returns_a_class
|
20
20
|
# It's also ok to assign a class constant another class constant
|
21
21
|
# SomeClass = SomeOtherClass
|
22
|
-
|
23
|
-
|
24
|
-
|
22
|
+
return if value && [:send, :block, :const].include?(value.type)
|
23
|
+
|
24
|
+
add_offense(node, :name) if const_name !~ SNAKE_CASE
|
25
25
|
end
|
26
26
|
end
|
27
27
|
end
|
@@ -28,11 +28,11 @@ module Rubocop
|
|
28
28
|
on_node(DECISION_POINT_NODES, node) { complexity += 1 }
|
29
29
|
|
30
30
|
max = cop_config['Max']
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
31
|
+
return unless complexity > max
|
32
|
+
|
33
|
+
add_offense(node, :keyword,
|
34
|
+
format(MSG, method_name, complexity, max)) do
|
35
|
+
self.max = complexity
|
36
36
|
end
|
37
37
|
end
|
38
38
|
end
|
@@ -12,13 +12,13 @@ module Rubocop
|
|
12
12
|
|
13
13
|
def on_send(node)
|
14
14
|
_receiver, method_name, *args = *node
|
15
|
+
return unless args.size == 1 &&
|
16
|
+
DEPRECATED_METHODS.include?(method_name)
|
15
17
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
proper_method_name(method_name)))
|
21
|
-
end
|
18
|
+
add_offense(node, :selector,
|
19
|
+
format(MSG,
|
20
|
+
method_name,
|
21
|
+
proper_method_name(method_name)))
|
22
22
|
end
|
23
23
|
|
24
24
|
def autocorrect(node)
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Rubocop
|
4
|
+
module Cop
|
5
|
+
module Style
|
6
|
+
# This cop looks for inject / reduce calls where the passed in object is
|
7
|
+
# returned at the end and so could be replace by each_with_object without
|
8
|
+
# the need to return the object at the end.
|
9
|
+
#
|
10
|
+
# @example
|
11
|
+
# # bad
|
12
|
+
# [1, 2].inject({}) { |a, e| a[e] = e; a }
|
13
|
+
#
|
14
|
+
# # good
|
15
|
+
# [1, 2].each_with_object({}) { |e, a| a[e] = e }
|
16
|
+
class EachWithObject < Cop
|
17
|
+
MSG = 'Use `each_with_object` instead of `%s`.'
|
18
|
+
METHODS = [:inject, :reduce]
|
19
|
+
|
20
|
+
def on_block(node)
|
21
|
+
method, args, body = *node
|
22
|
+
_, method_name, method_args = *method
|
23
|
+
|
24
|
+
return unless METHODS.include? method_name
|
25
|
+
return if method_args.type == :sym
|
26
|
+
return_value = body.children.last
|
27
|
+
return unless return_value.type == :lvar
|
28
|
+
first_arg, = *args
|
29
|
+
accumulator_var = *first_arg
|
30
|
+
return_var = *return_value
|
31
|
+
return unless accumulator_var == return_var
|
32
|
+
|
33
|
+
add_offense(method, :selector, format(MSG, method_name))
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -23,14 +23,14 @@ module Rubocop
|
|
23
23
|
# don't show up in the tokens
|
24
24
|
((prev_line + 1)...cur_line).each do |line|
|
25
25
|
# we check if the prev and current lines are empty
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
26
|
+
next unless processed_source[line - 2].empty? &&
|
27
|
+
processed_source[line - 1].empty?
|
28
|
+
|
29
|
+
range = source_range(processed_source.buffer,
|
30
|
+
processed_source[0...(line - 1)],
|
31
|
+
0,
|
32
|
+
1)
|
33
|
+
add_offense(range, range)
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
@@ -60,13 +60,13 @@ module Rubocop
|
|
60
60
|
end
|
61
61
|
|
62
62
|
def check_line(line, msg)
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
63
|
+
return unless processed_source.lines[line].empty?
|
64
|
+
|
65
|
+
range = source_range(processed_source.buffer,
|
66
|
+
processed_source[0...line],
|
67
|
+
0,
|
68
|
+
1)
|
69
|
+
add_offense(range, range, msg)
|
70
70
|
end
|
71
71
|
end
|
72
72
|
end
|
@@ -23,13 +23,12 @@ module Rubocop
|
|
23
23
|
line_number = encoding_line_number(processed_source)
|
24
24
|
message = offense(processed_source, line_number)
|
25
25
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
end
|
26
|
+
return unless message
|
27
|
+
add_offense(nil,
|
28
|
+
source_range(processed_source.buffer,
|
29
|
+
processed_source[0...line_number],
|
30
|
+
0, 1),
|
31
|
+
message)
|
33
32
|
end
|
34
33
|
|
35
34
|
private
|
@@ -12,16 +12,16 @@ module Rubocop
|
|
12
12
|
original_source = IO.read(buffer.name,
|
13
13
|
encoding: buffer.source.encoding)
|
14
14
|
original_source.lines.each_with_index do |line, index|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
15
|
+
next unless line =~ /\r$/
|
16
|
+
|
17
|
+
add_offense(nil,
|
18
|
+
source_range(buffer,
|
19
|
+
processed_source[0...index],
|
20
|
+
0, line.length),
|
21
|
+
MSG)
|
22
|
+
# Usually there will be carriage return characters on all or none
|
23
|
+
# of the lines in a file, so we report only one offense.
|
24
|
+
break
|
25
25
|
end
|
26
26
|
end
|
27
27
|
end
|
@@ -11,17 +11,21 @@ module Rubocop
|
|
11
11
|
|
12
12
|
def investigate(processed_source)
|
13
13
|
file_path = processed_source.buffer.name
|
14
|
-
|
15
14
|
return if config.file_to_include?(file_path)
|
16
15
|
|
17
16
|
basename = File.basename(file_path).sub(/\.[^\.]+$/, '')
|
17
|
+
return if snake_case?(basename)
|
18
|
+
|
19
|
+
add_offense(nil,
|
20
|
+
source_range(processed_source.buffer,
|
21
|
+
processed_source[0..0],
|
22
|
+
0, 1))
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
18
26
|
|
19
|
-
|
20
|
-
|
21
|
-
source_range(processed_source.buffer,
|
22
|
-
processed_source[0..0],
|
23
|
-
0, 1))
|
24
|
-
end
|
27
|
+
def snake_case?(basename)
|
28
|
+
basename.split('.').all? { |fragment| fragment =~ SNAKE_CASE }
|
25
29
|
end
|
26
30
|
end
|
27
31
|
end
|
@@ -3,16 +3,14 @@
|
|
3
3
|
module Rubocop
|
4
4
|
module Cop
|
5
5
|
module Style
|
6
|
-
#
|
6
|
+
# Use a guard clause instead of wrapping the code inside a conditional
|
7
|
+
# expression
|
7
8
|
#
|
8
9
|
# @example
|
9
|
-
#
|
10
10
|
# # bad
|
11
11
|
# def test
|
12
12
|
# if something
|
13
13
|
# work
|
14
|
-
# work
|
15
|
-
# work
|
16
14
|
# end
|
17
15
|
# end
|
18
16
|
#
|
@@ -20,48 +18,60 @@ module Rubocop
|
|
20
18
|
# def test
|
21
19
|
# return unless something
|
22
20
|
# work
|
23
|
-
# work
|
24
|
-
# work
|
25
21
|
# end
|
26
22
|
#
|
27
|
-
#
|
28
|
-
#
|
23
|
+
# # also good
|
24
|
+
# def test
|
25
|
+
# work if something
|
26
|
+
# end
|
29
27
|
class GuardClause < Cop
|
30
|
-
include
|
28
|
+
include ConfigurableEnforcedStyle
|
31
29
|
include IfNode
|
32
30
|
|
33
|
-
MSG = 'Use a guard clause instead of wrapping ' \
|
34
|
-
'
|
35
|
-
|
36
|
-
private
|
31
|
+
MSG = 'Use a guard clause instead of wrapping the code inside a ' \
|
32
|
+
'conditional expression.'
|
37
33
|
|
38
|
-
def
|
34
|
+
def on_def(node)
|
35
|
+
_, _, body = *node
|
39
36
|
return unless body
|
40
37
|
|
41
|
-
if body
|
38
|
+
if if?(body)
|
42
39
|
check_if_node(body)
|
43
40
|
elsif body.type == :begin
|
44
41
|
expressions = *body
|
45
42
|
last_expr = expressions.last
|
46
43
|
|
47
|
-
check_if_node(last_expr) if last_expr
|
44
|
+
check_if_node(last_expr) if if?(last_expr)
|
48
45
|
end
|
49
46
|
end
|
50
47
|
|
48
|
+
private
|
49
|
+
|
50
|
+
def if?(body)
|
51
|
+
body && body.type == :if
|
52
|
+
end
|
53
|
+
|
51
54
|
def check_if_node(node)
|
52
|
-
_cond,
|
55
|
+
_cond, body, else_body = *node
|
53
56
|
|
54
|
-
return if else_body
|
57
|
+
return if body && else_body
|
55
58
|
# discard modifier ifs and ternary_ops
|
56
59
|
return if modifier_if?(node) || ternary_op?(node)
|
57
60
|
# discard short ifs
|
58
|
-
return unless
|
61
|
+
return unless min_body_length?(node)
|
62
|
+
|
63
|
+
add_offense(node, :keyword, MSG)
|
64
|
+
end
|
59
65
|
|
60
|
-
|
66
|
+
def min_body_length?(node)
|
67
|
+
(node.loc.end.line - node.loc.keyword.line) > min_body_length
|
61
68
|
end
|
62
69
|
|
63
|
-
def
|
64
|
-
|
70
|
+
def min_body_length
|
71
|
+
length = cop_config['MinBodyLength'] || 1
|
72
|
+
return length if length.is_a?(Integer) && length > 0
|
73
|
+
|
74
|
+
fail 'MinBodyLength needs to be a positive integer!'
|
65
75
|
end
|
66
76
|
end
|
67
77
|
end
|
@@ -46,12 +46,12 @@ module Rubocop
|
|
46
46
|
def on_send(node)
|
47
47
|
super
|
48
48
|
receiver, method_name, *args = *node
|
49
|
+
return unless visibility_and_def_on_same_line?(receiver, method_name,
|
50
|
+
args)
|
49
51
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
ignore_node(args.first)
|
54
|
-
end
|
52
|
+
_method_name, _args, body = *args.first
|
53
|
+
check_indentation(node.loc.expression, body)
|
54
|
+
ignore_node(args.first)
|
55
55
|
end
|
56
56
|
|
57
57
|
def check(node, _method_name, _args, body)
|
@@ -65,9 +65,10 @@ module Rubocop
|
|
65
65
|
|
66
66
|
def on_while(node, base = node)
|
67
67
|
_condition, body = *node
|
68
|
-
|
69
|
-
|
70
|
-
|
68
|
+
return unless node.loc.keyword.begin_pos ==
|
69
|
+
node.loc.expression.begin_pos
|
70
|
+
|
71
|
+
check_indentation(base.loc, body)
|
71
72
|
end
|
72
73
|
|
73
74
|
alias_method :on_until, :on_while
|
@@ -115,34 +116,32 @@ module Rubocop
|
|
115
116
|
# assignment, we let rhs be the receiver of those method calls before
|
116
117
|
# we check its indentation.
|
117
118
|
rhs = first_part_of_call_chain(rhs)
|
119
|
+
return unless rhs
|
118
120
|
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
base = style == 'variable' ? node : rhs
|
123
|
-
|
124
|
-
case rhs.type
|
125
|
-
when :if then on_if(rhs, base)
|
126
|
-
when :while, :until then on_while(rhs, base)
|
127
|
-
else return
|
128
|
-
end
|
121
|
+
end_config = config.for_cop('EndAlignment')
|
122
|
+
style = end_config['Enabled'] ? end_config['AlignWith'] : 'keyword'
|
123
|
+
base = style == 'variable' ? node : rhs
|
129
124
|
|
130
|
-
|
125
|
+
case rhs.type
|
126
|
+
when :if then on_if(rhs, base)
|
127
|
+
when :while, :until then on_while(rhs, base)
|
128
|
+
else return
|
131
129
|
end
|
130
|
+
|
131
|
+
ignore_node(rhs)
|
132
132
|
end
|
133
133
|
|
134
134
|
def check_if(node, body, else_clause, base_loc)
|
135
135
|
return if ternary_op?(node)
|
136
136
|
|
137
137
|
check_indentation(base_loc, body)
|
138
|
+
return unless else_clause
|
138
139
|
|
139
|
-
if else_clause
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
else
|
144
|
-
check_indentation(node.loc.else, else_clause)
|
145
|
-
end
|
140
|
+
if elsif?(else_clause)
|
141
|
+
_condition, inner_body, inner_else_clause = *else_clause
|
142
|
+
check_if(else_clause, inner_body, inner_else_clause, base_loc)
|
143
|
+
else
|
144
|
+
check_indentation(node.loc.else, else_clause)
|
146
145
|
end
|
147
146
|
end
|
148
147
|
|