rubocop 1.67.0 → 1.77.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (499) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +23 -17
  4. data/config/default.yml +337 -53
  5. data/config/internal_affairs.yml +20 -0
  6. data/config/obsoletion.yml +8 -3
  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 +51 -26
  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/bundler/ordered_gems.rb +1 -1
  28. data/lib/rubocop/cop/correctors/alignment_corrector.rb +1 -12
  29. data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +1 -1
  30. data/lib/rubocop/cop/correctors/parentheses_corrector.rb +5 -2
  31. data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +10 -0
  32. data/lib/rubocop/cop/gemspec/attribute_assignment.rb +91 -0
  33. data/lib/rubocop/cop/gemspec/deprecated_attribute_assignment.rb +1 -2
  34. data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +37 -15
  35. data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +1 -1
  36. data/lib/rubocop/cop/gemspec/require_mfa.rb +15 -1
  37. data/lib/rubocop/cop/gemspec/required_ruby_version.rb +0 -2
  38. data/lib/rubocop/cop/generator.rb +6 -0
  39. data/lib/rubocop/cop/internal_affairs/cop_enabled.rb +85 -0
  40. data/lib/rubocop/cop/internal_affairs/example_description.rb +8 -4
  41. data/lib/rubocop/cop/internal_affairs/location_exists.rb +116 -0
  42. data/lib/rubocop/cop/internal_affairs/location_expression.rb +2 -1
  43. data/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +3 -4
  44. data/lib/rubocop/cop/internal_affairs/node_first_or_last_argument.rb +3 -2
  45. data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +5 -5
  46. data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_processor.rb +63 -0
  47. data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_walker.rb +131 -0
  48. data/lib/rubocop/cop/internal_affairs/node_pattern_groups.rb +231 -0
  49. data/lib/rubocop/cop/internal_affairs/node_type_group.rb +91 -0
  50. data/lib/rubocop/cop/internal_affairs/node_type_multiple_predicates.rb +126 -0
  51. data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +4 -3
  52. data/lib/rubocop/cop/internal_affairs/numblock_handler.rb +1 -1
  53. data/lib/rubocop/cop/internal_affairs/on_send_without_on_csend.rb +90 -0
  54. data/lib/rubocop/cop/internal_affairs/operator_keyword.rb +48 -0
  55. data/lib/rubocop/cop/internal_affairs/plugin.rb +33 -0
  56. data/lib/rubocop/cop/internal_affairs/redundant_described_class_as_subject.rb +6 -5
  57. data/lib/rubocop/cop/internal_affairs/redundant_source_range.rb +3 -1
  58. data/lib/rubocop/cop/internal_affairs/single_line_comparison.rb +5 -4
  59. data/lib/rubocop/cop/internal_affairs/style_detected_api_use.rb +0 -2
  60. data/lib/rubocop/cop/internal_affairs/undefined_config.rb +13 -2
  61. data/lib/rubocop/cop/internal_affairs.rb +7 -16
  62. data/lib/rubocop/cop/layout/access_modifier_indentation.rb +1 -1
  63. data/lib/rubocop/cop/layout/argument_alignment.rb +2 -9
  64. data/lib/rubocop/cop/layout/array_alignment.rb +1 -1
  65. data/lib/rubocop/cop/layout/begin_end_alignment.rb +0 -1
  66. data/lib/rubocop/cop/layout/block_alignment.rb +3 -2
  67. data/lib/rubocop/cop/layout/block_end_newline.rb +1 -0
  68. data/lib/rubocop/cop/layout/class_structure.rb +44 -9
  69. data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +5 -5
  70. data/lib/rubocop/cop/layout/def_end_alignment.rb +1 -1
  71. data/lib/rubocop/cop/layout/dot_position.rb +1 -1
  72. data/lib/rubocop/cop/layout/else_alignment.rb +2 -2
  73. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +3 -3
  74. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +7 -11
  75. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +37 -7
  76. data/lib/rubocop/cop/layout/empty_lines_around_begin_body.rb +5 -6
  77. data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +1 -0
  78. data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +4 -5
  79. data/lib/rubocop/cop/layout/empty_lines_around_method_body.rb +23 -1
  80. data/lib/rubocop/cop/layout/end_alignment.rb +1 -1
  81. data/lib/rubocop/cop/layout/extra_spacing.rb +1 -1
  82. data/lib/rubocop/cop/layout/first_argument_indentation.rb +4 -9
  83. data/lib/rubocop/cop/layout/first_array_element_indentation.rb +2 -7
  84. data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +2 -7
  85. data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +1 -1
  86. data/lib/rubocop/cop/layout/first_parameter_indentation.rb +2 -2
  87. data/lib/rubocop/cop/layout/hash_alignment.rb +8 -6
  88. data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +2 -1
  89. data/lib/rubocop/cop/layout/indentation_width.rb +8 -7
  90. data/lib/rubocop/cop/layout/leading_comment_space.rb +57 -2
  91. data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +11 -2
  92. data/lib/rubocop/cop/layout/line_continuation_spacing.rb +7 -1
  93. data/lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb +2 -2
  94. data/lib/rubocop/cop/layout/line_length.rb +149 -9
  95. data/lib/rubocop/cop/layout/multiline_block_layout.rb +1 -0
  96. data/lib/rubocop/cop/layout/multiline_hash_key_line_breaks.rb +1 -1
  97. data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +25 -0
  98. data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +2 -1
  99. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +4 -4
  100. data/lib/rubocop/cop/layout/multiline_method_definition_brace_layout.rb +1 -1
  101. data/lib/rubocop/cop/layout/multiline_method_parameter_line_breaks.rb +1 -0
  102. data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +3 -4
  103. data/lib/rubocop/cop/layout/parameter_alignment.rb +3 -4
  104. data/lib/rubocop/cop/layout/redundant_line_break.rb +19 -46
  105. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +6 -7
  106. data/lib/rubocop/cop/layout/single_line_block_chain.rb +1 -1
  107. data/lib/rubocop/cop/layout/space_after_colon.rb +2 -2
  108. data/lib/rubocop/cop/layout/space_after_comma.rb +1 -1
  109. data/lib/rubocop/cop/layout/space_after_method_name.rb +1 -1
  110. data/lib/rubocop/cop/layout/space_after_semicolon.rb +11 -1
  111. data/lib/rubocop/cop/layout/space_around_keyword.rb +2 -1
  112. data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +1 -1
  113. data/lib/rubocop/cop/layout/space_around_operators.rb +23 -21
  114. data/lib/rubocop/cop/layout/space_before_block_braces.rb +1 -0
  115. data/lib/rubocop/cop/layout/space_before_brackets.rb +7 -40
  116. data/lib/rubocop/cop/layout/space_before_comma.rb +1 -1
  117. data/lib/rubocop/cop/layout/space_before_semicolon.rb +1 -1
  118. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +18 -3
  119. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +5 -0
  120. data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +7 -0
  121. data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +0 -1
  122. data/lib/rubocop/cop/layout/trailing_whitespace.rb +5 -3
  123. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +1 -1
  124. data/lib/rubocop/cop/lint/ambiguous_range.rb +5 -0
  125. data/lib/rubocop/cop/lint/array_literal_in_regexp.rb +118 -0
  126. data/lib/rubocop/cop/lint/assignment_in_condition.rb +1 -3
  127. data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +10 -12
  128. data/lib/rubocop/cop/lint/boolean_symbol.rb +1 -1
  129. data/lib/rubocop/cop/lint/circular_argument_reference.rb +4 -1
  130. data/lib/rubocop/cop/lint/constant_definition_in_block.rb +3 -3
  131. data/lib/rubocop/cop/lint/constant_reassignment.rb +148 -0
  132. data/lib/rubocop/cop/lint/cop_directive_syntax.rb +84 -0
  133. data/lib/rubocop/cop/lint/debugger.rb +3 -3
  134. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +1 -1
  135. data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +3 -2
  136. data/lib/rubocop/cop/lint/duplicate_branch.rb +39 -4
  137. data/lib/rubocop/cop/lint/duplicate_match_pattern.rb +1 -1
  138. data/lib/rubocop/cop/lint/duplicate_methods.rb +86 -19
  139. data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +1 -1
  140. data/lib/rubocop/cop/lint/duplicate_set_element.rb +20 -7
  141. data/lib/rubocop/cop/lint/empty_conditional_body.rb +14 -64
  142. data/lib/rubocop/cop/lint/empty_ensure.rb +1 -1
  143. data/lib/rubocop/cop/lint/empty_expression.rb +0 -2
  144. data/lib/rubocop/cop/lint/empty_file.rb +0 -2
  145. data/lib/rubocop/cop/lint/empty_interpolation.rb +3 -1
  146. data/lib/rubocop/cop/lint/ensure_return.rb +1 -1
  147. data/lib/rubocop/cop/lint/erb_new_arguments.rb +0 -6
  148. data/lib/rubocop/cop/lint/float_comparison.rb +51 -18
  149. data/lib/rubocop/cop/lint/float_out_of_range.rb +2 -4
  150. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +2 -2
  151. data/lib/rubocop/cop/lint/hash_new_with_keyword_arguments_as_default.rb +55 -0
  152. data/lib/rubocop/cop/lint/identity_comparison.rb +19 -15
  153. data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +1 -1
  154. data/lib/rubocop/cop/lint/interpolation_check.rb +9 -0
  155. data/lib/rubocop/cop/lint/it_without_arguments_in_block.rb +3 -0
  156. data/lib/rubocop/cop/lint/literal_as_condition.rb +110 -9
  157. data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +1 -1
  158. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +24 -6
  159. data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +1 -1
  160. data/lib/rubocop/cop/lint/missing_super.rb +2 -2
  161. data/lib/rubocop/cop/lint/mixed_case_range.rb +5 -8
  162. data/lib/rubocop/cop/lint/mixed_regexp_capture_types.rb +1 -1
  163. data/lib/rubocop/cop/lint/nested_method_definition.rb +10 -6
  164. data/lib/rubocop/cop/lint/next_without_accumulator.rb +1 -1
  165. data/lib/rubocop/cop/lint/no_return_in_begin_end_blocks.rb +2 -2
  166. data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +12 -3
  167. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +3 -3
  168. data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +3 -3
  169. data/lib/rubocop/cop/lint/number_conversion.rb +0 -1
  170. data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +1 -2
  171. data/lib/rubocop/cop/lint/numeric_operation_with_constant_result.rb +93 -0
  172. data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +2 -3
  173. data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +3 -2
  174. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +1 -5
  175. data/lib/rubocop/cop/lint/raise_exception.rb +29 -10
  176. data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +1 -1
  177. data/lib/rubocop/cop/lint/redundant_regexp_quantifiers.rb +2 -2
  178. data/lib/rubocop/cop/lint/redundant_require_statement.rb +0 -21
  179. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +12 -7
  180. data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +8 -7
  181. data/lib/rubocop/cop/lint/redundant_string_coercion.rb +2 -2
  182. data/lib/rubocop/cop/lint/redundant_type_conversion.rb +261 -0
  183. data/lib/rubocop/cop/lint/redundant_with_index.rb +3 -0
  184. data/lib/rubocop/cop/lint/redundant_with_object.rb +3 -0
  185. data/lib/rubocop/cop/lint/refinement_import_methods.rb +1 -1
  186. data/lib/rubocop/cop/lint/regexp_as_condition.rb +0 -1
  187. data/lib/rubocop/cop/lint/rescue_exception.rb +1 -1
  188. data/lib/rubocop/cop/lint/rescue_type.rb +3 -7
  189. data/lib/rubocop/cop/lint/return_in_void_context.rb +9 -11
  190. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +17 -1
  191. data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +5 -1
  192. data/lib/rubocop/cop/lint/self_assignment.rb +33 -10
  193. data/lib/rubocop/cop/lint/shadowed_exception.rb +1 -1
  194. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +13 -1
  195. data/lib/rubocop/cop/lint/shared_mutable_default.rb +76 -0
  196. data/lib/rubocop/cop/lint/suppressed_exception.rb +1 -1
  197. data/lib/rubocop/cop/lint/suppressed_exception_in_number_conversion.rb +111 -0
  198. data/lib/rubocop/cop/lint/symbol_conversion.rb +1 -1
  199. data/lib/rubocop/cop/lint/syntax.rb +4 -1
  200. data/lib/rubocop/cop/lint/to_enum_arguments.rb +1 -1
  201. data/lib/rubocop/cop/lint/top_level_return_with_argument.rb +1 -1
  202. data/lib/rubocop/cop/lint/unescaped_bracket_in_regexp.rb +88 -0
  203. data/lib/rubocop/cop/lint/unexpected_block_arity.rb +3 -1
  204. data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +1 -1
  205. data/lib/rubocop/cop/lint/unreachable_code.rb +52 -2
  206. data/lib/rubocop/cop/lint/unreachable_loop.rb +6 -6
  207. data/lib/rubocop/cop/lint/unused_method_argument.rb +18 -2
  208. data/lib/rubocop/cop/lint/useless_access_modifier.rb +34 -8
  209. data/lib/rubocop/cop/lint/useless_assignment.rb +3 -1
  210. data/lib/rubocop/cop/lint/useless_constant_scoping.rb +71 -0
  211. data/lib/rubocop/cop/lint/useless_default_value_argument.rb +90 -0
  212. data/lib/rubocop/cop/lint/useless_defined.rb +55 -0
  213. data/lib/rubocop/cop/lint/useless_else_without_rescue.rb +4 -0
  214. data/lib/rubocop/cop/lint/useless_method_definition.rb +1 -1
  215. data/lib/rubocop/cop/lint/useless_numeric_operation.rb +2 -1
  216. data/lib/rubocop/cop/lint/useless_or.rb +98 -0
  217. data/lib/rubocop/cop/lint/useless_rescue.rb +2 -2
  218. data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +5 -5
  219. data/lib/rubocop/cop/lint/useless_setter_call.rb +14 -25
  220. data/lib/rubocop/cop/lint/void.rb +16 -12
  221. data/lib/rubocop/cop/message_annotator.rb +7 -3
  222. data/lib/rubocop/cop/metrics/abc_size.rb +1 -1
  223. data/lib/rubocop/cop/metrics/block_length.rb +1 -0
  224. data/lib/rubocop/cop/metrics/block_nesting.rb +1 -1
  225. data/lib/rubocop/cop/metrics/class_length.rb +9 -9
  226. data/lib/rubocop/cop/metrics/collection_literal_length.rb +7 -0
  227. data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +5 -2
  228. data/lib/rubocop/cop/metrics/method_length.rb +9 -1
  229. data/lib/rubocop/cop/metrics/module_length.rb +1 -1
  230. data/lib/rubocop/cop/metrics/perceived_complexity.rb +1 -1
  231. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +1 -1
  232. data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +3 -4
  233. data/lib/rubocop/cop/metrics/utils/repeated_attribute_discount.rb +7 -7
  234. data/lib/rubocop/cop/mixin/alignment.rb +3 -3
  235. data/lib/rubocop/cop/mixin/allowed_pattern.rb +4 -4
  236. data/lib/rubocop/cop/mixin/check_assignment.rb +4 -12
  237. data/lib/rubocop/cop/mixin/check_line_breakable.rb +22 -12
  238. data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +49 -0
  239. data/lib/rubocop/cop/mixin/comments_help.rb +8 -3
  240. data/lib/rubocop/cop/mixin/def_node.rb +1 -1
  241. data/lib/rubocop/cop/mixin/dig_help.rb +27 -0
  242. data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +1 -1
  243. data/lib/rubocop/cop/mixin/endless_method_rewriter.rb +24 -0
  244. data/lib/rubocop/cop/mixin/forbidden_identifiers.rb +20 -0
  245. data/lib/rubocop/cop/mixin/forbidden_pattern.rb +16 -0
  246. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +4 -3
  247. data/lib/rubocop/cop/mixin/gemspec_help.rb +22 -0
  248. data/lib/rubocop/cop/mixin/hash_alignment_styles.rb +15 -14
  249. data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +22 -22
  250. data/lib/rubocop/cop/mixin/hash_subset.rb +203 -0
  251. data/lib/rubocop/cop/mixin/hash_transform_method.rb +74 -74
  252. data/lib/rubocop/cop/mixin/line_length_help.rb +27 -10
  253. data/lib/rubocop/cop/mixin/method_complexity.rb +2 -1
  254. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +7 -9
  255. data/lib/rubocop/cop/mixin/ordered_gem_node.rb +1 -1
  256. data/lib/rubocop/cop/mixin/percent_literal.rb +1 -1
  257. data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +68 -30
  258. data/lib/rubocop/cop/mixin/range_help.rb +15 -4
  259. data/lib/rubocop/cop/mixin/space_before_punctuation.rb +1 -1
  260. data/lib/rubocop/cop/mixin/statement_modifier.rb +8 -3
  261. data/lib/rubocop/cop/mixin/string_help.rb +2 -2
  262. data/lib/rubocop/cop/mixin/string_literals_help.rb +1 -1
  263. data/lib/rubocop/cop/mixin/target_ruby_version.rb +17 -1
  264. data/lib/rubocop/cop/mixin/trailing_comma.rb +21 -5
  265. data/lib/rubocop/cop/naming/accessor_method_name.rb +6 -6
  266. data/lib/rubocop/cop/naming/block_forwarding.rb +20 -16
  267. data/lib/rubocop/cop/naming/constant_name.rb +6 -7
  268. data/lib/rubocop/cop/naming/file_name.rb +2 -4
  269. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +12 -13
  270. data/lib/rubocop/cop/naming/method_name.rb +64 -8
  271. data/lib/rubocop/cop/naming/predicate_method.rb +281 -0
  272. data/lib/rubocop/cop/naming/{predicate_name.rb → predicate_prefix.rb} +48 -4
  273. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +6 -14
  274. data/lib/rubocop/cop/naming/variable_name.rb +50 -6
  275. data/lib/rubocop/cop/naming/variable_number.rb +2 -3
  276. data/lib/rubocop/cop/offense.rb +2 -3
  277. data/lib/rubocop/cop/registry.rb +9 -6
  278. data/lib/rubocop/cop/security/compound_hash.rb +2 -0
  279. data/lib/rubocop/cop/security/yaml_load.rb +3 -2
  280. data/lib/rubocop/cop/style/access_modifier_declarations.rb +114 -34
  281. data/lib/rubocop/cop/style/accessor_grouping.rb +19 -5
  282. data/lib/rubocop/cop/style/ambiguous_endless_method_definition.rb +79 -0
  283. data/lib/rubocop/cop/style/and_or.rb +1 -1
  284. data/lib/rubocop/cop/style/arguments_forwarding.rb +47 -28
  285. data/lib/rubocop/cop/style/array_first_last.rb +18 -2
  286. data/lib/rubocop/cop/style/array_intersect.rb +42 -30
  287. data/lib/rubocop/cop/style/bitwise_predicate.rb +100 -0
  288. data/lib/rubocop/cop/style/block_delimiters.rb +43 -25
  289. data/lib/rubocop/cop/style/case_like_if.rb +9 -12
  290. data/lib/rubocop/cop/style/class_and_module_children.rb +52 -11
  291. data/lib/rubocop/cop/style/class_equality_comparison.rb +1 -1
  292. data/lib/rubocop/cop/style/collection_methods.rb +2 -1
  293. data/lib/rubocop/cop/style/collection_querying.rb +167 -0
  294. data/lib/rubocop/cop/style/combinable_defined.rb +115 -0
  295. data/lib/rubocop/cop/style/combinable_loops.rb +3 -2
  296. data/lib/rubocop/cop/style/command_literal.rb +1 -1
  297. data/lib/rubocop/cop/style/commented_keyword.rb +20 -3
  298. data/lib/rubocop/cop/style/comparable_between.rb +78 -0
  299. data/lib/rubocop/cop/style/concat_array_literals.rb +1 -1
  300. data/lib/rubocop/cop/style/conditional_assignment.rb +41 -27
  301. data/lib/rubocop/cop/style/constant_visibility.rb +3 -12
  302. data/lib/rubocop/cop/style/data_inheritance.rb +7 -0
  303. data/lib/rubocop/cop/style/def_with_parentheses.rb +18 -5
  304. data/lib/rubocop/cop/style/dig_chain.rb +89 -0
  305. data/lib/rubocop/cop/style/documentation.rb +1 -1
  306. data/lib/rubocop/cop/style/double_negation.rb +4 -4
  307. data/lib/rubocop/cop/style/each_for_simple_loop.rb +4 -7
  308. data/lib/rubocop/cop/style/each_with_object.rb +2 -3
  309. data/lib/rubocop/cop/style/empty_else.rb +4 -2
  310. data/lib/rubocop/cop/style/empty_literal.rb +5 -1
  311. data/lib/rubocop/cop/style/empty_method.rb +1 -1
  312. data/lib/rubocop/cop/style/empty_string_inside_interpolation.rb +100 -0
  313. data/lib/rubocop/cop/style/endless_method.rb +150 -18
  314. data/lib/rubocop/cop/style/eval_with_location.rb +4 -4
  315. data/lib/rubocop/cop/style/exact_regexp_match.rb +2 -3
  316. data/lib/rubocop/cop/style/expand_path_arguments.rb +2 -7
  317. data/lib/rubocop/cop/style/explicit_block_argument.rb +16 -3
  318. data/lib/rubocop/cop/style/exponential_notation.rb +5 -5
  319. data/lib/rubocop/cop/style/fetch_env_var.rb +34 -7
  320. data/lib/rubocop/cop/style/file_null.rb +89 -0
  321. data/lib/rubocop/cop/style/file_touch.rb +75 -0
  322. data/lib/rubocop/cop/style/float_division.rb +8 -4
  323. data/lib/rubocop/cop/style/for.rb +1 -1
  324. data/lib/rubocop/cop/style/format_string_token.rb +38 -11
  325. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +3 -2
  326. data/lib/rubocop/cop/style/global_std_stream.rb +3 -0
  327. data/lib/rubocop/cop/style/global_vars.rb +1 -3
  328. data/lib/rubocop/cop/style/guard_clause.rb +17 -3
  329. data/lib/rubocop/cop/style/hash_conversion.rb +12 -4
  330. data/lib/rubocop/cop/style/hash_each_methods.rb +6 -8
  331. data/lib/rubocop/cop/style/hash_except.rb +35 -147
  332. data/lib/rubocop/cop/style/hash_fetch_chain.rb +104 -0
  333. data/lib/rubocop/cop/style/hash_slice.rb +80 -0
  334. data/lib/rubocop/cop/style/hash_syntax.rb +9 -3
  335. data/lib/rubocop/cop/style/hash_transform_keys.rb +2 -2
  336. data/lib/rubocop/cop/style/hash_transform_values.rb +2 -2
  337. data/lib/rubocop/cop/style/identical_conditional_branches.rb +25 -6
  338. data/lib/rubocop/cop/style/if_inside_else.rb +10 -14
  339. data/lib/rubocop/cop/style/if_unless_modifier.rb +36 -9
  340. data/lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb +4 -7
  341. data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +3 -4
  342. data/lib/rubocop/cop/style/if_with_semicolon.rb +20 -9
  343. data/lib/rubocop/cop/style/infinite_loop.rb +1 -1
  344. data/lib/rubocop/cop/style/inverse_methods.rb +15 -12
  345. data/lib/rubocop/cop/style/invertible_unless_condition.rb +2 -2
  346. data/lib/rubocop/cop/style/ip_addresses.rb +2 -2
  347. data/lib/rubocop/cop/style/it_assignment.rb +36 -0
  348. data/lib/rubocop/cop/style/it_block_parameter.rb +119 -0
  349. data/lib/rubocop/cop/style/keyword_arguments_merging.rb +67 -0
  350. data/lib/rubocop/cop/style/keyword_parameters_order.rb +14 -8
  351. data/lib/rubocop/cop/style/lambda.rb +1 -0
  352. data/lib/rubocop/cop/style/lambda_call.rb +10 -4
  353. data/lib/rubocop/cop/style/line_end_concatenation.rb +10 -4
  354. data/lib/rubocop/cop/style/map_into_array.rb +11 -3
  355. data/lib/rubocop/cop/style/map_to_hash.rb +12 -1
  356. data/lib/rubocop/cop/style/map_to_set.rb +3 -2
  357. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +28 -18
  358. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +2 -0
  359. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +8 -11
  360. data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +3 -4
  361. data/lib/rubocop/cop/style/method_def_parentheses.rb +1 -1
  362. data/lib/rubocop/cop/style/min_max_comparison.rb +13 -5
  363. data/lib/rubocop/cop/style/missing_else.rb +2 -0
  364. data/lib/rubocop/cop/style/missing_respond_to_missing.rb +33 -3
  365. data/lib/rubocop/cop/style/multiline_block_chain.rb +3 -2
  366. data/lib/rubocop/cop/style/multiline_if_modifier.rb +2 -0
  367. data/lib/rubocop/cop/style/multiline_memoization.rb +1 -1
  368. data/lib/rubocop/cop/style/multiline_method_signature.rb +1 -9
  369. data/lib/rubocop/cop/style/multiple_comparison.rb +52 -51
  370. data/lib/rubocop/cop/style/mutable_constant.rb +7 -8
  371. data/lib/rubocop/cop/style/negated_if_else_condition.rb +7 -5
  372. data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +1 -1
  373. data/lib/rubocop/cop/style/nested_ternary_operator.rb +5 -4
  374. data/lib/rubocop/cop/style/next.rb +44 -0
  375. data/lib/rubocop/cop/style/not.rb +1 -1
  376. data/lib/rubocop/cop/style/object_then.rb +15 -15
  377. data/lib/rubocop/cop/style/one_line_conditional.rb +25 -4
  378. data/lib/rubocop/cop/style/open_struct_use.rb +5 -5
  379. data/lib/rubocop/cop/style/operator_method_call.rb +5 -6
  380. data/lib/rubocop/cop/style/or_assignment.rb +3 -6
  381. data/lib/rubocop/cop/style/parallel_assignment.rb +9 -18
  382. data/lib/rubocop/cop/style/parentheses_around_condition.rb +2 -2
  383. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +1 -1
  384. data/lib/rubocop/cop/style/percent_q_literals.rb +1 -1
  385. data/lib/rubocop/cop/style/proc.rb +2 -2
  386. data/lib/rubocop/cop/style/quoted_symbols.rb +1 -1
  387. data/lib/rubocop/cop/style/raise_args.rb +15 -13
  388. data/lib/rubocop/cop/style/random_with_offset.rb +3 -3
  389. data/lib/rubocop/cop/style/redundant_argument.rb +3 -1
  390. data/lib/rubocop/cop/style/redundant_array_flatten.rb +50 -0
  391. data/lib/rubocop/cop/style/redundant_assignment.rb +1 -1
  392. data/lib/rubocop/cop/style/redundant_begin.rb +2 -1
  393. data/lib/rubocop/cop/style/redundant_condition.rb +95 -23
  394. data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +16 -5
  395. data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +6 -10
  396. data/lib/rubocop/cop/style/redundant_each.rb +1 -1
  397. data/lib/rubocop/cop/style/redundant_exception.rb +2 -2
  398. data/lib/rubocop/cop/style/redundant_format.rb +262 -0
  399. data/lib/rubocop/cop/style/redundant_freeze.rb +3 -3
  400. data/lib/rubocop/cop/style/redundant_initialize.rb +12 -3
  401. data/lib/rubocop/cop/style/redundant_interpolation.rb +1 -1
  402. data/lib/rubocop/cop/style/redundant_line_continuation.rb +54 -18
  403. data/lib/rubocop/cop/style/redundant_parentheses.rb +77 -26
  404. data/lib/rubocop/cop/style/redundant_regexp_argument.rb +4 -0
  405. data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +1 -1
  406. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +1 -1
  407. data/lib/rubocop/cop/style/redundant_return.rb +2 -2
  408. data/lib/rubocop/cop/style/redundant_self.rb +15 -18
  409. data/lib/rubocop/cop/style/redundant_self_assignment.rb +20 -32
  410. data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +4 -4
  411. data/lib/rubocop/cop/style/redundant_sort.rb +3 -3
  412. data/lib/rubocop/cop/style/redundant_sort_by.rb +17 -1
  413. data/lib/rubocop/cop/style/redundant_string_escape.rb +2 -2
  414. data/lib/rubocop/cop/style/regexp_literal.rb +1 -1
  415. data/lib/rubocop/cop/style/rescue_modifier.rb +5 -3
  416. data/lib/rubocop/cop/style/return_nil.rb +2 -2
  417. data/lib/rubocop/cop/style/safe_navigation.rb +56 -16
  418. data/lib/rubocop/cop/style/safe_navigation_chain_length.rb +52 -0
  419. data/lib/rubocop/cop/style/select_by_regexp.rb +5 -2
  420. data/lib/rubocop/cop/style/self_assignment.rb +11 -17
  421. data/lib/rubocop/cop/style/semicolon.rb +1 -1
  422. data/lib/rubocop/cop/style/send_with_literal_method_name.rb +2 -1
  423. data/lib/rubocop/cop/style/signal_exception.rb +2 -3
  424. data/lib/rubocop/cop/style/single_argument_dig.rb +9 -5
  425. data/lib/rubocop/cop/style/single_line_block_params.rb +1 -1
  426. data/lib/rubocop/cop/style/single_line_do_end_block.rb +15 -4
  427. data/lib/rubocop/cop/style/single_line_methods.rb +6 -7
  428. data/lib/rubocop/cop/style/slicing_with_range.rb +40 -11
  429. data/lib/rubocop/cop/style/sole_nested_conditional.rb +43 -106
  430. data/lib/rubocop/cop/style/special_global_vars.rb +1 -1
  431. data/lib/rubocop/cop/style/string_concatenation.rb +15 -15
  432. data/lib/rubocop/cop/style/string_literals.rb +1 -1
  433. data/lib/rubocop/cop/style/string_methods.rb +1 -1
  434. data/lib/rubocop/cop/style/struct_inheritance.rb +8 -1
  435. data/lib/rubocop/cop/style/super_arguments.rb +66 -19
  436. data/lib/rubocop/cop/style/swap_values.rb +4 -15
  437. data/lib/rubocop/cop/style/symbol_proc.rb +3 -1
  438. data/lib/rubocop/cop/style/ternary_parentheses.rb +25 -4
  439. data/lib/rubocop/cop/style/top_level_method_definition.rb +2 -1
  440. data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +11 -2
  441. data/lib/rubocop/cop/style/trailing_comma_in_array_literal.rb +47 -6
  442. data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +1 -1
  443. data/lib/rubocop/cop/style/trailing_comma_in_hash_literal.rb +48 -6
  444. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +4 -4
  445. data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
  446. data/lib/rubocop/cop/style/variable_interpolation.rb +1 -2
  447. data/lib/rubocop/cop/style/while_until_modifier.rb +0 -1
  448. data/lib/rubocop/cop/style/yoda_condition.rb +8 -4
  449. data/lib/rubocop/cop/style/yoda_expression.rb +2 -1
  450. data/lib/rubocop/cop/team.rb +1 -1
  451. data/lib/rubocop/cop/util.rb +12 -5
  452. data/lib/rubocop/cop/utils/format_string.rb +10 -5
  453. data/lib/rubocop/cop/variable_force/assignment.rb +24 -5
  454. data/lib/rubocop/cop/variable_force/branch.rb +1 -1
  455. data/lib/rubocop/cop/variable_force/scope.rb +1 -1
  456. data/lib/rubocop/cop/variable_force/variable.rb +14 -3
  457. data/lib/rubocop/cop/variable_force/variable_table.rb +5 -5
  458. data/lib/rubocop/cop/variable_force.rb +5 -11
  459. data/lib/rubocop/cops_documentation_generator.rb +50 -25
  460. data/lib/rubocop/directive_comment.rb +45 -11
  461. data/lib/rubocop/ext/regexp_node.rb +0 -1
  462. data/lib/rubocop/formatter/disabled_config_formatter.rb +3 -2
  463. data/lib/rubocop/formatter/formatter_set.rb +1 -1
  464. data/lib/rubocop/formatter/fuubar_style_formatter.rb +1 -1
  465. data/lib/rubocop/formatter/html_formatter.rb +1 -1
  466. data/lib/rubocop/formatter/offense_count_formatter.rb +1 -1
  467. data/lib/rubocop/formatter/pacman_formatter.rb +1 -1
  468. data/lib/rubocop/lsp/diagnostic.rb +189 -0
  469. data/lib/rubocop/lsp/logger.rb +2 -2
  470. data/lib/rubocop/lsp/routes.rb +7 -23
  471. data/lib/rubocop/lsp/runtime.rb +18 -50
  472. data/lib/rubocop/lsp/server.rb +0 -2
  473. data/lib/rubocop/lsp/stdin_runner.rb +85 -0
  474. data/lib/rubocop/magic_comment.rb +11 -3
  475. data/lib/rubocop/options.rb +28 -12
  476. data/lib/rubocop/path_util.rb +15 -8
  477. data/lib/rubocop/plugin/configuration_integrator.rb +143 -0
  478. data/lib/rubocop/plugin/load_error.rb +26 -0
  479. data/lib/rubocop/plugin/loader.rb +100 -0
  480. data/lib/rubocop/plugin/not_supported_error.rb +29 -0
  481. data/lib/rubocop/plugin.rb +46 -0
  482. data/lib/rubocop/rake_task.rb +4 -1
  483. data/lib/rubocop/result_cache.rb +13 -13
  484. data/lib/rubocop/rspec/cop_helper.rb +13 -1
  485. data/lib/rubocop/rspec/expect_offense.rb +15 -5
  486. data/lib/rubocop/rspec/shared_contexts.rb +38 -1
  487. data/lib/rubocop/rspec/support.rb +4 -2
  488. data/lib/rubocop/runner.rb +26 -15
  489. data/lib/rubocop/server/cache.rb +47 -11
  490. data/lib/rubocop/server/cli.rb +2 -2
  491. data/lib/rubocop/target_finder.rb +7 -2
  492. data/lib/rubocop/target_ruby.rb +17 -2
  493. data/lib/rubocop/version.rb +53 -12
  494. data/lib/rubocop.rb +40 -2
  495. data/lib/ruby_lsp/rubocop/addon.rb +75 -0
  496. data/lib/ruby_lsp/rubocop/runtime_adapter.rb +65 -0
  497. metadata +87 -21
  498. data/lib/rubocop/cop/utils/regexp_ranges.rb +0 -113
  499. data/lib/rubocop/rspec/host_environment_simulation_helper.rb +0 -28
