rubocop 1.71.1 → 1.92.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (712) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +23 -19
  4. data/config/default.yml +886 -168
  5. data/config/internal_affairs.yml +20 -0
  6. data/config/obsoletion.yml +47 -4
  7. data/exe/rubocop +2 -9
  8. data/lib/rubocop/cache_config.rb +29 -0
  9. data/lib/rubocop/cached_data.rb +50 -5
  10. data/lib/rubocop/changed_files.rb +134 -0
  11. data/lib/rubocop/cli/command/auto_generate_config.rb +36 -4
  12. data/lib/rubocop/cli/command/cop_names.rb +57 -0
  13. data/lib/rubocop/cli/command/execute_runner.rb +54 -3
  14. data/lib/rubocop/cli/command/explain.rb +34 -0
  15. data/lib/rubocop/cli/command/list_enabled_cops_for.rb +40 -0
  16. data/lib/rubocop/cli/command/lsp.rb +1 -1
  17. data/lib/rubocop/cli/command/mcp.rb +19 -0
  18. data/lib/rubocop/cli/command/show_cops.rb +8 -2
  19. data/lib/rubocop/cli/command/show_docs_url.rb +8 -10
  20. data/lib/rubocop/cli/command/suggest_extensions.rb +8 -2
  21. data/lib/rubocop/cli.rb +59 -17
  22. data/lib/rubocop/comment_config/directive_range.rb +34 -0
  23. data/lib/rubocop/comment_config/disable_next.rb +143 -0
  24. data/lib/rubocop/comment_config/push_pop.rb +55 -0
  25. data/lib/rubocop/comment_config.rb +98 -45
  26. data/lib/rubocop/config.rb +137 -19
  27. data/lib/rubocop/config_finder.rb +1 -1
  28. data/lib/rubocop/config_loader.rb +75 -49
  29. data/lib/rubocop/config_loader_resolver.rb +124 -33
  30. data/lib/rubocop/config_obsoletion/cop_rule.rb +2 -1
  31. data/lib/rubocop/config_obsoletion/extracted_cop.rb +6 -3
  32. data/lib/rubocop/config_obsoletion/removed_cop.rb +9 -1
  33. data/lib/rubocop/config_obsoletion/renamed_cop.rb +18 -3
  34. data/lib/rubocop/config_obsoletion.rb +47 -3
  35. data/lib/rubocop/config_store.rb +7 -2
  36. data/lib/rubocop/config_validator.rb +75 -12
  37. data/lib/rubocop/cop/autocorrect_logic.rb +43 -17
  38. data/lib/rubocop/cop/badge.rb +10 -2
  39. data/lib/rubocop/cop/base.rb +128 -35
  40. data/lib/rubocop/cop/bundler/gem_comment.rb +5 -4
  41. data/lib/rubocop/cop/bundler/gem_version.rb +28 -28
  42. data/lib/rubocop/cop/bundler/ordered_gems.rb +2 -11
  43. data/lib/rubocop/cop/bundler.rb +19 -0
  44. data/lib/rubocop/cop/commissioner.rb +13 -11
  45. data/lib/rubocop/cop/cop_documentation.rb +81 -0
  46. data/lib/rubocop/cop/cop_explanation.rb +140 -0
  47. data/lib/rubocop/cop/corrector.rb +4 -4
  48. data/lib/rubocop/cop/correctors/alignment_corrector.rb +92 -11
  49. data/lib/rubocop/cop/correctors/condition_corrector.rb +1 -1
  50. data/lib/rubocop/cop/correctors/each_to_for_corrector.rb +37 -7
  51. data/lib/rubocop/cop/correctors/empty_line_corrector.rb +1 -1
  52. data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +7 -2
  53. data/lib/rubocop/cop/correctors/lambda_literal_to_method_corrector.rb +31 -4
  54. data/lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +35 -5
  55. data/lib/rubocop/cop/correctors/ordered_gem_corrector.rb +8 -1
  56. data/lib/rubocop/cop/correctors/parentheses_corrector.rb +73 -2
  57. data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +2 -2
  58. data/lib/rubocop/cop/correctors.rb +28 -0
  59. data/lib/rubocop/cop/documentation.rb +3 -4
  60. data/lib/rubocop/cop/exclude_limit.rb +31 -5
  61. data/lib/rubocop/cop/gemspec/attribute_assignment.rb +91 -0
  62. data/lib/rubocop/cop/gemspec/dependency_version.rb +0 -6
  63. data/lib/rubocop/cop/gemspec/development_dependencies.rb +1 -1
  64. data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +49 -17
  65. data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +2 -9
  66. data/lib/rubocop/cop/gemspec/require_mfa.rb +22 -5
  67. data/lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb +12 -7
  68. data/lib/rubocop/cop/gemspec.rb +22 -0
  69. data/lib/rubocop/cop/generator/registration_injector.rb +188 -0
  70. data/lib/rubocop/cop/generator.rb +5 -1
  71. data/lib/rubocop/cop/internal_affairs/example_description.rb +9 -5
  72. data/lib/rubocop/cop/internal_affairs/example_heredoc_delimiter.rb +8 -8
  73. data/lib/rubocop/cop/internal_affairs/itblock_handler.rb +69 -0
  74. data/lib/rubocop/cop/internal_affairs/location_exists.rb +142 -0
  75. data/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +1 -0
  76. data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +16 -20
  77. data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_processor.rb +1 -1
  78. data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_walker.rb +1 -2
  79. data/lib/rubocop/cop/internal_affairs/node_pattern_groups.rb +6 -2
  80. data/lib/rubocop/cop/internal_affairs/node_type_group.rb +85 -0
  81. data/lib/rubocop/cop/internal_affairs/on_send_without_on_csend.rb +2 -2
  82. data/lib/rubocop/cop/internal_affairs/plugin.rb +33 -0
  83. data/lib/rubocop/cop/internal_affairs/redundant_context_config_parameter.rb +1 -7
  84. data/lib/rubocop/cop/internal_affairs/redundant_described_class_as_subject.rb +6 -5
  85. data/lib/rubocop/cop/internal_affairs/redundant_let_rubocop_config_new.rb +5 -3
  86. data/lib/rubocop/cop/internal_affairs/style_detected_api_use.rb +1 -7
  87. data/lib/rubocop/cop/internal_affairs/undefined_config.rb +13 -2
  88. data/lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +4 -4
  89. data/lib/rubocop/cop/internal_affairs/useless_restrict_on_send.rb +1 -1
  90. data/lib/rubocop/cop/internal_affairs.rb +3 -16
  91. data/lib/rubocop/cop/layout/argument_alignment.rb +9 -3
  92. data/lib/rubocop/cop/layout/array_alignment.rb +1 -1
  93. data/lib/rubocop/cop/layout/begin_end_alignment.rb +1 -1
  94. data/lib/rubocop/cop/layout/block_alignment.rb +86 -4
  95. data/lib/rubocop/cop/layout/block_end_newline.rb +1 -0
  96. data/lib/rubocop/cop/layout/case_indentation.rb +28 -10
  97. data/lib/rubocop/cop/layout/class_structure.rb +191 -41
  98. data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +5 -5
  99. data/lib/rubocop/cop/layout/comment_indentation.rb +17 -7
  100. data/lib/rubocop/cop/layout/condition_position.rb +13 -3
  101. data/lib/rubocop/cop/layout/def_end_alignment.rb +5 -1
  102. data/lib/rubocop/cop/layout/dot_position.rb +27 -17
  103. data/lib/rubocop/cop/layout/else_alignment.rb +3 -15
  104. data/lib/rubocop/cop/layout/empty_comment.rb +8 -10
  105. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +27 -9
  106. data/lib/rubocop/cop/layout/empty_line_after_magic_comment.rb +63 -5
  107. data/lib/rubocop/cop/layout/empty_line_after_multiline_condition.rb +21 -8
  108. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +46 -21
  109. data/lib/rubocop/cop/layout/empty_lines.rb +5 -2
  110. data/lib/rubocop/cop/layout/empty_lines_after_module_inclusion.rb +101 -0
  111. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +34 -4
  112. data/lib/rubocop/cop/layout/empty_lines_around_arguments.rb +8 -29
  113. data/lib/rubocop/cop/layout/empty_lines_around_attribute_accessor.rb +2 -0
  114. data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +22 -5
  115. data/lib/rubocop/cop/layout/empty_lines_around_class_body.rb +17 -3
  116. data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +23 -1
  117. data/lib/rubocop/cop/layout/empty_lines_around_method_body.rb +22 -2
  118. data/lib/rubocop/cop/layout/empty_lines_around_module_body.rb +16 -2
  119. data/lib/rubocop/cop/layout/end_alignment.rb +23 -15
  120. data/lib/rubocop/cop/layout/extra_spacing.rb +109 -3
  121. data/lib/rubocop/cop/layout/first_argument_indentation.rb +82 -3
  122. data/lib/rubocop/cop/layout/first_array_element_indentation.rb +18 -5
  123. data/lib/rubocop/cop/layout/first_array_element_line_break.rb +41 -0
  124. data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +36 -23
  125. data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +25 -25
  126. data/lib/rubocop/cop/layout/first_method_argument_line_break.rb +6 -0
  127. data/lib/rubocop/cop/layout/first_method_parameter_line_break.rb +4 -0
  128. data/lib/rubocop/cop/layout/first_parameter_indentation.rb +11 -0
  129. data/lib/rubocop/cop/layout/hash_alignment.rb +20 -18
  130. data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +9 -5
  131. data/lib/rubocop/cop/layout/heredoc_indentation.rb +48 -3
  132. data/lib/rubocop/cop/layout/indentation_consistency.rb +22 -5
  133. data/lib/rubocop/cop/layout/indentation_style.rb +5 -2
  134. data/lib/rubocop/cop/layout/indentation_width.rb +159 -12
  135. data/lib/rubocop/cop/layout/leading_comment_space.rb +40 -1
  136. data/lib/rubocop/cop/layout/line_continuation_spacing.rb +10 -4
  137. data/lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb +25 -9
  138. data/lib/rubocop/cop/layout/line_length.rb +300 -31
  139. data/lib/rubocop/cop/layout/multiline_array_brace_layout.rb +69 -57
  140. data/lib/rubocop/cop/layout/multiline_assignment_layout.rb +8 -2
  141. data/lib/rubocop/cop/layout/multiline_block_layout.rb +11 -1
  142. data/lib/rubocop/cop/layout/multiline_hash_brace_layout.rb +65 -56
  143. data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +7 -1
  144. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +270 -40
  145. data/lib/rubocop/cop/layout/multiline_method_definition_brace_layout.rb +4 -0
  146. data/lib/rubocop/cop/layout/multiline_method_parameter_line_breaks.rb +1 -0
  147. data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +9 -5
  148. data/lib/rubocop/cop/layout/parameter_alignment.rb +1 -1
  149. data/lib/rubocop/cop/layout/redundant_line_break.rb +111 -7
  150. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +29 -9
  151. data/lib/rubocop/cop/layout/single_line_block_chain.rb +10 -2
  152. data/lib/rubocop/cop/layout/space_after_comma.rb +2 -10
  153. data/lib/rubocop/cop/layout/space_after_not.rb +5 -0
  154. data/lib/rubocop/cop/layout/space_after_semicolon.rb +11 -1
  155. data/lib/rubocop/cop/layout/space_around_block_parameters.rb +10 -4
  156. data/lib/rubocop/cop/layout/space_around_keyword.rb +20 -3
  157. data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +1 -1
  158. data/lib/rubocop/cop/layout/space_around_operators.rb +30 -4
  159. data/lib/rubocop/cop/layout/space_before_block_braces.rb +5 -1
  160. data/lib/rubocop/cop/layout/space_before_brackets.rb +6 -39
  161. data/lib/rubocop/cop/layout/space_in_lambda_literal.rb +9 -8
  162. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +55 -36
  163. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +32 -8
  164. data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +3 -0
  165. data/lib/rubocop/cop/layout/space_inside_reference_brackets.rb +2 -12
  166. data/lib/rubocop/cop/layout/trailing_whitespace.rb +1 -1
  167. data/lib/rubocop/cop/layout.rb +114 -0
  168. data/lib/rubocop/cop/lazy_loader.rb +41 -0
  169. data/lib/rubocop/cop/lint/ambiguous_assignment.rb +9 -17
  170. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +72 -1
  171. data/lib/rubocop/cop/lint/ambiguous_operator.rb +1 -1
  172. data/lib/rubocop/cop/lint/ambiguous_operator_precedence.rb +3 -11
  173. data/lib/rubocop/cop/lint/ambiguous_range.rb +6 -2
  174. data/lib/rubocop/cop/lint/ambiguous_regexp_literal.rb +6 -1
  175. data/lib/rubocop/cop/lint/argument_mismatch.rb +99 -0
  176. data/lib/rubocop/cop/lint/array_literal_in_regexp.rb +2 -3
  177. data/lib/rubocop/cop/lint/assignment_in_condition.rb +15 -1
  178. data/lib/rubocop/cop/lint/boolean_symbol.rb +1 -1
  179. data/lib/rubocop/cop/lint/circular_argument_reference.rb +47 -8
  180. data/lib/rubocop/cop/lint/constant_overwritten_in_rescue.rb +4 -3
  181. data/lib/rubocop/cop/lint/constant_reassignment.rb +94 -15
  182. data/lib/rubocop/cop/lint/constant_resolution.rb +31 -6
  183. data/lib/rubocop/cop/lint/cop_directive_syntax.rb +240 -0
  184. data/lib/rubocop/cop/lint/data_define_override.rb +63 -0
  185. data/lib/rubocop/cop/lint/debugger.rb +13 -4
  186. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +1 -1
  187. data/lib/rubocop/cop/lint/deprecated_constants.rb +2 -8
  188. data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +5 -2
  189. data/lib/rubocop/cop/lint/deprecated_reference.rb +194 -0
  190. data/lib/rubocop/cop/lint/duplicate_match_pattern.rb +4 -4
  191. data/lib/rubocop/cop/lint/duplicate_methods.rb +506 -41
  192. data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +5 -42
  193. data/lib/rubocop/cop/lint/else_layout.rb +19 -0
  194. data/lib/rubocop/cop/lint/empty_block.rb +4 -4
  195. data/lib/rubocop/cop/lint/empty_conditional_body.rb +22 -65
  196. data/lib/rubocop/cop/lint/empty_expression.rb +0 -2
  197. data/lib/rubocop/cop/lint/empty_in_pattern.rb +8 -1
  198. data/lib/rubocop/cop/lint/empty_interpolation.rb +14 -1
  199. data/lib/rubocop/cop/lint/empty_when.rb +8 -1
  200. data/lib/rubocop/cop/lint/ensure_return.rb +19 -1
  201. data/lib/rubocop/cop/lint/erb_new_arguments.rb +4 -8
  202. data/lib/rubocop/cop/lint/float_comparison.rb +33 -10
  203. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +1 -1
  204. data/lib/rubocop/cop/lint/heredoc_method_call_position.rb +4 -0
  205. data/lib/rubocop/cop/lint/identity_comparison.rb +19 -15
  206. data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +1 -2
  207. data/lib/rubocop/cop/lint/incompatible_io_select_with_fiber_scheduler.rb +5 -1
  208. data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +1 -2
  209. data/lib/rubocop/cop/lint/inherit_exception.rb +53 -7
  210. data/lib/rubocop/cop/lint/interpolation_check.rb +25 -6
  211. data/lib/rubocop/cop/lint/lambda_without_literal_block.rb +1 -1
  212. data/lib/rubocop/cop/lint/literal_as_condition.rb +152 -11
  213. data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +11 -1
  214. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +75 -37
  215. data/lib/rubocop/cop/lint/loop.rb +24 -2
  216. data/lib/rubocop/cop/lint/misplaced_magic_comment.rb +245 -0
  217. data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +60 -23
  218. data/lib/rubocop/cop/lint/missing_super.rb +31 -1
  219. data/lib/rubocop/cop/lint/mixed_case_range.rb +2 -2
  220. data/lib/rubocop/cop/lint/multiple_comparison.rb +2 -2
  221. data/lib/rubocop/cop/lint/name_typo.rb +270 -0
  222. data/lib/rubocop/cop/lint/nested_method_definition.rb +2 -2
  223. data/lib/rubocop/cop/lint/next_without_accumulator.rb +2 -0
  224. data/lib/rubocop/cop/lint/no_return_in_begin_end_blocks.rb +20 -0
  225. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +4 -2
  226. data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +4 -4
  227. data/lib/rubocop/cop/lint/number_conversion.rb +22 -11
  228. data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +1 -1
  229. data/lib/rubocop/cop/lint/numeric_operation_with_constant_result.rb +11 -0
  230. data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +1 -1
  231. data/lib/rubocop/cop/lint/ordered_magic_comments.rb +7 -7
  232. data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +15 -4
  233. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +20 -14
  234. data/lib/rubocop/cop/lint/raise_exception.rb +30 -11
  235. data/lib/rubocop/cop/lint/rand_one.rb +1 -1
  236. data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +160 -39
  237. data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +53 -19
  238. data/lib/rubocop/cop/lint/redundant_dir_glob_sort.rb +28 -6
  239. data/lib/rubocop/cop/lint/redundant_regexp_quantifiers.rb +1 -1
  240. data/lib/rubocop/cop/lint/redundant_require_statement.rb +5 -25
  241. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +134 -12
  242. data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +13 -4
  243. data/lib/rubocop/cop/lint/redundant_type_conversion.rb +267 -0
  244. data/lib/rubocop/cop/lint/redundant_with_index.rb +5 -3
  245. data/lib/rubocop/cop/lint/redundant_with_object.rb +8 -0
  246. data/lib/rubocop/cop/lint/refinement_import_methods.rb +8 -1
  247. data/lib/rubocop/cop/lint/regexp_as_condition.rb +9 -1
  248. data/lib/rubocop/cop/lint/require_parentheses.rb +13 -4
  249. data/lib/rubocop/cop/lint/require_range_parentheses.rb +3 -2
  250. data/lib/rubocop/cop/lint/require_relative_self_path.rb +7 -5
  251. data/lib/rubocop/cop/lint/rescue_exception.rb +1 -4
  252. data/lib/rubocop/cop/lint/rescue_type.rb +2 -2
  253. data/lib/rubocop/cop/lint/return_in_void_context.rb +9 -11
  254. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +28 -4
  255. data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +56 -6
  256. data/lib/rubocop/cop/lint/safe_navigation_with_empty.rb +1 -1
  257. data/lib/rubocop/cop/lint/script_permission.rb +5 -1
  258. data/lib/rubocop/cop/lint/self_assignment.rb +63 -6
  259. data/lib/rubocop/cop/lint/send_with_mixin_argument.rb +1 -1
  260. data/lib/rubocop/cop/lint/shadowed_argument.rb +7 -7
  261. data/lib/rubocop/cop/lint/shadowed_exception.rb +1 -1
  262. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +27 -1
  263. data/lib/rubocop/cop/lint/shared_mutable_default.rb +14 -1
  264. data/lib/rubocop/cop/lint/struct_new_override.rb +17 -1
  265. data/lib/rubocop/cop/lint/super_argument_mismatch.rb +179 -0
  266. data/lib/rubocop/cop/lint/suppressed_exception.rb +1 -1
  267. data/lib/rubocop/cop/lint/suppressed_exception_in_number_conversion.rb +122 -0
  268. data/lib/rubocop/cop/lint/symbol_conversion.rb +22 -4
  269. data/lib/rubocop/cop/lint/syntax.rb +25 -1
  270. data/lib/rubocop/cop/lint/to_enum_arguments.rb +73 -5
  271. data/lib/rubocop/cop/lint/to_json.rb +20 -17
  272. data/lib/rubocop/cop/lint/top_level_return_with_argument.rb +1 -1
  273. data/lib/rubocop/cop/lint/trailing_comma_in_attribute_declaration.rb +5 -1
  274. data/lib/rubocop/cop/lint/unescaped_bracket_in_regexp.rb +54 -11
  275. data/lib/rubocop/cop/lint/unexpected_block_arity.rb +2 -0
  276. data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +2 -1
  277. data/lib/rubocop/cop/lint/unreachable_code.rb +16 -9
  278. data/lib/rubocop/cop/lint/unreachable_loop.rb +5 -5
  279. data/lib/rubocop/cop/lint/unreachable_pattern_branch.rb +113 -0
  280. data/lib/rubocop/cop/lint/unused_method_argument.rb +10 -0
  281. data/lib/rubocop/cop/lint/unused_private_method.rb +234 -0
  282. data/lib/rubocop/cop/lint/uri_escape_unescape.rb +2 -0
  283. data/lib/rubocop/cop/lint/useless_access_modifier.rb +31 -6
  284. data/lib/rubocop/cop/lint/useless_assignment.rb +63 -27
  285. data/lib/rubocop/cop/lint/useless_constant_scoping.rb +107 -0
  286. data/lib/rubocop/cop/lint/useless_default_value_argument.rb +92 -0
  287. data/lib/rubocop/cop/lint/useless_method_definition.rb +1 -1
  288. data/lib/rubocop/cop/lint/useless_numeric_operation.rb +11 -10
  289. data/lib/rubocop/cop/lint/useless_or.rb +111 -0
  290. data/lib/rubocop/cop/lint/useless_rescue.rb +2 -3
  291. data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +13 -7
  292. data/lib/rubocop/cop/lint/useless_setter_call.rb +11 -5
  293. data/lib/rubocop/cop/lint/useless_times.rb +22 -1
  294. data/lib/rubocop/cop/lint/utils/nil_receiver_checker.rb +201 -0
  295. data/lib/rubocop/cop/lint/void.rb +68 -22
  296. data/lib/rubocop/cop/lint.rb +179 -0
  297. data/lib/rubocop/cop/message_annotator.rb +7 -3
  298. data/lib/rubocop/cop/metrics/abc_size.rb +1 -1
  299. data/lib/rubocop/cop/metrics/block_length.rb +2 -1
  300. data/lib/rubocop/cop/metrics/block_nesting.rb +23 -0
  301. data/lib/rubocop/cop/metrics/class_length.rb +4 -2
  302. data/lib/rubocop/cop/metrics/collection_literal_length.rb +1 -1
  303. data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +0 -4
  304. data/lib/rubocop/cop/metrics/method_length.rb +3 -2
  305. data/lib/rubocop/cop/metrics/module_length.rb +4 -2
  306. data/lib/rubocop/cop/metrics/perceived_complexity.rb +37 -7
  307. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +4 -3
  308. data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +2 -2
  309. data/lib/rubocop/cop/metrics/utils/iterating_block.rb +1 -1
  310. data/lib/rubocop/cop/metrics/utils/repeated_attribute_discount.rb +7 -7
  311. data/lib/rubocop/cop/metrics.rb +31 -0
  312. data/lib/rubocop/cop/migration/department_name.rb +11 -5
  313. data/lib/rubocop/cop/migration.rb +13 -0
  314. data/lib/rubocop/cop/mixin/alignment.rb +7 -3
  315. data/lib/rubocop/cop/mixin/allowed_methods.rb +5 -5
  316. data/lib/rubocop/cop/mixin/allowed_pattern.rb +9 -5
  317. data/lib/rubocop/cop/mixin/annotation_comment.rb +1 -1
  318. data/lib/rubocop/cop/mixin/check_line_breakable.rb +50 -28
  319. data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +13 -9
  320. data/lib/rubocop/cop/mixin/code_length.rb +10 -2
  321. data/lib/rubocop/cop/mixin/comments_help.rb +2 -3
  322. data/lib/rubocop/cop/mixin/configurable_enforced_style.rb +1 -2
  323. data/lib/rubocop/cop/mixin/configurable_max.rb +6 -5
  324. data/lib/rubocop/cop/mixin/def_node.rb +1 -1
  325. data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +13 -2
  326. data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +1 -7
  327. data/lib/rubocop/cop/mixin/endless_method_body_help.rb +105 -0
  328. data/lib/rubocop/cop/mixin/endless_method_rewriter.rb +13 -5
  329. data/lib/rubocop/cop/mixin/forbidden_identifiers.rb +20 -0
  330. data/lib/rubocop/cop/mixin/forbidden_pattern.rb +20 -0
  331. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +1 -2
  332. data/lib/rubocop/cop/mixin/gemspec_help.rb +22 -0
  333. data/lib/rubocop/cop/mixin/hash_alignment_styles.rb +68 -21
  334. data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +52 -25
  335. data/lib/rubocop/cop/mixin/hash_subset.rb +28 -6
  336. data/lib/rubocop/cop/mixin/hash_transform_method/autocorrection.rb +63 -0
  337. data/lib/rubocop/cop/mixin/hash_transform_method.rb +32 -78
  338. data/lib/rubocop/cop/mixin/indexed_method_arity.rb +94 -0
  339. data/lib/rubocop/cop/mixin/line_length_help.rb +52 -11
  340. data/lib/rubocop/cop/mixin/method_complexity.rb +2 -1
  341. data/lib/rubocop/cop/mixin/min_branches_count.rb +3 -1
  342. data/lib/rubocop/cop/mixin/multiline_element_line_breaks.rb +11 -1
  343. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +3 -1
  344. data/lib/rubocop/cop/mixin/multiline_literal_brace_layout.rb +10 -1
  345. data/lib/rubocop/cop/mixin/ordered_gem_node.rb +2 -2
  346. data/lib/rubocop/cop/mixin/pattern_matching_help.rb +35 -0
  347. data/lib/rubocop/cop/mixin/percent_literal.rb +1 -1
  348. data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +79 -8
  349. data/lib/rubocop/cop/mixin/project_index_help.rb +203 -0
  350. data/lib/rubocop/cop/mixin/range_help.rb +16 -5
  351. data/lib/rubocop/cop/mixin/reparsed_equivalence.rb +181 -0
  352. data/lib/rubocop/cop/mixin/space_after_punctuation.rb +5 -4
  353. data/lib/rubocop/cop/mixin/statement_modifier.rb +69 -12
  354. data/lib/rubocop/cop/mixin/string_help.rb +1 -1
  355. data/lib/rubocop/cop/mixin/target_ruby_version.rb +1 -1
  356. data/lib/rubocop/cop/mixin/trailing_comma.rb +23 -6
  357. data/lib/rubocop/cop/mixin/visibility_help.rb +2 -1
  358. data/lib/rubocop/cop/mixin.rb +93 -0
  359. data/lib/rubocop/cop/naming/accessor_method_name.rb +8 -0
  360. data/lib/rubocop/cop/naming/binary_operator_parameter_name.rb +17 -1
  361. data/lib/rubocop/cop/naming/block_forwarding.rb +7 -4
  362. data/lib/rubocop/cop/naming/block_parameter_name.rb +1 -1
  363. data/lib/rubocop/cop/naming/file_name.rb +6 -5
  364. data/lib/rubocop/cop/naming/heredoc_delimiter_case.rb +9 -2
  365. data/lib/rubocop/cop/naming/heredoc_delimiter_naming.rb +5 -3
  366. data/lib/rubocop/cop/naming/inclusive_language.rb +8 -2
  367. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +13 -6
  368. data/lib/rubocop/cop/naming/method_name.rb +190 -15
  369. data/lib/rubocop/cop/naming/predicate_method.rb +330 -0
  370. data/lib/rubocop/cop/naming/{predicate_name.rb → predicate_prefix.rb} +65 -8
  371. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +12 -7
  372. data/lib/rubocop/cop/naming/variable_name.rb +51 -6
  373. data/lib/rubocop/cop/naming/variable_number.rb +3 -1
  374. data/lib/rubocop/cop/naming.rb +31 -0
  375. data/lib/rubocop/cop/offense.rb +108 -9
  376. data/lib/rubocop/cop/registry.rb +234 -65
  377. data/lib/rubocop/cop/security/eval.rb +17 -3
  378. data/lib/rubocop/cop/security/io_methods.rb +2 -2
  379. data/lib/rubocop/cop/security/json_load.rb +45 -11
  380. data/lib/rubocop/cop/security/marshal_load.rb +1 -1
  381. data/lib/rubocop/cop/security/open.rb +1 -0
  382. data/lib/rubocop/cop/security.rb +19 -0
  383. data/lib/rubocop/cop/severity.rb +12 -0
  384. data/lib/rubocop/cop/style/access_modifier_declarations.rb +83 -14
  385. data/lib/rubocop/cop/style/accessor_grouping.rb +47 -10
  386. data/lib/rubocop/cop/style/alias.rb +33 -8
  387. data/lib/rubocop/cop/style/ambiguous_endless_method_definition.rb +4 -3
  388. data/lib/rubocop/cop/style/and_or.rb +8 -3
  389. data/lib/rubocop/cop/style/arguments_forwarding.rb +80 -39
  390. data/lib/rubocop/cop/style/array_first_last.rb +13 -3
  391. data/lib/rubocop/cop/style/array_intersect.rb +136 -38
  392. data/lib/rubocop/cop/style/array_intersect_with_single_element.rb +50 -0
  393. data/lib/rubocop/cop/style/array_join.rb +4 -2
  394. data/lib/rubocop/cop/style/ascii_comments.rb +6 -3
  395. data/lib/rubocop/cop/style/attr.rb +8 -6
  396. data/lib/rubocop/cop/style/bare_percent_literals.rb +4 -3
  397. data/lib/rubocop/cop/style/begin_block.rb +3 -1
  398. data/lib/rubocop/cop/style/bitwise_predicate.rb +13 -5
  399. data/lib/rubocop/cop/style/block_delimiters.rb +77 -40
  400. data/lib/rubocop/cop/style/case_equality.rb +29 -15
  401. data/lib/rubocop/cop/style/case_like_if.rb +12 -11
  402. data/lib/rubocop/cop/style/character_literal.rb +2 -2
  403. data/lib/rubocop/cop/style/class_and_module_children.rb +181 -27
  404. data/lib/rubocop/cop/style/class_equality_comparison.rb +22 -14
  405. data/lib/rubocop/cop/style/class_methods_definitions.rb +26 -5
  406. data/lib/rubocop/cop/style/collection_compact.rb +37 -17
  407. data/lib/rubocop/cop/style/collection_methods.rb +1 -0
  408. data/lib/rubocop/cop/style/collection_querying.rb +200 -0
  409. data/lib/rubocop/cop/style/colon_method_call.rb +16 -7
  410. data/lib/rubocop/cop/style/combinable_loops.rb +92 -9
  411. data/lib/rubocop/cop/style/command_literal.rb +1 -1
  412. data/lib/rubocop/cop/style/commented_keyword.rb +12 -5
  413. data/lib/rubocop/cop/style/comparable_between.rb +78 -0
  414. data/lib/rubocop/cop/style/comparable_clamp.rb +12 -1
  415. data/lib/rubocop/cop/style/concat_array_literals.rb +65 -9
  416. data/lib/rubocop/cop/style/conditional_assignment.rb +58 -24
  417. data/lib/rubocop/cop/style/constant_visibility.rb +23 -12
  418. data/lib/rubocop/cop/style/copyright.rb +27 -12
  419. data/lib/rubocop/cop/style/data_inheritance.rb +25 -0
  420. data/lib/rubocop/cop/style/date_time.rb +4 -4
  421. data/lib/rubocop/cop/style/def_with_parentheses.rb +22 -5
  422. data/lib/rubocop/cop/style/dig_chain.rb +6 -1
  423. data/lib/rubocop/cop/style/dir_empty.rb +4 -0
  424. data/lib/rubocop/cop/style/directive_scope.rb +304 -0
  425. data/lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb +184 -20
  426. data/lib/rubocop/cop/style/document_dynamic_eval_definition.rb +6 -1
  427. data/lib/rubocop/cop/style/documentation.rb +53 -6
  428. data/lib/rubocop/cop/style/documentation_method.rb +8 -12
  429. data/lib/rubocop/cop/style/double_negation.rb +14 -3
  430. data/lib/rubocop/cop/style/each_for_simple_loop.rb +1 -1
  431. data/lib/rubocop/cop/style/each_with_object.rb +4 -3
  432. data/lib/rubocop/cop/style/empty_block_parameter.rb +1 -1
  433. data/lib/rubocop/cop/style/empty_case_condition.rb +13 -4
  434. data/lib/rubocop/cop/style/empty_class_definition.rb +126 -0
  435. data/lib/rubocop/cop/style/empty_heredoc.rb +4 -0
  436. data/lib/rubocop/cop/style/empty_lambda_parameter.rb +1 -1
  437. data/lib/rubocop/cop/style/empty_literal.rb +12 -3
  438. data/lib/rubocop/cop/style/empty_method.rb +15 -9
  439. data/lib/rubocop/cop/style/empty_string_inside_interpolation.rb +152 -0
  440. data/lib/rubocop/cop/style/encoding.rb +7 -1
  441. data/lib/rubocop/cop/style/end_block.rb +3 -1
  442. data/lib/rubocop/cop/style/endless_method.rb +256 -19
  443. data/lib/rubocop/cop/style/env_home.rb +4 -0
  444. data/lib/rubocop/cop/style/eval_with_location.rb +3 -3
  445. data/lib/rubocop/cop/style/even_odd.rb +11 -1
  446. data/lib/rubocop/cop/style/exact_regexp_match.rb +52 -8
  447. data/lib/rubocop/cop/style/expand_path_arguments.rb +2 -7
  448. data/lib/rubocop/cop/style/explicit_block_argument.rb +62 -9
  449. data/lib/rubocop/cop/style/exponential_notation.rb +5 -4
  450. data/lib/rubocop/cop/style/fetch_env_var.rb +33 -7
  451. data/lib/rubocop/cop/style/file_null.rb +6 -4
  452. data/lib/rubocop/cop/style/file_open.rb +84 -0
  453. data/lib/rubocop/cop/style/file_write.rb +21 -16
  454. data/lib/rubocop/cop/style/float_division.rb +43 -15
  455. data/lib/rubocop/cop/style/for.rb +61 -1
  456. data/lib/rubocop/cop/style/format_string.rb +44 -9
  457. data/lib/rubocop/cop/style/format_string_token.rb +86 -16
  458. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +5 -3
  459. data/lib/rubocop/cop/style/global_std_stream.rb +3 -0
  460. data/lib/rubocop/cop/style/global_vars.rb +5 -2
  461. data/lib/rubocop/cop/style/guard_clause.rb +58 -40
  462. data/lib/rubocop/cop/style/hash_as_last_array_item.rb +31 -9
  463. data/lib/rubocop/cop/style/hash_conversion.rb +52 -16
  464. data/lib/rubocop/cop/style/hash_each_methods.rb +4 -4
  465. data/lib/rubocop/cop/style/hash_fetch_chain.rb +104 -0
  466. data/lib/rubocop/cop/style/hash_lookup_method.rb +128 -0
  467. data/lib/rubocop/cop/style/hash_slice.rb +16 -0
  468. data/lib/rubocop/cop/style/hash_syntax.rb +23 -6
  469. data/lib/rubocop/cop/style/hash_transform_keys.rb +19 -9
  470. data/lib/rubocop/cop/style/hash_transform_values.rb +19 -9
  471. data/lib/rubocop/cop/style/identical_conditional_branches.rb +39 -11
  472. data/lib/rubocop/cop/style/if_inside_else.rb +46 -21
  473. data/lib/rubocop/cop/style/if_unless_modifier.rb +101 -70
  474. data/lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb +19 -19
  475. data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +5 -2
  476. data/lib/rubocop/cop/style/if_with_semicolon.rb +61 -8
  477. data/lib/rubocop/cop/style/infinite_loop.rb +1 -1
  478. data/lib/rubocop/cop/style/inline_comment.rb +5 -2
  479. data/lib/rubocop/cop/style/inverse_methods.rb +34 -8
  480. data/lib/rubocop/cop/style/invertible_unless_condition.rb +27 -7
  481. data/lib/rubocop/cop/style/ip_addresses.rb +3 -4
  482. data/lib/rubocop/cop/style/it_assignment.rb +69 -12
  483. data/lib/rubocop/cop/style/it_block_parameter.rb +211 -0
  484. data/lib/rubocop/cop/style/keyword_arguments_merging.rb +4 -0
  485. data/lib/rubocop/cop/style/keyword_parameters_order.rb +23 -11
  486. data/lib/rubocop/cop/style/lambda.rb +46 -2
  487. data/lib/rubocop/cop/style/lambda_call.rb +31 -10
  488. data/lib/rubocop/cop/style/line_end_concatenation.rb +10 -4
  489. data/lib/rubocop/cop/style/magic_comment_format.rb +4 -4
  490. data/lib/rubocop/cop/style/map_compact_with_conditional_block.rb +11 -0
  491. data/lib/rubocop/cop/style/map_into_array.rb +6 -4
  492. data/lib/rubocop/cop/style/map_join.rb +123 -0
  493. data/lib/rubocop/cop/style/map_to_hash.rb +13 -5
  494. data/lib/rubocop/cop/style/map_to_set.rb +1 -3
  495. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +110 -27
  496. data/lib/rubocop/cop/style/method_call_with_args_parentheses/require_parentheses.rb +15 -2
  497. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +58 -6
  498. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +36 -8
  499. data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +2 -1
  500. data/lib/rubocop/cop/style/method_def_parentheses.rb +36 -8
  501. data/lib/rubocop/cop/style/min_max_comparison.rb +17 -6
  502. data/lib/rubocop/cop/style/missing_else.rb +7 -1
  503. data/lib/rubocop/cop/style/missing_respond_to_missing.rb +40 -7
  504. data/lib/rubocop/cop/style/mixin_grouping.rb +12 -3
  505. data/lib/rubocop/cop/style/mixin_usage.rb +1 -1
  506. data/lib/rubocop/cop/style/module_function.rb +4 -2
  507. data/lib/rubocop/cop/style/module_member_existence_check.rb +110 -0
  508. data/lib/rubocop/cop/style/multiline_block_chain.rb +2 -1
  509. data/lib/rubocop/cop/style/multiline_if_modifier.rb +47 -5
  510. data/lib/rubocop/cop/style/multiline_if_then.rb +10 -4
  511. data/lib/rubocop/cop/style/multiline_in_pattern_then.rb +7 -0
  512. data/lib/rubocop/cop/style/multiline_memoization.rb +7 -1
  513. data/lib/rubocop/cop/style/multiline_method_signature.rb +15 -22
  514. data/lib/rubocop/cop/style/multiline_ternary_operator.rb +7 -3
  515. data/lib/rubocop/cop/style/multiline_when_then.rb +7 -0
  516. data/lib/rubocop/cop/style/multiple_comparison.rb +33 -22
  517. data/lib/rubocop/cop/style/mutable_constant.rb +158 -14
  518. data/lib/rubocop/cop/style/negated_if_else_condition.rb +3 -3
  519. data/lib/rubocop/cop/style/negative_array_index.rb +228 -0
  520. data/lib/rubocop/cop/style/nested_modifier.rb +36 -12
  521. data/lib/rubocop/cop/style/nested_ternary_operator.rb +26 -8
  522. data/lib/rubocop/cop/style/next.rb +68 -10
  523. data/lib/rubocop/cop/style/nil_comparison.rb +53 -13
  524. data/lib/rubocop/cop/style/nil_lambda.rb +9 -1
  525. data/lib/rubocop/cop/style/non_nil_check.rb +21 -11
  526. data/lib/rubocop/cop/style/not.rb +12 -3
  527. data/lib/rubocop/cop/style/numeric_literal_prefix.rb +11 -1
  528. data/lib/rubocop/cop/style/numeric_literals.rb +3 -2
  529. data/lib/rubocop/cop/style/numeric_predicate.rb +22 -6
  530. data/lib/rubocop/cop/style/object_then.rb +1 -0
  531. data/lib/rubocop/cop/style/one_class_per_file.rb +115 -0
  532. data/lib/rubocop/cop/style/one_line_conditional.rb +35 -15
  533. data/lib/rubocop/cop/style/open_struct_use.rb +1 -1
  534. data/lib/rubocop/cop/style/operator_method_call.rb +10 -2
  535. data/lib/rubocop/cop/style/option_hash.rb +1 -1
  536. data/lib/rubocop/cop/style/optional_arguments.rb +1 -0
  537. data/lib/rubocop/cop/style/parallel_assignment.rb +58 -27
  538. data/lib/rubocop/cop/style/parentheses_around_condition.rb +7 -2
  539. data/lib/rubocop/cop/style/partition_instead_of_double_select.rb +270 -0
  540. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +18 -3
  541. data/lib/rubocop/cop/style/percent_q_literals.rb +1 -1
  542. data/lib/rubocop/cop/style/perl_backrefs.rb +5 -3
  543. data/lib/rubocop/cop/style/predicate_with_kind.rb +84 -0
  544. data/lib/rubocop/cop/style/preferred_hash_methods.rb +12 -12
  545. data/lib/rubocop/cop/style/proc.rb +4 -2
  546. data/lib/rubocop/cop/style/raise_args.rb +28 -18
  547. data/lib/rubocop/cop/style/reduce_to_hash.rb +216 -0
  548. data/lib/rubocop/cop/style/redundant_argument.rb +2 -0
  549. data/lib/rubocop/cop/style/redundant_array_constructor.rb +2 -2
  550. data/lib/rubocop/cop/style/redundant_array_flatten.rb +50 -0
  551. data/lib/rubocop/cop/style/redundant_assignment.rb +12 -2
  552. data/lib/rubocop/cop/style/redundant_begin.rb +60 -7
  553. data/lib/rubocop/cop/style/redundant_condition.rb +93 -18
  554. data/lib/rubocop/cop/style/redundant_constant_base.rb +42 -6
  555. data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +26 -4
  556. data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +17 -3
  557. data/lib/rubocop/cop/style/redundant_each.rb +4 -5
  558. data/lib/rubocop/cop/style/redundant_exception.rb +22 -4
  559. data/lib/rubocop/cop/style/redundant_fetch_block.rb +11 -11
  560. data/lib/rubocop/cop/style/redundant_file_extension_in_require.rb +9 -0
  561. data/lib/rubocop/cop/style/redundant_filter_chain.rb +1 -1
  562. data/lib/rubocop/cop/style/redundant_format.rb +319 -0
  563. data/lib/rubocop/cop/style/redundant_freeze.rb +13 -5
  564. data/lib/rubocop/cop/style/redundant_heredoc_delimiter_quotes.rb +6 -1
  565. data/lib/rubocop/cop/style/redundant_interpolation.rb +12 -3
  566. data/lib/rubocop/cop/style/redundant_interpolation_unfreeze.rb +49 -10
  567. data/lib/rubocop/cop/style/redundant_line_continuation.rb +83 -119
  568. data/lib/rubocop/cop/style/redundant_min_max_by.rb +93 -0
  569. data/lib/rubocop/cop/style/redundant_parentheses.rb +176 -83
  570. data/lib/rubocop/cop/style/redundant_percent_q.rb +5 -3
  571. data/lib/rubocop/cop/style/redundant_regexp_argument.rb +15 -0
  572. data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +6 -5
  573. data/lib/rubocop/cop/style/redundant_regexp_constructor.rb +27 -7
  574. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +16 -0
  575. data/lib/rubocop/cop/style/redundant_return.rb +4 -3
  576. data/lib/rubocop/cop/style/redundant_self.rb +20 -7
  577. data/lib/rubocop/cop/style/redundant_self_assignment.rb +2 -3
  578. data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +27 -4
  579. data/lib/rubocop/cop/style/redundant_sort.rb +45 -11
  580. data/lib/rubocop/cop/style/redundant_sort_by.rb +17 -1
  581. data/lib/rubocop/cop/style/redundant_string_escape.rb +1 -2
  582. data/lib/rubocop/cop/style/redundant_struct_keyword_init.rb +133 -0
  583. data/lib/rubocop/cop/style/regexp_literal.rb +107 -29
  584. data/lib/rubocop/cop/style/require_order.rb +25 -8
  585. data/lib/rubocop/cop/style/rescue_modifier.rb +16 -12
  586. data/lib/rubocop/cop/style/return_nil.rb +19 -4
  587. data/lib/rubocop/cop/style/return_nil_in_predicate_method_definition.rb +11 -1
  588. data/lib/rubocop/cop/style/reverse_find.rb +51 -0
  589. data/lib/rubocop/cop/style/safe_navigation.rb +76 -20
  590. data/lib/rubocop/cop/style/sample.rb +19 -13
  591. data/lib/rubocop/cop/style/select_by_kind.rb +158 -0
  592. data/lib/rubocop/cop/style/select_by_range.rb +197 -0
  593. data/lib/rubocop/cop/style/select_by_regexp.rb +54 -22
  594. data/lib/rubocop/cop/style/self_assignment.rb +13 -16
  595. data/lib/rubocop/cop/style/semicolon.rb +56 -14
  596. data/lib/rubocop/cop/style/send_with_literal_method_name.rb +4 -0
  597. data/lib/rubocop/cop/style/single_line_block_params.rb +2 -2
  598. data/lib/rubocop/cop/style/single_line_do_end_block.rb +22 -8
  599. data/lib/rubocop/cop/style/single_line_methods.rb +33 -11
  600. data/lib/rubocop/cop/style/sole_nested_conditional.rb +96 -104
  601. data/lib/rubocop/cop/style/special_global_vars.rb +7 -2
  602. data/lib/rubocop/cop/style/stabby_lambda_parentheses.rb +32 -6
  603. data/lib/rubocop/cop/style/static_class.rb +21 -0
  604. data/lib/rubocop/cop/style/string_concatenation.rb +38 -16
  605. data/lib/rubocop/cop/style/string_hash_keys.rb +1 -0
  606. data/lib/rubocop/cop/style/struct_inheritance.rb +44 -2
  607. data/lib/rubocop/cop/style/super_arguments.rb +7 -6
  608. data/lib/rubocop/cop/style/symbol_array.rb +1 -1
  609. data/lib/rubocop/cop/style/symbol_proc.rb +35 -15
  610. data/lib/rubocop/cop/style/tally_method.rb +181 -0
  611. data/lib/rubocop/cop/style/ternary_parentheses.rb +34 -1
  612. data/lib/rubocop/cop/style/time_now.rb +41 -0
  613. data/lib/rubocop/cop/style/top_level_method_definition.rb +3 -2
  614. data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +52 -1
  615. data/lib/rubocop/cop/style/trailing_comma_in_array_literal.rb +47 -6
  616. data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +2 -2
  617. data/lib/rubocop/cop/style/trailing_comma_in_hash_literal.rb +48 -6
  618. data/lib/rubocop/cop/style/trailing_method_end_statement.rb +1 -0
  619. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +35 -32
  620. data/lib/rubocop/cop/style/trivial_accessors.rb +2 -2
  621. data/lib/rubocop/cop/style/unless_else.rb +10 -9
  622. data/lib/rubocop/cop/style/unless_logical_operators.rb +3 -3
  623. data/lib/rubocop/cop/style/while_until_do.rb +7 -0
  624. data/lib/rubocop/cop/style/while_until_modifier.rb +16 -1
  625. data/lib/rubocop/cop/style/word_array.rb +1 -0
  626. data/lib/rubocop/cop/style/yoda_condition.rb +26 -12
  627. data/lib/rubocop/cop/style/yoda_expression.rb +11 -2
  628. data/lib/rubocop/cop/style/zero_length_predicate.rb +6 -3
  629. data/lib/rubocop/cop/style.rb +311 -0
  630. data/lib/rubocop/cop/team.rb +172 -49
  631. data/lib/rubocop/cop/util.rb +7 -10
  632. data/lib/rubocop/cop/utils/format_string.rb +20 -5
  633. data/lib/rubocop/cop/variable_force/assignment.rb +8 -4
  634. data/lib/rubocop/cop/variable_force/branch.rb +30 -6
  635. data/lib/rubocop/cop/variable_force/scope.rb +1 -1
  636. data/lib/rubocop/cop/variable_force/variable.rb +42 -11
  637. data/lib/rubocop/cop/variable_force.rb +26 -9
  638. data/lib/rubocop/cops_documentation_generator.rb +49 -15
  639. data/lib/rubocop/directive_comment.rb +147 -5
  640. data/lib/rubocop/ext/regexp_node.rb +0 -1
  641. data/lib/rubocop/feature_loader.rb +0 -6
  642. data/lib/rubocop/file_patterns.rb +9 -1
  643. data/lib/rubocop/formatter/base_formatter.rb +22 -0
  644. data/lib/rubocop/formatter/clang_style_formatter.rb +5 -2
  645. data/lib/rubocop/formatter/disabled_config_formatter.rb +57 -14
  646. data/lib/rubocop/formatter/emacs_style_formatter.rb +3 -1
  647. data/lib/rubocop/formatter/formatter_set.rb +7 -2
  648. data/lib/rubocop/formatter/fuubar_style_formatter.rb +1 -1
  649. data/lib/rubocop/formatter/github_actions_formatter.rb +6 -5
  650. data/lib/rubocop/formatter/html_formatter.rb +3 -5
  651. data/lib/rubocop/formatter/json_formatter.rb +82 -7
  652. data/lib/rubocop/formatter/junit_formatter.rb +27 -10
  653. data/lib/rubocop/formatter/markdown_formatter.rb +1 -0
  654. data/lib/rubocop/formatter/offense_count_formatter.rb +5 -4
  655. data/lib/rubocop/formatter/pacman_formatter.rb +5 -2
  656. data/lib/rubocop/formatter/sarif_formatter.rb +186 -0
  657. data/lib/rubocop/formatter/simple_text_formatter.rb +4 -5
  658. data/lib/rubocop/formatter/tap_formatter.rb +8 -3
  659. data/lib/rubocop/formatter/worst_offenders_formatter.rb +5 -4
  660. data/lib/rubocop/formatter.rb +23 -21
  661. data/lib/rubocop/lockfile.rb +18 -0
  662. data/lib/rubocop/lsp/diagnostic.rb +22 -41
  663. data/lib/rubocop/lsp/disable_comment_edits.rb +135 -0
  664. data/lib/rubocop/lsp/routes.rb +158 -55
  665. data/lib/rubocop/lsp/runtime.rb +66 -15
  666. data/lib/rubocop/lsp/server.rb +4 -2
  667. data/lib/rubocop/lsp/stdin_runner.rb +38 -19
  668. data/lib/rubocop/lsp.rb +5 -2
  669. data/lib/rubocop/magic_comment.rb +55 -0
  670. data/lib/rubocop/mcp/autocorrection_request.rb +52 -0
  671. data/lib/rubocop/mcp/explain_tool.rb +68 -0
  672. data/lib/rubocop/mcp/scope.rb +65 -0
  673. data/lib/rubocop/mcp/server.rb +307 -0
  674. data/lib/rubocop/mcp/source_files.rb +35 -0
  675. data/lib/rubocop/offense_limit.rb +30 -0
  676. data/lib/rubocop/options.rb +166 -23
  677. data/lib/rubocop/path_util.rb +20 -5
  678. data/lib/rubocop/pending_cops_reporter.rb +51 -0
  679. data/lib/rubocop/plugin/configuration_integrator.rb +153 -0
  680. data/lib/rubocop/plugin/load_error.rb +26 -0
  681. data/lib/rubocop/plugin/loader.rb +100 -0
  682. data/lib/rubocop/plugin/not_supported_error.rb +29 -0
  683. data/lib/rubocop/plugin.rb +46 -0
  684. data/lib/rubocop/project_index_loader.rb +82 -0
  685. data/lib/rubocop/rake_task.rb +6 -4
  686. data/lib/rubocop/remote_config.rb +18 -13
  687. data/lib/rubocop/result_cache.rb +110 -65
  688. data/lib/rubocop/rspec/cop_helper.rb +21 -1
  689. data/lib/rubocop/rspec/expect_offense.rb +11 -7
  690. data/lib/rubocop/rspec/shared_contexts.rb +85 -3
  691. data/lib/rubocop/rspec/support.rb +4 -0
  692. data/lib/rubocop/runner.rb +368 -106
  693. data/lib/rubocop/server/cache.rb +67 -48
  694. data/lib/rubocop/server/cli.rb +2 -4
  695. data/lib/rubocop/server/client_command/base.rb +10 -0
  696. data/lib/rubocop/server/client_command/exec.rb +2 -1
  697. data/lib/rubocop/server/client_command/start.rb +11 -1
  698. data/lib/rubocop/server/core.rb +8 -0
  699. data/lib/rubocop/server.rb +14 -0
  700. data/lib/rubocop/target_finder.rb +25 -11
  701. data/lib/rubocop/target_ruby.rb +52 -23
  702. data/lib/rubocop/todo_audit.rb +111 -0
  703. data/lib/rubocop/unified_diff.rb +257 -0
  704. data/lib/rubocop/util.rb +69 -0
  705. data/lib/rubocop/version.rb +48 -10
  706. data/lib/rubocop.rb +35 -682
  707. data/lib/ruby_lsp/rubocop/addon.rb +28 -17
  708. data/lib/ruby_lsp/rubocop/runtime_adapter.rb +99 -0
  709. metadata +129 -21
  710. data/lib/rubocop/cop/style/double_cop_disable_directive.rb +0 -46
  711. data/lib/rubocop/cop/utils/regexp_ranges.rb +0 -113
  712. data/lib/ruby_lsp/rubocop/wraps_built_in_lsp_runtime.rb +0 -50
