rubocop 1.67.0 → 1.75.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 (471) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +4 -4
  4. data/config/default.yml +266 -47
  5. data/config/internal_affairs.yml +20 -0
  6. data/config/obsoletion.yml +3 -1
  7. data/lib/rubocop/cached_data.rb +12 -4
  8. data/lib/rubocop/cli/command/execute_runner.rb +4 -4
  9. data/lib/rubocop/cli/command/show_cops.rb +24 -2
  10. data/lib/rubocop/cli/command/suggest_extensions.rb +7 -1
  11. data/lib/rubocop/cli/command/version.rb +2 -2
  12. data/lib/rubocop/cli.rb +1 -1
  13. data/lib/rubocop/comment_config.rb +2 -2
  14. data/lib/rubocop/config.rb +52 -10
  15. data/lib/rubocop/config_loader.rb +52 -9
  16. data/lib/rubocop/config_loader_resolver.rb +36 -10
  17. data/lib/rubocop/config_obsoletion/extracted_cop.rb +4 -3
  18. data/lib/rubocop/config_obsoletion/renamed_cop.rb +18 -3
  19. data/lib/rubocop/config_obsoletion.rb +46 -2
  20. data/lib/rubocop/config_validator.rb +25 -14
  21. data/lib/rubocop/cop/autocorrect_logic.rb +36 -19
  22. data/lib/rubocop/cop/base.rb +7 -1
  23. data/lib/rubocop/cop/bundler/duplicated_gem.rb +2 -2
  24. data/lib/rubocop/cop/bundler/gem_comment.rb +1 -1
  25. data/lib/rubocop/cop/bundler/gem_filename.rb +0 -1
  26. data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +0 -1
  27. data/lib/rubocop/cop/correctors/alignment_corrector.rb +1 -12
  28. data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +1 -1
  29. data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +10 -0
  30. data/lib/rubocop/cop/gemspec/deprecated_attribute_assignment.rb +1 -2
  31. data/lib/rubocop/cop/gemspec/required_ruby_version.rb +0 -2
  32. data/lib/rubocop/cop/generator.rb +6 -0
  33. data/lib/rubocop/cop/internal_affairs/cop_enabled.rb +85 -0
  34. data/lib/rubocop/cop/internal_affairs/example_description.rb +8 -4
  35. data/lib/rubocop/cop/internal_affairs/location_exists.rb +116 -0
  36. data/lib/rubocop/cop/internal_affairs/location_expression.rb +2 -1
  37. data/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +3 -4
  38. data/lib/rubocop/cop/internal_affairs/node_first_or_last_argument.rb +3 -2
  39. data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +1 -1
  40. data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_processor.rb +63 -0
  41. data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_walker.rb +131 -0
  42. data/lib/rubocop/cop/internal_affairs/node_pattern_groups.rb +230 -0
  43. data/lib/rubocop/cop/internal_affairs/node_type_group.rb +91 -0
  44. data/lib/rubocop/cop/internal_affairs/node_type_multiple_predicates.rb +126 -0
  45. data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +4 -3
  46. data/lib/rubocop/cop/internal_affairs/numblock_handler.rb +1 -1
  47. data/lib/rubocop/cop/internal_affairs/on_send_without_on_csend.rb +90 -0
  48. data/lib/rubocop/cop/internal_affairs/operator_keyword.rb +48 -0
  49. data/lib/rubocop/cop/internal_affairs/plugin.rb +33 -0
  50. data/lib/rubocop/cop/internal_affairs/redundant_described_class_as_subject.rb +6 -5
  51. data/lib/rubocop/cop/internal_affairs/redundant_source_range.rb +3 -1
  52. data/lib/rubocop/cop/internal_affairs/single_line_comparison.rb +5 -4
  53. data/lib/rubocop/cop/internal_affairs/style_detected_api_use.rb +0 -2
  54. data/lib/rubocop/cop/internal_affairs/undefined_config.rb +13 -2
  55. data/lib/rubocop/cop/internal_affairs.rb +7 -16
  56. data/lib/rubocop/cop/layout/access_modifier_indentation.rb +1 -1
  57. data/lib/rubocop/cop/layout/argument_alignment.rb +2 -9
  58. data/lib/rubocop/cop/layout/array_alignment.rb +1 -1
  59. data/lib/rubocop/cop/layout/begin_end_alignment.rb +0 -1
  60. data/lib/rubocop/cop/layout/block_alignment.rb +3 -2
  61. data/lib/rubocop/cop/layout/block_end_newline.rb +1 -0
  62. data/lib/rubocop/cop/layout/class_structure.rb +9 -9
  63. data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +4 -4
  64. data/lib/rubocop/cop/layout/def_end_alignment.rb +1 -1
  65. data/lib/rubocop/cop/layout/dot_position.rb +1 -1
  66. data/lib/rubocop/cop/layout/else_alignment.rb +2 -2
  67. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +3 -3
  68. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +7 -11
  69. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +30 -4
  70. data/lib/rubocop/cop/layout/empty_lines_around_begin_body.rb +5 -6
  71. data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +1 -0
  72. data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +4 -5
  73. data/lib/rubocop/cop/layout/empty_lines_around_method_body.rb +23 -1
  74. data/lib/rubocop/cop/layout/end_alignment.rb +1 -1
  75. data/lib/rubocop/cop/layout/extra_spacing.rb +1 -1
  76. data/lib/rubocop/cop/layout/first_argument_indentation.rb +3 -8
  77. data/lib/rubocop/cop/layout/first_array_element_indentation.rb +2 -7
  78. data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +2 -7
  79. data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +1 -1
  80. data/lib/rubocop/cop/layout/first_parameter_indentation.rb +2 -2
  81. data/lib/rubocop/cop/layout/hash_alignment.rb +8 -6
  82. data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +2 -1
  83. data/lib/rubocop/cop/layout/indentation_width.rb +8 -7
  84. data/lib/rubocop/cop/layout/leading_comment_space.rb +57 -2
  85. data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +11 -2
  86. data/lib/rubocop/cop/layout/line_continuation_spacing.rb +7 -1
  87. data/lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb +2 -2
  88. data/lib/rubocop/cop/layout/line_length.rb +123 -4
  89. data/lib/rubocop/cop/layout/multiline_block_layout.rb +1 -0
  90. data/lib/rubocop/cop/layout/multiline_hash_key_line_breaks.rb +1 -1
  91. data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +25 -0
  92. data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +2 -1
  93. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +4 -4
  94. data/lib/rubocop/cop/layout/multiline_method_definition_brace_layout.rb +1 -1
  95. data/lib/rubocop/cop/layout/multiline_method_parameter_line_breaks.rb +1 -0
  96. data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +3 -4
  97. data/lib/rubocop/cop/layout/parameter_alignment.rb +3 -4
  98. data/lib/rubocop/cop/layout/redundant_line_break.rb +19 -46
  99. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +6 -7
  100. data/lib/rubocop/cop/layout/single_line_block_chain.rb +1 -1
  101. data/lib/rubocop/cop/layout/space_after_colon.rb +2 -2
  102. data/lib/rubocop/cop/layout/space_after_comma.rb +1 -1
  103. data/lib/rubocop/cop/layout/space_after_method_name.rb +1 -1
  104. data/lib/rubocop/cop/layout/space_after_semicolon.rb +11 -1
  105. data/lib/rubocop/cop/layout/space_around_keyword.rb +2 -1
  106. data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +1 -1
  107. data/lib/rubocop/cop/layout/space_around_operators.rb +23 -21
  108. data/lib/rubocop/cop/layout/space_before_block_braces.rb +1 -0
  109. data/lib/rubocop/cop/layout/space_before_brackets.rb +5 -5
  110. data/lib/rubocop/cop/layout/space_before_comma.rb +1 -1
  111. data/lib/rubocop/cop/layout/space_before_semicolon.rb +1 -1
  112. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +11 -1
  113. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +5 -0
  114. data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +7 -0
  115. data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +0 -1
  116. data/lib/rubocop/cop/layout/trailing_whitespace.rb +5 -3
  117. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +1 -1
  118. data/lib/rubocop/cop/lint/array_literal_in_regexp.rb +118 -0
  119. data/lib/rubocop/cop/lint/assignment_in_condition.rb +1 -3
  120. data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +10 -12
  121. data/lib/rubocop/cop/lint/boolean_symbol.rb +1 -1
  122. data/lib/rubocop/cop/lint/circular_argument_reference.rb +4 -1
  123. data/lib/rubocop/cop/lint/constant_definition_in_block.rb +3 -3
  124. data/lib/rubocop/cop/lint/constant_reassignment.rb +148 -0
  125. data/lib/rubocop/cop/lint/cop_directive_syntax.rb +84 -0
  126. data/lib/rubocop/cop/lint/debugger.rb +3 -3
  127. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +1 -1
  128. data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +3 -2
  129. data/lib/rubocop/cop/lint/duplicate_branch.rb +39 -4
  130. data/lib/rubocop/cop/lint/duplicate_match_pattern.rb +1 -1
  131. data/lib/rubocop/cop/lint/duplicate_methods.rb +46 -19
  132. data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +1 -1
  133. data/lib/rubocop/cop/lint/duplicate_set_element.rb +20 -7
  134. data/lib/rubocop/cop/lint/empty_conditional_body.rb +14 -64
  135. data/lib/rubocop/cop/lint/empty_ensure.rb +1 -1
  136. data/lib/rubocop/cop/lint/empty_expression.rb +0 -2
  137. data/lib/rubocop/cop/lint/empty_file.rb +0 -2
  138. data/lib/rubocop/cop/lint/ensure_return.rb +1 -1
  139. data/lib/rubocop/cop/lint/erb_new_arguments.rb +0 -6
  140. data/lib/rubocop/cop/lint/float_comparison.rb +20 -14
  141. data/lib/rubocop/cop/lint/float_out_of_range.rb +2 -4
  142. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +2 -2
  143. data/lib/rubocop/cop/lint/hash_new_with_keyword_arguments_as_default.rb +55 -0
  144. data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +1 -1
  145. data/lib/rubocop/cop/lint/interpolation_check.rb +9 -0
  146. data/lib/rubocop/cop/lint/it_without_arguments_in_block.rb +3 -0
  147. data/lib/rubocop/cop/lint/literal_as_condition.rb +118 -9
  148. data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +1 -1
  149. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +24 -6
  150. data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +1 -1
  151. data/lib/rubocop/cop/lint/missing_super.rb +2 -2
  152. data/lib/rubocop/cop/lint/mixed_case_range.rb +5 -8
  153. data/lib/rubocop/cop/lint/mixed_regexp_capture_types.rb +1 -1
  154. data/lib/rubocop/cop/lint/nested_method_definition.rb +10 -6
  155. data/lib/rubocop/cop/lint/next_without_accumulator.rb +1 -1
  156. data/lib/rubocop/cop/lint/no_return_in_begin_end_blocks.rb +2 -2
  157. data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +12 -3
  158. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +3 -3
  159. data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +3 -3
  160. data/lib/rubocop/cop/lint/number_conversion.rb +0 -1
  161. data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +1 -2
  162. data/lib/rubocop/cop/lint/numeric_operation_with_constant_result.rb +93 -0
  163. data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +2 -3
  164. data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +3 -2
  165. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +1 -5
  166. data/lib/rubocop/cop/lint/raise_exception.rb +29 -10
  167. data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +1 -1
  168. data/lib/rubocop/cop/lint/redundant_regexp_quantifiers.rb +1 -1
  169. data/lib/rubocop/cop/lint/redundant_require_statement.rb +0 -21
  170. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +12 -7
  171. data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +8 -7
  172. data/lib/rubocop/cop/lint/redundant_string_coercion.rb +2 -2
  173. data/lib/rubocop/cop/lint/redundant_type_conversion.rb +261 -0
  174. data/lib/rubocop/cop/lint/redundant_with_index.rb +3 -0
  175. data/lib/rubocop/cop/lint/redundant_with_object.rb +3 -0
  176. data/lib/rubocop/cop/lint/refinement_import_methods.rb +1 -1
  177. data/lib/rubocop/cop/lint/regexp_as_condition.rb +0 -1
  178. data/lib/rubocop/cop/lint/rescue_exception.rb +1 -1
  179. data/lib/rubocop/cop/lint/rescue_type.rb +3 -7
  180. data/lib/rubocop/cop/lint/return_in_void_context.rb +9 -11
  181. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +17 -1
  182. data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +5 -1
  183. data/lib/rubocop/cop/lint/self_assignment.rb +8 -10
  184. data/lib/rubocop/cop/lint/shadowed_exception.rb +1 -1
  185. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +8 -1
  186. data/lib/rubocop/cop/lint/shared_mutable_default.rb +76 -0
  187. data/lib/rubocop/cop/lint/suppressed_exception.rb +1 -1
  188. data/lib/rubocop/cop/lint/suppressed_exception_in_number_conversion.rb +111 -0
  189. data/lib/rubocop/cop/lint/symbol_conversion.rb +1 -1
  190. data/lib/rubocop/cop/lint/syntax.rb +4 -1
  191. data/lib/rubocop/cop/lint/to_enum_arguments.rb +1 -1
  192. data/lib/rubocop/cop/lint/top_level_return_with_argument.rb +1 -1
  193. data/lib/rubocop/cop/lint/unescaped_bracket_in_regexp.rb +88 -0
  194. data/lib/rubocop/cop/lint/unexpected_block_arity.rb +3 -1
  195. data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +1 -1
  196. data/lib/rubocop/cop/lint/unreachable_code.rb +52 -2
  197. data/lib/rubocop/cop/lint/unreachable_loop.rb +6 -6
  198. data/lib/rubocop/cop/lint/unused_method_argument.rb +18 -2
  199. data/lib/rubocop/cop/lint/useless_access_modifier.rb +5 -4
  200. data/lib/rubocop/cop/lint/useless_assignment.rb +3 -1
  201. data/lib/rubocop/cop/lint/useless_constant_scoping.rb +71 -0
  202. data/lib/rubocop/cop/lint/useless_defined.rb +55 -0
  203. data/lib/rubocop/cop/lint/useless_else_without_rescue.rb +4 -0
  204. data/lib/rubocop/cop/lint/useless_method_definition.rb +1 -1
  205. data/lib/rubocop/cop/lint/useless_numeric_operation.rb +2 -1
  206. data/lib/rubocop/cop/lint/useless_rescue.rb +2 -2
  207. data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +2 -2
  208. data/lib/rubocop/cop/lint/useless_setter_call.rb +14 -25
  209. data/lib/rubocop/cop/lint/void.rb +16 -12
  210. data/lib/rubocop/cop/message_annotator.rb +7 -3
  211. data/lib/rubocop/cop/metrics/block_length.rb +1 -0
  212. data/lib/rubocop/cop/metrics/block_nesting.rb +1 -1
  213. data/lib/rubocop/cop/metrics/class_length.rb +9 -9
  214. data/lib/rubocop/cop/metrics/collection_literal_length.rb +7 -0
  215. data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +5 -2
  216. data/lib/rubocop/cop/metrics/method_length.rb +9 -1
  217. data/lib/rubocop/cop/metrics/module_length.rb +1 -1
  218. data/lib/rubocop/cop/metrics/perceived_complexity.rb +1 -1
  219. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +1 -1
  220. data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +3 -4
  221. data/lib/rubocop/cop/metrics/utils/repeated_attribute_discount.rb +7 -7
  222. data/lib/rubocop/cop/mixin/alignment.rb +2 -2
  223. data/lib/rubocop/cop/mixin/allowed_pattern.rb +4 -4
  224. data/lib/rubocop/cop/mixin/check_assignment.rb +4 -12
  225. data/lib/rubocop/cop/mixin/check_line_breakable.rb +22 -12
  226. data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +49 -0
  227. data/lib/rubocop/cop/mixin/comments_help.rb +8 -3
  228. data/lib/rubocop/cop/mixin/def_node.rb +1 -1
  229. data/lib/rubocop/cop/mixin/dig_help.rb +27 -0
  230. data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +1 -1
  231. data/lib/rubocop/cop/mixin/endless_method_rewriter.rb +24 -0
  232. data/lib/rubocop/cop/mixin/forbidden_identifiers.rb +20 -0
  233. data/lib/rubocop/cop/mixin/forbidden_pattern.rb +16 -0
  234. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +3 -2
  235. data/lib/rubocop/cop/mixin/hash_alignment_styles.rb +15 -14
  236. data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +22 -22
  237. data/lib/rubocop/cop/mixin/hash_subset.rb +203 -0
  238. data/lib/rubocop/cop/mixin/hash_transform_method.rb +74 -74
  239. data/lib/rubocop/cop/mixin/line_length_help.rb +5 -4
  240. data/lib/rubocop/cop/mixin/method_complexity.rb +2 -1
  241. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +7 -9
  242. data/lib/rubocop/cop/mixin/percent_literal.rb +1 -1
  243. data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +68 -30
  244. data/lib/rubocop/cop/mixin/range_help.rb +15 -4
  245. data/lib/rubocop/cop/mixin/space_before_punctuation.rb +1 -1
  246. data/lib/rubocop/cop/mixin/statement_modifier.rb +8 -3
  247. data/lib/rubocop/cop/mixin/string_help.rb +2 -2
  248. data/lib/rubocop/cop/mixin/string_literals_help.rb +1 -1
  249. data/lib/rubocop/cop/mixin/target_ruby_version.rb +17 -1
  250. data/lib/rubocop/cop/mixin/trailing_comma.rb +21 -5
  251. data/lib/rubocop/cop/naming/accessor_method_name.rb +6 -6
  252. data/lib/rubocop/cop/naming/block_forwarding.rb +20 -16
  253. data/lib/rubocop/cop/naming/constant_name.rb +6 -7
  254. data/lib/rubocop/cop/naming/file_name.rb +0 -2
  255. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +12 -13
  256. data/lib/rubocop/cop/naming/method_name.rb +64 -8
  257. data/lib/rubocop/cop/naming/predicate_name.rb +44 -0
  258. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +6 -14
  259. data/lib/rubocop/cop/naming/variable_name.rb +50 -6
  260. data/lib/rubocop/cop/naming/variable_number.rb +2 -3
  261. data/lib/rubocop/cop/offense.rb +2 -3
  262. data/lib/rubocop/cop/registry.rb +9 -6
  263. data/lib/rubocop/cop/security/compound_hash.rb +2 -0
  264. data/lib/rubocop/cop/security/yaml_load.rb +3 -2
  265. data/lib/rubocop/cop/style/access_modifier_declarations.rb +86 -28
  266. data/lib/rubocop/cop/style/accessor_grouping.rb +19 -5
  267. data/lib/rubocop/cop/style/ambiguous_endless_method_definition.rb +79 -0
  268. data/lib/rubocop/cop/style/and_or.rb +1 -1
  269. data/lib/rubocop/cop/style/arguments_forwarding.rb +47 -28
  270. data/lib/rubocop/cop/style/array_first_last.rb +18 -2
  271. data/lib/rubocop/cop/style/array_intersect.rb +42 -30
  272. data/lib/rubocop/cop/style/bitwise_predicate.rb +100 -0
  273. data/lib/rubocop/cop/style/block_delimiters.rb +43 -25
  274. data/lib/rubocop/cop/style/case_like_if.rb +8 -11
  275. data/lib/rubocop/cop/style/class_and_module_children.rb +52 -11
  276. data/lib/rubocop/cop/style/class_equality_comparison.rb +1 -1
  277. data/lib/rubocop/cop/style/collection_methods.rb +2 -1
  278. data/lib/rubocop/cop/style/combinable_defined.rb +115 -0
  279. data/lib/rubocop/cop/style/combinable_loops.rb +3 -2
  280. data/lib/rubocop/cop/style/commented_keyword.rb +20 -3
  281. data/lib/rubocop/cop/style/comparable_between.rb +78 -0
  282. data/lib/rubocop/cop/style/concat_array_literals.rb +1 -1
  283. data/lib/rubocop/cop/style/conditional_assignment.rb +39 -27
  284. data/lib/rubocop/cop/style/constant_visibility.rb +3 -12
  285. data/lib/rubocop/cop/style/data_inheritance.rb +7 -0
  286. data/lib/rubocop/cop/style/dig_chain.rb +89 -0
  287. data/lib/rubocop/cop/style/documentation.rb +1 -1
  288. data/lib/rubocop/cop/style/double_negation.rb +4 -4
  289. data/lib/rubocop/cop/style/each_for_simple_loop.rb +4 -7
  290. data/lib/rubocop/cop/style/each_with_object.rb +2 -3
  291. data/lib/rubocop/cop/style/empty_else.rb +4 -2
  292. data/lib/rubocop/cop/style/empty_literal.rb +5 -1
  293. data/lib/rubocop/cop/style/empty_method.rb +1 -1
  294. data/lib/rubocop/cop/style/endless_method.rb +150 -18
  295. data/lib/rubocop/cop/style/eval_with_location.rb +4 -4
  296. data/lib/rubocop/cop/style/exact_regexp_match.rb +2 -3
  297. data/lib/rubocop/cop/style/expand_path_arguments.rb +2 -7
  298. data/lib/rubocop/cop/style/explicit_block_argument.rb +16 -3
  299. data/lib/rubocop/cop/style/exponential_notation.rb +3 -3
  300. data/lib/rubocop/cop/style/fetch_env_var.rb +2 -1
  301. data/lib/rubocop/cop/style/file_null.rb +89 -0
  302. data/lib/rubocop/cop/style/file_touch.rb +75 -0
  303. data/lib/rubocop/cop/style/float_division.rb +8 -4
  304. data/lib/rubocop/cop/style/for.rb +1 -1
  305. data/lib/rubocop/cop/style/format_string_token.rb +38 -11
  306. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +3 -2
  307. data/lib/rubocop/cop/style/global_std_stream.rb +3 -0
  308. data/lib/rubocop/cop/style/global_vars.rb +1 -3
  309. data/lib/rubocop/cop/style/guard_clause.rb +17 -3
  310. data/lib/rubocop/cop/style/hash_conversion.rb +1 -2
  311. data/lib/rubocop/cop/style/hash_each_methods.rb +6 -8
  312. data/lib/rubocop/cop/style/hash_except.rb +35 -147
  313. data/lib/rubocop/cop/style/hash_fetch_chain.rb +104 -0
  314. data/lib/rubocop/cop/style/hash_slice.rb +80 -0
  315. data/lib/rubocop/cop/style/hash_syntax.rb +9 -3
  316. data/lib/rubocop/cop/style/hash_transform_keys.rb +2 -2
  317. data/lib/rubocop/cop/style/hash_transform_values.rb +2 -2
  318. data/lib/rubocop/cop/style/identical_conditional_branches.rb +25 -6
  319. data/lib/rubocop/cop/style/if_inside_else.rb +10 -14
  320. data/lib/rubocop/cop/style/if_unless_modifier.rb +25 -5
  321. data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +3 -4
  322. data/lib/rubocop/cop/style/if_with_semicolon.rb +20 -9
  323. data/lib/rubocop/cop/style/infinite_loop.rb +1 -1
  324. data/lib/rubocop/cop/style/inverse_methods.rb +15 -12
  325. data/lib/rubocop/cop/style/invertible_unless_condition.rb +2 -2
  326. data/lib/rubocop/cop/style/ip_addresses.rb +2 -2
  327. data/lib/rubocop/cop/style/it_assignment.rb +36 -0
  328. data/lib/rubocop/cop/style/it_block_parameter.rb +100 -0
  329. data/lib/rubocop/cop/style/keyword_arguments_merging.rb +67 -0
  330. data/lib/rubocop/cop/style/keyword_parameters_order.rb +14 -8
  331. data/lib/rubocop/cop/style/lambda.rb +1 -0
  332. data/lib/rubocop/cop/style/lambda_call.rb +10 -4
  333. data/lib/rubocop/cop/style/line_end_concatenation.rb +10 -4
  334. data/lib/rubocop/cop/style/map_into_array.rb +11 -3
  335. data/lib/rubocop/cop/style/map_to_hash.rb +1 -1
  336. data/lib/rubocop/cop/style/map_to_set.rb +3 -2
  337. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +27 -17
  338. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +2 -0
  339. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +8 -11
  340. data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +3 -4
  341. data/lib/rubocop/cop/style/method_def_parentheses.rb +1 -1
  342. data/lib/rubocop/cop/style/missing_else.rb +2 -0
  343. data/lib/rubocop/cop/style/missing_respond_to_missing.rb +33 -3
  344. data/lib/rubocop/cop/style/multiline_block_chain.rb +3 -2
  345. data/lib/rubocop/cop/style/multiline_if_modifier.rb +2 -0
  346. data/lib/rubocop/cop/style/multiline_memoization.rb +1 -1
  347. data/lib/rubocop/cop/style/multiline_method_signature.rb +1 -9
  348. data/lib/rubocop/cop/style/multiple_comparison.rb +52 -51
  349. data/lib/rubocop/cop/style/mutable_constant.rb +7 -8
  350. data/lib/rubocop/cop/style/negated_if_else_condition.rb +7 -5
  351. data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +1 -1
  352. data/lib/rubocop/cop/style/nested_ternary_operator.rb +5 -4
  353. data/lib/rubocop/cop/style/next.rb +44 -0
  354. data/lib/rubocop/cop/style/not.rb +1 -1
  355. data/lib/rubocop/cop/style/object_then.rb +15 -15
  356. data/lib/rubocop/cop/style/one_line_conditional.rb +25 -4
  357. data/lib/rubocop/cop/style/open_struct_use.rb +5 -5
  358. data/lib/rubocop/cop/style/operator_method_call.rb +5 -6
  359. data/lib/rubocop/cop/style/or_assignment.rb +3 -6
  360. data/lib/rubocop/cop/style/parallel_assignment.rb +9 -18
  361. data/lib/rubocop/cop/style/parentheses_around_condition.rb +2 -2
  362. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +1 -1
  363. data/lib/rubocop/cop/style/percent_q_literals.rb +1 -1
  364. data/lib/rubocop/cop/style/proc.rb +2 -2
  365. data/lib/rubocop/cop/style/quoted_symbols.rb +1 -1
  366. data/lib/rubocop/cop/style/raise_args.rb +15 -13
  367. data/lib/rubocop/cop/style/random_with_offset.rb +3 -3
  368. data/lib/rubocop/cop/style/redundant_argument.rb +3 -1
  369. data/lib/rubocop/cop/style/redundant_assignment.rb +1 -1
  370. data/lib/rubocop/cop/style/redundant_begin.rb +2 -1
  371. data/lib/rubocop/cop/style/redundant_condition.rb +95 -23
  372. data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +16 -5
  373. data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +6 -10
  374. data/lib/rubocop/cop/style/redundant_each.rb +1 -1
  375. data/lib/rubocop/cop/style/redundant_exception.rb +2 -2
  376. data/lib/rubocop/cop/style/redundant_format.rb +257 -0
  377. data/lib/rubocop/cop/style/redundant_freeze.rb +3 -3
  378. data/lib/rubocop/cop/style/redundant_initialize.rb +12 -3
  379. data/lib/rubocop/cop/style/redundant_line_continuation.rb +54 -18
  380. data/lib/rubocop/cop/style/redundant_parentheses.rb +56 -26
  381. data/lib/rubocop/cop/style/redundant_regexp_argument.rb +4 -0
  382. data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +1 -1
  383. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +1 -1
  384. data/lib/rubocop/cop/style/redundant_return.rb +2 -2
  385. data/lib/rubocop/cop/style/redundant_self.rb +9 -15
  386. data/lib/rubocop/cop/style/redundant_self_assignment.rb +20 -32
  387. data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +4 -4
  388. data/lib/rubocop/cop/style/redundant_sort.rb +3 -3
  389. data/lib/rubocop/cop/style/redundant_sort_by.rb +17 -1
  390. data/lib/rubocop/cop/style/redundant_string_escape.rb +2 -2
  391. data/lib/rubocop/cop/style/rescue_modifier.rb +5 -3
  392. data/lib/rubocop/cop/style/return_nil.rb +2 -2
  393. data/lib/rubocop/cop/style/safe_navigation.rb +32 -5
  394. data/lib/rubocop/cop/style/safe_navigation_chain_length.rb +52 -0
  395. data/lib/rubocop/cop/style/select_by_regexp.rb +5 -2
  396. data/lib/rubocop/cop/style/self_assignment.rb +11 -17
  397. data/lib/rubocop/cop/style/semicolon.rb +1 -1
  398. data/lib/rubocop/cop/style/send_with_literal_method_name.rb +2 -1
  399. data/lib/rubocop/cop/style/signal_exception.rb +2 -3
  400. data/lib/rubocop/cop/style/single_argument_dig.rb +9 -5
  401. data/lib/rubocop/cop/style/single_line_block_params.rb +1 -1
  402. data/lib/rubocop/cop/style/single_line_do_end_block.rb +15 -4
  403. data/lib/rubocop/cop/style/single_line_methods.rb +6 -7
  404. data/lib/rubocop/cop/style/slicing_with_range.rb +40 -11
  405. data/lib/rubocop/cop/style/sole_nested_conditional.rb +42 -106
  406. data/lib/rubocop/cop/style/special_global_vars.rb +1 -1
  407. data/lib/rubocop/cop/style/string_concatenation.rb +15 -15
  408. data/lib/rubocop/cop/style/string_literals.rb +1 -1
  409. data/lib/rubocop/cop/style/string_methods.rb +1 -1
  410. data/lib/rubocop/cop/style/struct_inheritance.rb +8 -1
  411. data/lib/rubocop/cop/style/super_arguments.rb +66 -19
  412. data/lib/rubocop/cop/style/swap_values.rb +4 -15
  413. data/lib/rubocop/cop/style/symbol_proc.rb +2 -0
  414. data/lib/rubocop/cop/style/ternary_parentheses.rb +25 -4
  415. data/lib/rubocop/cop/style/top_level_method_definition.rb +2 -1
  416. data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +11 -2
  417. data/lib/rubocop/cop/style/trailing_comma_in_array_literal.rb +47 -6
  418. data/lib/rubocop/cop/style/trailing_comma_in_hash_literal.rb +48 -6
  419. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +4 -4
  420. data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
  421. data/lib/rubocop/cop/style/variable_interpolation.rb +1 -2
  422. data/lib/rubocop/cop/style/while_until_modifier.rb +0 -1
  423. data/lib/rubocop/cop/style/yoda_condition.rb +8 -4
  424. data/lib/rubocop/cop/style/yoda_expression.rb +2 -1
  425. data/lib/rubocop/cop/util.rb +12 -5
  426. data/lib/rubocop/cop/utils/format_string.rb +10 -5
  427. data/lib/rubocop/cop/variable_force/assignment.rb +18 -3
  428. data/lib/rubocop/cop/variable_force/branch.rb +1 -1
  429. data/lib/rubocop/cop/variable_force/scope.rb +1 -1
  430. data/lib/rubocop/cop/variable_force/variable.rb +14 -3
  431. data/lib/rubocop/cop/variable_force/variable_table.rb +5 -5
  432. data/lib/rubocop/cop/variable_force.rb +5 -11
  433. data/lib/rubocop/cops_documentation_generator.rb +50 -25
  434. data/lib/rubocop/directive_comment.rb +45 -11
  435. data/lib/rubocop/ext/regexp_node.rb +0 -1
  436. data/lib/rubocop/formatter/disabled_config_formatter.rb +3 -2
  437. data/lib/rubocop/formatter/formatter_set.rb +1 -1
  438. data/lib/rubocop/formatter/html_formatter.rb +1 -1
  439. data/lib/rubocop/formatter/pacman_formatter.rb +1 -1
  440. data/lib/rubocop/lsp/diagnostic.rb +189 -0
  441. data/lib/rubocop/lsp/logger.rb +2 -2
  442. data/lib/rubocop/lsp/routes.rb +7 -23
  443. data/lib/rubocop/lsp/runtime.rb +18 -50
  444. data/lib/rubocop/lsp/server.rb +0 -2
  445. data/lib/rubocop/lsp/stdin_runner.rb +85 -0
  446. data/lib/rubocop/magic_comment.rb +11 -3
  447. data/lib/rubocop/options.rb +28 -12
  448. data/lib/rubocop/path_util.rb +15 -8
  449. data/lib/rubocop/plugin/configuration_integrator.rb +143 -0
  450. data/lib/rubocop/plugin/load_error.rb +26 -0
  451. data/lib/rubocop/plugin/loader.rb +100 -0
  452. data/lib/rubocop/plugin/not_supported_error.rb +29 -0
  453. data/lib/rubocop/plugin.rb +46 -0
  454. data/lib/rubocop/rake_task.rb +4 -1
  455. data/lib/rubocop/result_cache.rb +13 -13
  456. data/lib/rubocop/rspec/cop_helper.rb +13 -1
  457. data/lib/rubocop/rspec/expect_offense.rb +6 -2
  458. data/lib/rubocop/rspec/shared_contexts.rb +38 -1
  459. data/lib/rubocop/rspec/support.rb +4 -2
  460. data/lib/rubocop/runner.rb +26 -15
  461. data/lib/rubocop/server/cache.rb +47 -11
  462. data/lib/rubocop/server/cli.rb +2 -2
  463. data/lib/rubocop/target_finder.rb +7 -2
  464. data/lib/rubocop/target_ruby.rb +17 -2
  465. data/lib/rubocop/version.rb +53 -12
  466. data/lib/rubocop.rb +32 -1
  467. data/lib/ruby_lsp/rubocop/addon.rb +75 -0
  468. data/lib/ruby_lsp/rubocop/runtime_adapter.rb +65 -0
  469. metadata +79 -20
  470. data/lib/rubocop/cop/utils/regexp_ranges.rb +0 -113
  471. data/lib/rubocop/rspec/host_environment_simulation_helper.rb +0 -28