@@ -4,6 +4,7 @@ module RuboCop
4
4
  module Cop
5
5
  module Style
6
6
  # Checks for inheritance from `Data.define` to avoid creating the anonymous parent class.
7
+ # Inheriting from `Data.define` adds a superfluous level in inheritance tree.
7
8
  #
8
9
  # @safety
9
10
  # Autocorrection is unsafe because it will change the inheritance
@@ -17,12 +18,18 @@ module RuboCop
17
18
  # end
18
19
  # end
19
20
  #
21
+ # Person.ancestors
22
+ # # => [Person, #<Class:0x000000010b4e14a0>, Data, (...)]
23
+ #
20
24
  # # good
21
25
  # Person = Data.define(:first_name, :last_name) do
22
26
  # def age
23
27
  # 42
24
28
  # end
25
29
  # end
30
+ #
31
+ # Person.ancestors
32
+ # # => [Person, Data, (...)]
26
33
  class DataInheritance < Base
27
34
  include RangeHelp
28
35
  extend AutoCorrector
@@ -25,8 +25,9 @@ module RuboCop
25
25
  # # good
26
26
  # def foo = do_something
27
27
  #
28
- # # good (without parentheses it's a syntax error)
28
+ # # good - without parentheses it's a syntax error
29
29
  # def foo() do_something end
