rubocop 1.72.1 → 1.81.7

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 (316) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +22 -18
  3. data/config/default.yml +240 -65
  4. data/config/internal_affairs.yml +20 -0
  5. data/config/obsoletion.yml +8 -3
  6. data/exe/rubocop +1 -8
  7. data/lib/rubocop/cli/command/auto_generate_config.rb +2 -2
  8. data/lib/rubocop/cli.rb +19 -4
  9. data/lib/rubocop/config.rb +35 -6
  10. data/lib/rubocop/config_loader.rb +8 -40
  11. data/lib/rubocop/config_loader_resolver.rb +9 -7
  12. data/lib/rubocop/config_obsoletion/extracted_cop.rb +4 -3
  13. data/lib/rubocop/config_obsoletion/renamed_cop.rb +18 -3
  14. data/lib/rubocop/config_obsoletion.rb +46 -2
  15. data/lib/rubocop/config_store.rb +5 -0
  16. data/lib/rubocop/config_validator.rb +7 -6
  17. data/lib/rubocop/cop/autocorrect_logic.rb +22 -14
  18. data/lib/rubocop/cop/bundler/ordered_gems.rb +1 -1
  19. data/lib/rubocop/cop/correctors/alignment_corrector.rb +7 -4
  20. data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +7 -2
  21. data/lib/rubocop/cop/correctors/parentheses_corrector.rb +5 -2
  22. data/lib/rubocop/cop/gemspec/attribute_assignment.rb +91 -0
  23. data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +37 -15
  24. data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +1 -1
  25. data/lib/rubocop/cop/gemspec/require_mfa.rb +15 -1
  26. data/lib/rubocop/cop/internal_affairs/example_description.rb +9 -5
  27. data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +4 -4
  28. data/lib/rubocop/cop/internal_affairs/node_pattern_groups.rb +6 -2
  29. data/lib/rubocop/cop/internal_affairs/node_type_group.rb +92 -0
  30. data/lib/rubocop/cop/internal_affairs/on_send_without_on_csend.rb +1 -1
  31. data/lib/rubocop/cop/internal_affairs/redundant_described_class_as_subject.rb +6 -5
  32. data/lib/rubocop/cop/internal_affairs/undefined_config.rb +6 -1
  33. data/lib/rubocop/cop/internal_affairs/useless_restrict_on_send.rb +1 -1
  34. data/lib/rubocop/cop/internal_affairs.rb +1 -0
  35. data/lib/rubocop/cop/layout/block_alignment.rb +2 -2
  36. data/lib/rubocop/cop/layout/block_end_newline.rb +1 -0
  37. data/lib/rubocop/cop/layout/class_structure.rb +36 -1
  38. data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +5 -5
  39. data/lib/rubocop/cop/layout/def_end_alignment.rb +1 -1
  40. data/lib/rubocop/cop/layout/dot_position.rb +1 -1
  41. data/lib/rubocop/cop/layout/else_alignment.rb +1 -1
  42. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +1 -1
  43. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +32 -14
  44. data/lib/rubocop/cop/layout/empty_lines_after_module_inclusion.rb +101 -0
  45. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +34 -4
  46. data/lib/rubocop/cop/layout/empty_lines_around_arguments.rb +8 -29
  47. data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +1 -0
  48. data/lib/rubocop/cop/layout/empty_lines_around_class_body.rb +1 -1
  49. data/lib/rubocop/cop/layout/first_argument_indentation.rb +1 -1
  50. data/lib/rubocop/cop/layout/hash_alignment.rb +4 -7
  51. data/lib/rubocop/cop/layout/indentation_width.rb +1 -0
  52. data/lib/rubocop/cop/layout/leading_comment_space.rb +13 -1
  53. data/lib/rubocop/cop/layout/line_length.rb +43 -10
  54. data/lib/rubocop/cop/layout/multiline_block_layout.rb +1 -0
  55. data/lib/rubocop/cop/layout/multiline_method_parameter_line_breaks.rb +1 -0
  56. data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +9 -5
  57. data/lib/rubocop/cop/layout/redundant_line_break.rb +9 -5
  58. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +11 -5
  59. data/lib/rubocop/cop/layout/space_after_semicolon.rb +10 -0
  60. data/lib/rubocop/cop/layout/space_around_keyword.rb +6 -1
  61. data/lib/rubocop/cop/layout/space_around_operators.rb +12 -1
  62. data/lib/rubocop/cop/layout/space_before_block_braces.rb +1 -0
  63. data/lib/rubocop/cop/layout/space_before_brackets.rb +5 -38
  64. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +12 -3
  65. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +1 -0
  66. data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +3 -0
  67. data/lib/rubocop/cop/layout/trailing_whitespace.rb +1 -1
  68. data/lib/rubocop/cop/lint/ambiguous_range.rb +5 -0
  69. data/lib/rubocop/cop/lint/array_literal_in_regexp.rb +2 -3
  70. data/lib/rubocop/cop/lint/boolean_symbol.rb +1 -1
  71. data/lib/rubocop/cop/lint/circular_argument_reference.rb +2 -5
  72. data/lib/rubocop/cop/lint/constant_overwritten_in_rescue.rb +3 -2
  73. data/lib/rubocop/cop/lint/cop_directive_syntax.rb +13 -7
  74. data/lib/rubocop/cop/lint/debugger.rb +2 -4
  75. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +1 -1
  76. data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +5 -2
  77. data/lib/rubocop/cop/lint/duplicate_methods.rb +111 -23
  78. data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +5 -42
  79. data/lib/rubocop/cop/lint/empty_conditional_body.rb +14 -64
  80. data/lib/rubocop/cop/lint/empty_interpolation.rb +14 -1
  81. data/lib/rubocop/cop/lint/erb_new_arguments.rb +0 -6
  82. data/lib/rubocop/cop/lint/float_comparison.rb +32 -10
  83. data/lib/rubocop/cop/lint/identity_comparison.rb +19 -15
  84. data/lib/rubocop/cop/lint/literal_as_condition.rb +124 -10
  85. data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +17 -8
  86. data/lib/rubocop/cop/lint/mixed_case_range.rb +2 -2
  87. data/lib/rubocop/cop/lint/nested_method_definition.rb +1 -1
  88. data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +3 -3
  89. data/lib/rubocop/cop/lint/numeric_operation_with_constant_result.rb +1 -0
  90. data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +1 -1
  91. data/lib/rubocop/cop/lint/raise_exception.rb +29 -10
  92. data/lib/rubocop/cop/lint/redundant_regexp_quantifiers.rb +1 -1
  93. data/lib/rubocop/cop/lint/redundant_require_statement.rb +0 -21
  94. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +101 -2
  95. data/lib/rubocop/cop/lint/redundant_type_conversion.rb +43 -13
  96. data/lib/rubocop/cop/lint/redundant_with_index.rb +3 -0
  97. data/lib/rubocop/cop/lint/redundant_with_object.rb +3 -0
  98. data/lib/rubocop/cop/lint/require_range_parentheses.rb +1 -1
  99. data/lib/rubocop/cop/lint/rescue_exception.rb +1 -4
  100. data/lib/rubocop/cop/lint/rescue_type.rb +1 -1
  101. data/lib/rubocop/cop/lint/return_in_void_context.rb +9 -11
  102. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +4 -4
  103. data/lib/rubocop/cop/lint/self_assignment.rb +31 -5
  104. data/lib/rubocop/cop/lint/shadowed_argument.rb +7 -7
  105. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +13 -1
  106. data/lib/rubocop/cop/lint/shared_mutable_default.rb +12 -1
  107. data/lib/rubocop/cop/lint/suppressed_exception.rb +1 -1
  108. data/lib/rubocop/cop/lint/to_enum_arguments.rb +1 -1
  109. data/lib/rubocop/cop/lint/top_level_return_with_argument.rb +1 -1
  110. data/lib/rubocop/cop/lint/unexpected_block_arity.rb +2 -0
  111. data/lib/rubocop/cop/lint/unreachable_code.rb +1 -0
  112. data/lib/rubocop/cop/lint/unreachable_loop.rb +5 -5
  113. data/lib/rubocop/cop/lint/uri_escape_unescape.rb +2 -0
  114. data/lib/rubocop/cop/lint/useless_access_modifier.rb +30 -4
  115. data/lib/rubocop/cop/lint/useless_assignment.rb +2 -0
  116. data/lib/rubocop/cop/lint/useless_constant_scoping.rb +9 -12
  117. data/lib/rubocop/cop/lint/useless_default_value_argument.rb +90 -0
  118. data/lib/rubocop/cop/lint/useless_numeric_operation.rb +1 -0
  119. data/lib/rubocop/cop/lint/useless_or.rb +98 -0
  120. data/lib/rubocop/cop/lint/useless_rescue.rb +1 -1
  121. data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +3 -3
  122. data/lib/rubocop/cop/lint/utils/nil_receiver_checker.rb +121 -0
  123. data/lib/rubocop/cop/lint/void.rb +16 -2
  124. data/lib/rubocop/cop/message_annotator.rb +7 -3
  125. data/lib/rubocop/cop/metrics/abc_size.rb +1 -1
  126. data/lib/rubocop/cop/metrics/block_length.rb +1 -0
  127. data/lib/rubocop/cop/metrics/method_length.rb +1 -0
  128. data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +1 -1
  129. data/lib/rubocop/cop/mixin/alignment.rb +1 -1
  130. data/lib/rubocop/cop/mixin/allowed_pattern.rb +4 -4
  131. data/lib/rubocop/cop/mixin/check_line_breakable.rb +3 -3
  132. data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +2 -2
  133. data/lib/rubocop/cop/mixin/def_node.rb +1 -1
  134. data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +1 -1
  135. data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +1 -7
  136. data/lib/rubocop/cop/mixin/forbidden_identifiers.rb +20 -0
  137. data/lib/rubocop/cop/mixin/forbidden_pattern.rb +16 -0
  138. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +1 -2
  139. data/lib/rubocop/cop/mixin/gemspec_help.rb +22 -0
  140. data/lib/rubocop/cop/mixin/hash_alignment_styles.rb +15 -14
  141. data/lib/rubocop/cop/mixin/hash_subset.rb +19 -4
  142. data/lib/rubocop/cop/mixin/line_length_help.rb +24 -8
  143. data/lib/rubocop/cop/mixin/method_complexity.rb +1 -0
  144. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +2 -0
  145. data/lib/rubocop/cop/mixin/ordered_gem_node.rb +1 -1
  146. data/lib/rubocop/cop/mixin/range_help.rb +12 -0
  147. data/lib/rubocop/cop/mixin/target_ruby_version.rb +1 -1
  148. data/lib/rubocop/cop/mixin/trailing_comma.rb +18 -2
  149. data/lib/rubocop/cop/naming/block_forwarding.rb +3 -3
  150. data/lib/rubocop/cop/naming/file_name.rb +2 -2
  151. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +1 -1
  152. data/lib/rubocop/cop/naming/method_name.rb +187 -15
  153. data/lib/rubocop/cop/naming/predicate_method.rb +319 -0
  154. data/lib/rubocop/cop/naming/{predicate_name.rb → predicate_prefix.rb} +4 -4
  155. data/lib/rubocop/cop/naming/variable_name.rb +51 -6
  156. data/lib/rubocop/cop/registry.rb +9 -6
  157. data/lib/rubocop/cop/security/eval.rb +2 -1
  158. data/lib/rubocop/cop/security/json_load.rb +33 -11
  159. data/lib/rubocop/cop/security/open.rb +1 -0
  160. data/lib/rubocop/cop/style/access_modifier_declarations.rb +32 -10
  161. data/lib/rubocop/cop/style/accessor_grouping.rb +32 -6
  162. data/lib/rubocop/cop/style/arguments_forwarding.rb +21 -24
  163. data/lib/rubocop/cop/style/array_intersect.rb +113 -38
  164. data/lib/rubocop/cop/style/array_intersect_with_single_element.rb +47 -0
  165. data/lib/rubocop/cop/style/bitwise_predicate.rb +8 -1
  166. data/lib/rubocop/cop/style/block_delimiters.rb +3 -2
  167. data/lib/rubocop/cop/style/case_like_if.rb +1 -1
  168. data/lib/rubocop/cop/style/class_and_module_children.rb +48 -10
  169. data/lib/rubocop/cop/style/class_equality_comparison.rb +1 -1
  170. data/lib/rubocop/cop/style/collection_methods.rb +1 -0
  171. data/lib/rubocop/cop/style/collection_querying.rb +167 -0
  172. data/lib/rubocop/cop/style/combinable_loops.rb +1 -0
  173. data/lib/rubocop/cop/style/command_literal.rb +1 -1
  174. data/lib/rubocop/cop/style/commented_keyword.rb +12 -5
  175. data/lib/rubocop/cop/style/comparable_between.rb +78 -0
  176. data/lib/rubocop/cop/style/conditional_assignment.rb +26 -8
  177. data/lib/rubocop/cop/style/constant_visibility.rb +14 -9
  178. data/lib/rubocop/cop/style/data_inheritance.rb +7 -0
  179. data/lib/rubocop/cop/style/def_with_parentheses.rb +18 -5
  180. data/lib/rubocop/cop/style/dig_chain.rb +1 -1
  181. data/lib/rubocop/cop/style/double_negation.rb +3 -3
  182. data/lib/rubocop/cop/style/empty_literal.rb +4 -0
  183. data/lib/rubocop/cop/style/empty_string_inside_interpolation.rb +100 -0
  184. data/lib/rubocop/cop/style/endless_method.rb +176 -18
  185. data/lib/rubocop/cop/style/eval_with_location.rb +3 -3
  186. data/lib/rubocop/cop/style/expand_path_arguments.rb +2 -7
  187. data/lib/rubocop/cop/style/explicit_block_argument.rb +3 -3
  188. data/lib/rubocop/cop/style/exponential_notation.rb +5 -4
  189. data/lib/rubocop/cop/style/fetch_env_var.rb +32 -6
  190. data/lib/rubocop/cop/style/float_division.rb +15 -1
  191. data/lib/rubocop/cop/style/for.rb +1 -0
  192. data/lib/rubocop/cop/style/format_string_token.rb +38 -11
  193. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +3 -2
  194. data/lib/rubocop/cop/style/global_std_stream.rb +3 -0
  195. data/lib/rubocop/cop/style/guard_clause.rb +2 -1
  196. data/lib/rubocop/cop/style/hash_conversion.rb +16 -8
  197. data/lib/rubocop/cop/style/hash_each_methods.rb +3 -2
  198. data/lib/rubocop/cop/style/hash_fetch_chain.rb +104 -0
  199. data/lib/rubocop/cop/style/hash_syntax.rb +4 -1
  200. data/lib/rubocop/cop/style/hash_transform_keys.rb +2 -2
  201. data/lib/rubocop/cop/style/hash_transform_values.rb +2 -2
  202. data/lib/rubocop/cop/style/identical_conditional_branches.rb +3 -3
  203. data/lib/rubocop/cop/style/if_inside_else.rb +10 -13
  204. data/lib/rubocop/cop/style/if_unless_modifier.rb +35 -8
  205. data/lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb +4 -7
  206. data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +1 -1
  207. data/lib/rubocop/cop/style/infinite_loop.rb +1 -1
  208. data/lib/rubocop/cop/style/inverse_methods.rb +10 -6
  209. data/lib/rubocop/cop/style/invertible_unless_condition.rb +2 -2
  210. data/lib/rubocop/cop/style/ip_addresses.rb +2 -2
  211. data/lib/rubocop/cop/style/it_assignment.rb +69 -12
  212. data/lib/rubocop/cop/style/it_block_parameter.rb +121 -0
  213. data/lib/rubocop/cop/style/keyword_parameters_order.rb +13 -7
  214. data/lib/rubocop/cop/style/lambda.rb +1 -0
  215. data/lib/rubocop/cop/style/lambda_call.rb +7 -2
  216. data/lib/rubocop/cop/style/line_end_concatenation.rb +10 -4
  217. data/lib/rubocop/cop/style/map_into_array.rb +4 -1
  218. data/lib/rubocop/cop/style/map_to_hash.rb +12 -3
  219. data/lib/rubocop/cop/style/map_to_set.rb +1 -3
  220. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +9 -8
  221. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +16 -0
  222. data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +2 -1
  223. data/lib/rubocop/cop/style/min_max_comparison.rb +13 -5
  224. data/lib/rubocop/cop/style/multiline_block_chain.rb +2 -1
  225. data/lib/rubocop/cop/style/multiline_if_modifier.rb +2 -0
  226. data/lib/rubocop/cop/style/multiline_method_signature.rb +1 -9
  227. data/lib/rubocop/cop/style/next.rb +44 -0
  228. data/lib/rubocop/cop/style/nil_comparison.rb +9 -7
  229. data/lib/rubocop/cop/style/object_then.rb +1 -0
  230. data/lib/rubocop/cop/style/one_line_conditional.rb +17 -9
  231. data/lib/rubocop/cop/style/parallel_assignment.rb +32 -20
  232. data/lib/rubocop/cop/style/percent_q_literals.rb +1 -1
  233. data/lib/rubocop/cop/style/proc.rb +1 -0
  234. data/lib/rubocop/cop/style/raise_args.rb +8 -8
  235. data/lib/rubocop/cop/style/redundant_array_flatten.rb +50 -0
  236. data/lib/rubocop/cop/style/redundant_begin.rb +35 -0
  237. data/lib/rubocop/cop/style/redundant_condition.rb +57 -0
  238. data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +14 -4
  239. data/lib/rubocop/cop/style/redundant_exception.rb +1 -1
  240. data/lib/rubocop/cop/style/redundant_fetch_block.rb +1 -9
  241. data/lib/rubocop/cop/style/redundant_format.rb +79 -18
  242. data/lib/rubocop/cop/style/redundant_freeze.rb +2 -2
  243. data/lib/rubocop/cop/style/redundant_interpolation.rb +12 -3
  244. data/lib/rubocop/cop/style/redundant_line_continuation.rb +1 -4
  245. data/lib/rubocop/cop/style/redundant_parentheses.rb +73 -18
  246. data/lib/rubocop/cop/style/redundant_regexp_argument.rb +4 -0
  247. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +8 -0
  248. data/lib/rubocop/cop/style/redundant_self.rb +9 -5
  249. data/lib/rubocop/cop/style/redundant_self_assignment.rb +1 -1
  250. data/lib/rubocop/cop/style/redundant_sort_by.rb +17 -1
  251. data/lib/rubocop/cop/style/regexp_literal.rb +1 -1
  252. data/lib/rubocop/cop/style/rescue_modifier.rb +3 -0
  253. data/lib/rubocop/cop/style/return_nil.rb +2 -2
  254. data/lib/rubocop/cop/style/safe_navigation.rb +61 -14
  255. data/lib/rubocop/cop/style/select_by_regexp.rb +4 -1
  256. data/lib/rubocop/cop/style/semicolon.rb +23 -7
  257. data/lib/rubocop/cop/style/single_line_do_end_block.rb +3 -1
  258. data/lib/rubocop/cop/style/single_line_methods.rb +10 -7
  259. data/lib/rubocop/cop/style/sole_nested_conditional.rb +75 -101
  260. data/lib/rubocop/cop/style/stabby_lambda_parentheses.rb +1 -1
  261. data/lib/rubocop/cop/style/string_concatenation.rb +18 -15
  262. data/lib/rubocop/cop/style/struct_inheritance.rb +8 -1
  263. data/lib/rubocop/cop/style/super_arguments.rb +1 -2
  264. data/lib/rubocop/cop/style/symbol_array.rb +1 -1
  265. data/lib/rubocop/cop/style/symbol_proc.rb +3 -1
  266. data/lib/rubocop/cop/style/top_level_method_definition.rb +1 -0
  267. data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +52 -1
  268. data/lib/rubocop/cop/style/trailing_comma_in_array_literal.rb +47 -6
  269. data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +1 -1
  270. data/lib/rubocop/cop/style/trailing_comma_in_hash_literal.rb +48 -6
  271. data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
  272. data/lib/rubocop/cop/style/unless_else.rb +10 -9
  273. data/lib/rubocop/cop/team.rb +1 -1
  274. data/lib/rubocop/cop/util.rb +1 -1
  275. data/lib/rubocop/cop/utils/format_string.rb +15 -2
  276. data/lib/rubocop/cop/variable_force/assignment.rb +7 -3
  277. data/lib/rubocop/cop/variable_force/scope.rb +1 -1
  278. data/lib/rubocop/cop/variable_force/variable.rb +3 -8
  279. data/lib/rubocop/cop/variable_force.rb +26 -9
  280. data/lib/rubocop/cops_documentation_generator.rb +23 -7
  281. data/lib/rubocop/directive_comment.rb +1 -1
  282. data/lib/rubocop/ext/regexp_node.rb +0 -1
  283. data/lib/rubocop/formatter/disabled_config_formatter.rb +19 -5
  284. data/lib/rubocop/formatter/fuubar_style_formatter.rb +1 -1
  285. data/lib/rubocop/formatter/html_formatter.rb +1 -1
  286. data/lib/rubocop/formatter/markdown_formatter.rb +1 -0
  287. data/lib/rubocop/formatter/offense_count_formatter.rb +1 -1
  288. data/lib/rubocop/formatter/pacman_formatter.rb +2 -1
  289. data/lib/rubocop/lsp/diagnostic.rb +25 -24
  290. data/lib/rubocop/lsp/routes.rb +65 -9
  291. data/lib/rubocop/lsp/runtime.rb +5 -5
  292. data/lib/rubocop/lsp/server.rb +2 -2
  293. data/lib/rubocop/lsp/stdin_runner.rb +3 -17
  294. data/lib/rubocop/magic_comment.rb +8 -0
  295. data/lib/rubocop/pending_cops_reporter.rb +56 -0
  296. data/lib/rubocop/plugin/configuration_integrator.rb +2 -0
  297. data/lib/rubocop/plugin/load_error.rb +1 -1
  298. data/lib/rubocop/plugin.rb +9 -2
  299. data/lib/rubocop/result_cache.rb +14 -12
  300. data/lib/rubocop/rspec/cop_helper.rb +6 -1
  301. data/lib/rubocop/rspec/expect_offense.rb +9 -3
  302. data/lib/rubocop/rspec/shared_contexts.rb +34 -0
  303. data/lib/rubocop/rspec/support.rb +3 -0
  304. data/lib/rubocop/runner.rb +10 -4
  305. data/lib/rubocop/server/cache.rb +17 -12
  306. data/lib/rubocop/server/client_command/base.rb +10 -0
  307. data/lib/rubocop/server/client_command/exec.rb +2 -1
  308. data/lib/rubocop/server/client_command/start.rb +11 -1
  309. data/lib/rubocop/target_finder.rb +13 -9
  310. data/lib/rubocop/target_ruby.rb +11 -2
  311. data/lib/rubocop/version.rb +14 -7
  312. data/lib/rubocop.rb +17 -2
  313. data/lib/ruby_lsp/rubocop/addon.rb +25 -10
  314. data/lib/ruby_lsp/rubocop/runtime_adapter.rb +57 -5
  315. metadata +24 -8
  316. data/lib/rubocop/cop/utils/regexp_ranges.rb +0 -113
