rubocop 0.88.0 → 0.89.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 (239) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/bin/rubocop-profile +1 -0
  4. data/config/default.yml +96 -16
  5. data/lib/rubocop.rb +16 -4
  6. data/lib/rubocop/cli/command/auto_genenerate_config.rb +1 -1
  7. data/lib/rubocop/cli/command/base.rb +1 -0
  8. data/lib/rubocop/cli/command/execute_runner.rb +1 -1
  9. data/lib/rubocop/cli/command/show_cops.rb +1 -1
  10. data/lib/rubocop/cli/command/version.rb +2 -2
  11. data/lib/rubocop/comment_config.rb +2 -2
  12. data/lib/rubocop/config.rb +19 -2
  13. data/lib/rubocop/config_loader.rb +1 -1
  14. data/lib/rubocop/config_loader_resolver.rb +3 -3
  15. data/lib/rubocop/config_obsoletion.rb +6 -1
  16. data/lib/rubocop/config_validator.rb +1 -3
  17. data/lib/rubocop/cop/base.rb +2 -2
  18. data/lib/rubocop/cop/commissioner.rb +0 -1
  19. data/lib/rubocop/cop/correctors/line_break_corrector.rb +3 -3
  20. data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +1 -1
  21. data/lib/rubocop/cop/correctors/punctuation_corrector.rb +1 -1
  22. data/lib/rubocop/cop/correctors/unused_arg_corrector.rb +15 -18
  23. data/lib/rubocop/cop/force.rb +1 -0
  24. data/lib/rubocop/cop/gemspec/required_ruby_version.rb +32 -11
  25. data/lib/rubocop/cop/generator/configuration_injector.rb +2 -2
  26. data/lib/rubocop/cop/internal_affairs/method_name_equal.rb +4 -12
  27. data/lib/rubocop/cop/internal_affairs/node_destructuring.rb +1 -1
  28. data/lib/rubocop/cop/internal_affairs/offense_location_keyword.rb +8 -8
  29. data/lib/rubocop/cop/internal_affairs/redundant_location_argument.rb +10 -7
  30. data/lib/rubocop/cop/internal_affairs/redundant_message_argument.rb +7 -8
  31. data/lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +2 -2
  32. data/lib/rubocop/cop/layout/block_alignment.rb +1 -1
  33. data/lib/rubocop/cop/layout/empty_lines.rb +0 -2
  34. data/lib/rubocop/cop/layout/extra_spacing.rb +9 -16
  35. data/lib/rubocop/cop/layout/first_method_argument_line_break.rb +1 -1
  36. data/lib/rubocop/cop/layout/heredoc_indentation.rb +2 -2
  37. data/lib/rubocop/cop/layout/indentation_style.rb +0 -2
  38. data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +1 -1
  39. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +0 -2
  40. data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +9 -1
  41. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +7 -4
  42. data/lib/rubocop/cop/lint/ambiguous_operator.rb +15 -10
  43. data/lib/rubocop/cop/lint/ambiguous_regexp_literal.rb +11 -13
  44. data/lib/rubocop/cop/lint/assignment_in_condition.rb +2 -2
  45. data/lib/rubocop/cop/lint/big_decimal_new.rb +10 -10
  46. data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +49 -0
  47. data/lib/rubocop/cop/lint/boolean_symbol.rb +16 -11
  48. data/lib/rubocop/cop/lint/circular_argument_reference.rb +1 -1
  49. data/lib/rubocop/cop/lint/constant_resolution.rb +1 -1
  50. data/lib/rubocop/cop/lint/debugger.rb +7 -1
  51. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +9 -10
  52. data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +17 -13
  53. data/lib/rubocop/cop/lint/duplicate_case_condition.rb +1 -1
  54. data/lib/rubocop/cop/lint/duplicate_hash_key.rb +1 -1
  55. data/lib/rubocop/cop/lint/duplicate_methods.rb +7 -4
  56. data/lib/rubocop/cop/lint/duplicate_rescue_exception.rb +60 -0
  57. data/lib/rubocop/cop/lint/each_with_object_argument.rb +1 -1
  58. data/lib/rubocop/cop/lint/else_layout.rb +1 -1
  59. data/lib/rubocop/cop/lint/empty_conditional_body.rb +67 -0
  60. data/lib/rubocop/cop/lint/empty_ensure.rb +5 -5
  61. data/lib/rubocop/cop/lint/empty_expression.rb +2 -2
  62. data/lib/rubocop/cop/lint/empty_interpolation.rb +5 -6
  63. data/lib/rubocop/cop/lint/empty_when.rb +2 -2
  64. data/lib/rubocop/cop/lint/ensure_return.rb +27 -29
  65. data/lib/rubocop/cop/lint/erb_new_arguments.rb +11 -10
  66. data/lib/rubocop/cop/lint/flip_flop.rb +1 -1
  67. data/lib/rubocop/cop/lint/float_comparison.rb +93 -0
  68. data/lib/rubocop/cop/lint/float_out_of_range.rb +1 -1
  69. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +5 -4
  70. data/lib/rubocop/cop/lint/heredoc_method_call_position.rb +13 -14
  71. data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +2 -2
  72. data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +8 -8
  73. data/lib/rubocop/cop/lint/inherit_exception.rb +12 -7
  74. data/lib/rubocop/cop/lint/interpolation_check.rb +18 -15
  75. data/lib/rubocop/cop/lint/literal_as_condition.rb +4 -2
  76. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +7 -7
  77. data/lib/rubocop/cop/lint/loop.rb +23 -2
  78. data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +6 -5
  79. data/lib/rubocop/cop/lint/missing_super.rb +99 -0
  80. data/lib/rubocop/cop/lint/mixed_regexp_capture_types.rb +1 -1
  81. data/lib/rubocop/cop/lint/multiple_comparison.rb +6 -9
  82. data/lib/rubocop/cop/lint/nested_method_definition.rb +1 -1
  83. data/lib/rubocop/cop/lint/nested_percent_literal.rb +1 -1
  84. data/lib/rubocop/cop/lint/next_without_accumulator.rb +1 -1
  85. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +27 -23
  86. data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +2 -2
  87. data/lib/rubocop/cop/lint/number_conversion.rb +6 -9
  88. data/lib/rubocop/cop/lint/ordered_magic_comments.rb +11 -13
  89. data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +61 -0
  90. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +4 -10
  91. data/lib/rubocop/cop/lint/percent_string_array.rb +13 -12
  92. data/lib/rubocop/cop/lint/percent_symbol_array.rb +13 -12
  93. data/lib/rubocop/cop/lint/raise_exception.rb +12 -10
  94. data/lib/rubocop/cop/lint/rand_one.rb +2 -2
  95. data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +2 -2
  96. data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +7 -11
  97. data/lib/rubocop/cop/lint/redundant_require_statement.rb +4 -7
  98. data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +13 -9
  99. data/lib/rubocop/cop/lint/redundant_string_coercion.rb +6 -13
  100. data/lib/rubocop/cop/lint/redundant_with_index.rb +11 -14
  101. data/lib/rubocop/cop/lint/redundant_with_object.rb +11 -14
  102. data/lib/rubocop/cop/lint/regexp_as_condition.rb +4 -6
  103. data/lib/rubocop/cop/lint/require_parentheses.rb +2 -2
  104. data/lib/rubocop/cop/lint/rescue_exception.rb +1 -1
  105. data/lib/rubocop/cop/lint/rescue_type.rb +8 -8
  106. data/lib/rubocop/cop/lint/return_in_void_context.rb +2 -4
  107. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +3 -6
  108. data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +14 -10
  109. data/lib/rubocop/cop/lint/safe_navigation_with_empty.rb +7 -7
  110. data/lib/rubocop/cop/lint/script_permission.rb +10 -7
  111. data/lib/rubocop/cop/lint/self_assignment.rb +78 -0
  112. data/lib/rubocop/cop/lint/send_with_mixin_argument.rb +5 -11
  113. data/lib/rubocop/cop/lint/shadowed_argument.rb +3 -3
  114. data/lib/rubocop/cop/lint/shadowed_exception.rb +2 -2
  115. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +3 -3
  116. data/lib/rubocop/cop/lint/struct_new_override.rb +1 -1
  117. data/lib/rubocop/cop/lint/suppressed_exception.rb +4 -7
  118. data/lib/rubocop/cop/lint/to_json.rb +4 -6
  119. data/lib/rubocop/cop/lint/top_level_return_with_argument.rb +34 -0
  120. data/lib/rubocop/cop/lint/underscore_prefixed_variable_name.rb +4 -4
  121. data/lib/rubocop/cop/lint/unified_integer.rb +4 -6
  122. data/lib/rubocop/cop/lint/unreachable_code.rb +1 -1
  123. data/lib/rubocop/cop/lint/unreachable_loop.rb +174 -0
  124. data/lib/rubocop/cop/lint/unused_block_argument.rb +8 -3
  125. data/lib/rubocop/cop/lint/unused_method_argument.rb +8 -3
  126. data/lib/rubocop/cop/lint/uri_escape_unescape.rb +1 -1
  127. data/lib/rubocop/cop/lint/uri_regexp.rb +11 -31
  128. data/lib/rubocop/cop/lint/useless_access_modifier.rb +25 -15
  129. data/lib/rubocop/cop/lint/useless_assignment.rb +4 -4
  130. data/lib/rubocop/cop/lint/useless_else_without_rescue.rb +6 -15
  131. data/lib/rubocop/cop/lint/useless_setter_call.rb +4 -6
  132. data/lib/rubocop/cop/lint/void.rb +3 -7
  133. data/lib/rubocop/cop/metrics/abc_size.rb +1 -1
  134. data/lib/rubocop/cop/metrics/block_length.rb +2 -2
  135. data/lib/rubocop/cop/metrics/block_nesting.rb +2 -2
  136. data/lib/rubocop/cop/metrics/class_length.rb +2 -2
  137. data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +2 -1
  138. data/lib/rubocop/cop/metrics/method_length.rb +2 -2
  139. data/lib/rubocop/cop/metrics/module_length.rb +2 -2
  140. data/lib/rubocop/cop/metrics/parameter_lists.rb +2 -6
  141. data/lib/rubocop/cop/metrics/perceived_complexity.rb +7 -8
  142. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +48 -5
  143. data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +52 -24
  144. data/lib/rubocop/cop/metrics/utils/repeated_csend_discount.rb +37 -0
  145. data/lib/rubocop/cop/migration/department_name.rb +13 -15
  146. data/lib/rubocop/cop/mixin/array_min_size.rb +1 -1
  147. data/lib/rubocop/cop/mixin/check_line_breakable.rb +1 -1
  148. data/lib/rubocop/cop/mixin/code_length.rb +22 -5
  149. data/lib/rubocop/cop/mixin/enforce_superclass.rb +2 -0
  150. data/lib/rubocop/cop/mixin/method_complexity.rb +10 -2
  151. data/lib/rubocop/cop/mixin/statement_modifier.rb +35 -6
  152. data/lib/rubocop/cop/mixin/surrounding_space.rb +0 -25
  153. data/lib/rubocop/cop/mixin/uncommunicative_name.rb +6 -13
  154. data/lib/rubocop/cop/mixin/unused_argument.rb +4 -6
  155. data/lib/rubocop/cop/naming/accessor_method_name.rb +4 -2
  156. data/lib/rubocop/cop/naming/ascii_identifiers.rb +3 -3
  157. data/lib/rubocop/cop/naming/binary_operator_parameter_name.rb +1 -1
  158. data/lib/rubocop/cop/naming/block_parameter_name.rb +1 -1
  159. data/lib/rubocop/cop/naming/class_and_module_camel_case.rb +2 -2
  160. data/lib/rubocop/cop/naming/constant_name.rb +2 -2
  161. data/lib/rubocop/cop/naming/file_name.rb +3 -3
  162. data/lib/rubocop/cop/naming/heredoc_delimiter_case.rb +2 -2
  163. data/lib/rubocop/cop/naming/heredoc_delimiter_naming.rb +2 -2
  164. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +2 -2
  165. data/lib/rubocop/cop/naming/method_parameter_name.rb +1 -1
  166. data/lib/rubocop/cop/naming/predicate_name.rb +3 -5
  167. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +12 -11
  168. data/lib/rubocop/cop/registry.rb +3 -3
  169. data/lib/rubocop/cop/security/eval.rb +2 -2
  170. data/lib/rubocop/cop/security/json_load.rb +6 -8
  171. data/lib/rubocop/cop/security/marshal_load.rb +2 -4
  172. data/lib/rubocop/cop/security/open.rb +2 -2
  173. data/lib/rubocop/cop/security/yaml_load.rb +6 -6
  174. data/lib/rubocop/cop/style/access_modifier_declarations.rb +11 -1
  175. data/lib/rubocop/cop/style/accessor_grouping.rb +9 -7
  176. data/lib/rubocop/cop/style/alias.rb +7 -3
  177. data/lib/rubocop/cop/style/bisected_attr_accessor.rb +0 -2
  178. data/lib/rubocop/cop/style/case_equality.rb +22 -3
  179. data/lib/rubocop/cop/style/case_like_if.rb +2 -2
  180. data/lib/rubocop/cop/style/colon_method_call.rb +3 -3
  181. data/lib/rubocop/cop/style/conditional_assignment.rb +11 -2
  182. data/lib/rubocop/cop/style/documentation.rb +4 -4
  183. data/lib/rubocop/cop/style/each_with_object.rb +0 -2
  184. data/lib/rubocop/cop/style/empty_method.rb +5 -5
  185. data/lib/rubocop/cop/style/eval_with_location.rb +4 -0
  186. data/lib/rubocop/cop/style/expand_path_arguments.rb +4 -0
  187. data/lib/rubocop/cop/style/explicit_block_argument.rb +102 -0
  188. data/lib/rubocop/cop/style/format_string.rb +4 -0
  189. data/lib/rubocop/cop/style/format_string_token.rb +1 -0
  190. data/lib/rubocop/cop/style/global_std_stream.rb +65 -0
  191. data/lib/rubocop/cop/style/guard_clause.rb +2 -2
  192. data/lib/rubocop/cop/style/hash_as_last_array_item.rb +8 -1
  193. data/lib/rubocop/cop/style/hash_syntax.rb +6 -3
  194. data/lib/rubocop/cop/style/identical_conditional_branches.rb +1 -1
  195. data/lib/rubocop/cop/style/if_inside_else.rb +1 -1
  196. data/lib/rubocop/cop/style/if_unless_modifier.rb +0 -20
  197. data/lib/rubocop/cop/style/infinite_loop.rb +1 -1
  198. data/lib/rubocop/cop/style/inverse_methods.rb +2 -3
  199. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +5 -0
  200. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +1 -1
  201. data/lib/rubocop/cop/style/missing_respond_to_missing.rb +9 -2
  202. data/lib/rubocop/cop/style/multiline_memoization.rb +2 -2
  203. data/lib/rubocop/cop/style/multiline_method_signature.rb +1 -1
  204. data/lib/rubocop/cop/style/numeric_predicate.rb +4 -0
  205. data/lib/rubocop/cop/style/optional_boolean_parameter.rb +42 -0
  206. data/lib/rubocop/cop/style/parallel_assignment.rb +2 -2
  207. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +2 -2
  208. data/lib/rubocop/cop/style/random_with_offset.rb +1 -0
  209. data/lib/rubocop/cop/style/redundant_condition.rb +15 -3
  210. data/lib/rubocop/cop/style/redundant_exception.rb +4 -0
  211. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +9 -9
  212. data/lib/rubocop/cop/style/redundant_sort.rb +25 -10
  213. data/lib/rubocop/cop/style/signal_exception.rb +2 -0
  214. data/lib/rubocop/cop/style/single_argument_dig.rb +54 -0
  215. data/lib/rubocop/cop/style/string_concatenation.rb +92 -0
  216. data/lib/rubocop/cop/style/struct_inheritance.rb +1 -1
  217. data/lib/rubocop/cop/style/symbol_array.rb +1 -1
  218. data/lib/rubocop/cop/style/symbol_proc.rb +1 -1
  219. data/lib/rubocop/cop/style/trailing_method_end_statement.rb +1 -1
  220. data/lib/rubocop/cop/style/zero_length_predicate.rb +10 -6
  221. data/lib/rubocop/cop/team.rb +1 -1
  222. data/lib/rubocop/cop/tokens_util.rb +84 -0
  223. data/lib/rubocop/cop/util.rb +1 -13
  224. data/lib/rubocop/cop/variable_force.rb +0 -2
  225. data/lib/rubocop/cop/variable_force/branch.rb +1 -0
  226. data/lib/rubocop/cop/variable_force/variable.rb +2 -2
  227. data/lib/rubocop/cops_documentation_generator.rb +282 -0
  228. data/lib/rubocop/error.rb +1 -0
  229. data/lib/rubocop/formatter/formatter_set.rb +1 -0
  230. data/lib/rubocop/path_util.rb +19 -4
  231. data/lib/rubocop/rake_task.rb +1 -0
  232. data/lib/rubocop/rspec/expect_offense.rb +1 -1
  233. data/lib/rubocop/target_finder.rb +12 -9
  234. data/lib/rubocop/version.rb +2 -2
  235. metadata +19 -6
  236. data/lib/rubocop/cop/lint/useless_comparison.rb +0 -28
  237. data/lib/rubocop/cop/mixin/parser_diagnostic.rb +0 -37
  238. data/lib/rubocop/cop/mixin/too_many_lines.rb +0 -25
  239. data/lib/rubocop/cop/style/method_missing_super.rb +0 -34