@@ -43,12 +43,14 @@ module RuboCop
43
43
  # (Note: Passes may not happen exactly in this sequence.)
44
44
  module CheckLineBreakable
45
45
  def extract_breakable_node(node, max)
46
- if node.send_type?
46
+ if node.call_type?
47
+ return if chained_to_heredoc?(node)
48
+
47
49
  args = process_args(node.arguments)
48
50
  return extract_breakable_node_from_elements(node, args, max)
49
- elsif node.def_type?
51
+ elsif node.any_def_type?
50
52
  return extract_breakable_node_from_elements(node, node.arguments, max)
51
- elsif node.array_type? || node.hash_type?
53
+ elsif node.type?(:array, :hash)
52
54
  return extract_breakable_node_from_elements(node, node.children, max)
53
55
  end
54
56
  nil
@@ -72,9 +74,9 @@ module RuboCop
72
74
  def extract_first_element_over_column_limit(node, elements, max)
73
75
  line = node.first_line
74
76
 
75
- # If a `send` node is not parenthesized, don't move the first element, because it
77
+ # If a `send` or `csend` node is not parenthesized, don't move the first element, because it
76
78
  # can result in changed behavior or a syntax error.
77
- if node.send_type? && !node.parenthesized? && !first_argument_is_heredoc?(node)
79
+ if node.call_type? && !node.parenthesized? && !first_argument_is_heredoc?(node)
78
80
  elements = elements.drop(1)
