use std::path::Path;
pub(crate) fn cached_parse(
path: &Path,
cache: &mut cha_core::ProjectCache,
cwd: &Path,
) -> Option<(String, cha_core::SourceModel)> {
let rel = path
.strip_prefix(cwd)
.unwrap_or(path)
.to_string_lossy()
.to_string();
if let cha_core::FileStatus::Unchanged(chash) = cache.check_file(&rel, path)
&& let Some(model) = cache.get_model(chash)
{
return Some((rel, model));
}
let content = std::fs::read_to_string(path).ok()?;
let chash = cha_core::hash_content(&content);
if let Some(model) = cache.get_model(chash) {
let imports = model.imports.iter().map(|i| i.source.clone()).collect();
cache.update_file_entry(rel.clone(), path, chash, imports);
if cache.get_symbols(chash).is_none() {
let idx = cha_core::SymbolIndex::from_source_model(&model);
cache.put_symbols(chash, &idx);
}
return Some((rel, model));
}
let file = cha_core::SourceFile::new(path.to_path_buf(), content);
let model = cha_parser::parse_file(&file)?;
cache.put_model(chash, &model);
cache.put_symbols(chash, &cha_core::SymbolIndex::from_source_model(&model));
let imports = model.imports.iter().map(|i| i.source.clone()).collect();
cache.update_file_entry(rel.clone(), path, chash, imports);
Some((rel, model))
}
pub(crate) fn cached_symbols(
path: &Path,
cache: &mut cha_core::ProjectCache,
cwd: &Path,
) -> Option<(String, cha_core::SymbolIndex)> {
let rel = path
.strip_prefix(cwd)
.unwrap_or(path)
.to_string_lossy()
.to_string();
if let cha_core::FileStatus::Unchanged(chash) = cache.check_file(&rel, path)
&& let Some(idx) = cache.get_symbols(chash)
{
return Some((rel, idx));
}
let (rel, model) = cached_parse(path, cache, cwd)?;
Some((rel, cha_core::SymbolIndex::from_source_model(&model)))
}