rubocop 1.54.1 → 1.64.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 (297) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +5 -4
  4. data/assets/output.css.erb +159 -0
  5. data/assets/output.html.erb +1 -160
  6. data/config/default.yml +155 -26
  7. data/config/obsoletion.yml +5 -0
  8. data/lib/rubocop/cached_data.rb +11 -3
  9. data/lib/rubocop/cli/command/auto_generate_config.rb +22 -8
  10. data/lib/rubocop/cli/command/lsp.rb +2 -2
  11. data/lib/rubocop/cli/command/show_docs_url.rb +2 -2
  12. data/lib/rubocop/cli.rb +11 -2
  13. data/lib/rubocop/config.rb +36 -12
  14. data/lib/rubocop/config_finder.rb +14 -4
  15. data/lib/rubocop/config_loader.rb +0 -1
  16. data/lib/rubocop/config_obsoletion/parameter_rule.rb +9 -1
  17. data/lib/rubocop/config_obsoletion.rb +11 -8
  18. data/lib/rubocop/config_validator.rb +14 -7
  19. data/lib/rubocop/cop/autocorrect_logic.rb +9 -2
  20. data/lib/rubocop/cop/base.rb +64 -17
  21. data/lib/rubocop/cop/bundler/duplicated_gem.rb +1 -0
  22. data/lib/rubocop/cop/bundler/duplicated_group.rb +127 -0
  23. data/lib/rubocop/cop/bundler/gem_comment.rb +2 -2
  24. data/lib/rubocop/cop/bundler/gem_version.rb +3 -5
  25. data/lib/rubocop/cop/bundler/ordered_gems.rb +9 -1
  26. data/lib/rubocop/cop/correctors/each_to_for_corrector.rb +4 -8
  27. data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +5 -13
  28. data/lib/rubocop/cop/correctors/lambda_literal_to_method_corrector.rb +7 -4
  29. data/lib/rubocop/cop/documentation.rb +16 -6
  30. data/lib/rubocop/cop/exclude_limit.rb +1 -1
  31. data/lib/rubocop/cop/force.rb +12 -0
  32. data/lib/rubocop/cop/gemspec/dependency_version.rb +3 -5
  33. data/lib/rubocop/cop/gemspec/deprecated_attribute_assignment.rb +2 -2
  34. data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +9 -1
  35. data/lib/rubocop/cop/gemspec/required_ruby_version.rb +5 -1
  36. data/lib/rubocop/cop/generator/require_file_injector.rb +1 -1
  37. data/lib/rubocop/cop/internal_affairs/example_description.rb +46 -24
  38. data/lib/rubocop/cop/internal_affairs/method_name_end_with.rb +8 -6
  39. data/lib/rubocop/cop/internal_affairs/method_name_equal.rb +19 -20
  40. data/lib/rubocop/cop/internal_affairs/node_first_or_last_argument.rb +53 -0
  41. data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +123 -29
  42. data/lib/rubocop/cop/internal_affairs/redundant_expect_offense_arguments.rb +34 -0
  43. data/lib/rubocop/cop/internal_affairs/redundant_method_dispatch_node.rb +11 -2
  44. data/lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +2 -0
  45. data/lib/rubocop/cop/internal_affairs.rb +2 -0
  46. data/lib/rubocop/cop/layout/argument_alignment.rb +1 -1
  47. data/lib/rubocop/cop/layout/comment_indentation.rb +1 -1
  48. data/lib/rubocop/cop/layout/dot_position.rb +1 -5
  49. data/lib/rubocop/cop/layout/empty_comment.rb +3 -1
  50. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +42 -9
  51. data/lib/rubocop/cop/layout/empty_line_after_magic_comment.rb +14 -7
  52. data/lib/rubocop/cop/layout/end_alignment.rb +15 -3
  53. data/lib/rubocop/cop/layout/extra_spacing.rb +4 -10
  54. data/lib/rubocop/cop/layout/first_array_element_indentation.rb +24 -7
  55. data/lib/rubocop/cop/layout/first_parameter_indentation.rb +1 -1
  56. data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +2 -2
  57. data/lib/rubocop/cop/layout/heredoc_indentation.rb +4 -1
  58. data/lib/rubocop/cop/layout/indentation_width.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 +17 -9
  61. data/lib/rubocop/cop/layout/line_continuation_spacing.rb +1 -1
  62. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +18 -3
  63. data/lib/rubocop/cop/layout/redundant_line_break.rb +29 -6
  64. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +4 -4
  65. data/lib/rubocop/cop/layout/single_line_block_chain.rb +5 -0
  66. data/lib/rubocop/cop/layout/space_after_not.rb +1 -1
  67. data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +2 -2
  68. data/lib/rubocop/cop/layout/space_around_operators.rb +50 -20
  69. data/lib/rubocop/cop/layout/space_before_block_braces.rb +19 -10
  70. data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +1 -1
  71. data/lib/rubocop/cop/layout/space_inside_parens.rb +1 -1
  72. data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +3 -4
  73. data/lib/rubocop/cop/layout/trailing_empty_lines.rb +5 -0
  74. data/lib/rubocop/cop/lint/assignment_in_condition.rb +6 -6
  75. data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +2 -2
  76. data/lib/rubocop/cop/lint/constant_overwritten_in_rescue.rb +1 -1
  77. data/lib/rubocop/cop/lint/debugger.rb +38 -3
  78. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +1 -1
  79. data/lib/rubocop/cop/lint/duplicate_methods.rb +1 -1
  80. data/lib/rubocop/cop/lint/empty_block.rb +1 -1
  81. data/lib/rubocop/cop/lint/empty_conditional_body.rb +2 -2
  82. data/lib/rubocop/cop/lint/erb_new_arguments.rb +24 -17
  83. data/lib/rubocop/cop/lint/float_comparison.rb +10 -0
  84. data/lib/rubocop/cop/lint/hash_compare_by_identity.rb +2 -1
  85. data/lib/rubocop/cop/lint/it_without_arguments_in_block.rb +56 -0
  86. data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +85 -0
  87. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +1 -1
  88. data/lib/rubocop/cop/lint/mixed_case_range.rb +10 -5
  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 +9 -4
  93. data/lib/rubocop/cop/lint/redundant_require_statement.rb +4 -0
  94. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +72 -8
  95. data/lib/rubocop/cop/lint/redundant_with_index.rb +6 -2
  96. data/lib/rubocop/cop/lint/redundant_with_object.rb +2 -2
  97. data/lib/rubocop/cop/lint/rescue_type.rb +1 -3
  98. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +14 -8
  99. data/lib/rubocop/cop/lint/script_permission.rb +3 -3
  100. data/lib/rubocop/cop/lint/self_assignment.rb +38 -0
  101. data/lib/rubocop/cop/lint/shadowed_argument.rb +1 -0
  102. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +7 -1
  103. data/lib/rubocop/cop/lint/struct_new_override.rb +12 -12
  104. data/lib/rubocop/cop/lint/suppressed_exception.rb +1 -1
  105. data/lib/rubocop/cop/lint/symbol_conversion.rb +7 -2
  106. data/lib/rubocop/cop/lint/syntax.rb +6 -3
  107. data/lib/rubocop/cop/lint/to_enum_arguments.rb +12 -5
  108. data/lib/rubocop/cop/lint/trailing_comma_in_attribute_declaration.rb +1 -1
  109. data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +2 -2
  110. data/lib/rubocop/cop/lint/unreachable_code.rb +4 -2
  111. data/lib/rubocop/cop/lint/unreachable_loop.rb +8 -2
  112. data/lib/rubocop/cop/lint/useless_access_modifier.rb +2 -2
  113. data/lib/rubocop/cop/lint/useless_assignment.rb +38 -12
  114. data/lib/rubocop/cop/lint/useless_times.rb +2 -2
  115. data/lib/rubocop/cop/lint/void.rb +48 -12
  116. data/lib/rubocop/cop/metrics/abc_size.rb +3 -3
  117. data/lib/rubocop/cop/metrics/block_length.rb +1 -1
  118. data/lib/rubocop/cop/metrics/class_length.rb +8 -3
  119. data/lib/rubocop/cop/metrics/method_length.rb +1 -1
  120. data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +7 -7
  121. data/lib/rubocop/cop/mixin/check_line_breakable.rb +1 -1
  122. data/lib/rubocop/cop/mixin/code_length.rb +12 -1
  123. data/lib/rubocop/cop/mixin/comments_help.rb +16 -12
  124. data/lib/rubocop/cop/mixin/configurable_formatting.rb +1 -0
  125. data/lib/rubocop/cop/mixin/def_node.rb +1 -1
  126. data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +23 -13
  127. data/lib/rubocop/cop/mixin/method_complexity.rb +15 -6
  128. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +4 -3
  129. data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +6 -8
  130. data/lib/rubocop/cop/mixin/safe_assignment.rb +1 -1
  131. data/lib/rubocop/cop/mixin/space_before_punctuation.rb +1 -1
  132. data/lib/rubocop/cop/mixin/string_help.rb +4 -2
  133. data/lib/rubocop/cop/mixin/trailing_comma.rb +1 -1
  134. data/lib/rubocop/cop/naming/block_forwarding.rb +34 -7
  135. data/lib/rubocop/cop/naming/constant_name.rb +1 -2
  136. data/lib/rubocop/cop/naming/file_name.rb +3 -3
  137. data/lib/rubocop/cop/naming/heredoc_delimiter_naming.rb +3 -1
  138. data/lib/rubocop/cop/naming/inclusive_language.rb +1 -2
  139. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +1 -1
  140. data/lib/rubocop/cop/naming/predicate_name.rb +2 -2
  141. data/lib/rubocop/cop/registry.rb +1 -1
  142. data/lib/rubocop/cop/security/compound_hash.rb +2 -2
  143. data/lib/rubocop/cop/security/open.rb +2 -2
  144. data/lib/rubocop/cop/style/access_modifier_declarations.rb +52 -2
  145. data/lib/rubocop/cop/style/accessor_grouping.rb +1 -1
  146. data/lib/rubocop/cop/style/alias.rb +10 -8
  147. data/lib/rubocop/cop/style/arguments_forwarding.rb +414 -63
  148. data/lib/rubocop/cop/style/array_first_last.rb +64 -0
  149. data/lib/rubocop/cop/style/array_intersect.rb +13 -5
  150. data/lib/rubocop/cop/style/auto_resource_cleanup.rb +21 -14
  151. data/lib/rubocop/cop/style/bisected_attr_accessor.rb +2 -2
  152. data/lib/rubocop/cop/style/block_delimiters.rb +2 -1
  153. data/lib/rubocop/cop/style/case_like_if.rb +5 -5
  154. data/lib/rubocop/cop/style/class_check.rb +1 -0
  155. data/lib/rubocop/cop/style/class_equality_comparison.rb +7 -0
  156. data/lib/rubocop/cop/style/class_vars.rb +3 -3
  157. data/lib/rubocop/cop/style/collection_compact.rb +21 -11
  158. data/lib/rubocop/cop/style/collection_methods.rb +2 -0
  159. data/lib/rubocop/cop/style/combinable_loops.rb +17 -9
  160. data/lib/rubocop/cop/style/commented_keyword.rb +5 -2
  161. data/lib/rubocop/cop/style/concat_array_literals.rb +2 -1
  162. data/lib/rubocop/cop/style/conditional_assignment.rb +7 -8
  163. data/lib/rubocop/cop/style/copyright.rb +31 -21
  164. data/lib/rubocop/cop/style/date_time.rb +5 -4
  165. data/lib/rubocop/cop/style/documentation.rb +24 -24
  166. data/lib/rubocop/cop/style/documentation_method.rb +20 -0
  167. data/lib/rubocop/cop/style/each_for_simple_loop.rb +7 -7
  168. data/lib/rubocop/cop/style/each_with_object.rb +2 -2
  169. data/lib/rubocop/cop/style/empty_case_condition.rb +6 -1
  170. data/lib/rubocop/cop/style/empty_literal.rb +1 -1
  171. data/lib/rubocop/cop/style/eval_with_location.rb +6 -15
  172. data/lib/rubocop/cop/style/exact_regexp_match.rb +4 -2
  173. data/lib/rubocop/cop/style/explicit_block_argument.rb +2 -2
  174. data/lib/rubocop/cop/style/for.rb +3 -1
  175. data/lib/rubocop/cop/style/format_string.rb +33 -12
  176. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +3 -1
  177. data/lib/rubocop/cop/style/guard_clause.rb +26 -0
  178. data/lib/rubocop/cop/style/hash_conversion.rb +10 -0
  179. data/lib/rubocop/cop/style/hash_each_methods.rb +105 -11
  180. data/lib/rubocop/cop/style/hash_except.rb +2 -1
  181. data/lib/rubocop/cop/style/hash_syntax.rb +24 -2
  182. data/lib/rubocop/cop/style/identical_conditional_branches.rb +28 -3
  183. data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +5 -3
  184. data/lib/rubocop/cop/style/inverse_methods.rb +14 -13
  185. data/lib/rubocop/cop/style/invertible_unless_condition.rb +44 -2
  186. data/lib/rubocop/cop/style/lambda_call.rb +5 -0
  187. data/lib/rubocop/cop/style/map_compact_with_conditional_block.rb +8 -10
  188. data/lib/rubocop/cop/style/map_into_array.rb +175 -0
  189. data/lib/rubocop/cop/style/map_to_hash.rb +18 -8
  190. data/lib/rubocop/cop/style/map_to_set.rb +1 -1
  191. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +22 -6
  192. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +2 -4
  193. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +20 -0
  194. data/lib/rubocop/cop/style/method_def_parentheses.rb +1 -1
  195. data/lib/rubocop/cop/style/missing_respond_to_missing.rb +2 -2
  196. data/lib/rubocop/cop/style/mixin_grouping.rb +1 -1
  197. data/lib/rubocop/cop/style/multiline_block_chain.rb +1 -1
  198. data/lib/rubocop/cop/style/multiline_method_signature.rb +10 -1
  199. data/lib/rubocop/cop/style/multiline_ternary_operator.rb +6 -4
  200. data/lib/rubocop/cop/style/nested_ternary_operator.rb +3 -11
  201. data/lib/rubocop/cop/style/next.rb +1 -1
  202. data/lib/rubocop/cop/style/nil_comparison.rb +2 -0
  203. data/lib/rubocop/cop/style/numeric_literal_prefix.rb +1 -1
  204. data/lib/rubocop/cop/style/numeric_predicate.rb +10 -2
  205. data/lib/rubocop/cop/style/object_then.rb +5 -3
  206. data/lib/rubocop/cop/style/one_line_conditional.rb +1 -1
  207. data/lib/rubocop/cop/style/open_struct_use.rb +1 -1
  208. data/lib/rubocop/cop/style/operator_method_call.rb +8 -2
  209. data/lib/rubocop/cop/style/parallel_assignment.rb +3 -5
  210. data/lib/rubocop/cop/style/parentheses_around_condition.rb +8 -0
  211. data/lib/rubocop/cop/style/raise_args.rb +4 -1
  212. data/lib/rubocop/cop/style/redundant_argument.rb +33 -4
  213. data/lib/rubocop/cop/style/redundant_assignment.rb +10 -2
  214. data/lib/rubocop/cop/style/redundant_begin.rb +9 -1
  215. data/lib/rubocop/cop/style/redundant_conditional.rb +1 -9
  216. data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +5 -4
  217. data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +93 -5
  218. data/lib/rubocop/cop/style/redundant_each.rb +7 -4
  219. data/lib/rubocop/cop/style/redundant_exception.rb +32 -12
  220. data/lib/rubocop/cop/style/redundant_fetch_block.rb +3 -3
  221. data/lib/rubocop/cop/style/redundant_filter_chain.rb +23 -6
  222. data/lib/rubocop/cop/style/redundant_line_continuation.rb +19 -2
  223. data/lib/rubocop/cop/style/redundant_parentheses.rb +71 -22
  224. data/lib/rubocop/cop/style/redundant_percent_q.rb +1 -1
  225. data/lib/rubocop/cop/style/redundant_return.rb +14 -3
  226. data/lib/rubocop/cop/style/redundant_self.rb +17 -2
  227. data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +5 -0
  228. data/lib/rubocop/cop/style/redundant_sort.rb +9 -8
  229. data/lib/rubocop/cop/style/redundant_sort_by.rb +2 -2
  230. data/lib/rubocop/cop/style/redundant_string_escape.rb +1 -1
  231. data/lib/rubocop/cop/style/require_order.rb +1 -1
  232. data/lib/rubocop/cop/style/return_nil.rb +6 -2
  233. data/lib/rubocop/cop/style/return_nil_in_predicate_method_definition.rb +23 -9
  234. data/lib/rubocop/cop/style/sample.rb +3 -4
  235. data/lib/rubocop/cop/style/select_by_regexp.rb +7 -6
  236. data/lib/rubocop/cop/style/self_assignment.rb +1 -1
  237. data/lib/rubocop/cop/style/semicolon.rb +8 -3
  238. data/lib/rubocop/cop/style/send.rb +4 -4
  239. data/lib/rubocop/cop/style/send_with_literal_method_name.rb +90 -0
  240. data/lib/rubocop/cop/style/single_argument_dig.rb +7 -3
  241. data/lib/rubocop/cop/style/single_line_do_end_block.rb +67 -0
  242. data/lib/rubocop/cop/style/slicing_with_range.rb +76 -10
  243. data/lib/rubocop/cop/style/sole_nested_conditional.rb +3 -1
  244. data/lib/rubocop/cop/style/special_global_vars.rb +1 -2
  245. data/lib/rubocop/cop/style/string_chars.rb +1 -0
  246. data/lib/rubocop/cop/style/string_literals_in_interpolation.rb +30 -5
  247. data/lib/rubocop/cop/style/strip.rb +7 -4
  248. data/lib/rubocop/cop/style/super_arguments.rb +156 -0
  249. data/lib/rubocop/cop/style/super_with_args_parentheses.rb +35 -0
  250. data/lib/rubocop/cop/style/symbol_array.rb +35 -15
  251. data/lib/rubocop/cop/style/symbol_proc.rb +68 -5
  252. data/lib/rubocop/cop/style/top_level_method_definition.rb +1 -1
  253. data/lib/rubocop/cop/style/unpack_first.rb +11 -14
  254. data/lib/rubocop/cop/style/yoda_expression.rb +8 -7
  255. data/lib/rubocop/cop/team.rb +5 -0
  256. data/lib/rubocop/cop/utils/regexp_ranges.rb +27 -14
  257. data/lib/rubocop/cop/variable_force/assignment.rb +1 -3
  258. data/lib/rubocop/cops_documentation_generator.rb +15 -3
  259. data/lib/rubocop/directive_comment.rb +10 -8
  260. data/lib/rubocop/ext/regexp_node.rb +9 -4
  261. data/lib/rubocop/file_finder.rb +4 -7
  262. data/lib/rubocop/formatter/clang_style_formatter.rb +3 -7
  263. data/lib/rubocop/formatter/disabled_config_formatter.rb +23 -8
  264. data/lib/rubocop/formatter/formatter_set.rb +7 -1
  265. data/lib/rubocop/formatter/html_formatter.rb +35 -14
  266. data/lib/rubocop/formatter/json_formatter.rb +0 -1
  267. data/lib/rubocop/formatter/junit_formatter.rb +1 -1
  268. data/lib/rubocop/formatter/offense_count_formatter.rb +12 -2
  269. data/lib/rubocop/formatter/tap_formatter.rb +3 -7
  270. data/lib/rubocop/formatter.rb +1 -1
  271. data/lib/rubocop/lockfile.rb +56 -7
  272. data/lib/rubocop/lsp/logger.rb +1 -1
  273. data/lib/rubocop/lsp/routes.rb +43 -31
  274. data/lib/rubocop/lsp/runtime.rb +21 -4
  275. data/lib/rubocop/lsp/server.rb +13 -6
  276. data/lib/rubocop/lsp/severity.rb +1 -1
  277. data/lib/rubocop/lsp.rb +36 -0
  278. data/lib/rubocop/magic_comment.rb +13 -11
  279. data/lib/rubocop/options.rb +14 -11
  280. data/lib/rubocop/path_util.rb +6 -2
  281. data/lib/rubocop/rake_task.rb +1 -1
  282. data/lib/rubocop/result_cache.rb +4 -1
  283. data/lib/rubocop/rspec/cop_helper.rb +8 -2
  284. data/lib/rubocop/rspec/expect_offense.rb +16 -8
  285. data/lib/rubocop/rspec/shared_contexts.rb +55 -19
  286. data/lib/rubocop/rspec/support.rb +2 -0
  287. data/lib/rubocop/runner.rb +19 -6
  288. data/lib/rubocop/server/cache.rb +1 -1
  289. data/lib/rubocop/server/client_command/exec.rb +1 -2
  290. data/lib/rubocop/server/server_command/exec.rb +0 -1
  291. data/lib/rubocop/string_interpreter.rb +3 -3
  292. data/lib/rubocop/target_finder.rb +91 -81
  293. data/lib/rubocop/target_ruby.rb +82 -76
  294. data/lib/rubocop/version.rb +19 -4
  295. data/lib/rubocop.rb +9 -0
  296. metadata +29 -16
  297. /data/lib/rubocop/formatter/{git_hub_actions_formatter.rb → github_actions_formatter.rb} +0 -0
