rubocop 1.31.1 → 1.51.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 (462) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +5 -5
  4. data/config/default.yml +342 -52
  5. data/config/obsoletion.yml +23 -1
  6. data/exe/rubocop +1 -1
  7. data/lib/rubocop/arguments_env.rb +17 -0
  8. data/lib/rubocop/arguments_file.rb +17 -0
  9. data/lib/rubocop/cache_config.rb +29 -0
  10. data/lib/rubocop/cli/command/{auto_genenerate_config.rb → auto_generate_config.rb} +9 -2
  11. data/lib/rubocop/cli/command/execute_runner.rb +14 -9
  12. data/lib/rubocop/cli/command/init_dotfile.rb +1 -1
  13. data/lib/rubocop/cli/command/suggest_extensions.rb +61 -16
  14. data/lib/rubocop/cli.rb +56 -9
  15. data/lib/rubocop/comment_config.rb +60 -1
  16. data/lib/rubocop/config.rb +48 -20
  17. data/lib/rubocop/config_finder.rb +68 -0
  18. data/lib/rubocop/config_loader.rb +46 -68
  19. data/lib/rubocop/config_loader_resolver.rb +11 -12
  20. data/lib/rubocop/config_obsoletion/changed_parameter.rb +5 -0
  21. data/lib/rubocop/config_obsoletion/parameter_rule.rb +4 -0
  22. data/lib/rubocop/config_obsoletion.rb +9 -4
  23. data/lib/rubocop/config_validator.rb +1 -1
  24. data/lib/rubocop/cop/autocorrect_logic.rb +29 -13
  25. data/lib/rubocop/cop/badge.rb +9 -4
  26. data/lib/rubocop/cop/base.rb +115 -83
  27. data/lib/rubocop/cop/bundler/gem_comment.rb +1 -1
  28. data/lib/rubocop/cop/commissioner.rb +19 -6
  29. data/lib/rubocop/cop/cop.rb +54 -34
  30. data/lib/rubocop/cop/corrector.rb +31 -11
  31. data/lib/rubocop/cop/correctors/alignment_corrector.rb +3 -3
  32. data/lib/rubocop/cop/correctors/each_to_for_corrector.rb +3 -3
  33. data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +3 -3
  34. data/lib/rubocop/cop/correctors/line_break_corrector.rb +1 -1
  35. data/lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +23 -7
  36. data/lib/rubocop/cop/correctors/ordered_gem_corrector.rb +2 -7
  37. data/lib/rubocop/cop/correctors/parentheses_corrector.rb +58 -0
  38. data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +2 -2
  39. data/lib/rubocop/cop/gemspec/dependency_version.rb +17 -19
  40. data/lib/rubocop/cop/gemspec/deprecated_attribute_assignment.rb +1 -1
  41. data/lib/rubocop/cop/gemspec/development_dependencies.rb +107 -0
  42. data/lib/rubocop/cop/gemspec/require_mfa.rb +1 -1
  43. data/lib/rubocop/cop/generator/require_file_injector.rb +2 -2
  44. data/lib/rubocop/cop/generator.rb +5 -2
  45. data/lib/rubocop/cop/internal_affairs/cop_description.rb +8 -6
  46. data/lib/rubocop/cop/internal_affairs/create_empty_file.rb +37 -0
  47. data/lib/rubocop/cop/internal_affairs/example_heredoc_delimiter.rb +111 -0
  48. data/lib/rubocop/cop/internal_affairs/inherit_deprecated_cop_class.rb +1 -1
  49. data/lib/rubocop/cop/internal_affairs/lambda_or_proc.rb +46 -0
  50. data/lib/rubocop/cop/internal_affairs/location_expression.rb +37 -0
  51. data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +3 -3
  52. data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +1 -1
  53. data/lib/rubocop/cop/internal_affairs/numblock_handler.rb +69 -0
  54. data/lib/rubocop/cop/internal_affairs/processed_source_buffer_name.rb +42 -0
  55. data/lib/rubocop/cop/internal_affairs/redundant_let_rubocop_config_new.rb +11 -3
  56. data/lib/rubocop/cop/internal_affairs/redundant_location_argument.rb +1 -1
  57. data/lib/rubocop/cop/internal_affairs/redundant_message_argument.rb +1 -1
  58. data/lib/rubocop/cop/internal_affairs/redundant_source_range.rb +66 -0
  59. data/lib/rubocop/cop/internal_affairs/single_line_comparison.rb +62 -0
  60. data/lib/rubocop/cop/internal_affairs/useless_restrict_on_send.rb +60 -0
  61. data/lib/rubocop/cop/internal_affairs.rb +9 -0
  62. data/lib/rubocop/cop/layout/array_alignment.rb +1 -1
  63. data/lib/rubocop/cop/layout/block_alignment.rb +16 -12
  64. data/lib/rubocop/cop/layout/block_end_newline.rb +31 -9
  65. data/lib/rubocop/cop/layout/class_structure.rb +37 -27
  66. data/lib/rubocop/cop/layout/closing_heredoc_indentation.rb +1 -1
  67. data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +2 -6
  68. data/lib/rubocop/cop/layout/comment_indentation.rb +3 -1
  69. data/lib/rubocop/cop/layout/empty_comment.rb +3 -3
  70. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +1 -1
  71. data/lib/rubocop/cop/layout/empty_lines.rb +3 -1
  72. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +7 -2
  73. data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +2 -0
  74. data/lib/rubocop/cop/layout/end_alignment.rb +9 -1
  75. data/lib/rubocop/cop/layout/end_of_line.rb +4 -4
  76. data/lib/rubocop/cop/layout/extra_spacing.rb +15 -6
  77. data/lib/rubocop/cop/layout/first_argument_indentation.rb +15 -4
  78. data/lib/rubocop/cop/layout/first_array_element_indentation.rb +6 -5
  79. data/lib/rubocop/cop/layout/first_array_element_line_break.rb +35 -8
  80. data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +5 -5
  81. data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +36 -1
  82. data/lib/rubocop/cop/layout/first_method_argument_line_break.rb +57 -8
  83. data/lib/rubocop/cop/layout/first_method_parameter_line_break.rb +52 -19
  84. data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +10 -4
  85. data/lib/rubocop/cop/layout/heredoc_indentation.rb +8 -11
  86. data/lib/rubocop/cop/layout/indentation_style.rb +7 -2
  87. data/lib/rubocop/cop/layout/indentation_width.rb +6 -2
  88. data/lib/rubocop/cop/layout/initial_indentation.rb +1 -1
  89. data/lib/rubocop/cop/layout/leading_comment_space.rb +1 -1
  90. data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +80 -12
  91. data/lib/rubocop/cop/layout/line_continuation_spacing.rb +18 -8
  92. data/lib/rubocop/cop/layout/line_length.rb +8 -1
  93. data/lib/rubocop/cop/layout/multiline_array_line_breaks.rb +31 -1
  94. data/lib/rubocop/cop/layout/multiline_assignment_layout.rb +1 -1
  95. data/lib/rubocop/cop/layout/multiline_block_layout.rb +3 -1
  96. data/lib/rubocop/cop/layout/multiline_hash_key_line_breaks.rb +29 -1
  97. data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +39 -2
  98. data/lib/rubocop/cop/layout/multiline_method_parameter_line_breaks.rb +77 -0
  99. data/lib/rubocop/cop/layout/redundant_line_break.rb +9 -10
  100. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +2 -2
  101. data/lib/rubocop/cop/layout/space_around_block_parameters.rb +1 -1
  102. data/lib/rubocop/cop/layout/space_around_keyword.rb +3 -3
  103. data/lib/rubocop/cop/layout/space_around_operators.rb +1 -1
  104. data/lib/rubocop/cop/layout/space_before_block_braces.rb +2 -0
  105. data/lib/rubocop/cop/layout/space_before_first_arg.rb +1 -1
  106. data/lib/rubocop/cop/layout/space_in_lambda_literal.rb +2 -2
  107. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +22 -20
  108. data/lib/rubocop/cop/layout/space_inside_array_percent_literal.rb +3 -0
  109. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +27 -9
  110. data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +30 -3
  111. data/lib/rubocop/cop/layout/space_inside_parens.rb +2 -2
  112. data/lib/rubocop/cop/layout/space_inside_percent_literal_delimiters.rb +34 -0
  113. data/lib/rubocop/cop/layout/space_inside_reference_brackets.rb +10 -6
  114. data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +5 -4
  115. data/lib/rubocop/cop/layout/trailing_empty_lines.rb +1 -1
  116. data/lib/rubocop/cop/layout/trailing_whitespace.rb +12 -5
  117. data/lib/rubocop/cop/legacy/corrections_proxy.rb +1 -1
  118. data/lib/rubocop/cop/legacy/corrector.rb +1 -1
  119. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +39 -8
  120. data/lib/rubocop/cop/lint/ambiguous_operator.rb +4 -0
  121. data/lib/rubocop/cop/lint/assignment_in_condition.rb +11 -1
  122. data/lib/rubocop/cop/lint/constant_resolution.rb +5 -1
  123. data/lib/rubocop/cop/lint/debugger.rb +27 -31
  124. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +66 -110
  125. data/lib/rubocop/cop/lint/deprecated_constants.rb +8 -1
  126. data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +1 -1
  127. data/lib/rubocop/cop/lint/duplicate_branch.rb +0 -2
  128. data/lib/rubocop/cop/lint/duplicate_magic_comment.rb +73 -0
  129. data/lib/rubocop/cop/lint/duplicate_match_pattern.rb +122 -0
  130. data/lib/rubocop/cop/lint/duplicate_methods.rb +48 -18
  131. data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +26 -9
  132. data/lib/rubocop/cop/lint/duplicate_require.rb +1 -1
  133. data/lib/rubocop/cop/lint/else_layout.rb +3 -7
  134. data/lib/rubocop/cop/lint/empty_block.rb +3 -7
  135. data/lib/rubocop/cop/lint/empty_class.rb +3 -1
  136. data/lib/rubocop/cop/lint/empty_conditional_body.rb +110 -2
  137. data/lib/rubocop/cop/lint/empty_interpolation.rb +1 -1
  138. data/lib/rubocop/cop/lint/erb_new_arguments.rb +11 -11
  139. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +14 -7
  140. data/lib/rubocop/cop/lint/heredoc_method_call_position.rb +15 -17
  141. data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +1 -1
  142. data/lib/rubocop/cop/lint/incompatible_io_select_with_fiber_scheduler.rb +5 -2
  143. data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +1 -1
  144. data/lib/rubocop/cop/lint/interpolation_check.rb +4 -3
  145. data/lib/rubocop/cop/lint/lambda_without_literal_block.rb +1 -1
  146. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +48 -2
  147. data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +18 -3
  148. data/lib/rubocop/cop/lint/missing_super.rb +31 -2
  149. data/lib/rubocop/cop/lint/mixed_regexp_capture_types.rb +1 -0
  150. data/lib/rubocop/cop/lint/nested_method_definition.rb +53 -9
  151. data/lib/rubocop/cop/lint/next_without_accumulator.rb +25 -6
  152. data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +68 -28
  153. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +12 -0
  154. data/lib/rubocop/cop/lint/number_conversion.rb +28 -6
  155. data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +2 -2
  156. data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +2 -0
  157. data/lib/rubocop/cop/lint/ordered_magic_comments.rb +4 -5
  158. data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +17 -2
  159. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +5 -0
  160. data/lib/rubocop/cop/lint/percent_string_array.rb +1 -1
  161. data/lib/rubocop/cop/lint/percent_symbol_array.rb +1 -1
  162. data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +49 -9
  163. data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +6 -6
  164. data/lib/rubocop/cop/lint/redundant_dir_glob_sort.rb +7 -0
  165. data/lib/rubocop/cop/lint/redundant_require_statement.rb +48 -10
  166. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +13 -0
  167. data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +1 -1
  168. data/lib/rubocop/cop/lint/redundant_string_coercion.rb +35 -15
  169. data/lib/rubocop/cop/lint/redundant_with_index.rb +14 -11
  170. data/lib/rubocop/cop/lint/redundant_with_object.rb +13 -12
  171. data/lib/rubocop/cop/lint/refinement_import_methods.rb +2 -1
  172. data/lib/rubocop/cop/lint/regexp_as_condition.rb +6 -0
  173. data/lib/rubocop/cop/lint/require_parentheses.rb +3 -1
  174. data/lib/rubocop/cop/lint/require_range_parentheses.rb +57 -0
  175. data/lib/rubocop/cop/lint/rescue_type.rb +3 -3
  176. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +41 -8
  177. data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +1 -1
  178. data/lib/rubocop/cop/lint/script_permission.rb +1 -1
  179. data/lib/rubocop/cop/lint/send_with_mixin_argument.rb +5 -4
  180. data/lib/rubocop/cop/lint/shadowed_exception.rb +16 -11
  181. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +28 -3
  182. data/lib/rubocop/cop/lint/suppressed_exception.rb +1 -1
  183. data/lib/rubocop/cop/lint/syntax.rb +4 -0
  184. data/lib/rubocop/cop/lint/to_enum_arguments.rb +13 -3
  185. data/lib/rubocop/cop/lint/top_level_return_with_argument.rb +23 -9
  186. data/lib/rubocop/cop/lint/unreachable_loop.rb +12 -6
  187. data/lib/rubocop/cop/lint/unused_method_argument.rb +6 -1
  188. data/lib/rubocop/cop/lint/useless_access_modifier.rb +17 -12
  189. data/lib/rubocop/cop/lint/useless_assignment.rb +56 -1
  190. data/lib/rubocop/cop/lint/useless_method_definition.rb +12 -4
  191. data/lib/rubocop/cop/lint/useless_rescue.rb +89 -0
  192. data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +15 -5
  193. data/lib/rubocop/cop/lint/useless_times.rb +1 -1
  194. data/lib/rubocop/cop/lint/void.rb +92 -21
  195. data/lib/rubocop/cop/metrics/abc_size.rb +4 -2
  196. data/lib/rubocop/cop/metrics/block_length.rb +16 -11
  197. data/lib/rubocop/cop/metrics/block_nesting.rb +2 -2
  198. data/lib/rubocop/cop/metrics/class_length.rb +11 -5
  199. data/lib/rubocop/cop/metrics/collection_literal_length.rb +76 -0
  200. data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +1 -1
  201. data/lib/rubocop/cop/metrics/method_length.rb +17 -11
  202. data/lib/rubocop/cop/metrics/module_length.rb +10 -5
  203. data/lib/rubocop/cop/metrics/parameter_lists.rb +27 -0
  204. data/lib/rubocop/cop/metrics/perceived_complexity.rb +1 -1
  205. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +3 -6
  206. data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +9 -6
  207. data/lib/rubocop/cop/migration/department_name.rb +1 -1
  208. data/lib/rubocop/cop/mixin/alignment.rb +2 -2
  209. data/lib/rubocop/cop/mixin/allowed_identifiers.rb +2 -2
  210. data/lib/rubocop/cop/mixin/allowed_methods.rb +23 -2
  211. data/lib/rubocop/cop/mixin/allowed_pattern.rb +17 -1
  212. data/lib/rubocop/cop/mixin/annotation_comment.rb +14 -7
  213. data/lib/rubocop/cop/mixin/check_line_breakable.rb +5 -1
  214. data/lib/rubocop/cop/mixin/code_length.rb +1 -1
  215. data/lib/rubocop/cop/mixin/comments_help.rb +29 -7
  216. data/lib/rubocop/cop/mixin/configurable_enforced_style.rb +21 -9
  217. data/lib/rubocop/cop/mixin/def_node.rb +2 -7
  218. data/lib/rubocop/cop/mixin/documentation_comment.rb +1 -1
  219. data/lib/rubocop/cop/mixin/enforce_superclass.rb +2 -1
  220. data/lib/rubocop/cop/mixin/first_element_line_break.rb +11 -7
  221. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +4 -0
  222. data/lib/rubocop/cop/mixin/hash_alignment_styles.rb +1 -1
  223. data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +152 -12
  224. data/lib/rubocop/cop/mixin/hash_transform_method.rb +13 -9
  225. data/lib/rubocop/cop/mixin/line_length_help.rb +11 -2
  226. data/lib/rubocop/cop/mixin/method_complexity.rb +13 -16
  227. data/lib/rubocop/cop/mixin/min_branches_count.rb +40 -0
  228. data/lib/rubocop/cop/mixin/multiline_element_indentation.rb +7 -14
  229. data/lib/rubocop/cop/mixin/multiline_element_line_breaks.rb +5 -6
  230. data/lib/rubocop/cop/mixin/ordered_gem_node.rb +1 -1
  231. data/lib/rubocop/cop/mixin/percent_array.rb +58 -1
  232. data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +1 -1
  233. data/lib/rubocop/cop/mixin/range_help.rb +22 -5
  234. data/lib/rubocop/cop/mixin/require_library.rb +2 -0
  235. data/lib/rubocop/cop/mixin/rescue_node.rb +5 -3
  236. data/lib/rubocop/cop/mixin/space_after_punctuation.rb +1 -1
  237. data/lib/rubocop/cop/mixin/statement_modifier.rb +18 -3
  238. data/lib/rubocop/cop/mixin/surrounding_space.rb +13 -11
  239. data/lib/rubocop/cop/mixin/trailing_comma.rb +2 -2
  240. data/lib/rubocop/cop/mixin/visibility_help.rb +40 -5
  241. data/lib/rubocop/cop/naming/ascii_identifiers.rb +1 -1
  242. data/lib/rubocop/cop/naming/block_forwarding.rb +5 -1
  243. data/lib/rubocop/cop/naming/block_parameter_name.rb +1 -1
  244. data/lib/rubocop/cop/naming/class_and_module_camel_case.rb +3 -1
  245. data/lib/rubocop/cop/naming/constant_name.rb +3 -3
  246. data/lib/rubocop/cop/naming/heredoc_delimiter_case.rb +1 -1
  247. data/lib/rubocop/cop/naming/inclusive_language.rb +28 -6
  248. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +22 -7
  249. data/lib/rubocop/cop/naming/method_name.rb +3 -3
  250. data/lib/rubocop/cop/naming/predicate_name.rb +31 -2
  251. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +12 -4
  252. data/lib/rubocop/cop/registry.rb +73 -45
  253. data/lib/rubocop/cop/security/compound_hash.rb +2 -1
  254. data/lib/rubocop/cop/style/access_modifier_declarations.rb +92 -3
  255. data/lib/rubocop/cop/style/accessor_grouping.rb +46 -20
  256. data/lib/rubocop/cop/style/alias.rb +9 -1
  257. data/lib/rubocop/cop/style/arguments_forwarding.rb +6 -5
  258. data/lib/rubocop/cop/style/array_intersect.rb +111 -0
  259. data/lib/rubocop/cop/style/ascii_comments.rb +1 -1
  260. data/lib/rubocop/cop/style/attr.rb +11 -1
  261. data/lib/rubocop/cop/style/bisected_attr_accessor.rb +1 -1
  262. data/lib/rubocop/cop/style/block_comments.rb +2 -2
  263. data/lib/rubocop/cop/style/block_delimiters.rb +44 -10
  264. data/lib/rubocop/cop/style/case_equality.rb +40 -10
  265. data/lib/rubocop/cop/style/case_like_if.rb +20 -3
  266. data/lib/rubocop/cop/style/character_literal.rb +1 -1
  267. data/lib/rubocop/cop/style/class_and_module_children.rb +8 -15
  268. data/lib/rubocop/cop/style/class_equality_comparison.rb +94 -12
  269. data/lib/rubocop/cop/style/class_methods_definitions.rb +2 -1
  270. data/lib/rubocop/cop/style/collection_compact.rb +21 -5
  271. data/lib/rubocop/cop/style/collection_methods.rb +2 -0
  272. data/lib/rubocop/cop/style/colon_method_call.rb +2 -2
  273. data/lib/rubocop/cop/style/combinable_loops.rb +29 -7
  274. data/lib/rubocop/cop/style/command_literal.rb +1 -1
  275. data/lib/rubocop/cop/style/comment_annotation.rb +1 -1
  276. data/lib/rubocop/cop/style/commented_keyword.rb +2 -2
  277. data/lib/rubocop/cop/style/comparable_clamp.rb +125 -0
  278. data/lib/rubocop/cop/style/concat_array_literals.rb +94 -0
  279. data/lib/rubocop/cop/style/conditional_assignment.rb +8 -14
  280. data/lib/rubocop/cop/style/copyright.rb +6 -3
  281. data/lib/rubocop/cop/style/data_inheritance.rb +75 -0
  282. data/lib/rubocop/cop/style/dir_empty.rb +60 -0
  283. data/lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb +2 -2
  284. data/lib/rubocop/cop/style/document_dynamic_eval_definition.rb +2 -2
  285. data/lib/rubocop/cop/style/documentation.rb +22 -10
  286. data/lib/rubocop/cop/style/documentation_method.rb +10 -4
  287. data/lib/rubocop/cop/style/double_negation.rb +4 -2
  288. data/lib/rubocop/cop/style/each_for_simple_loop.rb +41 -6
  289. data/lib/rubocop/cop/style/each_with_object.rb +40 -9
  290. data/lib/rubocop/cop/style/empty_block_parameter.rb +2 -2
  291. data/lib/rubocop/cop/style/empty_else.rb +37 -0
  292. data/lib/rubocop/cop/style/empty_heredoc.rb +73 -0
  293. data/lib/rubocop/cop/style/empty_lambda_parameter.rb +2 -2
  294. data/lib/rubocop/cop/style/empty_method.rb +1 -1
  295. data/lib/rubocop/cop/style/endless_method.rb +1 -1
  296. data/lib/rubocop/cop/style/eval_with_location.rb +4 -4
  297. data/lib/rubocop/cop/style/exact_regexp_match.rb +62 -0
  298. data/lib/rubocop/cop/style/explicit_block_argument.rb +5 -1
  299. data/lib/rubocop/cop/style/fetch_env_var.rb +10 -177
  300. data/lib/rubocop/cop/style/file_empty.rb +71 -0
  301. data/lib/rubocop/cop/style/file_read.rb +1 -1
  302. data/lib/rubocop/cop/style/file_write.rb +1 -1
  303. data/lib/rubocop/cop/style/for.rb +2 -0
  304. data/lib/rubocop/cop/style/format_string_token.rb +25 -6
  305. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +1 -1
  306. data/lib/rubocop/cop/style/guard_clause.rb +127 -38
  307. data/lib/rubocop/cop/style/hash_as_last_array_item.rb +1 -0
  308. data/lib/rubocop/cop/style/hash_each_methods.rb +48 -12
  309. data/lib/rubocop/cop/style/hash_except.rb +27 -16
  310. data/lib/rubocop/cop/style/hash_like_case.rb +3 -9
  311. data/lib/rubocop/cop/style/hash_syntax.rb +26 -2
  312. data/lib/rubocop/cop/style/identical_conditional_branches.rb +15 -0
  313. data/lib/rubocop/cop/style/if_inside_else.rb +6 -0
  314. data/lib/rubocop/cop/style/if_unless_modifier.rb +112 -16
  315. data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +29 -2
  316. data/lib/rubocop/cop/style/if_with_semicolon.rb +4 -4
  317. data/lib/rubocop/cop/style/infinite_loop.rb +2 -5
  318. data/lib/rubocop/cop/style/inverse_methods.rb +15 -11
  319. data/lib/rubocop/cop/style/invertible_unless_condition.rb +118 -0
  320. data/lib/rubocop/cop/style/line_end_concatenation.rb +4 -1
  321. data/lib/rubocop/cop/style/magic_comment_format.rb +307 -0
  322. data/lib/rubocop/cop/style/map_compact_with_conditional_block.rb +2 -2
  323. data/lib/rubocop/cop/style/map_to_hash.rb +4 -1
  324. data/lib/rubocop/cop/style/map_to_set.rb +64 -0
  325. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +40 -24
  326. data/lib/rubocop/cop/style/method_call_with_args_parentheses/require_parentheses.rb +5 -1
  327. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +48 -41
  328. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +21 -2
  329. data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +4 -1
  330. data/lib/rubocop/cop/style/method_def_parentheses.rb +11 -4
  331. data/lib/rubocop/cop/style/min_max.rb +3 -3
  332. data/lib/rubocop/cop/style/min_max_comparison.rb +83 -0
  333. data/lib/rubocop/cop/style/missing_else.rb +13 -1
  334. data/lib/rubocop/cop/style/mixin_grouping.rb +4 -4
  335. data/lib/rubocop/cop/style/module_function.rb +30 -8
  336. data/lib/rubocop/cop/style/multiline_block_chain.rb +3 -1
  337. data/lib/rubocop/cop/style/multiline_if_modifier.rb +0 -4
  338. data/lib/rubocop/cop/style/multiline_in_pattern_then.rb +1 -1
  339. data/lib/rubocop/cop/style/multiline_memoization.rb +2 -2
  340. data/lib/rubocop/cop/style/multiline_method_signature.rb +7 -4
  341. data/lib/rubocop/cop/style/multiline_ternary_operator.rb +18 -3
  342. data/lib/rubocop/cop/style/negated_if_else_condition.rb +17 -10
  343. data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +9 -0
  344. data/lib/rubocop/cop/style/next.rb +3 -5
  345. data/lib/rubocop/cop/style/nil_lambda.rb +4 -4
  346. data/lib/rubocop/cop/style/numbered_parameters_limit.rb +11 -3
  347. data/lib/rubocop/cop/style/numeric_literals.rb +16 -1
  348. data/lib/rubocop/cop/style/numeric_predicate.rb +43 -9
  349. data/lib/rubocop/cop/style/object_then.rb +5 -0
  350. data/lib/rubocop/cop/style/one_line_conditional.rb +3 -6
  351. data/lib/rubocop/cop/style/operator_method_call.rb +67 -0
  352. data/lib/rubocop/cop/style/parallel_assignment.rb +29 -19
  353. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +2 -3
  354. data/lib/rubocop/cop/style/percent_q_literals.rb +1 -1
  355. data/lib/rubocop/cop/style/perl_backrefs.rb +22 -1
  356. data/lib/rubocop/cop/style/proc.rb +4 -1
  357. data/lib/rubocop/cop/style/quoted_symbols.rb +1 -1
  358. data/lib/rubocop/cop/style/redundant_argument.rb +3 -0
  359. data/lib/rubocop/cop/style/redundant_begin.rb +3 -0
  360. data/lib/rubocop/cop/style/redundant_condition.rb +41 -8
  361. data/lib/rubocop/cop/style/redundant_conditional.rb +0 -4
  362. data/lib/rubocop/cop/style/redundant_constant_base.rb +85 -0
  363. data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +45 -0
  364. data/lib/rubocop/cop/style/redundant_each.rb +116 -0
  365. data/lib/rubocop/cop/style/redundant_fetch_block.rb +7 -5
  366. data/lib/rubocop/cop/style/redundant_heredoc_delimiter_quotes.rb +58 -0
  367. data/lib/rubocop/cop/style/redundant_initialize.rb +3 -1
  368. data/lib/rubocop/cop/style/redundant_interpolation.rb +2 -2
  369. data/lib/rubocop/cop/style/redundant_line_continuation.rb +183 -0
  370. data/lib/rubocop/cop/style/redundant_parentheses.rb +22 -24
  371. data/lib/rubocop/cop/style/redundant_percent_q.rb +1 -1
  372. data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +9 -3
  373. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +21 -4
  374. data/lib/rubocop/cop/style/redundant_return.rb +7 -0
  375. data/lib/rubocop/cop/style/redundant_self.rb +2 -0
  376. data/lib/rubocop/cop/style/redundant_sort.rb +24 -9
  377. data/lib/rubocop/cop/style/redundant_sort_by.rb +24 -8
  378. data/lib/rubocop/cop/style/redundant_string_escape.rb +183 -0
  379. data/lib/rubocop/cop/style/regexp_literal.rb +11 -2
  380. data/lib/rubocop/cop/style/require_order.rb +138 -0
  381. data/lib/rubocop/cop/style/rescue_modifier.rb +1 -1
  382. data/lib/rubocop/cop/style/rescue_standard_error.rb +2 -2
  383. data/lib/rubocop/cop/style/safe_navigation.rb +41 -10
  384. data/lib/rubocop/cop/style/select_by_regexp.rb +13 -5
  385. data/lib/rubocop/cop/style/self_assignment.rb +2 -2
  386. data/lib/rubocop/cop/style/semicolon.rb +63 -5
  387. data/lib/rubocop/cop/style/signal_exception.rb +8 -6
  388. data/lib/rubocop/cop/style/single_line_block_params.rb +1 -1
  389. data/lib/rubocop/cop/style/slicing_with_range.rb +1 -1
  390. data/lib/rubocop/cop/style/sole_nested_conditional.rb +17 -8
  391. data/lib/rubocop/cop/style/special_global_vars.rb +2 -2
  392. data/lib/rubocop/cop/style/static_class.rb +32 -1
  393. data/lib/rubocop/cop/style/stderr_puts.rb +1 -1
  394. data/lib/rubocop/cop/style/string_hash_keys.rb +4 -1
  395. data/lib/rubocop/cop/style/string_literals.rb +1 -5
  396. data/lib/rubocop/cop/style/struct_inheritance.rb +1 -1
  397. data/lib/rubocop/cop/style/symbol_array.rb +6 -5
  398. data/lib/rubocop/cop/style/symbol_proc.rb +42 -10
  399. data/lib/rubocop/cop/style/ternary_parentheses.rb +1 -13
  400. data/lib/rubocop/cop/style/top_level_method_definition.rb +3 -1
  401. data/lib/rubocop/cop/style/trailing_body_on_class.rb +1 -0
  402. data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +4 -4
  403. data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +1 -1
  404. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +1 -1
  405. data/lib/rubocop/cop/style/trivial_accessors.rb +4 -1
  406. data/lib/rubocop/cop/style/unless_logical_operators.rb +1 -0
  407. data/lib/rubocop/cop/style/unpack_first.rb +3 -3
  408. data/lib/rubocop/cop/style/word_array.rb +59 -5
  409. data/lib/rubocop/cop/style/yoda_condition.rb +13 -6
  410. data/lib/rubocop/cop/style/yoda_expression.rb +90 -0
  411. data/lib/rubocop/cop/style/zero_length_predicate.rb +40 -19
  412. data/lib/rubocop/cop/team.rb +63 -56
  413. data/lib/rubocop/cop/util.rb +44 -8
  414. data/lib/rubocop/cop/variable_force/assignment.rb +5 -1
  415. data/lib/rubocop/cop/variable_force/scope.rb +3 -3
  416. data/lib/rubocop/cop/variable_force/variable.rb +5 -3
  417. data/lib/rubocop/cop/variable_force/variable_table.rb +6 -4
  418. data/lib/rubocop/cop/variable_force.rb +18 -30
  419. data/lib/rubocop/cops_documentation_generator.rb +45 -15
  420. data/lib/rubocop/directive_comment.rb +4 -4
  421. data/lib/rubocop/ext/comment.rb +18 -0
  422. data/lib/rubocop/ext/processed_source.rb +2 -0
  423. data/lib/rubocop/ext/range.rb +15 -0
  424. data/lib/rubocop/ext/regexp_node.rb +1 -1
  425. data/lib/rubocop/ext/regexp_parser.rb +1 -1
  426. data/lib/rubocop/feature_loader.rb +94 -0
  427. data/lib/rubocop/file_patterns.rb +43 -0
  428. data/lib/rubocop/formatter/clang_style_formatter.rb +1 -1
  429. data/lib/rubocop/formatter/disabled_config_formatter.rb +26 -9
  430. data/lib/rubocop/formatter/html_formatter.rb +4 -4
  431. data/lib/rubocop/formatter/junit_formatter.rb +4 -1
  432. data/lib/rubocop/formatter/markdown_formatter.rb +1 -1
  433. data/lib/rubocop/formatter/offense_count_formatter.rb +8 -5
  434. data/lib/rubocop/formatter/simple_text_formatter.rb +1 -1
  435. data/lib/rubocop/formatter/tap_formatter.rb +1 -1
  436. data/lib/rubocop/formatter/worst_offenders_formatter.rb +6 -3
  437. data/lib/rubocop/formatter.rb +4 -1
  438. data/lib/rubocop/options.rb +55 -22
  439. data/lib/rubocop/path_util.rb +50 -22
  440. data/lib/rubocop/rake_task.rb +5 -1
  441. data/lib/rubocop/result_cache.rb +26 -24
  442. data/lib/rubocop/rspec/cop_helper.rb +26 -3
  443. data/lib/rubocop/rspec/expect_offense.rb +6 -4
  444. data/lib/rubocop/rspec/shared_contexts.rb +31 -14
  445. data/lib/rubocop/rspec/support.rb +17 -2
  446. data/lib/rubocop/runner.rb +73 -18
  447. data/lib/rubocop/server/cache.rb +48 -2
  448. data/lib/rubocop/server/cli.rb +62 -19
  449. data/lib/rubocop/server/client_command/base.rb +1 -1
  450. data/lib/rubocop/server/client_command/exec.rb +6 -1
  451. data/lib/rubocop/server/client_command/start.rb +6 -1
  452. data/lib/rubocop/server/core.rb +42 -10
  453. data/lib/rubocop/server/helper.rb +1 -1
  454. data/lib/rubocop/server/server_command/exec.rb +1 -1
  455. data/lib/rubocop/server/socket_reader.rb +5 -1
  456. data/lib/rubocop/server.rb +1 -1
  457. data/lib/rubocop/target_finder.rb +1 -1
  458. data/lib/rubocop/target_ruby.rb +5 -5
  459. data/lib/rubocop/version.rb +10 -4
  460. data/lib/rubocop.rb +45 -9
  461. metadata +58 -33
  462. data/lib/rubocop/cop/mixin/ignored_methods.rb +0 -52