@@ -25,7 +25,7 @@ module RuboCop
25
25
  extend AutoCorrector
26
26
 
27
27
  def on_hash(node)
28
- return unless node.parent&.array_type?
28
+ return unless last_array_item?(node)
29
29
 
30
30
  if braces_style?
31
31
  check_braces(node)
@@ -36,6 +36,13 @@ module RuboCop
36
36
 
37
37
  private
38
38
 
39
+ def last_array_item?(node)
40
+ parent = node.parent
41
+ return false unless parent
42
+
43
+ parent.array_type? && parent.values.last == node
44
+ end
45
+
39
46
  def check_braces(node)
40
47
  return if node.braces?
41
48
 
@@ -62,6 +62,7 @@ module RuboCop
62
62
  MSG_NO_MIXED_KEYS = "Don't mix styles in the same hash."
63
63
  MSG_HASH_ROCKETS = 'Use hash rockets syntax.'
64
64
 
65
+ # rubocop:disable Metrics/PerceivedComplexity, Metrics/AbcSize
65
66
  def on_hash(node)
66
67
  pairs = node.pairs
67
68
 
@@ -73,10 +74,11 @@ module RuboCop
73
74
  ruby19_no_mixed_keys_check(pairs)
74
75
  elsif style == :no_mixed_keys
