about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--crates/rust-analyzer/src/bin/main.rs40
-rw-r--r--crates/rust-analyzer/src/cli.rs48
-rw-r--r--crates/rust-analyzer/src/cli/analysis_stats.rs21
-rw-r--r--crates/rust-analyzer/src/cli/diagnostics.rs120
-rw-r--r--crates/rust-analyzer/src/cli/flags.rs (renamed from crates/rust-analyzer/src/bin/flags.rs)5
-rw-r--r--crates/rust-analyzer/src/cli/highlight.rs14
-rw-r--r--crates/rust-analyzer/src/cli/parse.rs17
-rw-r--r--crates/rust-analyzer/src/cli/ssr.rs126
-rw-r--r--crates/rust-analyzer/src/cli/symbols.rs16
9 files changed, 201 insertions, 206 deletions
diff --git a/crates/rust-analyzer/src/bin/main.rs b/crates/rust-analyzer/src/bin/main.rs
index 97246cae6f0..ace07cc50d9 100644
--- a/crates/rust-analyzer/src/bin/main.rs
+++ b/crates/rust-analyzer/src/bin/main.rs
@@ -1,7 +1,6 @@
 //! Driver for rust-analyzer.
 //!
 //! Based on cli flags, either spawns an LSP server, or runs a batch analysis
-mod flags;
 mod logger;
 mod rustc_wrapper;
 
@@ -9,13 +8,7 @@ use std::{convert::TryFrom, env, fs, path::Path, process};
 
 use lsp_server::Connection;
 use project_model::ProjectManifest;
-use rust_analyzer::{
-    cli::{self, AnalysisStatsCmd},
-    config::Config,
-    from_json,
-    lsp_ext::supports_utf8,
-    Result,
-};
+use rust_analyzer::{cli::flags, config::Config, from_json, lsp_ext::supports_utf8, Result};
 use vfs::AbsPathBuf;
 
 #[cfg(all(feature = "mimalloc"))]
@@ -86,29 +79,14 @@ fn try_main() -> Result<()> {
             }
             run_server()?
         }
-        flags::RustAnalyzerCmd::ProcMacro(_) => proc_macro_srv::cli::run()?,
-        flags::RustAnalyzerCmd::Parse(cmd) => cli::parse(cmd.no_dump)?,
-        flags::RustAnalyzerCmd::Symbols(_) => cli::symbols()?,
-        flags::RustAnalyzerCmd::Highlight(cmd) => cli::highlight(cmd.rainbow)?,
-        flags::RustAnalyzerCmd::AnalysisStats(cmd) => AnalysisStatsCmd {
-            randomize: cmd.randomize,
-            parallel: cmd.parallel,
-            memory_usage: cmd.memory_usage,
-            only: cmd.only,
-            with_deps: cmd.with_deps,
-            no_sysroot: cmd.no_sysroot,
-            path: cmd.path,
-            enable_build_scripts: !cmd.disable_build_scripts,
-            enable_proc_macros: !cmd.disable_proc_macros,
-            skip_inference: cmd.skip_inference,
-        }
-        .run(verbosity)?,
-
-        flags::RustAnalyzerCmd::Diagnostics(cmd) => {
-            cli::diagnostics(&cmd.path, !cmd.disable_build_scripts, !cmd.disable_proc_macros)?
-        }
-        flags::RustAnalyzerCmd::Ssr(cmd) => cli::apply_ssr_rules(cmd.rule)?,
-        flags::RustAnalyzerCmd::Search(cmd) => cli::search_for_patterns(cmd.pattern, cmd.debug)?,
+        flags::RustAnalyzerCmd::ProcMacro(flags::ProcMacro) => proc_macro_srv::cli::run()?,
+        flags::RustAnalyzerCmd::Parse(cmd) => cmd.run()?,
+        flags::RustAnalyzerCmd::Symbols(cmd) => cmd.run()?,
+        flags::RustAnalyzerCmd::Highlight(cmd) => cmd.run()?,
+        flags::RustAnalyzerCmd::AnalysisStats(cmd) => cmd.run(verbosity)?,
+        flags::RustAnalyzerCmd::Diagnostics(cmd) => cmd.run()?,
+        flags::RustAnalyzerCmd::Ssr(cmd) => cmd.run()?,
+        flags::RustAnalyzerCmd::Search(cmd) => cmd.run()?,
     }
     Ok(())
 }
