rubocop 1.41.1 → 1.57.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (423) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +6 -4
  4. data/config/default.yml +243 -48
  5. data/config/obsoletion.yml +5 -0
  6. data/lib/rubocop/cli/command/auto_generate_config.rb +7 -0
  7. data/lib/rubocop/cli/command/execute_runner.rb +7 -2
  8. data/lib/rubocop/cli/command/lsp.rb +19 -0
  9. data/lib/rubocop/cli.rb +59 -10
  10. data/lib/rubocop/comment_config.rb +19 -0
  11. data/lib/rubocop/config.rb +14 -10
  12. data/lib/rubocop/config_finder.rb +2 -2
  13. data/lib/rubocop/config_loader.rb +20 -23
  14. data/lib/rubocop/config_loader_resolver.rb +5 -1
  15. data/lib/rubocop/config_obsoletion/parameter_rule.rb +9 -1
  16. data/lib/rubocop/config_obsoletion.rb +2 -2
  17. data/lib/rubocop/cop/autocorrect_logic.rb +31 -13
  18. data/lib/rubocop/cop/base.rb +96 -73
  19. data/lib/rubocop/cop/bundler/duplicated_gem.rb +1 -0
  20. data/lib/rubocop/cop/bundler/duplicated_group.rb +127 -0
  21. data/lib/rubocop/cop/bundler/gem_comment.rb +2 -2
  22. data/lib/rubocop/cop/bundler/gem_version.rb +2 -2
  23. data/lib/rubocop/cop/bundler/ordered_gems.rb +9 -1
  24. data/lib/rubocop/cop/commissioner.rb +8 -2
  25. data/lib/rubocop/cop/cop.rb +53 -33
  26. data/lib/rubocop/cop/corrector.rb +31 -11
  27. data/lib/rubocop/cop/correctors/alignment_corrector.rb +3 -3
  28. data/lib/rubocop/cop/correctors/each_to_for_corrector.rb +3 -3
  29. data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +3 -3
  30. data/lib/rubocop/cop/correctors/lambda_literal_to_method_corrector.rb +7 -4
  31. data/lib/rubocop/cop/correctors/line_break_corrector.rb +1 -1
  32. data/lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +2 -2
  33. data/lib/rubocop/cop/correctors/ordered_gem_corrector.rb +2 -7
  34. data/lib/rubocop/cop/correctors/parentheses_corrector.rb +1 -1
  35. data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +2 -2
  36. data/lib/rubocop/cop/gemspec/dependency_version.rb +19 -21
  37. data/lib/rubocop/cop/gemspec/deprecated_attribute_assignment.rb +1 -1
  38. data/lib/rubocop/cop/gemspec/development_dependencies.rb +107 -0
  39. data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +9 -1
  40. data/lib/rubocop/cop/generator/require_file_injector.rb +1 -1
  41. data/lib/rubocop/cop/internal_affairs/cop_description.rb +37 -13
  42. data/lib/rubocop/cop/internal_affairs/example_description.rb +42 -21
  43. data/lib/rubocop/cop/internal_affairs/example_heredoc_delimiter.rb +3 -3
  44. data/lib/rubocop/cop/internal_affairs/inherit_deprecated_cop_class.rb +1 -1
  45. data/lib/rubocop/cop/internal_affairs/location_expression.rb +37 -0
  46. data/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +3 -1
  47. data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +6 -6
  48. data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +1 -1
  49. data/lib/rubocop/cop/internal_affairs/processed_source_buffer_name.rb +42 -0
  50. data/lib/rubocop/cop/internal_affairs/redundant_let_rubocop_config_new.rb +11 -3
  51. data/lib/rubocop/cop/internal_affairs/redundant_location_argument.rb +1 -1
  52. data/lib/rubocop/cop/internal_affairs/redundant_message_argument.rb +1 -1
  53. data/lib/rubocop/cop/internal_affairs/redundant_method_dispatch_node.rb +11 -2
  54. data/lib/rubocop/cop/internal_affairs/redundant_source_range.rb +66 -0
  55. data/lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +2 -0
  56. data/lib/rubocop/cop/internal_affairs.rb +3 -0
  57. data/lib/rubocop/cop/layout/array_alignment.rb +1 -1
  58. data/lib/rubocop/cop/layout/block_end_newline.rb +7 -15
  59. data/lib/rubocop/cop/layout/class_structure.rb +44 -26
  60. data/lib/rubocop/cop/layout/closing_heredoc_indentation.rb +2 -3
  61. data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +2 -6
  62. data/lib/rubocop/cop/layout/comment_indentation.rb +3 -1
  63. data/lib/rubocop/cop/layout/dot_position.rb +1 -5
  64. data/lib/rubocop/cop/layout/empty_comment.rb +3 -3
  65. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +42 -9
  66. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +28 -5
  67. data/lib/rubocop/cop/layout/empty_lines.rb +1 -1
  68. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +2 -0
  69. data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +2 -0
  70. data/lib/rubocop/cop/layout/end_alignment.rb +9 -1
  71. data/lib/rubocop/cop/layout/extra_spacing.rb +6 -1
  72. data/lib/rubocop/cop/layout/first_argument_indentation.rb +8 -3
  73. data/lib/rubocop/cop/layout/first_array_element_line_break.rb +25 -34
  74. data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +7 -19
  75. data/lib/rubocop/cop/layout/first_method_argument_line_break.rb +42 -52
  76. data/lib/rubocop/cop/layout/first_method_parameter_line_break.rb +38 -55
  77. data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +10 -4
  78. data/lib/rubocop/cop/layout/heredoc_indentation.rb +11 -11
  79. data/lib/rubocop/cop/layout/indentation_style.rb +5 -2
  80. data/lib/rubocop/cop/layout/indentation_width.rb +3 -3
  81. data/lib/rubocop/cop/layout/initial_indentation.rb +1 -1
  82. data/lib/rubocop/cop/layout/leading_comment_space.rb +2 -2
  83. data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +18 -12
  84. data/lib/rubocop/cop/layout/line_continuation_spacing.rb +17 -13
  85. data/lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb +2 -0
  86. data/lib/rubocop/cop/layout/multiline_array_line_breaks.rb +8 -27
  87. data/lib/rubocop/cop/layout/multiline_block_layout.rb +1 -1
  88. data/lib/rubocop/cop/layout/multiline_hash_key_line_breaks.rb +7 -26
  89. data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +4 -21
  90. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +18 -3
  91. data/lib/rubocop/cop/layout/multiline_method_parameter_line_breaks.rb +6 -30
  92. data/lib/rubocop/cop/layout/redundant_line_break.rb +20 -11
  93. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +2 -2
  94. data/lib/rubocop/cop/layout/space_after_comma.rb +9 -1
  95. data/lib/rubocop/cop/layout/space_after_not.rb +1 -1
  96. data/lib/rubocop/cop/layout/space_around_keyword.rb +2 -2
  97. data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +2 -2
  98. data/lib/rubocop/cop/layout/space_around_operators.rb +4 -2
  99. data/lib/rubocop/cop/layout/space_before_first_arg.rb +1 -1
  100. data/lib/rubocop/cop/layout/space_in_lambda_literal.rb +2 -2
  101. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +11 -13
  102. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +3 -1
  103. data/lib/rubocop/cop/layout/space_inside_parens.rb +3 -3
  104. data/lib/rubocop/cop/layout/space_inside_percent_literal_delimiters.rb +1 -1
  105. data/lib/rubocop/cop/layout/space_inside_range_literal.rb +1 -1
  106. data/lib/rubocop/cop/layout/space_inside_reference_brackets.rb +4 -4
  107. data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +5 -4
  108. data/lib/rubocop/cop/layout/trailing_empty_lines.rb +5 -0
  109. data/lib/rubocop/cop/layout/trailing_whitespace.rb +6 -3
  110. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +13 -1
  111. data/lib/rubocop/cop/lint/ambiguous_operator.rb +4 -0
  112. data/lib/rubocop/cop/lint/constant_resolution.rb +1 -1
  113. data/lib/rubocop/cop/lint/debugger.rb +22 -25
  114. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +62 -112
  115. data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +1 -1
  116. data/lib/rubocop/cop/lint/duplicate_hash_key.rb +2 -1
  117. data/lib/rubocop/cop/lint/duplicate_match_pattern.rb +122 -0
  118. data/lib/rubocop/cop/lint/duplicate_methods.rb +2 -2
  119. data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +47 -22
  120. data/lib/rubocop/cop/lint/else_layout.rb +3 -7
  121. data/lib/rubocop/cop/lint/empty_block.rb +2 -2
  122. data/lib/rubocop/cop/lint/empty_conditional_body.rb +4 -2
  123. data/lib/rubocop/cop/lint/empty_interpolation.rb +1 -1
  124. data/lib/rubocop/cop/lint/erb_new_arguments.rb +3 -4
  125. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +14 -7
  126. data/lib/rubocop/cop/lint/heredoc_method_call_position.rb +16 -18
  127. data/lib/rubocop/cop/lint/identity_comparison.rb +0 -1
  128. data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +1 -1
  129. data/lib/rubocop/cop/lint/incompatible_io_select_with_fiber_scheduler.rb +5 -3
  130. data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +1 -1
  131. data/lib/rubocop/cop/lint/inherit_exception.rb +9 -0
  132. data/lib/rubocop/cop/lint/lambda_without_literal_block.rb +1 -1
  133. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +47 -5
  134. data/lib/rubocop/cop/lint/missing_super.rb +63 -5
  135. data/lib/rubocop/cop/lint/mixed_case_range.rb +111 -0
  136. data/lib/rubocop/cop/lint/mixed_regexp_capture_types.rb +1 -0
  137. data/lib/rubocop/cop/lint/nested_method_definition.rb +4 -9
  138. data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +10 -7
  139. data/lib/rubocop/cop/lint/number_conversion.rb +5 -0
  140. data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +2 -2
  141. data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +2 -0
  142. data/lib/rubocop/cop/lint/ordered_magic_comments.rb +0 -1
  143. data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +16 -1
  144. data/lib/rubocop/cop/lint/percent_string_array.rb +1 -1
  145. data/lib/rubocop/cop/lint/percent_symbol_array.rb +1 -1
  146. data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +11 -5
  147. data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +5 -5
  148. data/lib/rubocop/cop/lint/redundant_regexp_quantifiers.rb +130 -0
  149. data/lib/rubocop/cop/lint/redundant_require_statement.rb +21 -2
  150. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +20 -4
  151. data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +1 -1
  152. data/lib/rubocop/cop/lint/redundant_string_coercion.rb +35 -15
  153. data/lib/rubocop/cop/lint/redundant_with_index.rb +1 -1
  154. data/lib/rubocop/cop/lint/redundant_with_object.rb +1 -1
  155. data/lib/rubocop/cop/lint/refinement_import_methods.rb +2 -1
  156. data/lib/rubocop/cop/lint/regexp_as_condition.rb +6 -0
  157. data/lib/rubocop/cop/lint/require_parentheses.rb +3 -1
  158. data/lib/rubocop/cop/lint/rescue_type.rb +3 -3
  159. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +11 -4
  160. data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +1 -1
  161. data/lib/rubocop/cop/lint/script_permission.rb +1 -1
  162. data/lib/rubocop/cop/lint/send_with_mixin_argument.rb +1 -2
  163. data/lib/rubocop/cop/lint/shadowed_exception.rb +6 -12
  164. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +7 -1
  165. data/lib/rubocop/cop/lint/struct_new_override.rb +12 -12
  166. data/lib/rubocop/cop/lint/suppressed_exception.rb +2 -2
  167. data/lib/rubocop/cop/lint/symbol_conversion.rb +1 -1
  168. data/lib/rubocop/cop/lint/syntax.rb +4 -0
  169. data/lib/rubocop/cop/lint/to_enum_arguments.rb +18 -6
  170. data/lib/rubocop/cop/lint/top_level_return_with_argument.rb +23 -9
  171. data/lib/rubocop/cop/lint/unreachable_loop.rb +3 -3
  172. data/lib/rubocop/cop/lint/unused_method_argument.rb +2 -1
  173. data/lib/rubocop/cop/lint/useless_access_modifier.rb +10 -7
  174. data/lib/rubocop/cop/lint/useless_assignment.rb +94 -10
  175. data/lib/rubocop/cop/lint/useless_method_definition.rb +12 -4
  176. data/lib/rubocop/cop/lint/useless_rescue.rb +89 -0
  177. data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +14 -4
  178. data/lib/rubocop/cop/lint/useless_times.rb +1 -1
  179. data/lib/rubocop/cop/lint/void.rb +79 -16
  180. data/lib/rubocop/cop/metrics/block_length.rb +2 -2
  181. data/lib/rubocop/cop/metrics/block_nesting.rb +2 -2
  182. data/lib/rubocop/cop/metrics/class_length.rb +3 -2
  183. data/lib/rubocop/cop/metrics/collection_literal_length.rb +76 -0
  184. data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +1 -1
  185. data/lib/rubocop/cop/metrics/method_length.rb +1 -1
  186. data/lib/rubocop/cop/metrics/parameter_lists.rb +27 -0
  187. data/lib/rubocop/cop/metrics/perceived_complexity.rb +1 -1
  188. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +4 -8
  189. data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +33 -5
  190. data/lib/rubocop/cop/migration/department_name.rb +3 -3
  191. data/lib/rubocop/cop/mixin/alignment.rb +1 -1
  192. data/lib/rubocop/cop/mixin/allowed_methods.rb +3 -1
  193. data/lib/rubocop/cop/mixin/allowed_receivers.rb +34 -0
  194. data/lib/rubocop/cop/mixin/annotation_comment.rb +2 -2
  195. data/lib/rubocop/cop/mixin/code_length.rb +1 -1
  196. data/lib/rubocop/cop/mixin/comments_help.rb +13 -7
  197. data/lib/rubocop/cop/mixin/def_node.rb +1 -1
  198. data/lib/rubocop/cop/mixin/documentation_comment.rb +1 -1
  199. data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +1 -1
  200. data/lib/rubocop/cop/mixin/hash_alignment_styles.rb +1 -1
  201. data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +62 -23
  202. data/lib/rubocop/cop/mixin/hash_transform_method.rb +3 -3
  203. data/lib/rubocop/cop/mixin/heredoc.rb +6 -2
  204. data/lib/rubocop/cop/mixin/line_length_help.rb +3 -1
  205. data/lib/rubocop/cop/mixin/min_branches_count.rb +40 -0
  206. data/lib/rubocop/cop/mixin/multiline_element_line_breaks.rb +0 -3
  207. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +3 -2
  208. data/lib/rubocop/cop/mixin/ordered_gem_node.rb +1 -1
  209. data/lib/rubocop/cop/mixin/percent_literal.rb +1 -1
  210. data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +6 -8
  211. data/lib/rubocop/cop/mixin/range_help.rb +1 -6
  212. data/lib/rubocop/cop/mixin/space_after_punctuation.rb +1 -1
  213. data/lib/rubocop/cop/mixin/statement_modifier.rb +4 -3
  214. data/lib/rubocop/cop/mixin/string_help.rb +4 -2
  215. data/lib/rubocop/cop/mixin/surrounding_space.rb +3 -3
  216. data/lib/rubocop/cop/mixin/trailing_comma.rb +3 -3
  217. data/lib/rubocop/cop/naming/ascii_identifiers.rb +1 -1
  218. data/lib/rubocop/cop/naming/block_forwarding.rb +5 -1
  219. data/lib/rubocop/cop/naming/class_and_module_camel_case.rb +1 -1
  220. data/lib/rubocop/cop/naming/constant_name.rb +1 -1
  221. data/lib/rubocop/cop/naming/file_name.rb +1 -1
  222. data/lib/rubocop/cop/naming/heredoc_delimiter_case.rb +1 -1
  223. data/lib/rubocop/cop/naming/heredoc_delimiter_naming.rb +3 -1
  224. data/lib/rubocop/cop/naming/inclusive_language.rb +23 -4
  225. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +25 -10
  226. data/lib/rubocop/cop/naming/method_name.rb +3 -3
  227. data/lib/rubocop/cop/naming/predicate_name.rb +1 -1
  228. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +12 -4
  229. data/lib/rubocop/cop/naming/variable_name.rb +6 -1
  230. data/lib/rubocop/cop/registry.rb +37 -30
  231. data/lib/rubocop/cop/security/compound_hash.rb +2 -1
  232. data/lib/rubocop/cop/style/access_modifier_declarations.rb +26 -11
  233. data/lib/rubocop/cop/style/accessor_grouping.rb +43 -17
  234. data/lib/rubocop/cop/style/alias.rb +9 -8
  235. data/lib/rubocop/cop/style/arguments_forwarding.rb +280 -62
  236. data/lib/rubocop/cop/style/array_intersect.rb +14 -6
  237. data/lib/rubocop/cop/style/ascii_comments.rb +1 -1
  238. data/lib/rubocop/cop/style/attr.rb +11 -1
  239. data/lib/rubocop/cop/style/begin_block.rb +1 -2
  240. data/lib/rubocop/cop/style/bisected_attr_accessor.rb +1 -1
  241. data/lib/rubocop/cop/style/block_comments.rb +3 -3
  242. data/lib/rubocop/cop/style/block_delimiters.rb +22 -6
  243. data/lib/rubocop/cop/style/case_like_if.rb +20 -3
  244. data/lib/rubocop/cop/style/class_and_module_children.rb +5 -12
  245. data/lib/rubocop/cop/style/class_equality_comparison.rb +58 -40
  246. data/lib/rubocop/cop/style/collection_compact.rb +20 -7
  247. data/lib/rubocop/cop/style/collection_methods.rb +2 -0
  248. data/lib/rubocop/cop/style/colon_method_call.rb +2 -2
  249. data/lib/rubocop/cop/style/combinable_loops.rb +30 -8
  250. data/lib/rubocop/cop/style/command_literal.rb +1 -1
  251. data/lib/rubocop/cop/style/comment_annotation.rb +1 -1
  252. data/lib/rubocop/cop/style/commented_keyword.rb +2 -2
  253. data/lib/rubocop/cop/style/comparable_clamp.rb +125 -0
  254. data/lib/rubocop/cop/style/concat_array_literals.rb +32 -4
  255. data/lib/rubocop/cop/style/conditional_assignment.rb +11 -15
  256. data/lib/rubocop/cop/style/copyright.rb +6 -3
  257. data/lib/rubocop/cop/style/data_inheritance.rb +75 -0
  258. data/lib/rubocop/cop/style/dir.rb +1 -1
  259. data/lib/rubocop/cop/style/dir_empty.rb +54 -0
  260. data/lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb +2 -2
  261. data/lib/rubocop/cop/style/document_dynamic_eval_definition.rb +3 -3
  262. data/lib/rubocop/cop/style/documentation.rb +12 -6
  263. data/lib/rubocop/cop/style/documentation_method.rb +10 -4
  264. data/lib/rubocop/cop/style/double_negation.rb +2 -2
  265. data/lib/rubocop/cop/style/each_with_object.rb +1 -1
  266. data/lib/rubocop/cop/style/empty_block_parameter.rb +1 -1
  267. data/lib/rubocop/cop/style/empty_case_condition.rb +6 -1
  268. data/lib/rubocop/cop/style/empty_lambda_parameter.rb +1 -1
  269. data/lib/rubocop/cop/style/eval_with_location.rb +8 -8
  270. data/lib/rubocop/cop/style/exact_regexp_match.rb +68 -0
  271. data/lib/rubocop/cop/style/explicit_block_argument.rb +1 -1
  272. data/lib/rubocop/cop/style/file_empty.rb +71 -0
  273. data/lib/rubocop/cop/style/file_read.rb +3 -3
  274. data/lib/rubocop/cop/style/file_write.rb +1 -1
  275. data/lib/rubocop/cop/style/for.rb +1 -1
  276. data/lib/rubocop/cop/style/format_string.rb +24 -3
  277. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +4 -2
  278. data/lib/rubocop/cop/style/guard_clause.rb +40 -8
  279. data/lib/rubocop/cop/style/hash_conversion.rb +10 -0
  280. data/lib/rubocop/cop/style/hash_each_methods.rb +1 -10
  281. data/lib/rubocop/cop/style/hash_except.rb +23 -12
  282. data/lib/rubocop/cop/style/hash_like_case.rb +3 -9
  283. data/lib/rubocop/cop/style/hash_syntax.rb +16 -9
  284. data/lib/rubocop/cop/style/hash_transform_keys.rb +2 -2
  285. data/lib/rubocop/cop/style/hash_transform_values.rb +2 -2
  286. data/lib/rubocop/cop/style/identical_conditional_branches.rb +36 -3
  287. data/lib/rubocop/cop/style/if_inside_else.rb +6 -0
  288. data/lib/rubocop/cop/style/if_unless_modifier.rb +111 -15
  289. data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +2 -0
  290. data/lib/rubocop/cop/style/if_with_semicolon.rb +2 -2
  291. data/lib/rubocop/cop/style/infinite_loop.rb +2 -5
  292. data/lib/rubocop/cop/style/inverse_methods.rb +5 -5
  293. data/lib/rubocop/cop/style/invertible_unless_condition.rb +118 -0
  294. data/lib/rubocop/cop/style/lambda.rb +3 -3
  295. data/lib/rubocop/cop/style/lambda_call.rb +5 -0
  296. data/lib/rubocop/cop/style/map_compact_with_conditional_block.rb +2 -2
  297. data/lib/rubocop/cop/style/map_to_hash.rb +4 -1
  298. data/lib/rubocop/cop/style/map_to_set.rb +64 -0
  299. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +35 -24
  300. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +44 -37
  301. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +2 -0
  302. data/lib/rubocop/cop/style/method_def_parentheses.rb +11 -4
  303. data/lib/rubocop/cop/style/min_max.rb +3 -3
  304. data/lib/rubocop/cop/style/min_max_comparison.rb +83 -0
  305. data/lib/rubocop/cop/style/missing_else.rb +13 -1
  306. data/lib/rubocop/cop/style/mixin_grouping.rb +5 -5
  307. data/lib/rubocop/cop/style/multiline_block_chain.rb +1 -1
  308. data/lib/rubocop/cop/style/multiline_if_modifier.rb +0 -4
  309. data/lib/rubocop/cop/style/multiline_memoization.rb +2 -2
  310. data/lib/rubocop/cop/style/multiline_method_signature.rb +7 -4
  311. data/lib/rubocop/cop/style/multiline_ternary_operator.rb +19 -4
  312. data/lib/rubocop/cop/style/multiple_comparison.rb +14 -0
  313. data/lib/rubocop/cop/style/negated_if_else_condition.rb +13 -12
  314. data/lib/rubocop/cop/style/nested_ternary_operator.rb +3 -11
  315. data/lib/rubocop/cop/style/nil_lambda.rb +2 -2
  316. data/lib/rubocop/cop/style/numbered_parameters_limit.rb +11 -3
  317. data/lib/rubocop/cop/style/numeric_literals.rb +1 -1
  318. data/lib/rubocop/cop/style/one_line_conditional.rb +3 -6
  319. data/lib/rubocop/cop/style/open_struct_use.rb +1 -1
  320. data/lib/rubocop/cop/style/operator_method_call.rb +22 -2
  321. data/lib/rubocop/cop/style/parallel_assignment.rb +29 -19
  322. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +2 -3
  323. data/lib/rubocop/cop/style/percent_q_literals.rb +1 -1
  324. data/lib/rubocop/cop/style/preferred_hash_methods.rb +1 -1
  325. data/lib/rubocop/cop/style/redundant_argument.rb +6 -1
  326. data/lib/rubocop/cop/style/redundant_array_constructor.rb +77 -0
  327. data/lib/rubocop/cop/style/redundant_begin.rb +10 -2
  328. data/lib/rubocop/cop/style/redundant_condition.rb +18 -3
  329. data/lib/rubocop/cop/style/redundant_conditional.rb +2 -14
  330. data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +38 -0
  331. data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +96 -9
  332. data/lib/rubocop/cop/style/redundant_exception.rb +32 -12
  333. data/lib/rubocop/cop/style/redundant_fetch_block.rb +6 -4
  334. data/lib/rubocop/cop/style/redundant_filter_chain.rb +117 -0
  335. data/lib/rubocop/cop/style/redundant_heredoc_delimiter_quotes.rb +58 -0
  336. data/lib/rubocop/cop/style/redundant_interpolation.rb +2 -2
  337. data/lib/rubocop/cop/style/redundant_line_continuation.rb +183 -0
  338. data/lib/rubocop/cop/style/redundant_parentheses.rb +26 -8
  339. data/lib/rubocop/cop/style/redundant_percent_q.rb +1 -1
  340. data/lib/rubocop/cop/style/redundant_regexp_argument.rb +100 -0
  341. data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +7 -8
  342. data/lib/rubocop/cop/style/redundant_regexp_constructor.rb +46 -0
  343. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +13 -4
  344. data/lib/rubocop/cop/style/redundant_return.rb +7 -2
  345. data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +8 -1
  346. data/lib/rubocop/cop/style/redundant_sort.rb +4 -4
  347. data/lib/rubocop/cop/style/redundant_string_escape.rb +9 -6
  348. data/lib/rubocop/cop/style/regexp_literal.rb +11 -2
  349. data/lib/rubocop/cop/style/require_order.rb +16 -17
  350. data/lib/rubocop/cop/style/rescue_modifier.rb +1 -3
  351. data/lib/rubocop/cop/style/rescue_standard_error.rb +2 -2
  352. data/lib/rubocop/cop/style/return_nil.rb +6 -2
  353. data/lib/rubocop/cop/style/return_nil_in_predicate_method_definition.rb +95 -0
  354. data/lib/rubocop/cop/style/safe_navigation.rb +2 -2
  355. data/lib/rubocop/cop/style/select_by_regexp.rb +20 -6
  356. data/lib/rubocop/cop/style/self_assignment.rb +2 -2
  357. data/lib/rubocop/cop/style/semicolon.rb +35 -5
  358. data/lib/rubocop/cop/style/signal_exception.rb +9 -7
  359. data/lib/rubocop/cop/style/single_line_do_end_block.rb +65 -0
  360. data/lib/rubocop/cop/style/single_line_methods.rb +1 -1
  361. data/lib/rubocop/cop/style/slicing_with_range.rb +1 -1
  362. data/lib/rubocop/cop/style/sole_nested_conditional.rb +9 -5
  363. data/lib/rubocop/cop/style/special_global_vars.rb +3 -4
  364. data/lib/rubocop/cop/style/stderr_puts.rb +1 -1
  365. data/lib/rubocop/cop/style/string_hash_keys.rb +4 -1
  366. data/lib/rubocop/cop/style/string_literals_in_interpolation.rb +30 -5
  367. data/lib/rubocop/cop/style/struct_inheritance.rb +1 -1
  368. data/lib/rubocop/cop/style/symbol_array.rb +35 -15
  369. data/lib/rubocop/cop/style/trailing_body_on_class.rb +1 -0
  370. data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +4 -4
  371. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +1 -1
  372. data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
  373. data/lib/rubocop/cop/style/unless_logical_operators.rb +1 -0
  374. data/lib/rubocop/cop/style/unpack_first.rb +3 -3
  375. data/lib/rubocop/cop/style/word_array.rb +54 -1
  376. data/lib/rubocop/cop/style/yaml_file_read.rb +66 -0
  377. data/lib/rubocop/cop/style/yoda_condition.rb +17 -8
  378. data/lib/rubocop/cop/style/yoda_expression.rb +91 -0
  379. data/lib/rubocop/cop/style/zero_length_predicate.rb +40 -19
  380. data/lib/rubocop/cop/team.rb +60 -52
  381. data/lib/rubocop/cop/util.rb +14 -5
  382. data/lib/rubocop/cop/utils/regexp_ranges.rb +113 -0
  383. data/lib/rubocop/cop/variable_force/assignment.rb +45 -4
  384. data/lib/rubocop/cop/variable_force/scope.rb +3 -3
  385. data/lib/rubocop/cop/variable_force/variable.rb +5 -3
  386. data/lib/rubocop/cop/variable_force/variable_table.rb +5 -3
  387. data/lib/rubocop/cop/variable_force.rb +2 -4
  388. data/lib/rubocop/cops_documentation_generator.rb +11 -4
  389. data/lib/rubocop/directive_comment.rb +3 -3
  390. data/lib/rubocop/ext/comment.rb +18 -0
  391. data/lib/rubocop/ext/regexp_node.rb +1 -1
  392. data/lib/rubocop/ext/regexp_parser.rb +5 -2
  393. data/lib/rubocop/file_finder.rb +4 -7
  394. data/lib/rubocop/formatter/junit_formatter.rb +4 -1
  395. data/lib/rubocop/formatter/simple_text_formatter.rb +1 -1
  396. data/lib/rubocop/formatter.rb +0 -1
  397. data/lib/rubocop/lsp/logger.rb +22 -0
  398. data/lib/rubocop/lsp/routes.rb +246 -0
  399. data/lib/rubocop/lsp/runtime.rb +99 -0
  400. data/lib/rubocop/lsp/server.rb +68 -0
  401. data/lib/rubocop/lsp/severity.rb +27 -0
  402. data/lib/rubocop/magic_comment.rb +12 -10
  403. data/lib/rubocop/options.rb +37 -3
  404. data/lib/rubocop/path_util.rb +17 -7
  405. data/lib/rubocop/result_cache.rb +7 -3
  406. data/lib/rubocop/rspec/cop_helper.rb +2 -2
  407. data/lib/rubocop/rspec/expect_offense.rb +6 -4
  408. data/lib/rubocop/rspec/shared_contexts.rb +6 -3
  409. data/lib/rubocop/rspec/support.rb +1 -0
  410. data/lib/rubocop/runner.rb +55 -10
  411. data/lib/rubocop/server/cache.rb +12 -4
  412. data/lib/rubocop/server/cli.rb +37 -18
  413. data/lib/rubocop/server/client_command/exec.rb +4 -3
  414. data/lib/rubocop/server/client_command/start.rb +6 -1
  415. data/lib/rubocop/server/core.rb +24 -9
  416. data/lib/rubocop/server/helper.rb +1 -1
  417. data/lib/rubocop/server/server_command/exec.rb +1 -1
  418. data/lib/rubocop/string_interpreter.rb +3 -3
  419. data/lib/rubocop/target_finder.rb +7 -3
  420. data/lib/rubocop/target_ruby.rb +13 -9
  421. data/lib/rubocop/version.rb +10 -6
  422. data/lib/rubocop.rb +31 -0
  423. metadata +84 -37
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Style
6
+ # Checks for single-line `do`...`end` block.
7
+ #
8
+ # In practice a single line `do`...`end` is autocorrected when `EnforcedStyle: semantic`
9
+ # in `Style/BlockDelimiters`. The autocorrection maintains the `do` ... `end` syntax to
10
+ # preserve semantics and does not change it to `{`...`}` block.
11
+ #
12
+ # @example
13
+ #
14
+ # # bad
15
+ # foo do |arg| bar(arg) end
16
+ #
17
+ # # good
18
+ # foo do |arg|
19
+ # bar(arg)
20
+ # end
21
+ #
22
+ # # bad
23
+ # ->(arg) do bar(arg) end
24
+ #
25
+ # # good
26
+ # ->(arg) { bar(arg) }
27
+ #
28
+ class SingleLineDoEndBlock < Base
29
+ extend AutoCorrector
30
+
31
+ MSG = 'Prefer multiline `do`...`end` block.'
32
+
33
+ def on_block(node)
34
+ return if !node.single_line? || node.braces?
35
+
36
+ add_offense(node) do |corrector|
37
+ corrector.insert_after(do_line(node), "\n")
38
+
39
+ node_body = node.body
40
+
41
+ if node_body.respond_to?(:heredoc?) && node_body.heredoc?
42
+ corrector.remove(node.loc.end)
43
+ corrector.insert_after(node_body.loc.heredoc_end, "\nend")
44
+ else
45
+ corrector.insert_after(node_body, "\n")
46
+ end
47
+ end
48
+ end
49
+ alias on_numblock on_block
50
+
51
+ private
52
+
53
+ def do_line(node)
54
+ if node.numblock_type? || node.arguments.children.empty? || node.send_node.lambda_literal?
55
+ node.loc.begin
56
+ else
57
+ node.arguments
58
+ end
59
+ end
60
+
61
+ def x(corrector, node); end
62
+ end
63
+ end
64
+ end
65
+ end
@@ -135,7 +135,7 @@ module RuboCop
135
135
 