75
76
  no_mixed_keys_check(pairs)
76
- else
77
+ elsif node.source.include?('=>')
77
78
  ruby19_check(pairs)
78
79
  end
79
80
  end
81
+ # rubocop:enable Metrics/PerceivedComplexity, Metrics/AbcSize
80
82
 
81
83
  def ruby19_check(pairs)
82
84
  check(pairs, '=>', MSG_19) if sym_indices?(pairs)
@@ -174,7 +176,7 @@ module RuboCop
174
176
 
175
177
  corrector.replace(
176
178
  range,
177
- range.source.sub(/^:(.*\S)\s*=>\s*$/, space.to_s + '\1: ')
179
+ range.source.sub(/^:(.*\S)\s*=>\s*$/, "#{space}\\1: ")
178
180
  )
179
181
 
180
182
  hash_node = pair_node.parent
@@ -199,7 +201,8 @@ module RuboCop
199
201
  def autocorrect_hash_rockets(corrector, pair_node)
200
202
  op = pair_node.loc.operator
201
203
 
202
- corrector.wrap(pair_node.key, ':', pair_node.inverse_delimiter(true))
204
+ key_with_hash_rocket = ":#{pair_node.key.source}#{pair_node.inverse_delimiter(true)}"
205
+ corrector.replace(pair_node.key, key_with_hash_rocket)
203
206
  corrector.remove(range_with_surrounding_space(range: op))
