rubocop 0.73.0 → 0.77.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (216) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -2
  3. data/bin/console +1 -0
  4. data/config/default.yml +332 -295
  5. data/lib/rubocop.rb +46 -30
  6. data/lib/rubocop/ast/builder.rb +1 -0
  7. data/lib/rubocop/ast/node.rb +6 -8
  8. data/lib/rubocop/ast/node/block_node.rb +2 -0
  9. data/lib/rubocop/ast/node/mixin/method_dispatch_node.rb +1 -12
  10. data/lib/rubocop/ast/node/return_node.rb +24 -0
  11. data/lib/rubocop/cli.rb +11 -227
  12. data/lib/rubocop/cli/command.rb +21 -0
  13. data/lib/rubocop/cli/command/auto_genenerate_config.rb +105 -0
  14. data/lib/rubocop/cli/command/base.rb +33 -0
  15. data/lib/rubocop/cli/command/execute_runner.rb +76 -0
  16. data/lib/rubocop/cli/command/init_dotfile.rb +45 -0
  17. data/lib/rubocop/cli/command/show_cops.rb +73 -0
  18. data/lib/rubocop/cli/command/version.rb +17 -0
  19. data/lib/rubocop/cli/environment.rb +21 -0
  20. data/lib/rubocop/comment_config.rb +5 -4
  21. data/lib/rubocop/config.rb +28 -537
  22. data/lib/rubocop/config_loader.rb +21 -3
  23. data/lib/rubocop/config_loader_resolver.rb +4 -3
  24. data/lib/rubocop/config_obsoletion.rb +275 -0
  25. data/lib/rubocop/config_validator.rb +246 -0
  26. data/lib/rubocop/cop/autocorrect_logic.rb +2 -2
  27. data/lib/rubocop/cop/bundler/gem_comment.rb +4 -4
  28. data/lib/rubocop/cop/commissioner.rb +15 -7
  29. data/lib/rubocop/cop/cop.rb +33 -9
  30. data/lib/rubocop/cop/corrector.rb +8 -7
  31. data/lib/rubocop/cop/correctors/alignment_corrector.rb +43 -17
  32. data/lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +2 -2
  33. data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +1 -1
  34. data/lib/rubocop/cop/correctors/space_corrector.rb +1 -2
  35. data/lib/rubocop/cop/generator.rb +3 -3
  36. data/lib/rubocop/cop/generator/configuration_injector.rb +9 -4
  37. data/lib/rubocop/cop/generator/require_file_injector.rb +1 -1
  38. data/lib/rubocop/cop/internal_affairs.rb +1 -0
  39. data/lib/rubocop/cop/internal_affairs/method_name_equal.rb +59 -0
  40. data/lib/rubocop/cop/layout/{align_arguments.rb → argument_alignment.rb} +1 -1
  41. data/lib/rubocop/cop/layout/{align_array.rb → array_alignment.rb} +1 -1
  42. data/lib/rubocop/cop/layout/{indent_assignment.rb → assignment_indentation.rb} +11 -2
  43. data/lib/rubocop/cop/layout/block_alignment.rb +2 -2
  44. data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +1 -1
  45. data/lib/rubocop/cop/layout/comment_indentation.rb +10 -13
  46. data/lib/rubocop/cop/layout/empty_comment.rb +7 -16
  47. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +22 -7
  48. data/lib/rubocop/cop/layout/empty_line_after_magic_comment.rb +2 -2
  49. data/lib/rubocop/cop/layout/empty_lines_around_class_body.rb +2 -2
  50. data/lib/rubocop/cop/layout/end_of_line.rb +8 -3
  51. data/lib/rubocop/cop/layout/extra_spacing.rb +15 -60
  52. data/lib/rubocop/cop/layout/{indent_first_argument.rb → first_argument_indentation.rb} +12 -10
  53. data/lib/rubocop/cop/layout/{indent_first_array_element.rb → first_array_element_indentation.rb} +4 -4
  54. data/lib/rubocop/cop/layout/{indent_first_hash_element.rb → first_hash_element_indentation.rb} +4 -4
  55. data/lib/rubocop/cop/layout/{indent_first_parameter.rb → first_parameter_indentation.rb} +3 -3
  56. data/lib/rubocop/cop/layout/{align_hash.rb → hash_alignment.rb} +8 -4
  57. data/lib/rubocop/cop/layout/{indent_heredoc.rb → heredoc_indentation.rb} +2 -2
  58. data/lib/rubocop/cop/layout/indentation_width.rb +19 -5
  59. data/lib/rubocop/cop/layout/{leading_blank_lines.rb → leading_empty_lines.rb} +1 -1
  60. data/lib/rubocop/cop/layout/multiline_assignment_layout.rb +1 -1
  61. data/lib/rubocop/cop/layout/multiline_block_layout.rb +24 -2
  62. data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +1 -1
  63. data/lib/rubocop/cop/layout/{align_parameters.rb → parameter_alignment.rb} +1 -1
  64. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +2 -0
  65. data/lib/rubocop/cop/layout/space_around_block_parameters.rb +5 -1
  66. data/lib/rubocop/cop/layout/space_around_keyword.rb +12 -0
  67. data/lib/rubocop/cop/layout/space_around_operators.rb +43 -24
  68. data/lib/rubocop/cop/layout/space_in_lambda_literal.rb +9 -7
  69. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +8 -5
  70. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +7 -0
  71. data/lib/rubocop/cop/layout/space_inside_parens.rb +6 -6
  72. data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +24 -40
  73. data/lib/rubocop/cop/layout/{trailing_blank_lines.rb → trailing_empty_lines.rb} +1 -1
  74. data/lib/rubocop/cop/layout/trailing_whitespace.rb +18 -2
  75. data/lib/rubocop/cop/lint/assignment_in_condition.rb +17 -4
  76. data/lib/rubocop/cop/lint/debugger.rb +1 -3
  77. data/lib/rubocop/cop/lint/disjunctive_assignment_in_constructor.rb +1 -1
  78. data/lib/rubocop/cop/lint/{duplicated_key.rb → duplicate_hash_key.rb} +1 -1
  79. data/lib/rubocop/cop/lint/empty_interpolation.rb +4 -4
  80. data/lib/rubocop/cop/lint/erb_new_arguments.rb +61 -4
  81. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +10 -36
  82. data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +1 -1
  83. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +7 -8
  84. data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +2 -2
  85. data/lib/rubocop/cop/lint/{multiple_compare.rb → multiple_comparison.rb} +1 -1
  86. data/lib/rubocop/cop/lint/number_conversion.rb +1 -1
  87. data/lib/rubocop/cop/lint/{unneeded_cop_disable_directive.rb → redundant_cop_disable_directive.rb} +24 -24
  88. data/lib/rubocop/cop/lint/{unneeded_cop_enable_directive.rb → redundant_cop_enable_directive.rb} +6 -8
  89. data/lib/rubocop/cop/lint/{unneeded_require_statement.rb → redundant_require_statement.rb} +1 -1
  90. data/lib/rubocop/cop/lint/{unneeded_splat_expansion.rb → redundant_splat_expansion.rb} +12 -7
  91. data/lib/rubocop/cop/lint/{string_conversion_in_interpolation.rb → redundant_string_coercion.rb} +7 -7
  92. data/lib/rubocop/cop/lint/redundant_with_index.rb +2 -2
  93. data/lib/rubocop/cop/lint/redundant_with_object.rb +2 -2
  94. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +5 -6
  95. data/lib/rubocop/cop/lint/send_with_mixin_argument.rb +91 -0
  96. data/lib/rubocop/cop/lint/{handle_exceptions.rb → suppressed_exception.rb} +1 -1
  97. data/lib/rubocop/cop/lint/unused_block_argument.rb +22 -6
  98. data/lib/rubocop/cop/lint/unused_method_argument.rb +23 -5
  99. data/lib/rubocop/cop/lint/useless_access_modifier.rb +57 -23
  100. data/lib/rubocop/cop/lint/useless_setter_call.rb +1 -1
  101. data/lib/rubocop/cop/lint/void.rb +7 -26
  102. data/lib/rubocop/cop/message_annotator.rb +16 -7
  103. data/lib/rubocop/cop/metrics/abc_size.rb +1 -1
  104. data/lib/rubocop/cop/metrics/line_length.rb +48 -42
  105. data/lib/rubocop/cop/metrics/method_length.rb +1 -1
  106. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +23 -6
  107. data/lib/rubocop/cop/migration/department_name.rb +44 -0
  108. data/lib/rubocop/cop/mixin/alignment.rb +1 -1
  109. data/lib/rubocop/cop/mixin/documentation_comment.rb +0 -2
  110. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +1 -1
  111. data/lib/rubocop/cop/mixin/{hash_alignment.rb → hash_alignment_styles.rb} +1 -1
  112. data/lib/rubocop/cop/mixin/interpolation.rb +27 -0
  113. data/lib/rubocop/cop/mixin/method_complexity.rb +2 -1
  114. data/lib/rubocop/cop/mixin/nil_methods.rb +4 -4
  115. data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +87 -0
  116. data/lib/rubocop/cop/mixin/statement_modifier.rb +5 -2
  117. data/lib/rubocop/cop/mixin/surrounding_space.rb +7 -5
  118. data/lib/rubocop/cop/mixin/trailing_comma.rb +8 -6
  119. data/lib/rubocop/cop/naming/{uncommunicative_block_param_name.rb → block_parameter_name.rb} +3 -3
  120. data/lib/rubocop/cop/naming/file_name.rb +12 -5
  121. data/lib/rubocop/cop/naming/heredoc_delimiter_naming.rb +5 -5
  122. data/lib/rubocop/cop/naming/method_name.rb +12 -1
  123. data/lib/rubocop/cop/naming/{uncommunicative_method_param_name.rb → method_parameter_name.rb} +3 -3
  124. data/lib/rubocop/cop/naming/predicate_name.rb +6 -6
  125. data/lib/rubocop/cop/naming/variable_name.rb +1 -0
  126. data/lib/rubocop/cop/offense.rb +18 -7
  127. data/lib/rubocop/cop/registry.rb +22 -1
  128. data/lib/rubocop/cop/style/access_modifier_declarations.rb +1 -0
  129. data/lib/rubocop/cop/style/alias.rb +1 -1
  130. data/lib/rubocop/cop/style/array_join.rb +1 -1
  131. data/lib/rubocop/cop/style/attr.rb +2 -2
  132. data/lib/rubocop/cop/style/block_delimiters.rb +2 -1
  133. data/lib/rubocop/cop/style/braces_around_hash_parameters.rb +35 -16
  134. data/lib/rubocop/cop/style/class_and_module_children.rb +1 -1
  135. data/lib/rubocop/cop/style/comment_annotation.rb +5 -5
  136. data/lib/rubocop/cop/style/commented_keyword.rb +16 -30
  137. data/lib/rubocop/cop/style/conditional_assignment.rb +5 -7
  138. data/lib/rubocop/cop/style/constant_visibility.rb +13 -2
  139. data/lib/rubocop/cop/style/copyright.rb +11 -7
  140. data/lib/rubocop/cop/style/documentation_method.rb +44 -0
  141. data/lib/rubocop/cop/style/double_cop_disable_directive.rb +10 -4
  142. data/lib/rubocop/cop/style/empty_case_condition.rb +2 -2
  143. data/lib/rubocop/cop/style/empty_literal.rb +2 -2
  144. data/lib/rubocop/cop/style/empty_method.rb +5 -5
  145. data/lib/rubocop/cop/style/eval_with_location.rb +1 -1
  146. data/lib/rubocop/cop/style/even_odd.rb +1 -1
  147. data/lib/rubocop/cop/style/expand_path_arguments.rb +1 -1
  148. data/lib/rubocop/cop/style/format_string.rb +10 -7
  149. data/lib/rubocop/cop/style/format_string_token.rb +19 -68
  150. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +28 -33
  151. data/lib/rubocop/cop/style/guard_clause.rb +39 -10
  152. data/lib/rubocop/cop/style/hash_syntax.rb +2 -2
  153. data/lib/rubocop/cop/style/if_unless_modifier.rb +58 -15
  154. data/lib/rubocop/cop/style/infinite_loop.rb +5 -4
  155. data/lib/rubocop/cop/style/inverse_methods.rb +19 -13
  156. data/lib/rubocop/cop/style/ip_addresses.rb +4 -4
  157. data/lib/rubocop/cop/style/lambda.rb +0 -2
  158. data/lib/rubocop/cop/style/line_end_concatenation.rb +14 -10
  159. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +25 -25
  160. data/lib/rubocop/cop/style/method_def_parentheses.rb +17 -9
  161. data/lib/rubocop/cop/style/mixin_grouping.rb +1 -1
  162. data/lib/rubocop/cop/style/mixin_usage.rb +11 -1
  163. data/lib/rubocop/cop/style/multiline_memoization.rb +1 -1
  164. data/lib/rubocop/cop/style/multiline_when_then.rb +1 -1
  165. data/lib/rubocop/cop/style/nested_modifier.rb +22 -4
  166. data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +5 -5
  167. data/lib/rubocop/cop/style/next.rb +5 -5
  168. data/lib/rubocop/cop/style/non_nil_check.rb +21 -9
  169. data/lib/rubocop/cop/style/numeric_literals.rb +7 -3
  170. data/lib/rubocop/cop/style/option_hash.rb +3 -3
  171. data/lib/rubocop/cop/style/or_assignment.rb +6 -1
  172. data/lib/rubocop/cop/style/parentheses_around_condition.rb +14 -0
  173. data/lib/rubocop/cop/style/{unneeded_capital_w.rb → redundant_capital_w.rb} +1 -1
  174. data/lib/rubocop/cop/style/{unneeded_condition.rb → redundant_condition.rb} +3 -3
  175. data/lib/rubocop/cop/style/{unneeded_interpolation.rb → redundant_interpolation.rb} +1 -1
  176. data/lib/rubocop/cop/style/redundant_parentheses.rb +16 -7
  177. data/lib/rubocop/cop/style/{unneeded_percent_q.rb → redundant_percent_q.rb} +1 -1
  178. data/lib/rubocop/cop/style/redundant_return.rb +39 -29
  179. data/lib/rubocop/cop/style/redundant_self.rb +18 -1
  180. data/lib/rubocop/cop/style/{unneeded_sort.rb → redundant_sort.rb} +5 -5
  181. data/lib/rubocop/cop/style/rescue_modifier.rb +24 -0
  182. data/lib/rubocop/cop/style/safe_navigation.rb +23 -3
  183. data/lib/rubocop/cop/style/semicolon.rb +13 -2
  184. data/lib/rubocop/cop/style/single_line_methods.rb +8 -1
  185. data/lib/rubocop/cop/style/special_global_vars.rb +5 -7
  186. data/lib/rubocop/cop/style/ternary_parentheses.rb +19 -0
  187. data/lib/rubocop/cop/style/trailing_method_end_statement.rb +4 -6
  188. data/lib/rubocop/cop/style/trivial_accessors.rb +5 -5
  189. data/lib/rubocop/cop/style/variable_interpolation.rb +6 -16
  190. data/lib/rubocop/cop/team.rb +5 -0
  191. data/lib/rubocop/cop/util.rb +1 -1
  192. data/lib/rubocop/cop/utils/format_string.rb +120 -0
  193. data/lib/rubocop/cop/variable_force.rb +7 -5
  194. data/lib/rubocop/cop/variable_force/variable.rb +15 -2
  195. data/lib/rubocop/core_ext/string.rb +0 -24
  196. data/lib/rubocop/formatter/clang_style_formatter.rb +9 -6
  197. data/lib/rubocop/formatter/emacs_style_formatter.rb +22 -9
  198. data/lib/rubocop/formatter/file_list_formatter.rb +1 -1
  199. data/lib/rubocop/formatter/formatter_set.rb +16 -15
  200. data/lib/rubocop/formatter/pacman_formatter.rb +80 -0
  201. data/lib/rubocop/formatter/simple_text_formatter.rb +16 -4
  202. data/lib/rubocop/formatter/tap_formatter.rb +18 -7
  203. data/lib/rubocop/magic_comment.rb +4 -0
  204. data/lib/rubocop/node_pattern.rb +3 -1
  205. data/lib/rubocop/options.rb +17 -22
  206. data/lib/rubocop/path_util.rb +1 -1
  207. data/lib/rubocop/processed_source.rb +5 -1
  208. data/lib/rubocop/rake_task.rb +1 -0
  209. data/lib/rubocop/result_cache.rb +22 -8
  210. data/lib/rubocop/rspec/expect_offense.rb +4 -1
  211. data/lib/rubocop/runner.rb +55 -32
  212. data/lib/rubocop/target_finder.rb +12 -6
  213. data/lib/rubocop/version.rb +1 -1
  214. metadata +47 -32
  215. data/lib/rubocop/cop/mixin/ignored_method_patterns.rb +0 -19
  216. data/lib/rubocop/cop/mixin/safe_mode.rb +0 -22
