rubocop 0.46.0 → 0.47.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 (214) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +77 -2
  4. data/config/default.yml +151 -74
  5. data/config/disabled.yml +9 -0
  6. data/config/enabled.yml +49 -9
  7. data/lib/rubocop.rb +36 -8
  8. data/lib/rubocop/ast/builder.rb +59 -0
  9. data/lib/rubocop/ast/node.rb +607 -0
  10. data/lib/rubocop/ast/node/array_node.rb +45 -0
  11. data/lib/rubocop/ast/node/case_node.rb +63 -0
  12. data/lib/rubocop/ast/node/for_node.rb +53 -0
  13. data/lib/rubocop/ast/node/hash_node.rb +102 -0
  14. data/lib/rubocop/ast/node/if_node.rb +136 -0
  15. data/lib/rubocop/ast/node/keyword_splat_node.rb +45 -0
  16. data/lib/rubocop/ast/node/mixin/conditional_node.rb +45 -0
  17. data/lib/rubocop/ast/node/mixin/hash_element_node.rb +125 -0
  18. data/lib/rubocop/ast/node/mixin/modifier_node.rb +17 -0
  19. data/lib/rubocop/ast/node/pair_node.rb +64 -0
  20. data/lib/rubocop/ast/node/until_node.rb +43 -0
  21. data/lib/rubocop/ast/node/when_node.rb +61 -0
  22. data/lib/rubocop/ast/node/while_node.rb +43 -0
  23. data/lib/rubocop/ast/sexp.rb +16 -0
  24. data/lib/rubocop/{ast_node → ast}/traversal.rb +1 -1
  25. data/lib/rubocop/cli.rb +18 -14
  26. data/lib/rubocop/comment_config.rb +1 -3
  27. data/lib/rubocop/config.rb +93 -35
  28. data/lib/rubocop/config_loader.rb +1 -1
  29. data/lib/rubocop/cop/badge.rb +73 -0
  30. data/lib/rubocop/cop/bundler/duplicated_gem.rb +2 -2
  31. data/lib/rubocop/cop/bundler/ordered_gems.rb +43 -3
  32. data/lib/rubocop/cop/commissioner.rb +17 -6
  33. data/lib/rubocop/cop/cop.rb +25 -112
  34. data/lib/rubocop/cop/lint/ambiguous_operator.rb +9 -4
  35. data/lib/rubocop/cop/lint/ambiguous_regexp_literal.rb +7 -0
  36. data/lib/rubocop/cop/lint/assignment_in_condition.rb +18 -4
  37. data/lib/rubocop/cop/lint/block_alignment.rb +40 -9
  38. data/lib/rubocop/cop/lint/circular_argument_reference.rb +14 -0
  39. data/lib/rubocop/cop/lint/condition_position.rb +14 -16
  40. data/lib/rubocop/cop/lint/debugger.rb +28 -0
  41. data/lib/rubocop/cop/lint/def_end_alignment.rb +21 -1
  42. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +13 -1
  43. data/lib/rubocop/cop/lint/duplicate_case_condition.rb +26 -22
  44. data/lib/rubocop/cop/lint/duplicate_methods.rb +15 -1
  45. data/lib/rubocop/cop/lint/duplicated_key.rb +16 -8
  46. data/lib/rubocop/cop/lint/each_with_object_argument.rb +9 -0
  47. data/lib/rubocop/cop/lint/else_layout.rb +26 -29
  48. data/lib/rubocop/cop/lint/empty_ensure.rb +38 -0
  49. data/lib/rubocop/cop/lint/empty_expression.rb +11 -1
  50. data/lib/rubocop/cop/lint/empty_interpolation.rb +8 -0
  51. data/lib/rubocop/cop/lint/empty_when.rb +14 -16
  52. data/lib/rubocop/cop/lint/end_alignment.rb +48 -28
  53. data/lib/rubocop/cop/lint/end_in_method.rb +23 -0
  54. data/lib/rubocop/cop/lint/ensure_return.rb +21 -0
  55. data/lib/rubocop/cop/lint/float_out_of_range.rb +5 -0
  56. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +29 -4
  57. data/lib/rubocop/cop/lint/handle_exceptions.rb +40 -0
  58. data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +7 -2
  59. data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +11 -2
  60. data/lib/rubocop/cop/lint/invalid_character_literal.rb +3 -0
  61. data/lib/rubocop/cop/lint/literal_in_condition.rb +34 -36
  62. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +8 -0
  63. data/lib/rubocop/cop/lint/loop.rb +36 -0
  64. data/lib/rubocop/cop/lint/multiple_compare.rb +46 -0
  65. data/lib/rubocop/cop/lint/nested_method_definition.rb +22 -0
  66. data/lib/rubocop/cop/lint/next_without_accumulator.rb +5 -0
  67. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +8 -0
  68. data/lib/rubocop/cop/lint/percent_string_array.rb +27 -13
  69. data/lib/rubocop/cop/lint/percent_symbol_array.rb +14 -4
  70. data/lib/rubocop/cop/lint/rand_one.rb +7 -3
  71. data/lib/rubocop/cop/lint/require_parentheses.rb +20 -19
  72. data/lib/rubocop/cop/lint/rescue_exception.rb +20 -0
  73. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +66 -0
  74. data/lib/rubocop/cop/lint/shadowed_exception.rb +6 -1
  75. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +24 -0
  76. data/lib/rubocop/cop/lint/string_conversion_in_interpolation.rb +8 -0
  77. data/lib/rubocop/cop/lint/underscore_prefixed_variable_name.rb +24 -0
  78. data/lib/rubocop/cop/lint/unified_integer.rb +5 -0
  79. data/lib/rubocop/cop/lint/unneeded_disable.rb +2 -2
  80. data/lib/rubocop/cop/lint/unneeded_splat_expansion.rb +5 -0
  81. data/lib/rubocop/cop/lint/unreachable_code.rb +17 -0
  82. data/lib/rubocop/cop/lint/unused_block_argument.rb +2 -0
  83. data/lib/rubocop/cop/lint/unused_method_argument.rb +10 -0
  84. data/lib/rubocop/cop/lint/useless_access_modifier.rb +28 -1
  85. data/lib/rubocop/cop/lint/useless_assignment.rb +18 -0
  86. data/lib/rubocop/cop/lint/useless_comparison.rb +3 -1
  87. data/lib/rubocop/cop/lint/useless_else_without_rescue.rb +16 -1
  88. data/lib/rubocop/cop/lint/useless_setter_call.rb +16 -4
  89. data/lib/rubocop/cop/lint/void.rb +52 -0
  90. data/lib/rubocop/cop/message_annotator.rb +102 -0
  91. data/lib/rubocop/cop/metrics/block_length.rb +6 -0
  92. data/lib/rubocop/cop/metrics/block_nesting.rb +17 -5
  93. data/lib/rubocop/cop/metrics/line_length.rb +11 -4
  94. data/lib/rubocop/cop/metrics/perceived_complexity.rb +1 -2
  95. data/lib/rubocop/cop/mixin/array_syntax.rb +2 -11
  96. data/lib/rubocop/cop/mixin/configurable_enforced_style.rb +12 -5
  97. data/lib/rubocop/cop/mixin/configurable_formatting.rb +48 -0
  98. data/lib/rubocop/cop/mixin/configurable_max.rb +3 -3
  99. data/lib/rubocop/cop/mixin/configurable_naming.rb +5 -33
  100. data/lib/rubocop/cop/mixin/configurable_numbering.rb +6 -47
  101. data/lib/rubocop/cop/mixin/documentation_comment.rb +7 -1
  102. data/lib/rubocop/cop/mixin/duplication.rb +46 -0
  103. data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +2 -2
  104. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +14 -11
  105. data/lib/rubocop/cop/mixin/hash_alignment.rb +114 -0
  106. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +3 -3
  107. data/lib/rubocop/cop/mixin/negative_conditional.rb +21 -7
  108. data/lib/rubocop/cop/mixin/on_method_def.rb +14 -0
  109. data/lib/rubocop/cop/mixin/on_normal_if_unless.rb +1 -24
  110. data/lib/rubocop/cop/mixin/statement_modifier.rb +8 -13
  111. data/lib/rubocop/cop/mixin/target_ruby_version.rb +16 -0
  112. data/lib/rubocop/cop/mixin/trailing_comma.rb +2 -3
  113. data/lib/rubocop/cop/offense.rb +1 -1
  114. data/lib/rubocop/cop/performance/case_when_splat.rb +56 -59
  115. data/lib/rubocop/cop/performance/detect.rb +2 -2
  116. data/lib/rubocop/cop/performance/flat_map.rb +3 -3
  117. data/lib/rubocop/cop/performance/redundant_merge.rb +3 -6
  118. data/lib/rubocop/cop/performance/regexp_match.rb +201 -0
  119. data/lib/rubocop/cop/rails/delegate.rb +2 -2
  120. data/lib/rubocop/cop/rails/delegate_allow_blank.rb +10 -19
  121. data/lib/rubocop/cop/rails/enum_uniqueness.rb +12 -40
  122. data/lib/rubocop/cop/rails/file_path.rb +80 -0
  123. data/lib/rubocop/cop/rails/find_each.rb +5 -14
  124. data/lib/rubocop/cop/rails/http_positional_arguments.rb +30 -24
  125. data/lib/rubocop/cop/rails/not_null_column.rb +23 -0
  126. data/lib/rubocop/cop/rails/reversible_migration.rb +217 -0
  127. data/lib/rubocop/cop/rails/safe_navigation.rb +4 -2
  128. data/lib/rubocop/cop/rails/skips_model_validations.rb +46 -0
  129. data/lib/rubocop/cop/rails/time_zone.rb +1 -1
  130. data/lib/rubocop/cop/rails/uniq_before_pluck.rb +7 -5
  131. data/lib/rubocop/cop/registry.rb +170 -0
  132. data/lib/rubocop/cop/{lint → security}/eval.rb +7 -1
  133. data/lib/rubocop/cop/security/marshal_load.rb +33 -0
  134. data/lib/rubocop/cop/security/yaml_load.rb +37 -0
  135. data/lib/rubocop/cop/style/align_hash.rb +138 -169
  136. data/lib/rubocop/cop/style/and_or.rb +1 -1
  137. data/lib/rubocop/cop/style/braces_around_hash_parameters.rb +10 -15
  138. data/lib/rubocop/cop/style/case_indentation.rb +36 -27
  139. data/lib/rubocop/cop/style/conditional_assignment.rb +64 -47
  140. data/lib/rubocop/cop/style/each_with_object.rb +4 -1
  141. data/lib/rubocop/cop/style/else_alignment.rb +14 -20
  142. data/lib/rubocop/cop/style/empty_case_condition.rb +16 -25
  143. data/lib/rubocop/cop/style/empty_else.rb +20 -22
  144. data/lib/rubocop/cop/style/empty_literal.rb +4 -4
  145. data/lib/rubocop/cop/style/empty_method.rb +12 -6
  146. data/lib/rubocop/cop/style/encoding.rb +1 -1
  147. data/lib/rubocop/cop/style/file_name.rb +24 -4
  148. data/lib/rubocop/cop/style/first_method_argument_line_break.rb +1 -1
  149. data/lib/rubocop/cop/style/format_string.rb +17 -48
  150. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +40 -11
  151. data/lib/rubocop/cop/style/guard_clause.rb +11 -17
  152. data/lib/rubocop/cop/style/hash_syntax.rb +24 -42
  153. data/lib/rubocop/cop/style/identical_conditional_branches.rb +40 -28
  154. data/lib/rubocop/cop/style/if_inside_else.rb +6 -9
  155. data/lib/rubocop/cop/style/if_unless_modifier.rb +16 -25
  156. data/lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb +3 -9
  157. data/lib/rubocop/cop/style/indent_array.rb +1 -1
  158. data/lib/rubocop/cop/style/indentation_width.rb +29 -60
  159. data/lib/rubocop/cop/style/infinite_loop.rb +21 -22
  160. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +86 -0
  161. data/lib/rubocop/cop/style/{method_call_parentheses.rb → method_call_without_args_parentheses.rb} +8 -1
  162. data/lib/rubocop/cop/style/missing_else.rb +40 -14
  163. data/lib/rubocop/cop/style/multiline_if_modifier.rb +5 -15
  164. data/lib/rubocop/cop/style/multiline_if_then.rb +14 -8
  165. data/lib/rubocop/cop/style/multiline_method_call_indentation.rb +3 -3
  166. data/lib/rubocop/cop/style/multiline_ternary_operator.rb +1 -5
  167. data/lib/rubocop/cop/style/mutable_constant.rb +3 -2
  168. data/lib/rubocop/cop/style/negated_if.rb +3 -19
  169. data/lib/rubocop/cop/style/negated_while.rb +2 -17
  170. data/lib/rubocop/cop/style/nested_modifier.rb +16 -43
  171. data/lib/rubocop/cop/style/nested_ternary_operator.rb +3 -5
  172. data/lib/rubocop/cop/style/next.rb +23 -21
  173. data/lib/rubocop/cop/style/non_nil_check.rb +2 -3
  174. data/lib/rubocop/cop/style/not.rb +1 -3
  175. data/lib/rubocop/cop/style/numeric_literals.rb +2 -2
  176. data/lib/rubocop/cop/style/one_line_conditional.rb +12 -22
  177. data/lib/rubocop/cop/style/option_hash.rb +4 -15
  178. data/lib/rubocop/cop/style/parallel_assignment.rb +1 -3
  179. data/lib/rubocop/cop/style/parentheses_around_condition.rb +8 -12
  180. data/lib/rubocop/cop/style/percent_q_literals.rb +15 -12
  181. data/lib/rubocop/cop/style/redundant_freeze.rb +3 -2
  182. data/lib/rubocop/cop/style/redundant_parentheses.rb +27 -4
  183. data/lib/rubocop/cop/style/redundant_return.rb +4 -8
  184. data/lib/rubocop/cop/style/safe_navigation.rb +13 -6
  185. data/lib/rubocop/cop/style/space_after_colon.rb +2 -4
  186. data/lib/rubocop/cop/style/space_around_block_parameters.rb +1 -1
  187. data/lib/rubocop/cop/style/space_around_operators.rb +15 -13
  188. data/lib/rubocop/cop/style/string_methods.rb +1 -3
  189. data/lib/rubocop/cop/style/symbol_array.rb +1 -5
  190. data/lib/rubocop/cop/style/ternary_parentheses.rb +5 -6
  191. data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +2 -5
  192. data/lib/rubocop/cop/style/trailing_comma_in_literal.rb +1 -1
  193. data/lib/rubocop/cop/style/unless_else.rb +1 -5
  194. data/lib/rubocop/cop/style/when_then.rb +4 -2
  195. data/lib/rubocop/cop/style/while_until_do.rb +9 -13
  196. data/lib/rubocop/cop/style/while_until_modifier.rb +12 -11
  197. data/lib/rubocop/cop/style/word_array.rb +5 -9
  198. data/lib/rubocop/cop/team.rb +16 -15
  199. data/lib/rubocop/cop/util.rb +13 -3
  200. data/lib/rubocop/formatter/clang_style_formatter.rb +2 -2
  201. data/lib/rubocop/formatter/disabled_config_formatter.rb +2 -1
  202. data/lib/rubocop/magic_comment.rb +196 -0
  203. data/lib/rubocop/options.rb +5 -4
  204. data/lib/rubocop/processed_source.rb +1 -1
  205. data/lib/rubocop/rspec/cop_helper.rb +9 -0
  206. data/lib/rubocop/rspec/shared_examples.rb +1 -1
  207. data/lib/rubocop/runner.rb +7 -2
  208. data/lib/rubocop/version.rb +1 -1
  209. metadata +41 -14
  210. data/lib/rubocop/ast_node.rb +0 -624
  211. data/lib/rubocop/ast_node/builder.rb +0 -30
  212. data/lib/rubocop/ast_node/sexp.rb +0 -13
  213. data/lib/rubocop/cop/mixin/hash_node.rb +0 -14
  214. data/lib/rubocop/cop/mixin/if_node.rb +0 -42
