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,6 +8,10 @@ module RuboCop
8
8
  include PercentLiteral
9
9
  include ConfigurableEnforcedStyle
10
10
 
11
+ LOWER_CASE_Q_MSG = 'Do not use `%Q` unless interpolation is ' \
12
+ 'needed. Use `%q`.'.freeze
13
+ UPPER_CASE_Q_MSG = 'Use `%Q` instead of `%q`.'.freeze
14
+
11
15
  def on_str(node)
12
16
  process(node, '%Q', '%q')
13
17
  end
@@ -15,23 +19,22 @@ module RuboCop
15
19
  private
16
20
 
17
21
  def on_percent_literal(node)
18
- if style == :lower_case_q
19
- if type(node) == '%Q'
20
- check(node,
21
- 'Do not use `%Q` unless interpolation is needed. ' \
22
- 'Use `%q`.')
23
- end
24
- elsif type(node) == '%q'
25
- check(node, 'Use `%Q` instead of `%q`.')
26
- end
27
- end
22
+ return if correct_literal_style?(node)
28
23
 
29
- def check(node, msg)
30
24
  # Report offense only if changing case doesn't change semantics,
31
25
  # i.e., if the string would become dynamic or has special characters.
32
26
  return if node.children != parse(corrected(node.source)).ast.children
33
27
 
34
- add_offense(node, :begin, msg)
28
+ add_offense(node, :begin, message)
29
+ end
30
+
31
+ def correct_literal_style?(node)
32
+ style == :lower_case_q && type(node) == '%q' ||
33
+ style == :upper_case_q && type(node) == '%Q'
34
+ end
35
+
36
+ def message
37
+ style == :lower_case_q ? LOWER_CASE_Q_MSG : UPPER_CASE_Q_MSG
35
38
  end
36
39
 
37
40
  def autocorrect(node)
@@ -14,7 +14,8 @@ module RuboCop
14
14
  class RedundantFreeze < Cop
15
15
  include FrozenStringLiteral
16
16
 
17
- MSG = 'Freezing immutable objects is pointless.'.freeze
17
+ MSG = 'Do not freeze immutable objects, as freezing them has no ' \
18
+ 'effect.'.freeze
18
19
 
19
20
  def_node_matcher :freezing?, '(send $_ :freeze)'
20
21
 
@@ -38,7 +39,7 @@ module RuboCop
38
39
  return false unless node
39
40
  return true if node.immutable_literal?
40
41
  FROZEN_STRING_LITERAL_TYPES.include?(node.type) &&
41
- frozen_string_literals_enabled?(processed_source)
42
+ frozen_string_literals_enabled?
42
43
  end
43
44
  end
44
45
  end
@@ -37,7 +37,8 @@ module RuboCop
37
37
  hash_literal_as_first_arg?(node) ||
38
38
  rescue?(node) ||
39
39
  allowed_method_call?(node) ||
40
- allowed_array_or_hash_element?(node)
40
+ allowed_array_or_hash_element?(node) ||
41
+ allowed_multiple_expression?(node)
41
42
  end
42
43
 
43
44
  def allowed_ancestor?(node)
@@ -50,6 +51,13 @@ module RuboCop
50
51
  arg_in_call_with_block?(node) && !parentheses?(node.parent)
51
52
  end
52
53
 
54
+ def allowed_multiple_expression?(node)
55
+ return false if node.children.size == 1
56
+ ancestor = node.ancestors.first
57
+ return false unless ancestor
58
+ !ancestor.begin_type? && !ancestor.def_type? && !ancestor.block_type?
59
+ end
60
+
53
61
  def empty_parentheses?(node)
54
62
  # Don't flag `()`
55
63
  node.children.empty?
@@ -66,7 +74,9 @@ module RuboCop
66
74
  if keyword_with_redundant_parentheses?(node)
67
75
  return offense(begin_node, 'a keyword')
68
76
  end
69
- return offense(begin_node, 'a literal') if disallowed_literal?(node)
77
+ if disallowed_literal?(begin_node, node)
78
+ return offense(begin_node, 'a literal')
79
+ end
70
80
  return offense(begin_node, 'a variable') if node.variable?
71
81
  return offense(begin_node, 'a constant') if node.const_type?
72
82
  check_send(begin_node, node) if node.send_type?
@@ -126,8 +136,21 @@ module RuboCop
126
136
  line_range.source =~ /^\s*\)\s*,/
127
137
  end
128
138
 
