rubocop 1.50.2 → 1.59.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 (290) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +5 -3
  3. data/config/default.yml +153 -16
  4. data/config/obsoletion.yml +5 -0
  5. data/lib/rubocop/cli/command/auto_generate_config.rb +10 -5
  6. data/lib/rubocop/cli/command/lsp.rb +19 -0
  7. data/lib/rubocop/cli.rb +4 -1
  8. data/lib/rubocop/config.rb +4 -0
  9. data/lib/rubocop/config_finder.rb +2 -2
  10. data/lib/rubocop/config_loader_resolver.rb +4 -3
  11. data/lib/rubocop/config_obsoletion/parameter_rule.rb +9 -1
  12. data/lib/rubocop/config_obsoletion.rb +13 -10
  13. data/lib/rubocop/cop/autocorrect_logic.rb +3 -1
  14. data/lib/rubocop/cop/base.rb +6 -2
  15. data/lib/rubocop/cop/bundler/duplicated_gem.rb +1 -0
  16. data/lib/rubocop/cop/bundler/duplicated_group.rb +127 -0
  17. data/lib/rubocop/cop/bundler/gem_comment.rb +3 -3
  18. data/lib/rubocop/cop/bundler/gem_version.rb +2 -2
  19. data/lib/rubocop/cop/bundler/ordered_gems.rb +9 -1
  20. data/lib/rubocop/cop/correctors/alignment_corrector.rb +1 -1
  21. data/lib/rubocop/cop/correctors/lambda_literal_to_method_corrector.rb +7 -4
  22. data/lib/rubocop/cop/gemspec/dependency_version.rb +2 -2
  23. data/lib/rubocop/cop/gemspec/deprecated_attribute_assignment.rb +2 -2
  24. data/lib/rubocop/cop/gemspec/development_dependencies.rb +1 -1
  25. data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +9 -1
  26. data/lib/rubocop/cop/generator/require_file_injector.rb +1 -1
  27. data/lib/rubocop/cop/internal_affairs/cop_description.rb +32 -8
  28. data/lib/rubocop/cop/internal_affairs/example_description.rb +42 -21
  29. data/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +3 -1
  30. data/lib/rubocop/cop/internal_affairs/method_name_equal.rb +19 -20
  31. data/lib/rubocop/cop/internal_affairs/node_first_or_last_argument.rb +53 -0
  32. data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +7 -7
  33. data/lib/rubocop/cop/internal_affairs/redundant_method_dispatch_node.rb +11 -2
  34. data/lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +2 -0
  35. data/lib/rubocop/cop/internal_affairs.rb +1 -0
  36. data/lib/rubocop/cop/layout/argument_alignment.rb +1 -1
  37. data/lib/rubocop/cop/layout/class_structure.rb +7 -0
  38. data/lib/rubocop/cop/layout/closing_heredoc_indentation.rb +1 -2
  39. data/lib/rubocop/cop/layout/dot_position.rb +1 -5
  40. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +42 -9
  41. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +27 -4
  42. data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +2 -0
  43. data/lib/rubocop/cop/layout/end_alignment.rb +7 -1
  44. data/lib/rubocop/cop/layout/extra_spacing.rb +4 -10
  45. data/lib/rubocop/cop/layout/first_array_element_indentation.rb +6 -6
  46. data/lib/rubocop/cop/layout/first_parameter_indentation.rb +1 -1
  47. data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +4 -4
  48. data/lib/rubocop/cop/layout/heredoc_indentation.rb +4 -1
  49. data/lib/rubocop/cop/layout/indentation_style.rb +1 -1
  50. data/lib/rubocop/cop/layout/indentation_width.rb +3 -3
  51. data/lib/rubocop/cop/layout/leading_comment_space.rb +1 -1
  52. data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +17 -9
  53. data/lib/rubocop/cop/layout/line_continuation_spacing.rb +1 -1
  54. data/lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb +2 -0
  55. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +18 -3
  56. data/lib/rubocop/cop/layout/redundant_line_break.rb +16 -5
  57. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +4 -4
  58. data/lib/rubocop/cop/layout/single_line_block_chain.rb +5 -0
  59. data/lib/rubocop/cop/layout/space_after_comma.rb +9 -1
  60. data/lib/rubocop/cop/layout/space_after_not.rb +1 -1
  61. data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +2 -2
  62. data/lib/rubocop/cop/layout/space_around_operators.rb +53 -21
  63. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +2 -0
  64. data/lib/rubocop/cop/layout/space_inside_parens.rb +1 -1
  65. data/lib/rubocop/cop/layout/space_inside_range_literal.rb +1 -1
  66. data/lib/rubocop/cop/layout/trailing_empty_lines.rb +5 -0
  67. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +13 -1
  68. data/lib/rubocop/cop/lint/assignment_in_condition.rb +4 -4
  69. data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +2 -2
  70. data/lib/rubocop/cop/lint/constant_overwritten_in_rescue.rb +1 -1
  71. data/lib/rubocop/cop/lint/debugger.rb +19 -5
  72. data/lib/rubocop/cop/lint/duplicate_hash_key.rb +2 -1
  73. data/lib/rubocop/cop/lint/duplicate_methods.rb +1 -1
  74. data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +46 -19
  75. data/lib/rubocop/cop/lint/empty_block.rb +1 -1
  76. data/lib/rubocop/cop/lint/erb_new_arguments.rb +6 -7
  77. data/lib/rubocop/cop/lint/float_comparison.rb +10 -0
  78. data/lib/rubocop/cop/lint/hash_compare_by_identity.rb +2 -1
  79. data/lib/rubocop/cop/lint/heredoc_method_call_position.rb +1 -1
  80. data/lib/rubocop/cop/lint/identity_comparison.rb +0 -1
  81. data/lib/rubocop/cop/lint/incompatible_io_select_with_fiber_scheduler.rb +5 -3
  82. data/lib/rubocop/cop/lint/inherit_exception.rb +9 -0
  83. data/lib/rubocop/cop/lint/it_without_arguments_in_block.rb +56 -0
  84. data/lib/rubocop/cop/lint/lambda_without_literal_block.rb +1 -1
  85. data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +78 -0
  86. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +1 -1
  87. data/lib/rubocop/cop/lint/missing_super.rb +34 -5
  88. data/lib/rubocop/cop/lint/mixed_case_range.rb +111 -0
  89. data/lib/rubocop/cop/lint/next_without_accumulator.rb +6 -21
  90. data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +10 -7
  91. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +3 -5
  92. data/lib/rubocop/cop/lint/number_conversion.rb +14 -4
  93. data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +2 -2
  94. data/lib/rubocop/cop/lint/ordered_magic_comments.rb +0 -1
  95. data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +2 -2
  96. data/lib/rubocop/cop/lint/redundant_regexp_quantifiers.rb +130 -0
  97. data/lib/rubocop/cop/lint/redundant_require_statement.rb +12 -3
  98. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +63 -4
  99. data/lib/rubocop/cop/lint/redundant_string_coercion.rb +1 -1
  100. data/lib/rubocop/cop/lint/redundant_with_index.rb +2 -2
  101. data/lib/rubocop/cop/lint/redundant_with_object.rb +2 -2
  102. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +14 -8
  103. data/lib/rubocop/cop/lint/self_assignment.rb +38 -0
  104. data/lib/rubocop/cop/lint/send_with_mixin_argument.rb +1 -2
  105. data/lib/rubocop/cop/lint/shadowed_exception.rb +5 -11
  106. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +7 -1
  107. data/lib/rubocop/cop/lint/struct_new_override.rb +12 -12
  108. data/lib/rubocop/cop/lint/suppressed_exception.rb +2 -2
  109. data/lib/rubocop/cop/lint/symbol_conversion.rb +8 -3
  110. data/lib/rubocop/cop/lint/to_enum_arguments.rb +5 -3
  111. data/lib/rubocop/cop/lint/top_level_return_with_argument.rb +23 -9
  112. data/lib/rubocop/cop/lint/trailing_comma_in_attribute_declaration.rb +1 -1
  113. data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +2 -2
  114. data/lib/rubocop/cop/lint/useless_access_modifier.rb +2 -2
  115. data/lib/rubocop/cop/lint/useless_assignment.rb +94 -10
  116. data/lib/rubocop/cop/lint/useless_times.rb +1 -1
  117. data/lib/rubocop/cop/lint/void.rb +92 -11
  118. data/lib/rubocop/cop/metrics/abc_size.rb +3 -3
  119. data/lib/rubocop/cop/metrics/block_length.rb +1 -1
  120. data/lib/rubocop/cop/metrics/class_length.rb +8 -3
  121. data/lib/rubocop/cop/metrics/method_length.rb +1 -1
  122. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +1 -2
  123. data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +32 -4
  124. data/lib/rubocop/cop/migration/department_name.rb +2 -2
  125. data/lib/rubocop/cop/mixin/allowed_receivers.rb +34 -0
  126. data/lib/rubocop/cop/mixin/check_line_breakable.rb +1 -1
  127. data/lib/rubocop/cop/mixin/comments_help.rb +19 -11
  128. data/lib/rubocop/cop/mixin/def_node.rb +1 -1
  129. data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +1 -1
  130. data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +14 -11
  131. data/lib/rubocop/cop/mixin/heredoc.rb +6 -2
  132. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +3 -2
  133. data/lib/rubocop/cop/mixin/percent_literal.rb +1 -1
  134. data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +6 -8
  135. data/lib/rubocop/cop/mixin/space_after_punctuation.rb +1 -1
  136. data/lib/rubocop/cop/mixin/space_before_punctuation.rb +1 -1
  137. data/lib/rubocop/cop/mixin/string_help.rb +4 -2
  138. data/lib/rubocop/cop/mixin/trailing_comma.rb +1 -1
  139. data/lib/rubocop/cop/naming/block_forwarding.rb +3 -3
  140. data/lib/rubocop/cop/naming/constant_name.rb +2 -3
  141. data/lib/rubocop/cop/naming/file_name.rb +1 -1
  142. data/lib/rubocop/cop/naming/heredoc_delimiter_naming.rb +3 -1
  143. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +26 -11
  144. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +11 -3
  145. data/lib/rubocop/cop/naming/variable_name.rb +6 -1
  146. data/lib/rubocop/cop/style/access_modifier_declarations.rb +2 -2
  147. data/lib/rubocop/cop/style/accessor_grouping.rb +6 -2
  148. data/lib/rubocop/cop/style/alias.rb +9 -8
  149. data/lib/rubocop/cop/style/arguments_forwarding.rb +342 -63
  150. data/lib/rubocop/cop/style/array_first_last.rb +64 -0
  151. data/lib/rubocop/cop/style/array_intersect.rb +13 -5
  152. data/lib/rubocop/cop/style/attr.rb +11 -1
  153. data/lib/rubocop/cop/style/auto_resource_cleanup.rb +21 -14
  154. data/lib/rubocop/cop/style/begin_block.rb +1 -2
  155. data/lib/rubocop/cop/style/bisected_attr_accessor.rb +2 -2
  156. data/lib/rubocop/cop/style/block_comments.rb +1 -1
  157. data/lib/rubocop/cop/style/block_delimiters.rb +5 -4
  158. data/lib/rubocop/cop/style/case_like_if.rb +4 -4
  159. data/lib/rubocop/cop/style/class_and_module_children.rb +1 -1
  160. data/lib/rubocop/cop/style/class_check.rb +1 -0
  161. data/lib/rubocop/cop/style/class_equality_comparison.rb +24 -39
  162. data/lib/rubocop/cop/style/collection_compact.rb +22 -11
  163. data/lib/rubocop/cop/style/collection_methods.rb +2 -0
  164. data/lib/rubocop/cop/style/colon_method_call.rb +2 -2
  165. data/lib/rubocop/cop/style/combinable_loops.rb +36 -8
  166. data/lib/rubocop/cop/style/concat_array_literals.rb +2 -1
  167. data/lib/rubocop/cop/style/conditional_assignment.rb +6 -4
  168. data/lib/rubocop/cop/style/copyright.rb +5 -2
  169. data/lib/rubocop/cop/style/date_time.rb +5 -4
  170. data/lib/rubocop/cop/style/dir.rb +1 -1
  171. data/lib/rubocop/cop/style/dir_empty.rb +8 -14
  172. data/lib/rubocop/cop/style/document_dynamic_eval_definition.rb +1 -1
  173. data/lib/rubocop/cop/style/documentation.rb +1 -1
  174. data/lib/rubocop/cop/style/each_with_object.rb +2 -2
  175. data/lib/rubocop/cop/style/empty_case_condition.rb +6 -1
  176. data/lib/rubocop/cop/style/empty_literal.rb +1 -1
  177. data/lib/rubocop/cop/style/eval_with_location.rb +8 -8
  178. data/lib/rubocop/cop/style/exact_regexp_match.rb +69 -0
  179. data/lib/rubocop/cop/style/explicit_block_argument.rb +2 -2
  180. data/lib/rubocop/cop/style/file_read.rb +2 -2
  181. data/lib/rubocop/cop/style/for.rb +1 -1
  182. data/lib/rubocop/cop/style/format_string.rb +24 -3
  183. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +3 -1
  184. data/lib/rubocop/cop/style/guard_clause.rb +28 -0
  185. data/lib/rubocop/cop/style/hash_conversion.rb +10 -0
  186. data/lib/rubocop/cop/style/hash_each_methods.rb +84 -32
  187. data/lib/rubocop/cop/style/hash_except.rb +21 -9
  188. data/lib/rubocop/cop/style/hash_transform_keys.rb +2 -2
  189. data/lib/rubocop/cop/style/hash_transform_values.rb +2 -2
  190. data/lib/rubocop/cop/style/identical_conditional_branches.rb +31 -5
  191. data/lib/rubocop/cop/style/if_inside_else.rb +6 -0
  192. data/lib/rubocop/cop/style/if_unless_modifier.rb +3 -0
  193. data/lib/rubocop/cop/style/if_with_semicolon.rb +2 -2
  194. data/lib/rubocop/cop/style/inverse_methods.rb +6 -5
  195. data/lib/rubocop/cop/style/invertible_unless_condition.rb +10 -6
  196. data/lib/rubocop/cop/style/lambda.rb +3 -3
  197. data/lib/rubocop/cop/style/lambda_call.rb +5 -0
  198. data/lib/rubocop/cop/style/map_compact_with_conditional_block.rb +3 -2
  199. data/lib/rubocop/cop/style/map_to_hash.rb +10 -4
  200. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +12 -5
  201. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +1 -1
  202. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +20 -0
  203. data/lib/rubocop/cop/style/method_def_parentheses.rb +1 -1
  204. data/lib/rubocop/cop/style/missing_respond_to_missing.rb +2 -2
  205. data/lib/rubocop/cop/style/mixin_grouping.rb +1 -1
  206. data/lib/rubocop/cop/style/multiline_block_chain.rb +1 -1
  207. data/lib/rubocop/cop/style/multiline_ternary_operator.rb +1 -1
  208. data/lib/rubocop/cop/style/multiple_comparison.rb +14 -0
  209. data/lib/rubocop/cop/style/nested_ternary_operator.rb +3 -11
  210. data/lib/rubocop/cop/style/next.rb +1 -1
  211. data/lib/rubocop/cop/style/numeric_literals.rb +1 -1
  212. data/lib/rubocop/cop/style/open_struct_use.rb +1 -1
  213. data/lib/rubocop/cop/style/operator_method_call.rb +8 -2
  214. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +1 -1
  215. data/lib/rubocop/cop/style/preferred_hash_methods.rb +1 -1
  216. data/lib/rubocop/cop/style/redundant_argument.rb +9 -3
  217. data/lib/rubocop/cop/style/redundant_array_constructor.rb +77 -0
  218. data/lib/rubocop/cop/style/redundant_begin.rb +10 -2
  219. data/lib/rubocop/cop/style/redundant_conditional.rb +2 -10
  220. data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +38 -0
  221. data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +93 -5
  222. data/lib/rubocop/cop/style/redundant_exception.rb +32 -12
  223. data/lib/rubocop/cop/style/redundant_fetch_block.rb +3 -3
  224. data/lib/rubocop/cop/style/redundant_filter_chain.rb +118 -0
  225. data/lib/rubocop/cop/style/redundant_line_continuation.rb +9 -3
  226. data/lib/rubocop/cop/style/redundant_parentheses.rb +54 -21
  227. data/lib/rubocop/cop/style/redundant_regexp_argument.rb +100 -0
  228. data/lib/rubocop/cop/style/redundant_regexp_constructor.rb +46 -0
  229. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +2 -1
  230. data/lib/rubocop/cop/style/redundant_return.rb +8 -3
  231. data/lib/rubocop/cop/style/redundant_self.rb +17 -2
  232. data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +8 -1
  233. data/lib/rubocop/cop/style/redundant_sort.rb +10 -9
  234. data/lib/rubocop/cop/style/redundant_sort_by.rb +2 -2
  235. data/lib/rubocop/cop/style/redundant_string_escape.rb +3 -1
  236. data/lib/rubocop/cop/style/regexp_literal.rb +11 -2
  237. data/lib/rubocop/cop/style/require_order.rb +11 -5
  238. data/lib/rubocop/cop/style/rescue_modifier.rb +1 -3
  239. data/lib/rubocop/cop/style/return_nil.rb +6 -2
  240. data/lib/rubocop/cop/style/return_nil_in_predicate_method_definition.rb +95 -0
  241. data/lib/rubocop/cop/style/sample.rb +2 -1
  242. data/lib/rubocop/cop/style/select_by_regexp.rb +22 -11
  243. data/lib/rubocop/cop/style/self_assignment.rb +1 -1
  244. data/lib/rubocop/cop/style/semicolon.rb +20 -4
  245. data/lib/rubocop/cop/style/signal_exception.rb +1 -1
  246. data/lib/rubocop/cop/style/single_argument_dig.rb +7 -3
  247. data/lib/rubocop/cop/style/single_line_do_end_block.rb +67 -0
  248. data/lib/rubocop/cop/style/single_line_methods.rb +1 -1
  249. data/lib/rubocop/cop/style/slicing_with_range.rb +1 -1
  250. data/lib/rubocop/cop/style/sole_nested_conditional.rb +6 -2
  251. data/lib/rubocop/cop/style/special_global_vars.rb +3 -4
  252. data/lib/rubocop/cop/style/string_chars.rb +1 -0
  253. data/lib/rubocop/cop/style/string_literals_in_interpolation.rb +30 -5
  254. data/lib/rubocop/cop/style/strip.rb +7 -4
  255. data/lib/rubocop/cop/style/super_with_args_parentheses.rb +35 -0
  256. data/lib/rubocop/cop/style/symbol_array.rb +35 -15
  257. data/lib/rubocop/cop/style/unpack_first.rb +11 -14
  258. data/lib/rubocop/cop/style/yaml_file_read.rb +66 -0
  259. data/lib/rubocop/cop/style/yoda_condition.rb +4 -2
  260. data/lib/rubocop/cop/style/yoda_expression.rb +8 -7
  261. data/lib/rubocop/cop/team.rb +1 -1
  262. data/lib/rubocop/cop/util.rb +1 -1
  263. data/lib/rubocop/cop/utils/regexp_ranges.rb +113 -0
  264. data/lib/rubocop/cop/variable_force/assignment.rb +45 -4
  265. data/lib/rubocop/cop/variable_force/variable_table.rb +2 -2
  266. data/lib/rubocop/cop/variable_force.rb +1 -0
  267. data/lib/rubocop/cops_documentation_generator.rb +1 -1
  268. data/lib/rubocop/ext/regexp_parser.rb +4 -1
  269. data/lib/rubocop/file_finder.rb +4 -7
  270. data/lib/rubocop/formatter/html_formatter.rb +5 -4
  271. data/lib/rubocop/formatter/junit_formatter.rb +1 -1
  272. data/lib/rubocop/lsp/logger.rb +22 -0
  273. data/lib/rubocop/lsp/routes.rb +246 -0
  274. data/lib/rubocop/lsp/runtime.rb +99 -0
  275. data/lib/rubocop/lsp/server.rb +68 -0
  276. data/lib/rubocop/lsp/severity.rb +27 -0
  277. data/lib/rubocop/magic_comment.rb +12 -10
  278. data/lib/rubocop/options.rb +11 -1
  279. data/lib/rubocop/result_cache.rb +5 -2
  280. data/lib/rubocop/rspec/cop_helper.rb +1 -1
  281. data/lib/rubocop/rspec/shared_contexts.rb +2 -3
  282. data/lib/rubocop/runner.rb +6 -4
  283. data/lib/rubocop/server/cache.rb +1 -0
  284. data/lib/rubocop/server/client_command/exec.rb +3 -2
  285. data/lib/rubocop/string_interpreter.rb +3 -3
  286. data/lib/rubocop/target_finder.rb +7 -3
  287. data/lib/rubocop/target_ruby.rb +12 -7
  288. data/lib/rubocop/version.rb +10 -6
  289. data/lib/rubocop.rb +19 -0
  290. metadata +54 -15