@@ -8,20 +8,28 @@ module RuboCop
8
8
  # This cop mirrors a warning in Ruby 2.2.
9
9
  #
10
10
  # @example
11
+ #
12
+ # # bad
13
+ #
11
14
  # hash = { food: 'apple', food: 'orange' }
15
+ #
16
+ # @example
17
+ #
18
+ # # good
19
+ #
20
+ # hash = { food: 'apple', other_food: 'orange' }
12
21
  class DuplicatedKey < Cop
22
+ include Duplication
23
+
13
24
  MSG = 'Duplicated key in hash literal.'.freeze
14
25
 
15
26
  def on_hash(node)
16
- keys = []
27
+ keys = node.keys.select(&:recursive_basic_literal?)
28
+
29
+ return unless duplicates?(keys)
17
30
 
18
- hash_pairs = *node
19
- hash_pairs.each do |pair|
20
- key, _value = *pair
21
- if keys.include?(key) && key.recursive_basic_literal?
22
- add_offense(key, :expression)
23
- end
24
- keys << key
31
+ consecutive_duplicates(keys).each do |key|
32
+ add_offense(key, :expression)
25
33
  end
26
34
  end
27
35
  end
@@ -11,7 +11,16 @@ module RuboCop
11
11
  #
12
12
  # @example