204
207
  end
205
208
 
@@ -81,7 +81,7 @@ module RuboCop
81
81
 
82
82
  private
83
83
 
84
- def check_branches(branches) # rubocop:todo Metrics/CyclomaticComplexity
84
+ def check_branches(branches) # rubocop:todo Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
85
85
  # return if any branch is empty. An empty branch can be an `if`
86
86
  # without an `else` or a branch that contains only comments.
87
87
  return if branches.any?(&:nil?)
@@ -61,7 +61,7 @@ module RuboCop
61
61
  class IfInsideElse < Cop
62
62
  MSG = 'Convert `if` nested inside `else` to `elsif`.'
63
63
 
64
- def on_if(node) # rubocop:todo Metrics/CyclomaticComplexity
64
+ def on_if(node)
65
65
  return if node.ternary? || node.unless?
66
66
 
67
67
  else_branch = node.else_branch
@@ -148,26 +148,6 @@ module RuboCop
148
148
  sibling.source_range.first_line == line_no
149
149
  end
150
150
 
151
- def parenthesize?(node)
152
- # Parenthesize corrected expression if changing to modifier-if form
153
- # would change the meaning of the parent expression
154
- # (due to the low operator precedence of modifier-if)
155
- parent = node.parent
156
- return false if parent.nil?
157
- return true if parent.assignment? || parent.operator_keyword?
158
-
159
- node.parent.send_type? && !node.parent.parenthesized?
160
- end
161
-
162
- def to_modifier_form(node)
163
- expression = [node.body.source,
164
- node.keyword,
165
- node.condition.source,
166
- first_line_comment(node)].compact.join(' ')
167
-
168
- parenthesize?(node) ? "(#{expression})" : expression
169
- end
170
-
171
151
  def to_normal_form(node)
