MCPcopy Create free account
hub / github.com/PHPantom-dev/phpantom_lsp / extract_function_body

Function extract_function_body

src/completion/source/throws_analysis.rs:700–798  ·  view source on GitHub ↗

Extract the function/method body text that follows the docblock at the cursor position. Returns the text between the opening `{` and matching closing `}` of the function/method declaration. Returns `None` if the body cannot be located (e.g. abstract method, or the docblock is not followed by a function).

(content: &str, position: Position)

Source from the content-addressed store, hash-verified

698/// be located (e.g. abstract method, or the docblock is not followed by
699/// a function).
700pub(crate) fn extract_function_body(content: &str, position: Position) -> Option<String> {
701 let after_docblock = {
702 let byte_offset = position_to_byte_offset(content, position);
703 let after_cursor = &content[byte_offset.min(content.len())..];
704
705 if let Some(close_pos) = after_cursor.find("*/") {
706 after_cursor[close_pos + 2..].to_string()
707 } else {
708 after_cursor.to_string()
709 }
710 };
711
712 // Find the `function` keyword to confirm this is a function/method.
713 let func_idx = {
714 let lower = after_docblock.to_lowercase();
715 let mut start = 0;
716 let mut found = None;
717 while let Some(pos) = lower[start..].find("function") {
718 let abs = start + pos;
719 let before_ok = abs == 0 || !after_docblock.as_bytes()[abs - 1].is_ascii_alphanumeric();
720 let after_pos = abs + 8; // "function".len()
721 let after_ok = after_pos >= after_docblock.len()
722 || !after_docblock.as_bytes()[after_pos].is_ascii_alphanumeric();
723 if before_ok && after_ok {
724 found = Some(abs);
725 break;
726 }
727 start = abs + 8;
728 }
729 found?
730 };
731
732 let after_func = &after_docblock[func_idx..];
733
734 // Find the opening brace of the function body.
735 let open_brace = after_func.find('{')?;
736 let body_start = open_brace + 1;
737
738 // Walk forward to find the matching closing brace.
739 let mut depth = 1u32;
740 let mut pos = body_start;
741 let bytes = after_func.as_bytes();
742 // Track whether we are inside a string literal to avoid counting
743 // braces inside strings.
744 let mut in_single_quote = false;
745 let mut in_double_quote = false;
746 while pos < bytes.len() && depth > 0 {
747 let b = bytes[pos];
748 if in_single_quote {
749 if b == b'\\' {
750 pos += 1; // skip escaped char
751 } else if b == b'\'' {
752 in_single_quote = false;
753 }
754 } else if in_double_quote {
755 if b == b'\\' {
756 pos += 1; // skip escaped char
757 } else if b == b'"' {

Calls 2

position_to_byte_offsetFunction · 0.85
findMethod · 0.45