@@ -113,22 +113,30 @@ module RuboCop
113
113
  lambda do |corrector|
114
114
  if node.args_type?
115
115
  # offense is registered on args node when parentheses are unwanted
116
- corrector.replace(node.loc.begin, ' ')
117
- corrector.remove(node.loc.end)
116
+ correct_arguments(node, corrector)
118
117
  else
119
- args_expr = node.arguments.source_range
120
- args_with_space = range_with_surrounding_space(range: args_expr,
121
- side: :left)
122
- just_space = range_between(args_with_space.begin_pos,
123
- args_expr.begin_pos)
124
- corrector.replace(just_space, '(')
125
- corrector.insert_after(args_expr, ')')
118
+ correct_definition(node, corrector)
126
119
  end
127
120
  end
128
121
  end
129
122
 
130
123
  private
131
124
 
125
+ def correct_arguments(arg_node, corrector)
126
+ corrector.replace(arg_node.loc.begin, ' ')
127
+ corrector.remove(arg_node.loc.end)
128
+ end
129
+
130
+ def correct_definition(def_node, corrector)
131
+ arguments_range = def_node.arguments.source_range
132
+ args_with_space = range_with_surrounding_space(range: arguments_range,
133
+ side: :left)
134
+ leading_space = range_between(args_with_space.begin_pos,
135
+ arguments_range.begin_pos)
136
+ corrector.replace(leading_space, '(')
137
+ corrector.insert_after(arguments_range, ')')
138
+ end
139
+
132
140
  def require_parentheses?(args)