@@ -75,7 +75,7 @@ module RuboCop
75
75
  def right_hand_side(send_node)
76
76
  dot = send_node.loc.dot
77
77
  selector = send_node.loc.selector
78
- if send_node.dot? && selector && same_line?(dot, selector)
78
+ if (send_node.dot? || send_node.safe_navigation?) && selector && same_line?(dot, selector)
79
79
  dot.join(selector)
80
80
  elsif selector
81
81
  selector
@@ -179,10 +179,10 @@ module RuboCop
179
179
  # a.b
180
180
  # .c
181
181
  def semantic_alignment_base(node, rhs)
182
- return unless rhs.source.start_with?('.')
182
+ return unless rhs.source.start_with?('.', '&.')
183
183
 
184
184
  node = semantic_alignment_node(node)
185
- return unless node&.loc&.selector
185
+ return unless node&.loc&.selector && node.loc.dot
186
186
 
187
187
  node.loc.dot.join(node.loc.selector)
188
188
  end
@@ -204,6 +204,10 @@ module RuboCop
204
204
  dot_right_above = get_dot_right_above(node)
205
205
  return dot_right_above if dot_right_above
206
206
 
207
+ if (multiline_block_chain_node = find_multiline_block_chain_node(node))
208
+ return multiline_block_chain_node
209
+ end
210
+
207
211
  node = first_call_has_a_dot(node)
