rubocop 1.43.0 → 1.50.2

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 (286) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/config/default.yml +108 -40
  4. data/lib/rubocop/cli/command/auto_generate_config.rb +7 -0
  5. data/lib/rubocop/cli/command/execute_runner.rb +7 -2
  6. data/lib/rubocop/cli.rb +54 -8
  7. data/lib/rubocop/comment_config.rb +19 -0
  8. data/lib/rubocop/config.rb +3 -3
  9. data/lib/rubocop/config_loader.rb +20 -23
  10. data/lib/rubocop/config_loader_resolver.rb +3 -4
  11. data/lib/rubocop/cop/autocorrect_logic.rb +29 -13
  12. data/lib/rubocop/cop/base.rb +28 -10
  13. data/lib/rubocop/cop/bundler/gem_comment.rb +1 -1
  14. data/lib/rubocop/cop/commissioner.rb +8 -2
  15. data/lib/rubocop/cop/cop.rb +25 -5
  16. data/lib/rubocop/cop/corrector.rb +11 -3
  17. data/lib/rubocop/cop/correctors/alignment_corrector.rb +2 -2
  18. data/lib/rubocop/cop/correctors/each_to_for_corrector.rb +3 -3
  19. data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +3 -3
  20. data/lib/rubocop/cop/correctors/line_break_corrector.rb +1 -1
  21. data/lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +2 -2
  22. data/lib/rubocop/cop/correctors/ordered_gem_corrector.rb +2 -7
  23. data/lib/rubocop/cop/correctors/parentheses_corrector.rb +1 -1
  24. data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +2 -2
  25. data/lib/rubocop/cop/gemspec/dependency_version.rb +1 -1
  26. data/lib/rubocop/cop/gemspec/deprecated_attribute_assignment.rb +1 -1
  27. data/lib/rubocop/cop/gemspec/development_dependencies.rb +107 -0
  28. data/lib/rubocop/cop/internal_affairs/cop_description.rb +5 -5
  29. data/lib/rubocop/cop/internal_affairs/example_heredoc_delimiter.rb +3 -3
  30. data/lib/rubocop/cop/internal_affairs/inherit_deprecated_cop_class.rb +1 -1
  31. data/lib/rubocop/cop/internal_affairs/location_expression.rb +37 -0
  32. data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +1 -1
  33. data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +1 -1
  34. data/lib/rubocop/cop/internal_affairs/processed_source_buffer_name.rb +42 -0
  35. data/lib/rubocop/cop/internal_affairs/redundant_let_rubocop_config_new.rb +11 -3
  36. data/lib/rubocop/cop/internal_affairs/redundant_location_argument.rb +1 -1
  37. data/lib/rubocop/cop/internal_affairs/redundant_message_argument.rb +1 -1
  38. data/lib/rubocop/cop/internal_affairs/redundant_source_range.rb +66 -0
  39. data/lib/rubocop/cop/internal_affairs.rb +3 -0
  40. data/lib/rubocop/cop/layout/array_alignment.rb +1 -1
  41. data/lib/rubocop/cop/layout/block_end_newline.rb +7 -15
  42. data/lib/rubocop/cop/layout/class_structure.rb +8 -19
  43. data/lib/rubocop/cop/layout/closing_heredoc_indentation.rb +1 -1
  44. data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +2 -6
  45. data/lib/rubocop/cop/layout/empty_comment.rb +3 -3
  46. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +1 -1
  47. data/lib/rubocop/cop/layout/empty_lines.rb +1 -1
  48. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +2 -0
  49. data/lib/rubocop/cop/layout/end_alignment.rb +9 -1
  50. data/lib/rubocop/cop/layout/extra_spacing.rb +6 -1
  51. data/lib/rubocop/cop/layout/first_argument_indentation.rb +8 -3
  52. data/lib/rubocop/cop/layout/first_array_element_line_break.rb +25 -34
  53. data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +7 -19
  54. data/lib/rubocop/cop/layout/first_method_argument_line_break.rb +42 -52
  55. data/lib/rubocop/cop/layout/first_method_parameter_line_break.rb +38 -55
  56. data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +8 -2
  57. data/lib/rubocop/cop/layout/heredoc_indentation.rb +8 -11
  58. data/lib/rubocop/cop/layout/initial_indentation.rb +1 -1
  59. data/lib/rubocop/cop/layout/leading_comment_space.rb +1 -1
  60. data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +1 -3
  61. data/lib/rubocop/cop/layout/line_continuation_spacing.rb +11 -7
  62. data/lib/rubocop/cop/layout/multiline_array_line_breaks.rb +8 -27
  63. data/lib/rubocop/cop/layout/multiline_hash_key_line_breaks.rb +7 -26
  64. data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +4 -21
  65. data/lib/rubocop/cop/layout/multiline_method_parameter_line_breaks.rb +6 -30
  66. data/lib/rubocop/cop/layout/redundant_line_break.rb +6 -7
  67. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +2 -2
  68. data/lib/rubocop/cop/layout/space_around_keyword.rb +1 -1
  69. data/lib/rubocop/cop/layout/space_around_operators.rb +1 -1
  70. data/lib/rubocop/cop/layout/space_before_first_arg.rb +1 -1
  71. data/lib/rubocop/cop/layout/space_in_lambda_literal.rb +2 -2
  72. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +11 -13
  73. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +1 -1
  74. data/lib/rubocop/cop/layout/space_inside_parens.rb +2 -2
  75. data/lib/rubocop/cop/layout/space_inside_percent_literal_delimiters.rb +1 -1
  76. data/lib/rubocop/cop/layout/space_inside_reference_brackets.rb +4 -4
  77. data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +5 -4
  78. data/lib/rubocop/cop/layout/trailing_whitespace.rb +1 -1
  79. data/lib/rubocop/cop/lint/ambiguous_operator.rb +4 -0
  80. data/lib/rubocop/cop/lint/constant_resolution.rb +1 -1
  81. data/lib/rubocop/cop/lint/debugger.rb +11 -27
  82. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +62 -112
  83. data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +1 -1
  84. data/lib/rubocop/cop/lint/duplicate_match_pattern.rb +122 -0
  85. data/lib/rubocop/cop/lint/duplicate_methods.rb +2 -2
  86. data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +1 -3
  87. data/lib/rubocop/cop/lint/else_layout.rb +3 -7
  88. data/lib/rubocop/cop/lint/empty_block.rb +1 -1
  89. data/lib/rubocop/cop/lint/empty_conditional_body.rb +4 -2
  90. data/lib/rubocop/cop/lint/empty_interpolation.rb +1 -1
  91. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +14 -7
  92. data/lib/rubocop/cop/lint/heredoc_method_call_position.rb +15 -17
  93. data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +1 -1
  94. data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +1 -1
  95. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +46 -4
  96. data/lib/rubocop/cop/lint/missing_super.rb +31 -2
  97. data/lib/rubocop/cop/lint/mixed_regexp_capture_types.rb +1 -0
  98. data/lib/rubocop/cop/lint/nested_method_definition.rb +4 -9
  99. data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +2 -0
  100. data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +6 -10
  101. data/lib/rubocop/cop/lint/percent_string_array.rb +1 -1
  102. data/lib/rubocop/cop/lint/percent_symbol_array.rb +1 -1
  103. data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +11 -5
  104. data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +5 -5
  105. data/lib/rubocop/cop/lint/redundant_require_statement.rb +12 -2
  106. data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +1 -1
  107. data/lib/rubocop/cop/lint/redundant_string_coercion.rb +35 -15
  108. data/lib/rubocop/cop/lint/redundant_with_index.rb +1 -1
  109. data/lib/rubocop/cop/lint/redundant_with_object.rb +1 -1
  110. data/lib/rubocop/cop/lint/refinement_import_methods.rb +2 -1
  111. data/lib/rubocop/cop/lint/rescue_type.rb +3 -3
  112. data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +1 -1
  113. data/lib/rubocop/cop/lint/script_permission.rb +1 -1
  114. data/lib/rubocop/cop/lint/shadowed_exception.rb +1 -1
  115. data/lib/rubocop/cop/lint/syntax.rb +4 -0
  116. data/lib/rubocop/cop/lint/to_enum_arguments.rb +13 -3
  117. data/lib/rubocop/cop/lint/unreachable_loop.rb +3 -3
  118. data/lib/rubocop/cop/lint/useless_access_modifier.rb +10 -7
  119. data/lib/rubocop/cop/lint/useless_method_definition.rb +12 -4
  120. data/lib/rubocop/cop/lint/useless_rescue.rb +20 -2
  121. data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +9 -1
  122. data/lib/rubocop/cop/lint/useless_times.rb +1 -1
  123. data/lib/rubocop/cop/lint/void.rb +24 -11
  124. data/lib/rubocop/cop/metrics/block_length.rb +1 -1
  125. data/lib/rubocop/cop/metrics/block_nesting.rb +2 -2
  126. data/lib/rubocop/cop/metrics/class_length.rb +1 -0
  127. data/lib/rubocop/cop/metrics/collection_literal_length.rb +76 -0
  128. data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +1 -1
  129. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +2 -5
  130. data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +3 -3
  131. data/lib/rubocop/cop/migration/department_name.rb +1 -1
  132. data/lib/rubocop/cop/mixin/alignment.rb +1 -1
  133. data/lib/rubocop/cop/mixin/allowed_methods.rb +3 -1
  134. data/lib/rubocop/cop/mixin/annotation_comment.rb +1 -1
  135. data/lib/rubocop/cop/mixin/code_length.rb +1 -1
  136. data/lib/rubocop/cop/mixin/comments_help.rb +8 -6
  137. data/lib/rubocop/cop/mixin/documentation_comment.rb +1 -1
  138. data/lib/rubocop/cop/mixin/hash_alignment_styles.rb +1 -1
  139. data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +56 -25
  140. data/lib/rubocop/cop/mixin/hash_transform_method.rb +3 -3
  141. data/lib/rubocop/cop/mixin/line_length_help.rb +3 -1
  142. data/lib/rubocop/cop/mixin/min_branches_count.rb +40 -0
  143. data/lib/rubocop/cop/mixin/multiline_element_line_breaks.rb +0 -3
  144. data/lib/rubocop/cop/mixin/ordered_gem_node.rb +1 -1
  145. data/lib/rubocop/cop/mixin/range_help.rb +1 -6
  146. data/lib/rubocop/cop/mixin/statement_modifier.rb +3 -3
  147. data/lib/rubocop/cop/mixin/surrounding_space.rb +3 -3
  148. data/lib/rubocop/cop/mixin/trailing_comma.rb +2 -2
  149. data/lib/rubocop/cop/naming/ascii_identifiers.rb +1 -1
  150. data/lib/rubocop/cop/naming/block_forwarding.rb +4 -0
  151. data/lib/rubocop/cop/naming/class_and_module_camel_case.rb +1 -1
  152. data/lib/rubocop/cop/naming/heredoc_delimiter_case.rb +1 -1
  153. data/lib/rubocop/cop/naming/inclusive_language.rb +23 -4
  154. data/lib/rubocop/cop/naming/method_name.rb +3 -3
  155. data/lib/rubocop/cop/naming/predicate_name.rb +1 -1
  156. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +1 -1
  157. data/lib/rubocop/cop/registry.rb +15 -8
  158. data/lib/rubocop/cop/style/access_modifier_declarations.rb +26 -11
  159. data/lib/rubocop/cop/style/accessor_grouping.rb +39 -17
  160. data/lib/rubocop/cop/style/arguments_forwarding.rb +4 -3
  161. data/lib/rubocop/cop/style/array_intersect.rb +1 -1
  162. data/lib/rubocop/cop/style/ascii_comments.rb +1 -1
  163. data/lib/rubocop/cop/style/bisected_attr_accessor.rb +1 -1
  164. data/lib/rubocop/cop/style/block_comments.rb +1 -1
  165. data/lib/rubocop/cop/style/block_delimiters.rb +17 -2
  166. data/lib/rubocop/cop/style/case_like_if.rb +20 -3
  167. data/lib/rubocop/cop/style/class_and_module_children.rb +4 -11
  168. data/lib/rubocop/cop/style/class_equality_comparison.rb +42 -9
  169. data/lib/rubocop/cop/style/collection_compact.rb +4 -1
  170. data/lib/rubocop/cop/style/command_literal.rb +1 -1
  171. data/lib/rubocop/cop/style/comment_annotation.rb +1 -1
  172. data/lib/rubocop/cop/style/commented_keyword.rb +2 -2
  173. data/lib/rubocop/cop/style/comparable_clamp.rb +125 -0
  174. data/lib/rubocop/cop/style/concat_array_literals.rb +10 -2
  175. data/lib/rubocop/cop/style/conditional_assignment.rb +6 -12
  176. data/lib/rubocop/cop/style/copyright.rb +1 -1
  177. data/lib/rubocop/cop/style/data_inheritance.rb +75 -0
  178. data/lib/rubocop/cop/style/dir_empty.rb +60 -0
  179. data/lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb +2 -2
  180. data/lib/rubocop/cop/style/document_dynamic_eval_definition.rb +2 -2
  181. data/lib/rubocop/cop/style/documentation.rb +11 -5
  182. data/lib/rubocop/cop/style/documentation_method.rb +10 -4
  183. data/lib/rubocop/cop/style/double_negation.rb +2 -2
  184. data/lib/rubocop/cop/style/each_with_object.rb +1 -1
  185. data/lib/rubocop/cop/style/empty_block_parameter.rb +1 -1
  186. data/lib/rubocop/cop/style/empty_lambda_parameter.rb +1 -1
  187. data/lib/rubocop/cop/style/eval_with_location.rb +4 -4
  188. data/lib/rubocop/cop/style/explicit_block_argument.rb +1 -1
  189. data/lib/rubocop/cop/style/file_empty.rb +71 -0
  190. data/lib/rubocop/cop/style/file_read.rb +1 -1
  191. data/lib/rubocop/cop/style/file_write.rb +1 -1
  192. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +1 -1
  193. data/lib/rubocop/cop/style/guard_clause.rb +1 -1
  194. data/lib/rubocop/cop/style/hash_except.rb +4 -4
  195. data/lib/rubocop/cop/style/hash_like_case.rb +3 -9
  196. data/lib/rubocop/cop/style/hash_syntax.rb +5 -2
  197. data/lib/rubocop/cop/style/if_unless_modifier.rb +108 -15
  198. data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +2 -0
  199. data/lib/rubocop/cop/style/infinite_loop.rb +2 -5
  200. data/lib/rubocop/cop/style/inverse_methods.rb +5 -5
  201. data/lib/rubocop/cop/style/invertible_unless_condition.rb +114 -0
  202. data/lib/rubocop/cop/style/map_compact_with_conditional_block.rb +2 -2
  203. data/lib/rubocop/cop/style/map_to_hash.rb +4 -1
  204. data/lib/rubocop/cop/style/map_to_set.rb +4 -1
  205. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +14 -12
  206. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +44 -37
  207. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +2 -0
  208. data/lib/rubocop/cop/style/min_max.rb +3 -3
  209. data/lib/rubocop/cop/style/min_max_comparison.rb +11 -1
  210. data/lib/rubocop/cop/style/mixin_grouping.rb +4 -4
  211. data/lib/rubocop/cop/style/multiline_if_modifier.rb +0 -4
  212. data/lib/rubocop/cop/style/multiline_memoization.rb +2 -2
  213. data/lib/rubocop/cop/style/multiline_method_signature.rb +7 -4
  214. data/lib/rubocop/cop/style/multiline_ternary_operator.rb +18 -3
  215. data/lib/rubocop/cop/style/negated_if_else_condition.rb +13 -12
  216. data/lib/rubocop/cop/style/nil_lambda.rb +2 -2
  217. data/lib/rubocop/cop/style/numbered_parameters_limit.rb +11 -3
  218. data/lib/rubocop/cop/style/one_line_conditional.rb +3 -6
  219. data/lib/rubocop/cop/style/operator_method_call.rb +2 -2
  220. data/lib/rubocop/cop/style/parallel_assignment.rb +29 -19
  221. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +2 -3
  222. data/lib/rubocop/cop/style/percent_q_literals.rb +1 -1
  223. data/lib/rubocop/cop/style/redundant_condition.rb +18 -3
  224. data/lib/rubocop/cop/style/redundant_conditional.rb +0 -4
  225. data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +16 -10
  226. data/lib/rubocop/cop/style/redundant_fetch_block.rb +6 -4
  227. data/lib/rubocop/cop/style/redundant_heredoc_delimiter_quotes.rb +58 -0
  228. data/lib/rubocop/cop/style/redundant_interpolation.rb +2 -2
  229. data/lib/rubocop/cop/style/redundant_line_continuation.rb +179 -0
  230. data/lib/rubocop/cop/style/redundant_parentheses.rb +2 -2
  231. data/lib/rubocop/cop/style/redundant_percent_q.rb +1 -1
  232. data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +7 -8
  233. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +11 -4
  234. data/lib/rubocop/cop/style/redundant_sort.rb +3 -3
  235. data/lib/rubocop/cop/style/redundant_string_escape.rb +3 -4
  236. data/lib/rubocop/cop/style/require_order.rb +3 -12
  237. data/lib/rubocop/cop/style/rescue_standard_error.rb +2 -2
  238. data/lib/rubocop/cop/style/safe_navigation.rb +2 -2
  239. data/lib/rubocop/cop/style/self_assignment.rb +2 -2
  240. data/lib/rubocop/cop/style/semicolon.rb +24 -2
  241. data/lib/rubocop/cop/style/slicing_with_range.rb +1 -1
  242. data/lib/rubocop/cop/style/sole_nested_conditional.rb +3 -3
  243. data/lib/rubocop/cop/style/stderr_puts.rb +1 -1
  244. data/lib/rubocop/cop/style/struct_inheritance.rb +1 -1
  245. data/lib/rubocop/cop/style/symbol_array.rb +1 -1
  246. data/lib/rubocop/cop/style/trailing_body_on_class.rb +1 -0
  247. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +1 -1
  248. data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
  249. data/lib/rubocop/cop/style/unless_logical_operators.rb +1 -0
  250. data/lib/rubocop/cop/style/unpack_first.rb +3 -3
  251. data/lib/rubocop/cop/style/word_array.rb +18 -6
  252. data/lib/rubocop/cop/style/yoda_condition.rb +13 -6
  253. data/lib/rubocop/cop/style/yoda_expression.rb +11 -2
  254. data/lib/rubocop/cop/style/zero_length_predicate.rb +9 -5
  255. data/lib/rubocop/cop/team.rb +30 -22
  256. data/lib/rubocop/cop/util.rb +13 -4
  257. data/lib/rubocop/cop/variable_force/scope.rb +3 -3
  258. data/lib/rubocop/cop/variable_force/variable.rb +5 -3
  259. data/lib/rubocop/cop/variable_force/variable_table.rb +3 -1
  260. data/lib/rubocop/cop/variable_force.rb +1 -1
  261. data/lib/rubocop/cops_documentation_generator.rb +10 -3
  262. data/lib/rubocop/directive_comment.rb +3 -3
  263. data/lib/rubocop/ext/comment.rb +18 -0
  264. data/lib/rubocop/ext/regexp_node.rb +1 -1
  265. data/lib/rubocop/ext/regexp_parser.rb +1 -1
  266. data/lib/rubocop/formatter/junit_formatter.rb +4 -1
  267. data/lib/rubocop/formatter/simple_text_formatter.rb +1 -1
  268. data/lib/rubocop/formatter.rb +0 -1
  269. data/lib/rubocop/options.rb +26 -2
  270. data/lib/rubocop/result_cache.rb +1 -1
  271. data/lib/rubocop/rspec/cop_helper.rb +1 -1
  272. data/lib/rubocop/rspec/expect_offense.rb +6 -4
  273. data/lib/rubocop/rspec/shared_contexts.rb +4 -0
  274. data/lib/rubocop/rspec/support.rb +1 -0
  275. data/lib/rubocop/runner.rb +40 -4
  276. data/lib/rubocop/server/cache.rb +11 -4
  277. data/lib/rubocop/server/cli.rb +37 -18
  278. data/lib/rubocop/server/client_command/exec.rb +1 -1
  279. data/lib/rubocop/server/client_command/start.rb +6 -1
  280. data/lib/rubocop/server/core.rb +24 -9
  281. data/lib/rubocop/server/helper.rb +1 -1
  282. data/lib/rubocop/server/server_command/exec.rb +1 -1
  283. data/lib/rubocop/target_ruby.rb +1 -1
  284. data/lib/rubocop/version.rb +1 -1
  285. data/lib/rubocop.rb +12 -0
  286. metadata +21 -26