133
141
  style == :require_parentheses ||
134
142
  (style == :require_no_parentheses_except_multiline &&
@@ -103,7 +103,7 @@ module RuboCop
103
103
  .select(&:macro?)
104
104
 
105
105
  siblings.select do |sibling_node|
106
- sibling_node.method_name == send_node.method_name
106
+ sibling_node.method?(send_node.method_name)
107
107
  end
108
108
  end
109
109
 
@@ -49,6 +49,10 @@ module RuboCop
49
49
  const)
50
50
  PATTERN
51
51
 
52
+ def_node_matcher :wrapped_macro_scope?, <<~PATTERN
53
+ {({sclass class module block} ... ({begin if} ...))}
54
+ PATTERN
55
+
52
56
  def on_send(node)
53
57
  include_statement(node) do |statement|
54
58
  return if node.argument? ||
@@ -62,7 +66,13 @@ module RuboCop
62
66
  private
63
67
 
64
68
  def accepted_include?(node)
65
- node.parent && node.macro?
69
+ node.parent && (node.macro? || ascend_macro_scope?(node.parent))
70
+ end
71
+
72
+ def ascend_macro_scope?(ancestor)
73
+ return true if wrapped_macro_scope?(ancestor)
74
+
75
+ ancestor.parent && ascend_macro_scope?(ancestor.parent)
66
76
  end