@@ -6,22 +6,20 @@ module RuboCop
6
6
  # Enforces the presence (default) or absence of parentheses in
7
7
  # method calls containing parameters.
8
8
  #
9
- # In the default style (require_parentheses), macro methods are ignored.
10
- # Additional methods can be added to the `IgnoredMethods`
11
- # or `AllowedPatterns` list. These options are
12
- # valid only in the default style. Macros can be included by
13
- # either setting `IgnoreMacros` to false or adding specific macros to
14
- # the `IncludedMacros` list.
9
+ # In the default style (require_parentheses), macro methods are allowed.
10
+ # Additional methods can be added to the `AllowedMethods` or
11
+ # `AllowedPatterns` list. These options are valid only in the default
12
+ # style. Macros can be included by either setting `IgnoreMacros` to false
13
+ # or adding specific macros to the `IncludedMacros` list.
15
14
  #
16
- # Precedence of options is all follows:
15
+ # Precedence of options is as follows:
17
16
  #
18
- # 1. `IgnoredMethods`
17
+ # 1. `AllowedMethods`
19
18
  # 2. `AllowedPatterns`
20
19
  # 3. `IncludedMacros`
21
20
  #
22
- # eg. If a method is listed in both
23
- # `IncludedMacros` and `IgnoredMethods`, then the latter takes
24
- # precedence (that is, the method is ignored).
21
+ # If a method is listed in both `IncludedMacros` and `AllowedMethods`,
22
+ # then the latter takes precedence (that is, the method is allowed).
25
23
  #