@@ -6,7 +6,7 @@ module RuboCop
6
6
  class ForToEachCorrector
7
7
  extend NodePattern::Macros
8
8
 
9
- CORRECTION = '%<collection>s.each do |%<argument>s|'
9
+ CORRECTION = '%<collection>s%<dot>seach do |%<argument>s|'
10
10
 
11
11
  def initialize(for_node)
12
12
  @for_node = for_node
@@ -25,7 +25,12 @@ module RuboCop
25
25
  attr_reader :for_node, :variable_node, :collection_node
26
26
 
27
27
  def correction
28
- format(CORRECTION, collection: collection_source, argument: variable_node.source)
28
+ format(
29
+ CORRECTION,
30
+ collection: collection_source,
31
+ dot: collection_node.csend_type? ? '&.' : '.',
32
+ argument: variable_node.source
33
+ )
29
34
  end
30
35
 
31
36
  def collection_source
@@ -29,6 +29,10 @@ module RuboCop
29
29
  insert_arguments(corrector)
30
30
  end
31
31
 
32
+ def replace_delimiters?
33
+ !block_node.braces? && arg_to_unparenthesized_call?
34
+ end
35
+
32
36
  private
33
37
 
34
38
  attr_reader :block_node, :method, :arguments
@@ -72,12 +76,12 @@ module RuboCop
72
76
  end