67
77
 
68
78
  def belongs_to_class_or_module?(node)
@@ -73,7 +73,7 @@ module RuboCop
73
73
  end
74
74
 
75
75
  def keyword_begin_str(node, node_buf)
76
- indent = config.for_cop('IndentationWidth')['Width'] || 2
76
+ indent = config.for_cop('Layout/IndentationWidth')['Width'] || 2
77
77
  if node_buf.source[node.loc.begin.end_pos] == "\n"
78
78
  'begin'
79
79
  else
@@ -44,7 +44,7 @@ module RuboCop
44
44
  lambda do |corrector|
45
45
  corrector.remove(
46
46
  range_with_surrounding_space(
47
- range: node.loc.begin, side: :left
47
+ range: node.loc.begin, side: :left, newlines: false
48
48
  )
49
49
  )
50
50
  end
@@ -49,11 +49,13 @@ module RuboCop
49
49
  node.parent.condition.source_range.end_pos)
50
50
 
51
51
  lambda do |corrector|
52
- corrector.replace(range, new_expression(node.parent, node))
52
+ corrector.replace(range, new_expression(node))
53
53
  end
54
54
  end
55
55
 
56
- def new_expression(outer_node, inner_node)
56
+ def new_expression(inner_node)
57
+ outer_node = inner_node.parent
58
+
57
59
  operator = replacement_operator(outer_node.keyword)
