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
@@ -25,13 +25,8 @@ module RuboCop
25
25
  class NextWithoutAccumulator < Base
26
26
  MSG = 'Use `next` with an accumulator argument in a `reduce`.'
27
27
 
28
- # @!method on_body_of_reduce(node)
29
- def_node_matcher :on_body_of_reduce, <<~PATTERN
30
- (block (send _recv {:reduce :inject} !sym) _blockargs $(begin ...))
31
- PATTERN
32
-
33
28
  def on_block(node)
34
- on_body_of_reduce(node) do |body|
29
+ on_block_body_of_reduce(node) do |body|
35
30
  void_next = body.each_node(:next).find do |n|
36
31
  n.children.empty? && parent_block_node(n) == node
37
32
  end
@@ -40,11 +35,35 @@ module RuboCop
40
35
  end
41
36
  end
42
37
 
38
+ def on_numblock(node)
39
+ on_numblock_body_of_reduce(node) do |body|
40
+ void_next = body.each_node(:next).find do |n|
41
+ n.children.empty? && parent_numblock_node(n) == node
42
+ end
43
+
44
+ add_offense(void_next) if void_next
45
+ end
46
+ end
47
+
43
48
  private
44
49
 
50
+ # @!method on_block_body_of_reduce(node)
51
+ def_node_matcher :on_block_body_of_reduce, <<~PATTERN
52
+ (block (send _recv {:reduce :inject} !sym) _blockargs $(begin ...))
53
+ PATTERN
54
+
55
+ # @!method on_numblock_body_of_reduce(node)
56
+ def_node_matcher :on_numblock_body_of_reduce, <<~PATTERN
57
+ (numblock (send _recv {:reduce :inject} !sym) _argscount $(begin ...))
58
+ PATTERN
59
+
45
60
  def parent_block_node(node)
46
61
  node.each_ancestor(:block).first
47
62
  end
63
+
64
+ def parent_numblock_node(node)
65
+ node.each_ancestor(:numblock).first
66
+ end
48
67
  end
49
68
  end
50
69
  end
@@ -25,30 +25,36 @@ module RuboCop
25
25
  # to be strictly equivalent to that before the replacement.
26
26
  #
27
27
  # @example
28
- # # bad
29
- # unless FileTest.exist?(path)
30
- # FileUtils.makedirs(path)
28
+ # # bad - race condition with another process may result in an error in `mkdir`
29
+ # unless Dir.exist?(path)
30
+ # FileUtils.mkdir(path)
31
31
  # end
32
32
  #
33
- # if FileTest.exist?(path)
33
+ # # good - atomic and idempotent creation
34
+ # FileUtils.mkdir_p(path)
35
+ #
36
+ # # bad - race condition with another process may result in an error in `remove`
37
+ # if File.exist?(path)
34
38
  # FileUtils.remove(path)
35
39
  # end
36
40
  #
37
- # # good
38
- # FileUtils.mkdir_p(path)
39
- #
40
- # FileUtils.rm_rf(path)
41
+ # # good - atomic and idempotent removal
42
+ # FileUtils.rm_f(path)
41
43
  #
42
44
  class NonAtomicFileOperation < Base
43
45
  extend AutoCorrector
44
46
  include Alignment
45
- include RangeHelp
46
47
 
47
- MSG = 'Remove unnecessary existence checks `%<receiver>s.%<method_name>s`.'
48
- MAKE_METHODS = %i[makedirs mkdir mkdir_p mkpath].freeze
49
- REMOVE_METHODS = %i[remove remove_dir remove_entry remove_entry_secure delete unlink
50
- remove_file rm rm_f rm_r rm_rf rmdir rmtree safe_unlink].freeze
51
- RESTRICT_ON_SEND = (MAKE_METHODS + REMOVE_METHODS).freeze
48
+ MSG_REMOVE_FILE_EXIST_CHECK = 'Remove unnecessary existence check ' \
49
+ '`%<receiver>s.%<method_name>s`.'
50
+ MSG_CHANGE_FORCE_METHOD = 'Use atomic file operation method `FileUtils.%<method_name>s`.'
51
+ MAKE_FORCE_METHODS = %i[makedirs mkdir_p mkpath].freeze
52
+ MAKE_METHODS = %i[mkdir].freeze
53
+ REMOVE_FORCE_METHODS = %i[rm_f rm_rf].freeze
54
+ REMOVE_METHODS = %i[remove remove_dir remove_entry remove_entry_secure
55
+ delete unlink remove_file rm rmdir safe_unlink].freeze
56
+ RESTRICT_ON_SEND = (MAKE_METHODS + MAKE_FORCE_METHODS + REMOVE_METHODS +
57
+ REMOVE_FORCE_METHODS).freeze
52
58
 
