//! FIXME: write short doc here use std::{fmt, iter::FromIterator, sync::Arc}; use hir::MacroFile; use ra_db::{ salsa::{ debug::{DebugQueryTable, TableEntry}, Database, }, FileTextQuery, SourceRootId, }; use ra_ide_db::{ symbol_index::{LibrarySymbolsQuery, SymbolIndex}, RootDatabase, }; use ra_prof::{memory_usage, Bytes}; use ra_syntax::{ast, Parse, SyntaxNode}; use crate::FileId; fn syntax_tree_stats(db: &RootDatabase) -> SyntaxTreeStats { db.query(ra_db::ParseQuery).entries::() } fn macro_syntax_tree_stats(db: &RootDatabase) -> SyntaxTreeStats { db.query(hir::db::ParseMacroQuery).entries::() } pub(crate) fn status(db: &RootDatabase) -> String { let files_stats = db.query(FileTextQuery).entries::(); let syntax_tree_stats = syntax_tree_stats(db); let macro_syntax_tree_stats = macro_syntax_tree_stats(db); let symbols_stats = db.query(LibrarySymbolsQuery).entries::(); format!( "{}\n{}\n{}\n{} (macros)\n\n\nmemory:\n{}\ngc {:?} seconds ago", files_stats, symbols_stats, syntax_tree_stats, macro_syntax_tree_stats, memory_usage(), db.last_gc.elapsed().as_secs(), ) } #[derive(Default)] struct FilesStats { total: usize, size: Bytes, } impl fmt::Display for FilesStats { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { write!(fmt, "{} ({}) files", self.total, self.size) } } impl FromIterator>> for FilesStats { fn from_iter(iter: T) -> FilesStats where T: IntoIterator>>, { let mut res = FilesStats::default(); for entry in iter { res.total += 1; res.size += entry.value.unwrap().len(); } res } } #[derive(Default)] pub(crate) struct SyntaxTreeStats { total: usize, pub(crate) retained: usize, } impl fmt::Display for SyntaxTreeStats { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { write!(fmt, "{} trees, {} retained", self.total, self.retained) } } impl FromIterator>> for SyntaxTreeStats { fn from_iter(iter: T) -> SyntaxTreeStats where T: IntoIterator>>, { let mut res = SyntaxTreeStats::default(); for entry in iter { res.total += 1; res.retained += entry.value.is_some() as usize; } res } } impl FromIterator, M)>>> for SyntaxTreeStats { fn from_iter(iter: T) -> SyntaxTreeStats where T: IntoIterator, M)>>>, { let mut res = SyntaxTreeStats::default(); for entry in iter { res.total += 1; res.retained += entry.value.is_some() as usize; } res } } #[derive(Default)] struct LibrarySymbolsStats { total: usize, size: Bytes, } impl fmt::Display for LibrarySymbolsStats { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { write!(fmt, "{} ({}) symbols", self.total, self.size,) } } impl FromIterator>> for LibrarySymbolsStats { fn from_iter(iter: T) -> LibrarySymbolsStats where T: IntoIterator>>, { let mut res = LibrarySymbolsStats::default(); for entry in iter { let value = entry.value.unwrap(); res.total += value.len(); res.size += value.memory_size(); } res } }