136
136
  def disallow_endless_method_style?
137
137
  endless_method_config = config.for_cop('Style/EndlessMethod')
138
- return false unless endless_method_config['Enabled']
138
+ return true unless endless_method_config['Enabled']
139
139
 
140
140
  endless_method_config['EnforcedStyle'] == 'disallow'
141
141
  end
@@ -8,7 +8,7 @@ module RuboCop
8
8
  #
9
9
  # @safety
10
10
  # This cop is unsafe because `x..-1` and `x..` are only guaranteed to
11
- # be equivalent for `Array#[]`, and the cop cannot determine what class
11
+ # be equivalent for `Array#[]`, `String#[]`, and the cop cannot determine what class
12
12
  # the receiver is.
13
13
  #
14
14
  # For example:
@@ -167,13 +167,15 @@ module RuboCop
167
167
  corrector.insert_before(condition,
168
168
  "#{'!' if node.unless?}#{replace_condition(node.condition)} && ")
169
169
 
170
- corrector.remove(node.condition.loc.expression)
170
+ corrector.remove(node.condition)
171
171
  corrector.remove(range_with_surrounding_space(node.loc.keyword, newlines: false))
172
172
  corrector.replace(if_branch.loc.keyword, 'if')
173
173
  end
174
174
 
175
175
  def correct_for_comment(corrector, node, if_branch)