53
59
  # @!method send_exist_node(node)
54
60
  def_node_search :send_exist_node, <<-PATTERN
@@ -71,51 +77,85 @@ module RuboCop
71
77
  PATTERN
72
78
 
73
79
  def on_send(node)
74
- return unless node.parent&.if_type?
75
- return if node.parent.else_branch
80
+ return unless if_node_child?(node)
76
81
  return if explicit_not_force?(node)
77
82
  return unless (exist_node = send_exist_node(node.parent).first)
78
83
  return unless exist_node.first_argument == node.first_argument
79
84
 
80
- offense(node, exist_node)
85
+ register_offense(node, exist_node)
81
86
  end
82
87
 
83
88
  private
84
89
 
85
- def offense(node, exist_node)
86
- range = range_between(node.parent.loc.keyword.begin_pos,
87
- exist_node.loc.expression.end_pos)
90
+ def if_node_child?(node)
91
+ return false unless (parent = node.parent)
92
+
93
+ parent.if_type? && !allowable_use_with_if?(parent)
94
+ end
88
95
 
89
- add_offense(range, message: message(exist_node)) do |corrector|
90
- autocorrect(corrector, node, range)
96
+ def allowable_use_with_if?(if_node)
97
+ if_node.condition.and_type? || if_node.condition.or_type? || if_node.else_branch
98
+ end
99
+
100
+ def register_offense(node, exist_node)
101
+ add_offense(node, message: message_change_force_method(node)) unless force_method?(node)
102
+
103
+ parent = node.parent
104
+ range = parent.loc.keyword.begin.join(parent.condition.source_range.end)
105
+
106
+ add_offense(range, message: message_remove_file_exist_check(exist_node)) do |corrector|
107
+ autocorrect(corrector, node, range) unless parent.elsif?
91
108
  end
92
109
  end
93
110
 
94
- def message(node)
111
+ def message_change_force_method(node)
112
+ format(MSG_CHANGE_FORCE_METHOD, method_name: replacement_method(node))
113
+ end
114
+
115
+ def message_remove_file_exist_check(node)
95
116
  receiver, method_name = receiver_and_method_name(node)
96
- format(MSG, receiver: receiver, method_name: method_name)
117
+ format(MSG_REMOVE_FILE_EXIST_CHECK, receiver: receiver, method_name: method_name)
97
118
  end
98
119
 
99
120
  def autocorrect(corrector, node, range)
100
121
  corrector.remove(range)
122
+ autocorrect_replace_method(corrector, node)
123
+
124
+ if node.parent.modifier_form?
125
+ corrector.remove(node.source_range.end.join(node.parent.loc.keyword.begin))
126
+ else
127
+ corrector.remove(node.parent.loc.end)
128
+ end
129
+ end
130
+
131
+ def autocorrect_replace_method(corrector, node)
132
+ return if force_method?(node)
133
+
101
134
  corrector.replace(node.child_nodes.first.loc.name, 'FileUtils')
102
135
  corrector.replace(node.loc.selector, replacement_method(node))
103
- corrector.remove(node.parent.loc.end) if node.parent.multiline?
104
136
  end
105
137
 
106
138
  def replacement_method(node)
107
- return node.method_name if force_option?(node)
108
-
109
139
  if MAKE_METHODS.include?(node.method_name)
110
140
  'mkdir_p'
111
141
  elsif REMOVE_METHODS.include?(node.method_name)
112
- 'rm_rf'
142
+ 'rm_f'
143
+ else
144
+ node.method_name
113
145
  end
114
146
  end
115
147
 
148
+ def force_method?(node)
149
+ force_method_name?(node) || force_option?(node)
150
+ end
151
+
116
152
  def force_option?(node)
117
153
  node.arguments.any? { |arg| force?(arg) }
118
154
  end
155
+
156
+ def force_method_name?(node)
157
+ (MAKE_FORCE_METHODS + REMOVE_FORCE_METHODS).include?(node.method_name)
158
+ end
119
159
  end
120
160
  end
121
161
  end
@@ -74,6 +74,18 @@ module RuboCop
74
74
  end
75
75
  end
76
76
 