@@ -122,8 +122,8 @@ module RuboCop
122
122
  end
123
123
 
124
124
  def safe_to_register_offense?(block, except_key)
125
- extracted = extract_body_if_nagated(block.body)
126
- if extracted.method?('in?') || extracted.method?('include?') || \
125
+ extracted = extract_body_if_negated(block.body)
126
+ if extracted.method?('in?') || extracted.method?('include?') ||
127
127
  extracted.method?('exclude?')
128
128
  return true
129
129
  end
@@ -132,7 +132,7 @@ module RuboCop
132
132
  except_key.sym_type? || except_key.str_type?
133
133
  end
134
134
 
135
- def extract_body_if_nagated(body)
135
+ def extract_body_if_negated(body)
136
136
  return body unless body.method?('!')
137
137
 
138
138
  body.receiver
@@ -161,7 +161,7 @@ module RuboCop
161
161
 
162
162
  def except_key(node)
163
163
  key_argument = node.argument_list.first.source
164
- body = extract_body_if_nagated(node.body)
164
+ body = extract_body_if_negated(node.body)
165
165
  lhs, _method_name, rhs = *body
166
166
  return if [lhs, rhs].map(&:source).none?(key_argument)
167
167
 
@@ -37,6 +37,8 @@ module RuboCop
37
37
  # end