26
24
  # In the alternative style (omit_parentheses), there are three additional
27
25
  # options.
@@ -40,14 +38,29 @@ module RuboCop
40
38
  # to `true` allows the presence of parentheses in such a method call
41
39
  # even with arguments.
42
40
  #
43
- # NOTE: Parentheses are still allowed in cases where omitting them
44
- # results in ambiguous or syntactically incorrect code. For example,
45
- # parentheses are required around a method with arguments when inside an
46
- # endless method definition introduced in Ruby 3.0. Parentheses are also
47
- # allowed when forwarding arguments with the triple-dot syntax introduced
48
- # in Ruby 2.7 as omitting them starts an endless range.
49
- # And Ruby 3.1's hash omission syntax has a case that requires parentheses
50
- # because of the following issue: https://bugs.ruby-lang.org/issues/18396.
41
+ # NOTE: The style of `omit_parentheses` allows parentheses in cases where
42
+ # omitting them results in ambiguous or syntactically incorrect code.
43
+ #
44
+ # Non-exhaustive list of examples:
45
+ #
46
+ # - Parentheses are required allowed in method calls with arguments inside
47
+ # literals, logical operators, setting default values in position and
48
+ # keyword arguments, chaining and more.
49
+ # - Parentheses are allowed in method calls with arguments inside
50
+ # operators to avoid ambiguity.
51
+ # triple-dot syntax introduced in Ruby 2.7 as omitting them starts an
52
+ # endless range.
53
+ # - Parentheses are allowed when forwarding arguments with the
54
+ # triple-dot syntax introduced in Ruby 2.7 as omitting them starts an
55
+ # endless range.
56
+ # - Parentheses are required in calls with arguments when inside an
57
+ # endless method definition introduced in Ruby 3.0.
58
+ # - Ruby 3.1's hash omission syntax allows parentheses if the method call
59
+ # is in conditionals and requires parentheses if the call
60
+ # is not the value-returning expression. See
61
+ # https://bugs.ruby-lang.org/issues/18396.
62
+ # - Parentheses are required in anonymous arguments, keyword arguments
63
+ # and block passing in Ruby 3.2.
51
64
  #
