Parse symbol info (params, return type, property type) from the declaration text following the docblock.
(text: &str)
| 557 | /// Parse symbol info (params, return type, property type) from the |
| 558 | /// declaration text following the docblock. |
| 559 | fn parse_symbol_info(text: &str) -> SymbolInfo { |
| 560 | let mut info = SymbolInfo::default(); |
| 561 | |
| 562 | // Track blank lines — inline variable assignment detection requires |
| 563 | // the assignment to be on the very next line (no blank gap). |
| 564 | // |
| 565 | // The text starts right after `*/`, so the first line is the tail |
| 566 | // of the closing `*/` line (usually empty). That does NOT count |
| 567 | // as a blank gap — only subsequent empty lines do. |
| 568 | let mut saw_blank_before_code = false; |
| 569 | let mut skipped_first_line = false; |
| 570 | |
| 571 | // Collect the declaration — may span multiple lines until `{` or `;` |
| 572 | let mut decl = String::new(); |
| 573 | for line in text.lines() { |
| 574 | let trimmed = line.trim(); |
| 575 | if trimmed.starts_with('*') || trimmed.starts_with("/**") { |
| 576 | continue; |
| 577 | } |
| 578 | if trimmed.is_empty() { |
| 579 | if !skipped_first_line { |
| 580 | skipped_first_line = true; |
| 581 | } else if decl.is_empty() { |
| 582 | saw_blank_before_code = true; |
| 583 | } |
| 584 | continue; |
| 585 | } |
| 586 | skipped_first_line = true; |
| 587 | decl.push(' '); |
| 588 | decl.push_str(trimmed); |
| 589 | if trimmed.contains('{') || trimmed.contains(';') { |
| 590 | break; |
| 591 | } |
| 592 | } |
| 593 | |
| 594 | let decl = decl.trim(); |
| 595 | if decl.is_empty() { |
| 596 | return info; |
| 597 | } |
| 598 | |
| 599 | // Check if it's a function/method |
| 600 | if let Some(func_pos) = find_keyword_pos(decl, "function") { |
| 601 | let after_func = &decl[func_pos + 8..]; // "function" is 8 chars |
| 602 | |
| 603 | // Find the parameter list between ( and ) |
| 604 | if let Some(open_paren) = after_func.find('(') { |
| 605 | let after_open = &after_func[open_paren + 1..]; |
| 606 | if let Some(close_paren) = find_matching_paren(after_open) { |
| 607 | let params_str = &after_open[..close_paren]; |
| 608 | info.params = parse_params(params_str); |
| 609 | |
| 610 | // Extract return type: look for `: Type` after the closing paren |
| 611 | let after_close = &after_open[close_paren + 1..]; |
| 612 | info.return_type = extract_return_type_from_decl(after_close); |
| 613 | } |
| 614 | } |
| 615 | } else { |
| 616 | // Property or constant — extract type hint |
no test coverage detected