13
13
  #
14
+ # # bad
15
+ #
14
16
  # sum = numbers.each_with_object(0) { |e, a| a += e }
17
+ #
18
+ # @example
19
+ #
20
+ # # good
21
+ #
22
+ # num = 0
23
+ # sum = numbers.each_with_object(num) { |e, a| a += e }
15
24
  class EachWithObjectArgument < Cop
16
25
  MSG = 'The argument to each_with_object can not be immutable.'.freeze
17
26
 
@@ -9,18 +9,29 @@ module RuboCop
9
9
  #
10
10
  # @example
11
11
  #
12
+ # # bad
13
+ #
12
14
  # if something
13
15
  # ...
14
16
  # else do_this
15
17
  # do_that
16
18
  # end
19
+ #
20
+ # @example
21
+ #
22
+ # # good
23
+ #
24
+ # if something
25
+ # ...
26
+ # else
27
+ # do_this
28
+ # do_that
29
+ # end
17
30
  class ElseLayout < Cop
18
- include IfNode
31
+ MSG = 'Odd `else` layout detected. Did you mean to use `elsif`?'.freeze
19
32
 
20
33
  def on_if(node)
21
- return if ternary?(node)
22
- # ignore modifier ops & elsif nodes
23
- return unless node.loc.end
34
+ return if node.ternary? || node.elsif?
24
35
 
