rubocop 1.67.0 → 1.81.6

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 (526) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +23 -19
  4. data/config/default.yml +384 -72
  5. data/config/internal_affairs.yml +20 -0
  6. data/config/obsoletion.yml +8 -3
  7. data/exe/rubocop +1 -8
  8. data/lib/rubocop/cached_data.rb +12 -4
  9. data/lib/rubocop/cli/command/auto_generate_config.rb +2 -2
  10. data/lib/rubocop/cli/command/execute_runner.rb +4 -4
  11. data/lib/rubocop/cli/command/show_cops.rb +24 -2
  12. data/lib/rubocop/cli/command/suggest_extensions.rb +7 -1
  13. data/lib/rubocop/cli/command/version.rb +2 -2
  14. data/lib/rubocop/cli.rb +19 -4
  15. data/lib/rubocop/comment_config.rb +2 -2
  16. data/lib/rubocop/config.rb +52 -10
  17. data/lib/rubocop/config_loader.rb +56 -48
  18. data/lib/rubocop/config_loader_resolver.rb +36 -10
  19. data/lib/rubocop/config_obsoletion/extracted_cop.rb +4 -3
  20. data/lib/rubocop/config_obsoletion/renamed_cop.rb +18 -3
  21. data/lib/rubocop/config_obsoletion.rb +46 -2
  22. data/lib/rubocop/config_store.rb +5 -0
  23. data/lib/rubocop/config_validator.rb +25 -14
  24. data/lib/rubocop/cop/autocorrect_logic.rb +53 -28
  25. data/lib/rubocop/cop/base.rb +7 -1
  26. data/lib/rubocop/cop/bundler/duplicated_gem.rb +2 -2
  27. data/lib/rubocop/cop/bundler/gem_comment.rb +1 -1
  28. data/lib/rubocop/cop/bundler/gem_filename.rb +0 -1
  29. data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +0 -1
  30. data/lib/rubocop/cop/bundler/ordered_gems.rb +1 -1
  31. data/lib/rubocop/cop/correctors/alignment_corrector.rb +8 -16
  32. data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +8 -3
  33. data/lib/rubocop/cop/correctors/parentheses_corrector.rb +5 -2
  34. data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +10 -0
  35. data/lib/rubocop/cop/gemspec/attribute_assignment.rb +91 -0
  36. data/lib/rubocop/cop/gemspec/deprecated_attribute_assignment.rb +1 -2
  37. data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +37 -15
  38. data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +1 -1
  39. data/lib/rubocop/cop/gemspec/require_mfa.rb +15 -1
  40. data/lib/rubocop/cop/gemspec/required_ruby_version.rb +0 -2
  41. data/lib/rubocop/cop/generator.rb +6 -0
  42. data/lib/rubocop/cop/internal_affairs/cop_enabled.rb +85 -0
  43. data/lib/rubocop/cop/internal_affairs/example_description.rb +9 -5
  44. data/lib/rubocop/cop/internal_affairs/location_exists.rb +116 -0
  45. data/lib/rubocop/cop/internal_affairs/location_expression.rb +2 -1
  46. data/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +3 -4
  47. data/lib/rubocop/cop/internal_affairs/node_first_or_last_argument.rb +3 -2
  48. data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +5 -5
  49. data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_processor.rb +63 -0
  50. data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_walker.rb +131 -0
  51. data/lib/rubocop/cop/internal_affairs/node_pattern_groups.rb +233 -0
  52. data/lib/rubocop/cop/internal_affairs/node_type_group.rb +92 -0
  53. data/lib/rubocop/cop/internal_affairs/node_type_multiple_predicates.rb +126 -0
  54. data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +4 -3
  55. data/lib/rubocop/cop/internal_affairs/numblock_handler.rb +1 -1
  56. data/lib/rubocop/cop/internal_affairs/on_send_without_on_csend.rb +90 -0
  57. data/lib/rubocop/cop/internal_affairs/operator_keyword.rb +48 -0
  58. data/lib/rubocop/cop/internal_affairs/plugin.rb +33 -0
  59. data/lib/rubocop/cop/internal_affairs/redundant_described_class_as_subject.rb +6 -5
  60. data/lib/rubocop/cop/internal_affairs/redundant_source_range.rb +3 -1
  61. data/lib/rubocop/cop/internal_affairs/single_line_comparison.rb +5 -4
  62. data/lib/rubocop/cop/internal_affairs/style_detected_api_use.rb +0 -2
  63. data/lib/rubocop/cop/internal_affairs/undefined_config.rb +13 -2
  64. data/lib/rubocop/cop/internal_affairs/useless_restrict_on_send.rb +1 -1
  65. data/lib/rubocop/cop/internal_affairs.rb +7 -16
  66. data/lib/rubocop/cop/layout/access_modifier_indentation.rb +1 -1
  67. data/lib/rubocop/cop/layout/argument_alignment.rb +2 -9
  68. data/lib/rubocop/cop/layout/array_alignment.rb +1 -1
  69. data/lib/rubocop/cop/layout/begin_end_alignment.rb +0 -1
  70. data/lib/rubocop/cop/layout/block_alignment.rb +3 -2
  71. data/lib/rubocop/cop/layout/block_end_newline.rb +1 -0
  72. data/lib/rubocop/cop/layout/class_structure.rb +45 -10
  73. data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +5 -5
  74. data/lib/rubocop/cop/layout/def_end_alignment.rb +1 -1
  75. data/lib/rubocop/cop/layout/dot_position.rb +1 -1
  76. data/lib/rubocop/cop/layout/else_alignment.rb +2 -2
  77. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +3 -3
  78. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +34 -20
  79. data/lib/rubocop/cop/layout/empty_lines_after_module_inclusion.rb +101 -0
  80. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +37 -7
  81. data/lib/rubocop/cop/layout/empty_lines_around_arguments.rb +8 -29
  82. data/lib/rubocop/cop/layout/empty_lines_around_begin_body.rb +5 -6
  83. data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +1 -0
  84. data/lib/rubocop/cop/layout/empty_lines_around_class_body.rb +1 -1
  85. data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +4 -5
  86. data/lib/rubocop/cop/layout/empty_lines_around_method_body.rb +23 -1
  87. data/lib/rubocop/cop/layout/end_alignment.rb +1 -1
  88. data/lib/rubocop/cop/layout/extra_spacing.rb +1 -1
  89. data/lib/rubocop/cop/layout/first_argument_indentation.rb +4 -9
  90. data/lib/rubocop/cop/layout/first_array_element_indentation.rb +2 -7
  91. data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +2 -7
  92. data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +1 -1
  93. data/lib/rubocop/cop/layout/first_parameter_indentation.rb +2 -2
  94. data/lib/rubocop/cop/layout/hash_alignment.rb +8 -11
  95. data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +2 -1
  96. data/lib/rubocop/cop/layout/indentation_width.rb +8 -7
  97. data/lib/rubocop/cop/layout/leading_comment_space.rb +57 -2
  98. data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +11 -2
  99. data/lib/rubocop/cop/layout/line_continuation_spacing.rb +7 -1
  100. data/lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb +2 -2
  101. data/lib/rubocop/cop/layout/line_length.rb +158 -10
  102. data/lib/rubocop/cop/layout/multiline_block_layout.rb +1 -0
  103. data/lib/rubocop/cop/layout/multiline_hash_key_line_breaks.rb +1 -1
  104. data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +25 -0
  105. data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +2 -1
  106. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +4 -4
  107. data/lib/rubocop/cop/layout/multiline_method_definition_brace_layout.rb +1 -1
  108. data/lib/rubocop/cop/layout/multiline_method_parameter_line_breaks.rb +1 -0
  109. data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +11 -8
  110. data/lib/rubocop/cop/layout/parameter_alignment.rb +3 -4
  111. data/lib/rubocop/cop/layout/redundant_line_break.rb +19 -46
  112. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +14 -7
  113. data/lib/rubocop/cop/layout/single_line_block_chain.rb +1 -1
  114. data/lib/rubocop/cop/layout/space_after_colon.rb +2 -2
  115. data/lib/rubocop/cop/layout/space_after_comma.rb +1 -1
  116. data/lib/rubocop/cop/layout/space_after_method_name.rb +1 -1
  117. data/lib/rubocop/cop/layout/space_after_semicolon.rb +11 -1
  118. data/lib/rubocop/cop/layout/space_around_keyword.rb +8 -2
  119. data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +1 -1
  120. data/lib/rubocop/cop/layout/space_around_operators.rb +31 -21
  121. data/lib/rubocop/cop/layout/space_before_block_braces.rb +1 -0
  122. data/lib/rubocop/cop/layout/space_before_brackets.rb +7 -40
  123. data/lib/rubocop/cop/layout/space_before_comma.rb +1 -1
  124. data/lib/rubocop/cop/layout/space_before_semicolon.rb +1 -1
  125. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +18 -3
  126. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +5 -0
  127. data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +7 -0
  128. data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +0 -1
  129. data/lib/rubocop/cop/layout/trailing_whitespace.rb +6 -4
  130. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +1 -1
  131. data/lib/rubocop/cop/lint/ambiguous_range.rb +5 -0
  132. data/lib/rubocop/cop/lint/array_literal_in_regexp.rb +118 -0
  133. data/lib/rubocop/cop/lint/assignment_in_condition.rb +1 -3
  134. data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +10 -12
  135. data/lib/rubocop/cop/lint/boolean_symbol.rb +1 -1
  136. data/lib/rubocop/cop/lint/circular_argument_reference.rb +4 -1
  137. data/lib/rubocop/cop/lint/constant_definition_in_block.rb +3 -3
  138. data/lib/rubocop/cop/lint/constant_overwritten_in_rescue.rb +3 -2
  139. data/lib/rubocop/cop/lint/constant_reassignment.rb +148 -0
  140. data/lib/rubocop/cop/lint/cop_directive_syntax.rb +90 -0
  141. data/lib/rubocop/cop/lint/debugger.rb +3 -3
  142. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +1 -1
  143. data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +7 -3
  144. data/lib/rubocop/cop/lint/duplicate_branch.rb +39 -4
  145. data/lib/rubocop/cop/lint/duplicate_match_pattern.rb +1 -1
  146. data/lib/rubocop/cop/lint/duplicate_methods.rb +111 -23
  147. data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +6 -43
  148. data/lib/rubocop/cop/lint/duplicate_set_element.rb +20 -7
  149. data/lib/rubocop/cop/lint/empty_conditional_body.rb +14 -64
  150. data/lib/rubocop/cop/lint/empty_ensure.rb +1 -1
  151. data/lib/rubocop/cop/lint/empty_expression.rb +0 -2
  152. data/lib/rubocop/cop/lint/empty_file.rb +0 -2
  153. data/lib/rubocop/cop/lint/empty_interpolation.rb +14 -1
  154. data/lib/rubocop/cop/lint/ensure_return.rb +1 -1
  155. data/lib/rubocop/cop/lint/erb_new_arguments.rb +0 -6
  156. data/lib/rubocop/cop/lint/float_comparison.rb +51 -18
  157. data/lib/rubocop/cop/lint/float_out_of_range.rb +2 -4
  158. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +2 -2
  159. data/lib/rubocop/cop/lint/hash_new_with_keyword_arguments_as_default.rb +55 -0
  160. data/lib/rubocop/cop/lint/identity_comparison.rb +19 -15
  161. data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +1 -1
  162. data/lib/rubocop/cop/lint/interpolation_check.rb +9 -0
  163. data/lib/rubocop/cop/lint/it_without_arguments_in_block.rb +3 -0
  164. data/lib/rubocop/cop/lint/literal_as_condition.rb +125 -10
  165. data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +1 -1
  166. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +24 -6
  167. data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +1 -2
  168. data/lib/rubocop/cop/lint/missing_super.rb +2 -2
  169. data/lib/rubocop/cop/lint/mixed_case_range.rb +5 -8
  170. data/lib/rubocop/cop/lint/mixed_regexp_capture_types.rb +1 -1
  171. data/lib/rubocop/cop/lint/nested_method_definition.rb +10 -6
  172. data/lib/rubocop/cop/lint/next_without_accumulator.rb +1 -1
  173. data/lib/rubocop/cop/lint/no_return_in_begin_end_blocks.rb +2 -2
  174. data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +12 -3
  175. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +3 -3
  176. data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +3 -3
  177. data/lib/rubocop/cop/lint/number_conversion.rb +0 -1
  178. data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +1 -2
  179. data/lib/rubocop/cop/lint/numeric_operation_with_constant_result.rb +94 -0
  180. data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +2 -3
  181. data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +3 -2
  182. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +1 -5
  183. data/lib/rubocop/cop/lint/raise_exception.rb +29 -10
  184. data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +1 -1
  185. data/lib/rubocop/cop/lint/redundant_regexp_quantifiers.rb +2 -2
  186. data/lib/rubocop/cop/lint/redundant_require_statement.rb +0 -21
  187. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +113 -9
  188. data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +8 -7
  189. data/lib/rubocop/cop/lint/redundant_string_coercion.rb +2 -2
  190. data/lib/rubocop/cop/lint/redundant_type_conversion.rb +261 -0
  191. data/lib/rubocop/cop/lint/redundant_with_index.rb +3 -0
  192. data/lib/rubocop/cop/lint/redundant_with_object.rb +3 -0
  193. data/lib/rubocop/cop/lint/refinement_import_methods.rb +1 -1
  194. data/lib/rubocop/cop/lint/regexp_as_condition.rb +0 -1
  195. data/lib/rubocop/cop/lint/require_range_parentheses.rb +1 -1
  196. data/lib/rubocop/cop/lint/rescue_exception.rb +2 -5
  197. data/lib/rubocop/cop/lint/rescue_type.rb +4 -8
  198. data/lib/rubocop/cop/lint/return_in_void_context.rb +9 -11
  199. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +17 -1
  200. data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +5 -1
  201. data/lib/rubocop/cop/lint/self_assignment.rb +39 -15
  202. data/lib/rubocop/cop/lint/shadowed_argument.rb +7 -7
  203. data/lib/rubocop/cop/lint/shadowed_exception.rb +1 -1
  204. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +13 -1
  205. data/lib/rubocop/cop/lint/shared_mutable_default.rb +76 -0
  206. data/lib/rubocop/cop/lint/suppressed_exception.rb +1 -1
  207. data/lib/rubocop/cop/lint/suppressed_exception_in_number_conversion.rb +111 -0
  208. data/lib/rubocop/cop/lint/symbol_conversion.rb +1 -1
  209. data/lib/rubocop/cop/lint/syntax.rb +4 -1
  210. data/lib/rubocop/cop/lint/to_enum_arguments.rb +1 -1
  211. data/lib/rubocop/cop/lint/top_level_return_with_argument.rb +1 -1
  212. data/lib/rubocop/cop/lint/unescaped_bracket_in_regexp.rb +88 -0
  213. data/lib/rubocop/cop/lint/unexpected_block_arity.rb +3 -1
  214. data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +1 -1
  215. data/lib/rubocop/cop/lint/unreachable_code.rb +52 -2
  216. data/lib/rubocop/cop/lint/unreachable_loop.rb +6 -6
  217. data/lib/rubocop/cop/lint/unused_method_argument.rb +18 -2
  218. data/lib/rubocop/cop/lint/uri_escape_unescape.rb +2 -0
  219. data/lib/rubocop/cop/lint/useless_access_modifier.rb +34 -8
  220. data/lib/rubocop/cop/lint/useless_assignment.rb +3 -1
  221. data/lib/rubocop/cop/lint/useless_constant_scoping.rb +71 -0
  222. data/lib/rubocop/cop/lint/useless_default_value_argument.rb +90 -0
  223. data/lib/rubocop/cop/lint/useless_defined.rb +55 -0
  224. data/lib/rubocop/cop/lint/useless_else_without_rescue.rb +4 -0
  225. data/lib/rubocop/cop/lint/useless_method_definition.rb +1 -1
  226. data/lib/rubocop/cop/lint/useless_numeric_operation.rb +3 -1
  227. data/lib/rubocop/cop/lint/useless_or.rb +98 -0
  228. data/lib/rubocop/cop/lint/useless_rescue.rb +2 -2
  229. data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +5 -5
  230. data/lib/rubocop/cop/lint/useless_setter_call.rb +14 -25
  231. data/lib/rubocop/cop/lint/utils/nil_receiver_checker.rb +121 -0
  232. data/lib/rubocop/cop/lint/void.rb +23 -12
  233. data/lib/rubocop/cop/message_annotator.rb +7 -3
  234. data/lib/rubocop/cop/metrics/abc_size.rb +1 -1
  235. data/lib/rubocop/cop/metrics/block_length.rb +1 -0
  236. data/lib/rubocop/cop/metrics/block_nesting.rb +1 -1
  237. data/lib/rubocop/cop/metrics/class_length.rb +9 -9
  238. data/lib/rubocop/cop/metrics/collection_literal_length.rb +7 -0
  239. data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +5 -2
  240. data/lib/rubocop/cop/metrics/method_length.rb +9 -1
  241. data/lib/rubocop/cop/metrics/module_length.rb +1 -1
  242. data/lib/rubocop/cop/metrics/perceived_complexity.rb +1 -1
  243. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +1 -1
  244. data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +3 -4
  245. data/lib/rubocop/cop/metrics/utils/repeated_attribute_discount.rb +7 -7
  246. data/lib/rubocop/cop/mixin/alignment.rb +3 -3
  247. data/lib/rubocop/cop/mixin/allowed_pattern.rb +4 -4
  248. data/lib/rubocop/cop/mixin/check_assignment.rb +4 -12
  249. data/lib/rubocop/cop/mixin/check_line_breakable.rb +22 -12
  250. data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +49 -0
  251. data/lib/rubocop/cop/mixin/comments_help.rb +8 -3
  252. data/lib/rubocop/cop/mixin/def_node.rb +1 -1
  253. data/lib/rubocop/cop/mixin/dig_help.rb +27 -0
  254. data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +1 -1
  255. data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +1 -7
  256. data/lib/rubocop/cop/mixin/endless_method_rewriter.rb +24 -0
  257. data/lib/rubocop/cop/mixin/forbidden_identifiers.rb +20 -0
  258. data/lib/rubocop/cop/mixin/forbidden_pattern.rb +16 -0
  259. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +4 -3
  260. data/lib/rubocop/cop/mixin/gemspec_help.rb +22 -0
  261. data/lib/rubocop/cop/mixin/hash_alignment_styles.rb +15 -14
  262. data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +22 -22
  263. data/lib/rubocop/cop/mixin/hash_subset.rb +203 -0
  264. data/lib/rubocop/cop/mixin/hash_transform_method.rb +74 -74
  265. data/lib/rubocop/cop/mixin/line_length_help.rb +27 -10
  266. data/lib/rubocop/cop/mixin/method_complexity.rb +2 -1
  267. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +7 -9
  268. data/lib/rubocop/cop/mixin/ordered_gem_node.rb +1 -1
  269. data/lib/rubocop/cop/mixin/percent_literal.rb +1 -1
  270. data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +68 -30
  271. data/lib/rubocop/cop/mixin/range_help.rb +15 -4
  272. data/lib/rubocop/cop/mixin/space_before_punctuation.rb +1 -1
  273. data/lib/rubocop/cop/mixin/statement_modifier.rb +8 -3
  274. data/lib/rubocop/cop/mixin/string_help.rb +2 -2
  275. data/lib/rubocop/cop/mixin/string_literals_help.rb +1 -1
  276. data/lib/rubocop/cop/mixin/target_ruby_version.rb +17 -1
  277. data/lib/rubocop/cop/mixin/trailing_comma.rb +21 -5
  278. data/lib/rubocop/cop/naming/accessor_method_name.rb +6 -6
  279. data/lib/rubocop/cop/naming/block_forwarding.rb +20 -16
  280. data/lib/rubocop/cop/naming/constant_name.rb +6 -7
  281. data/lib/rubocop/cop/naming/file_name.rb +2 -4
  282. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +12 -13
  283. data/lib/rubocop/cop/naming/method_name.rb +185 -15
  284. data/lib/rubocop/cop/naming/predicate_method.rb +319 -0
  285. data/lib/rubocop/cop/naming/{predicate_name.rb → predicate_prefix.rb} +48 -4
  286. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +6 -14
  287. data/lib/rubocop/cop/naming/variable_name.rb +50 -6
  288. data/lib/rubocop/cop/naming/variable_number.rb +2 -3
  289. data/lib/rubocop/cop/offense.rb +2 -3
  290. data/lib/rubocop/cop/registry.rb +9 -6
  291. data/lib/rubocop/cop/security/compound_hash.rb +2 -0
  292. data/lib/rubocop/cop/security/eval.rb +2 -1
  293. data/lib/rubocop/cop/security/json_load.rb +33 -11
  294. data/lib/rubocop/cop/security/open.rb +1 -0
  295. data/lib/rubocop/cop/security/yaml_load.rb +3 -2
  296. data/lib/rubocop/cop/style/access_modifier_declarations.rb +114 -34
  297. data/lib/rubocop/cop/style/accessor_grouping.rb +32 -6
  298. data/lib/rubocop/cop/style/ambiguous_endless_method_definition.rb +79 -0
  299. data/lib/rubocop/cop/style/and_or.rb +1 -1
  300. data/lib/rubocop/cop/style/arguments_forwarding.rb +57 -44
  301. data/lib/rubocop/cop/style/array_first_last.rb +18 -2
  302. data/lib/rubocop/cop/style/array_intersect.rb +115 -39
  303. data/lib/rubocop/cop/style/array_intersect_with_single_element.rb +47 -0
  304. data/lib/rubocop/cop/style/bitwise_predicate.rb +107 -0
  305. data/lib/rubocop/cop/style/block_delimiters.rb +44 -26
  306. data/lib/rubocop/cop/style/case_like_if.rb +9 -12
  307. data/lib/rubocop/cop/style/class_and_module_children.rb +52 -11
  308. data/lib/rubocop/cop/style/class_equality_comparison.rb +1 -1
  309. data/lib/rubocop/cop/style/collection_methods.rb +2 -1
  310. data/lib/rubocop/cop/style/collection_querying.rb +167 -0
  311. data/lib/rubocop/cop/style/combinable_defined.rb +115 -0
  312. data/lib/rubocop/cop/style/combinable_loops.rb +3 -2
  313. data/lib/rubocop/cop/style/command_literal.rb +1 -1
  314. data/lib/rubocop/cop/style/commented_keyword.rb +20 -3
  315. data/lib/rubocop/cop/style/comparable_between.rb +78 -0
  316. data/lib/rubocop/cop/style/concat_array_literals.rb +1 -1
  317. data/lib/rubocop/cop/style/conditional_assignment.rb +49 -31
  318. data/lib/rubocop/cop/style/constant_visibility.rb +3 -12
  319. data/lib/rubocop/cop/style/data_inheritance.rb +7 -0
  320. data/lib/rubocop/cop/style/def_with_parentheses.rb +18 -5
  321. data/lib/rubocop/cop/style/dig_chain.rb +89 -0
  322. data/lib/rubocop/cop/style/documentation.rb +1 -1
  323. data/lib/rubocop/cop/style/double_negation.rb +5 -5
  324. data/lib/rubocop/cop/style/each_for_simple_loop.rb +4 -7
  325. data/lib/rubocop/cop/style/each_with_object.rb +2 -3
  326. data/lib/rubocop/cop/style/empty_else.rb +4 -2
  327. data/lib/rubocop/cop/style/empty_literal.rb +5 -1
  328. data/lib/rubocop/cop/style/empty_method.rb +1 -1
  329. data/lib/rubocop/cop/style/empty_string_inside_interpolation.rb +100 -0
  330. data/lib/rubocop/cop/style/endless_method.rb +163 -18
  331. data/lib/rubocop/cop/style/eval_with_location.rb +4 -4
  332. data/lib/rubocop/cop/style/exact_regexp_match.rb +2 -3
  333. data/lib/rubocop/cop/style/expand_path_arguments.rb +2 -7
  334. data/lib/rubocop/cop/style/explicit_block_argument.rb +17 -4
  335. data/lib/rubocop/cop/style/exponential_notation.rb +6 -5
  336. data/lib/rubocop/cop/style/fetch_env_var.rb +34 -7
  337. data/lib/rubocop/cop/style/file_null.rb +89 -0
  338. data/lib/rubocop/cop/style/file_touch.rb +75 -0
  339. data/lib/rubocop/cop/style/float_division.rb +8 -4
  340. data/lib/rubocop/cop/style/for.rb +1 -1
  341. data/lib/rubocop/cop/style/format_string_token.rb +38 -11
  342. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +3 -2
  343. data/lib/rubocop/cop/style/global_std_stream.rb +3 -0
  344. data/lib/rubocop/cop/style/global_vars.rb +1 -3
  345. data/lib/rubocop/cop/style/guard_clause.rb +17 -3
  346. data/lib/rubocop/cop/style/hash_conversion.rb +16 -9
  347. data/lib/rubocop/cop/style/hash_each_methods.rb +6 -8
  348. data/lib/rubocop/cop/style/hash_except.rb +35 -147
  349. data/lib/rubocop/cop/style/hash_fetch_chain.rb +104 -0
  350. data/lib/rubocop/cop/style/hash_slice.rb +80 -0
  351. data/lib/rubocop/cop/style/hash_syntax.rb +9 -3
  352. data/lib/rubocop/cop/style/hash_transform_keys.rb +2 -2
  353. data/lib/rubocop/cop/style/hash_transform_values.rb +2 -2
  354. data/lib/rubocop/cop/style/identical_conditional_branches.rb +25 -6
  355. data/lib/rubocop/cop/style/if_inside_else.rb +10 -14
  356. data/lib/rubocop/cop/style/if_unless_modifier.rb +36 -9
  357. data/lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb +4 -7
  358. data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +3 -4
  359. data/lib/rubocop/cop/style/if_with_semicolon.rb +20 -9
  360. data/lib/rubocop/cop/style/infinite_loop.rb +1 -1
  361. data/lib/rubocop/cop/style/inverse_methods.rb +16 -13
  362. data/lib/rubocop/cop/style/invertible_unless_condition.rb +2 -2
  363. data/lib/rubocop/cop/style/ip_addresses.rb +2 -2
  364. data/lib/rubocop/cop/style/it_assignment.rb +93 -0
  365. data/lib/rubocop/cop/style/it_block_parameter.rb +121 -0
  366. data/lib/rubocop/cop/style/keyword_arguments_merging.rb +67 -0
  367. data/lib/rubocop/cop/style/keyword_parameters_order.rb +14 -8
  368. data/lib/rubocop/cop/style/lambda.rb +1 -0
  369. data/lib/rubocop/cop/style/lambda_call.rb +10 -4
  370. data/lib/rubocop/cop/style/line_end_concatenation.rb +10 -4
  371. data/lib/rubocop/cop/style/map_into_array.rb +11 -3
  372. data/lib/rubocop/cop/style/map_to_hash.rb +13 -4
  373. data/lib/rubocop/cop/style/map_to_set.rb +4 -5
  374. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +28 -20
  375. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +18 -0
  376. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +8 -11
  377. data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +3 -4
  378. data/lib/rubocop/cop/style/method_def_parentheses.rb +1 -1
  379. data/lib/rubocop/cop/style/min_max_comparison.rb +13 -5
  380. data/lib/rubocop/cop/style/missing_else.rb +2 -0
  381. data/lib/rubocop/cop/style/missing_respond_to_missing.rb +33 -3
  382. data/lib/rubocop/cop/style/multiline_block_chain.rb +3 -2
  383. data/lib/rubocop/cop/style/multiline_if_modifier.rb +2 -0
  384. data/lib/rubocop/cop/style/multiline_memoization.rb +1 -1
  385. data/lib/rubocop/cop/style/multiline_method_signature.rb +1 -9
  386. data/lib/rubocop/cop/style/multiple_comparison.rb +52 -51
  387. data/lib/rubocop/cop/style/mutable_constant.rb +7 -8
  388. data/lib/rubocop/cop/style/negated_if_else_condition.rb +7 -5
  389. data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +1 -1
  390. data/lib/rubocop/cop/style/nested_ternary_operator.rb +5 -4
  391. data/lib/rubocop/cop/style/next.rb +44 -0
  392. data/lib/rubocop/cop/style/nil_comparison.rb +9 -7
  393. data/lib/rubocop/cop/style/not.rb +1 -1
  394. data/lib/rubocop/cop/style/object_then.rb +15 -15
  395. data/lib/rubocop/cop/style/one_line_conditional.rb +42 -13
  396. data/lib/rubocop/cop/style/open_struct_use.rb +5 -5
  397. data/lib/rubocop/cop/style/operator_method_call.rb +5 -6
  398. data/lib/rubocop/cop/style/or_assignment.rb +3 -6
  399. data/lib/rubocop/cop/style/parallel_assignment.rb +41 -38
  400. data/lib/rubocop/cop/style/parentheses_around_condition.rb +2 -2
  401. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +1 -1
  402. data/lib/rubocop/cop/style/percent_q_literals.rb +1 -1
  403. data/lib/rubocop/cop/style/proc.rb +2 -2
  404. data/lib/rubocop/cop/style/quoted_symbols.rb +1 -1
  405. data/lib/rubocop/cop/style/raise_args.rb +15 -13
  406. data/lib/rubocop/cop/style/random_with_offset.rb +3 -3
  407. data/lib/rubocop/cop/style/redundant_argument.rb +3 -1
  408. data/lib/rubocop/cop/style/redundant_array_flatten.rb +50 -0
  409. data/lib/rubocop/cop/style/redundant_assignment.rb +1 -1
  410. data/lib/rubocop/cop/style/redundant_begin.rb +36 -1
  411. data/lib/rubocop/cop/style/redundant_condition.rb +95 -23
  412. data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +16 -5
  413. data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +6 -10
  414. data/lib/rubocop/cop/style/redundant_each.rb +1 -1
  415. data/lib/rubocop/cop/style/redundant_exception.rb +2 -2
  416. data/lib/rubocop/cop/style/redundant_fetch_block.rb +1 -9
  417. data/lib/rubocop/cop/style/redundant_format.rb +283 -0
  418. data/lib/rubocop/cop/style/redundant_freeze.rb +4 -4
  419. data/lib/rubocop/cop/style/redundant_initialize.rb +12 -3
  420. data/lib/rubocop/cop/style/redundant_interpolation.rb +12 -3
  421. data/lib/rubocop/cop/style/redundant_line_continuation.rb +55 -19
  422. data/lib/rubocop/cop/style/redundant_parentheses.rb +105 -36
  423. data/lib/rubocop/cop/style/redundant_regexp_argument.rb +8 -0
  424. data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +1 -1
  425. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +9 -1
  426. data/lib/rubocop/cop/style/redundant_return.rb +2 -2
  427. data/lib/rubocop/cop/style/redundant_self.rb +15 -18
  428. data/lib/rubocop/cop/style/redundant_self_assignment.rb +20 -32
  429. data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +4 -4
  430. data/lib/rubocop/cop/style/redundant_sort.rb +3 -3
  431. data/lib/rubocop/cop/style/redundant_sort_by.rb +17 -1
  432. data/lib/rubocop/cop/style/redundant_string_escape.rb +2 -2
  433. data/lib/rubocop/cop/style/regexp_literal.rb +1 -1
  434. data/lib/rubocop/cop/style/rescue_modifier.rb +5 -3
  435. data/lib/rubocop/cop/style/return_nil.rb +2 -2
  436. data/lib/rubocop/cop/style/safe_navigation.rb +75 -16
  437. data/lib/rubocop/cop/style/safe_navigation_chain_length.rb +52 -0
  438. data/lib/rubocop/cop/style/select_by_regexp.rb +5 -2
  439. data/lib/rubocop/cop/style/self_assignment.rb +11 -17
  440. data/lib/rubocop/cop/style/semicolon.rb +21 -6
  441. data/lib/rubocop/cop/style/send_with_literal_method_name.rb +2 -1
  442. data/lib/rubocop/cop/style/signal_exception.rb +2 -3
  443. data/lib/rubocop/cop/style/single_argument_dig.rb +9 -5
  444. data/lib/rubocop/cop/style/single_line_block_params.rb +1 -1
  445. data/lib/rubocop/cop/style/single_line_do_end_block.rb +15 -4
  446. data/lib/rubocop/cop/style/single_line_methods.rb +13 -11
  447. data/lib/rubocop/cop/style/slicing_with_range.rb +40 -11
  448. data/lib/rubocop/cop/style/sole_nested_conditional.rb +68 -102
  449. data/lib/rubocop/cop/style/special_global_vars.rb +1 -1
  450. data/lib/rubocop/cop/style/stabby_lambda_parentheses.rb +1 -1
  451. data/lib/rubocop/cop/style/string_concatenation.rb +21 -17
  452. data/lib/rubocop/cop/style/string_literals.rb +1 -1
  453. data/lib/rubocop/cop/style/string_methods.rb +1 -1
  454. data/lib/rubocop/cop/style/struct_inheritance.rb +8 -1
  455. data/lib/rubocop/cop/style/super_arguments.rb +66 -19
  456. data/lib/rubocop/cop/style/swap_values.rb +4 -15
  457. data/lib/rubocop/cop/style/symbol_array.rb +1 -1
  458. data/lib/rubocop/cop/style/symbol_proc.rb +3 -1
  459. data/lib/rubocop/cop/style/ternary_parentheses.rb +25 -4
  460. data/lib/rubocop/cop/style/top_level_method_definition.rb +2 -1
  461. data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +56 -2
  462. data/lib/rubocop/cop/style/trailing_comma_in_array_literal.rb +47 -6
  463. data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +1 -1
  464. data/lib/rubocop/cop/style/trailing_comma_in_hash_literal.rb +48 -6
  465. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +4 -4
  466. data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
  467. data/lib/rubocop/cop/style/unless_else.rb +10 -9
  468. data/lib/rubocop/cop/style/variable_interpolation.rb +1 -2
  469. data/lib/rubocop/cop/style/while_until_modifier.rb +0 -1
  470. data/lib/rubocop/cop/style/yoda_condition.rb +8 -4
  471. data/lib/rubocop/cop/style/yoda_expression.rb +2 -1
  472. data/lib/rubocop/cop/team.rb +1 -1
  473. data/lib/rubocop/cop/util.rb +12 -5
  474. data/lib/rubocop/cop/utils/format_string.rb +20 -5
  475. data/lib/rubocop/cop/variable_force/assignment.rb +24 -5
  476. data/lib/rubocop/cop/variable_force/branch.rb +1 -1
  477. data/lib/rubocop/cop/variable_force/scope.rb +1 -1
  478. data/lib/rubocop/cop/variable_force/variable.rb +14 -3
  479. data/lib/rubocop/cop/variable_force/variable_table.rb +5 -5
  480. data/lib/rubocop/cop/variable_force.rb +30 -19
  481. data/lib/rubocop/cops_documentation_generator.rb +54 -28
  482. data/lib/rubocop/directive_comment.rb +45 -11
  483. data/lib/rubocop/ext/regexp_node.rb +0 -1
  484. data/lib/rubocop/formatter/disabled_config_formatter.rb +20 -6
  485. data/lib/rubocop/formatter/formatter_set.rb +1 -1
  486. data/lib/rubocop/formatter/fuubar_style_formatter.rb +1 -1
  487. data/lib/rubocop/formatter/html_formatter.rb +1 -1
  488. data/lib/rubocop/formatter/markdown_formatter.rb +1 -0
  489. data/lib/rubocop/formatter/offense_count_formatter.rb +1 -1
  490. data/lib/rubocop/formatter/pacman_formatter.rb +2 -1
  491. data/lib/rubocop/lsp/diagnostic.rb +190 -0
  492. data/lib/rubocop/lsp/logger.rb +2 -2
  493. data/lib/rubocop/lsp/routes.rb +66 -26
  494. data/lib/rubocop/lsp/runtime.rb +18 -50
  495. data/lib/rubocop/lsp/server.rb +2 -4
  496. data/lib/rubocop/lsp/stdin_runner.rb +69 -0
  497. data/lib/rubocop/magic_comment.rb +11 -3
  498. data/lib/rubocop/options.rb +28 -12
  499. data/lib/rubocop/path_util.rb +15 -8
  500. data/lib/rubocop/pending_cops_reporter.rb +56 -0
  501. data/lib/rubocop/plugin/configuration_integrator.rb +143 -0
  502. data/lib/rubocop/plugin/load_error.rb +26 -0
  503. data/lib/rubocop/plugin/loader.rb +100 -0
  504. data/lib/rubocop/plugin/not_supported_error.rb +29 -0
  505. data/lib/rubocop/plugin.rb +46 -0
  506. data/lib/rubocop/rake_task.rb +4 -1
  507. data/lib/rubocop/result_cache.rb +27 -25
  508. data/lib/rubocop/rspec/cop_helper.rb +13 -1
  509. data/lib/rubocop/rspec/expect_offense.rb +15 -5
  510. data/lib/rubocop/rspec/shared_contexts.rb +38 -1
  511. data/lib/rubocop/rspec/support.rb +4 -2
  512. data/lib/rubocop/runner.rb +31 -18
  513. data/lib/rubocop/server/cache.rb +51 -13
  514. data/lib/rubocop/server/cli.rb +2 -2
  515. data/lib/rubocop/server/client_command/base.rb +10 -0
  516. data/lib/rubocop/server/client_command/exec.rb +2 -1
  517. data/lib/rubocop/server/client_command/start.rb +11 -1
  518. data/lib/rubocop/target_finder.rb +14 -9
  519. data/lib/rubocop/target_ruby.rb +27 -3
  520. data/lib/rubocop/version.rb +53 -12
  521. data/lib/rubocop.rb +44 -2
  522. data/lib/ruby_lsp/rubocop/addon.rb +90 -0
  523. data/lib/ruby_lsp/rubocop/runtime_adapter.rb +99 -0
  524. metadata +91 -21
  525. data/lib/rubocop/cop/utils/regexp_ranges.rb +0 -113
  526. data/lib/rubocop/rspec/host_environment_simulation_helper.rb +0 -28