52
65
  # @example EnforcedStyle: require_parentheses (default)
53
66
  #
@@ -65,7 +78,7 @@ module RuboCop
65
78
  # # Setter methods don't need parens
66
79
  # foo.bar = baz
67
80
  #
68
- # # okay with `puts` listed in `IgnoredMethods`
81
+ # # okay with `puts` listed in `AllowedMethods`
69
82
  # puts 'test'
70
83
  #
71
84
  # # okay with `^assert` listed in `AllowedPatterns`
@@ -80,34 +93,28 @@ module RuboCop
80
93
  # array.delete e
81
94
  #
82
95
  # # bad
83
- # foo.enforce(strict: true)
96
+ # action.enforce(strict: true)
84
97
  #
85
98
  # # good
86
- # foo.enforce strict: true
99
+ # action.enforce strict: true
87
100
  #
88
101
  # # good
89
- # # Allows parens for calls that won't produce valid Ruby or be ambiguous.
90
- # model.validate strict(true)
102
+ # # Parentheses are allowed for code that can be ambiguous without
103
+ # # them.
104
+ # action.enforce(condition) || other_condition
91
105
  #
92
106
  # # good
93
- # # Allows parens for calls that won't produce valid Ruby or be ambiguous.
107
+ # # Parentheses are allowed for calls that won't produce valid Ruby
108
+ # # without them.
94
109
  # yield path, File.basename(path)