@@ -32,27 +32,27 @@ module RuboCop
32
32
 
33
33
  send_node = node.send_node
34
34
 
35
- range = send_node.receiver.source_range.join(send_node.loc.selector)
36
-
37
- add_offense(range) do |corrector|
35
+ add_offense(send_node) do |corrector|
38
36
  range_type, min, max = each_range(node)
39
37
 
40
38
  max += 1 if range_type == :irange
41
39
 
42
- corrector.replace(node.send_node, "#{max - min}.times")
40
+ corrector.replace(send_node, "#{max - min}.times")
43
41
  end
44
42
  end
45
43
 
46
44
  private
47
45
 
48
46
  def offending?(node)
47
+ return false unless node.arguments.empty?
48
+
49
49
  each_range_with_zero_origin?(node) || each_range_without_block_argument?(node)
50
50
  end
51
51
 
52
52
  # @!method each_range(node)
53
53
  def_node_matcher :each_range, <<~PATTERN
54
54
  (block
55
- (send
55
+ (call
56
56
  (begin
57
57
  (${irange erange}
58
58
  (int $_) (int $_)))
@@ -64,7 +64,7 @@ module RuboCop
64
64
  # @!method each_range_with_zero_origin?(node)
65
65
  def_node_matcher :each_range_with_zero_origin?, <<~PATTERN
66
66
  (block
67
- (send
67
+ (call
68
68
  (begin
69
69
  ({irange erange}
70
70
  (int 0) (int _)))
@@ -76,7 +76,7 @@ module RuboCop
76
76
  # @!method each_range_without_block_argument?(node)
77
77
  def_node_matcher :each_range_without_block_argument?, <<~PATTERN
78
78
  (block
79
- (send
79
+ (call
80
80
  (begin
81
81
  ({irange erange}
82
82
  (int _) (int _)))
@@ -58,12 +58,12 @@ module RuboCop
58
58
 
59
59
  # @!method each_with_object_block_candidate?(node)
60
60
  def_node_matcher :each_with_object_block_candidate?, <<~PATTERN
61
- (block $(send _ {:inject :reduce} _) $_ $_)
61
+ (block $(call _ {:inject :reduce} _) $_ $_)
62
62
  PATTERN
63
63
 
64
64
  # @!method each_with_object_numblock_candidate?(node)
65
65
  def_node_matcher :each_with_object_numblock_candidate?, <<~PATTERN
66
- (numblock $(send _ {:inject :reduce} _) 2 $_)
66
+ (numblock $(call _ {:inject :reduce} _) 2 $_)
67
67
  PATTERN
68
68
 
69
69
  def autocorrect_block(corrector, node, return_value)
@@ -40,9 +40,13 @@ module RuboCop
40
40
  extend AutoCorrector
41
41
 
42
42
  MSG = 'Do not use empty `case` condition, instead use an `if` expression.'
43
+ NOT_SUPPORTED_PARENT_TYPES = %i[return break next send csend].freeze
43
44
 
45
+ # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
44
46
  def on_case(case_node)
45
- return if case_node.condition
47
+ if case_node.condition || NOT_SUPPORTED_PARENT_TYPES.include?(case_node.parent&.type)
48
+ return
49
+ end
46
50
 
47
51
  branch_bodies = [*case_node.when_branches.map(&:body), case_node.else_branch].compact
48
52
 
@@ -52,6 +56,7 @@ module RuboCop
52
56
 
53
57
  add_offense(case_node.loc.keyword) { |corrector| autocorrect(corrector, case_node) }
54
58
  end
59
+ # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
55
60
 
56
61
  private
57
62
 
@@ -83,7 +83,7 @@ module RuboCop
83
83
  parent = node.parent
84
84
  return false unless parent && %i[send super zsuper].include?(parent.type)
85
85
 
86
- node.equal?(parent.arguments.first) && !parentheses?(node.parent)
86
+ node.equal?(parent.first_argument) && !parentheses?(node.parent)
87
87
  end
88
88
 
89
89
  def replacement_range(node)
@@ -84,7 +84,7 @@ module RuboCop
84
84
  # are considered.
85
85
  return if node.method?(:eval) && !valid_eval_receiver?(node.receiver)
86
86
 
87
- code = node.arguments.first
87
+ code = node.first_argument
88
88
  return unless code && (code.str_type? || code.dstr_type?)
89
89
 
90
90
  check_location(node, code)
@@ -128,17 +128,6 @@ module RuboCop
128
128
  node.method?(:eval) ? node.arguments.size >= 2 : true
129
129
  end
130
130
 
131
- # FIXME: It's a Style/ConditionalAssignment's false positive.
132
- # rubocop:disable Style/ConditionalAssignment
133
- def with_lineno?(node)
134
- if node.method?(:eval)
135
- node.arguments.size == 4
136
- else
137
- node.arguments.size == 3
138
- end
139
- end
140
- # rubocop:enable Style/ConditionalAssignment
141
-
142
131
  def add_offense_for_incorrect_line(method_name, line_node, sign, line_diff)
143
132
  expected = expected_line(sign, line_diff)
144
133
  message = format(MSG_INCORRECT_LINE,
@@ -152,7 +141,7 @@ module RuboCop
152
141
  end
153
142
 
154
143
  def check_file(node, file_node)
155
- return true if special_file_keyword?(file_node)
144
+ return if special_file_keyword?(file_node)
156
145
 
157
146
  message = format(MSG_INCORRECT_FILE,
158
147
  method_name: node.method_name,
@@ -165,7 +154,9 @@ module RuboCop
165
154
  end
166
155
 
167
156
  def check_line(node, code)
168
- line_node = node.arguments.last
157
+ line_node = node.last_argument
158
+ return if line_node.variable? || (line_node.send_type? && !line_node.method?(:+))
159
+
169
160
  line_diff = line_difference(line_node, code)
170
161
  if line_diff.zero?
171
162
  add_offense_for_same_line(node, line_node)
@@ -227,7 +218,7 @@ module RuboCop
227
218
  end
228
219
 
229
220
  def missing_line(node, code)
230
- line_diff = line_difference(node.arguments.last, code)
221
+ line_diff = line_difference(node.last_argument, code)
231
222
  sign = line_diff.positive? ? :+ : :-
232
223
  expected_line(sign, line_diff)
233
224
  end
@@ -30,7 +30,7 @@ module RuboCop
30
30
 
31
31
  # @!method exact_regexp_match(node)
32
32
  def_node_matcher :exact_regexp_match, <<~PATTERN
33
- (send
33
+ (call
34
34
  _ {:=~ :=== :!~ :match :match?}
35
35
  (regexp
36
36
  (str $_)
@@ -38,17 +38,19 @@ module RuboCop
38
38
  PATTERN
39
39
 
40
40
  def on_send(node)
41
+ return unless (receiver = node.receiver)
41
42
  return unless (regexp = exact_regexp_match(node))
42
43
 
43
44
  parsed_regexp = Regexp::Parser.parse(regexp)
44
45
  return unless exact_match_pattern?(parsed_regexp)
45
46
 
46
- prefer = "#{node.receiver.source} #{new_method(node)} '#{parsed_regexp[1].text}'"
47
+ prefer = "#{receiver.source} #{new_method(node)} '#{parsed_regexp[1].text}'"
47
48
 
48
49
  add_offense(node, message: format(MSG, prefer: prefer)) do |corrector|
49
50
  corrector.replace(node, prefer)
50
51
  end
51
52
  end
53
+ alias on_csend on_send
52
54
 
53
55
  private
54
56
 
@@ -86,7 +86,7 @@ module RuboCop
86
86
 
87
87
  def extract_block_name(def_node)
88
88
  if def_node.block_argument?
89
- def_node.arguments.last.name
89
+ def_node.last_argument.name
90
90
  else
91
91
  'block'
92
92
  end
@@ -127,7 +127,7 @@ module RuboCop
127
127
  end
128
128
 
129
129
  def insert_argument(node, corrector, block_name)
130
- last_arg = node.arguments.last
130
+ last_arg = node.last_argument
131
131
  arg_range = range_with_surrounding_comma(last_arg.source_range, :right)
132
132
  replacement = " &#{block_name}"
133
133
  replacement = ",#{replacement}" unless arg_range.source.end_with?(',')
@@ -66,6 +66,8 @@ module RuboCop
66
66
  return unless suspect_enumerable?(node)
67
67
 
68
68
  if style == :for
69
+ return unless node.receiver
70
+
69
71
  add_offense(node, message: PREFER_FOR) do |corrector|
70
72
  EachToForCorrector.new(node).call(corrector)
71
73
  opposite_style_detected
@@ -80,7 +82,7 @@ module RuboCop
80
82
  private
81
83
 
82
84
  def suspect_enumerable?(node)
83
- node.multiline? && node.send_node.method?(:each) && !node.send_node.arguments?
85
+ node.multiline? && node.method?(:each) && !node.send_node.arguments?
84
86
  end
85
87
  end
86
88
  end
@@ -4,36 +4,48 @@ module RuboCop
4
4
  module Cop
5
5
  module Style
6
6
  # Enforces the use of a single string formatting utility.
7
- # Valid options include Kernel#format, Kernel#sprintf and String#%.
7
+ # Valid options include `Kernel#format`, `Kernel#sprintf`, and `String#%`.
8
8
  #
9
- # The detection of String#% cannot be implemented in a reliable
9
+ # The detection of `String#%` cannot be implemented in a reliable
10
10
  # manner for all cases, so only two scenarios are considered -
11
11
  # if the first argument is a string literal and if the second
12
12
  # argument is an array literal.
13
13
  #
14
+ # Autocorrection will be applied when using argument is a literal or known built-in conversion
15
+ # methods such as `to_d`, `to_f`, `to_h`, `to_i`, `to_r`, `to_s`, and `to_sym` on variables,
16
+ # provided that their return value is not an array. For example, when using `to_s`,
17
+ # `'%s' % [1, 2, 3].to_s` can be autocorrected without any incompatibility:
18
+ #
19
+ # [source,ruby]
20
+ # ----
21
+ # '%s' % [1, 2, 3] #=> '1'
22
+ # format('%s', [1, 2, 3]) #=> '[1, 2, 3]'
23
+ # '%s' % [1, 2, 3].to_s #=> '[1, 2, 3]'
24
+ # ----
25
+ #
14
26
  # @example EnforcedStyle: format (default)
15
27
  # # bad
16
- # puts sprintf('%10s', 'hoge')
17
- # puts '%10s' % 'hoge'
28
+ # puts sprintf('%10s', 'foo')
29
+ # puts '%10s' % 'foo'
18
30
  #
19
31
  # # good
20
- # puts format('%10s', 'hoge')
32
+ # puts format('%10s', 'foo')
21
33
  #
22
34
  # @example EnforcedStyle: sprintf
23
35
  # # bad
24
- # puts format('%10s', 'hoge')
25
- # puts '%10s' % 'hoge'
36
+ # puts format('%10s', 'foo')
37
+ # puts '%10s' % 'foo'
26
38
  #
27
39
  # # good
28
- # puts sprintf('%10s', 'hoge')
40
+ # puts sprintf('%10s', 'foo')
29
41
  #
30
42
  # @example EnforcedStyle: percent
31
43
  # # bad
32
- # puts format('%10s', 'hoge')
33
- # puts sprintf('%10s', 'hoge')
44
+ # puts format('%10s', 'foo')
45
+ # puts sprintf('%10s', 'foo')
34
46
  #
35
47
  # # good
36
- # puts '%10s' % 'hoge'
48
+ # puts '%10s' % 'foo'
37
49
  #
38
50
  class FormatString < Base
39
51
  include ConfigurableEnforcedStyle
@@ -42,6 +54,9 @@ module RuboCop
42
54
  MSG = 'Favor `%<prefer>s` over `%<current>s`.'
43
55
  RESTRICT_ON_SEND = %i[format sprintf %].freeze
44
56
 
57
+ # Known conversion methods whose return value is not an array.
58
+ AUTOCORRECTABLE_METHODS = %i[to_d to_f to_h to_i to_r to_s to_sym].freeze
59
+
45
60
  # @!method formatter(node)
46
61
  def_node_matcher :formatter, <<~PATTERN
47
62
  {
@@ -53,7 +68,7 @@ module RuboCop
53
68
 
54
69
  # @!method variable_argument?(node)
55
70
  def_node_matcher :variable_argument?, <<~PATTERN
56
- (send {str dstr} :% {send_type? lvar_type?})
71
+ (send {str dstr} :% #autocorrectable?)
57
72
  PATTERN
58
73
 
59
74
  def on_send(node)
@@ -70,6 +85,12 @@ module RuboCop
70
85
 
71
86
  private
72
87
 
88
+ def autocorrectable?(node)
89
+ return true if node.lvar_type?
90
+
91
+ node.send_type? && !AUTOCORRECTABLE_METHODS.include?(node.method_name)
92
+ end
93
+
73
94
  def message(detected_style)
74
95
  format(MSG, prefer: method_name(style), current: method_name(detected_style))
75
96
  end
@@ -142,7 +142,9 @@ module RuboCop
142
142
  end
143
143
 
144
144
  next_token = processed_source.tokens[token_number]
145
- token = next_token if Encoding::ENCODING_PATTERN.match?(next_token&.text)
145
+ if next_token&.text&.valid_encoding? && Encoding::ENCODING_PATTERN.match?(next_token.text)
146
+ token = next_token
147
+ end
146
148
 
147
149
  token
148
150
  end
@@ -55,6 +55,25 @@ module RuboCop
55
55
  # foo || raise('exception') if something
56
56
  # ok
57
57
  #
58
+ # # bad
59
+ # define_method(:test) do
60
+ # if something
61
+ # work
62
+ # end
63
+ # end
64
+ #
65
+ # # good
66
+ # define_method(:test) do
67
+ # return unless something
68
+ #
69
+ # work
70
+ # end
71
+ #
72
+ # # also good
73
+ # define_method(:test) do
74
+ # work if something
75
+ # end
76
+ #
58
77
  # @example AllowConsecutiveConditionals: false (default)
59
78
  # # bad
60
79
  # def test
@@ -110,6 +129,13 @@ module RuboCop
110
129
  end
111
130
  alias on_defs on_def
112
131
 
132
+ def on_block(node)
133
+ return unless node.method?(:define_method) || node.method?(:define_singleton_method)
134
+
135
+ on_def(node)
136
+ end
137
+ alias on_numblock on_block
138
+
113
139
  def on_if(node)
114
140
  return if accepted_form?(node)
115
141
 
@@ -10,6 +10,16 @@ module RuboCop
10
10
  # `Hash[*ary]` can be replaced with `ary.each_slice(2).to_h` but it will be complicated.
11
11
  # So, `AllowSplatArgument` option is true by default to allow splat argument for simple code.
12
12
  #
13
+ # @safety
14
+ # This cop's autocorrection is unsafe because `ArgumentError` occurs
15
+ # if the number of elements is odd:
16
+ #
17
+ # [source,ruby]
18
+ # ----
19
+ # Hash[[[1, 2], [3]]] #=> {1=>2, 3=>nil}
20
+ # [[1, 2], [5]].to_h #=> wrong array length at 1 (expected 2, was 1) (ArgumentError)
21
+ # ----
22
+ #
13
23
  # @example
14
24
  # # bad
15
25
  # Hash[ary]
@@ -17,10 +17,16 @@ module RuboCop
17
17
  # @example
18
18
  # # bad
19
19
  # hash.keys.each { |k| p k }
20
- # hash.values.each { |v| p v }
20
+ # hash.each { |k, unused_value| p k }
21
21
  #
22
22
  # # good
23
23
  # hash.each_key { |k| p k }
24
+ #
25
+ # # bad
26
+ # hash.values.each { |v| p v }
27
+ # hash.each { |unused_key, v| p v }
28
+ #
29
+ # # good
24
30
  # hash.each_value { |v| p v }
25
31
  #
26
32
  # @example AllowedReceivers: ['execute']
@@ -33,25 +39,59 @@ module RuboCop
33
39
  extend AutoCorrector
34
40
 
35
41
  MSG = 'Use `%<prefer>s` instead of `%<current>s`.'
42
+ UNUSED_BLOCK_ARG_MSG = "#{MSG.chop} and remove the unused `%<unused_code>s` block argument."
43
+ ARRAY_CONVERTER_METHODS = %i[assoc chunk flatten rassoc sort sort_by to_a].freeze
36
44
 
37
45
  # @!method kv_each(node)
38
46
  def_node_matcher :kv_each, <<~PATTERN
39
- ({block numblock} $(send (send _ ${:keys :values}) :each) ...)
47
+ ({block numblock} $(call (call _ ${:keys :values}) :each) ...)
48
+ PATTERN
49
+
50
+ # @!method each_arguments(node)
51
+ def_node_matcher :each_arguments, <<~PATTERN
52
+ (block (call _ :each)(args $_key $_value) ...)
40
53
  PATTERN
41
54
 
42
55
  # @!method kv_each_with_block_pass(node)
43
56
  def_node_matcher :kv_each_with_block_pass, <<~PATTERN
44
- (send $(send _ ${:keys :values}) :each (block_pass (sym _)))
57
+ (call $(call _ ${:keys :values}) :each (block_pass (sym _)))
45
58
  PATTERN
46
59
 
47
60
  def on_block(node)
61
+ return unless handleable?(node)
62
+
48
63
  kv_each(node) do |target, method|
49
- register_kv_offense(target, method)
64
+ register_kv_offense(target, method) and return
50
65
  end
51
- end
52
66
 
67
+ return unless (key, value = each_arguments(node))
68
+
69
+ check_unused_block_args(node, key, value)
70
+ end
53
71
  alias on_numblock on_block
54
72
 
73
+ # rubocop:disable Metrics/AbcSize
74
+ def check_unused_block_args(node, key, value)
75
+ return if node.body.nil?
76
+
77
+ value_unused = unused_block_arg_exist?(node, value)
78
+ key_unused = unused_block_arg_exist?(node, key)
79
+ return if value_unused && key_unused
80
+
81
+ if value_unused
82
+ message = message('each_key', node.method_name, value.source)
83
+ unused_range = key.source_range.end.join(value.source_range.end)
84
+
85
+ register_each_args_offense(node, message, 'each_key', unused_range)
86
+ elsif key_unused
87
+ message = message('each_value', node.method_name, key.source)
88
+ unused_range = key.source_range.begin.join(value.source_range.begin)
89
+
90
+ register_each_args_offense(node, message, 'each_value', unused_range)
91
+ end
92
+ end
93
+ # rubocop:enable Metrics/AbcSize
94
+
55
95
  def on_block_pass(node)
56
96
  kv_each_with_block_pass(node.parent) do |target, method|
57
97
  register_kv_with_block_pass_offense(node, target, method)
@@ -60,27 +100,81 @@ module RuboCop
60
100
 
61
101
  private
62
102
 
103
+ def handleable?(node)
104
+ return false if use_array_converter_method_as_preceding?(node)
105
+ return false unless (root_receiver = root_receiver(node))
106
+
107
+ !root_receiver.literal? || root_receiver.hash_type?
108
+ end
109
+
63
110
  def register_kv_offense(target, method)
64
111
  return unless (parent_receiver = target.receiver.receiver)
65
112
  return if allowed_receiver?(parent_receiver)
66
113
 
67
- add_offense(kv_range(target), message: format_message(method)) do |corrector|
114
+ current = target.receiver.loc.selector.join(target.source_range.end).source
115
+
116
+ add_offense(kv_range(target), message: format_message(method, current)) do |corrector|
68
117
  correct_key_value_each(target, corrector)
69
118
  end
70
119
  end
71
120
 
121
+ def unused_block_arg_exist?(node, block_arg)
122
+ lvar_sources = node.body.each_descendant(:lvar).map(&:source)
123
+
124
+ if block_arg.mlhs_type?
125
+ block_arg.each_descendant(:arg, :restarg).all? do |block_arg|
126
+ lvar_sources.none?(block_arg.source.delete_prefix('*'))
127
+ end
128
+ else
129
+ lvar_sources.none?(block_arg.source.delete_prefix('*'))
130
+ end
131
+ end
132
+
133
+ def message(prefer, method_name, unused_code)
134
+ format(
135
+ UNUSED_BLOCK_ARG_MSG, prefer: prefer, current: method_name, unused_code: unused_code
136
+ )
137
+ end
138
+
139
+ def register_each_args_offense(node, message, prefer, unused_range)
140
+ add_offense(node, message: message) do |corrector|
141
+ corrector.replace(node.send_node.loc.selector, prefer)
142
+ corrector.remove(unused_range)
143
+ end
144
+ end
145
+
72
146
  def register_kv_with_block_pass_offense(node, target, method)
73
147
  return unless (parent_receiver = node.parent.receiver.receiver)
74
148
  return if allowed_receiver?(parent_receiver)
75
149
 
76
- range = target.loc.selector.with(end_pos: node.parent.loc.selector.end_pos)
77
- add_offense(range, message: format_message(method)) do |corrector|
150
+ range = target.loc.selector.join(node.parent.loc.selector.end)
151
+
152
+ add_offense(range, message: format_message(method, range.source)) do |corrector|
78
153
  corrector.replace(range, "each_#{method[0..-2]}")
79
154
  end
80
155
  end
81
156
 
82
- def format_message(method_name)
83
- format(MSG, prefer: "each_#{method_name[0..-2]}", current: "#{method_name}.each")
157
+ def use_array_converter_method_as_preceding?(node)
158
+ return false unless (preceding_method = node.children.first.children.first)
159
+ unless preceding_method.call_type? ||
160
+ preceding_method.block_type? || preceding_method.numblock_type?
161
+ return false
162
+ end
163
+
164
+ ARRAY_CONVERTER_METHODS.include?(preceding_method.method_name)
165
+ end
166
+
167
+ def root_receiver(node)
168
+ receiver = node.receiver
169
+ if receiver&.receiver
170
+ root_receiver(receiver)
171
+ else
172
+ receiver
173
+ end
174
+ end
175
+
176
+ def format_message(method_name, current)
177
+ format(MSG, prefer: "each_#{method_name[0..-2]}", current: current)
84
178
  end
85
179
 
86
180
  def check_argument(variable)
@@ -103,7 +197,7 @@ module RuboCop
103
197
  name = "each_#{node.receiver.method_name.to_s.chop}"
104
198
  return correct_implicit(node, corrector, name) unless receiver
105
199
 
106
- new_source = receiver.source + ".#{name}"
200
+ new_source = receiver.source + "#{node.loc.dot.source}#{name}"
107
201
  corrector.replace(node, new_source)
108
202
  end
109
203
 
@@ -43,7 +43,7 @@ module RuboCop
43
43
  # @!method bad_method_with_poro?(node)
44
44
  def_node_matcher :bad_method_with_poro?, <<~PATTERN
45
45
  (block
46
- (send _ _)
46
+ (call _ _)
47
47
  (args
48
48
  $(arg _)
49
49
  (arg _))
@@ -86,6 +86,7 @@ module RuboCop
86
86
  corrector.replace(range, preferred_method)
87
87
  end
88
88
  end
89
+ alias on_csend on_send
89
90
 
90
91
  private
91
92
 
@@ -29,6 +29,8 @@ module RuboCop
29
29
  # * never - forces use of explicit hash literal value
30
30
  # * either - accepts both shorthand and explicit use of hash literal value
31
31
  # * consistent - forces use of the 3.1 syntax only if all values can be omitted in the hash
32
+ # * either_consistent - accepts both shorthand and explicit use of hash literal value,
33
+ # but they must be consistent
32
34
  #
33
35
  # @example EnforcedStyle: ruby19 (default)
34
36
  # # bad
@@ -110,6 +112,22 @@ module RuboCop
110
112
  # # good - can't omit `baz`
111
113
  # {foo: foo, bar: baz}
112
114
  #
115
+ # @example EnforcedShorthandSyntax: either_consistent
116
+ #
117
+ # # good - `foo` and `bar` values can be omitted, but they are consistent, so it's accepted
118
+ # {foo: foo, bar: bar}
119
+ #
120
+ # # bad - `bar` value can be omitted
121
+ # {foo:, bar: bar}
122
+ #
123
+ # # bad - mixed syntaxes
124
+ # {foo:, bar: baz}
125
+ #
126
+ # # good
127
+ # {foo:, bar:}
128
+ #
129
+ # # good - can't omit `baz`
130
+ # {foo: foo, bar: baz}
113
131
  class HashSyntax < Base
114
132
  include ConfigurableEnforcedStyle
115
133
  include HashShorthandSyntax
@@ -195,6 +213,7 @@ module RuboCop
195
213
  acceptable_19_syntax_symbol?(pair.key.source)
196
214
  end
197
215
 
216
+ # rubocop:disable Metrics/CyclomaticComplexity
198
217
  def acceptable_19_syntax_symbol?(sym_name)
199
218
  sym_name.delete_prefix!(':')
200
219
 
@@ -209,9 +228,12 @@ module RuboCop
209
228
  # Most hash keys can be matched against a simple regex.
210
229
  return true if /\A[_a-z]\w*[?!]?\z/i.match?(sym_name)
211
230
 
212
- # For more complicated hash keys, let the parser validate the syntax.
213
- parse("{ #{sym_name}: :foo }").valid_syntax?
231
+ return false if target_ruby_version <= 2.1
232
+
233
+ (sym_name.start_with?("'") && sym_name.end_with?("'")) ||
234
+ (sym_name.start_with?('"') && sym_name.end_with?('"'))
214
235
  end
236
+ # rubocop:enable Metrics/CyclomaticComplexity
215
237
 
216
238
  def check(pairs, delim, msg)
217
239
  pairs.each do |pair|