77
+ def on_numblock(node)
78
+ return if target_ruby_version >= 3.0
79
+ return unless node.body
80
+ return unless unsorted_dir_loop?(node.send_node)
81
+
82
+ node.argument_list
83
+ .filter { |argument| var_is_required?(node.body, argument.name) }
84
+ .each do
85
+ add_offense(node.send_node) { |corrector| correct_block(corrector, node.send_node) }
86
+ end
87
+ end
88
+
77
89
  def on_block_pass(node)
78
90
  return if target_ruby_version >= 3.0
79
91
  return unless method_require?(node)
@@ -16,7 +16,8 @@ module RuboCop
16
16
  # NOTE: Some values cannot be converted properly using one of the `Kernel`
17
17
  # method (for instance, `Time` and `DateTime` values are allowed by this
18
18
  # cop by default). Similarly, Rails' duration methods do not work well
19
- # with `Integer()` and can be ignored with `IgnoredMethods`.
19
+ # with `Integer()` and can be allowed with `AllowedMethods`. By default,
20
+ # there are no methods to allowed.
20
21
  #
21
22
  # @safety
22
23
  # Autocorrection is unsafe because it is not guaranteed that the
@@ -45,7 +46,22 @@ module RuboCop
45
46
  # foo.try { |i| Float(i) }
46
47
  # bar.send { |i| Complex(i) }
47
48
  #
48
- # @example IgnoredMethods: [minutes]
49
+ # @example AllowedMethods: [] (default)
50
+ #
51
+ # # bad
52
+ # 10.minutes.to_i
53
+ #
54
+ # @example AllowedMethods: [minutes]
55
+ #
56
+ # # good
57
+ # 10.minutes.to_i
58
+ #
59
+ # @example AllowedPatterns: [] (default)
60
+ #
61
+ # # bad
62
+ # 10.minutes.to_i
63
+ #
64
+ # @example AllowedPatterns: ['min*']
49
65
  #
50
66
  # # good
51
67
  # 10.minutes.to_i
@@ -56,7 +72,8 @@ module RuboCop
56
72
  # Time.now.to_datetime.to_i
57
73
  class NumberConversion < Base
58
74
  extend AutoCorrector
59
- include IgnoredMethods
75
+ include AllowedMethods
76
+ include AllowedPattern
60
77
 