73
77
 
74
78
  def remove_trailing_whitespace(corrector)
75
- size = block_begin.begin_pos - arguments.source_range.end_pos - 1
76
- corrector.remove_preceding(block_begin, size) if size.positive?
79
+ whitespace = arguments.source_range.end.join(block_begin.begin)
80
+ corrector.replace(whitespace, ' ') if whitespace.size > 1
77
81
  end
78
82
 
79
83
  def replace_delimiters(corrector)
80
- return if block_node.braces? || !arg_to_unparenthesized_call?
84
+ return unless replace_delimiters?
81
85
 
82
86
  corrector.insert_after(block_begin, ' ') unless separating_space?
83
87
 
@@ -86,7 +90,13 @@ module RuboCop
86
90
  end
87
91
 
88
92
  def lambda_arg_string
89
- arguments.children.map(&:source).join(', ')
93
+ # Block-local (shadow) arguments are separated from regular arguments by a
94
+ # `;`; joining everything with `,` would turn them into extra parameters
95
+ # and change the lambda's arity.
96
+ regular, shadow = arguments.children.partition { |arg| !arg.shadowarg_type? }
97
+ arg_string = regular.map { |arg| argument_source(arg) }.join(', ')
98
+ arg_string += "; #{shadow.map(&:source).join(', ')}" unless shadow.empty?
99
+ arg_string
90
100
  end