172
152
  indentation = ' ' * node.source_range.column
173
153
  <<~RUBY.chomp
@@ -99,7 +99,7 @@ module RuboCop
99
99
  def modifier_replacement(node)
100
100
  body = node.body
101
101
  if node.single_line?
102
- 'loop { ' + body.source + ' }'
102
+ "loop { #{body.source} }"
103
103
  else
104
104
  indentation = body.source_range.source_line[LEADING_SPACE]
105
105
 
@@ -64,12 +64,11 @@ module RuboCop
64
64
  PATTERN
65
65
 
66
66
  def on_send(node)
67
- return if part_of_ignored_node?(node)
68
-
69
67
  inverse_candidate?(node) do |_method_call, lhs, method, rhs|
70
68
  return unless inverse_methods.key?(method)
71
- return if possible_class_hierarchy_check?(lhs, rhs, method)
72
69
  return if negated?(node)
70
+ return if part_of_ignored_node?(node)
71
+ return if possible_class_hierarchy_check?(lhs, rhs, method)
73
72
 
74
73
  add_offense(node,
75
74
  message: format(MSG, method: method,
@@ -60,6 +60,7 @@ module RuboCop
60
60
  call_with_ambiguous_arguments?(node) ||
61
61
  call_in_logical_operators?(node) ||
62
62
  call_in_optional_arguments?(node) ||
63
+ call_in_single_line_inheritance?(node) ||
63
64
  allowed_multiline_call_with_parentheses?(node) ||
64
65
  allowed_chained_call_with_parentheses?(node)
65
66
  end
@@ -86,6 +87,10 @@ module RuboCop
86
87
  (node.parent.optarg_type? || node.parent.kwoptarg_type?)
87
88
  end
88
89
 
90
+ def call_in_single_line_inheritance?(node)
91
+ node.parent&.class_type? && node.parent&.single_line?
92
+ end
93
+
89
94
  def call_with_ambiguous_arguments?(node)
90
95
  call_with_braced_block?(node) ||
91
96
  call_as_argument_or_chain?(node) ||
@@ -18,8 +18,8 @@ module RuboCop
18
18
  'no arguments.'
19
19
 
20
20
  def on_send(node)
21
- return if ineligible_node?(node)
22
21
  return unless !node.arguments? && node.parenthesized?
22
+ return if ineligible_node?(node)
23
23
  return if ignored_method?(node.method_name)
24
24
  return if same_name_assignment?(node)
25
25
 
@@ -36,9 +36,16 @@ module RuboCop
36
36
  private
37
37
 
38
38
  def implements_respond_to_missing?(node)
39
- node.parent.each_child_node(node.type).any? do |sibling|
40
- sibling.method?(:respond_to_missing?)
39
+ return false unless (grand_parent = node.parent.parent)
40
+
41
+ grand_parent.each_descendant(node.type) do |descendant|
42
+ return true if descendant.method?(:respond_to_missing?)
43
+
44
+ child = descendant.children.first
45
+ return true if child.respond_to?(:method?) && child.method?(:respond_to_missing?)
41
46
  end
47
+
48
+ false
42
49
  end
43
50
  end
44
51
  end
@@ -77,13 +77,13 @@ module RuboCop
77
77
  if node_buf.source[node.loc.begin.end_pos] == "\n"
78
78
  'begin'
79
79
  else
80
- "begin\n" + (' ' * (node.loc.column + indent))
80
+ "begin\n#{' ' * (node.loc.column + indent)}"
81
81
  end
82
82
  end
83
83
 
84
84
  def keyword_end_str(node, node_buf)
85
85
  if /[^\s)]/.match?(node_buf.source_line(node.loc.end.line))
86
- "\n" + (' ' * node.loc.column) + 'end'
86
+ "\n#{' ' * node.loc.column}end"
87
87
  else
88
88
  'end'
89
89
  end
@@ -53,7 +53,7 @@ module RuboCop
53
53
  end
54
54
 
55
55
  def max_line_length
56
- config.for_cop('Layout/LineLength')['Max'] || 80
56
+ config.for_cop('Layout/LineLength')['Max'] || 120
57
57
  end
58
58
  end
59
59
  end
@@ -53,7 +53,11 @@ module RuboCop
53
53
  'negative?' => '<'
54
54
  }.freeze
