sonicop 26.8.112 → 26.8.113

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 (343) hide show
  1. checksums.yaml +4 -4
  2. data/Cargo.lock +11 -11
  3. data/Cargo.toml +4 -4
  4. data/README.ja.md +36 -23
  5. data/README.md +38 -26
  6. data/lib/sonicop/version.rb +1 -1
  7. data/src/config/inheritance.rs +45 -3
  8. data/src/engine.rs +11 -7
  9. data/src/lib.rs +1 -0
  10. data/src/nul_bytes.rs +2 -6
  11. data/src/parser.rs +37 -0
  12. data/src/profile.rs +13 -1
  13. data/src/rules/bundler/duplicated_group.rs +3 -2
  14. data/src/rules/bundler/gem_comment.rs +5 -4
  15. data/src/rules/gemspec/attribute_assignment.rs +4 -3
  16. data/src/rules/gemspec/deprecated_attribute_assignment.rs +7 -6
  17. data/src/rules/gemspec/duplicated_assignment.rs +4 -3
  18. data/src/rules/gemspec/require_mfa.rs +10 -9
  19. data/src/rules/gemspec/required_ruby_version.rs +3 -2
  20. data/src/rules/gemspec/support.rs +3 -2
  21. data/src/rules/layout/array_alignment.rs +1 -2
  22. data/src/rules/layout/block_end_newline.rs +5 -5
  23. data/src/rules/layout/class_structure.rs +5 -3
  24. data/src/rules/layout/closing_heredoc_indentation.rs +4 -3
  25. data/src/rules/layout/closing_parenthesis_indentation.rs +1 -2
  26. data/src/rules/layout/condition_position.rs +3 -2
  27. data/src/rules/layout/def_end_alignment.rs +2 -2
  28. data/src/rules/layout/dot_position.rs +1 -2
  29. data/src/rules/layout/empty_line_after_guard_clause.rs +3 -6
  30. data/src/rules/layout/empty_line_after_multiline_condition.rs +5 -5
  31. data/src/rules/layout/empty_lines_around_access_modifier.rs +2 -3
  32. data/src/rules/layout/empty_lines_around_arguments.rs +4 -4
  33. data/src/rules/layout/empty_lines_around_exception_handling_keywords.rs +1 -2
  34. data/src/rules/layout/empty_lines_around_method_body.rs +3 -2
  35. data/src/rules/layout/end_alignment.rs +2 -2
  36. data/src/rules/layout/extra_spacing.rs +7 -6
  37. data/src/rules/layout/first_array_element_indentation.rs +1 -2
  38. data/src/rules/layout/first_hash_element_indentation.rs +8 -6
  39. data/src/rules/layout/hash_alignment.rs +4 -4
  40. data/src/rules/layout/heredoc_argument_closing_parenthesis.rs +6 -5
  41. data/src/rules/layout/heredoc_indentation.rs +4 -3
  42. data/src/rules/layout/indentation_style.rs +4 -3
  43. data/src/rules/layout/indentation_width.rs +14 -13
  44. data/src/rules/layout/line_continuation_leading_space.rs +4 -3
  45. data/src/rules/layout/line_continuation_spacing.rs +2 -2
  46. data/src/rules/layout/line_length.rs +101 -57
  47. data/src/rules/layout/multiline_assignment_layout.rs +4 -3
  48. data/src/rules/layout/multiline_block_layout.rs +1 -2
  49. data/src/rules/layout/multiline_expression.rs +60 -31
  50. data/src/rules/layout/multiline_hash_brace_layout.rs +4 -3
  51. data/src/rules/layout/multiline_method_call_indentation.rs +1 -1
  52. data/src/rules/layout/multiline_operation_indentation.rs +3 -3
  53. data/src/rules/layout/redundant_line_break.rs +3 -2
  54. data/src/rules/layout/single_line_block_chain.rs +4 -3
  55. data/src/rules/layout/space_around_block_parameters.rs +1 -2
  56. data/src/rules/layout/space_around_equals_in_parameter_default.rs +1 -2
  57. data/src/rules/layout/space_around_operators.rs +1 -2
  58. data/src/rules/layout/space_before_brackets.rs +6 -5
  59. data/src/rules/layout/space_before_comma.rs +3 -2
  60. data/src/rules/layout/space_inside_range_literal.rs +8 -6
  61. data/src/rules/layout/support.rs +9 -7
  62. data/src/rules/layout/tokens.rs +15 -6
  63. data/src/rules/lint/access_modifier.rs +19 -10
  64. data/src/rules/lint/ambiguity.rs +2 -2
  65. data/src/rules/lint/ambiguous_block_association.rs +7 -10
  66. data/src/rules/lint/ambiguous_regexp_literal.rs +7 -5
  67. data/src/rules/lint/array_literal_in_regexp.rs +4 -3
  68. data/src/rules/lint/assignment_in_condition.rs +3 -2
  69. data/src/rules/lint/blocks.rs +2 -1
  70. data/src/rules/lint/boolean_symbol.rs +4 -4
  71. data/src/rules/lint/constant_definition_in_block.rs +1 -2
  72. data/src/rules/lint/constant_reassignment.rs +2 -1
  73. data/src/rules/lint/deprecated_open_ssl_constant.rs +1 -2
  74. data/src/rules/lint/disjunctive_assignment_in_constructor.rs +2 -2
  75. data/src/rules/lint/duplicate_branch.rs +6 -5
  76. data/src/rules/lint/duplicate_case_condition.rs +5 -5
  77. data/src/rules/lint/duplicate_hash_key.rs +4 -3
  78. data/src/rules/lint/duplicate_match_pattern.rs +7 -5
  79. data/src/rules/lint/duplicate_methods.rs +4 -3
  80. data/src/rules/lint/duplicate_require.rs +1 -2
  81. data/src/rules/lint/duplicate_set_element.rs +3 -2
  82. data/src/rules/lint/empty_conditional_body.rs +4 -3
  83. data/src/rules/lint/empty_in_pattern.rs +3 -2
  84. data/src/rules/lint/empty_when.rs +4 -4
  85. data/src/rules/lint/ensure_return.rs +3 -2
  86. data/src/rules/lint/float_comparison.rs +8 -6
  87. data/src/rules/lint/format_parameter_mismatch.rs +4 -3
  88. data/src/rules/lint/hash_compare_by_identity.rs +5 -4
  89. data/src/rules/lint/heredoc_method_call_position.rs +3 -2
  90. data/src/rules/lint/implicit_string_concatenation.rs +7 -5
  91. data/src/rules/lint/ineffective_access_modifier.rs +5 -4
  92. data/src/rules/lint/inherit_exception.rs +4 -3
  93. data/src/rules/lint/literal_as_condition.rs +5 -3
  94. data/src/rules/lint/literal_assignment_in_condition.rs +4 -3
  95. data/src/rules/lint/literal_in_interpolation.rs +5 -5
  96. data/src/rules/lint/literals.rs +10 -8
  97. data/src/rules/lint/no_return_in_begin_end_blocks.rs +2 -2
  98. data/src/rules/lint/node_equality.rs +8 -5
  99. data/src/rules/lint/non_atomic_file_operation.rs +1 -1
  100. data/src/rules/lint/non_deterministic_require_order.rs +5 -3
  101. data/src/rules/lint/non_local_exit_from_iterator.rs +3 -2
  102. data/src/rules/lint/number_conversion.rs +1 -1
  103. data/src/rules/lint/out_of_range_regexp_ref.rs +6 -4
  104. data/src/rules/lint/redundant_dir_glob_sort.rs +1 -2
  105. data/src/rules/lint/redundant_safe_navigation.rs +4 -3
  106. data/src/rules/lint/redundant_splat_expansion.rs +4 -2
  107. data/src/rules/lint/redundant_string_coercion.rs +3 -2
  108. data/src/rules/lint/regexp_source.rs +2 -2
  109. data/src/rules/lint/require_range_parentheses.rs +5 -5
  110. data/src/rules/lint/rescue_exception.rs +4 -3
  111. data/src/rules/lint/rescue_type.rs +3 -2
  112. data/src/rules/lint/return_in_void_context.rs +2 -2
  113. data/src/rules/lint/safe_navigation_chain.rs +3 -2
  114. data/src/rules/lint/self_assignment.rs +3 -2
  115. data/src/rules/lint/shadowed_argument.rs +2 -2
  116. data/src/rules/lint/shadowed_exception.rs +2 -2
  117. data/src/rules/lint/suppressed_exception_in_number_conversion.rs +4 -3
  118. data/src/rules/lint/symbol_conversion.rs +6 -5
  119. data/src/rules/lint/syntax.rs +4 -3
  120. data/src/rules/lint/triple_quotes.rs +3 -2
  121. data/src/rules/lint/unescaped_bracket_in_regexp.rs +1 -1
  122. data/src/rules/lint/unexpected_block_arity.rs +3 -2
  123. data/src/rules/lint/unmodified_reduce_accumulator.rs +7 -6
  124. data/src/rules/lint/unreachable_pattern_branch.rs +4 -4
  125. data/src/rules/lint/unused_block_argument.rs +2 -2
  126. data/src/rules/lint/unused_method_argument.rs +1 -2
  127. data/src/rules/lint/useless_assignment.rs +3 -2
  128. data/src/rules/lint/useless_constant_scoping.rs +3 -2
  129. data/src/rules/lint/useless_else_without_rescue.rs +4 -3
  130. data/src/rules/lint/useless_rescue.rs +5 -4
  131. data/src/rules/lint/useless_ruby2_keywords.rs +2 -1
  132. data/src/rules/lint/useless_setter_call.rs +5 -4
  133. data/src/rules/lint/useless_times.rs +4 -3
  134. data/src/rules/lint/variable_force.rs +146 -100
  135. data/src/rules/lint/void.rs +5 -4
  136. data/src/rules/metrics/block_nesting.rs +1 -2
  137. data/src/rules/metrics/collection_literal_length.rs +2 -1
  138. data/src/rules/metrics/complexity.rs +18 -13
  139. data/src/rules/metrics/fragments.rs +10 -14
  140. data/src/rules/metrics/locals.rs +23 -12
  141. data/src/rules/metrics/parameter_lists.rs +7 -6
  142. data/src/rules/metrics/support.rs +1 -1
  143. data/src/rules/mod.rs +464 -62
  144. data/src/rules/naming/ascii_identifiers.rs +3 -3
  145. data/src/rules/naming/block_forwarding.rs +9 -8
  146. data/src/rules/naming/constant_name.rs +1 -1
  147. data/src/rules/naming/predicate_method.rs +6 -5
  148. data/src/rules/naming/predicate_prefix.rs +10 -8
  149. data/src/rules/naming/rescued_exceptions_variable_name.rs +8 -6
  150. data/src/rules/naming/support.rs +7 -5
  151. data/src/rules/naming/variable_number.rs +4 -4
  152. data/src/rules/node_ext.rs +1 -1
  153. data/src/rules/ruby_literal.rs +3 -2
  154. data/src/rules/security/compound_hash.rs +3 -2
  155. data/src/rules/security/open.rs +5 -4
  156. data/src/rules/send_node.rs +134 -0
  157. data/src/rules/single_line.rs +4 -4
  158. data/src/rules/style/access_modifier_declarations.rs +1 -1
  159. data/src/rules/style/alias.rs +1 -2
  160. data/src/rules/style/and_or.rs +2 -2
  161. data/src/rules/style/arguments_forwarding.rs +5 -5
  162. data/src/rules/style/array_coercion.rs +5 -5
  163. data/src/rules/style/array_first_last.rs +3 -3
  164. data/src/rules/style/array_intersect.rs +2 -2
  165. data/src/rules/style/array_intersect_with_single_element.rs +1 -1
  166. data/src/rules/style/attr.rs +1 -1
  167. data/src/rules/style/auto_resource_cleanup.rs +1 -1
  168. data/src/rules/style/bitwise_predicate.rs +2 -2
  169. data/src/rules/style/block_args.rs +1 -1
  170. data/src/rules/style/block_delimiters.rs +7 -6
  171. data/src/rules/style/case_equality.rs +3 -2
  172. data/src/rules/style/case_like_if.rs +1 -1
  173. data/src/rules/style/class_and_module_children.rs +7 -5
  174. data/src/rules/style/class_methods.rs +1 -1
  175. data/src/rules/style/collection_compact.rs +4 -4
  176. data/src/rules/style/combinable_defined.rs +2 -2
  177. data/src/rules/style/combinable_loops.rs +1 -1
  178. data/src/rules/style/comparable_clamp.rs +2 -2
  179. data/src/rules/style/concat_array_literals.rs +3 -3
  180. data/src/rules/style/conditional.rs +8 -1
  181. data/src/rules/style/constant_visibility.rs +3 -3
  182. data/src/rules/style/copyright.rs +1 -1
  183. data/src/rules/style/data_inheritance.rs +1 -1
  184. data/src/rules/style/def_with_parentheses.rs +1 -1
  185. data/src/rules/style/document_dynamic_eval_definition.rs +1 -1
  186. data/src/rules/style/documentation.rs +1 -1
  187. data/src/rules/style/each_for_simple_loop.rs +1 -1
  188. data/src/rules/style/each_with_object.rs +4 -4
  189. data/src/rules/style/empty_block_parameter.rs +1 -1
  190. data/src/rules/style/empty_case_condition.rs +6 -6
  191. data/src/rules/style/empty_class_definition.rs +1 -1
  192. data/src/rules/style/empty_else.rs +1 -1
  193. data/src/rules/style/empty_heredoc.rs +1 -1
  194. data/src/rules/style/empty_lambda_parameter.rs +1 -1
  195. data/src/rules/style/empty_literal.rs +2 -2
  196. data/src/rules/style/empty_method.rs +1 -1
  197. data/src/rules/style/empty_string_inside_interpolation.rs +1 -1
  198. data/src/rules/style/endless.rs +1 -1
  199. data/src/rules/style/env_home.rs +1 -1
  200. data/src/rules/style/even_odd.rs +1 -1
  201. data/src/rules/style/exact_regexp_match.rs +1 -1
  202. data/src/rules/style/expand_path_arguments.rs +3 -3
  203. data/src/rules/style/explicit_block_argument.rs +3 -3
  204. data/src/rules/style/file_open_call.rs +3 -3
  205. data/src/rules/style/file_write.rs +1 -1
  206. data/src/rules/style/for.rs +1 -1
  207. data/src/rules/style/format_string.rs +2 -2
  208. data/src/rules/style/format_string_token.rs +6 -6
  209. data/src/rules/style/guard_clause.rs +8 -7
  210. data/src/rules/style/hash_as_last_array_item.rs +4 -4
  211. data/src/rules/style/hash_each_methods.rs +1 -1
  212. data/src/rules/style/hash_like_case.rs +8 -8
  213. data/src/rules/style/hash_lookup_method.rs +3 -3
  214. data/src/rules/style/hash_subset.rs +16 -10
  215. data/src/rules/style/hash_syntax.rs +4 -4
  216. data/src/rules/style/hash_transform.rs +20 -18
  217. data/src/rules/style/identical_conditional_branches.rs +4 -5
  218. data/src/rules/style/if_inside_else.rs +3 -3
  219. data/src/rules/style/if_unless_modifier.rs +13 -14
  220. data/src/rules/style/if_with_boolean_literal_branches.rs +1 -1
  221. data/src/rules/style/if_with_semicolon.rs +1 -1
  222. data/src/rules/style/in_pattern_then.rs +2 -2
  223. data/src/rules/style/inverse_methods.rs +2 -2
  224. data/src/rules/style/invertible_unless_condition.rs +3 -3
  225. data/src/rules/style/it_block_parameter.rs +1 -1
  226. data/src/rules/style/keyword_arguments_merging.rs +2 -2
  227. data/src/rules/style/keyword_parameters_order.rs +1 -1
  228. data/src/rules/style/magic_comment_format.rs +3 -2
  229. data/src/rules/style/map_chain.rs +1 -1
  230. data/src/rules/style/map_compact_with_conditional_block.rs +3 -3
  231. data/src/rules/style/map_into_array.rs +7 -7
  232. data/src/rules/style/map_join.rs +3 -3
  233. data/src/rules/style/method_call_with_args_parentheses.rs +7 -7
  234. data/src/rules/style/method_call_without_args_parentheses.rs +2 -2
  235. data/src/rules/style/method_def_parentheses.rs +2 -3
  236. data/src/rules/style/min_max.rs +3 -3
  237. data/src/rules/style/min_max_comparison.rs +2 -2
  238. data/src/rules/style/missing_else.rs +1 -1
  239. data/src/rules/style/missing_respond_to_missing.rs +1 -1
  240. data/src/rules/style/mixin_grouping.rs +1 -1
  241. data/src/rules/style/multiline_block_chain.rs +2 -2
  242. data/src/rules/style/multiline_if_then.rs +1 -1
  243. data/src/rules/style/multiline_in_pattern_then.rs +1 -1
  244. data/src/rules/style/multiline_method_signature.rs +1 -1
  245. data/src/rules/style/multiline_when_then.rs +2 -2
  246. data/src/rules/style/mutable_constant.rs +3 -3
  247. data/src/rules/style/negated_if.rs +2 -2
  248. data/src/rules/style/negated_if_else_condition.rs +2 -2
  249. data/src/rules/style/negated_while.rs +1 -1
  250. data/src/rules/style/negative_array_index.rs +2 -2
  251. data/src/rules/style/nested_modifier.rs +1 -1
  252. data/src/rules/style/nested_parenthesized_calls.rs +2 -2
  253. data/src/rules/style/nested_ternary_operator.rs +2 -2
  254. data/src/rules/style/next.rs +1 -1
  255. data/src/rules/style/nil_lambda.rs +2 -2
  256. data/src/rules/style/nodes.rs +21 -0
  257. data/src/rules/style/non_nil_check.rs +2 -2
  258. data/src/rules/style/numbered_parameters_limit.rs +2 -2
  259. data/src/rules/style/one_line_conditional.rs +4 -4
  260. data/src/rules/style/optional_arguments.rs +1 -1
  261. data/src/rules/style/or_assignment.rs +1 -1
  262. data/src/rules/style/parallel_assignment.rs +9 -10
  263. data/src/rules/style/parens.rs +1 -1
  264. data/src/rules/style/parentheses_around_condition.rs +3 -3
  265. data/src/rules/style/partition_instead_of_double_select.rs +3 -3
  266. data/src/rules/style/percent.rs +9 -7
  267. data/src/rules/style/percent_q_literals.rs +4 -3
  268. data/src/rules/style/preferred_hash_methods.rs +1 -1
  269. data/src/rules/style/random_with_offset.rs +1 -1
  270. data/src/rules/style/reduce_to_hash.rs +6 -6
  271. data/src/rules/style/redundant_argument.rs +1 -1
  272. data/src/rules/style/redundant_assignment.rs +5 -5
  273. data/src/rules/style/redundant_begin.rs +2 -2
  274. data/src/rules/style/redundant_capital_w.rs +3 -2
  275. data/src/rules/style/redundant_condition.rs +9 -7
  276. data/src/rules/style/redundant_current_directory_in_path.rs +2 -2
  277. data/src/rules/style/redundant_double_splat_hash_braces.rs +4 -4
  278. data/src/rules/style/redundant_file_extension_in_require.rs +2 -2
  279. data/src/rules/style/redundant_format.rs +16 -14
  280. data/src/rules/style/redundant_freeze.rs +1 -1
  281. data/src/rules/style/redundant_heredoc_delimiter_quotes.rs +1 -1
  282. data/src/rules/style/redundant_initialize.rs +2 -2
  283. data/src/rules/style/redundant_interpolation.rs +2 -2
  284. data/src/rules/style/redundant_interpolation_unfreeze.rs +2 -2
  285. data/src/rules/style/redundant_line_continuation.rs +5 -4
  286. data/src/rules/style/redundant_parentheses.rs +16 -15
  287. data/src/rules/style/redundant_regexp_argument.rs +1 -1
  288. data/src/rules/style/redundant_regexp_character_class.rs +4 -3
  289. data/src/rules/style/redundant_regexp_escape.rs +3 -2
  290. data/src/rules/style/redundant_return.rs +1 -2
  291. data/src/rules/style/redundant_self.rs +11 -11
  292. data/src/rules/style/redundant_sort.rs +1 -1
  293. data/src/rules/style/redundant_sort_by.rs +1 -1
  294. data/src/rules/style/redundant_string_escape.rs +6 -5
  295. data/src/rules/style/regexp_literal.rs +3 -2
  296. data/src/rules/style/require_order.rs +2 -2
  297. data/src/rules/style/rescue_modifier.rs +1 -1
  298. data/src/rules/style/rescue_standard_error.rs +1 -1
  299. data/src/rules/style/return_nil.rs +2 -2
  300. data/src/rules/style/return_nil_in_predicate_method_definition.rs +2 -2
  301. data/src/rules/style/safe_navigation.rs +2 -2
  302. data/src/rules/style/sample.rs +3 -3
  303. data/src/rules/style/select_by.rs +2 -2
  304. data/src/rules/style/select_by_range.rs +1 -1
  305. data/src/rules/style/semicolon.rs +5 -4
  306. data/src/rules/style/single_argument_dig.rs +1 -1
  307. data/src/rules/style/single_line_block_params.rs +7 -6
  308. data/src/rules/style/single_line_do_end_block.rs +13 -12
  309. data/src/rules/style/single_line_methods.rs +2 -2
  310. data/src/rules/style/slicing_with_range.rs +2 -2
  311. data/src/rules/style/sole_nested_conditional.rs +4 -4
  312. data/src/rules/style/special_global_vars.rs +2 -2
  313. data/src/rules/style/stabby_lambda_parentheses.rs +1 -1
  314. data/src/rules/style/statement_modifier.rs +3 -2
  315. data/src/rules/style/static_class.rs +1 -1
  316. data/src/rules/style/string_concatenation.rs +9 -7
  317. data/src/rules/style/string_hash_keys.rs +3 -2
  318. data/src/rules/style/string_literals.rs +3 -3
  319. data/src/rules/style/string_literals_in_interpolation.rs +1 -1
  320. data/src/rules/style/struct_inheritance.rs +3 -3
  321. data/src/rules/style/super_arguments.rs +2 -2
  322. data/src/rules/style/super_with_args_parentheses.rs +1 -1
  323. data/src/rules/style/swap_values.rs +1 -1
  324. data/src/rules/style/symbol_array.rs +1 -1
  325. data/src/rules/style/symbol_proc.rs +3 -3
  326. data/src/rules/style/tally_method.rs +4 -4
  327. data/src/rules/style/ternary_parentheses.rs +4 -4
  328. data/src/rules/style/top_level_method_definition.rs +1 -1
  329. data/src/rules/style/trailing_body.rs +1 -1
  330. data/src/rules/style/trailing_comma_in_array_literal.rs +1 -1
  331. data/src/rules/style/trailing_comma_in_hash_literal.rs +1 -1
  332. data/src/rules/style/trailing_method_end_statement.rs +1 -1
  333. data/src/rules/style/trailing_underscore_variable.rs +4 -5
  334. data/src/rules/style/trivial_accessors.rs +2 -2
  335. data/src/rules/style/unless_logical_operators.rs +1 -1
  336. data/src/rules/style/unpack_first.rs +1 -1
  337. data/src/rules/style/when_then.rs +4 -4
  338. data/src/rules/style/while_until_do.rs +1 -1
  339. data/src/rules/style/while_until_modifier.rs +3 -3
  340. data/src/rules/style/word_array.rs +3 -3
  341. data/src/rules/style/yoda_condition.rs +2 -2
  342. data/src/rules/support.rs +33 -8
  343. metadata +2 -1
