aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_lsp_server/src/server_world.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_lsp_server/src/server_world.rs')
-rw-r--r--crates/ra_lsp_server/src/server_world.rs75
1 files changed, 61 insertions, 14 deletions
diff --git a/crates/ra_lsp_server/src/server_world.rs b/crates/ra_lsp_server/src/server_world.rs
index 76c76766d..4f3c231d3 100644
--- a/crates/ra_lsp_server/src/server_world.rs
+++ b/crates/ra_lsp_server/src/server_world.rs
@@ -15,7 +15,7 @@ use parking_lot::RwLock;
15use failure::format_err; 15use failure::format_err;
16 16
17use crate::{ 17use crate::{
18 project_model::{CargoWorkspace, TargetKind}, 18 project_model::{ProjectWorkspace, TargetKind},
19 Result, 19 Result,
20}; 20};
21 21
@@ -23,28 +23,33 @@ use crate::{
23pub struct ServerWorldState { 23pub struct ServerWorldState {
24 pub roots_to_scan: usize, 24 pub roots_to_scan: usize,
25 pub root: PathBuf, 25 pub root: PathBuf,
26 pub workspaces: Arc<Vec<CargoWorkspace>>, 26 pub workspaces: Arc<Vec<ProjectWorkspace>>,
27 pub analysis_host: AnalysisHost, 27 pub analysis_host: AnalysisHost,
28 pub vfs: Arc<RwLock<Vfs>>, 28 pub vfs: Arc<RwLock<Vfs>>,
29} 29}
30 30
31pub struct ServerWorld { 31pub struct ServerWorld {
32 pub workspaces: Arc<Vec<CargoWorkspace>>, 32 pub workspaces: Arc<Vec<ProjectWorkspace>>,
33 pub analysis: Analysis, 33 pub analysis: Analysis,
34 pub vfs: Arc<RwLock<Vfs>>, 34 pub vfs: Arc<RwLock<Vfs>>,
35} 35}
36 36
37impl ServerWorldState { 37impl ServerWorldState {
38 pub fn new(root: PathBuf, workspaces: Vec<CargoWorkspace>) -> ServerWorldState { 38 pub fn new(root: PathBuf, workspaces: Vec<ProjectWorkspace>) -> ServerWorldState {
39 let mut change = AnalysisChange::new(); 39 let mut change = AnalysisChange::new();
40 40
41 let mut roots = Vec::new(); 41 let mut roots = Vec::new();
42 roots.push(root.clone()); 42 roots.push(root.clone());
43 for ws in workspaces.iter() { 43 for ws in workspaces.iter() {
44 for pkg in ws.packages() { 44 for pkg in ws.cargo.packages() {
45 roots.push(pkg.root(&ws).to_path_buf()); 45 roots.push(pkg.root(&ws.cargo).to_path_buf());
46 }
47 for krate in ws.sysroot.crates() {
48 roots.push(krate.root_dir(&ws.sysroot).to_path_buf())
46 } 49 }
47 } 50 }
51 roots.sort();
52 roots.dedup();
48 let roots_to_scan = roots.len(); 53 let roots_to_scan = roots.len();
49 let (mut vfs, roots) = Vfs::new(roots); 54 let (mut vfs, roots) = Vfs::new(roots);
50 for r in roots { 55 for r in roots {
@@ -53,16 +58,43 @@ impl ServerWorldState {
53 } 58 }
54 59
55 let mut crate_graph = CrateGraph::default(); 60 let mut crate_graph = CrateGraph::default();
56 let mut pkg_to_lib_crate = FxHashMap::default();
57 let mut pkg_crates = FxHashMap::default();
58 for ws in workspaces.iter() { 61 for ws in workspaces.iter() {
59 for pkg in ws.packages() { 62 // First, load std
60 for tgt in pkg.targets(ws) { 63 let mut sysroot_crates = FxHashMap::default();
61 let root = tgt.root(ws); 64 for krate in ws.sysroot.crates() {
65 if let Some(file_id) = vfs.load(krate.root(&ws.sysroot)) {
66 let file_id = FileId(file_id.0.into());
67 sysroot_crates.insert(krate, crate_graph.add_crate_root(file_id));
68 }
69 }
70 for from in ws.sysroot.crates() {
71 for to in from.deps(&ws.sysroot) {
72 let name = to.name(&ws.sysroot);
73 if let (Some(&from), Some(&to)) =
74 (sysroot_crates.get(&from), sysroot_crates.get(&to))
75 {
76 crate_graph.add_dep(from, name.clone(), to);
77 }
78 }
79 }
80
81 let libstd = ws
82 .sysroot
83 .std()
84 .and_then(|it| sysroot_crates.get(&it).map(|&it| it));
85
86 let mut pkg_to_lib_crate = FxHashMap::default();
87 let mut pkg_crates = FxHashMap::default();
88 // Next, create crates for each package, target pair
89 for pkg in ws.cargo.packages() {
90 let mut lib_tgt = None;
91 for tgt in pkg.targets(&ws.cargo) {
92 let root = tgt.root(&ws.cargo);
62 if let Some(file_id) = vfs.load(root) { 93 if let Some(file_id) = vfs.load(root) {
63 let file_id = FileId(file_id.0.into()); 94 let file_id = FileId(file_id.0.into());
64 let crate_id = crate_graph.add_crate_root(file_id); 95 let crate_id = crate_graph.add_crate_root(file_id);
65 if tgt.kind(ws) == TargetKind::Lib { 96 if tgt.kind(&ws.cargo) == TargetKind::Lib {
97 lib_tgt = Some(crate_id);
66 pkg_to_lib_crate.insert(pkg, crate_id); 98 pkg_to_lib_crate.insert(pkg, crate_id);
67 } 99 }
68 pkg_crates 100 pkg_crates
@@ -71,9 +103,24 @@ impl ServerWorldState {
71 .push(crate_id); 103 .push(crate_id);
72 } 104 }
73 } 105 }
106
107 // Set deps to the std and to the lib target of the current package
108 for &from in pkg_crates.get(&pkg).into_iter().flatten() {
109 if let Some(to) = lib_tgt {
110 if to != from {
111 crate_graph.add_dep(from, pkg.name(&ws.cargo).into(), to);
112 }
113 }
114 if let Some(std) = libstd {
115 crate_graph.add_dep(from, "std".into(), std);
116 }
117 }
74 } 118 }
75 for pkg in ws.packages() { 119
76 for dep in pkg.dependencies(ws) { 120 // Now add a dep ednge from all targets of upstream to the lib
121 // target of downstream.
122 for pkg in ws.cargo.packages() {
123 for dep in pkg.dependencies(&ws.cargo) {
77 if let Some(&to) = pkg_to_lib_crate.get(&dep.pkg) { 124 if let Some(&to) = pkg_to_lib_crate.get(&dep.pkg) {
78 for &from in pkg_crates.get(&pkg).into_iter().flatten() { 125 for &from in pkg_crates.get(&pkg).into_iter().flatten() {
79 crate_graph.add_dep(from, dep.name.clone(), to); 126 crate_graph.add_dep(from, dep.name.clone(), to);