38
38
  #
39
39
  class HashLikeCase < Base
40
+ include MinBranchesCount
41
+
40
42
  MSG = 'Consider replacing `case-when` with a hash lookup.'
41
43
 
42
44
  # @!method hash_like_case?(node)
@@ -49,7 +51,7 @@ module RuboCop
49
51
  PATTERN
50
52
 
51
53
  def on_case(node)
52
- return if node.when_branches.size < min_branches_count
54
+ return unless min_branches_count?(node)
53
55
 
54
56
  hash_like_case?(node) do |condition_nodes, body_nodes|
55
57
  if nodes_of_same_type?(condition_nodes) && nodes_of_same_type?(body_nodes)
@@ -63,14 +65,6 @@ module RuboCop
63
65
  def nodes_of_same_type?(nodes)
64
66
  nodes.all? { |node| node.type == nodes.first.type }
65
67
  end
66
-
67
- def min_branches_count
68
- length = cop_config['MinBranchesCount'] || 3
69
- return length if length.is_a?(Integer) && length.positive?
70
-
71
- warn Rainbow('`MinBranchesCount` needs to be a positive integer!').red
72
- exit!
73
- end
74
68
  end
75
69
  end
76
70
  end
@@ -88,6 +88,9 @@ module RuboCop
88
88
  # {foo: foo, bar: bar}
