use std::path::PathBuf;
use ra_ap_hir::{self as hir};
use ra_ap_ide_db::RootDatabase;
use ra_ap_vfs::Vfs;
use crate::analyzer;
use self::{attr::ItemAttrs, visibility::ItemVisibility};
pub(crate) mod attr;
pub(crate) mod kind;
pub(crate) mod visibility;
#[derive(Clone, PartialEq, Debug)]
pub struct Item {
pub crate_name: Option<String>,
pub path: Vec<String>,
pub file_path: Option<PathBuf>,
pub hir: Option<hir::ModuleDef>,
pub visibility: Option<visibility::ItemVisibility>,
pub attrs: attr::ItemAttrs,
pub kind: Option<kind::ItemKind>,
}
impl Item {
pub fn new(
moduledef_hir: hir::ModuleDef,
path: Vec<String>,
db: &RootDatabase,
vfs: &Vfs,
) -> Self {
let crate_name = {
let krate = analyzer::krate(moduledef_hir, db);
krate.map(|krate| analyzer::crate_name(krate, db))
};
let file_path = {
match moduledef_hir {
hir::ModuleDef::Module(module) => Some(module),
_ => None,
}
.and_then(|module| {
analyzer::module_file(module.definition_source(db), db, vfs).map(Into::into)
})
};
let hir = Some(moduledef_hir);
let visibility = Some(ItemVisibility::new(moduledef_hir, db));
let attrs = {
let cfgs: Vec<_> = analyzer::cfg_attrs(moduledef_hir, db);
let test = analyzer::test_attr(moduledef_hir, db);
ItemAttrs { cfgs, test }
};
let kind = hir.map(|hir| kind::ItemKind::new(hir, db));
Self {
crate_name,
path,
file_path,
hir,
visibility,
attrs,
kind,
}
}
pub fn display_name(&self) -> String {
self.path
.last()
.expect("Expected path with at least one component")
.clone()
}
pub fn display_path(&self) -> String {
self.path.join("::")
}
pub fn kind_display_name(&self) -> Option<String> {
self.kind.as_ref().map(|kind| kind.to_string())
}
pub(crate) fn is_crate(&self, _db: &RootDatabase) -> bool {
let Some(hir::ModuleDef::Module(module)) = self.hir else {
return false;
};
module.is_crate_root()
}
pub(crate) fn is_file(&self) -> bool {
self.file_path.is_some()
}
}