From f84deffd72d28143bf95c91563121de9b41c76ae Mon Sep 17 00:00:00 2001 From: Emil Lauridsen Date: Mon, 16 Mar 2020 14:51:44 +0100 Subject: Support loading OUT_DIR for CLI runs --- crates/rust-analyzer/src/bin/args.rs | 14 +++-- crates/rust-analyzer/src/bin/main.rs | 32 +++++++----- crates/rust-analyzer/src/cli/analysis_bench.rs | 9 +++- crates/rust-analyzer/src/cli/analysis_stats.rs | 3 +- crates/rust-analyzer/src/cli/load_cargo.rs | 71 ++++++++++++++++---------- 5 files changed, 81 insertions(+), 48 deletions(-) (limited to 'crates') diff --git a/crates/rust-analyzer/src/bin/args.rs b/crates/rust-analyzer/src/bin/args.rs index 993d3d0b6..3cf394bb4 100644 --- a/crates/rust-analyzer/src/bin/args.rs +++ b/crates/rust-analyzer/src/bin/args.rs @@ -28,10 +28,12 @@ pub(crate) enum Command { only: Option, with_deps: bool, path: PathBuf, + load_output_dirs: bool, }, Bench { path: PathBuf, what: BenchWhat, + load_output_dirs: bool, }, RunServer, Version, @@ -136,8 +138,9 @@ USAGE: rust-analyzer analysis-stats [FLAGS] [OPTIONS] [PATH] FLAGS: - -h, --help Prints help information + -h, --help Prints help information --memory-usage + --load-output-dirs Load OUT_DIR values by running `cargo check` before analysis -v, --verbose -q, --quiet @@ -154,6 +157,7 @@ ARGS: let memory_usage = matches.contains("--memory-usage"); let only: Option = matches.opt_value_from_str(["-o", "--only"])?; let with_deps: bool = matches.contains("--with-deps"); + let load_output_dirs = matches.contains("--load-output-dirs"); let path = { let mut trailing = matches.free()?; if trailing.len() != 1 { @@ -162,7 +166,7 @@ ARGS: trailing.pop().unwrap().into() }; - Command::Stats { randomize, memory_usage, only, with_deps, path } + Command::Stats { randomize, memory_usage, only, with_deps, path, load_output_dirs } } "analysis-bench" => { if matches.contains(["-h", "--help"]) { @@ -174,7 +178,8 @@ USAGE: rust-analyzer analysis-bench [FLAGS] [OPTIONS] FLAGS: - -h, --help Prints help information + -h, --help Prints help information + --load-output-dirs Load OUT_DIR values by running `cargo check` before analysis -v, --verbose OPTIONS: @@ -201,7 +206,8 @@ ARGS: "exactly one of `--highlight`, `--complete` or `--goto-def` must be set" ), }; - Command::Bench { path, what } + let load_output_dirs = matches.contains("--load-output-dirs"); + Command::Bench { path, what, load_output_dirs } } _ => { eprintln!( diff --git a/crates/rust-analyzer/src/bin/main.rs b/crates/rust-analyzer/src/bin/main.rs index dd15b3458..a744a6695 100644 --- a/crates/rust-analyzer/src/bin/main.rs +++ b/crates/rust-analyzer/src/bin/main.rs @@ -19,19 +19,25 @@ fn main() -> Result<()> { args::Command::Parse { no_dump } => cli::parse(no_dump)?, args::Command::Symbols => cli::symbols()?, args::Command::Highlight { rainbow } => cli::highlight(rainbow)?, - args::Command::Stats { randomize, memory_usage, only, with_deps, path } => { - cli::analysis_stats( - args.verbosity, - memory_usage, - path.as_ref(), - only.as_ref().map(String::as_ref), - with_deps, - randomize, - )? - } - - args::Command::Bench { path, what } => { - cli::analysis_bench(args.verbosity, path.as_ref(), what)? + args::Command::Stats { + randomize, + memory_usage, + only, + with_deps, + path, + load_output_dirs, + } => cli::analysis_stats( + args.verbosity, + memory_usage, + path.as_ref(), + only.as_ref().map(String::as_ref), + with_deps, + randomize, + load_output_dirs, + )?, + + args::Command::Bench { path, what, load_output_dirs } => { + cli::analysis_bench(args.verbosity, path.as_ref(), what, load_output_dirs)? } args::Command::RunServer => run_server()?, diff --git a/crates/rust-analyzer/src/cli/analysis_bench.rs b/crates/rust-analyzer/src/cli/analysis_bench.rs index 28a23934f..7164b0ade 100644 --- a/crates/rust-analyzer/src/cli/analysis_bench.rs +++ b/crates/rust-analyzer/src/cli/analysis_bench.rs @@ -42,12 +42,17 @@ fn rsplit_at_char(s: &str, c: char) -> Result<(&str, &str)> { Ok((&s[..idx], &s[idx + 1..])) } -pub fn analysis_bench(verbosity: Verbosity, path: &Path, what: BenchWhat) -> Result<()> { +pub fn analysis_bench( + verbosity: Verbosity, + path: &Path, + what: BenchWhat, + load_output_dirs: bool, +) -> Result<()> { ra_prof::init(); let start = Instant::now(); eprint!("loading: "); - let (mut host, roots) = load_cargo(path)?; + let (mut host, roots) = load_cargo(path, load_output_dirs)?; let db = host.raw_database(); eprintln!("{:?}\n", start.elapsed()); diff --git a/crates/rust-analyzer/src/cli/analysis_stats.rs b/crates/rust-analyzer/src/cli/analysis_stats.rs index 643c54a9d..27459be8c 100644 --- a/crates/rust-analyzer/src/cli/analysis_stats.rs +++ b/crates/rust-analyzer/src/cli/analysis_stats.rs @@ -23,9 +23,10 @@ pub fn analysis_stats( only: Option<&str>, with_deps: bool, randomize: bool, + load_output_dirs: bool, ) -> Result<()> { let db_load_time = Instant::now(); - let (mut host, roots) = load_cargo(path)?; + let (mut host, roots) = load_cargo(path, load_output_dirs)?; let db = host.raw_database(); println!("Database loaded, {} roots, {:?}", roots.len(), db_load_time.elapsed()); let analysis_time = Instant::now(); diff --git a/crates/rust-analyzer/src/cli/load_cargo.rs b/crates/rust-analyzer/src/cli/load_cargo.rs index af61d1e0a..54e2fa1a7 100644 --- a/crates/rust-analyzer/src/cli/load_cargo.rs +++ b/crates/rust-analyzer/src/cli/load_cargo.rs @@ -1,13 +1,13 @@ //! Loads a Cargo project into a static instance of analysis, without support //! for incorporating changes. -use std::path::Path; +use std::path::{Path, PathBuf}; use anyhow::Result; use crossbeam_channel::{unbounded, Receiver}; -use ra_db::{CrateGraph, FileId, SourceRootId}; +use ra_db::{ExternSourceId, FileId, SourceRootId}; use ra_ide::{AnalysisChange, AnalysisHost}; -use ra_project_model::{get_rustc_cfg_options, PackageRoot, ProjectWorkspace}; +use ra_project_model::{get_rustc_cfg_options, CargoFeatures, PackageRoot, ProjectWorkspace}; use ra_vfs::{RootEntry, Vfs, VfsChange, VfsTask, Watch}; use rustc_hash::{FxHashMap, FxHashSet}; @@ -22,10 +22,21 @@ fn vfs_root_to_id(r: ra_vfs::VfsRoot) -> SourceRootId { pub(crate) fn load_cargo( root: &Path, + load_out_dirs_from_check: bool, ) -> 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 ws = ProjectWorkspace::discover( + root.as_ref(), + &CargoFeatures { load_out_dirs_from_check, ..Default::default() }, + )?; + + let mut extern_dirs = FxHashSet::default(); + extern_dirs.extend(ws.out_dirs()); + + let mut project_roots = ws.to_roots(); + project_roots + .extend(extern_dirs.iter().map(|path| PackageRoot::new(path.to_path_buf(), false))); + let (sender, receiver) = unbounded(); let sender = Box::new(move |t| sender.send(t).unwrap()); let (mut vfs, roots) = Vfs::new( @@ -44,25 +55,6 @@ pub(crate) fn load_cargo( 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 - }; - - // FIXME: outdirs? - let extern_source_roots = FxHashMap::default(); - - let crate_graph = - ws.to_crate_graph(&default_cfg_options, &extern_source_roots, &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| { @@ -75,23 +67,24 @@ pub(crate) fn load_cargo( (source_root_id, project_root) }) .collect::>(); - let host = load(&source_roots, crate_graph, &mut vfs, receiver); + let host = load(&source_roots, ws, &mut vfs, receiver, extern_dirs); Ok((host, source_roots)) } pub(crate) fn load( source_roots: &FxHashMap, - crate_graph: CrateGraph, + ws: ProjectWorkspace, vfs: &mut Vfs, receiver: Receiver, + extern_dirs: FxHashSet, ) -> AnalysisHost { let lru_cap = std::env::var("RA_LRU_CAP").ok().and_then(|it| it.parse::().ok()); let mut host = AnalysisHost::new(lru_cap); let mut analysis_change = AnalysisChange::new(); - analysis_change.set_crate_graph(crate_graph); // wait until Vfs has loaded all roots let mut roots_loaded = FxHashSet::default(); + let mut extern_source_roots = FxHashMap::default(); for task in receiver { vfs.handle_task(task); let mut done = false; @@ -111,6 +104,11 @@ pub(crate) fn load( source_roots[&source_root_id].path().display().to_string(), ); + let vfs_root_path = vfs.root2path(root); + if extern_dirs.contains(&vfs_root_path) { + extern_source_roots.insert(vfs_root_path, ExternSourceId(root.0)); + } + let mut file_map = FxHashMap::default(); for (vfs_file, path, text) in files { let file_id = vfs_file_to_id(vfs_file); @@ -137,6 +135,23 @@ pub(crate) fn load( } } + // 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 = + ws.to_crate_graph(&default_cfg_options, &extern_source_roots, &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); + analysis_change.set_crate_graph(crate_graph); + host.apply_change(analysis_change); host } @@ -150,7 +165,7 @@ mod tests { #[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 (host, _roots) = load_cargo(path, false).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); -- cgit v1.2.3