@@ -50,6 +50,7 @@ module RuboCop
50
50
 
51
51
  def on_send(node)
52
52
  return unless supported_operators.include?(node.method_name.to_s)
53
+ return unless node.arguments?
53
54
 
54
55
  lhs = node.receiver
55
56
  rhs = node.first_argument
@@ -71,7 +72,7 @@ module RuboCop
71
72
  end
72
73
 
73
74
  def constant_portion?(node)
74
- node.numeric_type? || node.const_type?
75
+ node.type?(:numeric, :const)
75
76
  end
76
77
 
77
78
  def supported_operators
@@ -279,7 +279,7 @@ module RuboCop
279
279
  @errors << message
280
280
  warn message
281
281
  if debug?
282
- puts error.message, error.backtrace
282
+ puts error.full_message
283
283
  else
284
284
  warn 'To see the complete backtrace run rubocop -d.'
285
285
  end
@@ -32,7 +32,7 @@ module RuboCop
32
32
  end
33
33
 
34
34
  def parentheses?(node)
35
- node.loc.respond_to?(:end) && node.loc.end&.is?(')')
35
+ node.loc_is?(:end, ')')
36
36
  end
37
37
 
38
38
  # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
@@ -74,9 +74,9 @@ module RuboCop
74
74
 
75
75
  def args_begin(node)