61
78
  CONVERSION_METHOD_CLASS_MAPPING = {
62
79
  to_i: "#{Integer.name}(%<number_object>s, 10)",
@@ -91,7 +108,7 @@ module RuboCop
91
108
 
92
109
  def handle_conversion_method(node)
93
110
  to_method(node) do |receiver, to_method|
94
- next if receiver.nil? || ignore_receiver?(receiver)
111
+ next if receiver.nil? || allow_receiver?(receiver)
95
112
 
96
113
  message = format(
97
114
  MSG,
@@ -135,9 +152,10 @@ module RuboCop
135
152
  corrector.remove(node.loc.end)
136
153
  end
137
154
 
138
- def ignore_receiver?(receiver)
155
+ def allow_receiver?(receiver)
139
156
  if receiver.numeric_type? || (receiver.send_type? &&
140
- (conversion_method?(receiver.method_name) || ignored_method?(receiver.method_name)))
157
+ (conversion_method?(receiver.method_name) ||
158
+ allowed_method_name?(receiver.method_name)))
141
159
  true
142
160
  elsif (receiver = top_receiver(receiver))
143
161
  receiver.const_type? && ignored_class?(receiver.const_name)
@@ -146,6 +164,10 @@ module RuboCop
146
164
  end
147
165
  end
148
166
 
167
+ def allowed_method_name?(name)
168
+ allowed_method?(name) || matches_allowed_pattern?(name)
169
+ end
170
+
149
171
  def top_receiver(node)
150
172
  receiver = node
151
173
  receiver = receiver.receiver until receiver.receiver.nil?
@@ -6,13 +6,13 @@ module RuboCop
6
6
  # Checks for uses of numbered parameter assignment.
7
7
  # It emulates the following warning in Ruby 2.7:
8
8
  #
9
- # % ruby -ve '_1 = :value'
9
+ # $ ruby -ve '_1 = :value'
10
10
  # ruby 2.7.2p137 (2020-10-01 revision 5445e04352) [x86_64-darwin19]
11
11
  # -e:1: warning: `_1' is reserved for numbered parameter; consider another name
12
12
  #
13
13
  # Assigning to a numbered parameter (from `_1` to `_9`) causes an error in Ruby 3.0.
14
14
  #
15
- # % ruby -ve '_1 = :value'
15
+ # $ ruby -ve '_1 = :value'
16
16
  # ruby 3.0.0p0 (2020-12-25 revision 95aff21468) [x86_64-darwin19]
17
17
  # -e:1: _1 is reserved for numbered parameter
18
18
  #
@@ -31,6 +31,8 @@ module RuboCop
31
31
  return unless lhs&.casgn_type?
32
32
 
33
33
  add_offense(node.loc.operator) do |corrector|
34
+ next if node.each_ancestor(:def, :defs).any?
35
+
34
36
  corrector.replace(node.loc.operator, '=')
35
37
  end
36
38
  end
@@ -7,6 +7,9 @@ module RuboCop
7
7
  # Checks the proper ordering of magic comments and whether
8
8
  # a magic comment is not placed before a shebang.
9
9
  #
10
+ # @safety
11
+ # This cop's autocorrection is unsafe because file encoding may change.
12
+ #
10
13
  # @example
11
14
  # # bad
12
15
  #
@@ -61,7 +64,7 @@ module RuboCop
61
64
  def magic_comment_lines
62
65
  lines = [nil, nil]
63
66
 
64
- magic_comments.each.with_index do |comment, index|
67
+ leading_magic_comments.each.with_index do |comment, index|
65
68
  if comment.encoding_specified?
66
69
  lines[0] = index
67
70
  elsif comment.frozen_string_literal_specified?
@@ -73,10 +76,6 @@ module RuboCop
73
76
 
74
77
  lines
75
78
  end
76
-
77
- def magic_comments
78
- leading_comment_lines.map { |line| MagicComment.parse(line) }
79
- end
80
79
  end
81
80
  end
82
81
  end
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Lint
6
- # This cops looks for references of Regexp captures that are out of range
6
+ # Looks for references of Regexp captures that are out of range
7
7
  # and thus always returns nil.
8
8
  #
9
9
  # @safety
@@ -65,7 +65,13 @@ module RuboCop
65
65
  def on_when(node)
66
66
  regexp_conditions = node.conditions.select(&:regexp_type?)
67
67
 
68
- @valid_ref = regexp_conditions.map { |condition| check_regexp(condition) }.compact.max
68
+ @valid_ref = regexp_conditions.filter_map { |condition| check_regexp(condition) }.max
69
+ end
70
+
71
+ def on_in_pattern(node)
72
+ regexp_patterns = regexp_patterns(node)
73
+
74
+ @valid_ref = regexp_patterns.filter_map { |pattern| check_regexp(pattern) }.max
69
75
  end
70
76
 
71
77
  def on_nth_ref(node)
@@ -84,6 +90,15 @@ module RuboCop
84
90
 
85
91
  private
86
92
 
93
+ def regexp_patterns(in_node)
94
+ pattern = in_node.pattern
95
+ if pattern.regexp_type?
96
+ [pattern]
97
+ else
98
+ pattern.each_descendant(:regexp).to_a
99
+ end
100
+ end
101
+
87
102
  def check_regexp(node)
88
103
  return if node.interpolation?
89
104
 
@@ -40,11 +40,16 @@ module RuboCop
40
40
  unless node.arguments.one? && first_argument_starts_with_left_parenthesis?(node)
41
41
  return true
42
42
  end
43
+ return true if first_argument_block_type?(node.first_argument)
43
44
 
44
45
  node.operator_method? || node.setter_method? || chained_calls?(node) ||
45
46
  valid_first_argument?(node.first_argument)
46
47
  end
47
48
 
49
+ def first_argument_block_type?(first_arg)
50
+ first_arg.block_type? || first_arg.numblock_type?
51
+ end
52
+
48
53
  def valid_first_argument?(first_arg)
49
54
  first_arg.operator_keyword? || first_arg.hash_type? || ternary_expression?(first_arg)
50
55
  end
@@ -50,7 +50,7 @@ module RuboCop
50
50
 
51
51
  add_offense(node) do |corrector|
52
52
  node.each_value do |value|
53
- range = value.loc.expression
53
+ range = value.source_range
54
54
 
55
55
  match = range.source.match(TRAILING_QUOTE)
56
56
  corrector.remove_trailing(range, match[0].length) if match
@@ -41,7 +41,7 @@ module RuboCop
41
41
 
42
42
  def autocorrect(corrector, node)
43
43
  node.children.each do |child|
44
- range = child.loc.expression
44
+ range = child.source_range
45
45
 
46
46
  corrector.remove_trailing(range, 1) if range.source.end_with?(',')
47
47
  corrector.remove_leading(range, 1) if
@@ -113,6 +113,7 @@ module RuboCop
113
113
  def each_line_range(cop, line_ranges)
114
114
  line_ranges.each_with_index do |line_range, line_range_index|
115
115
  next if ignore_offense?(line_range)
116
+ next if expected_final_disable?(cop, line_range)
116
117
 
117
118
  comment = processed_source.comment_at_line(line_range.begin)
118
119
  redundant = if all_disabled?(comment)
@@ -127,23 +128,35 @@ module RuboCop
127
128
  end
128
129
  end
129
130
 
131
+ # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
130
132
  def each_already_disabled(cop, line_ranges)
131
133
  line_ranges.each_cons(2) do |previous_range, range|
132
134
  next if ignore_offense?(range)
133
- next unless followed_ranges?(previous_range, range)
134
-
135
135
  # If a cop is disabled in a range that begins on the same line as
136
136
  # the end of the previous range, it means that the cop was
137
137
  # already disabled by an earlier comment. So it's redundant
138
138
  # whether there are offenses or not.
139
+ next unless followed_ranges?(previous_range, range)
140
+
139
141
  comment = processed_source.comment_at_line(range.begin)
140
142
 
143
+ next unless comment
141
144
  # Comments disabling all cops don't count since it's reasonable
142
145
  # to disable a few select cops first and then all cops further
143
146
  # down in the code.
144
- yield comment, cop if comment && !all_disabled?(comment)
147
+ next if all_disabled?(comment)
148
+
149
+ redundant =
150
+ if department_disabled?(cop, comment)
151
+ find_redundant_department(cop, range)
152
+ else
153
+ cop
154
+ end
155
+
156
+ yield comment, redundant if redundant
145
157
  end
146
158
  end
159
+ # rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
147
160
 
148
161
  def find_redundant_cop(cop, range)
149
162
  cop_offenses = offenses_to_check.select { |offense| offense.cop_name == cop }
@@ -179,11 +192,21 @@ module RuboCop
179
192
  end
180
193
 
181
194
  def ignore_offense?(line_range)
195
+ return true if line_range.min == CommentConfig::CONFIG_DISABLED_LINE_RANGE_MIN
196
+
182
197
  disabled_ranges.any? do |range|
183
198
  range.cover?(line_range.min) && range.cover?(line_range.max)
184
199
  end
185
200
  end
186
201
 
202
+ def expected_final_disable?(cop, line_range)
203
+ # A cop which is disabled in the config is being re-disabled until end of file
204
+ cop_class = RuboCop::Cop::Registry.global.find_by_cop_name cop
205
+ cop_class &&
206
+ !processed_source.registry.enabled?(cop_class, config) &&
207
+ line_range.max == Float::INFINITY
208
+ end
209
+
187
210
  def department_disabled?(cop, comment)
188
211
  directive = DirectiveComment.new(comment)
189
212
  directive.in_directive_department?(cop) && !directive.overridden_by_department?(cop)
@@ -208,8 +231,13 @@ module RuboCop
208
231
  cop_names = cops.sort.map { |c| describe(c) }.join(', ')
209
232
 
210
233
  add_offense(location, message: message(cop_names)) do |corrector|
211
- range = comment_range_with_surrounding_space(location, comment.loc.expression)
212
- corrector.remove(range)
234
+ range = comment_range_with_surrounding_space(location, comment.source_range)
235
+
236
+ if leave_free_comment?(comment, range)
237
+ corrector.replace(range, ' # ')
238
+ else
239
+ corrector.remove(range)
240
+ end
213
241
  end
214
242
  end
215
243
 
@@ -227,10 +255,16 @@ module RuboCop
227
255
  end
228
256
  end
229
257
 
258
+ def leave_free_comment?(comment, range)
259
+ free_comment = comment.text.gsub(range.source.strip, '')
260
+
261
+ !free_comment.empty? && !free_comment.start_with?('#')
262
+ end
263
+
230
264
  def cop_range(comment, cop)
231
265
  cop = remove_department_marker(cop)
232
- matching_range(comment.loc.expression, cop) ||
233
- matching_range(comment.loc.expression, Badge.parse(cop).cop_name) ||
266
+ matching_range(comment.source_range, cop) ||
267
+ matching_range(comment.source_range, Badge.parse(cop).cop_name) ||
234
268
  raise("Couldn't find #{cop} in comment: #{comment.text}")
235
269
  end
236
270
 
@@ -247,15 +281,21 @@ module RuboCop
247
281
  .drop_while { |r| !r.equal?(range) }
248
282
  .each_cons(2)
249
283
  .map { |range1, range2| range1.end.join(range2.begin).source }
250
- .all? { |intervening| /\A\s*,\s*\Z/.match?(intervening) }
284
+ .all?(/\A\s*,\s*\z/)
285
+ end
286
+
287
+ SIMILAR_COP_NAMES_CACHE = Hash.new do |hash, cop_name|
288
+ hash[:all_cop_names] = Registry.global.names unless hash.key?(:all_cop_names)
289
+ hash[cop_name] = NameSimilarity.find_similar_name(cop_name, hash[:all_cop_names])
251
290
  end
291
+ private_constant :SIMILAR_COP_NAMES_CACHE
252
292
 
253
293
  def describe(cop)
254
294
  return 'all cops' if cop == 'all'
255
295
  return "`#{remove_department_marker(cop)}` department" if department_marker?(cop)
256
296
  return "`#{cop}`" if all_cop_names.include?(cop)
257
297
 
258
- similar = NameSimilarity.find_similar_name(cop, all_cop_names)
298
+ similar = SIMILAR_COP_NAMES_CACHE[cop]
259
299
  similar ? "`#{cop}` (did you mean `#{similar}`?)" : "`#{cop}` (unknown cop)"
260
300
  end
261
301
 
@@ -42,7 +42,7 @@ module RuboCop
42
42
  MSG = 'Unnecessary enabling of %<cop>s.'
43
43
 
44
44
  def on_new_investigation
45
- return if processed_source.blank?
45
+ return if processed_source.blank? || !processed_source.raw_source.include?('enable')
46
46
 
47
47
  offenses = processed_source.comment_config.extra_enabled_comments
48
48
  offenses.each { |comment, cop_names| register_offense(comment, cop_names) }
@@ -74,7 +74,7 @@ module RuboCop
74
74
  end
75
75
 
76
76
  def comment_start(comment)
77
- comment.loc.expression.begin_pos
77
+ comment.source_range.begin_pos
78
78
  end
79
79
 
80
80
  def cop_name_indention(comment, name)
@@ -82,7 +82,7 @@ module RuboCop
82
82
  end
83
83
 
84
84
  def range_with_comma(comment, name)
85
- source = comment.loc.expression.source
85
+ source = comment.source
86
86
 
87
87
  begin_pos = cop_name_indention(comment, name)
88
88
  end_pos = begin_pos + name.size
@@ -94,14 +94,14 @@ module RuboCop
94
94
 
95
95
  def range_to_remove(begin_pos, end_pos, comment)
96
96
  start = comment_start(comment)
97
- source = comment.loc.expression.source
97
+ source = comment.source
98
98
 
99
99
  if source[begin_pos - 1] == ','
100
100
  range_with_comma_before(start, begin_pos, end_pos)
101
101
  elsif source[end_pos] == ','
102
102
  range_with_comma_after(comment, start, begin_pos, end_pos)
103
103
  else
104
- range_between(start, comment.loc.expression.end_pos)
104
+ range_between(start, comment.source_range.end_pos)
105
105
  end
106
106
  end
107
107
 
@@ -112,7 +112,7 @@ module RuboCop
112
112
  # If the list of cops is comma-separated, but without a empty space after the comma,
113
113
  # we should **not** remove the prepending empty space, thus begin_pos += 1
114
114
  def range_with_comma_after(comment, start, begin_pos, end_pos)
115
- begin_pos += 1 if comment.loc.expression.source[end_pos + 1] != ' '
115
+ begin_pos += 1 if comment.source[end_pos + 1] != ' '
116
116
 
117
117
  range_between(start + begin_pos, start + end_pos + 1)
118
118
  end
@@ -41,6 +41,7 @@ module RuboCop
41
41
  return unless (receiver = node.receiver)
42
42
  return unless receiver.receiver&.const_type? && receiver.receiver.short_name == :Dir
43
43
  return unless GLOB_METHODS.include?(receiver.method_name)
44
+ return if multiple_argument?(receiver)
44
45
 
45
46
  selector = node.loc.selector
46
47
 
@@ -49,6 +50,12 @@ module RuboCop
49
50
  corrector.remove(node.loc.dot)
50
51
  end
51
52
  end
53
+
54
+ private
55
+
56
+ def multiple_argument?(glob_method)
57
+ glob_method.arguments.count >= 2 || glob_method.first_argument&.splat_type?
58
+ end
52
59
  end
53
60
  end
54
61
  end