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.

Files changed (159) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +1 -1
  3. data/{rubocop-todo.yml → .rubocop_todo.yml} +5 -5
  4. data/CHANGELOG.md +41 -0
  5. data/README.md +21 -11
  6. data/config/default.yml +33 -10
  7. data/config/disabled.yml +0 -4
  8. data/config/enabled.yml +27 -1
  9. data/lib/rubocop.rb +17 -1
  10. data/lib/rubocop/config.rb +32 -27
  11. data/lib/rubocop/config_loader.rb +21 -8
  12. data/lib/rubocop/cop/cop.rb +8 -8
  13. data/lib/rubocop/cop/lint/block_alignment.rb +22 -22
  14. data/lib/rubocop/cop/lint/condition_position.rb +3 -5
  15. data/lib/rubocop/cop/lint/debugger.rb +4 -5
  16. data/lib/rubocop/cop/lint/end_alignment.rb +11 -10
  17. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +10 -11
  18. data/lib/rubocop/cop/lint/require_parentheses.rb +7 -7
  19. data/lib/rubocop/cop/lint/rescue_exception.rb +3 -3
  20. data/lib/rubocop/cop/lint/string_conversion_in_interpolation.rb +6 -7
  21. data/lib/rubocop/cop/lint/unreachable_code.rb +2 -3
  22. data/lib/rubocop/cop/lint/unused_block_argument.rb +2 -15
  23. data/lib/rubocop/cop/lint/unused_method_argument.rb +2 -14
  24. data/lib/rubocop/cop/lint/useless_comparison.rb +4 -5
  25. data/lib/rubocop/cop/lint/void.rb +6 -8
  26. data/lib/rubocop/cop/mixin/autocorrect_alignment.rb +4 -2
  27. data/lib/rubocop/cop/mixin/autocorrect_unless_changing_ast.rb +1 -3
  28. data/lib/rubocop/cop/mixin/code_length.rb +5 -5
  29. data/lib/rubocop/cop/mixin/negative_conditional.rb +6 -6
  30. data/lib/rubocop/cop/mixin/percent_literal.rb +2 -3
  31. data/lib/rubocop/cop/mixin/space_after_punctuation.rb +5 -5
  32. data/lib/rubocop/cop/mixin/space_inside.rb +10 -11
  33. data/lib/rubocop/cop/mixin/unused_argument.rb +35 -0
  34. data/lib/rubocop/cop/offense.rb +1 -1
  35. data/lib/rubocop/cop/rails/action_filter.rb +6 -8
  36. data/lib/rubocop/cop/rails/default_scope.rb +2 -4
  37. data/lib/rubocop/cop/rails/delegate.rb +2 -0
  38. data/lib/rubocop/cop/rails/has_and_belongs_to_many.rb +2 -3
  39. data/lib/rubocop/cop/rails/output.rb +2 -3
  40. data/lib/rubocop/cop/rails/read_write_attribute.rb +3 -4
  41. data/lib/rubocop/cop/rails/validation.rb +2 -3
  42. data/lib/rubocop/cop/style/alias.rb +3 -3
  43. data/lib/rubocop/cop/style/align_hash.rb +4 -4
  44. data/lib/rubocop/cop/style/align_parameters.rb +13 -1
  45. data/lib/rubocop/cop/style/and_or.rb +2 -5
  46. data/lib/rubocop/cop/style/array_join.rb +3 -4
  47. data/lib/rubocop/cop/style/ascii_identifiers.rb +2 -3
  48. data/lib/rubocop/cop/style/block_comments.rb +2 -3
  49. data/lib/rubocop/cop/style/block_nesting.rb +2 -3
  50. data/lib/rubocop/cop/style/blocks.rb +9 -9
  51. data/lib/rubocop/cop/style/braces_around_hash_parameters.rb +5 -5
  52. data/lib/rubocop/cop/style/class_and_module_children.rb +1 -1
  53. data/lib/rubocop/cop/style/class_methods.rb +3 -5
  54. data/lib/rubocop/cop/style/collection_methods.rb +8 -11
  55. data/lib/rubocop/cop/style/comment_annotation.rb +9 -9
  56. data/lib/rubocop/cop/style/comment_indentation.rb +66 -0
  57. data/lib/rubocop/cop/style/constant_name.rb +3 -3
  58. data/lib/rubocop/cop/style/cyclomatic_complexity.rb +5 -5
  59. data/lib/rubocop/cop/style/deprecated_hash_methods.rb +6 -6
  60. data/lib/rubocop/cop/style/each_with_object.rb +38 -0
  61. data/lib/rubocop/cop/style/empty_lines.rb +8 -8
  62. data/lib/rubocop/cop/style/empty_lines_around_body.rb +7 -7
  63. data/lib/rubocop/cop/style/encoding.rb +6 -7
  64. data/lib/rubocop/cop/style/end_of_line.rb +10 -10
  65. data/lib/rubocop/cop/style/file_name.rb +11 -7
  66. data/lib/rubocop/cop/style/guard_clause.rb +32 -22
  67. data/lib/rubocop/cop/style/indentation_width.rb +25 -26
  68. data/lib/rubocop/cop/style/lambda.rb +8 -9
  69. data/lib/rubocop/cop/style/leading_comment_space.rb +4 -5
  70. data/lib/rubocop/cop/style/line_end_concatenation.rb +29 -6
  71. data/lib/rubocop/cop/style/line_length.rb +9 -9
  72. data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +7 -6
  73. data/lib/rubocop/cop/style/module_function.rb +3 -4
  74. data/lib/rubocop/cop/style/multiline_if_then.rb +3 -3
  75. data/lib/rubocop/cop/style/negated_if.rb +2 -0
  76. data/lib/rubocop/cop/style/next.rb +80 -0
  77. data/lib/rubocop/cop/style/nil_comparison.rb +2 -3
  78. data/lib/rubocop/cop/style/non_nil_check.rb +15 -3
  79. data/lib/rubocop/cop/style/not.rb +4 -4
  80. data/lib/rubocop/cop/style/numeric_literals.rb +7 -8
  81. data/lib/rubocop/cop/style/op_method.rb +3 -5
  82. data/lib/rubocop/cop/style/parameter_lists.rb +4 -4
  83. data/lib/rubocop/cop/style/parentheses_around_condition.rb +5 -6
  84. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +5 -5
  85. data/lib/rubocop/cop/style/predicate_name.rb +2 -4
  86. data/lib/rubocop/cop/style/redundant_self.rb +11 -12
  87. data/lib/rubocop/cop/style/self_assignment.rb +8 -13
  88. data/lib/rubocop/cop/style/semicolon.rb +16 -19
  89. data/lib/rubocop/cop/style/signal_exception.rb +10 -11
  90. data/lib/rubocop/cop/style/single_line_block_params.rb +2 -3
  91. data/lib/rubocop/cop/style/single_line_methods.rb +3 -4
  92. data/lib/rubocop/cop/style/space_after_colon.rb +9 -9
  93. data/lib/rubocop/cop/style/space_after_control_keyword.rb +3 -3
  94. data/lib/rubocop/cop/style/space_after_method_name.rb +3 -3
  95. data/lib/rubocop/cop/style/space_after_not.rb +3 -4
  96. data/lib/rubocop/cop/style/space_around_operators.rb +5 -4
  97. data/lib/rubocop/cop/style/space_before_comment.rb +29 -0
  98. data/lib/rubocop/cop/style/space_before_modifier_keyword.rb +6 -7
  99. data/lib/rubocop/cop/style/symbol_array.rb +2 -3
  100. data/lib/rubocop/cop/style/tab.rb +8 -8
  101. data/lib/rubocop/cop/style/trailing_blank_lines.rb +10 -10
  102. data/lib/rubocop/cop/style/trailing_whitespace.rb +6 -7
  103. data/lib/rubocop/cop/style/trivial_accessors.rb +3 -4
  104. data/lib/rubocop/cop/style/unless_else.rb +2 -3
  105. data/lib/rubocop/cop/style/unneeded_capital_w.rb +3 -3
  106. data/lib/rubocop/cop/style/unneeded_percent_x.rb +26 -0
  107. data/lib/rubocop/cop/style/when_then.rb +3 -3
  108. data/lib/rubocop/cop/style/while_until_do.rb +3 -6
  109. data/lib/rubocop/cop/style/word_array.rb +8 -7
  110. data/lib/rubocop/cop/team.rb +9 -11
  111. data/lib/rubocop/cop/util.rb +2 -3
  112. data/lib/rubocop/cop/variable_force.rb +2 -3
  113. data/lib/rubocop/cop/variable_force/variable_table.rb +1 -2
  114. data/lib/rubocop/file_inspector.rb +5 -0
  115. data/lib/rubocop/formatter/clang_style_formatter.rb +3 -4
  116. data/lib/rubocop/formatter/disabled_config_formatter.rb +6 -6
  117. data/lib/rubocop/options.rb +14 -11
  118. data/lib/rubocop/target_finder.rb +12 -1
  119. data/lib/rubocop/version.rb +1 -1
  120. data/relnotes/v0.21.0.md +11 -0
  121. data/relnotes/v0.22.0.md +77 -0
  122. data/spec/rubocop/cli_spec.rb +86 -40
  123. data/spec/rubocop/comment_config_spec.rb +1 -1
  124. data/spec/rubocop/config_loader_spec.rb +3 -3
  125. data/spec/rubocop/config_spec.rb +14 -3
  126. data/spec/rubocop/cop/force_spec.rb +1 -1
  127. data/spec/rubocop/cop/lint/unused_block_argument_spec.rb +164 -99
  128. data/spec/rubocop/cop/lint/unused_method_argument_spec.rb +195 -85
  129. data/spec/rubocop/cop/lint/void_spec.rb +8 -0
  130. data/spec/rubocop/cop/rails/delegate_spec.rb +17 -0
  131. data/spec/rubocop/cop/rails/output_spec.rb +3 -3
  132. data/spec/rubocop/cop/severity_spec.rb +5 -5
  133. data/spec/rubocop/cop/style/align_parameters_spec.rb +108 -0
  134. data/spec/rubocop/cop/style/block_nesting_spec.rb +3 -3
  135. data/spec/rubocop/cop/style/class_and_module_children_spec.rb +12 -10
  136. data/spec/rubocop/cop/style/comment_indentation_spec.rb +174 -0
  137. data/spec/rubocop/cop/style/each_with_object_spec.rb +44 -0
  138. data/spec/rubocop/cop/style/end_of_line_spec.rb +3 -5
  139. data/spec/rubocop/cop/style/guard_clause_spec.rb +135 -57
  140. data/spec/rubocop/cop/style/if_unless_modifier_spec.rb +7 -7
  141. data/spec/rubocop/cop/style/line_end_concatenation_spec.rb +75 -1
  142. data/spec/rubocop/cop/style/line_length_spec.rb +7 -7
  143. data/spec/rubocop/cop/style/negated_if_spec.rb +5 -1
  144. data/spec/rubocop/cop/style/next_spec.rb +210 -0
  145. data/spec/rubocop/cop/style/non_nil_check_spec.rb +44 -13
  146. data/spec/rubocop/cop/style/self_assignment_spec.rb +1 -1
  147. data/spec/rubocop/cop/style/space_around_operators_spec.rb +1 -0
  148. data/spec/rubocop/cop/style/space_before_comment_spec.rb +34 -0
  149. data/spec/rubocop/cop/style/unneeded_percent_x_spec.rb +34 -0
  150. data/spec/rubocop/cop/style/while_until_modifier_spec.rb +2 -2
  151. data/spec/rubocop/cop/util_spec.rb +2 -2
  152. data/spec/rubocop/cop/variable_force_spec.rb +1 -1
  153. data/spec/rubocop/formatter/disabled_config_formatter_spec.rb +4 -4
  154. data/spec/rubocop/formatter/disabled_lines_formatter_spec.rb +2 -2
  155. data/spec/rubocop/formatter/offense_count_formatter_spec.rb +2 -2
  156. data/spec/rubocop/options_spec.rb +3 -0
  157. data/spec/support/shared_context.rb +1 -3
  158. data/spec/support/statement_modifier_helper.rb +2 -2
  159. 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