76
76
  loc = node.loc
77
- selector = if node.super_type? || node.yield_type?
77
+ selector = if node.type?(:super, :yield)
78
78
  loc.keyword
79
- elsif node.def_type? || node.defs_type?
79
+ elsif node.any_def_type?
80
80
  loc.name
81
81
  else
82
82
  loc.selector
@@ -193,11 +193,18 @@ module RuboCop
193
193
  enforced_style.sub(/^Enforced/, 'Supported').sub('Style', 'Styles')
194
194
  end
195
195
 
196
+ def parse_regexp(text)
197
+ Regexp::Parser.parse(text)
198
+ rescue Regexp::Parser::Error
199
+ # Upon encountering an invalid regular expression,
200
+ # we aim to proceed and identify any remaining potential offenses.
201
+ nil
202
+ end
203
+
196
204
  private
197
205
 
198
206
  def compatible_external_encoding_for?(src)
199
- src = src.dup if RUBY_ENGINE == 'jruby'
200
- src.force_encoding(Encoding.default_external).valid_encoding?
207
+ src.dup.force_encoding(Encoding.default_external).valid_encoding?
201
208
  end
202
209
 
203
210
  def include_or_equal?(source, target)
@@ -5,15 +5,19 @@ module RuboCop
5
5
  module Utils