95
110
  #
96
111
  # # good
97
- # # Operators methods calls with parens
98
- # array&.[](index)
99
- #
100
- # # good
101
- # # Operators methods without parens, if you prefer
102
- # array.[] index
103
- #
104
- # # good
105
- # # Operators methods calls with parens
106
- # array&.[](index)
107
- #
108
- # # good
109
- # # Operators methods without parens, if you prefer
110
- # array.[] index
112
+ # # Omitting the parentheses in Ruby 3.1 hash omission syntax can lead
113
+ # # to ambiguous code. We allow them in conditionals and non-last
114
+ # # expressions. See https://bugs.ruby-lang.org/issues/18396
115
+ # if meets(criteria:, action:)
116
+ # safe_action(action) || dangerous_action(action)
117
+ # end
111
118
  #
112
119
  # @example IgnoreMacros: true (default)
113
120
  #
@@ -197,7 +204,7 @@ module RuboCop
197
204
  require_relative 'method_call_with_args_parentheses/require_parentheses'
198
205
 
199
206
  include ConfigurableEnforcedStyle
200
- include IgnoredMethods
207
+ include AllowedMethods
201
208
  include AllowedPattern
202
209
  include RequireParentheses
203
210
  include OmitParentheses
@@ -226,7 +233,7 @@ module RuboCop
226
233
  end