176
- comments = processed_source.ast_with_comments[if_branch]
176
+ comments = processed_source.ast_with_comments[if_branch].select do |comment|
177
+ comment.loc.line < if_branch.condition.first_line
178
+ end
177
179
  comment_text = comments.map(&:text).join("\n") << "\n"
178
180
 
179
181
  corrector.insert_before(node.loc.keyword, comment_text) unless comments.empty?
@@ -186,8 +188,10 @@ module RuboCop
186
188
  begin_pos = condition.first_argument.source_range.begin_pos
187
189
  return if end_pos > begin_pos
188
190
 
189
- corrector.replace(range_between(end_pos, begin_pos), '(')
190
- corrector.insert_after(condition.last_argument.source_range, ')')
191
+ range = range_between(end_pos, begin_pos)
192
+ corrector.remove(range)
193
+ corrector.insert_after(range, '(')
194
+ corrector.insert_after(condition.last_argument, ')')
191
195
  end
192
196
 
193
197
  def insert_bang(corrector, node, is_modify_form)
@@ -240,7 +244,7 @@ module RuboCop
240
244
  end
241
245
 
242
246
  def outer_condition_modify_form?(node, if_branch)
243
- node.condition.loc.expression.begin_pos > if_branch.condition.loc.expression.begin_pos
247
+ node.condition.source_range.begin_pos > if_branch.condition.source_range.begin_pos
244
248
  end