30
+ # def foo()=do_something
30
31
  #
31
32
  # # bad
32
33
  # def Baz.foo()
@@ -38,19 +39,31 @@ module RuboCop
38
39
  # do_something
39
40
  # end
40
41
  class DefWithParentheses < Base
42
+ include RangeHelp
41
43
  extend AutoCorrector
42
44
 
43
45
  MSG = "Omit the parentheses in defs when the method doesn't accept any arguments."
44
46
 
45
47
  def on_def(node)
46
- return if node.single_line? && !node.endless?
47
- return unless !node.arguments? && (node_arguments = node.arguments.source_range)
48
+ return unless !node.arguments? && (arguments_range = node.arguments.source_range)
49
+ return if parentheses_required?(node, arguments_range)
48
50
 
49
- add_offense(node_arguments) do |corrector|
50
- corrector.remove(node_arguments)
51
+ add_offense(arguments_range) do |corrector|
52
+ corrector.remove(arguments_range)
51
53
  end
52
54
  end
53
55
  alias on_defs on_def
56
+
57
+ private
58
+
59
+ def parentheses_required?(node, arguments_range)
60
+ return true if node.single_line? && !node.endless?
61
+
62
+ end_pos = arguments_range.end.end_pos
63
+ token_after_argument = range_between(end_pos, end_pos + 1).source
64
+
65
+ token_after_argument == '='
66
+ end
54
67
  end