91
101
 
92
102
  def needs_separating_space?
@@ -134,6 +144,23 @@ module RuboCop
134
144
  def separating_space?
135
145
  block_begin.source_buffer.source[block_begin.begin_pos + 2].match?(/\s/)
136
146
  end
147
+
148
+ def argument_source(argument)
149
+ return argument.source unless argument.type?(:optarg, :kwoptarg)
150
+ return argument.source unless operator_expression?(argument.default_value)
151
+
152
+ default_value = argument.default_value
153
+ name = argument.source_range.begin.join(default_value.source_range.begin).source
154
+
155
+ "#{name}(#{default_value.source})"
156
+ end
157
+
158
+ def operator_expression?(node)
159
+ return true if node.type?(:range, :if, :and, :or)
160
+ return false unless node.call_type?
161
+
162
+ node.operator_method? && !node.method?(:[])
163
+ end
137
164
  end
138
165
  end
139
166
  end
@@ -27,6 +27,7 @@ module RuboCop
27
27
  # corrected. The user must handle the delicate decision of where to
28
28
  # put the comment.
29
29
  return if new_line_needed_before_closing_brace?(node)
30
+ return if nested_closing_bracket_moved_before_comment?
30
31
 
31
32
  end_range = last_element_range_with_trailing_comma(node).end