245
249
  end
246
250
  end
@@ -3,8 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Style
6
- #
7
- # This cop looks for uses of Perl-style global variables.
6
+ # Looks for uses of Perl-style global variables.
8
7
  # Correcting to global variables in the 'English' library
9
8
  # will add a require statement to the top of the file if
10
9
  # enabled by RequireEnglish config.
@@ -234,9 +233,9 @@ module RuboCop
234
233
  end
235
234
 
236
235
  def matching_styles(global)
237
- STYLE_VARS_MAP.map do |style, vars|
236
+ STYLE_VARS_MAP.filter_map do |style, vars|
238
237
  style if vars.values.flatten(1).include? global
239
- end.compact
238
+ end
240
239
  end
241
240
 
242
241
  def english_name_replacement(preferred_name, node)
@@ -49,7 +49,7 @@ module RuboCop
49
49
  end
50
50
 
51
51
  def stderr_puts_range(send)
52
- range_between(send.loc.expression.begin_pos, send.loc.selector.end_pos)
52
+ range_between(send.source_range.begin_pos, send.loc.selector.end_pos)
53
53
  end
54
54
  end
55
55
  end
@@ -41,10 +41,13 @@ module RuboCop
41
41
 
42
42
  def on_pair(node)
43
43
  return unless string_hash_key?(node)