diff --git a/crates/rust-analyzer/src/cli.rs b/crates/rust-analyzer/src/cli.rs
index 2f65a1dad07..efd8a2aa9fc 100644
--- a/crates/rust-analyzer/src/cli.rs
+++ b/crates/rust-analyzer/src/cli.rs
@@ -1,24 +1,22 @@
 //! Various batch processing tasks, intended primarily for debugging.
 
+pub mod flags;
 pub mod load_cargo;
+mod parse;
+mod symbols;
+mod highlight;
 mod analysis_stats;
 mod diagnostics;
-mod progress_report;
 mod ssr;
 
+mod progress_report;
+
 use std::io::Read;
 
 use anyhow::Result;
-use ide::{Analysis, AnalysisHost};
-use syntax::{AstNode, SourceFile};
+use ide::AnalysisHost;
 use vfs::Vfs;
 
-pub use self::{
-    analysis_stats::AnalysisStatsCmd,
-    diagnostics::diagnostics,
-    ssr::{apply_ssr_rules, search_for_patterns},
-};
-
 #[derive(Clone, Copy)]
 pub enum Verbosity {
     Spammy,
@@ -36,38 +34,6 @@ impl Verbosity {
     }
 }
 
-pub fn parse(no_dump: bool) -> Result<()> {
-    let _p = profile::span("parsing");
-    let file = file()?;
-    if !no_dump {
-        println!("{:#?}", file.syntax());
-    }
-    std::mem::forget(file);
-    Ok(())
-}
-
-pub fn symbols() -> Result<()> {
-    let text = read_stdin()?;
-    let (analysis, file_id) = Analysis::from_single_file(text);
-    let structure = analysis.file_structure(file_id).unwrap();
-    for s in structure {
-        println!("{:?}", s);
-    }
-    Ok(())
-}
-
-pub fn highlight(rainbow: bool) -> Result<()> {
-    let (analysis, file_id) = Analysis::from_single_file(read_stdin()?);
-    let html = analysis.highlight_as_html(file_id, rainbow).unwrap();
-    println!("{}", html);
-    Ok(())
-}
-
-fn file() -> Result<SourceFile> {
-    let text = read_stdin()?;
-    Ok(SourceFile::parse(&text).tree())
-}
-
 fn read_stdin() -> Result<String> {
     let mut buff = String::new();
     std::io::stdin().read_to_string(&mut buff)?;
diff --git a/crates/rust-analyzer/src/cli/analysis_stats.rs b/crates/rust-analyzer/src/cli/analysis_stats.rs
index 37da24f30e1..454510177e8 100644
--- a/crates/rust-analyzer/src/cli/analysis_stats.rs
+++ b/crates/rust-analyzer/src/cli/analysis_stats.rs
@@ -3,7 +3,6 @@
 
 use std::{
     env,
-    path::PathBuf,
     time::{SystemTime, UNIX_EPOCH},
 };
 
@@ -28,6 +27,7 @@ use syntax::AstNode;
 use vfs::{Vfs, VfsPath};
 
 use crate::cli::{
+    flags,
     load_cargo::{load_workspace_at, LoadCargoConfig},
     print_memory_usage,
     progress_report::ProgressReport,
@@ -43,20 +43,7 @@ impl<DB: ParallelDatabase> Clone for Snap<salsa::Snapshot<DB>> {
     }
 }
 
-pub struct AnalysisStatsCmd {
-    pub randomize: bool,
-    pub parallel: bool,
-    pub memory_usage: bool,
-    pub only: Option<String>,
-    pub with_deps: bool,
-    pub no_sysroot: bool,
-    pub path: PathBuf,
-    pub enable_build_scripts: bool,
-    pub enable_proc_macros: bool,
-    pub skip_inference: bool,
-}
-
-impl AnalysisStatsCmd {
+impl flags::AnalysisStats {
     pub fn run(self, verbosity: Verbosity) -> Result<()> {
         let mut rng = {
             let seed = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_millis() as u64;
@@ -67,8 +54,8 @@ impl AnalysisStatsCmd {
         let mut cargo_config = CargoConfig::default();
         cargo_config.no_sysroot = self.no_sysroot;
         let load_cargo_config = LoadCargoConfig {
-            load_out_dirs_from_check: self.enable_build_scripts,
-            with_proc_macro: self.enable_proc_macros,
+            load_out_dirs_from_check: !self.disable_build_scripts,
+            with_proc_macro: !self.disable_proc_macros,
             prefill_caches: false,
         };
         let (host, vfs, _proc_macro) =
diff --git a/crates/rust-analyzer/src/cli/diagnostics.rs b/crates/rust-analyzer/src/cli/diagnostics.rs
index 84aaf1d5055..52511ceb580 100644
--- a/crates/rust-analyzer/src/cli/diagnostics.rs
+++ b/crates/rust-analyzer/src/cli/diagnostics.rs
@@ -1,9 +1,6 @@
-//! Analyze all modules in a project for diagnostics. Exits with a non-zero status
-//! code if any errors are found.
+//! Analyze all modules in a project for diagnostics. Exits with a non-zero
+//! status code if any errors are found.
 
-use std::path::Path;
-
-use anyhow::anyhow;
 use rustc_hash::FxHashSet;
 
 use hir::{db::HirDatabase, Crate, Module};
@@ -11,74 +8,79 @@ use ide::{AssistResolveStrategy, DiagnosticsConfig, Severity};
 use ide_db::base_db::SourceDatabaseExt;
 
 use crate::cli::{
+    flags,
     load_cargo::{load_workspace_at, LoadCargoConfig},
-    Result,
 };
 
-fn all_modules(db: &dyn HirDatabase) -> Vec<Module> {
-    let mut worklist: Vec<_> =
-        Crate::all(db).into_iter().map(|krate| krate.root_module(db)).collect();
-    let mut modules = Vec::new();
+impl flags::Diagnostics {
+    pub fn run(self) -> anyhow::Result<()> {
+        let cargo_config = Default::default();
+        let load_cargo_config = LoadCargoConfig {
+            load_out_dirs_from_check: !self.disable_build_scripts,
+            with_proc_macro: !self.disable_proc_macros,
+            prefill_caches: false,
+        };
+        let (host, _vfs, _proc_macro) =
+            load_workspace_at(&self.path, &cargo_config, &load_cargo_config, &|_| {})?;
+        let db = host.raw_database();
+        let analysis = host.analysis();
 
-    while let Some(module) = worklist.pop() {
-        modules.push(module);
-        worklist.extend(module.children(db));
-    }
-
-    modules
-}
+        let mut found_error = false;
+        let mut visited_files = FxHashSet::default();
 
-pub fn diagnostics(
-    path: &Path,
-    load_out_dirs_from_check: bool,
-    with_proc_macro: bool,
-) -> Result<()> {
-    let cargo_config = Default::default();
-    let load_cargo_config =
-        LoadCargoConfig { load_out_dirs_from_check, with_proc_macro, prefill_caches: false };
-    let (host, _vfs, _proc_macro) =
-        load_workspace_at(path, &cargo_config, &load_cargo_config, &|_| {})?;
-    let db = host.raw_database();
-    let analysis = host.analysis();
+        let work = all_modules(db).into_iter().filter(|module| {
+            let file_id = module.definition_source(db).file_id.original_file(db);
+            let source_root = db.file_source_root(file_id);
+            let source_root = db.source_root(source_root);
+            !source_root.is_library
+        });
 
-    let mut found_error = false;
-    let mut visited_files = FxHashSet::default();
+        for module in work {
+            let file_id = module.definition_source(db).file_id.original_file(db);
+            if !visited_files.contains(&file_id) {
+                let crate_name =
+                    module.krate().display_name(db).as_deref().unwrap_or("unknown").to_string();
+                println!("processing crate: {}, module: {}", crate_name, _vfs.file_path(file_id));
+                for diagnostic in analysis
+                    .diagnostics(
+                        &DiagnosticsConfig::default(),
+                        AssistResolveStrategy::None,
+                        file_id,
+                    )
+                    .unwrap()
+                {
+                    if matches!(diagnostic.severity, Severity::Error) {
+                        found_error = true;
+                    }
 
-    let work = all_modules(db).into_iter().filter(|module| {
-        let file_id = module.definition_source(db).file_id.original_file(db);
-        let source_root = db.file_source_root(file_id);
-        let source_root = db.source_root(source_root);
-        !source_root.is_library
-    });
-
-    for module in work {
-        let file_id = module.definition_source(db).file_id.original_file(db);
-        if !visited_files.contains(&file_id) {
-            let crate_name =
-                module.krate().display_name(db).as_deref().unwrap_or("unknown").to_string();
-            println!("processing crate: {}, module: {}", crate_name, _vfs.file_path(file_id));
-            for diagnostic in analysis
-                .diagnostics(&DiagnosticsConfig::default(), AssistResolveStrategy::None, file_id)
-                .unwrap()
-            {
-                if matches!(diagnostic.severity, Severity::Error) {
-                    found_error = true;
+                    println!("{:?}", diagnostic);
                 }
 
-                println!("{:?}", diagnostic);
+                visited_files.insert(file_id);
             }
+        }
+
+        println!();
+        println!("diagnostic scan complete");
 
-            visited_files.insert(file_id);
+        if found_error {
+            println!();
+            anyhow::bail!("diagnostic error detected")
         }
+
+        Ok(())
     }
+}
 
-    println!();
-    println!("diagnostic scan complete");
+fn all_modules(db: &dyn HirDatabase) -> Vec<Module> {
+    let mut worklist: Vec<_> =
+        Crate::all(db).into_iter().map(|krate| krate.root_module(db)).collect();
+    let mut modules = Vec::new();
 
-    if found_error {
-        println!();
-        Err(anyhow!("diagnostic error detected"))
-    } else {
-        Ok(())
+    while let Some(module) = worklist.pop() {
+        modules.push(module);
+        worklist.extend(module.children(db));
     }
+
+    modules
 }
diff --git a/crates/rust-analyzer/src/bin/flags.rs b/crates/rust-analyzer/src/cli/flags.rs
index 19173241b28..f8babe4bc3d 100644
--- a/crates/rust-analyzer/src/bin/flags.rs
+++ b/crates/rust-analyzer/src/cli/flags.rs
@@ -3,7 +3,8 @@
 use std::path::PathBuf;
 
 use ide_ssr::{SsrPattern, SsrRule};
-use rust_analyzer::cli::Verbosity;
+
+use crate::cli::Verbosity;
 
 xflags::xflags! {
     src "./src/bin/flags.rs"
@@ -196,7 +197,7 @@ impl RustAnalyzer {
 // generated end
 
 impl RustAnalyzer {
-    pub(crate) fn verbosity(&self) -> Verbosity {
+    pub fn verbosity(&self) -> Verbosity {
         if self.quiet {
             return Verbosity::Quiet;
         }
diff --git a/crates/rust-analyzer/src/cli/highlight.rs b/crates/rust-analyzer/src/cli/highlight.rs
new file mode 100644
index 00000000000..4f9b362f1be
--- /dev/null
+++ b/crates/rust-analyzer/src/cli/highlight.rs
@@ -0,0 +1,14 @@
+//! Read Rust code on stdin, print HTML highlighted version to stdout.
+
+use ide::Analysis;
+
+use crate::cli::{flags, read_stdin};
+
+impl flags::Highlight {
+    pub fn run(self) -> anyhow::Result<()> {
+        let (analysis, file_id) = Analysis::from_single_file(read_stdin()?);
+        let html = analysis.highlight_as_html(file_id, self.rainbow).unwrap();
+        println!("{}", html);
+        Ok(())
+    }
+}
diff --git a/crates/rust-analyzer/src/cli/parse.rs b/crates/rust-analyzer/src/cli/parse.rs
new file mode 100644
index 00000000000..5ef8cdff4cf
--- /dev/null
+++ b/crates/rust-analyzer/src/cli/parse.rs
@@ -0,0 +1,17 @@
+//! Read Rust code on stdin, print syntax tree on stdout.
+use syntax::{AstNode, SourceFile};
+
+use crate::cli::{flags, read_stdin};
+
+impl flags::Parse {
+    pub fn run(self) -> anyhow::Result<()> {
+        let _p = profile::span("parsing");
+        let text = read_stdin()?;
+        let file = SourceFile::parse(&text).tree();
+        if !self.no_dump {
+            println!("{:#?}", file.syntax());
+        }
+        std::mem::forget(file);
+        Ok(())
+    }
+}
diff --git a/crates/rust-analyzer/src/cli/ssr.rs b/crates/rust-analyzer/src/cli/ssr.rs
index 60092127d96..e8291782b7a 100644
--- a/crates/rust-analyzer/src/cli/ssr.rs
+++ b/crates/rust-analyzer/src/cli/ssr.rs
@@ -1,72 +1,86 @@
 //! Applies structured search replace rules from the command line.
 
+use ide_ssr::MatchFinder;
+use project_model::CargoConfig;
+
 use crate::cli::{
+    flags,
     load_cargo::{load_workspace_at, LoadCargoConfig},
     Result,
 };
-use ide_ssr::{MatchFinder, SsrPattern, SsrRule};
-use project_model::CargoConfig;
 
-pub fn apply_ssr_rules(rules: Vec<SsrRule>) -> Result<()> {
-    use ide_db::base_db::SourceDatabaseExt;
-    let cargo_config = CargoConfig::default();
-    let load_cargo_config = LoadCargoConfig {
-        load_out_dirs_from_check: true,
-        with_proc_macro: true,
-        prefill_caches: false,
-    };
-    let (host, vfs, _proc_macro) =
-        load_workspace_at(&std::env::current_dir()?, &cargo_config, &load_cargo_config, &|_| {})?;
-    let db = host.raw_database();
-    let mut match_finder = MatchFinder::at_first_file(db)?;
-    for rule in rules {
-        match_finder.add_rule(rule)?;
-    }
-    let edits = match_finder.edits();
-    for (file_id, edit) in edits {
-        if let Some(path) = vfs.file_path(file_id).as_path() {
-            let mut contents = db.file_text(file_id).to_string();
-            edit.apply(&mut contents);
-            std::fs::write(path, contents)?;
+impl flags::Ssr {
+    pub fn run(self) -> Result<()> {
+        use ide_db::base_db::SourceDatabaseExt;
+        let cargo_config = CargoConfig::default();
+        let load_cargo_config = LoadCargoConfig {
+            load_out_dirs_from_check: true,
+            with_proc_macro: true,
+            prefill_caches: false,
+        };
+        let (host, vfs, _proc_macro) = load_workspace_at(
+            &std::env::current_dir()?,
+            &cargo_config,
+            &load_cargo_config,
+            &|_| {},
+        )?;
+        let db = host.raw_database();
+        let mut match_finder = MatchFinder::at_first_file(db)?;
+        for rule in self.rule {
+            match_finder.add_rule(rule)?;
+        }
+        let edits = match_finder.edits();
+        for (file_id, edit) in edits {
+            if let Some(path) = vfs.file_path(file_id).as_path() {
+                let mut contents = db.file_text(file_id).to_string();
+                edit.apply(&mut contents);
+                std::fs::write(path, contents)?;
+            }
         }
+        Ok(())
     }
-    Ok(())
 }
 
-/// Searches for `patterns`, printing debug information for any nodes whose text exactly matches
-/// `debug_snippet`. This is intended for debugging and probably isn't in it's current form useful
-/// for much else.
-pub fn search_for_patterns(patterns: Vec<SsrPattern>, debug_snippet: Option<String>) -> Result<()> {
-    use ide_db::base_db::SourceDatabaseExt;
-    use ide_db::symbol_index::SymbolsDatabase;
-    let cargo_config = CargoConfig::default();
-    let load_cargo_config = LoadCargoConfig {
-        load_out_dirs_from_check: true,
-        with_proc_macro: true,
-        prefill_caches: false,
-    };
-    let (host, _vfs, _proc_macro) =
-        load_workspace_at(&std::env::current_dir()?, &cargo_config, &load_cargo_config, &|_| {})?;
-    let db = host.raw_database();
-    let mut match_finder = MatchFinder::at_first_file(db)?;
-    for pattern in patterns {
-        match_finder.add_search_pattern(pattern)?;
-    }
-    if let Some(debug_snippet) = &debug_snippet {
-        for &root in db.local_roots().iter() {
-            let sr = db.source_root(root);
-            for file_id in sr.iter() {
-                for debug_info in match_finder.debug_where_text_equal(file_id, debug_snippet) {
-                    println!("{:#?}", debug_info);
+impl flags::Search {
+    /// Searches for `patterns`, printing debug information for any nodes whose text exactly matches
+    /// `debug_snippet`. This is intended for debugging and probably isn't in it's current form useful
+    /// for much else.
+    pub fn run(self) -> Result<()> {
+        use ide_db::base_db::SourceDatabaseExt;
+        use ide_db::symbol_index::SymbolsDatabase;
+        let cargo_config = CargoConfig::default();
+        let load_cargo_config = LoadCargoConfig {
+            load_out_dirs_from_check: true,
+            with_proc_macro: true,
+            prefill_caches: false,
+        };
+        let (host, _vfs, _proc_macro) = load_workspace_at(
+            &std::env::current_dir()?,
+            &cargo_config,
+            &load_cargo_config,
+            &|_| {},
+        )?;
+        let db = host.raw_database();
+        let mut match_finder = MatchFinder::at_first_file(db)?;
+        for pattern in self.pattern {
+            match_finder.add_search_pattern(pattern)?;
+        }
+        if let Some(debug_snippet) = &self.debug {
+            for &root in db.local_roots().iter() {
+                let sr = db.source_root(root);
+                for file_id in sr.iter() {
+                    for debug_info in match_finder.debug_where_text_equal(file_id, debug_snippet) {
+                        println!("{:#?}", debug_info);
+                    }
                 }
             }
+        } else {
+            for m in match_finder.matches().flattened().matches {
+                // We could possibly at some point do something more useful than just printing
+                // the matched text. For now though, that's the easiest thing to do.
+                println!("{}", m.matched_text());
+            }
         }
-    } else {
-        for m in match_finder.matches().flattened().matches {
-            // We could possibly at some point do something more useful than just printing
-            // the matched text. For now though, that's the easiest thing to do.
-            println!("{}", m.matched_text());
-        }
+        Ok(())
     }
-    Ok(())
 }
diff --git a/crates/rust-analyzer/src/cli/symbols.rs b/crates/rust-analyzer/src/cli/symbols.rs
new file mode 100644
index 00000000000..84659b5ea9c
--- /dev/null
+++ b/crates/rust-analyzer/src/cli/symbols.rs
@@ -0,0 +1,16 @@
+//! Read Rust code on stdin, print syntax tree on stdout.
+use ide::Analysis;
+
+use crate::cli::{flags, read_stdin};
+
+impl flags::Symbols {
+    pub fn run(self) -> anyhow::Result<()> {
+        let text = read_stdin()?;
+        let (analysis, file_id) = Analysis::from_single_file(text);
+        let structure = analysis.file_structure(file_id).unwrap();
+        for s in structure {
+            println!("{:?}", s);
+        }
+        Ok(())
+    }
+}