55
55
 
56
+ COMPARISON_METHODS = %i[== > < positive? negative? zero?].to_set.freeze
57
+
56
58
  def on_send(node)
59
+ return unless COMPARISON_METHODS.include?(node.method_name)
60
+
57
61
  numeric, replacement = check(node)
58
62
  return unless numeric
59
63
 
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Style
6
+ # This cop checks for places where keyword arguments can be used instead of
7
+ # boolean arguments when defining methods.
8
+ #
9
+ # @example
10
+ # # bad
11
+ # def some_method(bar = false)
12
+ # puts bar
13
+ # end
14
+ #
15
+ # # bad - common hack before keyword args were introduced
16
+ # def some_method(options = {})
17
+ # bar = options.fetch(:bar, false)
18
+ # puts bar
19
+ # end
20
+ #
21
+ # # good
22
+ # def some_method(bar: false)
23
+ # puts bar
24
+ # end
25
+ #
26
+ class OptionalBooleanParameter < Base
27
+ MSG = 'Use keyword arguments when defining method with boolean argument.'
28
+ BOOLEAN_TYPES = %i[true false].freeze
29
+
30
+ def on_def(node)
31
+ node.arguments.each do |arg|
32
+ next unless arg.optarg_type?
33
+
34
+ _name, value = *arg
35
+ add_offense(arg) if BOOLEAN_TYPES.include?(value.type)
36
+ end
37
+ end
38
+ alias on_defs on_def
39
+ end
40
+ end
41
+ end
42
+ end
@@ -131,8 +131,8 @@ module RuboCop
131
131
  @assignments = assignments