58
60
  lh_operand = left_hand_operand(outer_node, operator)
59
61
  rh_operand = right_hand_operand(inner_node, outer_node.keyword)
@@ -73,12 +75,28 @@ module RuboCop
73
75
  end
74
76
 
75
77
  def right_hand_operand(node, left_hand_keyword)
76
- expr = node.condition.source
77
- expr = "(#{expr})" if requires_parens?(node.condition)
78
+ condition = node.condition
79
+
80
+ expr = if condition.send_type? && !condition.arguments.empty? &&
81
+ !condition.operator_method?
82
+ add_parentheses_to_method_arguments(condition)
83
+ else
84
+ condition.source
85
+ end
86
+ expr = "(#{expr})" if requires_parens?(condition)
78
87
  expr = "!#{expr}" unless left_hand_keyword == node.keyword
79
88
  expr
80
89
  end
81
90
 
91
+ def add_parentheses_to_method_arguments(send_node)
92
+ expr = +''
93
+ expr << "#{send_node.receiver.source}." if send_node.receiver
94
+ expr << send_node.method_name.to_s
95
+ expr << "(#{send_node.arguments.map(&:source).join(', ')})"
96
+
97
+ expr
98
+ end
99
+
82
100
  def requires_parens?(node)
83
101
  node.or_type? ||