89
89
  #
90
90
  # # good
91
+ # {foo: foo, bar:}
92
+ #
93
+ # # good
91
94
  # {foo:, bar:}
92
95
  #
93
96
  # @example EnforcedShorthandSyntax: consistent
@@ -207,7 +210,7 @@ module RuboCop
207
210
  return true if /\A[_a-z]\w*[?!]?\z/i.match?(sym_name)
208
211
 
209
212
  # For more complicated hash keys, let the parser validate the syntax.
210
- ProcessedSource.new("{ #{sym_name}: :foo }", target_ruby_version).valid_syntax?
213
+ parse("{ #{sym_name}: :foo }").valid_syntax?
211
214
  end
212
215
 
213
216
  def check(pairs, delim, msg)
@@ -247,7 +250,7 @@ module RuboCop
247
250
  end
248
251
 
249
252
  def argument_without_space?(node)
250
- node.argument? && node.loc.expression.begin_pos == node.parent.loc.selector.end_pos
253
+ node.argument? && node.source_range.begin_pos == node.parent.loc.selector.end_pos
251
254
  end
252
255
 
253
256
  def autocorrect_hash_rockets(corrector, pair_node)
@@ -11,6 +11,32 @@ module RuboCop
11
11
  # cop. The tab size is configured in the `IndentationWidth` of the