@@ -6,6 +6,7 @@ use crate::rules::send_node::{arguments, is_plain_send, send_range};
6
6
 
7
7
  use super::locals::LocalVariables;
8
8
  use crate::rules::node_ext::NodeExt;
9
+ use crate::rules::send_node::named_children_of;
9
10
 
10
11
  const MSG: &str = "Use `Hash#compare_by_identity` instead of using `object_id` for keys.";
11
12
 
@@ -29,13 +30,13 @@ pub(super) fn check(context: &RuleContext<'_>, offenses: &mut Vec<Offense>) {
29
30
  /// reports it at.
30
31
  fn keyed_call<'tree>(
31
32
  node: Node<'tree>,
32
- context: &RuleContext<'_>,
33
+ context: &'tree RuleContext<'_>,
33
34
  ) -> Option<(Node<'tree>, std::ops::Range<usize>)> {
34
35
  if node.kind_str() == "element_reference" {
35
36
  let object = node.field("object")?;
36
- let mut cursor = node.walk();
37
- let key = node
38
- .named_children(&mut cursor)
37
+ let _cursor = node.walk();
38
+ let key = named_children_of(node, context)
39
+ .into_iter()
39
40
  .find(|child| child.id() != object.id())?;
40
41
  // `hash[k] = v` is one `[]=` send upstream, spanning the assignment rather than the
41
42
  // brackets. Written in a multiple assignment the send holds no value and stops at the
@@ -5,7 +5,8 @@ use tree_sitter::Node;
5
5
  use crate::diagnostic::{Edit, Offense};
6
6
  use crate::rules::RuleContext;
7
7
  use crate::rules::node_ext::NodeExt;
8
- use crate::rules::send_node::{arguments, heredoc_body, named_children};
8
+ use crate::rules::send_node::{arguments, heredoc_body};
9
+ use crate::rules::send_node::named_children_of;
9
10
 
10
11
  const MSG: &str =
11
12
  "Put a method call with a HEREDOC receiver on the same line as the HEREDOC opening.";
@@ -70,7 +71,7 @@ fn heredoc_receiver<'tree>(node: Node<'tree>) -> Option<Node<'tree>> {
70
71
  /// `heredoc.location.heredoc_end.end_pos`: where the terminator line ends.
71
72
  fn heredoc_end(heredoc: Node<'_>, context: &RuleContext<'_>) -> Option<usize> {
72
73
  let body = heredoc_body(heredoc, context)?;
73
- named_children(body)
74
+ named_children_of(body, context)
74
75
  .into_iter()
75
76
  .find(|child| child.kind_str() == "heredoc_end")
76
77
  .map(|end| end.end_byte())
@@ -3,7 +3,9 @@ use tree_sitter::Node;
3
3
  use crate::diagnostic::{Edit, Offense};
4
4
  use crate::rules::RuleContext;
5
5
  use crate::rules::node_ext::NodeExt;
6
- use crate::rules::send_node::{is_plain_send, named_children, string_text};
6
+ use crate::rules::send_node::{is_plain_send, string_text};
7
+ use crate::rules::send_node::named_children_of;
8
+ use crate::rules::send_node::all_children_of;
7
9
 
8
10
  const FOR_ARRAY: &str =
9
11
  " Or, if they were intended to be separate array elements, separate them with a comma.";
@@ -15,7 +17,7 @@ pub(super) fn check(context: &RuleContext<'_>, offenses: &mut Vec<Offense>) {
15
17
  // adjacent literals build: the parts of `"a\nb"` are fragments of a single literal, and the
16
18
  // delimiter test upstream applies is what tells the two apart.
17
19
  for node in context.nodes_of("chained_string") {
18
- let parts = named_children(node);
20
+ let parts = named_children_of(node, context);
19
21
  let suffix = suffix(node, context);
20
22
  for pair in parts.windows(2) {
21
23
  let (left, right) = (pair[0], pair[1]);
@@ -91,9 +93,9 @@ fn display(node: Node<'_>, context: &RuleContext<'_>) -> String {
91
93
  /// nothing to `str_type?` -- so the recursion joins an empty string for it. Showing the source
92
94
  /// instead puts `#{...}` in a message that upstream writes without it.
93
95
  fn str_content(node: Node<'_>, context: &RuleContext<'_>) -> String {
94
- let mut cursor = node.walk();
95
- let parts: Vec<String> = node
96
- .children(&mut cursor)
96
+ let _cursor = node.walk();
97
+ let parts: Vec<String> = all_children_of(node, context)
98
+ .into_iter()
97
99
  .filter(|child| child.is_named() && child.kind_str() != "interpolation")
98
100
  .map(|child| match child.kind_str() {
99
101
  // **`str_content` reads the value, not the source.** A `\` closing a line joins it to
@@ -5,6 +5,7 @@ use crate::diagnostic::Offense;
5
5
  use crate::rules::RuleContext;
6
6
  use crate::rules::send_node::symbol_name;
7
7
  use crate::rules::node_ext::NodeExt;
8
+ use crate::rules::send_node::named_children_iter;
8
9
 
9
10
  const ALTERNATIVE_PRIVATE: &str =
10
11
  "`private_class_method` or `private` inside a `class << self` block";
@@ -109,15 +110,15 @@ fn private_class_method_names(context: &RuleContext<'_>, node: Node<'_>) -> Vec<
109
110
  .is_some_and(|method| context.source.node_text(method) == "private_class_method")
110
111
  && let Some(arguments) = current.field("arguments")
111
112
  {
112
- let mut cursor = arguments.walk();
113
- for argument in arguments.named_children(&mut cursor) {
113
+ let _cursor = arguments.walk();
114
+ for argument in named_children_iter(arguments, context) {
114
115
  if let Some(name) = symbol_name(argument, context) {
115
116
  names.push(name.to_owned());
116
117
  }
117
118
  }
118
119
  }
119
- let mut cursor = current.walk();
120
- stack.extend(current.named_children(&mut cursor));
120
+ let _cursor = current.walk();
121
+ stack.extend(named_children_iter(current, context));
121
122
  }
122
123
  names
123
124
  }
@@ -3,6 +3,7 @@ use tree_sitter::Node;
3
3
  use crate::diagnostic::{Edit, Offense};
4
4
  use crate::rules::RuleContext;
5
5
  use crate::rules::node_ext::NodeExt;
6
+ use crate::rules::send_node::named_children_of;
6
7
 
7
8
  pub(super) fn check(context: &RuleContext<'_>, offenses: &mut Vec<Offense>) {
8
9
  // The indirect inheritance the cop can also report needs `AllCops/UseProjectIndex` and the
@@ -103,9 +104,9 @@ fn shadowed_by_a_sibling_definition(
103
104
  let Some(parent) = node.parent_of(context) else {
104
105
  return false;
105
106
  };
106
- let mut cursor = parent.walk();
107
- parent
108
- .named_children(&mut cursor)
107
+ let _cursor = parent.walk();
108
+ named_children_of(parent, context)
109
+ .into_iter()
109
110
  .take_while(|sibling| sibling.id() != node.id())
110
111
  .any(|sibling| {
111
112
  matches!(sibling.kind_str(), "class" | "module")
@@ -10,6 +10,8 @@ use crate::rules::send_node::named_children;
10
10
  use super::literals::{is_basic_literal, is_falsey_literal, is_literal, is_truthy_literal};
11
11
  use super::statements::{Branch, statements};
12
12
  use crate::rules::node_ext::NodeExt;
13
+ use crate::rules::send_node::{named_children_of};
14
+ use crate::rules::send_node::named_children_iter;
13
15
 
14
16
  /// The nodes whose `condition` the parser rewrites: a range there becomes a flip-flop and a regexp
15
17
  /// a match against `$_`, and neither is a literal any more.
@@ -315,11 +317,11 @@ fn check_case(node: Node<'_>, context: &RuleContext<'_>, offenses: &mut Vec<Offe
315
317
  check_case_condition(condition, context, offenses);
316
318
  return;
317
319
  }
318
- for branch in named_children(node)
320
+ for branch in named_children_of(node, context)
319
321
  .into_iter()
320
322
  .filter(|child| child.kind_str() == "when")
321
323
  {
322
- let conditions: Vec<Node<'_>> = named_children(branch)
324
+ let conditions: Vec<Node<'_>> = named_children_of(branch, context)
323
325
  .into_iter()
324
326
  .filter(|child| child.kind_str() == "pattern")
325
327
  .flat_map(named_children)
@@ -364,7 +366,7 @@ fn check_case_condition(
364
366
 
365
367
  /// `primitive_array?`.
366
368
  fn primitive_array(node: Node<'_>, context: &RuleContext<'_>) -> bool {
367
- named_children(node).into_iter().all(|child| {
369
+ named_children_iter(node, context).all(|child| {
368
370
  if child.kind_str() == "array" {
369
371
  primitive_array(child, context)
370
372
  } else {
@@ -4,6 +4,7 @@ use crate::diagnostic::Offense;
4
4
  use crate::rules::RuleContext;
5
5
  use crate::rules::node_ext::NodeExt;
6
6
  use crate::rules::send_node::{has_interpolation, heredoc_body, named_children};
7
+ use crate::rules::send_node::named_children_of;
7
8
 
8
9
  pub(super) fn check(context: &RuleContext<'_>, offenses: &mut Vec<Offense>) {
9
10
  for node in context.nodes_of_any(&[
@@ -86,11 +87,11 @@ fn all_literals(node: Node<'_>, context: &RuleContext<'_>) -> bool {
86
87
  "chained_string" | "subshell" => false,
87
88
  "string" => !has_interpolation(node),
88
89
  "heredoc_beginning" => is_single_line_heredoc(node, context),
89
- "array" | "string_array" | "symbol_array" | "right_assignment_list" => named_children(node)
90
+ "array" | "string_array" | "symbol_array" | "right_assignment_list" => named_children_of(node, context)
90
91
  .into_iter()
91
92
  .filter(|child| child.kind_str() != "comment")
92
93
  .all(|value| all_literals(value, context)),
93
- "hash" => named_children(node)
94
+ "hash" => named_children_of(node, context)
94
95
  .into_iter()
95
96
  .filter(|child| child.kind_str() != "comment")
96
97
  .all(|pair| {
@@ -123,7 +124,7 @@ fn is_single_line_heredoc(node: Node<'_>, context: &RuleContext<'_>) -> bool {
123
124
  let Some(body) = heredoc_body(node, context) else {
124
125
  return false;
125
126
  };
126
- let content: Vec<Node<'_>> = named_children(body)
127
+ let content: Vec<Node<'_>> = named_children_of(body, context)
127
128
  .into_iter()
128
129
  .filter(|child| child.kind_str() != "heredoc_end")
129
130
  .collect();
@@ -4,6 +4,7 @@ use crate::diagnostic::{Edit, Offense};
4
4
  use crate::rules::RuleContext;
5
5
  use crate::rules::node_ext::NodeExt;
6
6
  use crate::rules::ruby_literal::{character_value, inspect_string, inspect_symbol, string_value};
7
+ use crate::rules::send_node::named_children_of;
7
8
 
8
9
  const MSG: &str = "Literal interpolation detected.";
9
10
 
@@ -58,8 +59,7 @@ pub(super) fn check(context: &RuleContext<'_>, offenses: &mut Vec<Offense>) {
58
59
  /// evaluated and thrown away.
59
60
  fn last_statement<'tree>(interpolation: Node<'tree>) -> Option<Node<'tree>> {
60
61
  let mut cursor = interpolation.walk();
61
- interpolation
62
- .named_children(&mut cursor)
62
+ interpolation.named_children(&mut cursor)
63
63
  .filter(|child| {
64
64
  !matches!(
65
65
  child.kind_str(),
@@ -370,9 +370,9 @@ fn array_value(node: Node<'_>, context: &RuleContext<'_>) -> String {
370
370
  }
371
371
 
372
372
  fn hash_value(node: Node<'_>, context: &RuleContext<'_>) -> String {
373
- let mut cursor = node.walk();
374
- let pairs: Vec<String> = node
375
- .named_children(&mut cursor)
373
+ let _cursor = node.walk();
374
+ let pairs: Vec<String> = named_children_of(node, context)
375
+ .into_iter()
376
376
  .map(|pair| {
377
377
  let key = pair
378
378
  .field("key")
@@ -11,6 +11,7 @@ use tree_sitter::Node;
11
11
  use crate::rules::RuleContext;
12
12
  use crate::rules::node_ext::NodeExt;
13
13
  use crate::rules::send_node::has_interpolation;
14
+ use crate::rules::send_node::named_children_of;
14
15
 
15
16
  /// `BASIC_LITERALS`: a literal whose value is the node itself.
16
17
  const BASIC: &[&str] = &[
@@ -95,8 +96,9 @@ pub(crate) fn recursive_basic_literal(node: Node<'_>, context: &RuleContext<'_>)
95
96
 
96
97
  /// `children.compact.all?(&:recursive_basic_literal?)`.
97
98
  fn all_children(node: Node<'_>, context: &RuleContext<'_>) -> bool {
98
- let mut cursor = node.walk();
99
- node.named_children(&mut cursor)
99
+ let _cursor = node.walk();
100
+ named_children_of(node, context)
101
+ .into_iter()
100
102
  .filter(|child| child.kind_str() != "comment")
101
103
  .all(|child| match child.kind_str() {
102
104
  // The parts a quoted literal is written from are not nodes upstream at all: the text
@@ -189,9 +191,9 @@ fn string_type(node: Node<'_>, context: &RuleContext<'_>) -> &'static str {
189
191
  if has_interpolation(node) {
190
192
  return "dstr";
191
193
  }
192
- let mut cursor = node.walk();
193
- let broken = node
194
- .named_children(&mut cursor)
194
+ let _cursor = node.walk();
195
+ let broken = named_children_of(node, context)
196
+ .into_iter()
195
197
  .filter(|child| child.kind_str() == "string_content")
196
198
  .any(|child| context.source.node_text(child).contains('\n'));
197
199
  if broken { "dstr" } else { "str" }
@@ -206,9 +208,9 @@ fn heredoc_type(node: Node<'_>, context: &RuleContext<'_>) -> &'static str {
206
208
  if has_interpolation(body) {
207
209
  return "dstr";
208
210
  }
209
- let mut cursor = body.walk();
210
- let lines: usize = body
211
- .named_children(&mut cursor)
211
+ let _cursor = body.walk();
212
+ let lines: usize = named_children_of(body, context)
213
+ .into_iter()
212
214
  .filter(|child| child.kind_str() == "heredoc_content")
213
215
  .map(|child| context.source.node_text(child).matches('\n').count())
214
216
  .sum();
@@ -16,7 +16,7 @@ pub(super) fn check(context: &RuleContext<'_>, offenses: &mut Vec<Offense>) {
16
16
  continue;
17
17
  }
18
18
  for kwbegin in kwbegin_nodes(node) {
19
- walk_named(kwbegin, &mut |inner| {
19
+ walk_named(kwbegin, context, &mut |inner| {
20
20
  if inner.kind_str() != "return" || return_from_inner_scope(inner, kwbegin, context)
21
21
  {
22
22
  return;
@@ -84,7 +84,7 @@ fn return_from_inner_scope(node: Node<'_>, kwbegin: Node<'_>, context: &RuleCont
84
84
  return false;
85
85
  }
86
86
  if matches!(ancestor.kind_str(), "method" | "singleton_method" | "lambda")
87
- || is_lambda(ancestor, context.source)
87
+ || is_lambda(ancestor, context.source, context.ast_index())
88
88
  {
89
89
  return true;
90
90
  }
@@ -10,6 +10,8 @@ use tree_sitter::Node;
10
10
 
11
11
  use crate::rules::RuleContext;
12
12
  use crate::rules::node_ext::NodeExt;
13
+ use crate::rules::send_node::all_children_of;
14
+ use crate::rules::send_node::named_children_of;
13
15
 
14
16
  /// Whether the two operands are the same node. Upstream compares structurally rather than by
15
17
  /// source -- `Node#==` looks at the type and the children -- so a difference in spacing is no
@@ -227,8 +229,9 @@ fn heredoc_parts<'tree>(body: Node<'tree>) -> Vec<Node<'tree>> {
227
229
  }
228
230
 
229
231
  fn operator_text(node: Node<'_>, context: &RuleContext<'_>) -> String {
230
- let mut cursor = node.walk();
231
- node.children(&mut cursor)
232
+ let _cursor = node.walk();
233
+ all_children_of(node, context)
234
+ .into_iter()
232
235
  .filter(|child| !child.is_named())
233
236
  .map(|child| context.source.node_text(child))
234
237
  .collect()
@@ -288,9 +291,9 @@ fn literal(node: Node<'_>, context: &RuleContext<'_>) -> Option<Literal> {
288
291
  /// is a `dstr`/`dsym` upstream and has no value of its own, and an escape this cannot resolve
289
292
  /// leaves the node to be compared structurally instead.
290
293
  fn quoted_value(node: Node<'_>, context: &RuleContext<'_>) -> Option<Vec<u8>> {
291
- let mut cursor = node.walk();
292
- if node
293
- .named_children(&mut cursor)
294
+ let _cursor = node.walk();
295
+ if named_children_of(node, context)
296
+ .into_iter()
294
297
  .any(|child| child.kind_str() == "interpolation")
295
298
  {
296
299
  return None;
@@ -271,7 +271,7 @@ fn find_exist_call<'tree>(
271
271
  return Some(node);
272
272
  }
273
273
  let mut children = Vec::new();
274
- crate::rules::push_named_children(node, &mut children);
274
+ crate::rules::push_named_children_in(node, context, &mut children);
275
275
  children.reverse();
276
276
  stack.extend(children);
277
277
  }
@@ -3,11 +3,13 @@ use tree_sitter::Node;
3
3
  use crate::diagnostic::{Edit, Offense};
4
4
  use crate::ruby_version::RubyVersion;
5
5
  use crate::rules::RuleContext;
6
- use crate::rules::send_node::{arguments, is_plain_send, named_children, send_range};
6
+ use crate::rules::send_node::{arguments, is_plain_send, send_range};
7
7
 
8
8
  use super::blocks::{BLOCK_KINDS, BlockArgs};
9
9
  use super::locals::LocalVariables;
10
10
  use crate::rules::node_ext::NodeExt;
11
+ use crate::rules::send_node::named_children_of;
12
+ use crate::rules::send_node::named_children_iter;
11
13
 
12
14
  const MSG: &str = "Sort files before requiring them.";
13
15
 
@@ -190,7 +192,7 @@ fn is_method_require(node: Node<'_>, context: &RuleContext<'_>) -> bool {
190
192
  if node.kind_str() != "block_argument" {
191
193
  return false;
192
194
  }
193
- let Some(call) = named_children(node).into_iter().next() else {
195
+ let Some(call) = named_children_iter(node, context).next() else {
194
196
  return false;
195
197
  };
196
198
  if call.kind_str() != "call"
@@ -226,7 +228,7 @@ fn requires_variable(node: Node<'_>, name: &str, context: &RuleContext<'_>) -> b
226
228
  return true;
227
229
  }
228
230
  }
229
- named_children(node)
231
+ named_children_of(node, context)
230
232
  .into_iter()
231
233
  .any(|child| requires_variable(child, name, context))
232
234
  }
@@ -3,10 +3,11 @@ use tree_sitter::Node;
3
3
  use crate::diagnostic::Offense;
4
4
  use crate::rules::RuleContext;
5
5
  use crate::rules::node_ext::NodeExt;
6
- use crate::rules::send_node::{arguments, is_plain_send, named_children};
6
+ use crate::rules::send_node::{arguments, is_plain_send};
7
7
 
8
8
  use super::blocks::BlockArgs;
9
9
  use super::locals::LocalVariables;
10
+ use crate::rules::send_node::named_children_of;
10
11
 
11
12
  const MSG: &str = "Non-local exit from iterator, without return value. \
12
13
  `next`, `break`, `Array#find`, `Array#any?`, etc. is preferred.";
@@ -15,7 +16,7 @@ pub(super) fn check(context: &RuleContext<'_>, offenses: &mut Vec<Offense>) {
15
16
  let locals = LocalVariables::new(context);
16
17
  for node in context.nodes_of("return") {
17
18
  // `return_value?`: a `return` handing back a value leaves the iterator on purpose.
18
- if !named_children(node).is_empty() {
19
+ if !named_children_of(node, context).is_empty() {
19
20
  continue;
20
21
  }
21
22
  let Some(keyword) = node.child(0).filter(|child| child.kind_str() == "return") else {
@@ -205,7 +205,7 @@ fn uses_safe_navigation(node: Node<'_>, context: &RuleContext<'_>) -> bool {
205
205
  {
206
206
  return true;
207
207
  }
208
- crate::rules::push_named_children(current, &mut stack);
208
+ crate::rules::push_named_children_in(current, context, &mut stack);
209
209
  }
210
210
  false
211
211
  }
@@ -6,6 +6,8 @@ use crate::rules::send_node::{arguments, named_children};
6
6
 
7
7
  use super::regexp::{captures, interpolates, pattern};
8
8
  use crate::rules::node_ext::NodeExt;
9
+ use crate::rules::send_node::named_children_of;
10
+ use crate::rules::send_node::named_children_iter;
9
11
 
10
12
  /// The methods that leave `$~` set, which is what makes a numbered reference after them valid.
11
13
  /// `RESTRICT_ON_SEND` is this list, so a call to anything else leaves the state alone.
@@ -71,7 +73,7 @@ fn visit(node: Node<'_>, walk: &mut Walk, context: &RuleContext<'_>, offenses: &
71
73
  }
72
74
  }
73
75
  "when" => {
74
- walk.valid_ref = named_children(node)
76
+ walk.valid_ref = named_children_of(node, context)
75
77
  .into_iter()
76
78
  .filter(|child| child.kind_str() == "pattern")
77
79
  .flat_map(named_children)
@@ -100,7 +102,7 @@ fn visit(node: Node<'_>, walk: &mut Walk, context: &RuleContext<'_>, offenses: &
100
102
  // conditional puts its condition after its body here and before it upstream, for the same
101
103
  // reason: the walk has to see them in the order the parser's children are listed.
102
104
  let block = node.field("block");
103
- let mut children = named_children(node);
105
+ let mut children = named_children_of(node, context);
104
106
  if matches!(
105
107
  node.kind_str(),
106
108
  "if_modifier" | "unless_modifier" | "while_modifier" | "until_modifier"
@@ -198,7 +200,7 @@ fn is_capture_call(node: Node<'_>, context: &RuleContext<'_>) -> bool {
198
200
  }
199
201
 
200
202
  /// `regexp_first_argument?` and `regexp_receiver?`, which is what the state is taken from.
201
- fn regexp_operand<'tree>(node: Node<'tree>, context: &RuleContext<'_>) -> Option<Node<'tree>> {
203
+ fn regexp_operand<'tree>(node: Node<'tree>, context: &'tree RuleContext<'_>) -> Option<Node<'tree>> {
202
204
  let (name, first, receiver) = match node.kind_str() {
203
205
  "call" => (
204
206
  context
@@ -214,7 +216,7 @@ fn regexp_operand<'tree>(node: Node<'tree>, context: &RuleContext<'_>) -> Option
214
216
  node.field("right"),
215
217
  node.field("left"),
216
218
  ),
217
- "element_reference" => ("[]", named_children(node).into_iter().nth(1), node.child(0)),
219
+ "element_reference" => ("[]", named_children_iter(node, context).nth(1), node.child(0)),
218
220
  _ => return None,
219
221
  };
220
222
  if let Some(first) = first
@@ -91,8 +91,7 @@ fn is_dir_glob(receiver: Node<'_>, context: &RuleContext<'_>) -> bool {
91
91
  fn glob_arguments<'tree>(receiver: Node<'tree>) -> Vec<Node<'tree>> {
92
92
  if receiver.kind_str() == "element_reference" {
93
93
  let mut cursor = receiver.walk();
94
- return receiver
95
- .named_children(&mut cursor)
94
+ return receiver.named_children(&mut cursor)
96
95
  .filter(|child| {
97
96
  child.kind_str() != "comment"
98
97
  && receiver
@@ -2,13 +2,14 @@ use tree_sitter::Node;
2
2
 
3
3
  use crate::diagnostic::{Edit, Offense};
4
4
  use crate::rules::RuleContext;
5
- use crate::rules::send_node::{arguments, named_children, string_text, symbol_name};
5
+ use crate::rules::send_node::{arguments, string_text, symbol_name};
6
6
 
7
7
  use super::blocks::BLOCK_KINDS;
8
8
  use super::literals::{is_literal, literal_type};
9
9
  use super::nil_methods::NIL_METHODS;
10
10
  use super::nil_receiver::cant_be_nil;
11
11
  use crate::rules::node_ext::NodeExt;
12
+ use crate::rules::send_node::named_children_of;
12
13
 
13
14
  const MSG: &str = "Redundant safe navigation detected, use `.` instead.";
14
15
  const MSG_LITERAL: &str = "Redundant safe navigation with default literal detected.";
@@ -217,8 +218,8 @@ fn check_conversion_with_default(
217
218
  .field("block")
218
219
  .is_some_and(|block| BLOCK_KINDS.contains(&block.kind_str()));
219
220
  let matched = match context.source.node_text(method) {
220
- "to_h" => right.kind_str() == "hash" && named_children(right).is_empty(),
221
- "to_a" if !has_block => right.kind_str() == "array" && named_children(right).is_empty(),
221
+ "to_h" => right.kind_str() == "hash" && named_children_of(right, context).is_empty(),
222
+ "to_a" if !has_block => right.kind_str() == "array" && named_children_of(right, context).is_empty(),
222
223
  "to_i" if !has_block => {
223
224
  right.kind_str() == "integer" && context.source.node_text(right) == "0"
224
225
  }
@@ -9,6 +9,8 @@ use crate::rules::send_node::{is_plain_send, named_children, top_level_constant}
9
9
  use super::literals::literal_type;
10
10
  use super::statements::statements;
11
11
  use crate::rules::node_ext::NodeExt;
12
+ use crate::rules::send_node::named_children_of;
13
+ use crate::rules::send_node::named_children_iter;
12
14
 
13
15
  const MSG: &str = "Replace splat expansion with comma separated values.";
14
16
  const ARRAY_PARAM_MSG: &str = "Pass array contents as separate arguments.";
@@ -48,7 +50,7 @@ pub(super) fn check(context: &RuleContext<'_>, offenses: &mut Vec<Offense>) {
48
50
  .setting::<bool>("AllowPercentLiteralArrayArgument")
49
51
  .unwrap_or(true);
50
52
  for node in context.nodes_of("splat_argument") {
51
- let Some(expanded) = named_children(node).into_iter().next() else {
53
+ let Some(expanded) = named_children_iter(node, context).next() else {
52
54
  continue;
53
55
  };
54
56
  let (position, grandparent) = position_of(node);
@@ -67,7 +69,7 @@ pub(super) fn check(context: &RuleContext<'_>, offenses: &mut Vec<Offense>) {
67
69
  if !EXPANDABLE.contains(&kind) {
68
70
  continue;
69
71
  }
70
- if kind == "array" && named_children(expanded).is_empty() {
72
+ if kind == "array" && named_children_of(expanded, context).is_empty() {
71
73
  continue;
72
74
  }
73
75
  }
@@ -2,11 +2,12 @@ use tree_sitter::Node;
2
2
 
3
3
  use crate::diagnostic::{Edit, Offense};
4
4
  use crate::rules::RuleContext;
5
- use crate::rules::send_node::{arguments, named_children};
5
+ use crate::rules::send_node::arguments;
6
6
 
7
7
  use super::locals::LocalVariables;
8
8
  use super::statements::statements;
9
9
  use crate::rules::node_ext::NodeExt;
10
+ use crate::rules::send_node::named_children_of;
10
11
 
11
12
  /// The receiverless calls whose arguments coerce on their own.
12
13
  const PRINTERS: &[&str] = &["print", "puts", "warn"];
@@ -39,7 +40,7 @@ pub(super) fn check(context: &RuleContext<'_>, offenses: &mut Vec<Offense>) {
39
40
  let Some(list) = call.field("arguments") else {
40
41
  continue;
41
42
  };
42
- for argument in named_children(list) {
43
+ for argument in named_children_of(list, context) {
43
44
  if let Some(offense) = coercion(argument, &context_name, context, &locals) {
44
45
  offenses.push(offense);
45
46
  }
@@ -11,9 +11,9 @@ use tree_sitter::Node;
11
11
 
12
12
  use crate::rules::RuleContext;
13
13
  use crate::rules::node_ext::NodeExt;
14
- use crate::rules::send_node::named_children;
15
14
 
16
15
  use super::regexp_tree::{self, Tree};
16
+ use crate::rules::send_node::named_children_of;
17
17
 
18
18
  /// A regexp literal, parsed.
19
19
  pub(super) struct Pattern {
@@ -48,7 +48,7 @@ pub(super) fn parse(node: Node<'_>, context: &RuleContext<'_>) -> Option<Pattern
48
48
  let mut blanked = String::with_capacity(body.end - body.start);
49
49
  let mut interpolations = Vec::new();
50
50
  let mut cursor = body.start;
51
- for child in named_children(node) {
51
+ for child in named_children_of(node, context) {
52
52
  if child.kind_str() != "interpolation" {
53
53
  continue;
54
54
  }
@@ -13,6 +13,7 @@ use crate::rules::RuleContext;
13
13
  use crate::rules::node_ext::NodeExt;
14
14
 
15
15
  use super::statements::{holds_statements, statements};
16
+ use crate::rules::send_node::all_children_iter;
16
17
 
17
18
  pub(super) fn check(context: &RuleContext<'_>, offenses: &mut Vec<Offense>) {
18
19
  for node in context.nodes_of("range") {
@@ -53,9 +54,9 @@ pub(super) fn check(context: &RuleContext<'_>, offenses: &mut Vec<Offense>) {
53
54
  }
54
55
 
55
56
  /// `node.loc.operator`.
56
- fn operator<'tree>(node: Node<'tree>, context: &RuleContext<'_>) -> Option<Node<'tree>> {
57
- let mut cursor = node.walk();
58
- node.children(&mut cursor)
57
+ fn operator<'tree>(node: Node<'tree>, context: &'tree RuleContext<'_>) -> Option<Node<'tree>> {
58
+ let _cursor = node.walk();
59
+ all_children_iter(node, context)
59
60
  .find(|child| !child.is_named() && matches!(context.source.node_text(*child), ".." | "..."))
60
61
  }
61
62
 
@@ -106,8 +107,7 @@ fn innermost<'tree>(node: Node<'tree>) -> Node<'tree> {
106
107
  let mut current = node;
107
108
  loop {
108
109
  let mut cursor = current.walk();
109
- let first = current
110
- .named_children(&mut cursor)
110
+ let first = current.named_children(&mut cursor)
111
111
  .find(|child| !skippable(*child));
112
112
  match first {
113
113
  Some(child) => current = child,
@@ -2,6 +2,7 @@ use super::rescue_clause::{body, const_name, end};
2
2
  use crate::diagnostic::Offense;
3
3
  use crate::rules::RuleContext;
4
4
  use crate::rules::node_ext::NodeExt;
5
+ use crate::rules::send_node::named_children_of;
5
6
 
6
7
  const MSG: &str =
7
8
  "Avoid rescuing the `Exception` class. Perhaps you meant to rescue `StandardError`?";
@@ -11,9 +12,9 @@ pub(super) fn check(context: &RuleContext<'_>, offenses: &mut Vec<Offense>) {
11
12
  let Some(exceptions) = node.field("exceptions") else {
12
13
  continue;
13
14
  };
14
- let mut cursor = exceptions.walk();
15
- let targets_exception = exceptions
16
- .named_children(&mut cursor)
15
+ let _cursor = exceptions.walk();
16
+ let targets_exception = named_children_of(exceptions, context)
17
+ .into_iter()
17
18
  .any(|exception| const_name(exception, context.source).as_deref() == Some("Exception"));
18
19
  if !targets_exception {
19
20
  continue;
@@ -5,6 +5,7 @@ use crate::rules::RuleContext;
5
5
 
6
6
  use super::literals::literal_type;
7
7
  use crate::rules::node_ext::NodeExt;
8
+ use crate::rules::send_node::named_children_iter;
8
9
 
9
10
  /// `INVALID_TYPES`: the literals that name a value rather than a class, so that `rescue` raises a
10
11
  /// `TypeError` when it tries to match against them.
@@ -21,8 +22,8 @@ pub(super) fn check(context: &RuleContext<'_>, offenses: &mut Vec<Offense>) {
21
22
  let Some(list) = clause.field("exceptions") else {
22
23
  continue;
23
24
  };
24
- let mut cursor = list.walk();
25
- let exceptions: Vec<Node<'_>> = list.named_children(&mut cursor).collect();
25
+ let _cursor = list.walk();
26
+ let exceptions: Vec<Node<'_>> = named_children_iter(list, context).collect();
26
27
  let invalid: Vec<&Node<'_>> = exceptions
27
28
  .iter()
28
29
  .filter(|exception| is_invalid(**exception, context))