rubocop 1.9.0 → 1.12.1

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 (275) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +14 -14
  3. data/assets/output.html.erb +1 -1
  4. data/config/default.yml +70 -17
  5. data/config/obsoletion.yml +4 -0
  6. data/lib/rubocop.rb +5 -0
  7. data/lib/rubocop/cli/command/execute_runner.rb +1 -1
  8. data/lib/rubocop/cli/command/suggest_extensions.rb +3 -2
  9. data/lib/rubocop/comment_config.rb +43 -94
  10. data/lib/rubocop/config.rb +4 -1
  11. data/lib/rubocop/cop/base.rb +1 -0
  12. data/lib/rubocop/cop/bundler/duplicated_gem.rb +2 -1
  13. data/lib/rubocop/cop/bundler/gem_comment.rb +1 -0
  14. data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +1 -0
  15. data/lib/rubocop/cop/bundler/ordered_gems.rb +1 -0
  16. data/lib/rubocop/cop/correctors/alignment_corrector.rb +3 -6
  17. data/lib/rubocop/cop/exclude_limit.rb +26 -0
  18. data/lib/rubocop/cop/gemspec/date_assignment.rb +57 -0
  19. data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +2 -0
  20. data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +1 -0
  21. data/lib/rubocop/cop/gemspec/required_ruby_version.rb +2 -0
  22. data/lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb +2 -0
  23. data/lib/rubocop/cop/generator.rb +2 -2
  24. data/lib/rubocop/cop/internal_affairs.rb +1 -0
  25. data/lib/rubocop/cop/internal_affairs/example_description.rb +1 -0
  26. data/lib/rubocop/cop/internal_affairs/method_name_equal.rb +1 -0
  27. data/lib/rubocop/cop/internal_affairs/node_destructuring.rb +2 -0
  28. data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +151 -0
  29. data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +1 -0
  30. data/lib/rubocop/cop/internal_affairs/offense_location_keyword.rb +2 -0
  31. data/lib/rubocop/cop/internal_affairs/redundant_described_class_as_subject.rb +1 -0
  32. data/lib/rubocop/cop/internal_affairs/redundant_let_rubocop_config_new.rb +1 -0
  33. data/lib/rubocop/cop/internal_affairs/redundant_location_argument.rb +1 -0
  34. data/lib/rubocop/cop/internal_affairs/redundant_message_argument.rb +3 -0
  35. data/lib/rubocop/cop/internal_affairs/style_detected_api_use.rb +4 -0
  36. data/lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +2 -0
  37. data/lib/rubocop/cop/layout/access_modifier_indentation.rb +11 -8
  38. data/lib/rubocop/cop/layout/argument_alignment.rb +6 -5
  39. data/lib/rubocop/cop/layout/array_alignment.rb +7 -6
  40. data/lib/rubocop/cop/layout/assignment_indentation.rb +6 -3
  41. data/lib/rubocop/cop/layout/block_alignment.rb +1 -0
  42. data/lib/rubocop/cop/layout/block_end_newline.rb +4 -8
  43. data/lib/rubocop/cop/layout/class_structure.rb +1 -0
  44. data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +14 -15
  45. data/lib/rubocop/cop/layout/comment_indentation.rb +16 -16
  46. data/lib/rubocop/cop/layout/else_alignment.rb +9 -6
  47. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +20 -3
  48. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +37 -17
  49. data/lib/rubocop/cop/layout/extra_spacing.rb +2 -2
  50. data/lib/rubocop/cop/layout/first_argument_indentation.rb +27 -7
  51. data/lib/rubocop/cop/layout/first_array_element_indentation.rb +9 -6
  52. data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +22 -15
  53. data/lib/rubocop/cop/layout/first_parameter_indentation.rb +6 -5
  54. data/lib/rubocop/cop/layout/indentation_consistency.rb +9 -6
  55. data/lib/rubocop/cop/layout/indentation_style.rb +27 -30
  56. data/lib/rubocop/cop/layout/indentation_width.rb +20 -9
  57. data/lib/rubocop/cop/layout/line_length.rb +2 -1
  58. data/lib/rubocop/cop/layout/multiline_assignment_layout.rb +26 -0
  59. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +18 -5
  60. data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +10 -5
  61. data/lib/rubocop/cop/layout/parameter_alignment.rb +6 -5
  62. data/lib/rubocop/cop/layout/space_before_block_braces.rb +1 -1
  63. data/lib/rubocop/cop/layout/space_before_brackets.rb +9 -4
  64. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +1 -1
  65. data/lib/rubocop/cop/lint/big_decimal_new.rb +1 -0
  66. data/lib/rubocop/cop/lint/boolean_symbol.rb +1 -0
  67. data/lib/rubocop/cop/lint/constant_definition_in_block.rb +2 -0
  68. data/lib/rubocop/cop/lint/constant_resolution.rb +1 -0
  69. data/lib/rubocop/cop/lint/debugger.rb +60 -14
  70. data/lib/rubocop/cop/lint/deprecated_constants.rb +5 -0
  71. data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +14 -4
  72. data/lib/rubocop/cop/lint/duplicate_branch.rb +1 -1
  73. data/lib/rubocop/cop/lint/duplicate_methods.rb +3 -0
  74. data/lib/rubocop/cop/lint/duplicate_require.rb +3 -2
  75. data/lib/rubocop/cop/lint/each_with_object_argument.rb +1 -0
  76. data/lib/rubocop/cop/lint/else_layout.rb +1 -1
  77. data/lib/rubocop/cop/lint/erb_new_arguments.rb +1 -0
  78. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +1 -0
  79. data/lib/rubocop/cop/lint/hash_compare_by_identity.rb +1 -0
  80. data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +1 -0
  81. data/lib/rubocop/cop/lint/inherit_exception.rb +1 -0
  82. data/lib/rubocop/cop/lint/multiple_comparison.rb +5 -4
  83. data/lib/rubocop/cop/lint/nested_method_definition.rb +3 -0
  84. data/lib/rubocop/cop/lint/next_without_accumulator.rb +1 -0
  85. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +7 -0
  86. data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +3 -0
  87. data/lib/rubocop/cop/lint/number_conversion.rb +11 -2
  88. data/lib/rubocop/cop/lint/raise_exception.rb +2 -0
  89. data/lib/rubocop/cop/lint/rand_one.rb +1 -0
  90. data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +1 -2
  91. data/lib/rubocop/cop/lint/redundant_require_statement.rb +1 -0
  92. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +1 -0
  93. data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +7 -3
  94. data/lib/rubocop/cop/lint/redundant_string_coercion.rb +1 -0
  95. data/lib/rubocop/cop/lint/redundant_with_index.rb +1 -0
  96. data/lib/rubocop/cop/lint/redundant_with_object.rb +1 -0
  97. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +1 -0
  98. data/lib/rubocop/cop/lint/safe_navigation_with_empty.rb +1 -0
  99. data/lib/rubocop/cop/lint/send_with_mixin_argument.rb +1 -0
  100. data/lib/rubocop/cop/lint/shadowed_argument.rb +1 -0
  101. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +1 -0
  102. data/lib/rubocop/cop/lint/struct_new_override.rb +1 -0
  103. data/lib/rubocop/cop/lint/suppressed_exception.rb +44 -1
  104. data/lib/rubocop/cop/lint/symbol_conversion.rb +91 -3
  105. data/lib/rubocop/cop/lint/to_enum_arguments.rb +3 -0
  106. data/lib/rubocop/cop/lint/unified_integer.rb +1 -0
  107. data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +5 -0
  108. data/lib/rubocop/cop/lint/unreachable_code.rb +1 -0
  109. data/lib/rubocop/cop/lint/unreachable_loop.rb +1 -0
  110. data/lib/rubocop/cop/lint/unused_method_argument.rb +1 -0
  111. data/lib/rubocop/cop/lint/uri_escape_unescape.rb +1 -0
  112. data/lib/rubocop/cop/lint/useless_access_modifier.rb +4 -0
  113. data/lib/rubocop/cop/lint/useless_setter_call.rb +1 -0
  114. data/lib/rubocop/cop/lint/useless_times.rb +3 -0
  115. data/lib/rubocop/cop/message_annotator.rb +4 -1
  116. data/lib/rubocop/cop/metrics/block_nesting.rb +2 -2
  117. data/lib/rubocop/cop/metrics/module_length.rb +1 -0
  118. data/lib/rubocop/cop/metrics/parameter_lists.rb +6 -2
  119. data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +6 -4
  120. data/lib/rubocop/cop/metrics/utils/repeated_attribute_discount.rb +2 -0
  121. data/lib/rubocop/cop/mixin/alignment.rb +10 -3
  122. data/lib/rubocop/cop/mixin/check_line_breakable.rb +1 -1
  123. data/lib/rubocop/cop/mixin/code_length.rb +3 -1
  124. data/lib/rubocop/cop/mixin/comments_help.rb +5 -1
  125. data/lib/rubocop/cop/mixin/configurable_max.rb +1 -0
  126. data/lib/rubocop/cop/mixin/def_node.rb +1 -0
  127. data/lib/rubocop/cop/mixin/documentation_comment.rb +1 -1
  128. data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +3 -0
  129. data/lib/rubocop/cop/mixin/empty_parameter.rb +1 -0
  130. data/lib/rubocop/cop/mixin/enforce_superclass.rb +2 -0
  131. data/lib/rubocop/cop/mixin/hash_transform_method.rb +1 -0
  132. data/lib/rubocop/cop/mixin/line_length_help.rb +11 -6
  133. data/lib/rubocop/cop/mixin/method_complexity.rb +4 -1
  134. data/lib/rubocop/cop/mixin/multiline_element_indentation.rb +3 -1
  135. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +4 -23
  136. data/lib/rubocop/cop/mixin/negative_conditional.rb +3 -0
  137. data/lib/rubocop/cop/mixin/preferred_delimiters.rb +3 -3
  138. data/lib/rubocop/cop/mixin/rational_literal.rb +1 -0
  139. data/lib/rubocop/cop/mixin/safe_assignment.rb +5 -0
  140. data/lib/rubocop/cop/mixin/uncommunicative_name.rb +4 -6
  141. data/lib/rubocop/cop/mixin/visibility_help.rb +1 -0
  142. data/lib/rubocop/cop/naming/binary_operator_parameter_name.rb +1 -0
  143. data/lib/rubocop/cop/naming/constant_name.rb +2 -0
  144. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +6 -0
  145. data/lib/rubocop/cop/naming/method_name.rb +3 -0
  146. data/lib/rubocop/cop/naming/predicate_name.rb +1 -0
  147. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +10 -0
  148. data/lib/rubocop/cop/registry.rb +10 -1
  149. data/lib/rubocop/cop/security/eval.rb +1 -0
  150. data/lib/rubocop/cop/security/json_load.rb +1 -0
  151. data/lib/rubocop/cop/security/marshal_load.rb +1 -0
  152. data/lib/rubocop/cop/security/open.rb +1 -0
  153. data/lib/rubocop/cop/security/yaml_load.rb +1 -0
  154. data/lib/rubocop/cop/style/access_modifier_declarations.rb +3 -2
  155. data/lib/rubocop/cop/style/alias.rb +1 -0
  156. data/lib/rubocop/cop/style/and_or.rb +3 -1
  157. data/lib/rubocop/cop/style/arguments_forwarding.rb +3 -0
  158. data/lib/rubocop/cop/style/array_coercion.rb +2 -0
  159. data/lib/rubocop/cop/style/array_join.rb +1 -0
  160. data/lib/rubocop/cop/style/attr.rb +1 -0
  161. data/lib/rubocop/cop/style/bisected_attr_accessor.rb +59 -71
  162. data/lib/rubocop/cop/style/bisected_attr_accessor/macro.rb +62 -0
  163. data/lib/rubocop/cop/style/case_equality.rb +2 -1
  164. data/lib/rubocop/cop/style/case_like_if.rb +15 -4
  165. data/lib/rubocop/cop/style/class_equality_comparison.rb +3 -0
  166. data/lib/rubocop/cop/style/collection_compact.rb +2 -0
  167. data/lib/rubocop/cop/style/colon_method_call.rb +1 -0
  168. data/lib/rubocop/cop/style/command_literal.rb +1 -1
  169. data/lib/rubocop/cop/style/commented_keyword.rb +10 -10
  170. data/lib/rubocop/cop/style/conditional_assignment.rb +2 -0
  171. data/lib/rubocop/cop/style/constant_visibility.rb +28 -0
  172. data/lib/rubocop/cop/style/date_time.rb +3 -0
  173. data/lib/rubocop/cop/style/dir.rb +1 -0
  174. data/lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb +2 -2
  175. data/lib/rubocop/cop/style/documentation.rb +30 -3
  176. data/lib/rubocop/cop/style/documentation_method.rb +1 -0
  177. data/lib/rubocop/cop/style/double_negation.rb +3 -2
  178. data/lib/rubocop/cop/style/each_for_simple_loop.rb +1 -0
  179. data/lib/rubocop/cop/style/each_with_object.rb +1 -0
  180. data/lib/rubocop/cop/style/empty_literal.rb +9 -0
  181. data/lib/rubocop/cop/style/endless_method.rb +1 -0
  182. data/lib/rubocop/cop/style/eval_with_location.rb +90 -28
  183. data/lib/rubocop/cop/style/even_odd.rb +1 -0
  184. data/lib/rubocop/cop/style/expand_path_arguments.rb +3 -0
  185. data/lib/rubocop/cop/style/explicit_block_argument.rb +2 -1
  186. data/lib/rubocop/cop/style/exponential_notation.rb +6 -7
  187. data/lib/rubocop/cop/style/float_division.rb +4 -0
  188. data/lib/rubocop/cop/style/format_string.rb +2 -0
  189. data/lib/rubocop/cop/style/format_string_token.rb +1 -0
  190. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +0 -3
  191. data/lib/rubocop/cop/style/global_std_stream.rb +1 -0
  192. data/lib/rubocop/cop/style/hash_conversion.rb +108 -0
  193. data/lib/rubocop/cop/style/hash_each_methods.rb +1 -0
  194. data/lib/rubocop/cop/style/hash_except.rb +1 -0
  195. data/lib/rubocop/cop/style/hash_like_case.rb +1 -0
  196. data/lib/rubocop/cop/style/hash_syntax.rb +16 -15
  197. data/lib/rubocop/cop/style/hash_transform_keys.rb +4 -0
  198. data/lib/rubocop/cop/style/hash_transform_values.rb +4 -0
  199. data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +37 -11
  200. data/lib/rubocop/cop/style/implicit_runtime_error.rb +1 -0
  201. data/lib/rubocop/cop/style/inverse_methods.rb +2 -0
  202. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +46 -2
  203. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +19 -3
  204. data/lib/rubocop/cop/style/min_max.rb +1 -0
  205. data/lib/rubocop/cop/style/mixin_usage.rb +2 -0
  206. data/lib/rubocop/cop/style/module_function.rb +5 -0
  207. data/lib/rubocop/cop/style/multiline_method_signature.rb +10 -3
  208. data/lib/rubocop/cop/style/multiple_comparison.rb +21 -2
  209. data/lib/rubocop/cop/style/mutable_constant.rb +3 -0
  210. data/lib/rubocop/cop/style/negated_if_else_condition.rb +16 -2
  211. data/lib/rubocop/cop/style/nil_comparison.rb +6 -1
  212. data/lib/rubocop/cop/style/nil_lambda.rb +1 -0
  213. data/lib/rubocop/cop/style/non_nil_check.rb +7 -0
  214. data/lib/rubocop/cop/style/numeric_literals.rb +6 -9
  215. data/lib/rubocop/cop/style/numeric_predicate.rb +4 -1
  216. data/lib/rubocop/cop/style/option_hash.rb +1 -0
  217. data/lib/rubocop/cop/style/or_assignment.rb +2 -0
  218. data/lib/rubocop/cop/style/parallel_assignment.rb +6 -0
  219. data/lib/rubocop/cop/style/parentheses_around_condition.rb +1 -0
  220. data/lib/rubocop/cop/style/proc.rb +1 -0
  221. data/lib/rubocop/cop/style/random_with_offset.rb +5 -0
  222. data/lib/rubocop/cop/style/redundant_assignment.rb +1 -0
  223. data/lib/rubocop/cop/style/redundant_begin.rb +44 -4
  224. data/lib/rubocop/cop/style/redundant_conditional.rb +2 -0
  225. data/lib/rubocop/cop/style/redundant_exception.rb +2 -0
  226. data/lib/rubocop/cop/style/redundant_fetch_block.rb +2 -0
  227. data/lib/rubocop/cop/style/redundant_file_extension_in_require.rb +1 -0
  228. data/lib/rubocop/cop/style/redundant_freeze.rb +1 -0
  229. data/lib/rubocop/cop/style/redundant_parentheses.rb +13 -0
  230. data/lib/rubocop/cop/style/redundant_return.rb +4 -0
  231. data/lib/rubocop/cop/style/redundant_self.rb +7 -3
  232. data/lib/rubocop/cop/style/redundant_self_assignment.rb +2 -0
  233. data/lib/rubocop/cop/style/redundant_sort.rb +1 -0
  234. data/lib/rubocop/cop/style/redundant_sort_by.rb +1 -0
  235. data/lib/rubocop/cop/style/regexp_literal.rb +1 -1
  236. data/lib/rubocop/cop/style/rescue_modifier.rb +17 -14
  237. data/lib/rubocop/cop/style/rescue_standard_error.rb +2 -0
  238. data/lib/rubocop/cop/style/return_nil.rb +6 -0
  239. data/lib/rubocop/cop/style/safe_navigation.rb +2 -0
  240. data/lib/rubocop/cop/style/sample.rb +1 -0
  241. data/lib/rubocop/cop/style/signal_exception.rb +3 -0
  242. data/lib/rubocop/cop/style/single_argument_dig.rb +1 -0
  243. data/lib/rubocop/cop/style/single_line_methods.rb +4 -1
  244. data/lib/rubocop/cop/style/slicing_with_range.rb +1 -0
  245. data/lib/rubocop/cop/style/sole_nested_conditional.rb +20 -4
  246. data/lib/rubocop/cop/style/special_global_vars.rb +3 -3
  247. data/lib/rubocop/cop/style/stderr_puts.rb +1 -0
  248. data/lib/rubocop/cop/style/string_chars.rb +38 -0
  249. data/lib/rubocop/cop/style/string_concatenation.rb +1 -0
  250. data/lib/rubocop/cop/style/string_hash_keys.rb +2 -0
  251. data/lib/rubocop/cop/style/strip.rb +1 -0
  252. data/lib/rubocop/cop/style/struct_inheritance.rb +3 -0
  253. data/lib/rubocop/cop/style/symbol_proc.rb +25 -1
  254. data/lib/rubocop/cop/style/ternary_parentheses.rb +1 -0
  255. data/lib/rubocop/cop/style/trailing_body_on_method_definition.rb +5 -0
  256. data/lib/rubocop/cop/style/trailing_method_end_statement.rb +1 -1
  257. data/lib/rubocop/cop/style/trivial_accessors.rb +1 -0
  258. data/lib/rubocop/cop/style/unless_logical_operators.rb +105 -0
  259. data/lib/rubocop/cop/style/unpack_first.rb +1 -0
  260. data/lib/rubocop/cop/style/yoda_condition.rb +1 -0
  261. data/lib/rubocop/cop/style/zero_length_predicate.rb +5 -0
  262. data/lib/rubocop/cop/util.rb +4 -1
  263. data/lib/rubocop/directive_comment.rb +69 -9
  264. data/lib/rubocop/ext/regexp_parser.rb +3 -6
  265. data/lib/rubocop/formatter/clang_style_formatter.rb +4 -2
  266. data/lib/rubocop/formatter/offense_count_formatter.rb +1 -1
  267. data/lib/rubocop/formatter/simple_text_formatter.rb +2 -1
  268. data/lib/rubocop/formatter/tap_formatter.rb +4 -2
  269. data/lib/rubocop/formatter/worst_offenders_formatter.rb +1 -1
  270. data/lib/rubocop/magic_comment.rb +1 -1
  271. data/lib/rubocop/name_similarity.rb +1 -1
  272. data/lib/rubocop/target_finder.rb +1 -0
  273. data/lib/rubocop/target_ruby.rb +21 -13
  274. data/lib/rubocop/version.rb +1 -1
  275. metadata +14 -7