84
102
  !(RuboCop::AST::Node::COMPARISON_OPERATORS & node.children).empty?
@@ -49,17 +49,17 @@ module RuboCop
49
49
  def allowed_omission?(send_node)
50
50
  !send_node.arguments? || send_node.parenthesized? ||
51
51
  send_node.setter_method? || send_node.operator_method? ||
52
- whitelisted?(send_node)
52
+ allowed?(send_node)
53
53
  end
54
54
 
55
- def whitelisted?(send_node)
55
+ def allowed?(send_node)
56
56
  send_node.parent.arguments.one? &&
57
- whitelisted_methods.include?(send_node.method_name.to_s) &&
57
+ allowed_methods.include?(send_node.method_name.to_s) &&
58
58
  send_node.arguments.one?
59
59
  end
60
60
 
61
- def whitelisted_methods
62
- cop_config['Whitelist'] || []
61
+ def allowed_methods
62
+ cop_config['AllowedMethods'] || []
63
63
  end
64
64
  end
65
65
  end
@@ -20,18 +20,18 @@ module RuboCop
20
20
  # end
21
21
  #
22
22
  # # good
23
- # [1, 2].each do |o|
24
- # puts o unless o == 1
23
+ # [1, 2].each do |a|
24
+ # puts a if a == 1
25
25
  # end
26
26
  #
27
27
  # @example EnforcedStyle: always
28
28
  # # With `always` all conditions at the end of an iteration needs to be
29
29
  # # replaced by next - with `skip_modifier_ifs` the modifier if like
30
- # # this one are ignored: `[1, 2].each { |a| return 'yes' if a == 1 }`
30
+ # # this one are ignored: `[1, 2].each { |a| puts a if a == 1 }`
31
31
  #
32
32
  # # bad
33
- # [1, 2].each do |o|
34
- # puts o unless o == 1
33
+ # [1, 2].each do |a|
34
+ # puts a if a == 1
35
35
  # end
36
36
  #
37
37
  # # bad
@@ -5,27 +5,39 @@ module RuboCop
5
5
  module Style
6
6
  # This cop checks for non-nil checks, which are usually redundant.
7
7
  #
8
- # @example
8
+ # With `IncludeSemanticChanges` set to `false` by default, this cop
9
+ # does not report offenses for `!x.nil?` and does no changes that might
10
+ # change behavior.
11
+ #
12
+ # With `IncludeSemanticChanges` set to `true`, this cop reports offenses
13
+ # for `!x.nil?` and autocorrects that and `x != nil` to solely `x`, which
14
+ # is **usually** OK, but might change behavior.
9
15
  #
16
+ # @example
10
17
  # # bad
11
18
  # if x != nil
12
19
  # end
13
20
  #
14
- # # good (when not allowing semantic changes)
15
- # # bad (when allowing semantic changes)
16
- # if !x.nil?
17
- # end
18
- #
19
- # # good (when allowing semantic changes)
21
+ # # good
20
22
  # if x
21
23
  # end
22
24
  #
23
- # Non-nil checks are allowed if they are the final nodes of predicate.
24
- #
25
+ # # Non-nil checks are allowed if they are the final nodes of predicate.
25
26
  # # good
26
27
  # def signed_in?