129
- def disallowed_literal?(node)
130
- node.literal? && !ALLOWED_LITERALS.include?(node.type)
139
+ def disallowed_literal?(begin_node, node)
140
+ node.literal? &&
141
+ !ALLOWED_LITERALS.include?(node.type) &&
142
+ !raised_to_power_negative_numeric?(begin_node, node)
143
+ end
144
+
145
+ def raised_to_power_negative_numeric?(begin_node, node)
146
+ return false unless node.numeric_type?
147
+
148
+ siblings = begin_node.parent && begin_node.parent.children
149
+ return false if siblings.nil?
150
+ next_sibling = siblings[begin_node.sibling_index + 1]
151
+ base_value = node.children.first
152
+
153
+ base_value < 0 && next_sibling == :**
131
154
  end
132
155
 
133
156
  def keyword_with_redundant_parentheses?(node)
@@ -22,7 +22,6 @@ module RuboCop
22
22
  # or a case expression with a default branch.
23
23
  class RedundantReturn < Cop
24
24
  include OnMethodDef
25
- include IfNode
26
25
 
27
26
  MSG = 'Redundant `return` detected.'.freeze
28
27
 
@@ -39,17 +38,13 @@ module RuboCop
39
38
  if node.children.size > 1
40
39
  add_brackets(corrector, node)
41
40
  elsif return_value.hash_type?
42
- add_braces(corrector, return_value) unless braces?(return_value)
41
+ add_braces(corrector, return_value) unless return_value.braces?
43
42
  end
44
43
  return_kw = range_with_surrounding_space(node.loc.keyword, :right)
45
44
  corrector.remove(return_kw)
46
45
  end
47
46
  end
48
47
 
49
- def braces?(arg)
50
- arg.loc.begin
51
- end
52
-
53
48
  def add_brackets(corrector, node)
54
49
  kids = node.children.map(&:source_range)
55
50
  corrector.insert_before(kids.first, '[')
@@ -104,9 +99,10 @@ module RuboCop
104
99
  end
105
100
 
106
101
  def check_if_node(node)
107
- return if modifier_if?(node) || ternary?(node)
102
+ return if node.modifier_form? || node.ternary?
103
+
104
+ _cond, if_node, else_node = *node.node_parts
108
105
 
109
- _cond, if_node, else_node = if_node_parts(node)
110
106
  check_branch(if_node) if if_node
111
107
  check_branch(else_node) if else_node
112
108
  end
@@ -44,12 +44,14 @@ module RuboCop
44
44
  # # use safe navigation
45
45
  # foo.to_i if foo
46
46
  class SafeNavigation < Cop
47
- include IfNode
47
+ extend TargetRubyVersion
48
48
 
49
49
  MSG = 'Use safe navigation (`&.`) instead of checking if an object ' \
50
50
  'exists before calling the method.'.freeze
51
51
  NIL_METHODS = nil.methods.freeze
52
52
 
53
+ minimum_target_ruby_version 2.3
54
+
53
55
  def_node_matcher :safe_navigation_candidate, <<-PATTERN