12
12
  # `Layout/IndentationStyle` cop.
13
13
  #
14
+ # One-line pattern matching is always allowed. To ensure that there are few cases
15
+ # where the match variable is not used, and to prevent oversights. The variable `x`
16
+ # becomes undefined and raises `NameError` when the following example is changed to
17
+ # the modifier form:
18
+ #
19
+ # [source,ruby]
20
+ # ----
21
+ # if [42] in [x]
22
+ # x # `x` is undefined when using modifier form.
23
+ # end
24
+ # ----
25
+ #
26
+ # NOTE: It is allowed when `defined?` argument has an undefined value,
27
+ # because using the modifier form causes the following incompatibility:
28
+ #
29
+ # [source,ruby]
30
+ # ----
31
+ # unless defined?(undefined_foo)
32
+ # undefined_foo = 'default_value'
33
+ # end
34
+ # undefined_foo # => 'default_value'
35
+ #
36
+ # undefined_bar = 'default_value' unless defined?(undefined_bar)
37
+ # undefined_bar # => nil
38
+ # ----
39
+ #
14
40
  # @example
15
41
  # # bad
16
42
  # if condition
@@ -39,6 +65,7 @@ module RuboCop
39
65
  include LineLengthHelp
40
66
  include AllowedPattern
41
67
  include RangeHelp
68
+ include CommentsHelp
42
69
  extend AutoCorrector
43
70
 
44
71
  MSG_USE_MODIFIER = 'Favor modifier `%<keyword>s` usage when having a ' \
@@ -51,12 +78,10 @@ module RuboCop
51
78
  end
52
79
 
53
80
  def on_if(node)
54
- msg = if single_line_as_modifier?(node) && !named_capture_in_condition?(node)
55
- MSG_USE_MODIFIER
56
- elsif too_long_due_to_modifier?(node)
57
- MSG_USE_NORMAL
58
- end
59
- return unless msg
81
+ condition = node.condition
82
+ return if defined_nodes(condition).any? { |n| defined_argument_is_undefined?(node, n) } ||
83
+ pattern_matching_nodes(condition).any?
84
+ return unless (msg = message(node))
60
85
 
61
86
  add_offense(node.loc.keyword, message: format(msg, keyword: node.keyword)) do |corrector|
62
87
  autocorrect(corrector, node)
@@ -65,28 +90,81 @@ module RuboCop
65
90
 
66
91
  private
67
92
 
93
+ def defined_nodes(condition)
94
+ if condition.defined_type?
95
+ [condition]
96
+ else
97
+ condition.each_descendant.select(&:defined_type?)
98
+ end
99
+ end
100
+
101
+ def defined_argument_is_undefined?(if_node, defined_node)
102
+ defined_argument = defined_node.first_argument
103
+ return false unless defined_argument.lvar_type? || defined_argument.send_type?
104
+
105
+ if_node.left_siblings.none? do |sibling|
106
+ sibling.respond_to?(:lvasgn_type?) && sibling.lvasgn_type? &&
107
+ sibling.name == defined_argument.node_parts[0]
108
+ end
109
+ end
110
+
111
+ def pattern_matching_nodes(condition)
112
+ if condition.match_pattern_type? || condition.match_pattern_p_type?
113
+ [condition]
114
+ else
115
+ condition.each_descendant.select do |node|
116
+ node.match_pattern_type? || node.match_pattern_p_type?
117
+ end
118
+ end
119
+ end
120
+
121
+ def message(node)
122
+ if single_line_as_modifier?(node) && !named_capture_in_condition?(node)
123
+ MSG_USE_MODIFIER
124
+ elsif too_long_due_to_modifier?(node)
125
+ MSG_USE_NORMAL
126
+ end
127
+ end
128
+
68
129
  def autocorrect(corrector, node)
69
130
  replacement = if node.modifier_form?
70
- last_argument = node.if_branch.last_argument if node.if_branch.send_type?
71
-
72
- if last_argument.respond_to?(:heredoc?) && last_argument.heredoc?
73
- heredoc = extract_heredoc_from(last_argument)
74
- remove_heredoc(corrector, heredoc)
75
- to_normal_form_with_heredoc(node, indent(node), heredoc)
76
- else
77
- to_normal_form(node, indent(node))
78
- end
131
+ replacement_for_modifier_form(corrector, node)
79
132
  else
80
133
  to_modifier_form(node)
81
134
  end
82
135
  corrector.replace(node, replacement)
83
136
  end
84
137
 
138
+ def replacement_for_modifier_form(corrector, node) # rubocop:disable Metrics/AbcSize
139
+ comment = comment_on_node_line(node)
140
+ if comment && too_long_due_to_comment_after_modifier?(node, comment)
141
+ remove_comment(corrector, node, comment)
142
+
143
+ return to_modifier_form_with_move_comment(node, indent(node), comment)
144
+ end
145
+
146
+ last_argument = node.if_branch.last_argument if node.if_branch.send_type?
147
+ if last_argument.respond_to?(:heredoc?) && last_argument.heredoc?
148
+ heredoc = extract_heredoc_from(last_argument)
149
+ remove_heredoc(corrector, heredoc)
150
+
151
+ return to_normal_form_with_heredoc(node, indent(node), heredoc)
152
+ end
153
+
154
+ to_normal_form(node, indent(node))
155
+ end
156
+
85
157
  def too_long_due_to_modifier?(node)
86
158
  node.modifier_form? && too_long_single_line?(node) &&
