(&mut self, node: Node<'t>)
| 526 | } |
| 527 | |
| 528 | fn visit_for_calls_and_structure(&mut self, node: Node<'t>) { |
| 529 | let kind = node.kind(); |
| 530 | self.maybe_capture_fn_refs(node); |
| 531 | |
| 532 | if kind == "call" { |
| 533 | self.extract_call(node); |
| 534 | } else if let Some(bare) = self.bare_call_name(node) { |
| 535 | // extractBareCall: statement-level identifiers in BLOCK_PARENTS |
| 536 | // bodies (`do…end` = body_statement; brace blocks are block_body — |
| 537 | // NOT in the set, so `5.times { beep }` emits nothing for beep). |
| 538 | let name = bare.to_string(); |
| 539 | let from = self.top_row(); |
| 540 | self.push_ref_at(from, &name, edge_kind_index("calls").unwrap(), node); |
| 541 | } |
| 542 | |
| 543 | // (No INSTANTIATION_KINDS for ruby — `.new` is handled in extract_call; |
| 544 | // extractStaticMemberRef is gated off; no type annotations.) |
| 545 | |
| 546 | // Nested NAMED defs become their own function nodes; classes extract. |
| 547 | // A `module` inside a body mints NOTHING (the visitNode hook does not |
| 548 | // run here) — its children just recurse. Same for singleton_method |
| 549 | // (functionTypes-only check): unmatched, recursed. |
| 550 | if kind == "method" { |
| 551 | let name = self.extract_name(node); |
| 552 | if name != "<anonymous>" { |
| 553 | self.extract_function(node); |
| 554 | return; |
| 555 | } |
| 556 | } |
| 557 | if kind == "class" { |
| 558 | self.extract_class(node); |
| 559 | return; |
| 560 | } |
| 561 | |
| 562 | for i in 0..node.named_child_count() { |
| 563 | if let Some(c) = node.named_child(i) { |
| 564 | self.visit_for_calls_and_structure(c); |
| 565 | } |
| 566 | } |
| 567 | } |
| 568 | |
| 569 | /// rubyExtractor.extractBareCall (languages/ruby.ts:77-105). |
| 570 | fn bare_call_name(&self, node: Node) -> Option<&'t str> { |
no test coverage detected