From 0353e1c6f4eb0f9351f9a75f5fef016d6ac7960b Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 17 Feb 2020 17:12:37 +0100 Subject: Use Arguments::from_os --- crates/ra_cli/src/main.rs | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) (limited to 'crates/ra_cli') diff --git a/crates/ra_cli/src/main.rs b/crates/ra_cli/src/main.rs index 750cbab86..f0daaaf15 100644 --- a/crates/ra_cli/src/main.rs +++ b/crates/ra_cli/src/main.rs @@ -40,16 +40,10 @@ impl Verbosity { fn main() -> Result<()> { env_logger::try_init()?; - let subcommand = match std::env::args_os().nth(1) { - None => { - eprintln!("{}", help::GLOBAL_HELP); - return Ok(()); - } - Some(s) => s, - }; - let mut matches = Arguments::from_vec(std::env::args_os().skip(2).collect()); + let mut matches = Arguments::from_env(); + let subcommand = matches.subcommand()?.unwrap_or_default(); - match &*subcommand.to_string_lossy() { + match subcommand.as_str() { "parse" => { if matches.contains(["-h", "--help"]) { eprintln!("{}", help::PARSE_HELP); -- cgit v1.2.3 From d5371b5dec5fbf6add535d09afbddcb5b180ef85 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 17 Feb 2020 17:14:55 +0100 Subject: Inline help --- crates/ra_cli/src/help.rs | 75 --------------------------------- crates/ra_cli/src/main.rs | 103 ++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 96 insertions(+), 82 deletions(-) delete mode 100644 crates/ra_cli/src/help.rs (limited to 'crates/ra_cli') diff --git a/crates/ra_cli/src/help.rs b/crates/ra_cli/src/help.rs deleted file mode 100644 index d3c4c7d0b..000000000 --- a/crates/ra_cli/src/help.rs +++ /dev/null @@ -1,75 +0,0 @@ -//! FIXME: write short doc here - -pub const GLOBAL_HELP: &str = "ra-cli - -USAGE: - ra_cli - -FLAGS: - -h, --help Prints help information - -SUBCOMMANDS: - analysis-bench - analysis-stats - highlight - parse - symbols"; - -pub const ANALYSIS_BENCH_HELP: &str = "ra_cli-analysis-bench - -USAGE: - ra_cli analysis-bench [FLAGS] [OPTIONS] [PATH] - -FLAGS: - -h, --help Prints help information - -v, --verbose - -OPTIONS: - --complete Compute completions at this location - --highlight Hightlight this file - -ARGS: - Project to analyse"; - -pub const ANALYSIS_STATS_HELP: &str = "ra-cli-analysis-stats - -USAGE: - ra_cli analysis-stats [FLAGS] [OPTIONS] [PATH] - -FLAGS: - -h, --help Prints help information - --memory-usage - -v, --verbose - -q, --quiet - -OPTIONS: - -o - -ARGS: - "; - -pub const HIGHLIGHT_HELP: &str = "ra-cli-highlight - -USAGE: - ra_cli highlight [FLAGS] - -FLAGS: - -h, --help Prints help information - -r, --rainbow"; - -pub const SYMBOLS_HELP: &str = "ra-cli-symbols - -USAGE: - ra_cli highlight [FLAGS] - -FLAGS: - -h, --help Prints help inforamtion"; - -pub const PARSE_HELP: &str = "ra-cli-parse - -USAGE: - ra_cli parse [FLAGS] - -FLAGS: - -h, --help Prints help inforamtion - --no-dump"; diff --git a/crates/ra_cli/src/main.rs b/crates/ra_cli/src/main.rs index f0daaaf15..9a7f9724e 100644 --- a/crates/ra_cli/src/main.rs +++ b/crates/ra_cli/src/main.rs @@ -2,7 +2,6 @@ mod analysis_stats; mod analysis_bench; -mod help; mod progress_report; use std::{error::Error, fmt::Write, io::Read}; @@ -46,9 +45,20 @@ fn main() -> Result<()> { match subcommand.as_str() { "parse" => { if matches.contains(["-h", "--help"]) { - eprintln!("{}", help::PARSE_HELP); + eprintln!( + "\ +ra-cli-parse + +USAGE: + ra_cli parse [FLAGS] + +FLAGS: + -h, --help Prints help inforamtion + --no-dump" + ); return Ok(()); } + let no_dump = matches.contains("--no-dump"); matches.finish().or_else(handle_extra_flags)?; @@ -61,10 +71,21 @@ fn main() -> Result<()> { } "symbols" => { if matches.contains(["-h", "--help"]) { - eprintln!("{}", help::SYMBOLS_HELP); + eprintln!( + "\ +ra-cli-symbols + +USAGE: + ra_cli highlight [FLAGS] + +FLAGS: + -h, --help Prints help inforamtion" + ); return Ok(()); } + matches.finish().or_else(handle_extra_flags)?; + let file = file()?; for s in file_structure(&file) { println!("{:?}", s); @@ -72,20 +93,51 @@ fn main() -> Result<()> { } "highlight" => { if matches.contains(["-h", "--help"]) { - eprintln!("{}", help::HIGHLIGHT_HELP); + eprintln!( + "\ +ra-cli-highlight + +USAGE: + ra_cli highlight [FLAGS] + +FLAGS: + -h, --help Prints help information + -r, --rainbow" + ); return Ok(()); } + let rainbow_opt = matches.contains(["-r", "--rainbow"]); matches.finish().or_else(handle_extra_flags)?; + let (analysis, file_id) = Analysis::from_single_file(read_stdin()?); let html = analysis.highlight_as_html(file_id, rainbow_opt).unwrap(); println!("{}", html); } "analysis-stats" => { if matches.contains(["-h", "--help"]) { - eprintln!("{}", help::ANALYSIS_STATS_HELP); + eprintln!( + "\ +ra-cli-analysis-stats + +USAGE: + ra_cli analysis-stats [FLAGS] [OPTIONS] [PATH] + +FLAGS: + -h, --help Prints help information + --memory-usage + -v, --verbose + -q, --quiet + +OPTIONS: + -o + +ARGS: + " + ); return Ok(()); } + let verbosity = match ( matches.contains(["-vv", "--spammy"]), matches.contains(["-v", "--verbose"]), @@ -110,6 +162,8 @@ fn main() -> Result<()> { } trailing.pop().unwrap() }; + matches.finish().or_else(handle_extra_flags)?; + analysis_stats::run( verbosity, memory_usage, @@ -121,9 +175,27 @@ fn main() -> Result<()> { } "analysis-bench" => { if matches.contains(["-h", "--help"]) { - eprintln!("{}", help::ANALYSIS_BENCH_HELP); + eprintln!( + "\ +ra_cli-analysis-bench + +USAGE: + ra_cli analysis-bench [FLAGS] [OPTIONS] [PATH] + +FLAGS: + -h, --help Prints help information + -v, --verbose + +OPTIONS: + --complete Compute completions at this location + --highlight Hightlight this file + +ARGS: + Project to analyse" + ); return Ok(()); } + let verbose = matches.contains(["-v", "--verbose"]); let path: String = matches.opt_value_from_str("--path")?.unwrap_or_default(); let highlight_path: Option = matches.opt_value_from_str("--highlight")?; @@ -138,9 +210,26 @@ fn main() -> Result<()> { ), }; matches.finish().or_else(handle_extra_flags)?; + analysis_bench::run(verbose, path.as_ref(), op)?; } - _ => eprintln!("{}", help::GLOBAL_HELP), + _ => eprintln!( + "\ +ra-cli + +USAGE: + ra_cli + +FLAGS: + -h, --help Prints help information + +SUBCOMMANDS: + analysis-bench + analysis-stats + highlight + parse + symbols" + ), } Ok(()) } -- cgit v1.2.3 From 559c5f37f6d0435eb3a0bbb1cf10051783df4dfc Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 17 Feb 2020 17:19:55 +0100 Subject: Cleanup imports --- crates/ra_cli/src/analysis_stats.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'crates/ra_cli') diff --git a/crates/ra_cli/src/analysis_stats.rs b/crates/ra_cli/src/analysis_stats.rs index 6d2dd34c6..bfa174d51 100644 --- a/crates/ra_cli/src/analysis_stats.rs +++ b/crates/ra_cli/src/analysis_stats.rs @@ -2,17 +2,16 @@ use std::{collections::HashSet, fmt::Write, path::Path, time::Instant}; -use itertools::Itertools; -use rand::{seq::SliceRandom, thread_rng}; - use hir::{ db::{DefDatabase, HirDatabase}, AssocItem, Crate, HasSource, HirDisplay, ModuleDef, }; use hir_def::FunctionId; use hir_ty::{Ty, TypeWalk}; +use itertools::Itertools; use ra_db::SourceDatabaseExt; use ra_syntax::AstNode; +use rand::{seq::SliceRandom, thread_rng}; use crate::{progress_report::ProgressReport, Result, Verbosity}; -- cgit v1.2.3 From d7be1da8df45027ce18b8af9da68ed98b9a454cc Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 17 Feb 2020 17:31:09 +0100 Subject: Inline ra_batch --- crates/ra_cli/Cargo.toml | 15 ++-- crates/ra_cli/src/analysis_bench.rs | 4 +- crates/ra_cli/src/analysis_stats.rs | 4 +- crates/ra_cli/src/load_cargo.rs | 153 ++++++++++++++++++++++++++++++++++++ crates/ra_cli/src/main.rs | 3 +- 5 files changed, 168 insertions(+), 11 deletions(-) create mode 100644 crates/ra_cli/src/load_cargo.rs (limited to 'crates/ra_cli') diff --git a/crates/ra_cli/Cargo.toml b/crates/ra_cli/Cargo.toml index 53d4876f6..03494a809 100644 --- a/crates/ra_cli/Cargo.toml +++ b/crates/ra_cli/Cargo.toml @@ -6,18 +6,23 @@ authors = ["rust-analyzer developers"] publish = false [dependencies] +crossbeam-channel = "0.4.0" +env_logger = { version = "0.7.1", default-features = false } itertools = "0.8.0" +log = "0.4.5" pico-args = "0.3.0" -env_logger = { version = "0.7.1", default-features = false } rand = { version = "0.7.0", features = ["small_rng"] } +rustc-hash = "1.0" -ra_syntax = { path = "../ra_syntax" } -ra_ide = { path = "../ra_ide" } -ra_batch = { path = "../ra_batch" } hir = { path = "../ra_hir", package = "ra_hir" } -hir_ty = { path = "../ra_hir_ty", package = "ra_hir_ty" } hir_def = { path = "../ra_hir_def", package = "ra_hir_def" } +hir_ty = { path = "../ra_hir_ty", package = "ra_hir_ty" } ra_db = { path = "../ra_db" } +ra_ide = { path = "../ra_ide" } +ra_project_model = { path = "../ra_project_model" } +ra_syntax = { path = "../ra_syntax" } +ra_vfs = "0.5.0" +ra_vfs_glob = { path = "../ra_vfs_glob" } [dependencies.ra_prof] path = "../ra_prof" diff --git a/crates/ra_cli/src/analysis_bench.rs b/crates/ra_cli/src/analysis_bench.rs index 4835a68ce..3f10ed400 100644 --- a/crates/ra_cli/src/analysis_bench.rs +++ b/crates/ra_cli/src/analysis_bench.rs @@ -13,7 +13,7 @@ use ra_db::{ }; use ra_ide::{Analysis, AnalysisChange, AnalysisHost, FilePosition, LineCol}; -use crate::Result; +use crate::{load_cargo::load_cargo, Result}; pub(crate) struct Position { path: PathBuf, @@ -46,7 +46,7 @@ pub(crate) fn run(verbose: bool, path: &Path, op: Op) -> Result<()> { let start = Instant::now(); eprint!("loading: "); - let (mut host, roots) = ra_batch::load_cargo(path)?; + let (mut host, roots) = load_cargo(path)?; let db = host.raw_database(); eprintln!("{:?}\n", start.elapsed()); diff --git a/crates/ra_cli/src/analysis_stats.rs b/crates/ra_cli/src/analysis_stats.rs index bfa174d51..d40f04391 100644 --- a/crates/ra_cli/src/analysis_stats.rs +++ b/crates/ra_cli/src/analysis_stats.rs @@ -13,7 +13,7 @@ use ra_db::SourceDatabaseExt; use ra_syntax::AstNode; use rand::{seq::SliceRandom, thread_rng}; -use crate::{progress_report::ProgressReport, Result, Verbosity}; +use crate::{load_cargo::load_cargo, progress_report::ProgressReport, Result, Verbosity}; pub fn run( verbosity: Verbosity, @@ -24,7 +24,7 @@ pub fn run( randomize: bool, ) -> Result<()> { let db_load_time = Instant::now(); - let (mut host, roots) = ra_batch::load_cargo(path)?; + let (mut host, roots) = load_cargo(path)?; let db = host.raw_database(); println!("Database loaded, {} roots, {:?}", roots.len(), db_load_time.elapsed()); let analysis_time = Instant::now(); diff --git a/crates/ra_cli/src/load_cargo.rs b/crates/ra_cli/src/load_cargo.rs new file mode 100644 index 000000000..2d6433f18 --- /dev/null +++ b/crates/ra_cli/src/load_cargo.rs @@ -0,0 +1,153 @@ +//! FIXME: write short doc here + +use std::{collections::HashSet, error::Error, path::Path}; + +use rustc_hash::FxHashMap; + +use crossbeam_channel::{unbounded, Receiver}; +use ra_db::{CrateGraph, FileId, SourceRootId}; +use ra_ide::{AnalysisChange, AnalysisHost, FeatureFlags}; +use ra_project_model::{get_rustc_cfg_options, PackageRoot, ProjectWorkspace}; +use ra_vfs::{RootEntry, Vfs, VfsChange, VfsTask, Watch}; +use ra_vfs_glob::RustPackageFilterBuilder; + +type Result = std::result::Result>; + +fn vfs_file_to_id(f: ra_vfs::VfsFile) -> FileId { + FileId(f.0) +} +fn vfs_root_to_id(r: ra_vfs::VfsRoot) -> SourceRootId { + SourceRootId(r.0) +} + +pub fn load_cargo(root: &Path) -> Result<(AnalysisHost, FxHashMap)> { + let root = std::env::current_dir()?.join(root); + let ws = ProjectWorkspace::discover(root.as_ref(), &Default::default())?; + let project_roots = ws.to_roots(); + let (sender, receiver) = unbounded(); + let sender = Box::new(move |t| sender.send(t).unwrap()); + let (mut vfs, roots) = Vfs::new( + project_roots + .iter() + .map(|pkg_root| { + RootEntry::new( + pkg_root.path().clone(), + RustPackageFilterBuilder::default() + .set_member(pkg_root.is_member()) + .into_vfs_filter(), + ) + }) + .collect(), + sender, + Watch(false), + ); + + // FIXME: cfg options? + let default_cfg_options = { + let mut opts = get_rustc_cfg_options(); + opts.insert_atom("test".into()); + opts.insert_atom("debug_assertion".into()); + opts + }; + + let (crate_graph, _crate_names) = + ws.to_crate_graph(&default_cfg_options, &mut |path: &Path| { + let vfs_file = vfs.load(path); + log::debug!("vfs file {:?} -> {:?}", path, vfs_file); + vfs_file.map(vfs_file_to_id) + }); + log::debug!("crate graph: {:?}", crate_graph); + + let source_roots = roots + .iter() + .map(|&vfs_root| { + let source_root_id = vfs_root_to_id(vfs_root); + let project_root = project_roots + .iter() + .find(|it| it.path() == &vfs.root2path(vfs_root)) + .unwrap() + .clone(); + (source_root_id, project_root) + }) + .collect::>(); + let host = load(&source_roots, crate_graph, &mut vfs, receiver); + Ok((host, source_roots)) +} + +pub fn load( + source_roots: &FxHashMap, + crate_graph: CrateGraph, + vfs: &mut Vfs, + receiver: Receiver, +) -> AnalysisHost { + let lru_cap = std::env::var("RA_LRU_CAP").ok().and_then(|it| it.parse::().ok()); + let mut host = AnalysisHost::new(lru_cap, FeatureFlags::default()); + let mut analysis_change = AnalysisChange::new(); + analysis_change.set_crate_graph(crate_graph); + + // wait until Vfs has loaded all roots + let mut roots_loaded = HashSet::new(); + for task in receiver { + vfs.handle_task(task); + let mut done = false; + for change in vfs.commit_changes() { + match change { + VfsChange::AddRoot { root, files } => { + let source_root_id = vfs_root_to_id(root); + let is_local = source_roots[&source_root_id].is_member(); + log::debug!( + "loaded source root {:?} with path {:?}", + source_root_id, + vfs.root2path(root) + ); + analysis_change.add_root(source_root_id, is_local); + analysis_change.set_debug_root_path( + source_root_id, + source_roots[&source_root_id].path().display().to_string(), + ); + + let mut file_map = FxHashMap::default(); + for (vfs_file, path, text) in files { + let file_id = vfs_file_to_id(vfs_file); + analysis_change.add_file(source_root_id, file_id, path.clone(), text); + file_map.insert(path, file_id); + } + roots_loaded.insert(source_root_id); + if roots_loaded.len() == vfs.n_roots() { + done = true; + } + } + VfsChange::AddFile { root, file, path, text } => { + let source_root_id = vfs_root_to_id(root); + let file_id = vfs_file_to_id(file); + analysis_change.add_file(source_root_id, file_id, path, text); + } + VfsChange::RemoveFile { .. } | VfsChange::ChangeFile { .. } => { + // We just need the first scan, so just ignore these + } + } + } + if done { + break; + } + } + + host.apply_change(analysis_change); + host +} + +#[cfg(test)] +mod tests { + use super::*; + + use hir::Crate; + + #[test] + fn test_loading_rust_analyzer() { + let path = Path::new(env!("CARGO_MANIFEST_DIR")).parent().unwrap().parent().unwrap(); + let (host, _roots) = load_cargo(path).unwrap(); + let n_crates = Crate::all(host.raw_database()).len(); + // RA has quite a few crates, but the exact count doesn't matter + assert!(n_crates > 20); + } +} diff --git a/crates/ra_cli/src/main.rs b/crates/ra_cli/src/main.rs index 9a7f9724e..4a428faff 100644 --- a/crates/ra_cli/src/main.rs +++ b/crates/ra_cli/src/main.rs @@ -1,5 +1,6 @@ //! FIXME: write short doc here +mod load_cargo; mod analysis_stats; mod analysis_bench; mod progress_report; @@ -157,12 +158,10 @@ ARGS: let path = { let mut trailing = matches.free()?; if trailing.len() != 1 { - eprintln!("{}", help::ANALYSIS_STATS_HELP); Err("Invalid flags")?; } trailing.pop().unwrap() }; - matches.finish().or_else(handle_extra_flags)?; analysis_stats::run( verbosity, -- cgit v1.2.3