55
68
  end
56
69
  end
@@ -0,0 +1,89 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Style
6
+ # Check for chained `dig` calls that can be collapsed into a single `dig`.
7
+ #
8
+ # @safety
9
+ # This cop is unsafe because it cannot be guaranteed that the receiver
10
+ # is an `Enumerable` or does not have a nonstandard implementation
11
+ # of `dig`.
12
+ #
13
+ # @example
14
+ # # bad
15
+ # x.dig(:foo).dig(:bar).dig(:baz)
16
+ # x.dig(:foo, :bar).dig(:baz)
17
+ # x.dig(:foo, :bar)&.dig(:baz)
18
+ #
19
+ # # good
20
+ # x.dig(:foo, :bar, :baz)
21
+ #
22
+ # # good - `dig`s cannot be combined
23
+ # x.dig(:foo).bar.dig(:baz)
24
+ #
25
+ class DigChain < Base
26
+ extend AutoCorrector
27
+ include CommentsHelp
28
+ include DigHelp
29
+
30
+ MSG = 'Use `%<replacement>s` instead of chaining.'
31
+ RESTRICT_ON_SEND = %i[dig].freeze
32
+
33
+ def on_send(node)
34
+ return if ignored_node?(node)
35
+ return unless node.loc.dot
36
+ return unless dig?(node)
37
+
38
+ range, arguments = inspect_chain(node)
39
+ return if invalid_arguments?(arguments)
40
+ return unless range
41
+
42
+ register_offense(node, range, arguments)
43
+ end
44
+ alias on_csend on_send
45
+
46
+ private
47
+
48
+ # Walk up the method chain while the receiver is `dig` with arguments.
49
+ def inspect_chain(node)
50
+ arguments = node.arguments.dup
51
+ end_range = node.source_range.end
52
+
53
+ while dig?(node = node.receiver)
54
+ begin_range = node.loc.selector
55
+ arguments.unshift(*node.arguments)
56
+ ignore_node(node)
57
+ end
58
+
59
+ return unless begin_range
60
+
61
+ [begin_range.join(end_range), arguments]
62
+ end
63
+
64
+ def invalid_arguments?(arguments)
65
+ # If any of the arguments are arguments forwarding (`...`), it can only be the
66
+ # first argument, or else the resulting code will have a syntax error.
67
+
68
+ return false unless arguments&.any?
69
+
70
+ forwarded_args_index = arguments.index(&:forwarded_args_type?)
71
+ forwarded_args_index && forwarded_args_index < (arguments.size - 1)
72
+ end
73
+
74
+ def register_offense(node, range, arguments)
75
+ arguments = arguments.map(&:source).join(', ')
76
+ replacement = "dig(#{arguments})"
77
+
78
+ add_offense(range, message: format(MSG, replacement: replacement)) do |corrector|
79
+ corrector.replace(range, replacement)
80
+
81
+ comments_in_range(node).reverse_each do |comment|
82
+ corrector.insert_before(node, "#{comment.source}\n")
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end
89
+ end
@@ -186,7 +186,7 @@ module RuboCop
186
186
  def qualify_const(node)