79
81
  end
80
82
 
@@ -96,10 +98,10 @@ module RuboCop
96
98
  end
97
99
 
98
100
  # @api private
99
- # If a send node contains a heredoc argument, splitting cannot happen
101
+ # If a `send` or `csend` node contains a heredoc argument, splitting cannot happen
100
102
  # after the heredoc or else it will cause a syntax error.
101
103
  def shift_elements_for_heredoc_arg(node, elements, index)
102
- return index unless node.send_type? || node.array_type?
104
+ return index unless node.type?(:call, :array)
103
105
 
104
106
  heredoc_index = elements.index { |arg| arg.respond_to?(:heredoc?) && arg.heredoc? }
105
107
  return index unless heredoc_index
@@ -152,9 +154,9 @@ module RuboCop
152
154
  # Ignore ancestors on different lines.
153
155
  break if ancestor.first_line != node.first_line
154
156
 
155
- if ancestor.hash_type? || ancestor.array_type?
157
+ if ancestor.type?(:hash, :array)
156
158
  elements = ancestor.children
157
- elsif ancestor.send_type?
159
+ elsif ancestor.call_type?
158
160
  elements = process_args(ancestor.arguments)
159
161
  else
160
162
  next
@@ -169,12 +171,12 @@ module RuboCop
169
171
  # @api private