87
159
  !another_statement_on_same_line?(node)
88
160
  end
89
161
 
162
+ def too_long_due_to_comment_after_modifier?(node, comment)
163
+ source_length = processed_source.lines[node.first_line - 1].length
164
+ source_length >= max_line_length &&
165
+ source_length - comment.source_range.length <= max_line_length
166
+ end
167
+
90
168
  def allowed_patterns
91
169
  line_length_config = config.for_cop('Layout/LineLength')
92
170
  line_length_config['AllowedPatterns'] || line_length_config['IgnoredPatterns'] || []
@@ -181,6 +259,13 @@ module RuboCop
181
259
  RUBY
182
260
  end
183
261
 
262
+ def to_modifier_form_with_move_comment(node, indentation, comment)
263
+ <<~RUBY.chomp
264
+ #{comment.source}
265
+ #{indentation}#{node.body.source} #{node.keyword} #{node.condition.source}
266
+ RUBY
267
+ end
268
+
184
269
  def extract_heredoc_from(last_argument)
185
270
  heredoc_body = last_argument.loc.heredoc_body
186
271
  heredoc_end = last_argument.loc.heredoc_end
@@ -193,6 +278,14 @@ module RuboCop
193
278
  corrector.remove(range_by_whole_lines(range, include_final_newline: true))
194
279
  end
195
280
  end
281
+
282
+ def comment_on_node_line(node)
283
+ processed_source.comments.find { |c| same_line?(c, node) }
284
+ end
285
+
286
+ def remove_comment(corrector, _node, comment)
287
+ corrector.remove(range_with_surrounding_space(range: comment.source_range, side: :left))
288
+ end
196
289
  end
197
290
  end
198
291
  end
@@ -118,6 +118,8 @@ module RuboCop
118
118
  end
119
119
 
120
120
  def return_boolean_value?(condition)
121
+ return false unless condition
122
+
121
123
  if condition.begin_type?
122
124
  return_boolean_value?(condition.children.first)
123
125
  elsif condition.or_type?
@@ -21,6 +21,7 @@ module RuboCop
21
21
  # work
22
22
  # end
23
23
  class InfiniteLoop < Base
24
+ include Alignment
24
25
  extend AutoCorrector
25
26
 
26
27
  LEADING_SPACE = /\A(\s*)/.freeze
@@ -106,7 +107,7 @@ module RuboCop
106
107
  else
107
108
  indentation = body.source_range.source_line[LEADING_SPACE]
108
109
 
109
- ['loop do', body.source.gsub(/^/, configured_indent), 'end'].join("\n#{indentation}")
110
+ ['loop do', body.source.gsub(/^/, indentation(node)), 'end'].join("\n#{indentation}")
110
111
  end
111
112
  end
112
113
 
@@ -120,10 +121,6 @@ module RuboCop
120
121
 
121
122
  start_range.join(end_range)
122
123
  end
123
-
124
- def configured_indent
125
- ' ' * config.for_cop('Layout/IndentationWidth')['Width']
126
- end
127
124
  end
128
125
  end
129
126
  end
@@ -155,15 +155,15 @@ module RuboCop
155
155
  end
156
156
 
157
157
  def not_to_receiver(node, method_call)
158
- Parser::Source::Range.new(node.loc.expression.source_buffer,
158
+ Parser::Source::Range.new(node.source_range.source_buffer,
159
159
  node.loc.selector.begin_pos,
160
- method_call.loc.expression.begin_pos)
160
+ method_call.source_range.begin_pos)
161
161
  end
162
162
 
163
163
  def end_parentheses(node, method_call)
164
- Parser::Source::Range.new(node.loc.expression.source_buffer,
165
- method_call.loc.expression.end_pos,
166
- node.loc.expression.end_pos)
164
+ Parser::Source::Range.new(node.source_range.source_buffer,
165
+ method_call.source_range.end_pos,
166
+ node.source_range.end_pos)
167
167
  end
168
168
 
169
169
  # When comparing classes, `!(Integer < Numeric)` is not the same as
@@ -0,0 +1,114 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Style
6
+ # Checks for usages of `unless` which can be replaced by `if` with inverted condition.
7
+ # Code without `unless` is easier to read, but that is subjective, so this cop
8
+ # is disabled by default.
9
+ #
10
+ # Methods that can be inverted should be defined in `InverseMethods`. Note that
11
+ # the relationship of inverse methods needs to be defined in both directions.
12
+ # For example,
13
+ # InverseMethods:
14
+ # :!=: :==
15
+ # :even?: :odd?
16
+ # :odd?: :even?
17
+ #
18
+ # will suggest both `even?` and `odd?` to be inverted, but only `!=` (and not `==`).
19
+ #
20
+ # @safety
21
+ # This cop is unsafe because it cannot be guaranteed that the method
22
+ # and its inverse method are both defined on receiver, and also are
23
+ # actually inverse of each other.
24
+ #
25
+ # @example
26
+ # # bad (simple condition)
27
+ # foo unless !bar
28
+ # foo unless x != y
29
+ # foo unless x >= 10
30
+ # foo unless x.even?
31
+ #
32
+ # # good
33
+ # foo if bar
34
+ # foo if x == y
35
+ # foo if x < 10
36
+ # foo if x.odd?
37
+ #
38
+ # # bad (complex condition)
39
+ # foo unless x != y || x.even?
40
+ #
41
+ # # good
42
+ # foo if x == y && x.odd?
43
+ #
44
+ # # good (if)
45
+ # foo if !condition
46
+ #
47
+ class InvertibleUnlessCondition < Base
48
+ extend AutoCorrector
49
+
50
+ MSG = 'Favor `if` with inverted condition over `unless`.'
51
+
52
+ def on_if(node)
53
+ return unless node.unless?
54
+
55
+ condition = node.condition
56
+ return unless invertible?(condition)
57
+
58
+ add_offense(node) do |corrector|
59
+ corrector.replace(node.loc.keyword, node.inverse_keyword)
60
+ autocorrect(corrector, condition)
61
+ end
62
+ end
63
+
64
+ private
65
+
66
+ def invertible?(node)
67
+ case node.type
68
+ when :begin
69
+ invertible?(node.children.first)
70
+ when :send
71
+ return if inheritance_check?(node)
72
+
73
+ node.method?(:!) || inverse_methods.key?(node.method_name)
74
+ when :or, :and
75
+ invertible?(node.lhs) && invertible?(node.rhs)
76
+ else
77
+ false
78
+ end
79
+ end
80
+
81
+ def inheritance_check?(node)
82
+ argument = node.first_argument
83
+ node.method?(:<) &&
84
+ (argument.const_type? && argument.short_name.to_s.upcase != argument.short_name.to_s)
85
+ end
86
+
87
+ def autocorrect(corrector, node)
88
+ case node.type
89
+ when :begin
90
+ autocorrect(corrector, node.children.first)
91
+ when :send
92
+ autocorrect_send_node(corrector, node)
93
+ when :or, :and
94
+ corrector.replace(node.loc.operator, node.inverse_operator)
95
+ autocorrect(corrector, node.lhs)
96
+ autocorrect(corrector, node.rhs)
97
+ end
98
+ end
99
+
100
+ def autocorrect_send_node(corrector, node)
101
+ if node.method?(:!)
102
+ corrector.remove(node.loc.selector)
103
+ else
104
+ corrector.replace(node.loc.selector, inverse_methods[node.method_name])
105
+ end
106
+ end
107
+
108
+ def inverse_methods
109
+ @inverse_methods ||= cop_config['InverseMethods']
110
+ end
111
+ end
112
+ end
113
+ end
114
+ end
@@ -123,10 +123,10 @@ module RuboCop
123
123
  end
