Visit a SUB...END SUB definition and emit a Function node.
(
state: &mut ExtractionState,
node: TsNode<'_>,
pending_comment: Option<&str>,
)
| 479 | |
| 480 | /// Visit a SUB...END SUB definition and emit a Function node. |
| 481 | fn visit_sub_definition( |
| 482 | state: &mut ExtractionState, |
| 483 | node: TsNode<'_>, |
| 484 | pending_comment: Option<&str>, |
| 485 | ) { |
| 486 | let Some(name_node) = node.child_by_field_name("name") else { |
| 487 | return; |
| 488 | }; |
| 489 | let name = state.node_text(name_node); |
| 490 | |
| 491 | let start_line = node.start_position().row as u32; |
| 492 | let end_line = node.end_position().row as u32; |
| 493 | let start_column = node.start_position().column as u32; |
| 494 | let end_column = node.end_position().column as u32; |
| 495 | let qualified_name = format!("{}::{}", state.qualified_prefix(), name); |
| 496 | let fn_id = generate_node_id(&state.file_path, &NodeKind::Function, &name, start_line); |
| 497 | |
| 498 | // Build signature from the first line of text. |
| 499 | let text = state.node_text(node); |
| 500 | let signature = text.lines().next().unwrap_or("").trim().to_string(); |
| 501 | |
| 502 | // Count complexity using the generic counter. |
| 503 | let metrics = if node.child_count() > 0 { |
| 504 | count_complexity(node, &QBASIC_COMPLEXITY, &state.source) |
| 505 | } else { |
| 506 | ComplexityMetrics::default() |
| 507 | }; |
| 508 | |
| 509 | let graph_node = Node { |
| 510 | id: fn_id.clone(), |
| 511 | kind: NodeKind::Function, |
| 512 | name: name.clone(), |
| 513 | qualified_name, |
| 514 | file_path: state.file_path.clone(), |
| 515 | start_line, |
| 516 | attrs_start_line: start_line, |
| 517 | end_line, |
| 518 | start_column, |
| 519 | end_column, |
| 520 | signature: Some(signature), |
| 521 | docstring: pending_comment.map(std::string::ToString::to_string), |
| 522 | visibility: Visibility::Pub, |
| 523 | is_async: false, |
| 524 | branches: metrics.branches, |
| 525 | loops: metrics.loops, |
| 526 | returns: metrics.returns, |
| 527 | max_nesting: metrics.max_nesting, |
| 528 | unsafe_blocks: metrics.unsafe_blocks, |
| 529 | unchecked_calls: metrics.unchecked_calls, |
| 530 | assertions: metrics.assertions, |
| 531 | updated_at: state.timestamp, |
| 532 | parent_id: None, |
| 533 | }; |
| 534 | state.nodes.push(graph_node); |
| 535 | |
| 536 | if let Some(parent_id) = state.parent_node_id() { |
| 537 | state.edges.push(Edge { |
| 538 | source: parent_id.to_string(), |
nothing calls this directly
no test coverage detected