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

Method scan_phar_archive

src/server.rs:1967–2043  ·  view source on GitHub ↗

Parse a `.phar` archive and register its PHP classes in the fqn_uri_index for lazy loading. The phar's raw bytes are read from disk, parsed by [`phar::PharArchive`], and stored in [`phar_archives`](crate::Backend::phar_archives). Each `.php` file inside the archive is scanned with the lightweight [`find_classes`](classmap_scanner::find_classes) byte scanner, and discovered classes are registered

(&self, phar_path: &Path)

Source from the content-addressed store, hash-verified

1965 /// to extract content from the phar instead of reading from disk)
1966 /// and a `phar://` URI for completions and workspace symbols
1967 fn scan_phar_archive(&self, phar_path: &Path) {
1968 // Avoid scanning the same phar twice.
1969 if self.phar_archives.read().contains_key(phar_path) {
1970 return;
1971 }
1972
1973 let data = match std::fs::read(phar_path) {
1974 Ok(d) => d,
1975 Err(_) => return,
1976 };
1977
1978 let archive = match phar::PharArchive::parse(data) {
1979 Some(a) => a,
1980 None => {
1981 tracing::warn!("failed to parse phar archive: {}", phar_path.display());
1982 return;
1983 }
1984 };
1985
1986 // Collect PHP file paths first so we can iterate while
1987 // holding the archive reference.
1988 let php_files: Vec<String> = archive
1989 .file_paths()
1990 .filter(|p| p.ends_with(".php"))
1991 .map(String::from)
1992 .collect();
1993
1994 let mut classmap_entries: Vec<(String, PathBuf)> = Vec::new();
1995 let mut fqn_uri_entries: Vec<(String, String)> = Vec::new();
1996
1997 for internal_path in &php_files {
1998 if let Some(content) = archive.read_file(internal_path) {
1999 let classes = classmap_scanner::find_classes(content);
2000 for fqn in classes {
2001 // Sentinel path: "archive.phar!internal/path.php"
2002 let sentinel =
2003 PathBuf::from(format!("{}!{}", phar_path.display(), internal_path));
2004 let phar_uri = format!("phar://{}/{}", phar_path.display(), internal_path);
2005 classmap_entries.push((fqn.clone(), sentinel));
2006 fqn_uri_entries.push((fqn, phar_uri));
2007 }
2008 }
2009 }
2010
2011 let class_count = classmap_entries.len();
2012
2013 // Register classes in the fqn_uri_index.
2014 {
2015 let mut idx = self.fqn_uri_index.write();
2016 for (fqn, path) in classmap_entries {
2017 idx.entry(fqn)
2018 .or_insert_with(|| crate::util::path_to_uri(&path));
2019 }
2020 for (fqn, uri) in fqn_uri_entries {
2021 idx.entry(fqn).or_insert(uri);
2022 }
2023 }
2024

Callers 1

scan_autoload_filesMethod · 0.80

Calls 10

find_classesFunction · 0.85
path_to_uriFunction · 0.85
filterMethod · 0.80
file_pathsMethod · 0.80
read_fileMethod · 0.80
pushMethod · 0.80
cloneMethod · 0.80
writeMethod · 0.80
mapMethod · 0.45
insertMethod · 0.45

Tested by

no test coverage detected