27
28
  # !current_user.nil?
28
29
  # end
30
+ #
31
+ # @example IncludeSemanticChanges: false (default)
32
+ # # good
33
+ # if !x.nil?
34
+ # end
35
+ #
36
+ # @example IncludeSemanticChanges: true
37
+ # # bad
38
+ # if !x.nil?
39
+ # end
40
+ #
29
41
  class NonNilCheck < Cop
30
42
  def_node_matcher :not_equal_to_nil?, '(send _ :!= nil)'
31
43
  def_node_matcher :unless_check?, '(if (send _ :nil?) ...)'
@@ -9,18 +9,22 @@ module RuboCop
9
9
  # @example
10
10
  #
11
11
  # # bad
12
- #
13
12
  # 1000000
14
13
  # 1_00_000
15
14
  # 1_0000
16
15
  #
17
16
  # # good
18
- #
19
17
  # 1_000_000
20
18
  # 1000
21
19
  #
22
- # # good unless Strict is set
20
+ # @example Strict: false (default)
23
21
  #
22
+ # # good
23
+ # 10_000_00 # typical representation of $10,000 in cents
24
+ #
25
+ # @example Strict: true
26
+ #
27
+ # # bad
24
28
  # 10_000_00 # typical representation of $10,000 in cents
25
29
  #
26
30
  class NumericLiterals < Cop
@@ -28,7 +28,7 @@ module RuboCop
28
28
 
29
29
  def on_args(node)
30
30
  return if super_used?(node)
31
- return if whitelist.include?(node.parent.method_name.to_s)
31
+ return if allowlist.include?(node.parent.method_name.to_s)
32
32
 
33
33
  option_hash(node) do |options|
34
34
  add_offense(options)
@@ -37,8 +37,8 @@ module RuboCop
37
37
 
38
38
  private
39
39
 
40
- def whitelist
41
- cop_config['Whitelist'] || []
40
+ def allowlist
41
+ cop_config['Allowlist'] || []
42
42
  end
43
43
 
44
44
  def suspicious_name?(arg_name)
@@ -81,7 +81,12 @@ module RuboCop
81
81
  end
82
82
 
83
83
  def take_variable_and_default_from_unless(node)
84
- variable, default = *node.if_branch
84
+ if node.if_branch
85
+ variable, default = *node.if_branch
86
+ else
87
+ variable, default = *node.else_branch
88
+ end
89
+
85
90
  [variable, default]
86
91
  end
87
92
  end
@@ -6,6 +6,11 @@ module RuboCop
6
6
  # This cop checks for the presence of superfluous parentheses around the
7
7
  # condition of if/unless/while/until.
8
8
  #
9
+ # `AllowSafeAssignment` option for safe assignment.
10
+ # By safe assignment we mean putting parentheses around
11
+ # an assignment to indicate "I know I'm using an assignment
12
+ # as a condition. It's not a mistake."
13
+ #
9
14
  # @example
10
15
  # # bad
11
16
  # x += 1 while (x < 10)
@@ -23,6 +28,14 @@ module RuboCop
23
28
  # elsif x < 3
24
29
  # end
25
30
  #
31
+ # @example AllowSafeAssignment: true (default)
32
+ # # good
33
+ # foo unless (bar = baz)
34
+ #
35
+ # @example AllowSafeAssignment: false
36
+ # # bad
37
+ # foo unless (bar = baz)
38
+ #
26
39
  # @example AllowInMultilineConditions: false (default)
27
40
  # # bad
28
41
  # if (x > 10 &&
@@ -39,6 +52,7 @@ module RuboCop
39
52
  # if (x > 10 &&
40
53
  # y > 10)
41
54
  # end
55
+ #
42
56
  class ParenthesesAroundCondition < Cop
43
57
  include SafeAssignment
44
58
  include Parentheses
@@ -14,7 +14,7 @@ module RuboCop
14
14
  # %w/swim run bike/
15
15
  # %w[shirt pants shoes]
16
16
  # %W(apple #{fruit} grape)
17
- class UnneededCapitalW < Cop
17
+ class RedundantCapitalW < Cop
18
18
  include PercentLiteral
19
19
 
20
20
  MSG = 'Do not use `%W` unless interpolation is needed. ' \
@@ -30,11 +30,11 @@ module RuboCop
30
30
  # c
31
31
  # end
32
32
  #
