]> git.lizzy.rs Git - rust.git/blob - crates/rust-analyzer/src/cli.rs
Merge #7777
[rust.git] / crates / rust-analyzer / src / cli.rs
1 //! Various batch processing tasks, intended primarily for debugging.
2
3 mod load_cargo;
4 mod analysis_stats;
5 mod analysis_bench;
6 mod diagnostics;
7 mod progress_report;
8 mod ssr;
9
10 use std::io::Read;
11
12 use anyhow::Result;
13 use ide::{Analysis, AnalysisHost};
14 use syntax::{AstNode, SourceFile};
15 use vfs::Vfs;
16
17 pub use self::{
18     analysis_bench::{BenchCmd, BenchWhat, Position},
19     analysis_stats::AnalysisStatsCmd,
20     diagnostics::diagnostics,
21     load_cargo::{load_workspace, load_workspace_at, LoadCargoConfig},
22     ssr::{apply_ssr_rules, search_for_patterns},
23 };
24
25 #[derive(Clone, Copy)]
26 pub enum Verbosity {
27     Spammy,
28     Verbose,
29     Normal,
30     Quiet,
31 }
32
33 impl Verbosity {
34     pub fn is_verbose(self) -> bool {
35         matches!(self, Verbosity::Verbose | Verbosity::Spammy)
36     }
37     pub fn is_spammy(self) -> bool {
38         matches!(self, Verbosity::Spammy)
39     }
40 }
41
42 pub fn parse(no_dump: bool) -> Result<()> {
43     let _p = profile::span("parsing");
44     let file = file()?;
45     if !no_dump {
46         println!("{:#?}", file.syntax());
47     }
48     std::mem::forget(file);
49     Ok(())
50 }
51
52 pub fn symbols() -> Result<()> {
53     let text = read_stdin()?;
54     let (analysis, file_id) = Analysis::from_single_file(text);
55     let structure = analysis.file_structure(file_id).unwrap();
56     for s in structure {
57         println!("{:?}", s);
58     }
59     Ok(())
60 }
61
62 pub fn highlight(rainbow: bool) -> Result<()> {
63     let (analysis, file_id) = Analysis::from_single_file(read_stdin()?);
64     let html = analysis.highlight_as_html(file_id, rainbow).unwrap();
65     println!("{}", html);
66     Ok(())
67 }
68
69 fn file() -> Result<SourceFile> {
70     let text = read_stdin()?;
71     Ok(SourceFile::parse(&text).tree())
72 }
73
74 fn read_stdin() -> Result<String> {
75     let mut buff = String::new();
76     std::io::stdin().read_to_string(&mut buff)?;
77     Ok(buff)
78 }
79
80 fn report_metric(metric: &str, value: u64, unit: &str) {
81     if std::env::var("RA_METRICS").is_err() {
82         return;
83     }
84     println!("METRIC:{}:{}:{}", metric, value, unit)
85 }
86
87 fn print_memory_usage(mut host: AnalysisHost, vfs: Vfs) {
88     let mut mem = host.per_query_memory_usage();
89
90     let before = profile::memory_usage();
91     drop(vfs);
92     let vfs = before.allocated - profile::memory_usage().allocated;
93     mem.push(("VFS".into(), vfs));
94
95     let before = profile::memory_usage();
96     drop(host);
97     mem.push(("Unaccounted".into(), before.allocated - profile::memory_usage().allocated));
98
99     mem.push(("Remaining".into(), profile::memory_usage().allocated));
100
101     for (name, bytes) in mem {
102         // NOTE: Not a debug print, so avoid going through the `eprintln` defined above.
103         eprintln!("{:>8} {}", bytes, name);
104     }
105 }