aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_cli
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2020-02-17 16:31:09 +0000
committerAleksey Kladov <[email protected]>2020-02-17 16:32:17 +0000
commitd7be1da8df45027ce18b8af9da68ed98b9a454cc (patch)
treebbbf059cd41cb48859710155c30d5dac4a657440 /crates/ra_cli
parent559c5f37f6d0435eb3a0bbb1cf10051783df4dfc (diff)
Inline ra_batch
Diffstat (limited to 'crates/ra_cli')
-rw-r--r--crates/ra_cli/Cargo.toml15
-rw-r--r--crates/ra_cli/src/analysis_bench.rs4
-rw-r--r--crates/ra_cli/src/analysis_stats.rs4
-rw-r--r--crates/ra_cli/src/load_cargo.rs153
-rw-r--r--crates/ra_cli/src/main.rs3
5 files changed, 168 insertions, 11 deletions
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"]
6publish = false 6publish = false
7 7
8[dependencies] 8[dependencies]
9crossbeam-channel = "0.4.0"
10env_logger = { version = "0.7.1", default-features = false }
9itertools = "0.8.0" 11itertools = "0.8.0"
12log = "0.4.5"
10pico-args = "0.3.0" 13pico-args = "0.3.0"
11env_logger = { version = "0.7.1", default-features = false }
12rand = { version = "0.7.0", features = ["small_rng"] } 14rand = { version = "0.7.0", features = ["small_rng"] }
15rustc-hash = "1.0"
13 16
14ra_syntax = { path = "../ra_syntax" }
15ra_ide = { path = "../ra_ide" }
16ra_batch = { path = "../ra_batch" }
17hir = { path = "../ra_hir", package = "ra_hir" } 17hir = { path = "../ra_hir", package = "ra_hir" }
18hir_ty = { path = "../ra_hir_ty", package = "ra_hir_ty" }
19hir_def = { path = "../ra_hir_def", package = "ra_hir_def" } 18hir_def = { path = "../ra_hir_def", package = "ra_hir_def" }
19hir_ty = { path = "../ra_hir_ty", package = "ra_hir_ty" }
20ra_db = { path = "../ra_db" } 20ra_db = { path = "../ra_db" }
21ra_ide = { path = "../ra_ide" }
22ra_project_model = { path = "../ra_project_model" }
23ra_syntax = { path = "../ra_syntax" }
24ra_vfs = "0.5.0"
25ra_vfs_glob = { path = "../ra_vfs_glob" }
21 26
22[dependencies.ra_prof] 27[dependencies.ra_prof]
23path = "../ra_prof" 28path = "../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::{
13}; 13};
14use ra_ide::{Analysis, AnalysisChange, AnalysisHost, FilePosition, LineCol}; 14use ra_ide::{Analysis, AnalysisChange, AnalysisHost, FilePosition, LineCol};
15 15
16use crate::Result; 16use crate::{load_cargo::load_cargo, Result};
17 17
18pub(crate) struct Position { 18pub(crate) struct Position {
19 path: PathBuf, 19 path: PathBuf,
@@ -46,7 +46,7 @@ pub(crate) fn run(verbose: bool, path: &Path, op: Op) -> Result<()> {
46 46
47 let start = Instant::now(); 47 let start = Instant::now();
48 eprint!("loading: "); 48 eprint!("loading: ");
49 let (mut host, roots) = ra_batch::load_cargo(path)?; 49 let (mut host, roots) = load_cargo(path)?;
50 let db = host.raw_database(); 50 let db = host.raw_database();
51 eprintln!("{:?}\n", start.elapsed()); 51 eprintln!("{:?}\n", start.elapsed());
52 52
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;
13use ra_syntax::AstNode; 13use ra_syntax::AstNode;
14use rand::{seq::SliceRandom, thread_rng}; 14use rand::{seq::SliceRandom, thread_rng};
15 15
16use crate::{progress_report::ProgressReport, Result, Verbosity}; 16use crate::{load_cargo::load_cargo, progress_report::ProgressReport, Result, Verbosity};
17 17
18pub fn run( 18pub fn run(
19 verbosity: Verbosity, 19 verbosity: Verbosity,
@@ -24,7 +24,7 @@ pub fn run(
24 randomize: bool, 24 randomize: bool,
25) -> Result<()> { 25) -> Result<()> {
26 let db_load_time = Instant::now(); 26 let db_load_time = Instant::now();
27 let (mut host, roots) = ra_batch::load_cargo(path)?; 27 let (mut host, roots) = load_cargo(path)?;
28 let db = host.raw_database(); 28 let db = host.raw_database();
29 println!("Database loaded, {} roots, {:?}", roots.len(), db_load_time.elapsed()); 29 println!("Database loaded, {} roots, {:?}", roots.len(), db_load_time.elapsed());
30 let analysis_time = Instant::now(); 30 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 @@
1//! FIXME: write short doc here
2
3use std::{collections::HashSet, error::Error, path::Path};
4
5use rustc_hash::FxHashMap;
6
7use crossbeam_channel::{unbounded, Receiver};
8use ra_db::{CrateGraph, FileId, SourceRootId};
9use ra_ide::{AnalysisChange, AnalysisHost, FeatureFlags};
10use ra_project_model::{get_rustc_cfg_options, PackageRoot, ProjectWorkspace};
11use ra_vfs::{RootEntry, Vfs, VfsChange, VfsTask, Watch};
12use ra_vfs_glob::RustPackageFilterBuilder;
13
14type Result<T> = std::result::Result<T, Box<dyn Error + Send + Sync>>;
15
16fn vfs_file_to_id(f: ra_vfs::VfsFile) -> FileId {
17 FileId(f.0)
18}
19fn vfs_root_to_id(r: ra_vfs::VfsRoot) -> SourceRootId {
20 SourceRootId(r.0)
21}
22
23pub fn load_cargo(root: &Path) -> Result<(AnalysisHost, FxHashMap<SourceRootId, PackageRoot>)> {
24 let root = std::env::current_dir()?.join(root);
25 let ws = ProjectWorkspace::discover(root.as_ref(), &Default::default())?;
26 let project_roots = ws.to_roots();
27 let (sender, receiver) = unbounded();
28 let sender = Box::new(move |t| sender.send(t).unwrap());
29 let (mut vfs, roots) = Vfs::new(
30 project_roots
31 .iter()
32 .map(|pkg_root| {
33 RootEntry::new(
34 pkg_root.path().clone(),
35 RustPackageFilterBuilder::default()
36 .set_member(pkg_root.is_member())
37 .into_vfs_filter(),
38 )
39 })
40 .collect(),
41 sender,
42 Watch(false),
43 );
44
45 // FIXME: cfg options?
46 let default_cfg_options = {
47 let mut opts = get_rustc_cfg_options();
48 opts.insert_atom("test".into());
49 opts.insert_atom("debug_assertion".into());
50 opts
51 };
52
53 let (crate_graph, _crate_names) =
54 ws.to_crate_graph(&default_cfg_options, &mut |path: &Path| {
55 let vfs_file = vfs.load(path);
56 log::debug!("vfs file {:?} -> {:?}", path, vfs_file);
57 vfs_file.map(vfs_file_to_id)
58 });
59 log::debug!("crate graph: {:?}", crate_graph);
60
61 let source_roots = roots
62 .iter()
63 .map(|&vfs_root| {
64 let source_root_id = vfs_root_to_id(vfs_root);
65 let project_root = project_roots
66 .iter()
67 .find(|it| it.path() == &vfs.root2path(vfs_root))
68 .unwrap()
69 .clone();
70 (source_root_id, project_root)
71 })
72 .collect::<FxHashMap<_, _>>();
73 let host = load(&source_roots, crate_graph, &mut vfs, receiver);
74 Ok((host, source_roots))
75}
76
77pub fn load(
78 source_roots: &FxHashMap<SourceRootId, PackageRoot>,
79 crate_graph: CrateGraph,
80 vfs: &mut Vfs,
81 receiver: Receiver<VfsTask>,
82) -> AnalysisHost {
83 let lru_cap = std::env::var("RA_LRU_CAP").ok().and_then(|it| it.parse::<usize>().ok());
84 let mut host = AnalysisHost::new(lru_cap, FeatureFlags::default());
85 let mut analysis_change = AnalysisChange::new();
86 analysis_change.set_crate_graph(crate_graph);
87
88 // wait until Vfs has loaded all roots
89 let mut roots_loaded = HashSet::new();
90 for task in receiver {
91 vfs.handle_task(task);
92 let mut done = false;
93 for change in vfs.commit_changes() {
94 match change {
95 VfsChange::AddRoot { root, files } => {
96 let source_root_id = vfs_root_to_id(root);
97 let is_local = source_roots[&source_root_id].is_member();
98 log::debug!(
99 "loaded source root {:?} with path {:?}",
100 source_root_id,
101 vfs.root2path(root)
102 );
103 analysis_change.add_root(source_root_id, is_local);
104 analysis_change.set_debug_root_path(
105 source_root_id,
106 source_roots[&source_root_id].path().display().to_string(),
107 );
108
109 let mut file_map = FxHashMap::default();
110 for (vfs_file, path, text) in files {
111 let file_id = vfs_file_to_id(vfs_file);
112 analysis_change.add_file(source_root_id, file_id, path.clone(), text);
113 file_map.insert(path, file_id);
114 }
115 roots_loaded.insert(source_root_id);
116 if roots_loaded.len() == vfs.n_roots() {
117 done = true;
118 }
119 }
120 VfsChange::AddFile { root, file, path, text } => {
121 let source_root_id = vfs_root_to_id(root);
122 let file_id = vfs_file_to_id(file);
123 analysis_change.add_file(source_root_id, file_id, path, text);
124 }
125 VfsChange::RemoveFile { .. } | VfsChange::ChangeFile { .. } => {
126 // We just need the first scan, so just ignore these
127 }
128 }
129 }
130 if done {
131 break;
132 }
133 }
134
135 host.apply_change(analysis_change);
136 host
137}
138
139#[cfg(test)]
140mod tests {
141 use super::*;
142
143 use hir::Crate;
144
145 #[test]
146 fn test_loading_rust_analyzer() {
147 let path = Path::new(env!("CARGO_MANIFEST_DIR")).parent().unwrap().parent().unwrap();
148 let (host, _roots) = load_cargo(path).unwrap();
149 let n_crates = Crate::all(host.raw_database()).len();
150 // RA has quite a few crates, but the exact count doesn't matter
151 assert!(n_crates > 20);
152 }
153}
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 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2 2
3mod load_cargo;
3mod analysis_stats; 4mod analysis_stats;
4mod analysis_bench; 5mod analysis_bench;
5mod progress_report; 6mod progress_report;
@@ -157,12 +158,10 @@ ARGS:
157 let path = { 158 let path = {
158 let mut trailing = matches.free()?; 159 let mut trailing = matches.free()?;
159 if trailing.len() != 1 { 160 if trailing.len() != 1 {
160 eprintln!("{}", help::ANALYSIS_STATS_HELP);
161 Err("Invalid flags")?; 161 Err("Invalid flags")?;
162 } 162 }
163 trailing.pop().unwrap() 163 trailing.pop().unwrap()
164 }; 164 };
165 matches.finish().or_else(handle_extra_flags)?;
166 165
167 analysis_stats::run( 166 analysis_stats::run(
168 verbosity, 167 verbosity,