33
- class UnneededCondition < Cop
33
+ class RedundantCondition < Cop
34
34
  include RangeHelp
35
35
 
36
36
  MSG = 'Use double pipes `||` instead.'
37
- UNNEEDED_CONDITION = 'This condition is not needed.'
37
+ REDUNDANT_CONDITION = 'This condition is not needed.'
38
38
 
39
39
  def on_if(node)
40
40
  return if node.elsif_conditional?
@@ -61,7 +61,7 @@ module RuboCop
61
61
 
62
62
  def message(node)
63
63
  if node.modifier_form? || !node.else_branch
64
- UNNEEDED_CONDITION
64
+ REDUNDANT_CONDITION
65
65
  else
66
66
  MSG
67
67
  end
@@ -15,7 +15,7 @@ module RuboCop
15
15
  #
16
16
  # # good if @var is already a String
17
17
  # @var
18
- class UnneededInterpolation < Cop
18
+ class RedundantInterpolation < Cop
19
19
  include PercentLiteral
20
20
 
21
21
  MSG = 'Prefer `to_s` over string interpolation.'
@@ -19,7 +19,7 @@ module RuboCop
19
19
  def_node_matcher :square_brackets?,
20
20
  '(send {(send _recv _msg) str array hash} :[] ...)'
21
21
  def_node_matcher :range_end?, '^^{irange erange}'
22
- def_node_matcher :method_node_and_args, '$(send _recv _msg $...)'
22
+ def_node_matcher :method_node_and_args, '$(call _recv _msg $...)'
23
23
  def_node_matcher :rescue?, '{^resbody ^^resbody}'
24
24
  def_node_matcher :arg_in_call_with_block?,
25
25
  '^^(block (send _ _ equal?(%0) ...) ...)'
@@ -40,7 +40,7 @@ module RuboCop
40
40
 
41
41
  def parens_allowed?(node)
42
42
  empty_parentheses?(node) ||
43
- hash_literal_as_first_arg?(node) ||
43
+ first_arg_begins_with_hash_literal?(node) ||
44
44
  rescue?(node) ||
45
45
  allowed_expression?(node)
46
46
  end
@@ -76,12 +76,21 @@ module RuboCop
76
76
  node.children.empty?
77
77
  end
78
78
 
79
- def hash_literal_as_first_arg?(node)
80
- # Don't flag `method ({key: value})`
81
- node.children.first.hash_type? && first_argument?(node) &&
79
+ def first_arg_begins_with_hash_literal?(node)
80
+ # Don't flag `method ({key: value})` or `method ({key: value}.method)`
81
+ method_chain_begins_with_hash_literal?(node.children.first) &&
82
+ first_argument?(node) &&
82
83
  !parentheses?(node.parent)
83
84
  end
84
85
 
86
+ def method_chain_begins_with_hash_literal?(node)
87
+ return false if node.nil?
88
+ return true if node.hash_type?
89
+ return false unless node.send_type?
90
+
91
+ method_chain_begins_with_hash_literal?(node.children.first)
92
+ end
93
+
85
94
  def check(begin_node)
86
95
  node = begin_node.children.first
87
96
  if keyword_with_redundant_parentheses?(node)
@@ -93,7 +102,7 @@ module RuboCop
93
102
  return offense(begin_node, 'a variable') if node.variable?
94
103
  return offense(begin_node, 'a constant') if node.const_type?
95
104
 
96
- check_send(begin_node, node) if node.send_type?
105
+ check_send(begin_node, node) if node.call_type?
97
106
  end
98
107
 
99
108
  def check_send(begin_node, node)
@@ -186,7 +195,7 @@ module RuboCop
186
195
  end
187
196
 
188
197
  def method_call_with_redundant_parentheses?(node)
189
- return false unless node.send_type?
198
+ return false unless node.call_type?
190
199
  return false if node.prefix_not?
191
200
  return false if range_end?(node)
192
201
 
@@ -17,7 +17,7 @@ module RuboCop
17
17
  # time = "8 o'clock"
18
18
  # question = '"What did you say?"'
19
19
  #
20
- class UnneededPercentQ < Cop
20
+ class RedundantPercentQ < Cop
21
21
  MSG = 'Use `%<q_type>s` only for strings that contain both ' \
22
22
  'single quotes and double quotes%<extra>s.'
23
23
  DYNAMIC_MSG = ', or for dynamic strings that contain ' \