187
187
  return if node.nil?
188
188
 
189
- if node.cbase_type? || node.self_type? || node.call_type? || node.variable?
189
+ if node.type?(:cbase, :self, :call) || node.variable?
190
190
  node.source
191
191
  else
192
192
  [qualify_const(node.namespace), node.short_name].compact
@@ -93,7 +93,7 @@ module RuboCop
93
93
 
94
94
  if conditional_node
95
95
  double_negative_condition_return_value?(node, last_child, conditional_node)
96
- elsif last_child.pair_type? || last_child.hash_type? || last_child.parent.array_type?
96
+ elsif last_child.type?(:pair, :hash) || last_child.parent.array_type?
97
97
  false
98
98
  else
99
99
  last_child.last_line <= node.last_line
@@ -102,14 +102,14 @@ module RuboCop
102
102
 
103
103
  def find_def_node_from_ascendant(node)
104
104
  return unless (parent = node.parent)
105
- return parent if parent.def_type? || parent.defs_type?
105
+ return parent if parent.any_def_type?
106
106
  return node.parent.child_nodes.first if define_method?(parent)
107
107
 
108
108
  find_def_node_from_ascendant(node.parent)
109
109
  end
110
110
 
111
111
  def define_method?(node)
112
- return false unless node.block_type?
112
+ return false unless node.any_block_type?
113
113
 