170
172
  def contained_by_multiline_collection_that_could_be_broken_up?(node)
171
173
  node.each_ancestor.find do |ancestor|
172
- if (ancestor.hash_type? || ancestor.array_type?) &&
174
+ if ancestor.type?(:hash, :array) &&
173
175
  breakable_collection?(ancestor, ancestor.children)
174
176
  return children_could_be_broken_up?(ancestor.children)
175
177
  end
176
178
 
177
- next unless ancestor.send_type?
179
+ next unless ancestor.call_type?
178
180
 
179
181
  args = process_args(ancestor.arguments)
180
182
  return children_could_be_broken_up?(args) if breakable_collection?(ancestor, args)
@@ -218,10 +220,18 @@ module RuboCop
218
220
 
219
221
  # @api private
220
222
  def already_on_multiple_lines?(node)
221
- return node.first_line != node.last_argument.last_line if node.def_type?
223
+ return node.first_line != node.last_argument.last_line if node.any_def_type?
222
224
 
223
225
  !node.single_line?
224
226
  end
227
+
228
+ def chained_to_heredoc?(node)
229
+ while (node = node.receiver)
230
+ return true if node.type?(:str, :dstr, :xstr) && node.heredoc?
231
+ end
232
+
233
+ false
234
+ end
225
235
  end
