aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/rust-analyzer/src/bin/args.rs14
-rw-r--r--crates/rust-analyzer/src/bin/main.rs32
-rw-r--r--crates/rust-analyzer/src/cli/analysis_bench.rs9
-rw-r--r--crates/rust-analyzer/src/cli/analysis_stats.rs3
-rw-r--r--crates/rust-analyzer/src/cli/load_cargo.rs71
5 files changed, 81 insertions, 48 deletions
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 {
28 only: Option<String>, 28 only: Option<String>,
29 with_deps: bool, 29 with_deps: bool,
30 path: PathBuf, 30 path: PathBuf,
31 load_output_dirs: bool,
31 }, 32 },
32 Bench { 33 Bench {
33 path: PathBuf, 34 path: PathBuf,
34 what: BenchWhat, 35 what: BenchWhat,
36 load_output_dirs: bool,
35 }, 37 },
36 RunServer, 38 RunServer,
37 Version, 39 Version,
@@ -136,8 +138,9 @@ USAGE:
136 rust-analyzer analysis-stats [FLAGS] [OPTIONS] [PATH] 138 rust-analyzer analysis-stats [FLAGS] [OPTIONS] [PATH]
137 139
138FLAGS: 140FLAGS:
139 -h, --help Prints help information 141 -h, --help Prints help information
140 --memory-usage 142 --memory-usage
143 --load-output-dirs Load OUT_DIR values by running `cargo check` before analysis
141 -v, --verbose 144 -v, --verbose
142 -q, --quiet 145 -q, --quiet
143 146
@@ -154,6 +157,7 @@ ARGS:
154 let memory_usage = matches.contains("--memory-usage"); 157 let memory_usage = matches.contains("--memory-usage");
155 let only: Option<String> = matches.opt_value_from_str(["-o", "--only"])?; 158 let only: Option<String> = matches.opt_value_from_str(["-o", "--only"])?;
156 let with_deps: bool = matches.contains("--with-deps"); 159 let with_deps: bool = matches.contains("--with-deps");
160 let load_output_dirs = matches.contains("--load-output-dirs");
157 let path = { 161 let path = {
158 let mut trailing = matches.free()?; 162 let mut trailing = matches.free()?;
159 if trailing.len() != 1 { 163 if trailing.len() != 1 {
@@ -162,7 +166,7 @@ ARGS:
162 trailing.pop().unwrap().into() 166 trailing.pop().unwrap().into()
163 }; 167 };
164 168
165 Command::Stats { randomize, memory_usage, only, with_deps, path } 169 Command::Stats { randomize, memory_usage, only, with_deps, path, load_output_dirs }
166 } 170 }
167 "analysis-bench" => { 171 "analysis-bench" => {
168 if matches.contains(["-h", "--help"]) { 172 if matches.contains(["-h", "--help"]) {
@@ -174,7 +178,8 @@ USAGE:
174 rust-analyzer analysis-bench [FLAGS] [OPTIONS] 178 rust-analyzer analysis-bench [FLAGS] [OPTIONS]
175 179
176FLAGS: 180FLAGS:
177 -h, --help Prints help information 181 -h, --help Prints help information
182 --load-output-dirs Load OUT_DIR values by running `cargo check` before analysis
178 -v, --verbose 183 -v, --verbose
179 184
180OPTIONS: 185OPTIONS:
@@ -201,7 +206,8 @@ ARGS:
201 "exactly one of `--highlight`, `--complete` or `--goto-def` must be set" 206 "exactly one of `--highlight`, `--complete` or `--goto-def` must be set"
202 ), 207 ),
203 }; 208 };
204 Command::Bench { path, what } 209 let load_output_dirs = matches.contains("--load-output-dirs");
210 Command::Bench { path, what, load_output_dirs }
205 } 211 }
206 _ => { 212 _ => {
207 eprintln!( 213 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<()> {
19 args::Command::Parse { no_dump } => cli::parse(no_dump)?, 19 args::Command::Parse { no_dump } => cli::parse(no_dump)?,
20 args::Command::Symbols => cli::symbols()?, 20 args::Command::Symbols => cli::symbols()?,
21 args::Command::Highlight { rainbow } => cli::highlight(rainbow)?, 21 args::Command::Highlight { rainbow } => cli::highlight(rainbow)?,
22 args::Command::Stats { randomize, memory_usage, only, with_deps, path } => { 22 args::Command::Stats {
23 cli::analysis_stats( 23 randomize,
24 args.verbosity, 24 memory_usage,
25 memory_usage, 25 only,
26 path.as_ref(), 26 with_deps,
27 only.as_ref().map(String::as_ref), 27 path,
28 with_deps, 28 load_output_dirs,
29 randomize, 29 } => cli::analysis_stats(
30 )? 30 args.verbosity,
31 } 31 memory_usage,
32 32 path.as_ref(),
33 args::Command::Bench { path, what } => { 33 only.as_ref().map(String::as_ref),
34 cli::analysis_bench(args.verbosity, path.as_ref(), what)? 34 with_deps,
35 randomize,
36 load_output_dirs,
37 )?,
38
39 args::Command::Bench { path, what, load_output_dirs } => {
40 cli::analysis_bench(args.verbosity, path.as_ref(), what, load_output_dirs)?
35 } 41 }
36 42
37 args::Command::RunServer => run_server()?, 43 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)> {
42 Ok((&s[..idx], &s[idx + 1..])) 42 Ok((&s[..idx], &s[idx + 1..]))
43} 43}
44 44
45pub fn analysis_bench(verbosity: Verbosity, path: &Path, what: BenchWhat) -> Result<()> { 45pub fn analysis_bench(
46 verbosity: Verbosity,
47 path: &Path,
48 what: BenchWhat,
49 load_output_dirs: bool,
50) -> Result<()> {
46 ra_prof::init(); 51 ra_prof::init();
47 52
48 let start = Instant::now(); 53 let start = Instant::now();
49 eprint!("loading: "); 54 eprint!("loading: ");
50 let (mut host, roots) = load_cargo(path)?; 55 let (mut host, roots) = load_cargo(path, load_output_dirs)?;
51 let db = host.raw_database(); 56 let db = host.raw_database();
52 eprintln!("{:?}\n", start.elapsed()); 57 eprintln!("{:?}\n", start.elapsed());
53 58
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(
23 only: Option<&str>, 23 only: Option<&str>,
24 with_deps: bool, 24 with_deps: bool,
25 randomize: bool, 25 randomize: bool,
26 load_output_dirs: bool,
26) -> Result<()> { 27) -> Result<()> {
27 let db_load_time = Instant::now(); 28 let db_load_time = Instant::now();
28 let (mut host, roots) = load_cargo(path)?; 29 let (mut host, roots) = load_cargo(path, load_output_dirs)?;
29 let db = host.raw_database(); 30 let db = host.raw_database();
30 println!("Database loaded, {} roots, {:?}", roots.len(), db_load_time.elapsed()); 31 println!("Database loaded, {} roots, {:?}", roots.len(), db_load_time.elapsed());
31 let analysis_time = Instant::now(); 32 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 @@
1//! Loads a Cargo project into a static instance of analysis, without support 1//! Loads a Cargo project into a static instance of analysis, without support
2//! for incorporating changes. 2//! for incorporating changes.
3 3
4use std::path::Path; 4use std::path::{Path, PathBuf};
5 5
6use anyhow::Result; 6use anyhow::Result;
7use crossbeam_channel::{unbounded, Receiver}; 7use crossbeam_channel::{unbounded, Receiver};
8use ra_db::{CrateGraph, FileId, SourceRootId}; 8use ra_db::{ExternSourceId, FileId, SourceRootId};
9use ra_ide::{AnalysisChange, AnalysisHost}; 9use ra_ide::{AnalysisChange, AnalysisHost};
10use ra_project_model::{get_rustc_cfg_options, PackageRoot, ProjectWorkspace}; 10use ra_project_model::{get_rustc_cfg_options, CargoFeatures, PackageRoot, ProjectWorkspace};
11use ra_vfs::{RootEntry, Vfs, VfsChange, VfsTask, Watch}; 11use ra_vfs::{RootEntry, Vfs, VfsChange, VfsTask, Watch};
12use rustc_hash::{FxHashMap, FxHashSet}; 12use rustc_hash::{FxHashMap, FxHashSet};
13 13
@@ -22,10 +22,21 @@ fn vfs_root_to_id(r: ra_vfs::VfsRoot) -> SourceRootId {
22 22
23pub(crate) fn load_cargo( 23pub(crate) fn load_cargo(
24 root: &Path, 24 root: &Path,
25 load_out_dirs_from_check: bool,
25) -> Result<(AnalysisHost, FxHashMap<SourceRootId, PackageRoot>)> { 26) -> Result<(AnalysisHost, FxHashMap<SourceRootId, PackageRoot>)> {
26 let root = std::env::current_dir()?.join(root); 27 let root = std::env::current_dir()?.join(root);
27 let ws = ProjectWorkspace::discover(root.as_ref(), &Default::default())?; 28 let ws = ProjectWorkspace::discover(
28 let project_roots = ws.to_roots(); 29 root.as_ref(),
30 &CargoFeatures { load_out_dirs_from_check, ..Default::default() },
31 )?;
32
33 let mut extern_dirs = FxHashSet::default();
34 extern_dirs.extend(ws.out_dirs());
35
36 let mut project_roots = ws.to_roots();
37 project_roots
38 .extend(extern_dirs.iter().map(|path| PackageRoot::new(path.to_path_buf(), false)));
39
29 let (sender, receiver) = unbounded(); 40 let (sender, receiver) = unbounded();
30 let sender = Box::new(move |t| sender.send(t).unwrap()); 41 let sender = Box::new(move |t| sender.send(t).unwrap());
31 let (mut vfs, roots) = Vfs::new( 42 let (mut vfs, roots) = Vfs::new(
@@ -44,25 +55,6 @@ pub(crate) fn load_cargo(
44 Watch(false), 55 Watch(false),
45 ); 56 );
46 57
47 // FIXME: cfg options?
48 let default_cfg_options = {
49 let mut opts = get_rustc_cfg_options();
50 opts.insert_atom("test".into());
51 opts.insert_atom("debug_assertion".into());
52 opts
53 };
54
55 // FIXME: outdirs?
56 let extern_source_roots = FxHashMap::default();
57
58 let crate_graph =
59 ws.to_crate_graph(&default_cfg_options, &extern_source_roots, &mut |path: &Path| {
60 let vfs_file = vfs.load(path);
61 log::debug!("vfs file {:?} -> {:?}", path, vfs_file);
62 vfs_file.map(vfs_file_to_id)
63 });
64 log::debug!("crate graph: {:?}", crate_graph);
65
66 let source_roots = roots 58 let source_roots = roots
67 .iter() 59 .iter()
68 .map(|&vfs_root| { 60 .map(|&vfs_root| {
@@ -75,23 +67,24 @@ pub(crate) fn load_cargo(
75 (source_root_id, project_root) 67 (source_root_id, project_root)
76 }) 68 })
77 .collect::<FxHashMap<_, _>>(); 69 .collect::<FxHashMap<_, _>>();
78 let host = load(&source_roots, crate_graph, &mut vfs, receiver); 70 let host = load(&source_roots, ws, &mut vfs, receiver, extern_dirs);
79 Ok((host, source_roots)) 71 Ok((host, source_roots))
80} 72}
81 73
82pub(crate) fn load( 74pub(crate) fn load(
83 source_roots: &FxHashMap<SourceRootId, PackageRoot>, 75 source_roots: &FxHashMap<SourceRootId, PackageRoot>,
84 crate_graph: CrateGraph, 76 ws: ProjectWorkspace,
85 vfs: &mut Vfs, 77 vfs: &mut Vfs,
86 receiver: Receiver<VfsTask>, 78 receiver: Receiver<VfsTask>,
79 extern_dirs: FxHashSet<PathBuf>,
87) -> AnalysisHost { 80) -> AnalysisHost {
88 let lru_cap = std::env::var("RA_LRU_CAP").ok().and_then(|it| it.parse::<usize>().ok()); 81 let lru_cap = std::env::var("RA_LRU_CAP").ok().and_then(|it| it.parse::<usize>().ok());
89 let mut host = AnalysisHost::new(lru_cap); 82 let mut host = AnalysisHost::new(lru_cap);
90 let mut analysis_change = AnalysisChange::new(); 83 let mut analysis_change = AnalysisChange::new();
91 analysis_change.set_crate_graph(crate_graph);
92 84
93 // wait until Vfs has loaded all roots 85 // wait until Vfs has loaded all roots
94 let mut roots_loaded = FxHashSet::default(); 86 let mut roots_loaded = FxHashSet::default();
87 let mut extern_source_roots = FxHashMap::default();
95 for task in receiver { 88 for task in receiver {
96 vfs.handle_task(task); 89 vfs.handle_task(task);
97 let mut done = false; 90 let mut done = false;
@@ -111,6 +104,11 @@ pub(crate) fn load(
111 source_roots[&source_root_id].path().display().to_string(), 104 source_roots[&source_root_id].path().display().to_string(),
112 ); 105 );
113 106
107 let vfs_root_path = vfs.root2path(root);
108 if extern_dirs.contains(&vfs_root_path) {
109 extern_source_roots.insert(vfs_root_path, ExternSourceId(root.0));
110 }
111
114 let mut file_map = FxHashMap::default(); 112 let mut file_map = FxHashMap::default();
115 for (vfs_file, path, text) in files { 113 for (vfs_file, path, text) in files {
116 let file_id = vfs_file_to_id(vfs_file); 114 let file_id = vfs_file_to_id(vfs_file);
@@ -137,6 +135,23 @@ pub(crate) fn load(
137 } 135 }
138 } 136 }
139 137
138 // FIXME: cfg options?
139 let default_cfg_options = {
140 let mut opts = get_rustc_cfg_options();
141 opts.insert_atom("test".into());
142 opts.insert_atom("debug_assertion".into());
143 opts
144 };
145
146 let crate_graph =
147 ws.to_crate_graph(&default_cfg_options, &extern_source_roots, &mut |path: &Path| {
148 let vfs_file = vfs.load(path);
149 log::debug!("vfs file {:?} -> {:?}", path, vfs_file);
150 vfs_file.map(vfs_file_to_id)
151 });
152 log::debug!("crate graph: {:?}", crate_graph);
153 analysis_change.set_crate_graph(crate_graph);
154
140 host.apply_change(analysis_change); 155 host.apply_change(analysis_change);
141 host 156 host
142} 157}
@@ -150,7 +165,7 @@ mod tests {
150 #[test] 165 #[test]
151 fn test_loading_rust_analyzer() { 166 fn test_loading_rust_analyzer() {
152 let path = Path::new(env!("CARGO_MANIFEST_DIR")).parent().unwrap().parent().unwrap(); 167 let path = Path::new(env!("CARGO_MANIFEST_DIR")).parent().unwrap().parent().unwrap();
153 let (host, _roots) = load_cargo(path).unwrap(); 168 let (host, _roots) = load_cargo(path, false).unwrap();
154 let n_crates = Crate::all(host.raw_database()).len(); 169 let n_crates = Crate::all(host.raw_database()).len();
155 // RA has quite a few crates, but the exact count doesn't matter 170 // RA has quite a few crates, but the exact count doesn't matter
156 assert!(n_crates > 20); 171 assert!(n_crates > 20);