44
+
45
+ key_content = node.key.str_content
46
+ return unless key_content.valid_encoding?
44
47
  return if receive_environments_method?(node)
45
48
 
46
49
  add_offense(node.key) do |corrector|
47
- symbol_content = node.key.str_content.to_sym.inspect
50
+ symbol_content = key_content.to_sym.inspect
48
51
 
49
52
  corrector.replace(node.key, symbol_content)
50
53
  end
@@ -3,22 +3,42 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Style
6
- # Checks that quotes inside the string interpolation
6
+ # Checks that quotes inside string, symbol, and regexp interpolations
7
7
  # match the configured preference.
8
8
  #
9
9
  # @example EnforcedStyle: single_quotes (default)
10
10
  # # bad
11
- # result = "Tests #{success ? "PASS" : "FAIL"}"
11
+ # string = "Tests #{success ? "PASS" : "FAIL"}"
12
+ # symbol = :"Tests #{success ? "PASS" : "FAIL"}"
13
+ # heredoc = <<~TEXT
14
+ # Tests #{success ? "PASS" : "FAIL"}
15
+ # TEXT
16
+ # regexp = /Tests #{success ? "PASS" : "FAIL"}/
12
17
  #
13
18
  # # good
14
- # result = "Tests #{success ? 'PASS' : 'FAIL'}"
19
+ # string = "Tests #{success ? 'PASS' : 'FAIL'}"
20
+ # symbol = :"Tests #{success ? 'PASS' : 'FAIL'}"
21
+ # heredoc = <<~TEXT
22
+ # Tests #{success ? 'PASS' : 'FAIL'}
23
+ # TEXT
24
+ # regexp = /Tests #{success ? 'PASS' : 'FAIL'}/
15
25
  #