124
124
 
125
125
  def range(node)
126
- buffer = node.loc.expression.source_buffer
126
+ buffer = node.source_range.source_buffer
127
127
  map_node = node.receiver.send_node
128
128
  begin_pos = map_node.loc.selector.begin_pos
129
- end_pos = node.loc.expression.end_pos
129
+ end_pos = node.source_range.end_pos
130
130
 
131
131
  Parser::Source::Range.new(buffer, begin_pos, end_pos)
132
132
  end
@@ -39,7 +39,10 @@ module RuboCop
39
39
 
40
40
  # @!method map_to_h?(node)
41
41
  def_node_matcher :map_to_h?, <<~PATTERN
42
- $(send (block $(send _ {:map :collect}) ...) :to_h)
42
+ {
43
+ $(send ({block numblock} $(send _ {:map :collect}) ...) :to_h)
44
+ $(send $(send _ {:map :collect} (block_pass sym)) :to_h)
45
+ }
43
46
  PATTERN
44
47
 
45
48
  def on_send(node)
@@ -32,7 +32,10 @@ module RuboCop
32
32
 
33
33
  # @!method map_to_set?(node)
34
34
  def_node_matcher :map_to_set?, <<~PATTERN
35
- $(send (block $(send _ {:map :collect}) ...) :to_set)
35
+ {
36
+ $(send ({block numblock} $(send _ {:map :collect}) ...) :to_set)
37
+ $(send $(send _ {:map :collect} (block_pass sym)) :to_set)
38
+ }
36
39
  PATTERN
37
40
 
38
41
  def on_send(node)
@@ -13,8 +13,7 @@ module RuboCop
13
13
 
14
14
  private
15
15
 
16
- # rubocop:disable Metrics/PerceivedComplexity
17
- def omit_parentheses(node)
16
+ def omit_parentheses(node) # rubocop:disable Metrics/PerceivedComplexity
18
17
  return unless node.parenthesized?
19
18
  return if inside_endless_method_def?(node)
20
19
  return if require_parentheses_for_hash_value_omission?(node)
@@ -28,7 +27,6 @@ module RuboCop
28
27
  autocorrect(corrector, node)
29
28
  end
30
29
  end
31
- # rubocop:enable Metrics/PerceivedComplexity
32
30
 
33
31
  def autocorrect(corrector, node)
34
32
  if parentheses_at_the_end_of_multiline_call?(node)
@@ -52,17 +50,13 @@ module RuboCop
52
50
  return false unless (last_argument = node.last_argument)
53
51
  return false if !last_argument.hash_type? || !last_argument.pairs.last&.value_omission?
54
52
 
55
- modifier_form?(node) || exist_next_line_expression?(node)
56
- end
57
-
58
- def modifier_form?(node)
59
- node.parent.respond_to?(:modifier_form?) && node.parent.modifier_form?
53
+ node.parent&.conditional? || !last_expression?(node)
60
54
  end
61
55
 
62
56
  # Require hash value omission be enclosed in parentheses to prevent the following issue:
63
57
  # https://bugs.ruby-lang.org/issues/18396.
64
- def exist_next_line_expression?(node)
65
- node.parent&.assignment? ? node.parent.right_sibling : node.right_sibling
58
+ def last_expression?(node)
59
+ !(node.parent&.assignment? ? node.parent.right_sibling : node.right_sibling)
66
60
  end
67
61
 
68
62
  def syntax_like_method_call?(node)
@@ -90,7 +84,7 @@ module RuboCop
90
84
  .end_with?('(')
91
85
  end
92
86
 
93
- def legitimate_call_with_parentheses?(node)
87
+ def legitimate_call_with_parentheses?(node) # rubocop:disable Metrics/PerceivedComplexity
94
88
  call_in_literals?(node) ||
95
89
  call_with_ambiguous_arguments?(node) ||
96
90
  call_in_logical_operators?(node) ||
@@ -98,7 +92,8 @@ module RuboCop
98
92
  call_in_single_line_inheritance?(node) ||
99
93
  allowed_multiline_call_with_parentheses?(node) ||
100
94
  allowed_chained_call_with_parentheses?(node) ||
101
- assignment_in_condition?(node)
95
+ assignment_in_condition?(node) ||
96
+ forwards_anonymous_rest_arguments?(node)
102
97
  end
103
98
 
104
99
  def call_in_literals?(node)
@@ -216,6 +211,13 @@ module RuboCop
216
211
 
217
212
  parent.assignment? && (grandparent.conditional? || grandparent.when_type?)