208
212
  return if node.loc.dot.line != node.first_line
209
213
 
@@ -219,6 +223,17 @@ module RuboCop
219
223
  end
220
224
  end
221
225
 
226
+ def find_multiline_block_chain_node(node)
227
+ return unless (block_node = node.each_descendant(:block, :numblock).first)
228
+ return unless block_node.multiline? && block_node.parent.call_type?
229
+
230
+ if node.receiver.call_type?
231
+ node.receiver
232
+ else
233
+ block_node.parent
234
+ end
235
+ end
236
+
222
237
  def first_call_has_a_dot(node)
223
238
  # descend to root of method chain
224
239
  node = node.receiver while node.receiver
@@ -48,6 +48,10 @@ module RuboCop
48
48
 
49
49
  MSG = 'Redundant line break detected.'
50
50
 
51
+ def on_lvasgn(node)
52
+ super unless end_with_percent_blank_string?(processed_source)
53
+ end
54
+
51
55
  def on_send(node)
52
56
  # Include "the whole expression".
53
57
  node = node.parent while node.parent&.send_type? ||
@@ -58,9 +62,14 @@ module RuboCop
58
62
 
59
63
  register_offense(node)
60
64
  end
65
+ alias on_csend on_send
61
66
 
62
67
  private
63
68
 