227
234
 
228
235
  def args_end(node)
229
- node.loc.expression.end
236
+ node.source_range.end
230
237
  end
231
238
 
232
239
  def args_parenthesized?(node)
@@ -5,14 +5,27 @@ module RuboCop
5
5
  module Style
6
6
  # Checks for unwanted parentheses in parameterless method calls.
7
7
  #
8
+ # This cop can be customized allowed methods with `AllowedMethods`.
9
+ # By default, there are no methods to allowed.
10
+ #
8
11
  # @example
9
12
  # # bad
10
13
  # object.some_method()
11
14
  #
12
15
  # # good
13
16
  # object.some_method
17
+ #
18
+ # @example AllowedMethods: [] (default)
19
+ # # bad
20
+ # object.foo()
21
+ #
22
+ # @example AllowedMethods: [foo]
23
+ # # good
24
+ # object.foo()
25
+ #
14
26
  class MethodCallWithoutArgsParentheses < Base
15
- include IgnoredMethods
27
+ include AllowedMethods
28
+ include AllowedPattern
16
29
  extend AutoCorrector
17
30
 
18
31
  MSG = 'Do not use parentheses for method calls with no arguments.'
@@ -21,7 +34,7 @@ module RuboCop
21
34
  return unless !node.arguments? && node.parenthesized?
22
35
  return if ineligible_node?(node)
23
36
  return if default_argument?(node)
24
- return if ignored_method?(node.method_name)
37
+ return if allowed_method_name?(node.method_name)
25
38
  return if same_name_assignment?(node)
26
39
 
27
40
  register_offense(node)
@@ -44,7 +57,13 @@ module RuboCop
44
57
  node.parent&.optarg_type?
45
58
  end
46
59
 
60
+ def allowed_method_name?(name)
61
+ allowed_method?(name) || matches_allowed_pattern?(name)
62
+ end
63
+
47
64
  def same_name_assignment?(node)
65
+ return false if node.receiver
66
+
48
67
  any_assignment?(node) do |asgn_node|
49
68
  next variable_in_mass_assignment?(node.method_name, asgn_node) if asgn_node.masgn_type?
50
69
 
@@ -35,12 +35,15 @@ module RuboCop
35
35
  ignore_node(node.send_node)
36
36
  end
37
37
 
38
+ alias on_numblock on_block
39
+
38
40
  def on_send(node)
39
41
  return if ignored_node?(node)
40
42
 
41
43
  receiver = node.receiver
42
44
 
43
- return unless receiver&.block_type? && receiver.loc.end.is?('end')
45
+ return unless (receiver&.block_type? || receiver&.numblock_type?) &&
46
+ receiver.loc.end.is?('end')
44
47
 
45
48
  range = range_between(receiver.loc.end.begin_pos, node.source_range.end_pos)
46
49
 
@@ -10,7 +10,9 @@ module RuboCop
10
10
  #
11
11
  # 1. Endless methods
12
12
  # 2. Argument lists containing a `forward-arg` (`...`)
13
- # 3. Argument lists containing an anonymous block forwarding (`&`)
13
+ # 3. Argument lists containing an anonymous rest arguments forwarding (`*`)
14
+ # 4. Argument lists containing an anonymous keyword rest arguments forwarding (`**`)
15
+ # 5. Argument lists containing an anonymous block forwarding (`&`)
14
16
  #
15
17
  # Removing the parens would be a syntax error here.
16
18
  #
@@ -130,9 +132,11 @@ module RuboCop
130
132
  # Regardless of style, parentheses are necessary for:
131
133
  # 1. Endless methods
132
134
  # 2. Argument lists containing a `forward-arg` (`...`)
133
- # 3. Argument lists containing an anonymous block forwarding (`&`)
135
+ # 3. Argument lists containing an anonymous rest arguments forwarding (`*`)
136
+ # 4. Argument lists containing an anonymous keyword rest arguments forwarding (`**`)
137
+ # 5. Argument lists containing an anonymous block forwarding (`&`)
134
138
  # Removing the parens would be a syntax error here.
135
- node.endless? || node.arguments.any?(&:forward_arg_type?) || anonymous_block_arg?(node)
139
+ node.endless? || anonymous_arguments?(node)
136
140
  end
137
141
 
138
142
  def require_parentheses?(args)
@@ -162,7 +166,10 @@ module RuboCop
162
166
  end
163
167
  end
164
168
 