16
26
  # @example EnforcedStyle: double_quotes
17
27
  # # bad
18
- # result = "Tests #{success ? 'PASS' : 'FAIL'}"
28
+ # string = "Tests #{success ? 'PASS' : 'FAIL'}"
29
+ # symbol = :"Tests #{success ? 'PASS' : 'FAIL'}"
30
+ # heredoc = <<~TEXT
31
+ # Tests #{success ? 'PASS' : 'FAIL'}
32
+ # TEXT
33
+ # regexp = /Tests #{success ? 'PASS' : 'FAIL'}/
19
34
  #
20
35
  # # good
21
- # result = "Tests #{success ? "PASS" : "FAIL"}"
36
+ # string = "Tests #{success ? "PASS" : "FAIL"}"
37
+ # symbol = :"Tests #{success ? "PASS" : "FAIL"}"
38
+ # heredoc = <<~TEXT
39
+ # Tests #{success ? "PASS" : "FAIL"}
40
+ # TEXT
41
+ # regexp = /Tests #{success ? "PASS" : "FAIL"}/
22
42
  class StringLiteralsInInterpolation < Base
23
43
  include ConfigurableEnforcedStyle
24
44
  include StringLiteralsHelp
@@ -29,6 +49,11 @@ module RuboCop
29
49
  StringLiteralCorrector.correct(corrector, node, style)
30
50
  end
31
51
 
52
+ # Cop classes that include the StringHelp module usually ignore regexp
53
+ # nodes. Not so for this cop, which is why we override the on_regexp
54
+ # definition with an empty one.
55
+ def on_regexp(node); end
56
+
32
57
  private
33
58
 
34
59
  def message(_node)
@@ -55,7 +55,7 @@ module RuboCop
55
55
  elsif (class_node = parent.parent).body.nil?
56
56
  corrector.remove(range_for_empty_class_body(class_node, parent))
57
57
  else
58
- corrector.insert_after(parent.loc.expression, ' do')
58
+ corrector.insert_after(parent, ' do')
59
59
  end
60
60
  end
61
61
 
@@ -22,6 +22,15 @@ module RuboCop
22
22
  # # bad
23
23
  # [:foo, :bar, :baz]
24
24
  #
25
+ # # bad (contains spaces)
26
+ # %i[foo\ bar baz\ quux]
27
+ #
28
+ # # bad (contains [] with spaces)
29
+ # %i[foo \[ \]]
30
+ #
31
+ # # bad (contains () with spaces)
32
+ # %i(foo \( \))
33
+ #
25
34
  # @example EnforcedStyle: brackets
26
35
  # # good
27
36
  # [:foo, :bar, :baz]
@@ -40,6 +49,15 @@ module RuboCop
40
49
 
41
50
  PERCENT_MSG = 'Use `%i` or `%I` for an array of symbols.'
42
51
  ARRAY_MSG = 'Use %<prefer>s for an array of symbols.'