@@ -3,13 +3,13 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Lint
6
- # Checks for redundant uses of `to_s`, `to_sym`, `to_i`, `to_f`, `to_r`, `to_c`,
6
+ # Checks for redundant uses of `to_s`, `to_sym`, `to_i`, `to_f`, `to_d`, `to_r`, `to_c`,
7
7
  # `to_a`, `to_h`, and `to_set`.
8
8
  #
9
9
  # When one of these methods is called on an object of the same type, that object
10
10
  # is returned, making the call unnecessary. The cop detects conversion methods called
11
11
  # on object literals, class constructors, class `[]` methods, and the `Kernel` methods
12
- # `String()`, `Integer()`, `Float()`, `Rational()`, `Complex()` and `Array()`.
12
+ # `String()`, `Integer()`, `Float()`, BigDecimal(), `Rational()`, `Complex()`, and `Array()`.
13
13
  #
14
14
  # Specifically, these cases are detected for each conversion method:
15
15
  #
@@ -27,7 +27,8 @@ module RuboCop
27
27
  # In all cases, chaining one same `to_*` conversion methods listed above is redundant.
28
28
  #
29
29
  # The cop can also register an offense for chaining conversion methods on methods that are
30
- # expected to return a specific type regardless of receiver (eg. `foo.inspect.to_s`).
30
+ # expected to return a specific type regardless of receiver (eg. `foo.inspect.to_s` and
31
+ # `foo.to_json.to_s`).
31
32
  #