165
- def anonymous_block_arg?(node)
169
+ def anonymous_arguments?(node)
170
+ return true if node.arguments.any? do |arg|
171
+ arg.forward_arg_type? || arg.restarg_type? || arg.kwrestarg_type?
172
+ end
166
173
  return false unless (last_argument = node.arguments.last)
167
174
 
168
175
  last_argument.blockarg_type? && last_argument.name.nil?
@@ -48,13 +48,13 @@ module RuboCop
48
48
  when :return
49
49
  argument_range(node)
50
50
  else
51
- node.loc.expression
51
+ node.source_range
52
52
  end
53
53
  end
54
54
 
55
55
  def argument_range(node)
56
- first_argument_range = node.children.first.loc.expression
57
- last_argument_range = node.children.last.loc.expression
56
+ first_argument_range = node.children.first.source_range
57
+ last_argument_range = node.children.last.source_range
58
58
 
59
59
  first_argument_range.join(last_argument_range)
60
60
  end
@@ -0,0 +1,83 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Style
6
+ # Enforces the use of `max` or `min` instead of comparison for greater or less.
7
+ #
8
+ # NOTE: It can be used if you want to present limit or threshold in Ruby 2.7+.
9
+ # That it is slow though. So autocorrection will apply generic `max` or `min`:
10
+ #
11
+ # [source,ruby]
12
+ # ----
13
+ # a.clamp(b..) # Same as `[a, b].max`
14
+ # a.clamp(..b) # Same as `[a, b].min`
15
+ # ----
16
+ #
17
+ # @safety
18
+ # This cop is unsafe because even if a value has `<` or `>` method,
19
+ # it is not necessarily `Comparable`.
20
+ #
21
+ # @example
22
+ #
23
+ # # bad
24
+ # a > b ? a : b
25
+ # a >= b ? a : b
26
+ #
27
+ # # good
28
+ # [a, b].max
29
+ #
30
+ # # bad
31
+ # a < b ? a : b
32
+ # a <= b ? a : b
33
+ #
34
+ # # good
35
+ # [a, b].min
36
+ #
37
+ class MinMaxComparison < Base
38
+ extend AutoCorrector
39
+ include RangeHelp
40
+
41
+ MSG = 'Use `%<prefer>s` instead.'
42
+ GRATER_OPERATORS = %i[> >=].freeze
43
+ LESS_OPERATORS = %i[< <=].freeze
44
+ COMPARISON_OPERATORS = GRATER_OPERATORS + LESS_OPERATORS
45
+
46
+ def on_if(node)
47
+ lhs, operator, rhs = *node.condition
48
+ return unless COMPARISON_OPERATORS.include?(operator)
49
+
50
+ if_branch = node.if_branch
51
+ else_branch = node.else_branch
52
+ preferred_method = preferred_method(operator, lhs, rhs, if_branch, else_branch)
53
+ return unless preferred_method
54
+
55
+ replacement = "[#{lhs.source}, #{rhs.source}].#{preferred_method}"
56
+
57
+ add_offense(node, message: format(MSG, prefer: replacement)) do |corrector|
58
+ autocorrect(corrector, node, replacement)
59
+ end
60
+ end
61
+
62
+ private
63
+
64
+ def preferred_method(operator, lhs, rhs, if_branch, else_branch)
65
+ if lhs == if_branch && rhs == else_branch
66
+ GRATER_OPERATORS.include?(operator) ? 'max' : 'min'
67
+ elsif lhs == else_branch && rhs == if_branch
68
+ LESS_OPERATORS.include?(operator) ? 'max' : 'min'
69
+ end
70
+ end
71
+
72
+ def autocorrect(corrector, node, replacement)
73
+ if node.elsif?
74
+ corrector.remove(range_between(node.parent.loc.else.begin_pos, node.loc.else.begin_pos))
75
+ corrector.replace(node.else_branch, replacement)
76
+ else
77
+ corrector.replace(node, replacement)
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
@@ -99,6 +99,7 @@ module RuboCop
99
99
  class MissingElse < Base
100
100
  include OnNormalIfUnless
101
101
  include ConfigurableEnforcedStyle
102
+ extend AutoCorrector
102
103
 
103
104
  MSG = '`%<type>s` condition requires an `else`-clause.'
104
105
  MSG_NIL = '`%<type>s` condition requires an `else`-clause with `nil` in it.'
@@ -126,7 +127,9 @@ module RuboCop
126
127
  def check(node)
127
128
  return if node.else?
128
129
 
129
- add_offense(node, message: format(message_template, type: node.type))
130
+ add_offense(node, message: format(message_template, type: node.type)) do |corrector|
131
+ autocorrect(corrector, node)
132
+ end
130
133
  end
131
134
 
132
135
  def message_template
@@ -140,6 +143,15 @@ module RuboCop
140
143
  end
141
144
  end
142
145
 
146
+ def autocorrect(corrector, node)
147
+ case empty_else_style
148
+ when :empty
149
+ corrector.insert_before(node.loc.end, 'else; nil; ')
150
+ when :nil
151
+ corrector.insert_before(node.loc.end, 'else; ')
152
+ end
153
+ end
154
+
143
155
  def if_style?
144
156
  style == :if
145
157
  end
@@ -51,9 +51,9 @@ module RuboCop
51
51
  private
52
52
 
53
53
  def range_to_remove_for_subsequent_mixin(mixins, node)
54
- range = node.loc.expression
54
+ range = node.source_range
55
55
  prev_mixin = mixins.each_cons(2) { |m, n| break m if n == node }
56
- between = prev_mixin.loc.expression.end.join(range.begin)
56
+ between = prev_mixin.source_range.end.join(range.begin)
57
57
  # if separated from previous mixin with only whitespace?
58
58
  unless /\S/.match?(between.source)
59
59
  range = range.join(between) # then remove that too
@@ -75,7 +75,7 @@ module RuboCop
75
75
  message = format(MSG, mixin: send_node.method_name, suffix: 'a single statement')
76
76
 
77
77
  add_offense(send_node, message: message) do |corrector|
78
- range = send_node.loc.expression
78
+ range = send_node.source_range
79
79
  mixins = sibling_mixins(send_node)
80
80
  if send_node == mixins.first
81
81
  correction = group_mixins(send_node, mixins)
@@ -94,7 +94,7 @@ module RuboCop
94
94
  message = format(MSG, mixin: send_node.method_name, suffix: 'separate statements')
95
95
 
96
96
  add_offense(send_node, message: message) do |corrector|
97
- range = send_node.loc.expression
97
+ range = send_node.source_range
98
98
  correction = separate_mixins(send_node)
99
99
 
100
100
  corrector.replace(range, correction)
@@ -3,13 +3,15 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Style
6
- # Checks for use of `extend self` or `module_function` in a
7
- # module.
6
+ # Checks for use of `extend self` or `module_function` in a module.
8
7
  #
9
- # Supported styles are: module_function, extend_self, forbidden. `forbidden`
10
- # style prohibits the usage of both styles.
8
+ # Supported styles are: `module_function` (default), `extend_self` and `forbidden`.
11
9
  #
12
- # NOTE: the cop won't be activated when the module contains any private methods.
10
+ # A couple of things to keep in mind:
11
+ #
12
+ # - `forbidden` style prohibits the usage of both styles
13
+ # - in default mode (`module_function`), the cop won't be activated when the module
14
+ # contains any private methods
13
15
  #
14
16
  # @safety
15
17
  # Autocorrection is unsafe (and is disabled by default) because `extend self`
@@ -28,7 +30,6 @@ module RuboCop
28
30
  # # ...
29
31
  # end
30
32
  #
31
- # @example EnforcedStyle: module_function (default)
32
33
  # # good