132
132
  end
133
133
 
134
- def tsort_each_node
135
- @assignments.each { |a| yield a }
134
+ def tsort_each_node(&block)
135
+ @assignments.each(&block)
136
136
  end
137
137
 
138
138
  def tsort_each_child(assignment)
@@ -102,12 +102,12 @@ module RuboCop
102
102
  delimiters_regexp = Regexp.union(delimiters)
103
103
  node
104
104
  .children.map { |n| string_source(n) }.compact
105
- .any? { |s| delimiters_regexp.match?(s.scrub) }
105
+ .any? { |s| delimiters_regexp.match?(s) }
106
106
  end
107
107
 
108
108
  def string_source(node)
109
109
  if node.is_a?(String)
110
- node
110
+ node.scrub
111
111
  elsif node.respond_to?(:type) && (node.str_type? || node.sym_type?)
112
112
  node.source
113
113
  end
@@ -56,6 +56,7 @@ module RuboCop
56
56
  PATTERN
57
57
 
58
58
  def on_send(node)
59
+ return unless node.receiver
59
60
  return unless integer_op_rand?(node) ||
60
61
  rand_op_integer?(node) ||
61
62
  rand_modified?(node)
@@ -90,10 +90,10 @@ module RuboCop
90
90
  end
91
91
 
92
92
  def else_source(else_branch)
93
- if else_branch.basic_conditional? &&
94
- else_branch.modifier_form? ||
95
- else_branch.range_type?
93
+ if require_parentheses?(else_branch)
96
94
  "(#{else_branch.source})"
95
+ elsif without_argument_parentheses_method?(else_branch)
96
+ "#{else_branch.method_name}(#{else_branch.arguments.map(&:source).join(', ')})"
97
97
  else
98
98
  else_branch.source
99
99
  end
@@ -118,6 +118,18 @@ module RuboCop
118
118
 
119
119
  corrector.wrap(node.else_branch, '(', ')')
120
120
  end
121
+
122
+ def require_parentheses?(node)
123
+ node.basic_conditional? &&
124
+ node.modifier_form? ||
125
+ node.range_type? ||
126
+ node.rescue_type? ||
127
+ node.respond_to?(:semantic_operator?) && node.semantic_operator?
128
+ end
129
+
130
+ def without_argument_parentheses_method?(node)
131
+ node.send_type? && !node.arguments.empty? && !node.parenthesized?
132
+ end
121
133
  end