25
36
  check(node)
26
37
  end
@@ -28,39 +39,25 @@ module RuboCop
28
39
  private
29
40
 
30
41
  def check(node)
31
- return unless node
32
- return check_else(node) if else?(node)
42
+ return unless node.else_branch
33
43
 
34
- check_if(node) if if?(node)
44
+ if node.else? && node.loc.else.is?('else')
45
+ check_else(node)
46
+ elsif node.if?
47
+ check(node.else_branch)
48
+ end
35
49
  end
36
50
 
37
51
  def check_else(node)
38
- _cond, _if_branch, else_branch = *node
39
- return unless else_branch && else_branch.begin_type?
40
-
41
- first_else_expr = else_branch.children.first
42
- return unless first_else_expr.source_range.line == node.loc.else.line
52
+ else_branch = node.else_branch
43
53
 
44
- add_offense(first_else_expr, :expression, message)
45
- end
54
+ return unless else_branch.begin_type?
46
55
 
47
- def check_if(node)
48
- _cond, _if_branch, else_branch = *node
49
- check(else_branch)
50
- end
56
+ first_else = else_branch.children.first
51
57
 
52
- def if?(node)
53
- node.loc.respond_to?(:keyword) &&
54
- %w(if elsif).include?(node.loc.keyword.source)
55
- end
56
-
57
- def else?(node)
58
- node.loc.respond_to?(:else) && node.loc.else &&
59
- node.loc.else.is?('else')
60
- end
58
+ return unless first_else.source_range.line == node.loc.else.line
61
59
 