32
33
 
@@ -43,6 +44,39 @@ module RuboCop
43
44
  corrector.insert_before(node.loc.end, "\n")
44
45
  end
45
46
 
47
+ def nested_closing_bracket_moved_before_comment?
48
+ last_element = children(node).last
49
+ return false unless (comment = processed_source.comment_at_line(last_element.last_line - 1))
50
+ return false unless (nested = nested_literal_with_closing_bracket_on_own_line(last_element))
51
+
52
+ own_line_comment?(comment) || !(nested.chained? || nested.argument?)
53
+ end
54
+
55
+ def nested_literal_with_closing_bracket_on_own_line(last_element)
56
+ last_line = last_element.last_line
57
+
58
+ last_element.each_node.find do |descendant|
59
+ same_kind_as_node?(descendant) && closing_bracket_on_own_line?(descendant, last_line)
60
+ end
61
+ end
62
+
63
+ def same_kind_as_node?(descendant)
64
+ descendant.type == node.type || (descendant.call_type? && node.call_type?)
65
+ end
66
+
67
+ def closing_bracket_on_own_line?(descendant, line)
68
+ return false unless descendant.loc?(:end) && descendant.loc.end.is?('}', ']', ')')
69
+
70
+ closing_bracket = descendant.loc.end
71
+ return false if closing_bracket.line != line
72
+
73
+ closing_bracket.source_line[0...closing_bracket.column].strip.empty?
74
+ end
75
+
76
+ def own_line_comment?(comment)
77
+ comment.source_range.source_line.lstrip.start_with?('#')
78
+ end
79
+
46
80
  def correct_next_line_brace(corrector, end_range)