@@ -81,10 +81,12 @@ module RuboCop
81
81
  MSG_EXPLICIT = 'Avoid rescuing without specifying ' \
82
82
  'an error class.'
83
83
 
84
+ # @!method rescue_without_error_class?(node)
84
85
  def_node_matcher :rescue_without_error_class?, <<~PATTERN
85
86
  (resbody nil? _ _)
86
87
  PATTERN
87
88
 
89
+ # @!method rescue_standard_error?(node)
88
90
  def_node_matcher :rescue_standard_error?, <<~PATTERN
89
91
  (resbody $(array (const {nil? cbase} :StandardError)) _ _)
90
92
  PATTERN
@@ -35,7 +35,10 @@ module RuboCop
35
35
  RETURN_MSG = 'Use `return` instead of `return nil`.'
36
36
  RETURN_NIL_MSG = 'Use `return nil` instead of `return`.'
37
37
 
38
+ # @!method return_node?(node)
38
39
  def_node_matcher :return_node?, '(return)'
40
+
41
+ # @!method return_nil_node?(node)
39
42
  def_node_matcher :return_nil_node?, '(return nil)'
40
43
 
41
44
  def on_return(node)
@@ -79,7 +82,10 @@ module RuboCop
79
82
  node.def_type? || node.defs_type? || node.lambda?