62
- def message
63
- 'Odd `else` layout detected. Did you mean to use `elsif`?'
60
+ add_offense(first_else, :expression)
64
61
  end
65
62
  end
66
63
  end
@@ -4,6 +4,44 @@ module RuboCop
4
4
  module Cop
5
5
  module Lint
6
6
  # This cop checks for empty `ensure` blocks
7
+ #
8
+ # @example
9
+ #
10
+ # # bad
11
+ #
12
+ # def some_method
13
+ # do_something
14
+ # ensure
15
+ # end
16
+ #
17
+ # @example
18
+ #
19
+ # # bad
20
+ #
21
+ # begin
22
+ # do_something
23
+ # ensure
24
+ # end
25
+ #
26
+ # @example
27
+ #
28
+ # # good
29
+ #
30
+ # def some_method
31
+ # do_something
32
+ # ensure
33
+ # do_something_else
34
+ # end
35
+ #
36
+ # @example
37
+ #
38
+ # # good
39
+ #
40
+ # begin
41
+ # do_something
42
+ # ensure
43
+ # do_something_else
44
+ # end
7
45
  class EmptyEnsure < Cop
8
46
  MSG = 'Empty `ensure` block detected.'.freeze
9
47
 
@@ -7,11 +7,21 @@ module RuboCop
7
7
  #
8
8
  # @example
9
9
  #
