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

Method find_function_references

src/references/mod.rs:970–1087  ·  view source on GitHub ↗

Find all references to a function across all files.

(
        &self,
        target_fqn: &str,
        target_short: &str,
        include_declaration: bool,
    )

Source from the content-addressed store, hash-verified

968
969 /// Find all references to a function across all files.
970 fn find_function_references(
971 &self,
972 target_fqn: &str,
973 target_short: &str,
974 include_declaration: bool,
975 ) -> Vec<Location> {
976 let mut locations = Vec::new();
977
978 // Input boundary: callers may pass FQNs with a leading `\`.
979 let target = strip_fqn_prefix(target_fqn);
980
981 let snapshot = self.user_file_symbol_maps();
982
983 for (file_uri, symbol_map) in &snapshot {
984 // Prefer mago-names resolved_names; lazy-load use_map only
985 // when an offset is not tracked (e.g. docblock references).
986 let resolved_names = self.resolved_names.read().get(file_uri).cloned();
987 let file_namespace = self.first_file_namespace(file_uri);
988 let file_use_map = std::cell::OnceCell::new();
989
990 // First pass: resolved-name check. Function imports can be aliased
991 // (`use function Foo\bar as baz; baz()`), so the call-site text
992 // alone is not enough to decide whether this file can match.
993 let has_potential_match = symbol_map.spans.iter().any(|span| {
994 if let SymbolKind::FunctionCall { name, .. } = &span.kind {
995 if name == target_short {
996 true
997 } else {
998 let resolved = if let Some(fqn) =
999 resolved_names.as_ref().and_then(|rn| rn.get(span.start))
1000 {
1001 fqn.to_string()
1002 } else {
1003 let use_map = file_use_map.get_or_init(|| {
1004 self.file_imports
1005 .read()
1006 .get(file_uri)
1007 .cloned()
1008 .unwrap_or_default()
1009 });
1010 Self::resolve_to_fqn(name, use_map, &file_namespace)
1011 };
1012 let resolved_normalized = strip_fqn_prefix(&resolved);
1013 resolved_normalized == target
1014 || crate::util::short_name(resolved_normalized) == target_short
1015 }
1016 } else {
1017 false
1018 }
1019 });
1020
1021 if !has_potential_match {
1022 continue;
1023 }
1024
1025 let parsed_uri = match Url::parse(file_uri) {
1026 Ok(u) => u,
1027 Err(_) => continue,

Callers 1

Calls 12

strip_fqn_prefixFunction · 0.85
offset_to_positionFunction · 0.85
user_file_symbol_mapsMethod · 0.80
first_file_namespaceMethod · 0.80
iterMethod · 0.80
get_file_content_arcMethod · 0.80
pushMethod · 0.80
cloneMethod · 0.80
as_strMethod · 0.80
resolve_to_fqnFunction · 0.50
short_nameFunction · 0.50
getMethod · 0.45

Tested by

no test coverage detected