218
213
  end
214
+
215
+ def forwards_anonymous_rest_arguments?(node)
216
+ return false unless (last_argument = node.last_argument)
217
+ return true if last_argument.forwarded_restarg_type?
218
+
219
+ last_argument.hash_type? && last_argument.children.first&.forwarded_kwrestarg_type?
220
+ end
219
221
  end
220
222
  # rubocop:enable Metrics/ModuleLength, Metrics/CyclomaticComplexity
221
223
  end
@@ -7,21 +7,19 @@ module RuboCop
7
7
  # method calls containing parameters.
8
8
  #
9
9
  # In the default style (require_parentheses), macro methods are allowed.
10
- # Additional methods can be added to the `AllowedMethods`
11
- # or `AllowedPatterns` list. These options are
12
- # valid only in the default style. Macros can be included by
13
- # either setting `IgnoreMacros` to false or adding specific macros to
14
- # the `IncludedMacros` list.
10
+ # Additional methods can be added to the `AllowedMethods` or
11
+ # `AllowedPatterns` list. These options are valid only in the default
12
+ # style. Macros can be included by either setting `IgnoreMacros` to false
13
+ # or adding specific macros to the `IncludedMacros` list.
15
14
  #
16
- # Precedence of options is all follows:
15
+ # Precedence of options is as follows:
17
16
  #
18
17
  # 1. `AllowedMethods`
19
18
  # 2. `AllowedPatterns`
20
19
  # 3. `IncludedMacros`
21
20
  #
22
- # eg. If a method is listed in both
23
- # `IncludedMacros` and `AllowedMethods`, then the latter takes
24
- # precedence (that is, the method is allowed).
21
+ # If a method is listed in both `IncludedMacros` and `AllowedMethods`,
22
+ # then the latter takes precedence (that is, the method is allowed).
25
23
  #
26
24
  # In the alternative style (omit_parentheses), there are three additional
27
25
  # options.
@@ -40,14 +38,29 @@ module RuboCop
40
38
  # to `true` allows the presence of parentheses in such a method call
41
39
  # even with arguments.
42
40
  #
43
- # NOTE: Parentheses are still allowed in cases where omitting them
44
- # results in ambiguous or syntactically incorrect code. For example,
45
- # parentheses are required around a method with arguments when inside an
46
- # endless method definition introduced in Ruby 3.0. Parentheses are also
47
- # allowed when forwarding arguments with the triple-dot syntax introduced
48
- # in Ruby 2.7 as omitting them starts an endless range.
49
- # And Ruby 3.1's hash omission syntax has a case that requires parentheses
50
- # because of the following issue: https://bugs.ruby-lang.org/issues/18396.
41
+ # NOTE: The style of `omit_parentheses` allows parentheses in cases where
42
+ # omitting them results in ambiguous or syntactically incorrect code.
43
+ #
44
+ # Non-exhaustive list of examples:
45
+ #
46
+ # - Parentheses are required allowed in method calls with arguments inside
47
+ # literals, logical operators, setting default values in position and
48
+ # keyword arguments, chaining and more.
49
+ # - Parentheses are allowed in method calls with arguments inside
50
+ # operators to avoid ambiguity.
51
+ # triple-dot syntax introduced in Ruby 2.7 as omitting them starts an
52
+ # endless range.
53
+ # - Parentheses are allowed when forwarding arguments with the
54
+ # triple-dot syntax introduced in Ruby 2.7 as omitting them starts an
55
+ # endless range.
56
+ # - Parentheses are required in calls with arguments when inside an
57
+ # endless method definition introduced in Ruby 3.0.
58
+ # - Ruby 3.1's hash omission syntax allows parentheses if the method call
59
+ # is in conditionals and requires parentheses if the call
60
+ # is not the value-returning expression. See
61
+ # https://bugs.ruby-lang.org/issues/18396.
62
+ # - Parentheses are required in anonymous arguments, keyword arguments
63
+ # and block passing in Ruby 3.2.
51
64
  #
52
65
  # @example EnforcedStyle: require_parentheses (default)
53
66
  #
@@ -80,34 +93,28 @@ module RuboCop
80
93
  # array.delete e
81
94
  #
82
95
  # # bad
83
- # foo.enforce(strict: true)
96
+ # action.enforce(strict: true)
84
97
  #
85
98
  # # good
86
- # foo.enforce strict: true
99
+ # action.enforce strict: true
87
100
  #
88
101
  # # good
89
- # # Allows parens for calls that won't produce valid Ruby or be ambiguous.
90
- # model.validate strict(true)
102
+ # # Parentheses are allowed for code that can be ambiguous without
103
+ # # them.
104
+ # action.enforce(condition) || other_condition
91
105
  #
92
106
  # # good
93
- # # Allows parens for calls that won't produce valid Ruby or be ambiguous.
107
+ # # Parentheses are allowed for calls that won't produce valid Ruby
108
+ # # without them.
94
109
  # yield path, File.basename(path)
95
110
  #
96
111
  # # good
97
- # # Operators methods calls with parens
98
- # array&.[](index)
99
- #
100
- # # good
101
- # # Operators methods without parens, if you prefer
102
- # array.[] index
103
- #
104
- # # good
105
- # # Operators methods calls with parens
106
- # array&.[](index)
107
- #
108
- # # good
109
- # # Operators methods without parens, if you prefer
110
- # array.[] index
112
+ # # Omitting the parentheses in Ruby 3.1 hash omission syntax can lead
113
+ # # to ambiguous code. We allow them in conditionals and non-last
114
+ # # expressions. See https://bugs.ruby-lang.org/issues/18396
115
+ # if meets(criteria:, action:)
116
+ # safe_action(action) || dangerous_action(action)
117
+ # end
111
118
  #
112
119
  # @example IgnoreMacros: true (default)
113
120
  #
@@ -226,7 +233,7 @@ module RuboCop
226
233
  end
227
234
 
228
235
  def args_end(node)
229
- node.loc.expression.end
236
+ node.source_range.end
230
237
  end
231
238
 
232
239
  def args_parenthesized?(node)