use std::sync::Arc;
use crate::db::MirDatabase;
use mir_types::Name;
#[salsa::input]
pub struct ResolverConfig {
pub revision: u64,
}
#[salsa::interned]
pub struct Fqcn<'db> {
pub name: Name,
}
impl<'db> Fqcn<'db> {
#[inline]
pub fn from_str(db: &'db dyn MirDatabase, name: &str) -> Self {
Self::new(db, Name::new(name))
}
}
#[salsa::tracked]
pub fn resolve_fqcn_to_path<'db>(db: &'db dyn MirDatabase, fqcn: Fqcn<'db>) -> Option<Arc<str>> {
let cfg = db.resolver_config()?;
let _rev = cfg.revision(db);
let resolver = db.current_resolver()?;
let name = fqcn.name(db);
let path = resolver.resolve(name.as_str())?;
Some(Arc::from(path.to_string_lossy().as_ref()))
}
pub fn source_file_for_fqcn<'db>(
db: &'db dyn MirDatabase,
fqcn: Fqcn<'db>,
) -> Option<crate::db::SourceFile> {
if let Some(path) = resolve_fqcn_to_path(db, fqcn) {
if let Some(sf) = db.lookup_source_file(&path) {
return Some(sf);
}
}
let name = fqcn.name(db);
let lower = name.ascii_lowercase();
let lookup = |index: &crate::db::WorkspaceSymbolIndex| -> Option<crate::db::SourceFile> {
if let Some(loc) = index.class_like.get(&lower) {
return match loc {
crate::db::SymbolLoc::Class { file, .. }
| crate::db::SymbolLoc::Interface { file, .. }
| crate::db::SymbolLoc::Trait { file, .. }
| crate::db::SymbolLoc::Enum { file, .. } => Some(*file),
_ => None,
};
}
if let Some(crate::db::SymbolLoc::Function { file, .. }) = index.functions.get(&lower) {
return Some(*file);
}
if let Some(crate::db::SymbolLoc::Constant { file, .. }) = index.constants.get(&name) {
return Some(*file);
}
None
};
match db.frozen_workspace_index() {
Some(frozen) => lookup(frozen),
None => lookup(&crate::db::workspace_index(db)),
}
}