47
81
  corrector.remove(range_with_surrounding_space(node.loc.end, side: :left))
48
82
  corrector.insert_before(end_range, content_if_comment_present(corrector, node))
@@ -59,11 +93,7 @@ module RuboCop
59
93
  end
60
94
 
61
95
  def content_if_comment_present(corrector, node)
62
- range = range_with_surrounding_space(
63
- children(node).last.source_range,
64
- side: :right
65
- ).end.resize(1)
66
- if range.source == '#'
96
+ if processed_source.comment_at_line(children(node).last.last_line)
67
97
  select_content_to_be_inserted_after_last_element(corrector, node)
68
98
  else
69
99
  node.loc.end.source
@@ -18,7 +18,14 @@ module RuboCop
18
18
  current_range = declaration_with_comment(node)
19
19
  previous_range = declaration_with_comment(previous_declaration)
20
20
 
21
- ->(corrector) { corrector.swap(current_range, previous_range) }
21
+ lambda do |corrector|
22
+ if current_range.source.end_with?("\n")
23
+ corrector.swap(current_range, previous_range)
24
+ else
25
+ corrector.insert_before(previous_range, "#{current_range.source}\n")
26
+ corrector.remove(current_range)
27
+ end
28
+ end
22
29
  end
23
30
 
24
31
  private