6
6
  # Parses {Kernel#sprintf} format strings.
7
7
  class FormatString
8
- DIGIT_DOLLAR = /(\d+)\$/.freeze
8
+ # Escaping the `#` in `INTERPOLATION` and `TEMPLATE_NAME` is necessary to
9
+ # avoid a bug in Ruby 3.2.0
10
+ # See: https://bugs.ruby-lang.org/issues/19379
11
+ DIGIT_DOLLAR = /(?<arg_number>\d+)\$/.freeze
12
+ INTERPOLATION = /\#\{.*?\}/.freeze
9
13
  FLAG = /[ #0+-]|#{DIGIT_DOLLAR}/.freeze
10
14
  NUMBER_ARG = /\*#{DIGIT_DOLLAR}?/.freeze
11
- NUMBER = /\d+|#{NUMBER_ARG}/.freeze
15
+ NUMBER = /\d+|#{NUMBER_ARG}|#{INTERPOLATION}/.freeze
12
16
  WIDTH = /(?<width>#{NUMBER})/.freeze
13
- PRECISION = /\.(?<precision>#{NUMBER})/.freeze
17
+ PRECISION = /\.(?<precision>#{NUMBER}?)/.freeze
14
18
  TYPE = /(?<type>[bBdiouxXeEfgGaAcps])/.freeze
15
19
  NAME = /<(?<name>\w+)>/.freeze
16
- TEMPLATE_NAME = /\{(?<name>\w+)\}/.freeze
20
+ TEMPLATE_NAME = /(?<!\#)\{(?<name>\w+)\}/.freeze
17
21
 
18
22
  SEQUENCE = /
19
23
  % (?<type>%)
@@ -41,7 +45,7 @@ module RuboCop
41
45
  #
42
46
  # @see https://ruby-doc.org/core-2.6.3/Kernel.html#method-i-format
43
47
  class FormatSequence
44
- attr_reader :begin_pos, :end_pos, :flags, :width, :precision, :name, :type
48
+ attr_reader :begin_pos, :end_pos, :flags, :width, :precision, :name, :type, :arg_number
45
49
 
46
50
  def initialize(match)
47
51
  @source = match[0]
@@ -52,6 +56,7 @@ module RuboCop
52
56
  @precision = match[:precision]
53
57
  @name = match[:name]
54
58
  @type = match[:type]
59
+ @arg_number = match[:arg_number]
55
60
  end
56
61
 
57
62
  def percent?
@@ -66,6 +71,16 @@ module RuboCop
66
71
  name && @source.include?('{')
67
72
  end
68
73
 
74
+ def variable_width?
75
+ !!width&.start_with?('*')
76
+ end
77
+
78
+ def variable_width_argument_number
79
+ return unless variable_width?
80
+
81
+ width == '*' ? 1 : width.match(DIGIT_DOLLAR)['arg_number'].to_i
82
+ end
83
+
69
84
  # Number of arguments required for the format sequence
70
85
  def arity
71
86
  @source.scan('*').count + 1
@@ -9,9 +9,10 @@ module RuboCop
9
9
 
10
10
  MULTIPLE_LEFT_HAND_SIDE_TYPE = :mlhs
11
11
 
12
- attr_reader :node, :variable, :referenced, :references
12
+ attr_reader :node, :variable, :referenced, :references, :reassigned
13
13
 
14
14
  alias referenced? referenced
15
+ alias reassigned? reassigned
15
16
 
16
17
  def initialize(node, variable)
17
18
  unless VARIABLE_ASSIGNMENT_TYPES.include?(node.type)
@@ -24,6 +25,7 @@ module RuboCop
24
25
  @variable = variable
25
26
  @referenced = false
26
27
  @references = []
28
+ @reassigned = false
27
29
  end
28
30
 
29
31
  def name
@@ -39,8 +41,14 @@ module RuboCop
39
41
  @referenced = true
40
42
  end
41
43
 
44
+ def reassigned!
45
+ return if referenced?
46
+
47
+ @reassigned = true
48
+ end
49
+
42
50
  def used?
43
- @variable.captured_by_block? || @referenced
51
+ (!reassigned? && @variable.captured_by_block?) || @referenced
44
52
  end
45
53
 
46
54
  def regexp_named_capture?
@@ -102,7 +110,13 @@ module RuboCop
102
110
  end
103
111
 
104
112
  def multiple_assignment_node
105
- return nil unless (grandparent_node = node.parent&.parent)
113
+ return nil unless (candidate_mlhs_node = node.parent)
114
+
115
+ # In `(foo, bar), *baz`, the splat node must be traversed as well.
116
+ candidate_mlhs_node = candidate_mlhs_node.parent if candidate_mlhs_node.splat_type?
117
+
118
+ return nil unless candidate_mlhs_node.mlhs_type?
119
+ return nil unless (grandparent_node = node.parent.parent)
106
120
  if (node = find_multiple_assignment_node(grandparent_node))
107
121
  return node
108
122
  end
@@ -119,12 +133,17 @@ module RuboCop
119
133
  end
120
134
 
121
135
  def for_assignment_node
122
- node.ancestors.find(&:for_type?)
136
+ return unless (parent_node = node.parent)
137
+ return parent_node if parent_node.for_type?
138
+
139
+ grandparent_node = parent_node.parent
140
+ return grandparent_node if parent_node.mlhs_type? && grandparent_node&.for_type?
141
+
142
+ nil
123
143
  end
124
144
 
125
145
  def find_multiple_assignment_node(grandparent_node)
126
146
  return unless grandparent_node.type == MULTIPLE_LEFT_HAND_SIDE_TYPE
127
- return if grandparent_node.children.any?(&:splat_type?)
128
147
 
129
148
  parent = grandparent_node.parent
130
149
  return parent if parent.type == MULTIPLE_ASSIGNMENT_TYPE
@@ -74,7 +74,7 @@ module RuboCop
74
74
  def parent
75
75
  return @parent if instance_variable_defined?(:@parent)
76
76
 
77
- @branch = Branch.of(control_node, scope: scope)
77
+ @parent = Branch.of(control_node, scope: scope)
78
78
  end
79
79
 
80
80
  def each_ancestor(include_self: false, &block)
@@ -46,7 +46,7 @@ module RuboCop
46
46
  else
47
47
  child_index = case node.type
48
48
  when :module, :sclass then 1
49
- when :def, :class, :block, :numblock then 2
49
+ when :def, :class, :block, :numblock, :itblock then 2
50
50
  when :defs then 3
51
51
  end
52
52
 
@@ -29,7 +29,18 @@ module RuboCop
29
29
  end
30
30
 
31
31
  def assign(node)
32
- @assignments << Assignment.new(node, self)
32
+ assignment = Assignment.new(node, self)
33
+
34
+ mark_last_as_reassigned!(assignment)
35
+
36
+ @assignments << assignment
37
+ end
38
+
39
+ def mark_last_as_reassigned!(assignment)
40
+ return if captured_by_block?
41
+ return unless assignment.branch == @assignments.last&.branch
42
+
43
+ @assignments.last&.reassigned!
33
44
  end
34
45
 
35
46
  def referenced?
@@ -68,7 +79,7 @@ module RuboCop
68
79
  parent = parent.parent if parent&.begin_type?
69
80
  return false if parent.nil?
70
81
 
71
- (parent.if_type? || parent.while_type? || parent.until_type?) && parent.modifier_form?
82
+ parent.basic_conditional? && parent.modifier_form?
72
83
  end
73
84
 
74
85
  def capture_with_block!
@@ -96,7 +107,7 @@ module RuboCop
96
107
  end
97
108
 
98
109
  def method_argument?
99
- argument? && %i[def defs].include?(@scope.node.type)
110
+ argument? && @scope.node.any_def_type?
100
111
  end
101
112
 
102
113
  def block_argument?
@@ -61,8 +61,8 @@ module RuboCop
61
61
  "at #{node.source_range}, #{node.inspect}"
62
62
  end
63
63
 
64
- variable.assign(node)
65
64
  mark_variable_as_captured_by_block_if_so(variable)
65
+ variable.assign(node)
66
66
  end
67
67
 
68
68
  def reference_variable(name, node)
@@ -87,8 +87,8 @@ module RuboCop
87
87
  # So just skip.
88
88
  return unless variable
89
89
 
90
- variable.reference!(node)
91
90
  mark_variable_as_captured_by_block_if_so(variable)
91
+ variable.reference!(node)
92
92
  end
93
93
 
94
94
  def find_variable(name)
@@ -100,7 +100,7 @@ module RuboCop
100
100
 
101
101
  # Only block scope allows referencing outer scope variables.
102
102
  node = scope.node
103
- return nil unless node.block_type? || node.numblock_type?
103
+ return nil unless node.any_block_type?
104
104
  end
105
105
 
106
106
  nil
@@ -113,14 +113,14 @@ module RuboCop
113
113
  def accessible_variables
114
114
  scope_stack.reverse_each.with_object([]) do |scope, variables|
115
115
  variables.concat(scope.variables.values)
116
- break variables unless scope.node.block_type? || scope.node.numblock_type?
116
+ break variables unless scope.node.any_block_type?
117
117
  end
118
118
  end
119
119
 
120
120
  private
121
121
 
122
122
  def mark_variable_as_captured_by_block_if_so(variable)
123
- return unless current_scope.node.block_type? || current_scope.node.numblock_type?
123
+ return unless current_scope.node.any_block_type?
124
124
  return if variable.scope == current_scope
125
125
 
126
126
  variable.capture_with_block!
@@ -54,7 +54,7 @@ module RuboCop
54
54
 
55
55
  ZERO_ARITY_SUPER_TYPE = :zsuper
56
56
 
57
- TWISTED_SCOPE_TYPES = %i[block numblock class sclass defs module].freeze
57
+ TWISTED_SCOPE_TYPES = %i[block numblock itblock class sclass defs module].freeze
58
58
  SCOPE_TYPES = (TWISTED_SCOPE_TYPES + [:def]).freeze
59
59
 
60
60
  SEND_TYPE = :send
@@ -71,6 +71,8 @@ module RuboCop
71
71
  end
72
72
  end
73
73
 
74
+ BRANCH_NODES = %i[if case case_match rescue].freeze
75
+
74
76
  def variable_table
75
77
  @variable_table ||= VariableTable.new(self)
76
78
  end
@@ -194,15 +196,10 @@ module RuboCop
194
196
  end
195
197
 
196
198
  def process_variable_operator_assignment(node)
197
- if LOGICAL_OPERATOR_ASSIGNMENT_TYPES.include?(node.type)
198
- asgn_node, rhs_node = *node
199
- else
200
- asgn_node, _operator, rhs_node = *node
201
- end
202
-
199
+ asgn_node = node.lhs
203
200
  return unless asgn_node.lvasgn_type?
204
201
 
205
- name = asgn_node.children.first
202
+ name = asgn_node.name
206
203
 
207
204
  variable_table.declare_variable(name, asgn_node) unless variable_table.variable_exist?(name)
208
205
 
@@ -222,7 +219,7 @@ module RuboCop
222
219
  # before processing rhs nodes.
223
220
 
224
221
  variable_table.reference_variable(name, node)
225
- process_node(rhs_node)
222
+ process_node(node.rhs)
226
223
  variable_table.assign_to_variable(name, asgn_node)
227
224
 
228
225
  skip_children!
@@ -241,11 +238,16 @@ module RuboCop
241
238
  end
242
239
 
243
240
  def process_loop(node)
244
- if POST_CONDITION_LOOP_TYPES.include?(node.type)
241
+ if node.post_condition_loop?
245
242
  # See the comment at the end of file for this behavior.
246
243
  condition_node, body_node = *node
247
244
  process_node(body_node)
248
245
  process_node(condition_node)
246
+ elsif node.for_type?
247
+ # In `for item in items` the rightmost expression is evaluated first.
248
+ process_node(node.collection)
249
+ process_node(node.variable)
250
+ process_node(node.body) if node.body
249
251
  else
250
252
  process_children(node)
251
253
  end
@@ -301,7 +303,7 @@ module RuboCop
301
303
  variable_table.accessible_variables.each { |variable| variable.reference!(node) }
302
304
  end
303
305
 
304
- # Mark all assignments which are referenced in the same loop
306
+ # Mark last assignments which are referenced in the same loop
305
307
  # as referenced by ignoring AST order since they would be referenced
306
308
  # in next iteration.
307
309
  def mark_assignments_as_referenced_in_loop(node)
@@ -313,13 +315,12 @@ module RuboCop
313
315
  # would be skipped here.
314
316
  next unless variable
315
317
 
316
- variable.assignments.each do |assignment|
317
- next if assignment_nodes_in_loop.none? do |assignment_node|
318
- assignment_node.equal?(assignment.node)
319
- end
320
-
321
- assignment.reference!(node)
318
+ loop_assignments = variable.assignments.select do |assignment|
319
+ assignment_nodes_in_loop.include?(assignment.node)
322
320
  end
321
+ next unless loop_assignments.any?
322
+
323
+ reference_assignments(loop_assignments, node)
323
324
  end
324
325
  end
325
326
 
@@ -355,9 +356,19 @@ module RuboCop
355
356
  when :lvasgn
356
357
  AssignmentReference.new(node)
357
358
  when *OPERATOR_ASSIGNMENT_TYPES
358
- asgn_node = node.children.first
359
- VariableReference.new(asgn_node.children.first) if asgn_node.lvasgn_type?
359
+ VariableReference.new(node.lhs.name) if node.lhs.lvasgn_type?
360
+ end
361
+ end
362
+
363
+ def reference_assignments(loop_assignments, loop_node)
364
+ # If inside a branching statement, mark all as referenced.
365
+ # Otherwise, mark only the last assignment as referenced.
366
+ # Note that `rescue` must be considered as branching because of
367
+ # the `retry` keyword.
368
+ loop_assignments.each do |assignment|
369
+ assignment.reference!(loop_node) if assignment.node.each_ancestor(*BRANCH_NODES).any?
360
370
  end
371
+ loop_assignments.last&.reference!(loop_node)
361
372
  end
362
373
 
363
374
  def scanned_node?(node)
@@ -1,11 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'fileutils'
4
+ require 'yard'
4
5
 
5
6
  # Class for generating documentation of all cops departments
6
7
  # @api private
7
8
  class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
8
9
  include ::RuboCop::Cop::Documentation
10
+
9
11
  CopData = Struct.new(
10
12
  :cop, :description, :example_objects, :safety_objects, :see_objects, :config, keyword_init: true
11
13
  )
@@ -17,7 +19,7 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
17
19
  description: ->(data) { "#{data.description}\n" },
18
20
  safety: ->(data) { safety_object(data.safety_objects, data.cop) },
19
21
  examples: ->(data) { examples(data.example_objects, data.cop) },
20
- configuration: ->(data) { configurations(data.cop.department, data.config, data.cop) },
22
+ configuration: ->(data) { configurations(data.cop.department, data.cop, data.config) },
21
23
  references: ->(data) { references(data.cop, data.see_objects) }
22
24
  }.freeze
23
25
 
@@ -27,6 +29,12 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
27
29
  #
28
30
  # CopsDocumentationGenerator.new(departments: ['Lint']).call
29
31
  #
32
+ # For plugin extensions, specify `:plugin_name` keyword as follows:
33
+ #
34
+ # CopsDocumentationGenerator.new(
35
+ # departments: ['Performance'], plugin_name: 'rubocop-performance'
36
+ # ).call
37
+ #
30
38
  # You can append additional information:
31
39
  #
32
40
  # callback = ->(data) { required_rails_version(data.cop) }
@@ -35,13 +43,19 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
35
43
  # This will insert the string returned from the lambda _after_ the section from RuboCop itself.
36
44
  # See `CopsDocumentationGenerator::STRUCTURE` for available sections.
37
45
  #
38
- def initialize(departments: [], extra_info: {})
46
+ def initialize(departments: [], extra_info: {}, base_dir: Dir.pwd, plugin_name: nil)
39
47
  @departments = departments.map(&:to_sym).sort!
40
48
  @extra_info = extra_info
41
49
  @cops = RuboCop::Cop::Registry.global
42
50
  @config = RuboCop::ConfigLoader.default_configuration
43
- @docs_path = "#{Dir.pwd}/docs/modules/ROOT/pages/"
44
- FileUtils.mkdir_p(@docs_path)
51
+ # NOTE: For example, this prevents excessive plugin loading before another task executes,
52
+ # in cases where plugins are already loaded by `internal_investigation`.
53
+ if plugin_name && @config.loaded_plugins.none? { |plugin| plugin.about.name == plugin_name }
54
+ RuboCop::Plugin.integrate_plugins(RuboCop::Config.new, [plugin_name])
55
+ end
56
+ @base_dir = base_dir
57
+ @docs_path = "#{base_dir}/docs/modules/ROOT"
58
+ FileUtils.mkdir_p("#{@docs_path}/pages")
45
59
  end
46
60
 
47
61
  def call
@@ -112,7 +126,15 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
112
126
  def required_ruby_version(cop)
113
127
  return '' unless cop.respond_to?(:required_minimum_ruby_version)
114
128
 
115
- "NOTE: Required Ruby version: #{cop.required_minimum_ruby_version}\n\n"
129
+ if cop.required_minimum_ruby_version
130
+ requirement = cop.required_minimum_ruby_version
131
+ elsif cop.required_maximum_ruby_version
132
+ requirement = "<= #{cop.required_maximum_ruby_version}"
133
+ else
134
+ return ''
135
+ end
136
+
137
+ "NOTE: Requires Ruby version #{requirement}\n\n"
116
138
  end
117
139
 
118
140
  # rubocop:disable Metrics/MethodLength
@@ -157,8 +179,8 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
157
179
  end
158
180
 
159
181
  def example_header(title, cop)
160
- content = "[##{to_anchor(title)}-#{to_anchor(cop.cop_name)}]\n"
161
- content << +"==== #{title}\n"
182
+ content = +"[##{to_anchor(title)}-#{to_anchor(cop.cop_name)}]\n"
183
+ content << "==== #{title}\n"
162
184
  content << "\n"
163
185
  content
164
186
  end
@@ -170,17 +192,17 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
170
192
  content
171
193
  end
172
194
 
173
- def configurations(department, pars, cop)
174
- return '' if pars.empty?
175
-
195
+ def configurations(department, cop, cop_config)
176
196
  header = ['Name', 'Default value', 'Configurable values']
177
- configs = pars
178
- .each_key
179
- .reject { |key| key.start_with?('Supported') }
180
- .reject { |key| key.start_with?('AllowMultipleStyles') }
197
+ configs = cop_config.each_key.reject do |key|
198
+ key == 'AllowMultipleStyles' ||
199
+ (key != 'SupportedTypes' && key.start_with?('Supported'))
200
+ end
201
+ return '' if configs.empty?
202
+
181
203
  content = configs.map do |name|
182
- configurable = configurable_values(pars, name)
183
- default = format_table_value(pars[name])
204
+ configurable = configurable_values(cop_config, name)
205
+ default = format_table_value(cop_config[name])
184
206
 
185
207
  [configuration_name(department, name), default, configurable]
186
208
  end
@@ -196,17 +218,17 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
196
218
  end
197
219
 
198
220
  # rubocop:disable Metrics/CyclomaticComplexity,Metrics/MethodLength
199
- def configurable_values(pars, name)
221
+ def configurable_values(cop_config, name)
200
222
  case name
201
223
  when /^Enforced/
202
224
  supported_style_name = RuboCop::Cop::Util.to_supported_styles(name)
203
- format_table_value(pars[supported_style_name])
225
+ format_table_value(cop_config[supported_style_name])
204
226
  when 'IndentationWidth'
205
227
  'Integer'
206
228
  when 'Database'
207
- format_table_value(pars['SupportedDatabases'])
229
+ format_table_value(cop_config['SupportedDatabases'])
208
230
  else
209
- case pars[name]
231
+ case cop_config[name]
210
232
  when String
211
233
  'String'
212
234
  when Integer
@@ -246,7 +268,7 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
246
268
  else
247
269
  wrap_backtick(val.nil? ? '<none>' : val)
248
270
  end
249
- value.gsub("#{Dir.pwd}/", '').rstrip
271
+ value.gsub("#{@base_dir}/", '').rstrip
250
272
  end
251
273
 
252
274
  def wrap_backtick(value)
@@ -275,7 +297,7 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
275
297
  return '' unless department == :Layout
276
298
 
277
299
  filename = "#{department_to_basename(department)}_footer.adoc"
278
- file = "#{Dir.pwd}/docs/modules/ROOT/partials/#{filename}"
300
+ file = "#{docs_path}/partials/#{filename}"
279
301
  return '' unless File.exist?(file)
280
302
 
281
303
  "\ninclude::../partials/#{filename}[]\n"
@@ -295,7 +317,7 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
295
317
  HEADER
296
318
  selected_cops.each { |cop| content << print_cop_with_doc(cop) }
297
319
  content << footer_for_department(department)
298
- file_name = "#{docs_path}/#{department_to_basename(department)}.adoc"
320
+ file_name = "#{docs_path}/pages/#{department_to_basename(department)}.adoc"
299
321
  File.open(file_name, 'w') do |file|
300
322
  puts "* generated #{file_name}"
301
323
  file.write("#{content.strip}\n")
@@ -306,10 +328,14 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
306
328
  def print_cop_with_doc(cop) # rubocop:todo Metrics/AbcSize, Metrics/MethodLength
307
329
  cop_config = config.for_cop(cop)
308
330
  non_display_keys = %w[
309
- AutoCorrect Description Enabled StyleGuide Reference Safe SafeAutoCorrect VersionAdded
310
- VersionChanged
331
+ Enabled
332
+ Description
333
+ StyleGuide
334
+ Reference References
335
+ Safe SafeAutoCorrect AutoCorrect
336
+ VersionAdded VersionChanged
311
337
  ]
312
- pars = cop_config.reject { |k| non_display_keys.include? k }
338
+ parameters = cop_config.reject { |k| non_display_keys.include? k }
313
339
  description = 'No documentation'
314
340
  example_objects = safety_objects = see_objects = []
315
341
  cop_code(cop) do |code_object|
@@ -319,7 +345,7 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
319
345
  see_objects = code_object.tags('see')
320
346
  end
321
347
  data = CopData.new(cop: cop, description: description, example_objects: example_objects,
322
- safety_objects: safety_objects, see_objects: see_objects, config: pars)
348
+ safety_objects: safety_objects, see_objects: see_objects, config: parameters)
323
349
  cops_body(data)
324
350
  end
325
351
 
@@ -344,7 +370,7 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
344
370
  end
345
371
 
346
372
  def print_table_of_contents
347
- path = "#{docs_path}/cops.adoc"
373
+ path = "#{docs_path}/pages/cops.adoc"
348
374
 
349
375
  File.write(path, table_contents) and return unless File.exist?(path)
350
376