114
114
  child = node.child_nodes.first
115
115
  return false unless child.send_type?
@@ -147,7 +147,7 @@ module RuboCop
147
147
  def find_parent_not_enumerable(node)
148
148
  return unless (parent = node.parent)
149
149
 
150
- if parent.pair_type? || parent.hash_type? || parent.array_type?
150
+ if parent.type?(:pair, :hash, :array)
151
151
  find_parent_not_enumerable(parent)
152
152
  else
153
153
  parent
@@ -4,7 +4,7 @@ module RuboCop
4
4
  module Cop
5
5
  module Style
6
6
  # Checks for loops which iterate a constant number of times,
7
- # using a Range literal and `#each`. This can be done more readably using
7
+ # using a `Range` literal and `#each`. This can be done more readably using
8
8
  # `Integer#times`.
9
9
  #
10
10
  # This check only applies if the block takes no parameters.
@@ -53,8 +53,7 @@ module RuboCop
53
53
  (block
54
54
  (call
55
55
  (begin
56
- (${irange erange}
57
- (int $_) (int $_)))
56
+ ($range (int $_) (int $_)))
58
57
  :each)
59
58
  (args ...)
60
59
  ...)
@@ -65,8 +64,7 @@ module RuboCop
65
64
  (block
66
65
  (call
67
66
  (begin
68
- ({irange erange}
69
- (int 0) (int _)))
67
+ (range (int 0) (int _)))
70
68
  :each)
71
69
  (args ...)
72
70
  ...)
@@ -77,8 +75,7 @@ module RuboCop
77
75
  (block
78
76
  (call
79
77
  (begin
80
- ({irange erange}
81
- (int _) (int _)))
78
+ (range (int _) (int _)))
82
79
  :each)
83
80
  (args)
84
81
  ...)
@@ -58,7 +58,7 @@ module RuboCop
58
58
 
59
59
  # @!method each_with_object_block_candidate?(node)
60
60
  def_node_matcher :each_with_object_block_candidate?, <<~PATTERN
61
- (block $(call _ {:inject :reduce} _) $_ $_)
61
+ (block $(call _ {:inject :reduce} _) $(args _ _) $_)
62
62
  PATTERN