69
+ def end_with_percent_blank_string?(processed_source)
70
+ processed_source.buffer.source.end_with?("%\n\n")
71
+ end
72
+
64
73
  def check_assignment(node, _rhs)
65
74
  return unless offense?(node)
66
75
 
@@ -98,9 +107,9 @@ module RuboCop
98
107
 
99
108
  def suitable_as_single_line?(node)
100
109
  !comment_within?(node) &&
101
- node.each_descendant(:if, :case, :kwbegin, :def).none? &&
102
- node.each_descendant(:dstr, :str).none?(&:heredoc?) &&
103
- node.each_descendant(:begin).none? { |b| !b.single_line? }
110
+ node.each_descendant(:if, :case, :kwbegin, :def, :defs).none? &&
111
+ node.each_descendant(:dstr, :str).none? { |n| n.heredoc? || n.value.include?("\n") } &&
112
+ node.each_descendant(:begin, :sym).none? { |b| !b.single_line? }
104
113
  end
105
114
 
106
115
  def convertible_block?(node)
@@ -110,7 +119,9 @@ module RuboCop
110
119
  end
111
120
 
112
121
  def comment_within?(node)
113
- processed_source.comments.map(&:loc).map(&:line).any? do |comment_line_number|
122
+ comment_line_numbers = processed_source.comments.map { |comment| comment.loc.line }
123
+
124
+ comment_line_numbers.any? do |comment_line_number|
114
125
  comment_line_number >= node.first_line && comment_line_number <= node.last_line