@@ -10,8 +10,10 @@ module RuboCop
10
10
  COMMA_REGEXP = /(?<=\))\s*,/.freeze
11
11
 
12
12
  def correct(corrector, node)
13
- corrector.remove(node.loc.begin)
14
- corrector.remove(node.loc.end)
13
+ buffer = node.source_range.source_buffer
14
+ corrector.remove(range_with_surrounding_space(range: node.loc.begin, buffer: buffer,
15
+ side: :right, whitespace: true))
16
+ remove_close_paren(corrector, node, buffer)
15
17
  handle_orphaned_comma(corrector, node)
16
18
 
17
19
  return unless ternary_condition?(node) && next_char_is_question_mark?(node)
@@ -19,8 +21,77 @@ module RuboCop
19
21
  corrector.insert_after(node.loc.end, ' ')
20
22
  end
21
23
 
24
+ def heredoc_strands_code_after_close_paren?(node)
25
+ return false unless heredoc_body_before_close_paren?(node)
26
+
27
+ after_paren = text_after_close_paren(node)
28
+
29
+ !after_paren.empty? && !after_paren.start_with?('.', '&.', ',')
30
+ end
31
+
22
32
  private
23
33
 
34
+ # When the line above `)` ends with a comment and a chained call follows `)`,
35
+ # crossing the newline would pull the chain into the comment. Preserve the newline.
36
+ # When a heredoc body comes before `)`, a chained call has to start on the line
37
+ # after the terminator instead, since the terminator must stay alone on its line.
38
+ def remove_close_paren(corrector, node, buffer)
39
+ if heredoc_above_close_paren_swallows_chain?(node)
40
+ range = range_with_surrounding_space(range: node.loc.end, buffer: buffer, side: :left)
41
+
42
+ corrector.replace(range, "\n")
43
+ else
44
+ newlines = !comment_above_close_paren_swallows_chain?(node, buffer)
45
+ range = range_with_surrounding_space(
46
+ range: node.loc.end, buffer: buffer, side: :left, newlines: newlines
47
+ )
48
+
49
+ corrector.remove(range)
50
+ end
51
+ end
52
+
53
+ def heredoc_above_close_paren_swallows_chain?(node)
54
+ return false unless heredoc_body_before_close_paren?(node)
55
+
56
+ text_after_close_paren(node).start_with?('.', '&.')
57
+ end
58
+
59
+ def heredoc_body_before_close_paren?(node)
60
+ return false unless (last_child = node.children.last)
61
+
62
+ close_paren_pos = node.loc.end.begin_pos
63
+
64
+ last_child.each_node(:any_str).any? do |str_node|
65
+ str_node.heredoc? && str_node.loc.heredoc_end.end_pos <= close_paren_pos
66
+ end
67
+ end
68
+
69
+ def text_after_close_paren(node)
70
+ close_paren = node.loc.end
71
+
72
+ close_paren.source_line[(close_paren.column + 1)..].to_s.lstrip
73
+ end
74
+
75
+ def comment_above_close_paren_swallows_chain?(node, buffer)
76
+ last_child = node.children.last
77
+ return false unless last_child
78
+
79
+ body_end = last_child.source_range.end_pos
80
+ close_paren_begin = node.loc.end.begin_pos
81
+ return false if body_end >= close_paren_begin
82
+
83
+ source_between = buffer.source[body_end...close_paren_begin]
84
+ return false unless source_between.match?(/#[^\n]*\n/)
85
+
86
+ chained_after_close_paren?(node)
87
+ end
88
+
89
+ def chained_after_close_paren?(node)
90
+ trimmed = text_after_close_paren(node)
91
+
92
+ !trimmed.empty? && !trimmed.start_with?('#')
93
+ end
94
+
24
95
  def ternary_condition?(node)
25
96
  node.parent&.if_type? && node.parent.ternary?
26
97
  end
@@ -97,8 +97,8 @@ module RuboCop
97
97
  if delimiters.first != delimiters.last
98
98
  # With different delimiters (eg. `[]`, `()`), if there are the same
99
99
  # number of each, escaping is not necessary
100
- delimiter_counts = delimiters.each_with_object({}) do |delimiter, counts|
101
- counts[delimiter] = content.count(delimiter)
100
+ delimiter_counts = delimiters.to_h do |delimiter|
101
+ [delimiter, content.count(delimiter)]
102
102
  end
103
103
 
104
104
  return content if delimiter_counts[delimiters.first] == delimiter_counts[delimiters.last]
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop # rubocop:disable Style/Documentation -- a namespace that only autoloads the correctors below
5
+ # Autoloads corrector classes used by cops. Classes are autoloaded to reduce the number of
6
+ # required classes because they're referenced only when autocorrection is performed.
7
+
8
+ # rubocop:disable Layout/LineLength -- the autoload paths do not wrap
9
+ autoload :AlignmentCorrector, 'rubocop/cop/correctors/alignment_corrector'
10
+ autoload :ConditionCorrector, 'rubocop/cop/correctors/condition_corrector'
11
+ autoload :EachToForCorrector, 'rubocop/cop/correctors/each_to_for_corrector'
12
+ autoload :EmptyLineCorrector, 'rubocop/cop/correctors/empty_line_corrector'
13
+ autoload :ForToEachCorrector, 'rubocop/cop/correctors/for_to_each_corrector'
14
+ autoload :IfThenCorrector, 'rubocop/cop/correctors/if_then_corrector'
15
+ autoload :LambdaLiteralToMethodCorrector, 'rubocop/cop/correctors/lambda_literal_to_method_corrector'
16
+ autoload :LineBreakCorrector, 'rubocop/cop/correctors/line_break_corrector'
17
+ autoload :MultilineLiteralBraceCorrector, 'rubocop/cop/correctors/multiline_literal_brace_corrector'
18
+ autoload :OrderedGemCorrector, 'rubocop/cop/correctors/ordered_gem_corrector'
19
+ autoload :ParenthesesCorrector, 'rubocop/cop/correctors/parentheses_corrector'
20
+ autoload :PercentLiteralCorrector, 'rubocop/cop/correctors/percent_literal_corrector'
21
+ autoload :PunctuationCorrector, 'rubocop/cop/correctors/punctuation_corrector'
22
+ autoload :RequireLibraryCorrector, 'rubocop/cop/correctors/require_library_corrector'
23
+ autoload :SpaceCorrector, 'rubocop/cop/correctors/space_corrector'
24
+ autoload :StringLiteralCorrector, 'rubocop/cop/correctors/string_literal_corrector'
25
+ autoload :UnusedArgCorrector, 'rubocop/cop/correctors/unused_arg_corrector'
26
+ # rubocop:enable Layout/LineLength
27
+ end
28
+ end
@@ -14,7 +14,7 @@ module RuboCop
14
14
  # @api private
15
15
  def url_for(cop_class, config = nil)
16
16
  base = department_to_basename(cop_class.department)
17
- fragment = cop_class.cop_name.downcase.gsub(/[^a-z]/, '')
17
+ fragment = cop_class.cop_name.downcase.delete('/')
18
18
  base_url = base_url_for(cop_class, config)
19
19
  extension = extension_for(cop_class, config)
20
20
 
@@ -55,10 +55,9 @@ module RuboCop
55
55
 
56
56
  # @api private
57
57
  def builtin?(cop_class)
58
- # any custom method will do
59
- return false unless (m = cop_class.instance_methods(false).first)
58
+ return false unless (name = cop_class.name)
60
59
 
61
- path, _line = cop_class.instance_method(m).source_location
60
+ path, _line = Module.const_source_location(name)
62
61
  path.start_with?(__dir__)
63
62
  end
64
63
  end
@@ -4,16 +4,42 @@ module RuboCop
4
4
  # Allows specified configuration options to have an exclude limit
5
5
  # ie. a maximum value tracked that it can be used by `--auto-gen-config`.
6
6
  module ExcludeLimit
7
+ class << self
8
+ attr_accessor :tmp_dir
9
+
10
+ # Reads the aggregated exclude limit values for a cop from tmp files.
11
+ # Returns a hash like { 'Max' => 81 } or an empty hash if no values were written.
12
+ def read_limits(cop_name)
13
+ cop_dir = cop_dir_for(cop_name)
14
+ return {} unless cop_dir&.directory?
15
+
16
+ limits = {}
17
+ cop_dir.children.each do |filepath|
18
+ next unless filepath.file?
19
+
20
+ values = filepath.readlines.map(&:to_i)
21
+ limits[filepath.basename.to_s] = values.max unless values.empty?
22
+ end
23
+ limits
24
+ end
25
+
26
+ # Returns the tmp directory path for a given cop, or nil if tmp_dir is not set.
27
+ def cop_dir_for(cop_name)
28
+ tmp_dir&.join(cop_name.tr('/', '-'))
29
+ end
30
+ end
31
+
7
32
  # Sets up a configuration option to have an exclude limit tracked.
8
33
  # The parameter name given is transformed into a method name (eg. `Max`
9
34
  # becomes `self.max=` and `MinDigits` becomes `self.min_digits=`).
10
35
  def exclude_limit(parameter_name, method_name: transform(parameter_name))
11
36
  define_method(:"#{method_name}=") do |value|
12
- cfg = config_to_allow_offenses
13
- cfg[:exclude_limit] ||= {}
14
- current_max = cfg[:exclude_limit][parameter_name]
15
- value = [current_max, value].max if current_max
16
- cfg[:exclude_limit][parameter_name] = value
37
+ cop_dir = RuboCop::ExcludeLimit.cop_dir_for(self.class.badge.to_s)
38
+ return unless cop_dir
39
+
40
+ cop_dir.mkpath
41
+ filepath = cop_dir.join(parameter_name)
42
+ filepath.write("#{value}\n", mode: 'a')
17
43
  end
18
44
  end
19
45
 
@@ -0,0 +1,91 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Gemspec
6
+ # Use consistent style for Gemspec attributes assignment.
7
+ #
8
+ # @example
9
+ #
10
+ # # bad
11
+ # # This example uses two styles for assignment of metadata attribute.
12
+ # Gem::Specification.new do |spec|
13
+ # spec.metadata = { 'key' => 'value' }
14
+ # spec.metadata['another-key'] = 'another-value'
15
+ # end
16
+ #
17
+ # # good
18
+ # Gem::Specification.new do |spec|
19
+ # spec.metadata['key'] = 'value'
20
+ # spec.metadata['another-key'] = 'another-value'
21
+ # end
22
+ #
23
+ # # good
24
+ # Gem::Specification.new do |spec|
25
+ # spec.metadata = { 'key' => 'value', 'another-key' => 'another-value' }
26
+ # end
27
+ #
28
+ # # bad
29
+ # # This example uses two styles for assignment of authors attribute.
30
+ # Gem::Specification.new do |spec|
31
+ # spec.authors = %w[author-0 author-1]
32
+ # spec.authors[2] = 'author-2'
33
+ # end
34
+ #
35
+ # # good
36
+ # Gem::Specification.new do |spec|
37
+ # spec.authors = %w[author-0 author-1 author-2]
38
+ # end
39
+ #
40
+ # # good
41
+ # Gem::Specification.new do |spec|
42
+ # spec.authors[0] = 'author-0'
43
+ # spec.authors[1] = 'author-1'
44
+ # spec.authors[2] = 'author-2'
45
+ # end
46
+ #
47
+ # # good
48
+ # # This example uses consistent assignment per attribute,
49
+ # # even though two different styles are used overall.
50
+ # Gem::Specification.new do |spec|
51
+ # spec.metadata = { 'key' => 'value' }
52
+ # spec.authors[0] = 'author-0'
53
+ # spec.authors[1] = 'author-1'
54
+ # spec.authors[2] = 'author-2'
55
+ # end
56
+ #
57
+ class AttributeAssignment < Base
58
+ include GemspecHelp
59
+
60
+ MSG = 'Use consistent style for Gemspec attributes assignment.'
61
+
62
+ def on_new_investigation
63
+ return if processed_source.blank?
64
+
65
+ assignments = source_assignments(processed_source.ast)
66
+ indexed_assignments = source_indexed_assignments(processed_source.ast)
67
+
68
+ assignments.keys.intersection(indexed_assignments.keys).each do |attribute|
69
+ indexed_assignments[attribute].each do |node|
70
+ add_offense(node)
71
+ end
72
+ end
73
+ end
74
+
75
+ private
76
+
77
+ def source_assignments(ast)
78
+ assignment_method_declarations(ast)
79
+ .select(&:assignment_method?)
80
+ .group_by(&:method_name)
81
+ .transform_keys { |method_name| method_name.to_s.delete_suffix('=').to_sym }
82
+ end
83
+
84
+ def source_indexed_assignments(ast)
85
+ indexed_assignment_method_declarations(ast)
86
+ .group_by { |node| node.children.first.method_name }
87
+ end
88
+ end
89
+ end
90
+ end
91
+ end
@@ -109,12 +109,6 @@ module RuboCop
109
109
  end
110
110
  end
111
111
 
112
- def match_block_variable_name?(receiver_name)
113
- gem_specification(processed_source.ast) do |block_variable_name|
114
- return block_variable_name == receiver_name
115
- end
116
- end
117
-
118
112
  def add_dependency_method?(method_name)
119
113
  ADD_DEPENDENCY_METHODS.include?(method_name)
120
114
  end
@@ -95,7 +95,7 @@ module RuboCop
95
95
  private
96
96
 
97
97
  def forbidden_gem?(gem_name)
98
- !cop_config['AllowedGems'].include?(gem_name)
98
+ !Array(cop_config['AllowedGems']).include?(gem_name)
99
99
  end
100
100
 
101
101
  def message(_range)
@@ -3,13 +3,14 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Gemspec
6
- # An attribute assignment method calls should be listed only once
6
+ # An attribute assignment method call should be listed only once
7
7
  # in a gemspec.
8
8
  #
9
- # Assigning to an attribute with the same name using `spec.foo =` will be
10
- # an unintended usage. On the other hand, duplication of methods such
11
- # as `spec.requirements`, `spec.add_runtime_dependency`, and others are
12
- # permitted because it is the intended use of appending values.
9
+ # Assigning to an attribute with the same name using `spec.foo =` or
10
+ # `spec.attribute#[]=` will be an unintended usage. On the other hand,
11
+ # duplication of methods such as `spec.requirements`,
12
+ # `spec.add_runtime_dependency`, and others are permitted because it is
13
+ # the intended use of appending values.
13
14
  #
14
15
  # @example
15
16
  # # bad
@@ -34,6 +35,18 @@ module RuboCop
34
35
  # spec.add_dependency('parallel', '~> 1.10')
35
36
  # spec.add_dependency('parser', '>= 2.3.3.1', '< 3.0')
36
37
  # end
38
+ #
39
+ # # bad
40
+ # Gem::Specification.new do |spec|
41
+ # spec.metadata["key"] = "value"
42
+ # spec.metadata["key"] = "value"
43
+ # end
44
+ #
45
+ # # good
46
+ # Gem::Specification.new do |spec|
47
+ # spec.metadata["key"] = "value"
48
+ # end
49
+ #
37
50
  class DuplicatedAssignment < Base
38
51
  include RangeHelp
39
52
  include GemspecHelp
@@ -41,15 +54,16 @@ module RuboCop
41
54
  MSG = '`%<assignment>s` method calls already given on line ' \
42
55
  '%<line_of_first_occurrence>d of the gemspec.'
43
56
 
44
- # @!method assignment_method_declarations(node)
45
- def_node_search :assignment_method_declarations, <<~PATTERN
46
- (send
47
- (lvar #match_block_variable_name?) _ ...)
48
- PATTERN
49
-
50
57
  def on_new_investigation
51
58
  return if processed_source.blank?
52
59
 
60
+ process_assignment_method_nodes
61
+ process_indexed_assignment_method_nodes
62
+ end
63
+
64
+ private
65
+
66
+ def process_assignment_method_nodes
53
67
  duplicated_assignment_method_nodes.each do |nodes|
54
68
  nodes[1..].each do |node|
55
69
  register_offense(node, node.method_name, nodes.first.first_line)
@@ -57,22 +71,40 @@ module RuboCop
57
71
  end
58
72
  end
59
73
 
60
- private
61
-
62
- def match_block_variable_name?(receiver_name)
63
- gem_specification(processed_source.ast) do |block_variable_name|
64
- return block_variable_name == receiver_name
74
+ def process_indexed_assignment_method_nodes
75
+ duplicated_indexed_assignment_method_nodes.each do |nodes|
76
+ nodes[1..].each do |node|
77
+ assignment = "#{node.children.first.method_name}[#{node.first_argument.source}]="
78
+ register_offense(node, assignment, nodes.first.first_line)
79
+ end
65
80
  end
66
81
  end
67
82
 
68
83
  def duplicated_assignment_method_nodes
69
84
  assignment_method_declarations(processed_source.ast)
70
85
  .select(&:assignment_method?)
71
- .group_by(&:method_name)
86
+ .group_by { |node| [enclosing_specification(node), node.method_name] }
72
87
  .values
73
88
  .select { |nodes| nodes.size > 1 }
74
89
  end
75
90
 
91
+ def duplicated_indexed_assignment_method_nodes
92
+ indexed_assignment_method_declarations(processed_source.ast)
93
+ .group_by { |node| indexed_assignment_key(node) }
94
+ .values
95
+ .select { |nodes| nodes.size > 1 }
96
+ end
97
+
98
+ def indexed_assignment_key(node)
99
+ [enclosing_specification(node), node.children.first.method_name, node.first_argument]
100
+ end
101
+
102
+ # Assignments in separate `Gem::Specification.new` blocks are not duplicates of
103
+ # one another, so the enclosing specification is part of the grouping key.
104
+ def enclosing_specification(node)
105
+ node.each_ancestor(:block).find { |block| gem_specification?(block) }
106
+ end
107
+
76
108
  def register_offense(node, assignment, line_of_first_occurrence)
77
109
  line_range = node.loc.column...node.loc.last_column
78
110
  offense_location = source_range(processed_source.buffer, node.first_line, line_range)
@@ -69,9 +69,8 @@ module RuboCop
69
69
  def on_new_investigation
70
70
  return if processed_source.blank?
71
71
 
72
- dependency_declarations(processed_source.ast)
73
- .each_cons(2) do |previous, current|
74
- next unless consecutive_lines(previous, current)
72
+ dependency_declarations(processed_source.ast).each_cons(2) do |previous, current|
73
+ next unless consecutive_lines?(previous, current)
75
74
  next unless case_insensitive_out_of_order?(gem_name(current), gem_name(previous))
76
75
  next unless get_dependency_name(previous) == get_dependency_name(current)
77
76
 
@@ -81,12 +80,6 @@ module RuboCop
81
80
 
82
81
  private
83
82
 
84
- def previous_declaration(node)
85
- declarations = dependency_declarations(processed_source.ast)
86
- node_index = declarations.find_index(node)
87
- declarations.to_a[node_index - 1]
88
- end
89
-
90
83
  def get_dependency_name(node)
91
84
  node.method_name
92
85
  end