63
63
 
64
64
  # @!method each_with_object_numblock_candidate?(node)
@@ -71,8 +71,7 @@ module RuboCop
71
71
 
72
72
  first_arg, second_arg = *node.arguments
73
73
 
74
- corrector.replace(first_arg, second_arg.source)
75
- corrector.replace(second_arg, first_arg.source)
74
+ corrector.swap(first_arg, second_arg)
76
75
 
77
76
  if return_value_occupies_whole_line?(return_value)
78
77
  corrector.remove(whole_line_expression(return_value))
@@ -131,6 +131,8 @@ module RuboCop
131
131
  extend AutoCorrector
132
132
 
133
133
  MSG = 'Redundant `else`-clause.'
134
+ NIL_STYLES = %i[nil both].freeze
135
+ EMPTY_STYLES = %i[empty both].freeze
134
136
 
135
137
  def on_normal_if_unless(node)
136
138
  check(node)
@@ -150,11 +152,11 @@ module RuboCop
150
152
  end
151
153
 
152
154
  def nil_style?
153
- style == :nil || style == :both
155
+ NIL_STYLES.include?(style)
154
156
  end
155
157
 
156
158
  def empty_style?
157
- style == :empty || style == :both
159
+ EMPTY_STYLES.include?(style)
158
160
  end
159
161
 
160
162
  def empty_check(node)
@@ -6,6 +6,10 @@ module RuboCop
6
6
  # Checks for the use of a method, the result of which
7
7
  # would be a literal, like an empty array, hash, or string.
8
8
  #
9
+ # NOTE: When frozen string literals are enabled, `String.new`
10
+ # isn't corrected to an empty string since the former is
11
+ # mutable and the latter would be frozen.
12
+ #
9
13
  # @example
10
14
  # # bad
11
15
  # a = Array.new
@@ -136,7 +140,7 @@ module RuboCop
136
140
  def frozen_strings?
137
141
  return true if frozen_string_literals_enabled?
138
142
 
139
- frozen_string_cop_enabled = config.for_cop('Style/FrozenStringLiteralComment')['Enabled']
143
+ frozen_string_cop_enabled = config.cop_enabled?('Style/FrozenStringLiteralComment')
140
144
  frozen_string_cop_enabled &&
141
145
  !frozen_string_literals_disabled? &&
142
146
  string_literals_frozen_by_default?.nil?
@@ -109,7 +109,7 @@ module RuboCop
109
109
  end
110
110
 
111
111
  def max_line_length
112
- return unless config.for_cop('Layout/LineLength')['Enabled']
112
+ return unless config.cop_enabled?('Layout/LineLength')
113
113
 
114
114
  config.for_cop('Layout/LineLength')['Max']
115
115
  end
@@ -0,0 +1,100 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Style
6
+ # Checks for empty strings being assigned inside string interpolation.
7
+ #
8
+ # Empty strings are a meaningless outcome inside of string interpolation, so we remove them.
9
+ # Alternatively, when configured to do so, we prioritise using empty strings.
10
+ #
11
+ # While this cop would also apply to variables that are only going to be used as strings,
12
+ # RuboCop can't detect that, so we only check inside of string interpolation.
13
+ #
14
+ # @example EnforcedStyle: trailing_conditional (default)
15
+ # # bad
16
+ # "#{condition ? 'foo' : ''}"
17
+ #
18
+ # # good
19
+ # "#{'foo' if condition}"
20
+ #
21
+ # # bad
22
+ # "#{condition ? '' : 'foo'}"
23
+ #
24
+ # # good
25
+ # "#{'foo' unless condition}"
26
+ #
27
+ # @example EnforcedStyle: ternary
28
+ # # bad
29
+ # "#{'foo' if condition}"
30
+ #
31
+ # # good
32
+ # "#{condition ? 'foo' : ''}"
33
+ #
34
+ # # bad
35
+ # "#{'foo' unless condition}"
36
+ #
37
+ # # good
38
+ # "#{condition ? '' : 'foo'}"
39
+ #
40
+ class EmptyStringInsideInterpolation < Base
41
+ include ConfigurableEnforcedStyle
42
+ include Interpolation
43
+ extend AutoCorrector
44
+
45
+ MSG_TRAILING_CONDITIONAL = 'Do not use trailing conditionals in string interpolation.'
46
+ MSG_TERNARY = 'Do not return empty strings in string interpolation.'
47
+
48
+ # rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/PerceivedComplexity
49
+ def on_interpolation(node)
50
+ node.each_child_node(:if) do |child_node|
51
+ if style == :trailing_conditional
52
+ if empty_if_outcome?(child_node)
53
+ ternary_style_autocorrect(child_node, child_node.else_branch.source, 'unless')
54
+ end
55
+
56
+ if empty_else_outcome?(child_node)
57
+ ternary_style_autocorrect(child_node, child_node.if_branch.source, 'if')
58
+ end
59
+ elsif style == :ternary
60
+ next unless child_node.modifier_form?
61
+
62
+ ternary_component = if child_node.unless?
63
+ "'' : #{child_node.if_branch.source}"
64
+ else
65
+ "#{child_node.if_branch.source} : ''"
66
+ end
67
+
68
+ add_offense(node, message: MSG_TRAILING_CONDITIONAL) do |corrector|
69
+ corrector.replace(node, "\#{#{child_node.condition.source} ? #{ternary_component}}")
70
+ end
71
+ end
72
+ end
73
+ end
74
+ # rubocop:enable Metrics/AbcSize, Metrics/MethodLength, Metrics/PerceivedComplexity
75
+
76
+ private
77
+
78
+ def empty_if_outcome?(node)
79
+ empty_branch_outcome?(node.if_branch)
80
+ end
81
+
82
+ def empty_else_outcome?(node)
83
+ empty_branch_outcome?(node.else_branch)
84
+ end
85
+
86
+ def empty_branch_outcome?(branch)
87
+ return false unless branch
88
+
89
+ branch.nil_type? || (branch.str_type? && branch.value.empty?)
90
+ end
91
+
92
+ def ternary_style_autocorrect(node, outcome, condition)
93
+ add_offense(node, message: MSG_TERNARY) do |corrector|
94
+ corrector.replace(node, "#{outcome} #{condition} #{node.condition.source}")
95
+ end
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
@@ -5,8 +5,11 @@ module RuboCop
5
5
  module Style
6
6
  # Checks for endless methods.
7
7
  #
8
- # It can enforce either the use of endless methods definitions
9
- # for single-lined method bodies, or disallow endless methods.
8
+ # It can enforce endless method definitions whenever possible or with single line methods.
9
+ # It can also disallow multiline endless method definitions or all endless definitions.
10
+ #
11
+ # `require_single_line` style enforces endless method definitions for single line methods.
12
+ # `require_always` style enforces endless method definitions for single statement methods.
10
13
  #
11
14
  # Other method definition types are not considered by this cop.
12
15
  #
@@ -15,39 +18,120 @@ module RuboCop
15
18
  # * allow_single_line (default) - only single line endless method definitions are allowed.
16
19
  # * allow_always - all endless method definitions are allowed.
17
20
  # * disallow - all endless method definitions are disallowed.
21
+ # * require_single_line - endless method definitions are required for single line methods.
22
+ # * require_always - all endless method definitions are required.
18
23
  #
19
24
  # NOTE: Incorrect endless method definitions will always be
20
25
  # corrected to a multi-line definition.