115
126
  end
116
127
  end
@@ -125,7 +136,7 @@ module RuboCop
125
136
  .gsub(/" *\\\n\s*'/, %q(" + ')) # Double quote, backslash, and then single quote
126
137
  .gsub(/' *\\\n\s*"/, %q(' + ")) # Single quote, backslash, and then double quote
127
138
  .gsub(/(["']) *\\\n\s*\1/, '') # Double or single quote, backslash, then same quote
128
- .gsub(/\n\s*(?=\.\w)/, '') # Extra space within method chaining
139
+ .gsub(/\n\s*(?=(&)?\.\w)/, '') # Extra space within method chaining which includes `&.`
129
140
  .gsub(/\s*\\?\n\s*/, ' ') # Any other line break, with or without backslash
130
141
  end
131
142
 
@@ -29,7 +29,7 @@ module RuboCop
29
29
  MSG = '`%<kw_loc>s` at %<kw_loc_line>d, %<kw_loc_column>d is not ' \
30
30
  'aligned with `%<beginning>s` at ' \
31
31
  '%<begin_loc_line>d, %<begin_loc_column>d.'
32
- ANCESTOR_TYPES = %i[kwbegin def defs class module block].freeze
32
+ ANCESTOR_TYPES = %i[kwbegin def defs class module block numblock].freeze
33
33
  ANCESTOR_TYPES_WITH_ACCESS_MODIFIERS = %i[def defs].freeze
34
34
  ALTERNATIVE_ACCESS_MODIFIERS = %i[public_class_method private_class_method].freeze
35
35
 
@@ -95,7 +95,7 @@ module RuboCop
95
95
  def alignment_source(node, starting_loc)
96
96
  ending_loc =
97
97
  case node.type
98
- when :block, :kwbegin
98
+ when :block, :numblock, :kwbegin
99
99
  node.loc.begin
100
100
  when :def, :defs, :class, :module,
101
101
  :lvasgn, :ivasgn, :cvasgn, :gvasgn, :casgn
@@ -104,8 +104,8 @@ module RuboCop
104
104
  mlhs_node, = *node
105
105
  mlhs_node.source_range
106
106
  else
107
- # It is a wrapper with access modifier.
108
- node.child_nodes.first.loc.name
107
+ # It is a wrapper with receiver of object attribute or access modifier.
108
+ node.receiver&.source_range || node.child_nodes.first.loc.name
109
109
  end
110
110
 
111
111
  range_between(starting_loc.begin_pos, ending_loc.end_pos).source
@@ -25,10 +25,15 @@ module RuboCop
25
25
 
26
26
  MSG = 'Put method call on a separate line if chained to a single line block.'
27
27
 
28
+ def self.autocorrect_incompatible_with
29
+ [Style::MapToHash]
30
+ end
31
+
28
32
  def on_send(node)
29
33
  range = offending_range(node)
30
34
  add_offense(range) { |corrector| corrector.insert_before(range, "\n") } if range
31
35
  end
36
+ alias on_csend on_send
32
37
 
33
38
  private
34
39
 
@@ -24,7 +24,15 @@ module RuboCop
24
24
  end
25
25
 
26
26
  def kind(token)
27
- 'comma' if token.comma?
27
+ 'comma' if token.comma? && !before_semicolon?(token)
28
+ end
29
+
30
+ private
31
+
32
+ def before_semicolon?(token)
33
+ tokens = processed_source.tokens
34
+
35
+ tokens[tokens.index(token) + 1].semicolon?
28
36
  end
29
37
  end
30
38
  end
@@ -31,7 +31,7 @@ module RuboCop
31
31
  private
32
32
 
33
33
  def whitespace_after_operator?(node)
34
- node.receiver.loc.column - node.loc.column > 1
34
+ node.receiver.source_range.begin_pos - node.source_range.begin_pos > 1
35
35
  end
36
36
  end
37
37
  end
@@ -19,7 +19,7 @@ module RuboCop
19
19
  # foo &. bar
20
20
  # foo &. bar&. buzz
21
21
  # RuboCop:: Cop
22
- # RuboCop:: Cop:: Cop
22
+ # RuboCop:: Cop:: Base
23
23
  # :: RuboCop::Cop
24
24
  #
25
25
  # # good
@@ -31,7 +31,7 @@ module RuboCop
31
31
  # foo&.bar
32
32
  # foo&.bar&.buzz
33
33
  # RuboCop::Cop
34
- # RuboCop::Cop::Cop
34
+ # RuboCop::Cop::Base
35
35
  # ::RuboCop::Cop
36
36
  #
37
37
  class SpaceAroundMethodCallOperator < Base
@@ -50,6 +50,20 @@ module RuboCop
50
50
  #
51
51
  # # good
52
52
  # a ** b
53
+ #
54
+ # @example EnforcedStyleForRationalLiterals: no_space (default)
55
+ # # bad
56
+ # 1 / 48r
57
+ #
58
+ # # good
59
+ # 1/48r
60
+ #
61
+ # @example EnforcedStyleForRationalLiterals: space
62
+ # # bad
63
+ # 1/48r
64
+ #
65
+ # # good
66
+ # 1 / 48r
53
67
  class SpaceAroundOperators < Base
54
68
  include PrecedingFollowingAlignment
55
69
  include RangeHelp
@@ -64,7 +78,7 @@ module RuboCop
64
78
  end
65
79
 
66
80
  def on_sclass(node)
67
- check_operator(:sclass, node.loc.operator, node.source_range)
81
+ check_operator(:sclass, node.loc.operator, node)
68
82
  end
69
83
 
70
84
  def on_pair(node)
@@ -72,14 +86,14 @@ module RuboCop
72
86
 
73
87
  return if hash_table_style? && !node.parent.pairs_on_same_line?
74
88
 
75
- check_operator(:pair, node.loc.operator, node.source_range)
89
+ check_operator(:pair, node.loc.operator, node)
76
90
  end
77
91
 
78
92
  def on_if(node)
79
93
  return unless node.ternary?
80
94
 
81
- check_operator(:if, node.loc.question, node.if_branch.source_range)
82
- check_operator(:if, node.loc.colon, node.else_branch.source_range)
95
+ check_operator(:if, node.loc.question, node.if_branch)
96
+ check_operator(:if, node.loc.colon, node.else_branch)
83
97
  end
84
98
 
85
99
  def on_resbody(node)
@@ -87,7 +101,7 @@ module RuboCop
87
101
 
88
102
  _, variable, = *node
89
103
 
90
- check_operator(:resbody, node.loc.assoc, variable.source_range)
104
+ check_operator(:resbody, node.loc.assoc, variable)
91
105
  end
92
106
 
93
107
  def on_send(node)
@@ -96,7 +110,7 @@ module RuboCop
96
110
  if node.setter_method?
97
111
  on_special_asgn(node)
98
112
  elsif regular_operator?(node)
99
- check_operator(:send, node.loc.selector, node.first_argument.source_range)
113
+ check_operator(:send, node.loc.selector, node.first_argument)
100
114
  end
101
115
  end
102
116
 
@@ -105,7 +119,7 @@ module RuboCop
105
119
 
106
120
  return unless rhs
107
121
 
108
- check_operator(:assignment, node.loc.operator, rhs.source_range)
122
+ check_operator(:assignment, node.loc.operator, rhs)
109
123
  end
110
124
 
111
125
  def on_casgn(node)
@@ -113,7 +127,7 @@ module RuboCop
113
127
 
114
128
  return unless right
115
129
 
116
- check_operator(:assignment, node.loc.operator, right.source_range)
130
+ check_operator(:assignment, node.loc.operator, right)
117
131
  end
118
132
 
119
133
  def on_binary(node)
@@ -121,7 +135,7 @@ module RuboCop
121
135
 
122
136
  return unless rhs
123
137
 
124
- check_operator(:binary, node.loc.operator, rhs.source_range)
138
+ check_operator(:binary, node.loc.operator, rhs)
125
139
  end
126
140
 
127
141
  def on_special_asgn(node)
@@ -129,13 +143,13 @@ module RuboCop
129
143
 
130
144
  return unless right
131
145
 
132
- check_operator(:special_asgn, node.loc.operator, right.source_range)
146
+ check_operator(:special_asgn, node.loc.operator, right)
133
147
  end
134
148
 
135
149
  def on_match_pattern(node)
136
150
  return if target_ruby_version < 3.0
137
151
 
138
- check_operator(:match_pattern, node.loc.operator, node.source_range)
152
+ check_operator(:match_pattern, node.loc.operator, node)
139
153
  end
140
154
 
141
155
  alias on_or on_binary
@@ -153,7 +167,9 @@ module RuboCop
153
167
  private
154
168
 
155
169
  def regular_operator?(send_node)
156
- !send_node.unary_operation? && !send_node.dot? && operator_with_regular_syntax?(send_node)
170
+ return false if send_node.unary_operation? || send_node.dot? || send_node.double_colon?
171
+
172
+ operator_with_regular_syntax?(send_node)
157
173
  end
158
174
 
159
175
  def operator_with_regular_syntax?(send_node)
@@ -166,7 +182,7 @@ module RuboCop
166
182
 
167
183
  offense(type, operator, with_space, right_operand) do |msg|
168
184
  add_offense(operator, message: msg) do |corrector|
169
- autocorrect(corrector, with_space)
185
+ autocorrect(corrector, with_space, right_operand)
170
186
  end
171
187
  end
172
188
  end
@@ -176,11 +192,15 @@ module RuboCop
176
192
  yield msg if msg
177
193
  end
178
194
 
179
- def autocorrect(corrector, range)
180
- if range.source.include?('**') && !space_around_exponent_operator?
195
+ def autocorrect(corrector, range, right_operand)
196
+ range_source = range.source
197
+
198
+ if range_source.include?('**') && !space_around_exponent_operator?
181
199
  corrector.replace(range, '**')
182
- elsif range.source.end_with?("\n")
183
- corrector.replace(range, " #{range.source.strip}\n")
200
+ elsif range_source.include?('/') && !space_around_slash_operator?(right_operand)
201
+ corrector.replace(range, '/')
202
+ elsif range_source.end_with?("\n")
203
+ corrector.replace(range, " #{range_source.strip}\n")
184
204
  else
185
205
  enclose_operator_with_space(corrector, range)
186
206
  end
@@ -200,14 +220,14 @@ module RuboCop
200
220
  end
201
221
 
202
222
  def offense_message(type, operator, with_space, right_operand)
203
- if should_not_have_surrounding_space?(operator)
223
+ if should_not_have_surrounding_space?(operator, right_operand)
204
224
  return if with_space.is?(operator.source)
205
225
 
206
226
  "Space around operator `#{operator.source}` detected."
207
227
  elsif !/^\s.*\s$/.match?(with_space.source)
208
228
  "Surrounding space missing for operator `#{operator.source}`."
209
229
  elsif excess_leading_space?(type, operator, with_space) ||
210
- excess_trailing_space?(right_operand, with_space)
230
+ excess_trailing_space?(right_operand.source_range, with_space)
211
231
  "Operator `#{operator.source}` should be surrounded " \
212
232
  'by a single space.'
213
233
  end
@@ -245,12 +265,24 @@ module RuboCop
245
265
  cop_config['EnforcedStyleForExponentOperator'] == 'space'
246
266
  end
247
267
 
268
+ def space_around_slash_operator?(right_operand)
269
+ return true unless right_operand.rational_type?
270
+
271
+ cop_config['EnforcedStyleForRationalLiterals'] == 'space'
272
+ end
273
+
248
274
  def force_equal_sign_alignment?
249
275
  config.for_cop('Layout/ExtraSpacing')['ForceEqualSignAlignment']
250
276
  end
251
277
 
252
- def should_not_have_surrounding_space?(operator)
253
- operator.is?('**') ? !space_around_exponent_operator? : false
278
+ def should_not_have_surrounding_space?(operator, right_operand)
279
+ if operator.is?('**')
280
+ !space_around_exponent_operator?
281
+ elsif operator.is?('/')
282
+ !space_around_slash_operator?(right_operand)
283
+ else
284
+ false
285
+ end
254
286
  end
255
287
  end
256
288
  end
@@ -236,6 +236,8 @@ module RuboCop
236
236
  end
237
237
 
238
238
  def offense(begin_pos, end_pos, msg, style_param = 'EnforcedStyle')
239
+ return if begin_pos > end_pos
240
+
239
241
  range = range_between(begin_pos, end_pos)
240
242
  add_offense(range, message: msg) do |corrector|
241
243
  case range.source
@@ -168,7 +168,7 @@ module RuboCop
168
168
  # follows, and that the rules for space inside don't apply.
169
169
  return true if token2.comment?
170
170
 
171
- return true unless same_line?(token1, token2) && !token1.space_after?
171
+ !same_line?(token1, token2) || token1.space_after?
172
172
  end
173
173
  end
174
174
  end
@@ -35,7 +35,7 @@ module RuboCop
35
35
  def check(node)
36
36
  expression = node.source
37
37
  op = node.loc.operator.source
38
- escaped_op = op.gsub(/\./, '\.')
38
+ escaped_op = op.gsub('.', '\.')
39
39
 
40
40
  # account for multiline range literals
41
41
  expression.sub!(/#{escaped_op}\n\s*/, op)
@@ -51,6 +51,7 @@ module RuboCop
51
51
  # there could be good reasons why it needs to end with a certain
52
52
  # number of newlines.
53
53
  return if ends_in_end?(processed_source)
54
+ return if end_with_percent_blank_string?(processed_source)
54
55
 
55
56
  whitespace_at_end = buffer.source[/\s*\Z/]
56
57
  blank_lines = whitespace_at_end.count("\n") - 1
@@ -86,6 +87,10 @@ module RuboCop
86
87
  extra&.strip&.start_with?('__END__')
87
88
  end
88
89
 
90
+ def end_with_percent_blank_string?(processed_source)
91
+ processed_source.buffer.source.end_with?("%\n\n")
92
+ end
93
+
89
94
  def message(wanted_blank_lines, blank_lines)
90
95
  case blank_lines
91
96
  when -1
@@ -52,6 +52,8 @@ module RuboCop
52
52
  # expect { do_something }.to not_change { object.attribute }
53
53
  #
54
54
  class AmbiguousBlockAssociation < Base
55
+ extend AutoCorrector
56
+
55
57
  include AllowedMethods
56
58
  include AllowedPattern
57
59
 
@@ -68,7 +70,9 @@ module RuboCop
68
70
 
69
71
  message = message(node)
70
72
 
71
- add_offense(node, message: message)
73
+ add_offense(node, message: message) do |corrector|
74
+ wrap_in_parentheses(corrector, node)
75
+ end
72
76
  end
73
77
  alias on_csend on_send
74
78
 
@@ -89,6 +93,14 @@ module RuboCop
89
93
 
90
94
  format(MSG, param: block_param.source, method: block_param.send_node.source)
91
95
  end
96
+
97
+ def wrap_in_parentheses(corrector, node)
98
+ range = node.loc.selector.end.join(node.first_argument.source_range.begin)
99
+
100
+ corrector.remove(range)
101
+ corrector.insert_before(range, '(')
102
+ corrector.insert_after(node.last_argument, ')')
103
+ end
92
104
  end
93
105
  end
94
106
  end
@@ -17,24 +17,24 @@ module RuboCop
17
17
  #
18
18
  # @example
19
19
  # # bad
20
- # if some_var = true
20
+ # if some_var = value
21
21
  # do_something
22
22
  # end
23
23
  #
24
24
  # # good
25
- # if some_var == true
25
+ # if some_var == value
26
26
  # do_something
27
27
  # end
28
28
  #
29
29
  # @example AllowSafeAssignment: true (default)
30
30
  # # good
31
- # if (some_var = true)
31
+ # if (some_var = value)
32
32
  # do_something
33
33
  # end
34
34
  #
35
35
  # @example AllowSafeAssignment: false
36
36
  # # bad
37
- # if (some_var = true)
37
+ # if (some_var = value)
38
38
  # do_something
39
39
  # end
40
40
  #
@@ -6,10 +6,10 @@ module RuboCop
6
6
  # Checks for places where binary operator has identical operands.
7
7
  #
8
8
  # It covers arithmetic operators: `-`, `/`, `%`;
9
- # comparison operators: `==`, `===`, `=~`, `>`, `>=`, `<`, `<=`;
9
+ # comparison operators: `==`, `===`, `=~`, `>`, `>=`, `<`, ``<=``;
10
10
  # bitwise operators: `|`, `^`, `&`;
11
11
  # boolean operators: `&&`, `||`
12
- # and "spaceship" operator - `<=>`.
12
+ # and "spaceship" operator - ``<=>``.
13
13
  #
14
14
  # Simple arithmetic operations are allowed by this cop: `+`, `*`, `**`, `<<` and `>>`.
15
15
  # Although these can be rewritten in a different way, it should not be necessary to
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Lint
6
- # Checks for overwriting an exception with an exception result by use `rescue =>`.
6
+ # Checks for overwriting an exception with an exception result by use ``rescue =>``.
7
7
  #
8
8
  # You intended to write as `rescue StandardError`.
9
9
  # However, you have written `rescue => StandardError`.
@@ -66,12 +66,10 @@ module RuboCop
66
66
  # end
67
67
  class Debugger < Base
68
68
  MSG = 'Remove debugger entry point `%<source>s`.'
69
+ BLOCK_TYPES = %i[block numblock kwbegin].freeze
69
70
 
70
71
  def on_send(node)
71
- return unless debugger_method?(node)
72
-
73
- # Basically, debugger methods are not used as a method argument without arguments.
74
- return if node.arguments.empty? && node.each_ancestor(:send, :csend).any?
72
+ return if !debugger_method?(node) || assumed_usage_context?(node)
75
73
 
76
74
  add_offense(node)
77
75
  end
@@ -90,11 +88,21 @@ module RuboCop
90
88
  end
91
89
 
92
90
  def debugger_method?(send_node)
93
- return if send_node.parent&.send_type? && send_node.parent.receiver == send_node
91
+ return false if send_node.parent&.send_type? && send_node.parent.receiver == send_node
94
92
 
95
93
  debugger_methods.include?(chained_method_name(send_node))
96
94
  end
97
95
 
96
+ def assumed_usage_context?(node)
97
+ # Basically, debugger methods are not used as a method argument without arguments.
98
+ return false unless node.arguments.empty? && node.each_ancestor(:send, :csend).any?
99
+ return true if assumed_argument?(node)
100
+
101
+ node.each_ancestor.none? do |ancestor|
102
+ BLOCK_TYPES.include?(ancestor.type) || ancestor.lambda_or_proc?
103
+ end
104
+ end
105
+
98
106
  def chained_method_name(send_node)
99
107
  chained_method_name = send_node.method_name.to_s
100
108
  receiver = send_node.receiver
@@ -105,6 +113,12 @@ module RuboCop
105
113
  end
106
114
  chained_method_name
107
115
  end
116
+
117
+ def assumed_argument?(node)
118
+ parent = node.parent
119
+
120
+ parent.call_type? || parent.literal? || parent.pair_type?
121
+ end
108
122
  end
109
123
  end
110
124
  end
@@ -4,6 +4,7 @@ module RuboCop
4
4
  module Cop
5
5
  module Lint
6
6
  # Checks for duplicated keys in hash literals.
7
+ # This cop considers both primitive types and constants for the hash keys.
7
8
  #
8
9
  # This cop mirrors a warning in Ruby 2.2.
9
10
  #
@@ -24,7 +25,7 @@ module RuboCop
24
25
  MSG = 'Duplicated key in hash literal.'
25
26
 
26
27
  def on_hash(node)
27
- keys = node.keys.select(&:recursive_basic_literal?)
28
+ keys = node.keys.select { |key| key.recursive_basic_literal? || key.const_type? }
28
29
 
29
30
  return unless duplicates?(keys)
30
31
 
@@ -253,7 +253,7 @@ module RuboCop
253
253
  # Assume that if a method definition is inside any block call which
254
254
  # we can't identify, it could be a DSL
255
255
  node.each_ancestor(:block).any? do |ancestor|
256
- ancestor.method_name != :class_eval && !ancestor.class_constructor?
256
+ !ancestor.method?(:class_eval) && !ancestor.class_constructor?
257
257
  end
258
258
  end
259
259