32
33
  # @example
33
34
  # # bad
@@ -39,7 +40,7 @@ module RuboCop
39
40
  # 1i.to_c
40
41
  # [].to_a
41
42
  # {}.to_h
42
- # Set.new.to_s
43
+ # Set.new.to_set
43
44
  #
44
45
  # # good
45
46
  # "text"
@@ -52,6 +53,16 @@ module RuboCop
52
53
  # {}
53
54
  # Set.new
54
55
  #
56
+ # # bad
57
+ # Integer(var).to_i
58
+ #
59
+ # # good
60
+ # Integer(var)
61
+ #
62
+ # # good - chaining to a type constructor with exceptions suppressed
63
+ # # in this case, `Integer()` could return `nil`
64
+ # Integer(var, exception: false).to_i
65
+ #
55
66
  # # bad - chaining the same conversion
56
67
  # foo.to_s.to_s
57
68
  #
@@ -59,10 +70,12 @@ module RuboCop
59
70
  # foo.to_s
60
71
  #
61
72
  # # bad - chaining a conversion to a method that is expected to return the same type
62
- # inspect.to_s
73
+ # foo.inspect.to_s
74
+ # foo.to_json.to_s
63
75
  #
64
76
  # # good
65
- # inspect
77
+ # foo.inspect
78
+ # foo.to_json
66
79
  #