226
236
  end
227
237
  end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ # Checks for code on multiple lines that could be rewritten on a single line
6
+ # without changing semantics or exceeding the `Max` parameter of `Layout/LineLength`.
7
+ module CheckSingleLineSuitability
8
+ def suitable_as_single_line?(node)
9
+ !too_long?(node) &&
10
+ !comment_within?(node) &&
11
+ safe_to_split?(node)
12
+ end
13
+
14
+ private
15
+
16
+ def too_long?(node)
17
+ lines = processed_source.lines[(node.first_line - 1)...node.last_line]
18
+ to_single_line(lines.join("\n")).length > max_line_length
19
+ end
20
+
21
+ def to_single_line(source)
22
+ source
23
+ .gsub(/" *\\\n\s*'/, %q(" + ')) # Double quote, backslash, and then single quote
24
+ .gsub(/' *\\\n\s*"/, %q(' + ")) # Single quote, backslash, and then double quote
25
+ .gsub(/(["']) *\\\n\s*\1/, '') # Double or single quote, backslash, then same quote
26
+ .gsub(/\n\s*(?=(&)?\.\w)/, '') # Extra space within method chaining which includes `&.`
27
+ .gsub(/\s*\\?\n\s*/, ' ') # Any other line break, with or without backslash
28
+ end
29
+
30
+ def max_line_length
31
+ config.for_cop('Layout/LineLength')['Max']
32
+ end
33
+
34
+ def comment_within?(node)
35
+ comment_line_numbers = processed_source.comments.map { |comment| comment.loc.line }
36
+
37
+ comment_line_numbers.any? do |comment_line_number|
38
+ comment_line_number.between?(node.first_line, node.last_line)
39
+ end
40
+ end
41
+
42
+ def safe_to_split?(node)
43
+ node.each_descendant(:if, :case, :kwbegin, :any_def).none? &&
44
+ node.each_descendant(:dstr, :str).none? { |n| n.heredoc? || n.value.include?("\n") } &&
45
+ node.each_descendant(:begin, :sym).none? { |b| !b.single_line? }
46
+ end
47
+ end
48
+ end
49
+ end
@@ -16,6 +16,8 @@ module RuboCop
16
16
  end
17
17
 
18
18
  def comments_in_range(node)
19
+ return [] unless node.source_range
20
+
19
21
  start_line = node.source_range.line
20
22
  end_line = find_end_line(node)
21
23
 
@@ -71,13 +73,16 @@ module RuboCop
71
73
  node.else_branch.loc.line
72
74
  elsif node.elsif?
73
75
  node.each_ancestor(:if).find(&:if?).loc.end.line
76
+ elsif node.if? && node.parent && parentheses?(node.parent)
77
+ node.parent.loc.end.line
74
78
  end
75
- elsif node.block_type? || node.numblock_type?
79
+ elsif node.any_block_type?
76
80
  node.loc.end.line
77
- elsif (next_sibling = node.right_sibling) && next_sibling.is_a?(AST::Node)
81
+ elsif (next_sibling = node.right_sibling) && next_sibling.is_a?(AST::Node) &&
82
+ next_sibling.source_range
78
83
  next_sibling.loc.line
79
84
  elsif (parent = node.parent)
80
- if parent.loc.respond_to?(:end) && parent.loc.end
85
+ if parent.loc?(:end)
81
86
  parent.loc.end.line
82
87
  else
83
88
  parent.loc.line
@@ -19,7 +19,7 @@ module RuboCop
19
19
 
20
20
  # @!method non_public_modifier?(node)
21
21
  def_node_matcher :non_public_modifier?, <<~PATTERN
22
- (send nil? {:private :protected :private_class_method} ({def defs} ...))
22
+ (send nil? {:private :protected :private_class_method} (any_def ...))
23
23
  PATTERN
24
24
  end
25
25
  end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ # Help methods for working with `Enumerable#dig` in cops.
6
+ # Used by `Style::DigChain` and `Style::SingleArgumentDig`
7
+ module DigHelp
8
+ extend NodePattern::Macros
9
+
10
+ # @!method dig?(node)
11
+ def_node_matcher :dig?, <<~PATTERN
12
+ (call _ :dig !{hash block_pass}+)
13
+ PATTERN
14
+
15
+ # @!method single_argument_dig?(node)
16
+ def_node_matcher :single_argument_dig?, <<~PATTERN
17
+ (send _ :dig $!splat)
18
+ PATTERN
19
+
20
+ private
21
+
22
+ def dig_chain_enabled?
23
+ @config.cop_enabled?('Style/DigChain')
24
+ end
25
+ end
26
+ end
27
+ end
@@ -21,7 +21,7 @@ module RuboCop
21
21
 
22
22
  # @!method empty_line_required?(node)
23
23
  def_node_matcher :empty_line_required?,
24
- '{def defs class module (send nil? {:private :protected :public})}'
24
+ '{any_def class module (send nil? {:private :protected :public})}'
25
25
 
26
26
  def check(node, body, adjusted_first_line: nil)
27
27
  return if valid_body_style?(body)
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ # Common functionality for rewriting endless methods to normal method definitions
6
+ module EndlessMethodRewriter
7
+ def correct_to_multiline(corrector, node)
8
+ replacement = <<~RUBY.strip
9
+ def #{node.method_name}#{arguments(node)}
10
+ #{node.body.source}
11
+ end
12
+ RUBY
13
+
14
+ corrector.replace(node, replacement)
15
+ end
16
+
17
+ private
18
+
19
+ def arguments(node, missing = '')
20
+ node.arguments.any? ? node.arguments.source : missing
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ # This module encapsulates the ability to forbid certain identifiers in a cop.
6
+ module ForbiddenIdentifiers
7
+ SIGILS = '@$' # if a variable starts with a sigil it will be removed
8
+
9
+ def forbidden_identifier?(name)
10
+ name = name.to_s.delete(SIGILS)
11
+
12
+ forbidden_identifiers.any? && forbidden_identifiers.include?(name)
13
+ end
14
+
15
+ def forbidden_identifiers
16
+ cop_config.fetch('ForbiddenIdentifiers', [])
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ # This module encapsulates the ability to forbid certain patterns in a cop.
6
+ module ForbiddenPattern
7
+ def forbidden_pattern?(name)
8
+ forbidden_patterns.any? { |pattern| Regexp.new(pattern).match?(name) }
9
+ end
10
+
11
+ def forbidden_patterns
12
+ cop_config.fetch('ForbiddenPatterns', [])
13
+ end
14
+ end
15
+ end
16
+ end
@@ -6,7 +6,6 @@ module RuboCop
6
6
  module FrozenStringLiteral
7
7
  module_function
8
8
 
9
- FROZEN_STRING_LITERAL = '# frozen_string_literal:'
10
9
  FROZEN_STRING_LITERAL_ENABLED = '# frozen_string_literal: true'
11
10
  FROZEN_STRING_LITERAL_TYPES_RUBY27 = %i[str dstr].freeze
12
11
 
@@ -29,7 +28,9 @@ module RuboCop
29
28
  end
30
29
 
31
30
  def uninterpolated_string?(node)
32
- node.str_type? || (node.dstr_type? && node.each_descendant(:begin).none?)
31
+ node.str_type? || (
32
+ node.dstr_type? && node.each_descendant(:begin, :ivar, :cvar, :gvar).none?
33
+ )
33
34
  end
34
35
 
35
36
  def uninterpolated_heredoc?(node)
@@ -10,7 +10,7 @@ module RuboCop
10
10
  true
11
11
  end
12
12
 
13
- def deltas_for_first_pair(first_pair, _node)
13
+ def deltas_for_first_pair(first_pair)
14
14
  {
15
15
  separator: separator_delta(first_pair),
16
16
  value: value_delta(first_pair)
@@ -81,13 +81,7 @@ module RuboCop
81
81
  class TableAlignment
82
82
  include ValueAlignment
83
83
 
84
- def initialize
85
- self.max_key_width = 0
86
- end
87
-
88
- def deltas_for_first_pair(first_pair, node)
89
- self.max_key_width = node.keys.map { |key| key.source.length }.max
90
-
84
+ def deltas_for_first_pair(first_pair)
91
85
  separator_delta = separator_delta(first_pair, first_pair, 0)
92
86
  {
93
87
  separator: separator_delta,
@@ -97,30 +91,37 @@ module RuboCop
97
91
 
98
92
  private
99
93
 
100
- attr_accessor :max_key_width
101
-
102
94
  def key_delta(first_pair, current_pair)
103
95
  first_pair.key_delta(current_pair)
104
96
  end
105
97
 
106
98
  def hash_rocket_delta(first_pair, current_pair)
107
- first_pair.loc.column + max_key_width + 1 - current_pair.loc.operator.column
99
+ first_pair.loc.column + max_key_width(first_pair.parent) + 1 -
100
+ current_pair.loc.operator.column
108
101
  end
109
102
 
110
103
  def value_delta(first_pair, current_pair)
111
104
  correct_value_column = first_pair.key.loc.column +
112
- current_pair.delimiter(true).length +
113
- max_key_width
105
+ max_key_width(first_pair.parent) +
106
+ max_delimiter_width(first_pair.parent)
114
107
 
115
108
  current_pair.value_omission? ? 0 : correct_value_column - current_pair.value.loc.column
116
109
  end
110
+
111
+ def max_key_width(hash_node)
112
+ hash_node.keys.map { |key| key.source.length }.max
113
+ end
114
+
115
+ def max_delimiter_width(hash_node)
116
+ hash_node.pairs.map { |pair| pair.delimiter(true).length }.max
117
+ end
117
118
  end
118
119
 
119
120
  # Handles calculation of deltas when the enforced style is 'separator'.
120
121
  class SeparatorAlignment
121
122
  include ValueAlignment
122
123
 
123
- def deltas_for_first_pair(*_nodes)
124
+ def deltas_for_first_pair(_first_pair)
124
125
  {}
125
126
  end
126
127
 
@@ -11,6 +11,24 @@ module RuboCop
11
11
  DO_NOT_MIX_OMIT_VALUE_MSG = "#{DO_NOT_MIX_MSG_PREFIX} #{OMIT_HASH_VALUE_MSG}"
12
12
  DO_NOT_MIX_EXPLICIT_VALUE_MSG = "#{DO_NOT_MIX_MSG_PREFIX} #{EXPLICIT_HASH_VALUE_MSG}"
13
13
 
14
+ DefNode = Struct.new(:node) do
15
+ def selector
16
+ if node.loc.respond_to?(:selector)
17
+ node.loc.selector
18
+ else
19
+ node.loc.keyword
20
+ end
21
+ end
22
+
23
+ def first_argument
24
+ node.first_argument
25
+ end
26
+
27
+ def last_argument
28
+ node.last_argument
29
+ end
30
+ end
31
+
14
32
  def on_hash_for_mixed_shorthand(hash_node)
15
33
  return if ignore_mixed_hash_shorthand_syntax?(hash_node)
16
34
 
@@ -86,7 +104,7 @@ module RuboCop
86
104
  return true if !node.key.sym_type? || require_hash_value_for_around_hash_literal?(node)
87
105
 
88
106
  hash_value = node.value
89
- return true unless hash_value.send_type? || hash_value.lvar_type?
107
+ return true unless hash_value.type?(:send, :lvar)
90
108
 
91
109
  hash_key_source != hash_value.source || hash_key_source.end_with?('!', '?')
92
110
  end
@@ -109,7 +127,7 @@ module RuboCop
109
127
  return if dispatch_node.parent && parentheses?(dispatch_node.parent)
110
128
  return if last_expression?(dispatch_node) && !method_dispatch_as_argument?(dispatch_node)
111
129
 
112
- def_node = node.each_ancestor(:send, :csend, :super, :yield).first
130
+ def_node = node.each_ancestor(:call, :super, :yield).first
113
131
 
114
132
  DefNode.new(def_node) unless def_node && def_node.arguments.empty?
115
133
  end
@@ -117,7 +135,7 @@ module RuboCop
117
135
 
118
136
  def find_ancestor_method_dispatch_node(node)
119
137
  return unless (ancestor = node.parent.parent)
120
- return unless ancestor.call_type? || ancestor.super_type? || ancestor.yield_type?
138
+ return unless ancestor.type?(:call, :super, :yield)
121
139
  return if brackets?(ancestor)
122
140
 
123
141
  ancestor
@@ -150,7 +168,7 @@ module RuboCop
150
168
  parent = method_dispatch_node.parent
151
169
  return false unless parent
152
170
 
153
- parent.call_type? || parent.super_type? || parent.yield_type?
171
+ parent.type?(:call, :super, :yield)
154
172
  end
155
173
 
156
174
  def breakdown_value_types_of_hash(hash_node)
@@ -212,24 +230,6 @@ module RuboCop
212
230
  register_offense(pair_node, OMIT_HASH_VALUE_MSG, replacement)
213
231
  end
214
232
  end
215
-
216
- DefNode = Struct.new(:node) do
217
- def selector
218
- if node.loc.respond_to?(:selector)
219
- node.loc.selector
220
- else
221
- node.loc.keyword
222
- end
223
- end
224
-
225
- def first_argument
226
- node.first_argument
227
- end
228
-
229
- def last_argument
230
- node.last_argument
231
- end
232
- end
233
233
  end
234
234
  end
235
235
  # rubocop:enable Metrics/ModuleLength
@@ -0,0 +1,203 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ # Common functionality for Style/HashExcept and Style/HashSlice cops.
6
+ # It registers an offense on methods with blocks that are equivalent
7
+ # to Hash#except or Hash#slice.
8
+ # rubocop:disable Metrics/ModuleLength
9
+ module HashSubset
10
+ include RangeHelp
11
+ extend NodePattern::Macros
12
+
13
+ RESTRICT_ON_SEND = %i[reject select filter].freeze
14
+
15
+ SUBSET_METHODS = %i[== != eql? include?].freeze
16
+ ACTIVE_SUPPORT_SUBSET_METHODS = (SUBSET_METHODS + %i[in? exclude?]).freeze
17
+
18
+ MSG = 'Use `%<prefer>s` instead.'
19
+
20
+ # @!method block_with_first_arg_check?(node)
21
+ def_node_matcher :block_with_first_arg_check?, <<~PATTERN
22
+ (block
23
+ (call _ _)
24
+ (args
25
+ $(arg _key)
26
+ $(arg _))
27
+ {
28
+ $(send
29
+ {(lvar _key) $_ _ | _ $_ (lvar _key)})
30
+ (send
31
+ $(send
32
+ {(lvar _key) $_ _ | _ $_ (lvar _key)}) :!)
33
+ })
34
+ PATTERN
35
+
36
+ def on_send(node)
37
+ offense_range, key_source = extract_offense(node)
38
+
39
+ return unless offense_range
40
+ return unless semantically_subset_method?(node)
41
+
42
+ preferred_method = "#{preferred_method_name}(#{key_source})"
43
+ add_offense(offense_range, message: format(MSG, prefer: preferred_method)) do |corrector|
44
+ corrector.replace(offense_range, preferred_method)
45
+ end
46
+ end
47
+ alias on_csend on_send
48
+
49
+ private
50
+
51
+ def semantically_subset_method?(node)
52
+ raise NotImplementedError
53
+ end
54
+
55
+ def preferred_method_name
56
+ raise NotImplementedError
57
+ end
58
+
59
+ def extract_offense(node)
60
+ block = node.parent
61
+ return unless extracts_hash_subset?(block)
62
+
63
+ except_key = except_key(block)
64
+ return if except_key.nil? || !safe_to_register_offense?(block, except_key)
65
+
66
+ [offense_range(node), except_key_source(except_key)]
67
+ end
68
+
69
+ def extracts_hash_subset?(block)
70
+ block_with_first_arg_check?(block) do |key_arg, value_arg, send_node, method|
71
+ # Only consider methods that have one argument
72
+ return false unless send_node.arguments.one?
73
+
74
+ return false unless supported_subset_method?(method)
75
+ return false if range_include?(send_node)
76
+
77
+ case method
78
+ when :include?, :exclude?
79
+ slices_key?(send_node, :first_argument, key_arg, value_arg)
80
+ when :in?
81
+ slices_key?(send_node, :receiver, key_arg, value_arg)
82
+ else
83
+ true
84
+ end
85
+ end
86
+ end
87
+
88
+ def slices_key?(send_node, method, key_arg, value_arg)
89
+ return false if using_value_variable?(send_node, value_arg)
90
+
91
+ node = method == :receiver ? send_node.receiver : send_node.first_argument
92
+ node.source == key_arg.source
93
+ end
94
+
95
+ def range_include?(send_node)
96
+ # When checking `include?`, `exclude?` and `in?` for offenses, if the receiver
97
+ # or first argument is a range, an offense should not be registered.
98
+ # ie. `(1..5).include?(k)` or `k.in?('a'..'z')`
99
+
100
+ return true if send_node.first_argument.range_type?
101
+
102
+ receiver = send_node.receiver
103
+ receiver = receiver.child_nodes.first while receiver.begin_type?
104
+ receiver.range_type?
105
+ end
106
+
107
+ def using_value_variable?(send_node, value_arg)
108
+ # If the receiver of `include?` or `exclude?`, or the first argument of `in?` is the
109
+ # hash value block argument, an offense should not be registered.
110
+ # ie. `v.include?(k)` or `k.in?(v)`
111
+ (send_node.receiver.lvar_type? && send_node.receiver.name == value_arg.name) ||
112
+ (send_node.first_argument.lvar_type? && send_node.first_argument.name == value_arg.name)
113
+ end
114
+
115
+ def supported_subset_method?(method)
116
+ if active_support_extensions_enabled?
117
+ ACTIVE_SUPPORT_SUBSET_METHODS.include?(method)
118
+ else
119
+ SUBSET_METHODS.include?(method)
120
+ end
121
+ end
122
+
123
+ def semantically_except_method?(node)
124
+ block = node.parent
125
+ body, negated = extract_body_if_negated(block.body)
126
+
127
+ if node.method?('reject')
128
+ body.method?('==') || body.method?('eql?') || included?(body, negated)
129
+ else
130
+ body.method?('!=') || not_included?(body, negated)
131
+ end
132
+ end
133
+
134
+ def semantically_slice_method?(node)
135
+ !semantically_except_method?(node)
136
+ end
137
+
138
+ def included?(body, negated)
139
+ if negated
140
+ body.method?('exclude?')
141
+ else
142
+ body.method?('include?') || body.method?('in?')
143
+ end
144
+ end
145
+
146
+ def not_included?(body, negated)
147
+ included?(body, !negated)
148
+ end
149
+
150
+ def safe_to_register_offense?(block, except_key)
151
+ body = block.body
152
+
153
+ if body.method?('==') || body.method?('!=')
154
+ except_key.type?(:sym, :str)
155
+ else
156
+ true
157
+ end
158
+ end
159
+
160
+ def extract_body_if_negated(body)
161
+ if body.method?('!')
162
+ [body.receiver, true]
163
+ else
164
+ [body, false]
165
+ end
166
+ end
167
+
168
+ def except_key_source(key)
169
+ if key.array_type?
170
+ key = if key.percent_literal?
171
+ key.each_value.map { |v| decorate_source(v) }
172
+ else
173
+ key.each_value.map(&:source)
174
+ end
175
+ return key.join(', ')
176
+ end
177
+
178
+ key.literal? ? key.source : "*#{key.source}"
179
+ end
180
+
181
+ def decorate_source(value)
182
+ return ":\"#{value.source}\"" if value.dsym_type?
183
+ return "\"#{value.source}\"" if value.dstr_type?
184
+ return ":#{value.source}" if value.sym_type?
185
+
186
+ "'#{value.source}'"
187
+ end
188
+
189
+ def except_key(node)
190
+ key_arg = node.argument_list.first.source
191
+ body, = extract_body_if_negated(node.body)
192
+ lhs, _method_name, rhs = *body
193
+
194
+ lhs.source == key_arg ? rhs : lhs
195
+ end
196
+
197
+ def offense_range(node)
198
+ range_between(node.loc.selector.begin_pos, node.parent.loc.end.end_pos)
199
+ end
200
+ end
201
+ # rubocop:enable Metrics/ModuleLength
202
+ end
203
+ end