52
+ DELIMITERS = ['[', ']', '(', ')'].freeze
53
+ SPECIAL_GVARS = %w[
54
+ $! $" $$ $& $' $* $+ $, $/ $; $: $. $< $= $> $? $@ $\\ $_ $` $~ $0
55
+ $-0 $-F $-I $-K $-W $-a $-d $-i $-l $-p $-v $-w
56
+ ].freeze
57
+ REDEFINABLE_OPERATORS = %w(
58
+ | ^ & <=> == === =~ > >= < <= << >>
59
+ + - * / % ** ~ +@ -@ [] []= ` ! != !~
60
+ ).freeze
43
61
 
44
62
  class << self
45
63
  attr_accessor :largest_brackets
@@ -47,7 +65,7 @@ module RuboCop
47
65
 
48
66
  def on_array(node)
49
67
  if bracketed_array_of?(:sym, node)
50
- return if symbols_contain_spaces?(node)
68
+ return if complex_content?(node)
51
69
 
52
70
  check_bracketed_array(node, 'i')
53
71
  elsif node.percent_literal?(:symbol)
@@ -57,13 +75,24 @@ module RuboCop
57
75
 
58
76
  private
59
77
 
60
- def symbols_contain_spaces?(node)
78
+ def complex_content?(node)
61
79
  node.children.any? do |sym|
62
- content, = *sym
63
- / /.match?(content)
80
+ return false if DELIMITERS.include?(sym.source)
81
+
82
+ content = *sym
83
+ content = content.map { |c| c.is_a?(AST::Node) ? c.source : c }.join
84
+ content_without_delimiter_pairs = content.gsub(/(\[[^\s\[\]]*\])|(\([^\s\(\)]*\))/, '')
85
+
86
+ content.include?(' ') || DELIMITERS.any? do |delimiter|
87
+ content_without_delimiter_pairs.include?(delimiter)
88
+ end
64
89
  end
65
90
  end
66
91
 
92
+ def invalid_percent_array_contents?(node)
93
+ complex_content?(node)
94
+ end
95
+
67
96
  def build_bracketed_array(node)
68
97
  return '[]' if node.children.empty?
69
98
 
@@ -88,15 +117,6 @@ module RuboCop
88
117
  end
89
118
 
90
119
  def symbol_without_quote?(string)
91
- special_gvars = %w[
92
- $! $" $$ $& $' $* $+ $, $/ $; $: $. $< $= $> $? $@ $\\ $_ $` $~ $0
93
- $-0 $-F $-I $-K $-W $-a $-d $-i $-l $-p $-v $-w
94
- ]
95
- redefinable_operators = %w(
96
- | ^ & <=> == === =~ > >= < <= << >>
97
- + - * / % ** ~ +@ -@ [] []= ` ! != !~
98
- )
99
-
100
120
  # method name
101
121
  /\A[a-zA-Z_]\w*[!?]?\z/.match?(string) ||
102
122
  # instance / class variable
@@ -104,8 +124,8 @@ module RuboCop
104
124
  # global variable
105
125
  /\A\$[1-9]\d*\z/.match?(string) ||
106
126
  /\A\$[a-zA-Z_]\w*\z/.match?(string) ||
107
- special_gvars.include?(string) ||
108
- redefinable_operators.include?(string)
127
+ SPECIAL_GVARS.include?(string) ||
128
+ REDEFINABLE_OPERATORS.include?(string)
109
129
  end
110
130
  end
111
131
  end
@@ -34,6 +34,7 @@ module RuboCop
34
34
  )
35
35
  end
36
36
  end
37
+ alias on_sclass on_class
37
38
  end
38
39
  end
39
40
  end
@@ -88,6 +88,10 @@ module RuboCop
88
88
  include TrailingComma
89
89
  extend AutoCorrector
90
90
 
91
+ def self.autocorrect_incompatible_with
92
+ [Layout::HeredocArgumentClosingParenthesis]
93
+ end
94
+
91
95
  def on_send(node)
92
96
  return unless node.arguments? && node.parenthesized?
93
97
 
@@ -96,10 +100,6 @@ module RuboCop
96
100
  node.source_range.end_pos)
97
101
  end
98
102
  alias on_csend on_send
99
-
100
- def self.autocorrect_incompatible_with
101
- [Layout::HeredocArgumentClosingParenthesis]
102
- end
103
103
  end
104
104
  end
105
105
  end
@@ -144,7 +144,7 @@ module RuboCop
144
144
  end
145
145
 
146
146
  def range_for_parentheses(offense, left)
147
- range_between(offense.source_range.begin_pos - 1, left.loc.expression.end_pos - 1)
147
+ range_between(offense.source_range.begin_pos - 1, left.source_range.end_pos - 1)
148
148
  end
149
149
  end
150
150
  end
@@ -238,7 +238,7 @@ module RuboCop
238
238
 
239
239
  indent = ' ' * node.loc.column
240
240
  corrector.replace(
241
- node.source_range,
241
+ node,
242
242
  ['class << self',
243
243
  "#{indent} #{accessor(kind, node.method_name)}",
244
244
  "#{indent}end"].join("\n")
@@ -8,6 +8,7 @@ module RuboCop
8
8
  # to read and understand.
9
9
  #
10
10
  # This cop supports two styles:
11
+ #
11
12
  # - `forbid_mixed_logical_operators` (default)
12
13
  # - `forbid_logical_operators`
13
14
  #
@@ -52,9 +52,9 @@ module RuboCop
52
52
  private
53
53
 
54
54
  def first_element_range(node, unpack_call)
55
- Parser::Source::Range.new(node.loc.expression.source_buffer,
56
- unpack_call.loc.expression.end_pos,
57
- node.loc.expression.end_pos)
55
+ Parser::Source::Range.new(node.source_range.source_buffer,
56
+ unpack_call.source_range.end_pos,
57
+ node.source_range.end_pos)
58
58
  end
59
59
  end
60
60
  end
@@ -27,6 +27,25 @@ module RuboCop
27
27
  # # bad (contains spaces)
28
28
  # %w[foo\ bar baz\ quux]
29
29
  #
30
+ # # bad
31
+ # [
32
+ # ['one', 'One'],
33
+ # ['two', 'Two']
34
+ # ]
35
+ #
36
+ # # good
37
+ # [
38
+ # %w[one One],
39
+ # %w[two Two]
40
+ # ]
41
+ #
42
+ # # good (2d array containing spaces)
43
+ # [
44
+ # ['one', 'One'],
45
+ # ['two', 'Two'],
46
+ # ['forty two', 'Forty Two']
47
+ # ]
48
+ #
30
49
  # @example EnforcedStyle: brackets
31
50
  # # good
32
51
  # ['foo', 'bar', 'baz']
@@ -36,6 +55,19 @@ module RuboCop
36
55
  #
37
56
  # # good (contains spaces)
38
57
  # ['foo bar', 'baz quux']
58
+ #
59
+ # # good
60
+ # [
61
+ # ['one', 'One'],
62
+ # ['two', 'Two']
63
+ # ]
64
+ #
65
+ # # bad
66
+ # [
67
+ # %w[one One],
68
+ # %w[two Two]
69
+ # ]
70
+ #
39
71
  class WordArray < Base
40
72
  include ArrayMinSize
41
73
  include ArraySyntax
@@ -50,9 +82,19 @@ module RuboCop
50
82
  attr_accessor :largest_brackets
51
83
  end
52
84
 
85
+ def on_new_investigation
86
+ super
87
+
88
+ # Prevent O(n2) checks (checking the entire matrix once for each child array) by caching
89
+ @matrix_of_complex_content_cache = Hash.new do |cache, node|
90
+ cache[node] = matrix_of_complex_content?(node)
91
+ end
92
+ end
93
+
53
94
  def on_array(node)
54
95
  if bracketed_array_of?(:str, node)
55
96
  return if complex_content?(node.values)
97
+ return if within_matrix_of_complex_content?(node)
56
98
 
57
99
  check_bracketed_array(node, 'w')
58
100
  elsif node.percent_literal?(:string)
@@ -62,6 +104,17 @@ module RuboCop
62
104
 
63
105
  private
64
106
 
107
+ def within_matrix_of_complex_content?(node)
108
+ return false unless (parent = node.parent)
109
+
110
+ parent.array_type? && @matrix_of_complex_content_cache[parent]
111
+ end
112
+
113
+ def matrix_of_complex_content?(array)
114
+ array.values.all?(&:array_type?) &&
115
+ array.values.any? { |subarray| complex_content?(subarray.values) }
116
+ end
117
+
65
118
  def complex_content?(strings, complex_regex: word_regex)
66
119
  strings.any? do |s|
67
120
  next unless s.str_content
@@ -69,7 +122,7 @@ module RuboCop
69
122
  string = s.str_content.dup.force_encoding(::Encoding::UTF_8)
70
123
  !string.valid_encoding? ||
71
124
  (complex_regex && !complex_regex.match?(string)) ||
72
- / /.match?(string)
125
+ string.include?(' ')
73
126
  end
74
127
  end
75
128
 
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Style
6
+ # Checks for the use of `YAML.load`, `YAML.safe_load`, and `YAML.parse` with
7
+ # `File.read` argument.
8
+ #
9
+ # NOTE: `YAML.safe_load_file` was introduced in Ruby 3.0.
10
+ #
11
+ # @example
12
+ #
13
+ # # bad
14
+ # YAML.load(File.read(path))
15
+ # YAML.parse(File.read(path))
16
+ #
17
+ # # good
18
+ # YAML.load_file(path)
19
+ # YAML.parse_file(path)
20
+ #
21
+ # # bad
22
+ # YAML.safe_load(File.read(path)) # Ruby 3.0 and newer
23
+ #
24
+ # # good
25
+ # YAML.safe_load_file(path) # Ruby 3.0 and newer
26
+ #
27
+ class YAMLFileRead < Base
28
+ extend AutoCorrector
29
+
30
+ MSG = 'Use `%<prefer>s` instead.'
31
+ RESTRICT_ON_SEND = %i[load safe_load parse].freeze
32
+
33
+ # @!method yaml_file_read?(node)
34
+ def_node_matcher :yaml_file_read?, <<~PATTERN
35
+ (send
36
+ (const {cbase nil?} :YAML) _
37
+ (send
38
+ (const {cbase nil?} :File) :read $_) $...)
39
+ PATTERN
40
+
41
+ def on_send(node)
42
+ return if node.method?(:safe_load) && target_ruby_version <= 2.7
43
+ return unless (file_path, rest_arguments = yaml_file_read?(node))
44
+
45
+ range = offense_range(node)
46
+ rest_arguments = if rest_arguments.empty?
47
+ ''
48
+ else
49
+ ", #{rest_arguments.map(&:source).join(', ')}"
50
+ end
51
+ prefer = "#{node.method_name}_file(#{file_path.source}#{rest_arguments})"
52
+
53
+ add_offense(range, message: format(MSG, prefer: prefer)) do |corrector|
54
+ corrector.replace(range, prefer)
55
+ end
56
+ end
57
+
58
+ private
59
+
60
+ def offense_range(node)
61
+ node.loc.selector.join(node.source_range.end)
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
@@ -33,12 +33,14 @@ module RuboCop
33
33
  # "bar" != foo
34
34
  # 42 >= foo
35
35
  # 10 < bar
36
+ # 99 == CONST
36
37
  #
37
38
  # # good
38
39
  # foo == 99
39
40
  # foo == "bar"
40
41
  # foo <= 42
41
42
  # bar > 10
43
+ # CONST == 99
42
44
  # "#{interpolation}" == foo
43
45
  # /#{interpolation}/ == foo
44
46
  #
@@ -92,9 +94,10 @@ module RuboCop
92
94
  def on_send(node)
93
95
  return unless yoda_compatible_condition?(node)
94
96
  return if (equality_only? && non_equality_operator?(node)) ||
95
- file_constant_equal_program_name?(node)
97
+ file_constant_equal_program_name?(node) ||
98
+ valid_yoda?(node)
96
99
 
97
- valid_yoda?(node) || add_offense(node) do |corrector|
100
+ add_offense(node) do |corrector|
98
101
  corrector.replace(actual_code_range(node), corrected_code(node))
99
102
  end
100
103
  end
@@ -115,16 +118,18 @@ module RuboCop
115
118
  node.comparison_method? && !noncommutative_operator?(node)
116
119
  end
117
120
 
121
+ # rubocop:disable Metrics/CyclomaticComplexity
118
122
  def valid_yoda?(node)
119
- lhs = node.receiver
120
- rhs = node.first_argument
123
+ return true unless (rhs = node.first_argument)
121
124
 
122
- return true if (lhs.literal? && rhs.literal?) ||
123
- (!lhs.literal? && !rhs.literal?) ||
125
+ lhs = node.receiver
126
+ return true if (constant_portion?(lhs) && constant_portion?(rhs)) ||
127
+ (!constant_portion?(lhs) && !constant_portion?(rhs)) ||
124
128
  interpolation?(lhs)
125
129
 
126
- enforce_yoda? ? lhs.literal? : rhs.literal?
130
+ enforce_yoda? ? constant_portion?(lhs) : constant_portion?(rhs)
127
131
  end
132
+ # rubocop:enable Metrics/CyclomaticComplexity
128
133
 
129
134
  def message(node)
130
135
  format(MSG, source: node.source)
@@ -137,8 +142,12 @@ module RuboCop
137
142
  "#{rhs.source} #{reverse_comparison(node.method_name)} #{lhs.source}"
138
143
  end
139
144
 
145
+ def constant_portion?(node)
146
+ node.literal? || node.const_type?
147
+ end
148
+
140
149
  def actual_code_range(node)
141
- range_between(node.loc.expression.begin_pos, node.loc.expression.end_pos)
150
+ range_between(node.source_range.begin_pos, node.source_range.end_pos)
142
151
  end
143
152
 
144
153
  def reverse_comparison(operator)