67
80
  class RedundantTypeConversion < Base
68
81
  extend AutoCorrector
@@ -88,6 +101,7 @@ module RuboCop
88
101
  to_s: 'string_constructor?',
89
102
  to_i: 'integer_constructor?',
90
103
  to_f: 'float_constructor?',
104
+ to_d: 'bigdecimal_constructor?',
91
105
  to_r: 'rational_constructor?',
92
106
  to_c: 'complex_constructor?',
93
107
  to_a: 'array_constructor?',
@@ -97,10 +111,10 @@ module RuboCop
97
111
 
98
112
  # Methods that already are expected to return a given type, which makes a further
99
113
  # conversion redundant.
100
- TYPED_METHODS = { to_s: %i[inspect] }.freeze
114
+ TYPED_METHODS = { to_s: %i[inspect to_json] }.freeze
101
115
 
102
116
  CONVERSION_METHODS = Set[*LITERAL_NODE_TYPES.keys].freeze
103
- RESTRICT_ON_SEND = CONVERSION_METHODS
117
+ RESTRICT_ON_SEND = CONVERSION_METHODS + [:to_d]
104
118
 
105
119
  private_constant :LITERAL_NODE_TYPES, :CONSTRUCTOR_MAPPING
106
120
 
@@ -127,6 +141,11 @@ module RuboCop
127
141
  #type_constructor?(:Float)