54
56
  {
55
57
  (if
@@ -71,7 +73,8 @@ module RuboCop
71
73
  PATTERN
72
74
 
73
75
  def on_if(node)
74
- return if ternary?(node)
76
+ return if node.ternary?
77
+
75
78
  check_node(node)
76
79
  end
77
80
 
@@ -85,15 +88,19 @@ module RuboCop
85
88
 
86
89
  def check_node(node)
87
90
  return if target_ruby_version < 2.3
88
- return if if_else?(node)
89
- return if elsif?(node)
91
+ return if allowed_if_condition?(node)
90
92
  checked_variable, receiver, method = extract_parts(node)
91
93
  return unless receiver == checked_variable
92
94
  return if NIL_METHODS.include?(method)
93
95
  return unless method =~ /\w+[=!?]?/
96
+
94
97
  add_offense(node, :expression)
95
98
  end
96
99
 
100
+ def allowed_if_condition?(node)
101
+ node.if_type? && (node.else? || node.elsif?)
102
+ end
103
+
97
104
  def extract_parts(node)
98
105
  if cop_config['ConvertCodeThatCanStartToReturnNil']
99
106
  safe_navigation_candidate(node) ||
@@ -104,8 +111,8 @@ module RuboCop
104
111
  end
105
112
 
106
113
  def autocorrect(node)
107
- if node.loc.respond_to?(:keyword) && node.loc.keyword.is?('unless')
108
- _check, _else, body = *node
114
+ if node.if_type?
115
+ _check, body, = *node.node_parts
109
116
  else
110
117
  _check, body = *node
111
118
  end
@@ -7,14 +7,12 @@ module RuboCop
7
7
  # N.B. this cop does not handle spaces after a ternary operator, which are
8
8
  # instead handled by Style/SpaceAroundOperators.
9
9
  class SpaceAfterColon < Cop
10
- include IfNode
11
-
12
10
  MSG = 'Space missing after colon.'.freeze
13
11
 
14
12
  def on_pair(node)
15
- colon = node.loc.operator
13
+ return unless node.colon?
16
14
 
17
- return unless colon.is?(':')
15
+ colon = node.loc.operator
18
16
 
19
17
  add_offense(colon, colon) unless followed_by_space?(colon)
20
18
  end
@@ -33,7 +33,7 @@ module RuboCop
33
33
 
34
34
  private
35
35
 
36
- def parameter_name
36
+ def style_parameter_name
37
37
  'EnforcedStyleInsidePipes'
38
38
  end
39
39
 
@@ -6,28 +6,21 @@ module RuboCop
6
6
  # Checks that operators have space around them, except for **
7
7
  # which should not have surrounding space.
8
8
  class SpaceAroundOperators < Cop
9
- include IfNode
10
9
  include PrecedingFollowingAlignment
11
- include HashNode # any_pairs_on_the_same_line?
12
10
 
13
11
  def on_pair(node)
14
- return unless node.loc.operator.is?('=>')
12
+ return unless node.hash_rocket?
15
13
 
16
- align_hash_config = config.for_cop('Style/AlignHash')
17
- return if align_hash_config['EnforcedHashRocketStyle'] == 'table' &&
18
- !any_pairs_on_the_same_line?(node.parent)
14
+ return if hash_table_style? && !node.parent.pairs_on_same_line?
19
15
 
20
- _, right = *node
21
-
22
- check_operator(node.loc.operator, right.source_range)
16
+ check_operator(node.loc.operator, node.source_range)
23
17
  end
24
18
 
25
19
  def on_if(node)
26
- return unless ternary?(node)
27
- _, if_branch, else_branch = *node
20
+ return unless node.ternary?
28
21
 
29
- check_operator(node.loc.question, if_branch.source_range)
30
- check_operator(node.loc.colon, else_branch.source_range)
22
+ check_operator(node.loc.question, node.if_branch.source_range)
23
+ check_operator(node.loc.colon, node.else_branch.source_range)
31
24
  end
32
25
 
33
26
  def on_resbody(node)
@@ -130,6 +123,15 @@ module RuboCop
130
123
  end
131
124
  end
132
125
  end
126
+
127
+ def align_hash_cop_config
128
+ config.for_cop('Style/AlignHash')
129
+ end
130
+
131
+ def hash_table_style?
132
+ align_hash_cop_config &&
133
+ align_hash_cop_config['EnforcedHashRocketStyle'] == 'table'
134
+ end
133
135
  end
134
136
  end
135
137
  end
@@ -14,9 +14,7 @@ module RuboCop
14
14
  _receiver, method_name, *_args = *node
15
15
  return unless preferred_methods[method_name]
16
16
  add_offense(node, :selector,
17
- format(MSG,
18
- preferred_method(method_name),
19
- method_name))
17
+ format(MSG, preferred_method(method_name), method_name))
20
18
  end
21
19
 
22
20
  def autocorrect(node)
@@ -19,7 +19,7 @@ module RuboCop
19
19
  def on_array(node)
20
20
  if bracketed_array_of?(:sym, node)
21
21
  check_bracketed_array(node)
22
- elsif percent_array?(node)
22
+ elsif node.percent_literal?(:symbol)
23
23
  check_percent_array(node)
24
24
  end
25
25
  end
@@ -39,10 +39,6 @@ module RuboCop
39
39
 
40
40
  private
41
41
 
42
- def percent_array?(node)
43
- node.loc.begin && node.loc.begin.source =~ /\A%[iI]/
44
- end
45
-
46
42
  def check_bracketed_array(node)
47
43
  return if comments_in_array?(node)
48
44
  return if symbols_contain_spaces?(node)
@@ -49,7 +49,6 @@ module RuboCop
49
49
  # foo = bar.baz ? a : b
50
50
  # foo = (bar && baz) ? a : b
51
51
  class TernaryParentheses < Cop
52
- include IfNode
53
52
  include SafeAssignment
54
53
  include ConfigurableEnforcedStyle
55
54
 
@@ -58,14 +57,15 @@ module RuboCop
58
57
  ' complex conditions.'.freeze
59
58
 
60
59
  def on_if(node)
61
- return unless ternary?(node) && !infinite_loop? && offense?(node)
60
+ return unless node.ternary? && !infinite_loop? && offense?(node)
61
+
62
62
  add_offense(node, node.source_range, message(node))
63
63
  end
64
64
 
65
65
  private
66
66
 
67
67
  def offense?(node)
68
- condition, = *node
68
+ condition = node.condition
69
69
 
70
70
  if safe_assignment?(condition)
71
71
  !safe_assignment_allowed?
@@ -81,7 +81,7 @@ module RuboCop
81
81
  end
82
82
 
83
83
  def autocorrect(node)
84
- condition, = *node
84
+ condition = node.condition
85
85
 
86
86
  return nil if parenthesized?(condition) &&
87
87
  (safe_assignment?(condition) ||
@@ -118,8 +118,7 @@ module RuboCop
118
118
 
119
119
  def message(node)
120
120
  if require_parentheses_when_complex?
121
- condition, = *node
122
- omit = parenthesized?(condition) ? 'Only use' : 'Use'
121
+ omit = parenthesized?(node.condition) ? 'Only use' : 'Use'
123
122
  format(MSG_COMPLEX, omit)
124
123
  else
125
124
  verb = require_parentheses? ? 'Use' : 'Omit'
@@ -43,11 +43,8 @@ module RuboCop
43
43
  private
44
44
 
45
45
  def avoid_autocorrect?(args)
46
- hash_with_braces?(args.last) && braces_will_be_removed?(args)
47
- end
48
-
49
- def hash_with_braces?(node)
50
- node.hash_type? && node.loc.begin
46
+ args.last.hash_type? && args.last.braces? &&
47
+ braces_will_be_removed?(args)
51
48
  end
52
49
 
53
50
  # Returns true if running with --auto-correct would remove the braces
@@ -31,7 +31,7 @@ module RuboCop
31
31
  include TrailingComma
32
32
 
33
33
  def on_array(node)
34
- check_literal(node, 'item of %s array') if square_brackets?(node)
34
+ check_literal(node, 'item of %s array') if node.square_brackets?
35
35
  end
36
36
 
37
37
  def on_hash(node)
@@ -9,11 +9,7 @@ module RuboCop
9
9
  'positive case first.'.freeze
10
10
 
11
11
  def on_if(node)
12
- loc = node.loc
13
-
14
- # discard ternary ops and modifier if/unless nodes
15
- return unless loc.respond_to?(:keyword) && loc.respond_to?(:else)
16
- return unless loc.keyword.is?('unless'.freeze) && loc.else
12
+ return unless node.unless? && node.else?
17
13
 
18
14
  add_offense(node, :expression)
19
15
  end
@@ -8,13 +8,15 @@ module RuboCop
8
8
  MSG = 'Do not use `when x;`. Use `when x then` instead.'.freeze
9
9
 
10
10
  def on_when(node)
11
- return unless node.loc.begin && node.loc.begin.is?(';')
11
+ return if node.multiline? || node.then? || !node.body
12
12
 
13
13
  add_offense(node, :begin)
14
14
  end
15
15
 
16
16
  def autocorrect(node)
17
- ->(corrector) { corrector.replace(node.loc.begin, ' then') }
17
+ lambda do |corrector|
18
+ corrector.replace(node.loc.begin, ' then')
19
+ end
18
20
  end
19
21
  end
20
22
  end
@@ -5,6 +5,8 @@ module RuboCop
5
5
  module Style
6
6
  # Checks for uses of `do` in multi-line `while/until` statements.
7
7
  class WhileUntilDo < Cop
8
+ MSG = 'Do not use `do` with multi-line `%s`.'.freeze
9
+
8
10
  def on_while(node)
9
11
  handle(node)
10
12
  end
@@ -14,25 +16,19 @@ module RuboCop
14
16
  end
15
17
 
16
18
  def handle(node)
17
- length = node.source.lines.to_a.size
18
- return unless length > 1
19
- return unless node.loc.begin && node.loc.begin.is?('do')
19
+ return unless node.multiline? && node.do?
20
20
 
21
- add_offense(node, :begin, error_message(node.type))
21
+ add_offense(node, :begin, format(MSG, node.keyword))
22
22
  end
23
23
 
24
24
  private
25
25
 
26
- def error_message(node_type)
27
- format('Do not use `do` with multi-line `%s`.', node_type)
28
- end
29
-
30
26
  def autocorrect(node)
31
- condition_node, = *node
32
- end_of_condition_range = condition_node.source_range.end
33
- do_range = node.loc.begin
34
- whitespaces_and_do_range = end_of_condition_range.join(do_range)
35
- ->(corrector) { corrector.remove(whitespaces_and_do_range) }
27
+ do_range = node.condition.source_range.end.join(node.loc.begin)
28
+
29
+ lambda do |corrector|
30
+ corrector.remove(do_range)
31
+ end
36
32
  end
37
33
  end
38
34
  end