33
34
  # module Test
34
35
  # extend self
@@ -37,6 +38,13 @@ module RuboCop
37
38
  # # ...
38
39
  # end
39
40
  #
41
+ # # good
42
+ # module Test
43
+ # class << self
44
+ # # ...
45
+ # end
46
+ # end
47
+ #
40
48
  # @example EnforcedStyle: extend_self
41
49
  # # bad
42
50
  # module Test
@@ -50,6 +58,13 @@ module RuboCop
50
58
  # # ...
51
59
  # end
52
60
  #
61
+ # # good
62
+ # module Test
63
+ # class << self
64
+ # # ...
65
+ # end
66
+ # end
67
+ #
53
68
  # @example EnforcedStyle: forbidden
54
69
  # # bad
55
70
  # module Test
@@ -70,6 +85,13 @@ module RuboCop
70
85
  # private
71
86
  # # ...
72
87
  # end
88
+ #
89
+ # # good
90
+ # module Test
91
+ # class << self
92
+ # # ...
93
+ # end
94
+ # end
73
95
  class ModuleFunction < Base
74
96
  include ConfigurableEnforcedStyle
75
97
  extend AutoCorrector
@@ -117,10 +139,10 @@ module RuboCop
117
139
  end
118
140
 
119
141
  def check_module_function(nodes)
120
- private_directive = nodes.any? { |node| private_directive?(node) }
142
+ return if nodes.any? { |node| private_directive?(node) }
121
143
 
122
144
  nodes.each do |node|
123
- yield node if extend_self_node?(node) && !private_directive
145
+ yield node if extend_self_node?(node)
124
146
  end
125
147
  end
126
148
 
@@ -31,7 +31,7 @@ module RuboCop
31
31
  node.send_node.each_node(:send) do |send_node|
32
32
  receiver = send_node.receiver
33
33
 
34
- next unless receiver&.block_type? && receiver&.multiline?
34
+ next unless (receiver&.block_type? || receiver&.numblock_type?) && receiver&.multiline?
35
35
 
36
36
  range = range_between(receiver.loc.end.begin_pos, node.send_node.source_range.end_pos)
37
37
 
@@ -42,6 +42,8 @@ module RuboCop
42
42
  break
43
43
  end
44
44
  end
45
+
46
+ alias on_numblock on_block
45
47
  end
46
48
  end
47
49
  end
@@ -40,10 +40,6 @@ module RuboCop
40
40
  [condition, indented_body, indented_end].join("\n")
41
41
  end
42
42
 
43
- def configured_indentation_width
44
- super || 2
45
- end
46
-
47
43
  def indented_body(body, node)
48
44
  body_source = "#{offset(node)}#{body.source}"
49
45
  body_source.each_line.map do |line|
@@ -49,7 +49,7 @@ module RuboCop
49
49
 
50
50
  # Requires `then` for write `in` and its body on the same line.
51
51
  def require_then?(in_pattern_node)
52
- return true if in_pattern_node.pattern.first_line != in_pattern_node.pattern.last_line
52
+ return true unless in_pattern_node.pattern.single_line?
53
53
  return false unless in_pattern_node.body
54
54
 
55
55
  same_line?(in_pattern_node, in_pattern_node.body)
@@ -31,6 +31,7 @@ module RuboCop
31
31
  # baz
32
32
  # )
33
33
  class MultilineMemoization < Base
34
+ include Alignment
34
35
  include ConfigurableEnforcedStyle
35
36
  extend AutoCorrector
36
37
 
@@ -75,11 +76,10 @@ module RuboCop
75
76
  end
76
77
 
77
78
  def keyword_begin_str(node, node_buf)
78
- indent = config.for_cop('Layout/IndentationWidth')['Width'] || 2
79
79
  if node_buf.source[node.loc.begin.end_pos] == "\n"
80
80
  'begin'
81
81
  else
82
- "begin\n#{' ' * (node.loc.column + indent)}"
82
+ "begin\n#{' ' * (node.loc.column + configured_indentation_width)}"
83
83
  end
84
84
  end
85
85
 
@@ -28,14 +28,17 @@ module RuboCop
28
28
  return unless node.arguments?
29
29
  return if opening_line(node) == closing_line(node)
30
30
  return if correction_exceeds_max_line_length?(node)
31
+ return unless (begin_of_arguments = node.arguments.loc.begin)
31
32
 
32
- add_offense(node) { |corrector| autocorrect(corrector, node) }
33
+ add_offense(node) do |corrector|
34
+ autocorrect(corrector, node, begin_of_arguments)
35
+ end
33
36
  end
34
37
  alias on_defs on_def
35
38
 
36
39
  private
37
40
 
38
- def autocorrect(corrector, node)
41
+ def autocorrect(corrector, node, begin_of_arguments)
39
42
  arguments = node.arguments
40
43
  joined_arguments = arguments.map(&:source).join(', ')
41
44
  last_line_source_of_arguments = last_line_source_of_arguments(arguments)
@@ -47,7 +50,7 @@ module RuboCop
47
50
  end
48
51
 
49
52
  corrector.remove(arguments_range(node))
50
- corrector.insert_after(arguments.loc.begin, joined_arguments)
53
+ corrector.insert_after(begin_of_arguments, joined_arguments)
51
54
  end
52
55
 
53
56
  def last_line_source_of_arguments(arguments)
@@ -75,7 +78,7 @@ module RuboCop
75
78
  end
76
79
 
77
80
  def indentation_width(node)
78
- processed_source.line_indentation(node.loc.expression.line)
81
+ processed_source.line_indentation(node.source_range.line)
79
82
  end
80
83
 
81
84
  def definition_width(node)
@@ -34,6 +34,7 @@ module RuboCop
34
34
  # return cond ? b : c
35
35
  #
36
36
  class MultilineTernaryOperator < Base
37
+ include CommentsHelp
37
38
  extend AutoCorrector
38
39
 
39
40
  MSG_IF = 'Avoid multi-line ternary operators, use `if` or `unless` instead.'
@@ -46,9 +47,7 @@ module RuboCop
46
47
  message = enforce_single_line_ternary_operator?(node) ? MSG_SINGLE_LINE : MSG_IF
47
48
 
48
49
  add_offense(node, message: message) do |corrector|
49
- next unless offense?(node)
50
-
51
- corrector.replace(node, replacement(node))
50
+ autocorrect(corrector, node)
52
51
  end
53
52
  end
54
53
 
@@ -58,6 +57,16 @@ module RuboCop
58
57
  node.ternary? && node.multiline?
59
58
  end
60
59
 
60
+ def autocorrect(corrector, node)
61
+ return unless offense?(node)
62
+
63
+ corrector.replace(node, replacement(node))
64
+ return unless (parent = node.parent)
65
+ return unless (comments_in_condition = comments_in_condition(node))
66
+
67
+ corrector.insert_before(parent, comments_in_condition)
68
+ end
69
+
61
70
  def replacement(node)
62
71
  if enforce_single_line_ternary_operator?(node)
63
72
  "#{node.condition.source} ? #{node.if_branch.source} : #{node.else_branch.source}"
@@ -72,6 +81,12 @@ module RuboCop
72
81
  end
73
82
  end
74
83
 
84
+ def comments_in_condition(node)
85
+ comments_in_range(node).map do |comment|
86
+ "#{comment.source}\n"
87
+ end.join
88
+ end
89
+
75
90
  def enforce_single_line_ternary_operator?(node)
76
91
  SINGLE_LINE_TYPES.include?(node.parent&.type) && !use_assignment_method?(node.parent)
77
92
  end