128
142
  PATTERN
129
143
 
144
+ # @!method bigdecimal_constructor?(node)
145
+ def_node_matcher :bigdecimal_constructor?, <<~PATTERN
146
+ #type_constructor?(:BigDecimal)
147
+ PATTERN
148
+
130
149
  # @!method rational_constructor?(node)
131
150
  def_node_matcher :rational_constructor?, <<~PATTERN
132
151
  #type_constructor?(:Rational)
@@ -161,9 +180,14 @@ module RuboCop
161
180
  }
162
181
  PATTERN
163
182
 
164
- # rubocop:disable Metrics/AbcSize
183
+ # @!method exception_false_keyword_argument?(node)
184
+ def_node_matcher :exception_false_keyword_argument?, <<~PATTERN
185
+ (hash (pair (sym :exception) false))
186
+ PATTERN
187
+
188
+ # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity
165
189
  def on_send(node)
166
- return if hash_or_set_with_block?(node)
190
+ return if node.arguments.any? || hash_or_set_with_block?(node)
167
191
 
168
192
  receiver = find_receiver(node)
169
193
  return unless literal_receiver?(node, receiver) ||
@@ -174,10 +198,10 @@ module RuboCop
174
198
  message = format(MSG, method: node.method_name)
175
199
 
176
200
  add_offense(node.loc.selector, message: message) do |corrector|
177
- corrector.remove(node.loc.dot.join(node.loc.selector))
201
+ corrector.remove(node.loc.dot.join(node.loc.end || node.loc.selector))
178
202
  end
179
203
  end
180
- # rubocop:enable Metrics/AbcSize
204
+ # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity
181
205
  alias on_csend on_send
182
206
 
183
207
  private
@@ -211,7 +235,13 @@ module RuboCop
211
235
  matcher = CONSTRUCTOR_MAPPING[node.method_name]
212
236
  return false unless matcher
213
237
 
214
- public_send(matcher, receiver)
238
+ public_send(matcher, receiver) && !constructor_suppresses_exceptions?(receiver)
239
+ end
240
+
241
+ def constructor_suppresses_exceptions?(receiver)
242
+ # If the constructor suppresses exceptions with `exception: false`, it is possible
243
+ # it could return `nil`, and therefore a chained conversion is not redundant.
244
+ receiver.arguments.any? { |arg| exception_false_keyword_argument?(arg) }
215
245
  end
216
246
 
217
247
  def chained_conversion?(node, receiver)
@@ -53,6 +53,7 @@ module RuboCop
53
53
  # rubocop:enable Metrics/AbcSize
54
54
 
55
55
  alias on_numblock on_block
56
+ alias on_itblock on_block
56
57
 
57
58
  private
58
59
 
@@ -64,6 +65,8 @@ module RuboCop
64
65
  (args (arg _)) ...)
65
66
  (numblock
66
67
  $(call _ {:each_with_index :with_index} ...) 1 ...)
68
+ (itblock
69
+ $(call _ {:each_with_index :with_index} ...) _ ...)
67
70
  }
68
71
  PATTERN
69
72
 
@@ -49,6 +49,7 @@ module RuboCop
49
49
  end
50
50
 
51
51
  alias on_numblock on_block
52
+ alias on_itblock on_block
52
53
 
53
54
  private
54
55
 
@@ -59,6 +60,8 @@ module RuboCop
59
60
  $(call _ {:each_with_object :with_object} _) (args (arg _)) ...)
60
61
  (numblock
61
62
  $(call _ {:each_with_object :with_object} _) 1 ...)
63
+ (itblock
64
+ $(call _ {:each_with_object :with_object} _) _ ...)
62
65
  }
63
66
  PATTERN
64
67
 
@@ -43,7 +43,7 @@ module RuboCop
43
43
  def on_irange(node)
44
44
  return if node.parent&.begin_type?
45
45
  return unless node.begin && node.end