10
- # @bad
10
+ # # bad
11
+ #
11
12
  # foo = ()
12
13
  # if ()
13
14
  # bar
14
15
  # end
16
+ #
17
+ # @example
18
+ #
19
+ # # good
20
+ #
21
+ # foo = (some_expression)
22
+ # if (some_expression)
23
+ # bar
24
+ # end
15
25
  class EmptyExpression < Cop
16
26
  MSG = 'Avoid empty expressions.'.freeze
17
27
 
@@ -7,7 +7,15 @@ module RuboCop
7
7
  #
8
8
  # @example
9
9
  #
10
+ # # bad
11
+ #
10
12
  # "result is #{}"
13
+ #
14
+ # @example
15
+ #
16
+ # # good
17
+ #
18
+ # "result is #{some_result}"
11
19
  class EmptyInterpolation < Cop
12
20
  MSG = 'Empty interpolation detected.'.freeze
13
21
 
@@ -7,33 +7,31 @@ module RuboCop
7
7
  #
8
8
  # @example
9
9
  #
10
- # @bad
10
+ # # bad
11
+ #
11
12
  # case foo
12
13
  # when bar then 1
13
14
  # when baz then # nothing
14
15
  # end
16
+ #
17
+ # @example
18
+ #
19
+ # # good
20
+ #
21
+ # case foo
22
+ # when bar then 1
23
+ # when baz then 2
24
+ # end
15
25
  class EmptyWhen < Cop
16
26
  MSG = 'Avoid `when` branches without a body.'.freeze
17
27
 
18
28
  def on_case(node)
19
- _cond_node, *when_nodes, _else_node = *node
29
+ node.each_when do |when_node|
30
+ next if when_node.body
20
31
 
21
- when_nodes.each do |when_node|
22
- check_when(when_node)
32
+ add_offense(when_node, when_node.source_range, MSG)
23
33
  end
24
34
  end
25
-
26
- private
27
-
28
- def check_when(when_node)
29
- return unless empty_when_body?(when_node)
30
-
31
- add_offense(when_node, when_node.source_range, MSG)
32
- end
33
-
34
- def empty_when_body?(when_node)
35
- !when_node.to_a.last
36
- end
37
35
  end
38
36
  end
39
37
  end
@@ -5,8 +5,8 @@ module RuboCop
5
5
  module Lint
6
6
  # This cop checks whether the end keywords are aligned properly.
7
7
  #
8
- # Three modes are supported through the `AlignWith` configuration
9
- # parameter:
8
+ # Three modes are supported through the `EnforcedStyleAlignWith`
9
+ # configuration parameter:
10
10
  #
11
11
  # If it's set to `keyword` (which is the default), the `end`
12
12
  # shall be aligned with the start of the keyword (if, class, etc.).
@@ -18,22 +18,41 @@ module RuboCop
18
18
  # start of the line where the matching keyword appears.
19
19
  #
20
20
  # @example
21
- # @good
22
- # # keyword style
21
+ #
22
+ # # bad
23
+ #
24
+ # variable = if true
25
+ # end
26
+ #
27
+ # @example
28
+ #
29
+ # # EnforcedStyleAlignWith: keyword (default)
30
+ #
31
+ # # good
32
+ #
23
33
  # variable = if true
24
34
  # end
25
35
  #
26
- # # variable style
36
+ # @example
37
+ #
38
+ # # EnforcedStyleAlignWith: variable
39
+ #
40
+ # # good
41
+ #
27
42
  # variable = if true
28
43
  # end
29
44
  #
30
- # # start_of_line style
45
+ # @example
46
+ #
47
+ # # EnforcedStyleAlignWith: start_of_line
48
+ #
49
+ # # good
50
+ #
31
51
  # puts(if true
32
52
  # end)
33
53
  class EndAlignment < Cop
34
54
  include CheckAssignment
35
55
  include EndKeywordAlignment
36
- include IfNode
37
56
 
38
57
  def on_class(node)
39
58
  check_other_alignment(node)
@@ -44,7 +63,7 @@ module RuboCop
44
63
  end
45
64
 
46
65
  def on_if(node)
47
- check_other_alignment(node) unless ternary?(node)
66
+ check_other_alignment(node) unless node.ternary?
48
67
  end
49
68
 
50
69
  def on_while(node)
@@ -56,8 +75,11 @@ module RuboCop
56
75
  end
57
76
 
58
77
  def on_case(node)