80
83
  end
81
84
 
85
+ # @!method chained_send?(node)
82
86
  def_node_matcher :chained_send?, '(send !nil? ...)'
87
+
88
+ # @!method define_method?(node)
83
89
  def_node_matcher :define_method?, <<~PATTERN
84
90
  (send _ {:define_method :define_singleton_method} _)
85
91
  PATTERN
@@ -74,6 +74,7 @@ module RuboCop
74
74
 
75
75
  # if format: (if checked_variable body nil)
76
76
  # unless format: (if checked_variable nil body)
77
+ # @!method modifier_if_safe_navigation_candidate(node)
77
78
  def_node_matcher :modifier_if_safe_navigation_candidate, <<~PATTERN
78
79
  {
79
80
  (if {
@@ -88,6 +89,7 @@ module RuboCop
88
89
  }
89
90
  PATTERN
90
91
 
92
+ # @!method not_nil_check?(node)
91
93
  def_node_matcher :not_nil_check?, '(send (send $_ :nil?) :!)'
92
94
 
93
95
  def on_if(node)
@@ -33,6 +33,7 @@ module RuboCop
33
33
  MSG = 'Use `%<correct>s` instead of `%<incorrect>s`.'
34
34
  RESTRICT_ON_SEND = %i[first last [] at slice].freeze
35
35
 
36
+ # @!method sample_candidate?(node)
36
37
  def_node_matcher :sample_candidate?, <<~PATTERN
37
38
  (send $(send _ :shuffle $...) ${:#{RESTRICT_ON_SEND.join(' :')}} $...)
38
39
  PATTERN
@@ -114,7 +114,10 @@ module RuboCop
114
114
 
115
115
  RESTRICT_ON_SEND = %i[raise fail].freeze
116
116
 
117
+ # @!method kernel_call?(node, name)
117
118
  def_node_matcher :kernel_call?, '(send (const {nil? cbase} :Kernel) %1 ...)'
119
+
120
+ # @!method custom_fail_methods(node)
118
121
  def_node_search :custom_fail_methods,
119
122
  '{(def :fail ...) (defs _ :fail ...)}'
120
123
 
@@ -29,6 +29,7 @@ module RuboCop
29
29
  MSG = 'Use `%<receiver>s[%<argument>s]` instead of `%<original>s`.'
30
30
  RESTRICT_ON_SEND = %i[dig].freeze
31
31
 
32
+ # @!method single_argument_dig?(node)
32
33
  def_node_matcher :single_argument_dig?, <<~PATTERN
33
34
  (send _ :dig $!splat)
34
35
  PATTERN
@@ -63,6 +63,8 @@ module RuboCop
63
63
  end
64
64
 
65
65
  def correct_to_endless?(body_node)
66
+ return false if target_ruby_version < 3.0
67
+
66
68
  endless_method_config = config.for_cop('Style/EndlessMethod')
67
69
 
68
70
  return false unless endless_method_config['Enabled']
@@ -89,8 +91,9 @@ module RuboCop
89
91
  end
90
92
 
91
93
  def correct_to_endless(corrector, node)
94
+ self_receiver = node.self_receiver? ? 'self.' : ''
92
95
  arguments = node.arguments.any? ? node.arguments.source : '()'
93
- replacement = "def #{node.method_name}#{arguments} = #{node.body.source}"
96
+ replacement = "def #{self_receiver}#{node.method_name}#{arguments} = #{node.body.source}"
94
97
  corrector.replace(node, replacement)
95
98
  end
96
99
 
@@ -21,6 +21,7 @@ module RuboCop
21
21
  MSG = 'Prefer ary[n..] over ary[n..-1].'
22
22
  RESTRICT_ON_SEND = %i[[]].freeze
23
23
 
24
+ # @!method range_till_minus_one?(node)
24
25
  def_node_matcher :range_till_minus_one?, '(irange !nil? (int -1))'
25
26
 
26
27
  def on_send(node)
@@ -43,6 +43,7 @@ module RuboCop
43
43
  return if node.ternary? || node.else? || node.elsif?
44
44
 
45
45
  if_branch = node.if_branch
46
+ return if use_variable_assignment_in_condition?(node.condition, if_branch)
46
47
  return unless offending_branch?(if_branch)
47
48
 
48
49
  message = format(MSG, conditional_type: node.keyword)
@@ -53,6 +54,21 @@ module RuboCop
53
54
 
54
55
  private
55
56
 
57
+ def use_variable_assignment_in_condition?(condition, if_branch)
58
+ assigned_variables = assigned_variables(condition)
59
+
60
+ assigned_variables && if_branch&.if_type? &&
61
+ assigned_variables.include?(if_branch.condition.source)
62
+ end
63
+
64
+ def assigned_variables(condition)
65
+ assigned_variables = condition.assignment? ? [condition.children.first.to_s] : []
66
+
67
+ assigned_variables + condition.descendants.select(&:assignment?).map do |node|
68
+ node.children.first.to_s
69
+ end
70
+ end
71
+
56
72
  def offending_branch?(branch)
57
73
  return false unless branch
58
74
 
@@ -112,11 +128,11 @@ module RuboCop
112
128
  def correct_outer_condition(corrector, condition)
113
129
  return unless requrie_parentheses?(condition)
114
130
 
115
- range = range_between(
116
- condition.loc.selector.end_pos, condition.first_argument.source_range.begin_pos
117
- )
131
+ end_pos = condition.loc.selector.end_pos
132
+ begin_pos = condition.first_argument.source_range.begin_pos
133
+ return if end_pos > begin_pos
118
134
 
119
- corrector.replace(range, '(')
135
+ corrector.replace(range_between(end_pos, begin_pos), '(')
120
136
  corrector.insert_after(condition.last_argument.source_range, ')')
121
137
  end
122
138
 
@@ -81,13 +81,13 @@ module RuboCop
81
81
  }
82
82
 
83
83
  PERL_VARS =
84
- Hash[ENGLISH_VARS.flat_map { |k, vs| vs.map { |v| [v, [k]] } }]
84
+ ENGLISH_VARS.flat_map { |k, vs| vs.map { |v| [v, [k]] } }.to_h
85
85
 
86
86
  ENGLISH_VARS.merge!(
87
- Hash[ENGLISH_VARS.flat_map { |_, vs| vs.map { |v| [v, [v]] } }]
87
+ ENGLISH_VARS.flat_map { |_, vs| vs.map { |v| [v, [v]] } }.to_h
88
88
  )
89
89
  PERL_VARS.merge!(
90
- Hash[PERL_VARS.flat_map { |_, vs| vs.map { |v| [v, [v]] } }]
90
+ PERL_VARS.flat_map { |_, vs| vs.map { |v| [v, [v]] } }.to_h
91
91
  )
92
92
  ENGLISH_VARS.each_value(&:freeze).freeze
93
93
  PERL_VARS.each_value(&:freeze).freeze
@@ -22,6 +22,7 @@ module RuboCop
22
22
  'Use `warn` instead of `%<bad>s` to allow such output to be disabled.'
23
23
  RESTRICT_ON_SEND = %i[puts].freeze
24
24
 
25
+ # @!method stderr_puts?(node)
25
26
  def_node_matcher :stderr_puts?, <<~PATTERN
26
27
  (send
27
28
  {(gvar #stderr_gvar?) (const {nil? cbase} :STDERR)}
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Style
6
+ # Checks for uses of `String#split` with empty string or regexp literal argument.
7
+ #
8
+ # This cop is marked as unsafe. But probably it's quite unlikely that some other class would
9
+ # define a `split` method that takes exactly the same arguments.
10
+ #
11
+ # @example
12
+ # # bad
13
+ # string.split(//)
14
+ # string.split('')
15
+ #
16
+ # # good
17
+ # string.chars
18
+ #
19
+ class StringChars < Base
20
+ extend AutoCorrector
21
+
22
+ MSG = 'Use `chars` instead of `%<current>s`.'
23
+ RESTRICT_ON_SEND = %i[split].freeze
24
+ BAD_ARGUMENTS = %w[// '' ""].freeze
25
+
26
+ def on_send(node)
27
+ return unless node.arguments.one? && BAD_ARGUMENTS.include?(node.first_argument.source)
28
+
29
+ range = node.loc.selector.begin.join(node.loc.end)
30
+
31
+ add_offense(range, message: format(MSG, current: range.source)) do |corrector|
32
+ corrector.replace(range, 'chars')
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -34,6 +34,7 @@ module RuboCop
34
34
  MSG = 'Prefer string interpolation to string concatenation.'
35
35
  RESTRICT_ON_SEND = %i[+].freeze
36
36
 
37
+ # @!method string_concatenation?(node)
37
38
  def_node_matcher :string_concatenation?, <<~PATTERN
38
39
  {
39
40
  (send str_type? :+ _)
@@ -17,10 +17,12 @@ module RuboCop
17
17
 
18
18
  MSG = 'Prefer symbols instead of strings as hash keys.'
19
19
 
20
+ # @!method string_hash_key?(node)
20
21
  def_node_matcher :string_hash_key?, <<~PATTERN
21
22
  (pair (str _) _)
22
23
  PATTERN
23
24
 
25
+ # @!method receive_environments_method?(node)
24
26
  def_node_matcher :receive_environments_method?, <<~PATTERN
25
27
  {
26
28
  ^^(send (const {nil? cbase} :IO) :popen ...)
@@ -20,6 +20,7 @@ module RuboCop
20
20
  MSG = 'Use `strip` instead of `%<methods>s`.'
21
21
  RESTRICT_ON_SEND = %i[lstrip rstrip].freeze
22
22
 
23
+ # @!method lstrip_rstrip(node)
23
24
  def_node_matcher :lstrip_rstrip, <<~PATTERN
24
25
  {(send $(send _ $:rstrip) $:lstrip)
25
26
  (send $(send _ $:lstrip) $:rstrip)}
@@ -37,6 +37,7 @@ module RuboCop
37
37
  end
38
38
  end
39
39
 
40
+ # @!method struct_constructor?(node)
40
41
  def_node_matcher :struct_constructor?, <<~PATTERN
41
42
  {(send (const {nil? cbase} :Struct) :new ...)
42
43
  (block (send (const {nil? cbase} :Struct) :new ...) ...)}
@@ -47,6 +48,8 @@ module RuboCop
47
48
  def correct_parent(parent, corrector)
48
49
  if parent.block_type?
49
50
  corrector.remove(range_with_surrounding_space(range: parent.loc.end, newlines: false))
51
+ elsif (class_node = parent.parent).body.nil?
52
+ corrector.remove(range_by_whole_lines(class_node.loc.end, include_final_newline: true))
50
53
  else
51
54
  corrector.insert_after(parent.loc.expression, ' do')
52
55
  end
@@ -5,6 +5,9 @@ module RuboCop
5
5
  module Style
6
6
  # Use symbols as procs when possible.
7
7
  #
8
+ # If you prefer a style that allows block for method with arguments,
9
+ # please set `true` to `AllowMethodsWithArguments`.
10
+ #
8
11
  # @example
9
12
  # # bad
10
13
  # something.map { |s| s.upcase }
@@ -12,6 +15,17 @@ module RuboCop
12
15
  #
13
16
  # # good
14
17
  # something.map(&:upcase)
18
+ #
19
+ # @example AllowMethodsWithArguments: false (default)
20
+ # # bad
21
+ # something.do_something(foo) { |o| o.bar }
22
+ #
23
+ # # good
24
+ # something.do_something(foo, &:bar)
25
+ #
26
+ # @example AllowMethodsWithArguments: true
27
+ # # good
28
+ # something.do_something(foo) { |o| o.bar }
15
29
  class SymbolProc < Base
16
30
  include RangeHelp
17
31
  include IgnoredMethods
@@ -21,8 +35,13 @@ module RuboCop
21
35
  'instead of a block.'
22
36
  SUPER_TYPES = %i[super zsuper].freeze
23
37
 
38
+ # @!method proc_node?(node)
24
39
  def_node_matcher :proc_node?, '(send (const {nil? cbase} :Proc) :new)'
40
+
41
+ # @!method symbol_proc_receiver?(node)
25
42
  def_node_matcher :symbol_proc_receiver?, '{(send ...) (super ...) zsuper}'
43
+
44
+ # @!method symbol_proc?(node)
26
45
  def_node_matcher :symbol_proc?, <<~PATTERN
27
46
  {
28
47
  (block $#symbol_proc_receiver? $(args (arg _var)) (send (lvar _var) $_))
@@ -37,11 +56,12 @@ module RuboCop
37
56
  def on_block(node)
38
57
  symbol_proc?(node) do |dispatch_node, arguments_node, method_name|
39
58
  # TODO: Rails-specific handling that we should probably make
40
- # configurable - https://github.com/rubocop-hq/rubocop/issues/1485
59
+ # configurable - https://github.com/rubocop/rubocop/issues/1485
41
60
  # we should ignore lambdas & procs
42
61
  return if proc_node?(dispatch_node)
43
62
  return if %i[lambda proc].include?(dispatch_node.method_name)
44
63
  return if ignored_method?(dispatch_node.method_name)
64
+ return if allow_if_method_has_argument?(node)
45
65
  return if node.block_type? && destructuring_block_argument?(arguments_node)
46
66
 
47
67
  register_offense(node, method_name, dispatch_node.method_name)
@@ -103,6 +123,10 @@ module RuboCop
103
123
  node.loc.begin.begin_pos
104
124
  end
105
125
  end
126
+
127
+ def allow_if_method_has_argument?(node)
128
+ !!cop_config.fetch('AllowMethodsWithArguments', false) && !node.arguments.count.zero?
129
+ end
106
130
  end
107
131
  end
108
132
  end
@@ -191,6 +191,7 @@ module RuboCop
191
191
  (child.send_type? && child.prefix_not?)
192
192
  end
193
193
 
194
+ # @!method method_name(node)
194
195
  def_node_matcher :method_name, <<~PATTERN
195
196
  {($:defined? _ ...)
196
197
  (send {_ nil?} $_ _ ...)}
@@ -5,6 +5,8 @@ module RuboCop
5
5
  module Style
6
6
  # This cop checks for trailing code after the method definition.
7
7
  #
8
+ # NOTE: It always accepts endless method definitions that are basically on the same line.
9
+ #
8
10
  # @example
9
11
  # # bad
10
12
  # def some_method; do_stuff
@@ -24,6 +26,8 @@ module RuboCop
24
26
  # b[c: x]
25
27
  # end
26
28
  #
29
+ # def endless_method = do_stuff
30
+ #
27
31
  class TrailingBodyOnMethodDefinition < Base
28
32
  include Alignment
29
33
  include TrailingBody
@@ -34,6 +38,7 @@ module RuboCop
34
38
 
35
39
  def on_def(node)
36
40
  return unless trailing_body?(node)
41
+ return if node.endless?
37
42
 
38
43
  add_offense(first_part_of(node.body)) do |corrector|
39
44
  LineBreakCorrector.correct_trailing_body(
@@ -40,7 +40,7 @@ module RuboCop
40
40
  'its own line.'
41
41
 
42
42
  def on_def(node)
43
- return unless trailing_end?(node)
43
+ return if node.endless? || !trailing_end?(node)
44
44
 
45
45
  add_offense(node.loc.end) do |corrector|
46
46
  corrector.insert_before(
@@ -120,6 +120,7 @@ module RuboCop
120
120
  !allowed_method_name?(node) && !allowed_writer?(node.method_name)
121
121
  end
122
122
 
123
+ # @!method looks_like_trivial_writer?(node)
123
124
  def_node_matcher :looks_like_trivial_writer?, <<~PATTERN
124
125
  {(def _ (args (arg ...)) (ivasgn _ (lvar _)))
125
126
  (defs _ _ (args (arg ...)) (ivasgn _ (lvar _)))}
@@ -0,0 +1,105 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Style
6
+ # This cop checks for the use of logical operators in an `unless` condition.
7
+ # It discourages such code, as the condition becomes more difficult
8
+ # to read and understand.
9
+ #
10
+ # This cop supports two styles:
11
+ # - `forbid_mixed_logical_operators` (default)
12
+ # - `forbid_logical_operators`
13
+ #
14
+ # `forbid_mixed_logical_operators` style forbids the use of more than one type
15
+ # of logical operators. This makes the `unless` condition easier to read
16
+ # because either all conditions need to be met or any condition need to be met
17
+ # in order for the expression to be truthy or falsey.
18
+ #
19
+ # `forbid_logical_operators` style forbids any use of logical operator.
20
+ # This makes it even more easy to read the `unless` condition as
21
+ # there is only one condition in the expression.
22
+ #
23
+ # @example EnforcedStyle: forbid_mixed_logical_operators (default)
24
+ # # bad
25
+ # return unless a || b && c
26
+ # return unless a && b || c
27
+ # return unless a && b and c
28
+ # return unless a || b or c
29
+ # return unless a && b or c
30
+ # return unless a || b and c
31
+ #
32
+ # # good
33
+ # return unless a && b && c
34
+ # return unless a || b || c
35
+ # return unless a and b and c
36
+ # return unless a or b or c
37
+ # return unless a?
38
+ #
39
+ # @example EnforcedStyle: forbid_logical_operators
40
+ # # bad
41
+ # return unless a || b
42
+ # return unless a && b
43
+ # return unless a or b
44
+ # return unless a and b
45
+ #
46
+ # # good
47
+ # return unless a
48
+ # return unless a?
49
+ class UnlessLogicalOperators < Base
50
+ include ConfigurableEnforcedStyle
51
+
52
+ FORBID_MIXED_LOGICAL_OPERATORS = 'Do not use mixed logical operators in an `unless`.'
53
+ FORBID_LOGICAL_OPERATORS = 'Do not use any logical operator in an `unless`.'
54
+
55
+ # @!method or_with_and?(node)
56
+ def_node_matcher :or_with_and?, <<~PATTERN
57
+ (if (or <`and ...> ) ...)
58
+ PATTERN
59
+
60
+ # @!method and_with_or?(node)
61
+ def_node_matcher :and_with_or?, <<~PATTERN
62
+ (if (and <`or ...> ) ...)
63
+ PATTERN
64
+
65
+ # @!method logical_operator?(node)
66
+ def_node_matcher :logical_operator?, <<~PATTERN
67
+ (if ({and or} ... ) ...)
68
+ PATTERN
69
+
70
+ def on_if(node)
71
+ return unless node.unless?
72
+
73
+ if style == :forbid_mixed_logical_operators && mixed_logical_operator?(node)
74
+ add_offense(node, message: FORBID_MIXED_LOGICAL_OPERATORS)
75
+ elsif style == :forbid_logical_operators && logical_operator?(node)
76
+ add_offense(node, message: FORBID_LOGICAL_OPERATORS)
77
+ end
78
+ end
79
+
80
+ private
81
+
82
+ def mixed_logical_operator?(node)
83
+ or_with_and?(node) ||
84
+ and_with_or?(node) ||
85
+ mixed_precedence_and?(node) ||
86
+ mixed_precedence_or?(node)
87
+ end
88
+
89
+ def mixed_precedence_and?(node)
90
+ and_sources = node.condition.each_descendant(:and).map(&:operator)
91
+ and_sources << node.condition.operator if node.condition.and_type?
92
+
93
+ !(and_sources.all? { |s| s == '&&' } || and_sources.all? { |s| s == 'and' })
94
+ end
95
+
96
+ def mixed_precedence_or?(node)
97
+ or_sources = node.condition.each_descendant(:or).map(&:operator)
98
+ or_sources << node.condition.operator if node.condition.or_type?
99
+
100
+ !(or_sources.all? { |s| s == '||' } || or_sources.all? { |s| s == 'or' })
101
+ end
102
+ end
103
+ end
104
+ end
105
+ end