46
- return if same_line?(node.begin, node.end)
46
+ return if same_line?(node.loc.operator, node.end)
47
47
 
48
48
  message = format(MSG, range: "#{node.begin.source}#{node.loc.operator.source}")
49
49
 
@@ -24,10 +24,7 @@ module RuboCop
24
24
  MSG = 'Avoid rescuing the `Exception` class. Perhaps you meant to rescue `StandardError`?'
25
25
 
26
26
  def on_resbody(node)
27
- return unless node.children.first
28
-
29
- rescue_args = node.children.first.children
30
- return unless rescue_args.any? { |a| targets_exception?(a) }
27
+ return unless node.exceptions.any? { |exception| targets_exception?(exception) }
31
28
 
32
29
  add_offense(node)
33
30
  end
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Lint
6
- # Check for arguments to `rescue` that will result in a `TypeError`
6
+ # Checks for arguments to `rescue` that will result in a `TypeError`
7
7
  # if an exception is raised.
8
8
  #
9
9
  # @example
@@ -32,25 +32,23 @@ module RuboCop
32
32
  class ReturnInVoidContext < Base
33
33
  MSG = 'Do not return a value in `%<method>s`.'
34
34
 
35
+ # Returning out of these methods only exits the block itself.
36
+ SCOPE_CHANGING_METHODS = %i[lambda define_method define_singleton_method].freeze
37
+
35
38
  def on_return(return_node)
36
39
  return unless return_node.descendants.any?
37
40
 
38
- context_node = non_void_context(return_node)
39
-
40
- return unless context_node&.def_type?
41
- return unless context_node&.void_context?
41
+ def_node = return_node.each_ancestor(:any_def).first
42
+ return unless def_node&.void_context?
43
+ return if return_node.each_ancestor(:any_block).any? do |block_node|
44
+ SCOPE_CHANGING_METHODS.include?(block_node.method_name)
45
+ end
42
46
 
43
47
  add_offense(
44
48
  return_node.loc.keyword,
45
- message: format(message, method: context_node.method_name)
49
+ message: format(message, method: def_node.method_name)
46
50
  )
47
51
  end
48
-
49
- private
50
-
51
- def non_void_context(return_node)
52
- return_node.each_ancestor(:block, :def, :defs).first
53
- end
54
52
  end
55
53
  end
56
54
  end
@@ -97,7 +97,7 @@ module RuboCop
97
97
  end
98
98
 
99
99
  def require_parentheses?(send_node)
100
- return true if operator_inside_hash?(send_node)
100
+ return true if operator_inside_collection_literal?(send_node)
101
101
  return false unless send_node.comparison_method?
102
102
  return false unless (node = send_node.parent)
103
103
 
@@ -105,10 +105,10 @@ module RuboCop
105
105
  (node.respond_to?(:comparison_method?) && node.comparison_method?)
106
106
  end
107
107
 
108
- def operator_inside_hash?(send_node)
109
- # If an operator call (without a dot) is inside a hash, it needs
108
+ def operator_inside_collection_literal?(send_node)
109
+ # If an operator call (without a dot) is inside an array or a hash, it needs
110
110
  # to be parenthesized when converted to safe navigation.
111
- send_node.parent&.pair_type? && !send_node.loc.dot
111
+ send_node.parent&.type?(:array, :pair) && !send_node.loc.dot
112
112
  end
113
113
  end
114
114
  end
@@ -23,6 +23,14 @@ module RuboCop
23
23
  # # good (method calls possibly can return different results)
24
24
  # hash[foo] = hash[foo]
25
25
  #
26
+ # @example AllowRBSInlineAnnotation:true
27
+ # # good
28
+ # foo = foo #: Integer
29
+ # foo, bar = foo, bar #: Integer
30
+ # Foo = Foo #: Integer
31
+ # hash['foo'] = hash['foo'] #: Integer
32
+ # obj.attr = obj.attr #: Integer
33
+ #
26
34
  class SelfAssignment < Base
27
35
  MSG = 'Self-assignment detected.'
28
36
 
@@ -34,8 +42,10 @@ module RuboCop
34
42
  }.freeze
35
43
 
36
44
  def on_send(node)
45
+ return if allow_rbs_inline_annotation? && rbs_inline_annotation?(node.receiver)
46
+
37
47
  if node.method?(:[]=)
38
- handle_key_assignment(node) if node.arguments.size == 2
48
+ handle_key_assignment(node)
39
49
  elsif node.assignment_method?
40
50
  handle_attribute_assignment(node) if node.arguments.size == 1
41
51
  end
@@ -44,6 +54,7 @@ module RuboCop
44
54
 
45
55
  def on_lvasgn(node)
46
56
  return unless node.rhs
57
+ return if allow_rbs_inline_annotation? && rbs_inline_annotation?(node.rhs)
47
58
 
48
59
  rhs_type = ASSIGNMENT_TYPE_TO_RHS_TYPE[node.type]
49
60
 
@@ -55,16 +66,22 @@ module RuboCop
55
66
 
56
67
  def on_casgn(node)
57
68
  return unless node.rhs&.const_type?
69
+ return if allow_rbs_inline_annotation? && rbs_inline_annotation?(node.rhs)
58
70
 
59
71
  add_offense(node) if node.namespace == node.rhs.namespace &&
60
72
  node.short_name == node.rhs.short_name
61
73
  end
62
74
 
63
75
  def on_masgn(node)
76
+ first_lhs = node.lhs.assignments.first
77
+ return if allow_rbs_inline_annotation? && rbs_inline_annotation?(first_lhs)
78
+
64
79
  add_offense(node) if multiple_self_assignment?(node)
65
80
  end
66
81
 
67
82
  def on_or_asgn(node)
83
+ return if allow_rbs_inline_annotation? && rbs_inline_annotation?(node.lhs)
84
+
68
85
  add_offense(node) if rhs_matches_lhs?(node.rhs, node.lhs)
69
86
  end
70
87
  alias on_and_asgn on_or_asgn
@@ -88,12 +105,13 @@ module RuboCop
88
105
  end
89
106
 
90
107
  def handle_key_assignment(node)
91
- value_node = node.arguments[1]
108
+ value_node = node.last_argument
109
+ node_arguments = node.arguments[0...-1]
92
110
 
93
- if value_node.send_type? && value_node.method?(:[]) &&
111
+ if value_node.respond_to?(:method?) && value_node.method?(:[]) &&
94
112
  node.receiver == value_node.receiver &&
