(&mut self, node: Node<'t>)
| 487 | // --- extractFunction / extractMethod (1517 / 1737) -------------------- |
| 488 | |
| 489 | fn extract_function(&mut self, node: Node<'t>) { |
| 490 | // :1522 receiver short-circuit IS the method routing. |
| 491 | if let Some(receiver) = self.receiver_type(node) { |
| 492 | let receiver = receiver.to_string(); |
| 493 | self.extract_method(node, receiver); |
| 494 | return; |
| 495 | } |
| 496 | let name = self.extract_name(node); |
| 497 | if name == "<anonymous>" { |
| 498 | // Unreachable for function_declaration (grammar requires a name) |
| 499 | // but preserved: body walked with nothing pushed. |
| 500 | if let Some(body) = node.child_by_field_name("body") { |
| 501 | self.visit_body(body); |
| 502 | } |
| 503 | return; |
| 504 | } |
| 505 | let docstring = preceding_docstring(node, self.src); |
| 506 | let signature = self.signature_of(node); |
| 507 | let is_exported = self.is_exported_of(node); // lua None / luau Some(false) |
| 508 | let fn_row = self.create_node( |
| 509 | "function", |
| 510 | &name, |
| 511 | node, |
| 512 | Extra { docstring, signature, is_exported, ..Default::default() }, |
| 513 | ); |
| 514 | let Some(row) = fn_row else { return }; |
| 515 | // extractTypeAnnotations / extractDecoratorsFor: structurally zero |
| 516 | // output for lua/luau (gates + no decorator kinds in scan positions). |
| 517 | self.stack.push(Scope { row, kind: "function", name }); |
| 518 | if let Some(body) = node.child_by_field_name("body") { |
| 519 | self.visit_body(body); |
| 520 | } |
| 521 | self.stack.pop(); |
| 522 | } |
| 523 | |
| 524 | fn extract_method(&mut self, node: Node<'t>, receiver: String) { |
| 525 | let name = self.extract_name(node); |
no test coverage detected