- if args.size == 1 && args.first.type == :block_pass
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
- if preferred_methods[method_name]
42
- add_offense(
43
- node, :selector,
44
- format(MSG,
45
- preferred_method(method_name),
46
- method_name)
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
- if annotation?(comment) && !correct_annotation?(first_word, colon,
18
- space, note)
19
- start = comment.loc.expression.begin_pos + margin.length
20
- length = first_word.length + (colon || '').length
21
- range = Parser::Source::Range.new(processed_source.buffer,
22
- start,
23
- start + length)
24
- add_offense(nil, range)
25
- end
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
- unless value && [:send, :block, :const].include?(value.type)
23
- add_offense(node, :name) if const_name !~ SNAKE_CASE
24
- end
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
- if complexity > max
32
- add_offense(node, :keyword,
33
- format(MSG, method_name, complexity, max)) do
34
- self.max = complexity
35
- end
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
- if args.size == 1 && DEPRECATED_METHODS.include?(method_name)
17
- add_offense(node, :selector,
18
- format(MSG,
19
- method_name,
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
- if processed_source[line - 2].empty? &&
27
- processed_source[line - 1].empty?
28
- range = source_range(processed_source.buffer,
29
- processed_source[0...(line - 1)],
30
- 0,
31
- 1)
32
- add_offense(range, range)
33
- end
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
- if processed_source.lines[line].empty?
64
- range = source_range(processed_source.buffer,
65
- processed_source[0...line],
66
- 0,
67
- 1)
68
- add_offense(range, range, msg)
69
- end
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
- if message
27
- add_offense(nil,
28
- source_range(processed_source.buffer,
29
- processed_source[0...line_number],
30
- 0, 1),
31
- message)
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
- if line =~ /\r$/
16
- add_offense(nil,
17
- source_range(buffer,
18
- processed_source[0...index],
19
- 0, line.length),
20
- MSG)
21
- # Usually there will be carriage return characters on all or none
22
- # of the lines in a file, so we report only one offense.
23
- break
24
- end
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
- unless basename.split('.').all? { |fragment| fragment =~ SNAKE_CASE }
20
- add_offense(nil,
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
- # This cop if/unless expression that can be replace with a guard clause.
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
- # It should be extended to handle methods whose body is if/else
28
- # or a case expression with a default branch.
23
+ # # also good
24
+ # def test
25
+ # work if something
26
+ # end
29
27
  class GuardClause < Cop
30
- include CheckMethods
28
+ include ConfigurableEnforcedStyle
31
29
  include IfNode
32
30
 
33
- MSG = 'Use a guard clause instead of wrapping ' \
34
- 'the code inside a conditional expression.'
35
-
36
- private
31
+ MSG = 'Use a guard clause instead of wrapping the code inside a ' \
32
+ 'conditional expression.'
37
33
 
38
- def check(_node, _method_name, _args, body)
34
+ def on_def(node)
35
+ _, _, body = *node
39
36
  return unless body
40
37
 
41
- if body.type == :if
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 && last_expr.type == :if
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, _body, else_body = *node
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 if_length(node) > 3
61
+ return unless min_body_length?(node)
62
+
63
+ add_offense(node, :keyword, MSG)
64
+ end
59
65
 
60
- add_offense(node, :keyword)
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 if_length(node)
64
- node.loc.end.line - node.loc.keyword.line + 1
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
- if visibility_and_def_on_same_line?(receiver, method_name, args)
51
- _method_name, _args, body = *args.first
52
- check_indentation(node.loc.expression, body)
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
- if node.loc.keyword.begin_pos == node.loc.expression.begin_pos
69
- check_indentation(base.loc, body)
70
- end
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
- if rhs
120
- end_config = config.for_cop('EndAlignment')
121
- style = end_config['Enabled'] ? end_config['AlignWith'] : 'keyword'
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
- ignore_node(rhs)
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
- 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)
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