95
- !node.first_argument.call_type? &&
96
- node.first_argument == value_node.first_argument
113
+ node_arguments.none?(&:call_type?) &&
114
+ node_arguments == value_node.arguments
97
115
  add_offense(node)
98
116
  end
99
117
  end
@@ -108,6 +126,14 @@ module RuboCop
108
126
  add_offense(node)
109
127
  end
110
128
  end
129
+
130
+ def rbs_inline_annotation?(node)
131
+ processed_source.ast_with_comments[node].any? { |comment| comment.text.start_with?('#:') }
132
+ end
133
+
134
+ def allow_rbs_inline_annotation?
135
+ cop_config['AllowRBSInlineAnnotation']
136
+ end
111
137
  end
112
138
  end
113
139
  end
@@ -125,13 +125,13 @@ module RuboCop
125
125
  next false if assignment_node.shorthand_asgn?
126
126
  next false unless assignment_node.parent
127
127
 
128
- node_within_block_or_conditional =
129
- node_within_block_or_conditional?(assignment_node.parent, argument.scope.node)
128
+ conditional_assignment =
129
+ conditional_assignment?(assignment_node.parent, argument.scope.node)
130
130
 
131
131
  unless uses_var?(assignment_node, argument.name)
132
132
  # It's impossible to decide whether a branch or block is executed,
133
133
  # so the precise reassignment location is undecidable.
134
- next false if node_within_block_or_conditional
134
+ next false if conditional_assignment
135
135
 
136
136
  yield(assignment.node, location_known)
137
137
  break
@@ -147,13 +147,13 @@ module RuboCop
147
147
  node.source_range.begin_pos
148
148
  end
149
149
 
150
- # Check whether the given node is nested into block or conditional.
150
+ # Check whether the given node is always executed or not
151
151
  #
152
- def node_within_block_or_conditional?(node, stop_search_node)
152
+ def conditional_assignment?(node, stop_search_node)
153
153
  return false if node == stop_search_node
154
154
 
155
- node.conditional? || node.block_type? ||
156
- node_within_block_or_conditional?(node.parent, stop_search_node)
155
+ node.conditional? || node.type?(:block, :rescue) ||
156
+ conditional_assignment?(node.parent, stop_search_node)
157
157
  end
158
158
 
159
159
  # Get argument references without assignments' references
@@ -8,6 +8,11 @@ module RuboCop
8
8
  # given by `ruby -cw` prior to Ruby 2.6:
9
9
  # "shadowing outer local variable - foo".
10
10
  #
11
+ # The cop is now disabled by default to match the upstream Ruby behavior.
12
+ # It's useful, however, if you'd like to avoid shadowing variables from outer
13
+ # scopes, which some people consider an anti-pattern that makes it harder
14
+ # to keep track of what's going on in a program.
15
+ #
11
16
  # NOTE: Shadowing of variables in block passed to `Ractor.new` is allowed
12
17
  # because `Ractor` should not access outer variables.
13
18
  # eg. following style is encouraged:
@@ -56,19 +61,26 @@ module RuboCop
56
61
 
57
62
  outer_local_variable = variable_table.find_variable(variable.name)
58
63
  return unless outer_local_variable
64
+ return if variable_used_in_declaration_of_outer?(variable, outer_local_variable)
59
65
  return if same_conditions_node_different_branch?(variable, outer_local_variable)
60
66
 
61
67
  message = format(MSG, variable: variable.name)
62
68
  add_offense(variable.declaration_node, message: message)
63
69
  end
64
70
 
71
+ private
72
+
73
+ def variable_used_in_declaration_of_outer?(variable, outer_local_variable)
74
+ variable.scope.node.each_ancestor.any?(outer_local_variable.declaration_node)
75
+ end
76
+
65
77
  def same_conditions_node_different_branch?(variable, outer_local_variable)
66
78
  variable_node = variable_node(variable)
67
79
  return false unless node_or_its_ascendant_conditional?(variable_node)
68
80
 
69
81
  outer_local_variable_node =
70
82
  find_conditional_node_from_ascendant(outer_local_variable.declaration_node)
71
- return true unless outer_local_variable_node
83
+ return false unless outer_local_variable_node
72
84
  return false unless outer_local_variable_node.conditional?
73
85
  return true if variable_node == outer_local_variable_node
74
86
 
@@ -51,7 +51,18 @@ module RuboCop
51
51
 
52
52
  # @!method hash_initialized_with_mutable_shared_object?(node)
53
53
  def_node_matcher :hash_initialized_with_mutable_shared_object?, <<~PATTERN