59
- return check_asgn_alignment(node.parent, node) if argument_case?(node)
60
- check_other_alignment(node)
78
+ if node.argument?
79
+ check_asgn_alignment(node.parent, node)
80
+ else
81
+ check_other_alignment(node)
82
+ end
61
83
  end
62
84
 
63
85
  private
@@ -67,29 +89,31 @@ module RuboCop
67
89
  # assignment, we let rhs be the receiver of those method calls before
68
90
  # we check if it's an if/unless/while/until.
69
91
  return unless (rhs = first_part_of_call_chain(rhs))
70
- return unless [:if, :while, :until, :case].include?(rhs.type)
71
- return if ternary?(rhs)
92
+ return unless CONDITIONAL_NODES.include?(rhs.type)
93
+ return if rhs.if_type? && rhs.ternary?
72
94
 
73
95
  check_asgn_alignment(node, rhs)
74
96
  end
75
97
 
76
98
  def check_asgn_alignment(outer_node, inner_node)
77
- expr = outer_node.source_range
78
-
79
99
  align_with = {
80
100
  keyword: inner_node.loc.keyword,
81
- start_of_line: start_line_range(outer_node)
101
+ start_of_line: start_line_range(outer_node),
102
+ variable: asgn_variable_align_with(outer_node, inner_node)
82
103
  }
83
104
 
84
- align_with[:variable] =
85
- if !line_break_before_keyword?(expr, inner_node)
86
- range_between(expr.begin_pos, inner_node.loc.keyword.end_pos)
87
- else
88
- inner_node.loc.keyword
89
- end
90
-
91
105
  check_end_kw_alignment(inner_node, align_with)
92
- ignore_node(inner_node) # Don't check again.
106
+ ignore_node(inner_node)
107
+ end
108
+
109
+ def asgn_variable_align_with(outer_node, inner_node)
110
+ expr = outer_node.source_range
111
+
112
+ if !line_break_before_keyword?(expr, inner_node)
113
+ range_between(expr.begin_pos, inner_node.loc.keyword.end_pos)
114
+ else
115
+ inner_node.loc.keyword
116
+ end
93
117
  end
94
118
 
95
119
  def check_other_alignment(node)
@@ -109,7 +133,7 @@ module RuboCop
109
133
  if style == :keyword
110
134
  node
111
135
  elsif style == :variable
112
- return node.parent if argument_case?(node)
136
+ return node.parent if node.case_type? && node.argument?
113
137
  # Fall back to 'keyword' style if this node is not on the RHS
114
138
  # of an assignment
115
139
  node.ancestors.find(&:assignment?) || node
@@ -118,10 +142,6 @@ module RuboCop
118
142
  end
119
143
  end
120
144
 
121
- def argument_case?(node)
122
- node.case_type? && node.parent && node.parent.send_type?
123
- end
124
-
125
145
  def start_line_range(node)
126
146
  expr = node.source_range
127
147
  buffer = expr.source_buffer
@@ -4,6 +4,29 @@ module RuboCop
4
4
  module Cop
5
5
  module Lint
6
6
  # This cop checks for END blocks in method definitions.
7
+ #
8
+ # @example
9
+ #
10
+ # # bad
11
+ #
12
+ # def some_method
13
+ # END { do_something }
14
+ # end
15
+ #
16
+ # @example
17
+ #
18
+ # # good
19
+ #
20
+ # def some_method
21
+ # at_exit { do_something }
22
+ # end
23
+ #
24
+ # @example
25
+ #
26
+ # # good
27
+ #
28
+ # # outside defs
29
+ # END { do_something }
7
30
  class EndInMethod < Cop
8
31
  MSG = '`END` found in method definition. Use `at_exit` instead.'.freeze
9
32
 
@@ -4,6 +4,27 @@ module RuboCop
4
4
  module Cop
5
5
  module Lint
6
6
  # This cop checks for *return* from an *ensure* block.
7
+ #
8
+ # @example
9
+ #
10
+ # # bad
11
+ #
12
+ # begin
13
+ # do_something
14
+ # ensure
15
+ # do_something_else
16
+ # return
17
+ # end
18
+ #
19
+ # @example
20
+ #
21
+ # # good
22
+ #
23
+ # begin
24
+ # do_something
25
+ # ensure
26
+ # do_something_else
27
+ # end
7
28
  class EnsureReturn < Cop
8
29
  MSG = 'Do not return from an `ensure` block.'.freeze
9
30