rust_analyzer/
cli.rs

1//! Various batch processing tasks, intended primarily for debugging.
2
3#![allow(clippy::print_stdout, clippy::print_stderr)]
4
5mod analysis_stats;
6mod diagnostics;
7pub mod flags;
8mod highlight;
9mod lsif;
10mod parse;
11mod prime_caches;
12mod run_tests;
13mod rustc_tests;
14mod scip;
15mod ssr;
16mod symbols;
17mod unresolved_references;
18
19mod progress_report;
20
21use std::io::Read;
22
23use anyhow::Result;
24use hir::{Module, Name};
25use hir_ty::db::HirDatabase;
26use ide::{AnalysisHost, Edition};
27use itertools::Itertools;
28use vfs::Vfs;
29
30#[derive(Clone, Copy)]
31pub enum Verbosity {
32    Spammy,
33    Verbose,
34    Normal,
35    Quiet,
36}
37
38impl Verbosity {
39    pub fn is_verbose(self) -> bool {
40        matches!(self, Verbosity::Verbose | Verbosity::Spammy)
41    }
42    pub fn is_spammy(self) -> bool {
43        matches!(self, Verbosity::Spammy)
44    }
45}
46
47fn read_stdin() -> anyhow::Result<String> {
48    let mut buff = String::new();
49    std::io::stdin().read_to_string(&mut buff)?;
50    Ok(buff)
51}
52
53fn report_metric(metric: &str, value: u64, unit: &str) {
54    if std::env::var("RA_METRICS").is_err() {
55        return;
56    }
57    println!("METRIC:{metric}:{value}:{unit}")
58}
59
60fn print_memory_usage(mut host: AnalysisHost, vfs: Vfs) {
61    let mem = host.per_query_memory_usage();
62
63    let before = profile::memory_usage();
64    drop(vfs);
65    let vfs = before.allocated - profile::memory_usage().allocated;
66
67    let before = profile::memory_usage();
68    drop(host);
69    let unaccounted = before.allocated - profile::memory_usage().allocated;
70    let remaining = profile::memory_usage().allocated;
71
72    for (name, bytes, entries) in mem {
73        // NOTE: Not a debug print, so avoid going through the `eprintln` defined above.
74        eprintln!("{bytes:>8} {entries:>6} {name}");
75    }
76    eprintln!("{vfs:>8}        VFS");
77
78    eprintln!("{unaccounted:>8}        Unaccounted");
79
80    eprintln!("{remaining:>8}        Remaining");
81}
82
83fn full_name_of_item(db: &dyn HirDatabase, module: Module, name: Name) -> String {
84    module
85        .path_to_root(db)
86        .into_iter()
87        .rev()
88        .filter_map(|it| it.name(db))
89        .chain(Some(name))
90        .map(|it| it.display(db, Edition::LATEST).to_string())
91        .join("::")
92}