122
134
  end
123
135
  end
@@ -23,9 +23,13 @@ module RuboCop
23
23
  MSG_2 = 'Redundant `RuntimeError.new` call can be replaced with ' \
24
24
  'just the message.'
25
25
 
26
+ RAISE_METHODS = %i[raise fail].freeze
27
+
26
28
  # Switch `raise RuntimeError, 'message'` to `raise 'message'`, and
27
29
  # `raise RuntimeError.new('message')` to `raise 'message'`.
28
30
  def on_send(node)
31
+ return unless RAISE_METHODS.include?(node.method_name)
32
+
29
33
  fix_exploded(node) || fix_compact(node)
30
34
  end
31
35
 
@@ -92,18 +92,18 @@ module RuboCop
92
92
 
93
93
  def each_escape(node)
94
94
  pattern_source(node).each_char.with_index.reduce(
95
- [nil, false]
96
- ) do |(previous, within_character_class), (current, index)|
95
+ [nil, 0]
96
+ ) do |(previous, char_class_depth), (current, index)|
97
97
  if previous == '\\'
98
- yield [current, index - 1, within_character_class]
98
+ yield [current, index - 1, !char_class_depth.zero?]
99
99
 
100
- [nil, within_character_class]
101
- elsif previous == '[' && current != ':'
102
- [current, true]
103
- elsif previous != ':' && current == ']'
104
- [current, false]
100
+ [nil, char_class_depth]
101
+ elsif previous == '['
102
+ [current, char_class_depth + 1]
103
+ elsif current == ']'
104
+ [current, char_class_depth - 1]
105
105
  else
106
- [current, within_character_class]
106
+ [current, char_class_depth]
107
107
  end
108
108
  end
109
109
  end
@@ -55,6 +55,8 @@ module RuboCop
55
55
  MSG = 'Use `%<suggestion>s` instead of '\
56
56
  '`%<sorter>s...%<accessor_source>s`.'
57
57
 
58
+ SORT_METHODS = %i[sort sort_by].freeze
59
+
58
60
  def_node_matcher :redundant_sort?, <<~MATCHER
59
61
  {
60
62
  (send $(send _ $:sort ...) ${:last :first})
@@ -71,20 +73,25 @@ module RuboCop
71
73
  }
72
74
  MATCHER
73
75
 
76
+ # rubocop:disable Metrics/AbcSize
74
77
  def on_send(node)
75
- redundant_sort?(node) do |sort_node, sorter, accessor|
76
- range = range_between(
77
- sort_node.loc.selector.begin_pos,
78
- node.loc.expression.end_pos
79
- )
78
+ return unless sort_method?(node)
80
79
 
81
- add_offense(node,
82
- location: range,
83
- message: message(node,
84
- sorter,
85
- accessor))
80
+ if (sort_node, sorter, accessor = redundant_sort?(node.parent))
81
+ ancestor = node.parent
82
+ elsif (sort_node, sorter, accessor = redundant_sort?(node.parent&.parent))
83
+ ancestor = node.parent.parent
84
+ else
85
+ return
86
86
  end
87
+
88
+ add_offense(ancestor,
89
+ location: offense_range(sort_node, ancestor),
90
+ message: message(ancestor,
91
+ sorter,
92
+ accessor))
87
93
  end
94
+ # rubocop:enable Metrics/AbcSize
88
95
 
89
96
  def autocorrect(node)
90
97
  sort_node, sorter, accessor = redundant_sort?(node)
@@ -108,6 +115,14 @@ module RuboCop
108
115
 
109
116
  private
110
117
 
118
+ def sort_method?(node)
119
+ SORT_METHODS.include?(node.method_name)
120
+ end
121
+
122
+ def offense_range(sort_node, ancestor)
123
+ range_between(sort_node.loc.selector.begin_pos, ancestor.loc.expression.end_pos)
124
+ end
125
+
111
126
  def message(node, sorter, accessor)
112
127
  accessor_source = range_between(
113
128
  node.loc.selector.begin_pos,
@@ -191,6 +191,8 @@ module RuboCop
191
191
  end
192
192
 
193
193
  def command_or_kernel_call?(name, node)
194
+ return unless node.method?(name)
195
+
194
196
  node.command?(name) || kernel_call?(node, name)
195
197
  end
196
198