54
- (send (const {nil? cbase} :Hash) :new {array hash (send (const {nil? cbase} {:Array :Hash}) :new)})
54
+ {
55
+ (send (const {nil? cbase} :Hash) :new [
56
+ {array hash (send (const {nil? cbase} {:Array :Hash}) :new)}
57
+ !#capacity_keyword_argument?
58
+ ])
59
+ (send (const {nil? cbase} :Hash) :new hash #capacity_keyword_argument?)
60
+ }
61
+ PATTERN
62
+
63
+ # @!method capacity_keyword_argument?(node)
64
+ def_node_matcher :capacity_keyword_argument?, <<~PATTERN
65
+ (hash (pair (sym :capacity) _))
55
66
  PATTERN
56
67
 
57
68
  def on_send(node)
@@ -116,7 +116,7 @@ module RuboCop
116
116
  private
117
117
 
118
118
  def comment_between_rescue_and_end?(node)
119
- ancestor = node.each_ancestor(:kwbegin, :def, :defs, :any_block).first
119
+ ancestor = node.each_ancestor(:kwbegin, :any_def, :any_block).first
120
120
  return false unless ancestor
121
121
 
122
122
  end_line = ancestor.loc.end&.line || ancestor.loc.last_line
@@ -45,7 +45,7 @@ module RuboCop
45
45
  PATTERN
46
46
 
47
47
  def on_send(node)
48
- def_node = node.each_ancestor(:def, :defs).first
48
+ def_node = node.each_ancestor(:any_def).first
49
49
  return unless def_node
50
50
 
51
51
  enum_conversion_call?(node) do |method_node, arguments|
@@ -40,7 +40,7 @@ module RuboCop
40
40
  # top-level return node's ancestors should not be of block, def, or
41
41
  # defs type.
42
42
  def top_level_return?(return_node)
43
- return_node.each_ancestor(:block, :def, :defs).none?
43
+ return_node.each_ancestor(:block, :any_def).none?
44
44
  end
45
45
  end
46
46
  end
@@ -53,6 +53,7 @@ module RuboCop
53
53
  end
54
54
 
55
55
  alias on_numblock on_block
56
+ alias on_itblock on_block
56
57
 
57
58
  private
58
59
 
@@ -74,6 +75,7 @@ module RuboCop
74
75
 
75
76
  def arg_count(node)
76
77
  return node.children[1] if node.numblock_type? # the maximum numbered param for the block
78
+ return 1 if node.itblock_type? # `it` block parameter is always one
77
79
 
78
80
  # Only `arg`, `optarg` and `mlhs` (destructuring) count as arguments that
79
81
  # can be used. Keyword arguments are not used for these methods so are
@@ -43,6 +43,7 @@ module RuboCop
43
43
  end
44
44
 
45
45
  alias on_numblock on_block
46
+ alias on_itblock on_block
46
47
 
47
48
  def after_block(node)
48
49
  @instance_eval_count -= 1 if instance_eval_block?(node)
@@ -101,9 +101,8 @@ module RuboCop
101
101
  check(node) if loop_method?(node)
102
102
  end
103
103
 
104
- def on_numblock(node)
105
- check(node) if loop_method?(node)
106
- end
104
+ alias on_numblock on_block
105
+ alias on_itblock on_block
107
106
 
108
107
  private
109
108
 
@@ -189,8 +188,9 @@ module RuboCop
189
188
 
190
189
  def preceded_by_continue_statement?(break_statement)
191
190
  break_statement.left_siblings.any? do |sibling|
192
- # Numblocks have the arguments count as a number in the AST.
193
- next if sibling.is_a?(Integer)
191
+ # Numblocks have the arguments count as a number or,
192
+ # itblocks have `:it` symbol in the AST.
193
+ next if sibling.is_a?(Integer) || sibling.is_a?(Symbol)
194
194
  next if sibling.loop_keyword? || loop_method?(sibling)
195
195
 
196
196
  sibling.each_descendant(*CONTINUE_KEYWORDS).any?
@@ -17,6 +17,7 @@ module RuboCop
17
17
  #
18
18
  # # good
19
19
  # CGI.escape('http://example.com')
20
+ # URI.encode_uri_component(uri) # Since Ruby 3.1
20
21
  # URI.encode_www_form([['example', 'param'], ['lang', 'en']])
21
22
  # URI.encode_www_form(page: 10, locale: 'en')
22
23
  # URI.encode_www_form_component('http://example.com')
@@ -27,6 +28,7 @@ module RuboCop
27
28
  #
28
29
  # # good
29
30
  # CGI.unescape(enc_uri)
31
+ # URI.decode_uri_component(uri) # Since Ruby 3.1
30
32
  # URI.decode_www_form(enc_uri)
31
33
  # URI.decode_www_form_component(enc_uri)
32
34
  class UriEscapeUnescape < Base
@@ -4,10 +4,10 @@ module RuboCop
4
4
  module Cop
5
5
  module Lint
6
6
  # Checks for redundant access modifiers, including those with no
7
- # code, those which are repeated, and leading `public` modifiers in a
8
- # class or module body. Conditionally-defined methods are considered as
9
- # always being defined, and thus access modifiers guarding such methods
10
- # are not redundant.
7
+ # code, those which are repeated, those which are on top-level, and
8
+ # leading `public` modifiers in a class or module body.
9
+ # Conditionally-defined methods are considered as always being defined,
10
+ # and thus access modifiers guarding such methods are not redundant.
11
11
  #
12
12
  # This cop has `ContextCreatingMethods` option. The default setting value
13
13
  # is an empty array that means no method is specified.
@@ -58,6 +58,12 @@ module RuboCop
58
58
  # private # this is redundant (no following methods are defined)
59
59
  # end
60
60
  #
61
+ # # bad
62
+ # private # this is useless (access modifiers have no effect on top-level)
63
+ #
64
+ # def method
65
+ # end
66
+ #
61
67
  # # good
62
68
  # class Foo
63
69
  # private # this is not redundant (a method is defined)
@@ -143,6 +149,18 @@ module RuboCop
143
149
  end
144
150
 
145
151
  alias on_numblock on_block
152
+ alias on_itblock on_block
153
+
154
+ def on_begin(node)
155
+ return if node.parent
156
+
157
+ node.child_nodes.each do |child|
158
+ next unless child.send_type? && access_modifier?(child)
159
+
160
+ # This call always registers an offense for access modifier `child.method_name`
161
+ check_send_node(child, child.method_name, true)
162
+ end
163
+ end
146
164
 
147
165
  private
148
166
 
@@ -256,6 +274,10 @@ module RuboCop
256
274
 
257
275
  def any_method_definition?(child)
258
276
  cop_config.fetch('MethodCreatingMethods', []).any? do |m|
277
+ # Some users still have `"included"` in their `MethodCreatingMethods` configurations,
278
+ # so to prevent Ruby method redefinition warnings let's just skip this value.
279
+ next if m == 'included'
280
+
259
281
  matcher_name = :"#{m}_method?"
260
282
  unless respond_to?(matcher_name)
261
283
  self.class.def_node_matcher matcher_name, <<~PATTERN
@@ -278,7 +300,11 @@ module RuboCop
278
300
  end
279
301
 
280
302
  def any_context_creating_methods?(child)
303
+ # Some users still have `"included"` in their `ContextCreatingMethods` configurations,
304
+ # so to prevent Ruby method redefinition warnings let's just skip this value.
281
305
  cop_config.fetch('ContextCreatingMethods', []).any? do |m|
306
+ next if m == 'included'
307
+
282
308
  matcher_name = :"#{m}_block?"
283
309
  unless respond_to?(matcher_name)
284
310
  self.class.def_node_matcher matcher_name, <<~PATTERN
@@ -104,6 +104,8 @@ module RuboCop
104
104
  end
105
105
 
106
106
  def chained_assignment?(node)
107
+ return true if node.lvasgn_type? && node.expression&.send_type?
108
+
107
109
  node.respond_to?(:expression) && node.expression&.lvasgn_type?
108
110
  end
109
111