21
26
  #
22
27
  # @example EnforcedStyle: allow_single_line (default)
28
+ # # bad, multi-line endless method
29
+ # def my_method = x.foo
30
+ # .bar
31
+ # .baz
32
+ #
23
33
  # # good
24
- # def my_method() = x
34
+ # def my_method
35
+ # x
36
+ # end
25
37
  #
26
- # # bad, multi-line endless method
27
- # def my_method() = x.foo
28
- # .bar
29
- # .baz
38
+ # # good
39
+ # def my_method = x
40
+ #
41
+ # # good
42
+ # def my_method
43
+ # x.foo
44
+ # .bar
45
+ # .baz
46
+ # end
30
47
  #
31
48
  # @example EnforcedStyle: allow_always
32
49
  # # good
33
- # def my_method() = x
50
+ # def my_method
51
+ # x
52
+ # end
34
53
  #
35
54
  # # good
36
- # def my_method() = x.foo
37
- # .bar
38
- # .baz
55
+ # def my_method = x
56
+ #
57
+ # # good
58
+ # def my_method = x.foo
59
+ # .bar
60
+ # .baz
61
+ #
62
+ # # good
63
+ # def my_method
64
+ # x.foo
65
+ # .bar
66
+ # .baz
67
+ # end
39
68
  #
40
69
  # @example EnforcedStyle: disallow
41
70
  # # bad
42
- # def my_method() = x
71
+ # def my_method = x
72
+ #
73
+ # # bad
74
+ # def my_method = x.foo
75
+ # .bar
76
+ # .baz
77
+ #
78
+ # # good
79
+ # def my_method
80
+ # x
81
+ # end
82
+ #
83
+ # # good
84
+ # def my_method
85
+ # x.foo
86
+ # .bar
87
+ # .baz
88
+ # end
89
+ #
90
+ # @example EnforcedStyle: require_single_line
91
+ # # bad
92
+ # def my_method
93
+ # x
94
+ # end
95
+ #
96
+ # # bad
97
+ # def my_method = x.foo
98
+ # .bar
99
+ # .baz
100
+ #
101
+ # # good
102
+ # def my_method = x
103
+ #
104
+ # # good
105
+ # def my_method
106
+ # x.foo
107
+ # .bar
108
+ # .baz
109
+ # end
110
+ #
111
+ # @example EnforcedStyle: require_always
112
+ # # bad
113
+ # def my_method
114
+ # x
115
+ # end
43
116
  #
44
117
  # # bad
45
- # def my_method() = x.foo
46
- # .bar
47
- # .baz
118
+ # def my_method
119
+ # x.foo
120
+ # .bar
121
+ # .baz
122
+ # end
123
+ #
124
+ # # good
125
+ # def my_method = x
126
+ #
127
+ # # good
128
+ # def my_method = x.foo
129
+ # .bar
130
+ # .baz
48
131
  #
49
132
  class EndlessMethod < Base
50
133
  include ConfigurableEnforcedStyle
134
+ include EndlessMethodRewriter
51
135
  extend TargetRubyVersion
52
136
  extend AutoCorrector
53
137
 
@@ -56,12 +140,21 @@ module RuboCop
56
140
  CORRECTION_STYLES = %w[multiline single_line].freeze
57
141
  MSG = 'Avoid endless method definitions.'
58
142
  MSG_MULTI_LINE = 'Avoid endless method definitions with multiple lines.'
143
+ MSG_REQUIRE_SINGLE = 'Use endless method definitions for single line methods.'
144
+ MSG_REQUIRE_ALWAYS = 'Use endless method definitions.'
59
145
 
60
146
  def on_def(node)
61
- if style == :disallow
62
- handle_disallow_style(node)
63
- else
147
+ return if node.assignment_method?
148
+
149
+ case style
150
+ when :allow_single_line, :allow_always
64
151
  handle_allow_style(node)
152
+ when :disallow
153
+ handle_disallow_style(node)
154
+ when :require_single_line
155
+ handle_require_single_line_style(node)
156
+ when :require_always
157
+ handle_require_always_style(node)
65
158
  end
66
159
  end
67
160
 
@@ -76,6 +169,29 @@ module RuboCop
76
169
  end
77
170
  end
78
171
 
172
+ def handle_require_single_line_style(node)
173
+ if node.endless? && !node.single_line?
174
+ add_offense(node, message: MSG_MULTI_LINE) do |corrector|
175
+ correct_to_multiline(corrector, node)
176
+ end
177
+ elsif !node.endless? && can_be_made_endless?(node) && node.body.single_line?
178
+ return if too_long_when_made_endless?(node)
179
+
180
+ add_offense(node, message: MSG_REQUIRE_SINGLE) do |corrector|
181
+ corrector.replace(node, endless_replacement(node))
182
+ end
183
+ end
184
+ end
185
+
186
+ def handle_require_always_style(node)
187
+ return if node.endless? || !can_be_made_endless?(node)
188
+ return if too_long_when_made_endless?(node)
189
+
190
+ add_offense(node, message: MSG_REQUIRE_ALWAYS) do |corrector|
191
+ corrector.replace(node, endless_replacement(node))
192
+ end
193
+ end
194
+
79
195
  def handle_disallow_style(node)
80
196
  return unless node.endless?
81
197
 
@@ -92,9 +208,25 @@ module RuboCop
92
208
  corrector.replace(node, replacement)
93
209
  end
94
210
 
211
+ def endless_replacement(node)
212
+ <<~RUBY.strip
213
+ def #{node.method_name}#{arguments(node)} = #{node.body.source}
214
+ RUBY
215
+ end
216
+
95
217
  def arguments(node, missing = '')
96
218
  node.arguments.any? ? node.arguments.source : missing
97
219
  end
220
+
221
+ def can_be_made_endless?(node)
222
+ node.body && !node.body.begin_type? && !node.body.kwbegin_type?
223
+ end
224
+
225
+ def too_long_when_made_endless?(node)
226
+ return false unless config.cop_enabled?('Layout/LineLength')
227
+
228
+ endless_replacement(node).length > config.for_cop('Layout/LineLength')['Max']
229
+ end
98
230
  end
99
231
  end
100
232
  end
@@ -4,12 +4,12 @@ module RuboCop
4
4
  module Cop
5
5
  module Style
6
6
  # Ensures that eval methods (`eval`, `instance_eval`, `class_eval`
7
- # and `module_eval`) are given filename and line number values (`\_\_FILE\_\_`
8
- # and `\_\_LINE\_\_`). This data is used to ensure that any errors raised
7
+ # and `module_eval`) are given filename and line number values (`+__FILE__+`
8
+ # and `+__LINE__+`). This data is used to ensure that any errors raised
9
9
  # within the evaluated code will be given the correct identification
10
10
  # in a backtrace.
11
11
  #
12
- # The cop also checks that the line number given relative to `\_\_LINE\_\_` is
12
+ # The cop also checks that the line number given relative to `+__LINE__+` is
13
13
  # correct.
14
14
  #
15
15
  # This cop will autocorrect incorrect or missing filename and line number
@@ -86,7 +86,7 @@ module RuboCop
86
86
  return if node.method?(:eval) && !valid_eval_receiver?(node.receiver)
87
87
 
88
88
  code = node.first_argument
89
- return unless code && (code.str_type? || code.dstr_type?)
89
+ return unless code&.type?(:str, :dstr)
90
90
 
91
91
  check_location(node, code)
92
92
  end