diff options
-rw-r--r-- | crates/rust-analyzer/src/bin/args.rs | 14 | ||||
-rw-r--r-- | crates/rust-analyzer/src/bin/main.rs | 32 | ||||
-rw-r--r-- | crates/rust-analyzer/src/cli/analysis_bench.rs | 9 | ||||
-rw-r--r-- | crates/rust-analyzer/src/cli/analysis_stats.rs | 3 | ||||
-rw-r--r-- | crates/rust-analyzer/src/cli/load_cargo.rs | 71 |
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 | ||
138 | FLAGS: | 140 | FLAGS: |
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 | ||
176 | FLAGS: | 180 | FLAGS: |
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 | ||
180 | OPTIONS: | 185 | OPTIONS: |
@@ -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 | ||
45 | pub fn analysis_bench(verbosity: Verbosity, path: &Path, what: BenchWhat) -> Result<()> { | 45 | pub 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 | ||
4 | use std::path::Path; | 4 | use std::path::{Path, PathBuf}; |
5 | 5 | ||
6 | use anyhow::Result; | 6 | use anyhow::Result; |
7 | use crossbeam_channel::{unbounded, Receiver}; | 7 | use crossbeam_channel::{unbounded, Receiver}; |
8 | use ra_db::{CrateGraph, FileId, SourceRootId}; | 8 | use ra_db::{ExternSourceId, FileId, SourceRootId}; |
9 | use ra_ide::{AnalysisChange, AnalysisHost}; | 9 | use ra_ide::{AnalysisChange, AnalysisHost}; |
10 | use ra_project_model::{get_rustc_cfg_options, PackageRoot, ProjectWorkspace}; | 10 | use ra_project_model::{get_rustc_cfg_options, CargoFeatures, PackageRoot, ProjectWorkspace}; |
11 | use ra_vfs::{RootEntry, Vfs, VfsChange, VfsTask, Watch}; | 11 | use ra_vfs::{RootEntry, Vfs, VfsChange, VfsTask, Watch}; |
12 | use rustc_hash::{FxHashMap, FxHashSet}; | 12 | use rustc_hash::{FxHashMap, FxHashSet}; |
13 | 13 | ||
@@ -22,10 +22,21 @@ fn vfs_root_to_id(r: ra_vfs::VfsRoot) -> SourceRootId { | |||
22 | 22 | ||
23 | pub(crate) fn load_cargo( | 23 | pub(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 | ||
82 | pub(crate) fn load( | 74 | pub(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); |