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

Function detect_single_call

src/code_actions/extract_function.rs:688–759  ·  view source on GitHub ↗

Detect when the body is a single method call or function call statement (no assignment, no return). Returns a name derived from the called method/function. Examples: - `$this->execute($fn)` → `"execute"` - `self::validate($x)` → `"validate"` - `doSomething($x)` → `"doSomething"`

(body: &str)

Source from the content-addressed store, hash-verified

686/// - `self::validate($x)` → `"validate"`
687/// - `doSomething($x)` → `"doSomething"`
688fn detect_single_call(body: &str) -> Option<String> {
689 let trimmed = body.trim();
690
691 // Must be a single non-comment line.
692 let lines: Vec<&str> = trimmed
693 .lines()
694 .map(|l| l.trim())
695 .filter(|l| !l.is_empty() && !l.starts_with("//") && !l.starts_with('#'))
696 .collect();
697 if lines.len() != 1 {
698 return None;
699 }
700
701 let line = lines[0].strip_suffix(';').unwrap_or(lines[0]).trim();
702
703 // Must not be an assignment.
704 if line.contains('=') {
705 // Allow `==`, `!=`, `===`, `!==`, `>=`, `<=` inside expressions,
706 // but reject bare `$var = ...` assignments.
707 if let Some(eq_pos) = line.find('=') {
708 let before = &line[..eq_pos];
709 let after = &line[eq_pos + 1..];
710 if before.trim().starts_with('$')
711 && !after.starts_with('=')
712 && !before.ends_with('!')
713 && !before.ends_with('<')
714 && !before.ends_with('>')
715 {
716 return None;
717 }
718 }
719 }
720
721 // Extract the method/function name from the call.
722 // `$this->foo(...)` or `$var->foo(...)`
723 if let Some(arrow_pos) = line.rfind("->") {
724 let after = &line[arrow_pos + 2..];
725 let name: String = after
726 .chars()
727 .take_while(|c| c.is_alphanumeric() || *c == '_')
728 .collect();
729 if !name.is_empty() && after[name.len()..].starts_with('(') {
730 return Some(name);
731 }
732 }
733 // `self::foo(...)` or `static::foo(...)` or `ClassName::foo(...)`
734 if let Some(colon_pos) = line.rfind("::") {
735 let after = &line[colon_pos + 2..];
736 let name: String = after
737 .chars()
738 .take_while(|c| c.is_alphanumeric() || *c == '_')
739 .collect();
740 if !name.is_empty() && after[name.len()..].starts_with('(') {
741 return Some(name);
742 }
743 }
744 // `functionName(...)` — bare function call
745 let name: String = line

Callers 1

derive_base_nameFunction · 0.85

Calls 6

filterMethod · 0.80
containsMethod · 0.80
nextMethod · 0.80
mapMethod · 0.45
is_emptyMethod · 0.45
findMethod · 0.45

Tested by

no test coverage detected