aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_lsp_server
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_lsp_server')
-rw-r--r--crates/ra_lsp_server/src/server_world.rs85
1 files changed, 3 insertions, 82 deletions
diff --git a/crates/ra_lsp_server/src/server_world.rs b/crates/ra_lsp_server/src/server_world.rs
index 02f2a37a8..23270d0aa 100644
--- a/crates/ra_lsp_server/src/server_world.rs
+++ b/crates/ra_lsp_server/src/server_world.rs
@@ -9,13 +9,12 @@ use ra_ide_api::{
9 SourceRootId 9 SourceRootId
10}; 10};
11use ra_vfs::{Vfs, VfsChange, VfsFile, VfsRoot}; 11use ra_vfs::{Vfs, VfsChange, VfsFile, VfsRoot};
12use rustc_hash::FxHashMap;
13use relative_path::RelativePathBuf; 12use relative_path::RelativePathBuf;
14use parking_lot::RwLock; 13use parking_lot::RwLock;
15use failure::format_err; 14use failure::format_err;
16 15
17use crate::{ 16use crate::{
18 project_model::{ProjectWorkspace, TargetKind}, 17 project_model::ProjectWorkspace,
19 Result, 18 Result,
20}; 19};
21 20
@@ -57,88 +56,10 @@ impl ServerWorldState {
57 change.add_root(SourceRootId(r.0.into()), is_local); 56 change.add_root(SourceRootId(r.0.into()), is_local);
58 } 57 }
59 58
59 // Create crate graph from all the workspaces
60 let mut crate_graph = CrateGraph::default(); 60 let mut crate_graph = CrateGraph::default();
61 for ws in workspaces.iter() { 61 for ws in workspaces.iter() {
62 // First, load std 62 crate_graph.extend(ws.to_crate_graph(&mut vfs));
63 let mut sysroot_crates = FxHashMap::default();
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 if let Err(_) = crate_graph.add_dep(from, name.clone(), to) {
77 log::error!("cyclic dependency between sysroot crates")
78 }
79 }
80 }
81 }
82
83 let libstd = ws.sysroot.std().and_then(|it| sysroot_crates.get(&it).map(|&it| it));
84
85 let mut pkg_to_lib_crate = FxHashMap::default();
86 let mut pkg_crates = FxHashMap::default();
87 // Next, create crates for each package, target pair
88 for pkg in ws.cargo.packages() {
89 let mut lib_tgt = None;
90 for tgt in pkg.targets(&ws.cargo) {
91 let root = tgt.root(&ws.cargo);
92 if let Some(file_id) = vfs.load(root) {
93 let file_id = FileId(file_id.0.into());
94 let crate_id = crate_graph.add_crate_root(file_id);
95 if tgt.kind(&ws.cargo) == TargetKind::Lib {
96 lib_tgt = Some(crate_id);
97 pkg_to_lib_crate.insert(pkg, crate_id);
98 }
99 pkg_crates.entry(pkg).or_insert_with(Vec::new).push(crate_id);
100 }
101 }
102
103 // Set deps to the std and to the lib target of the current package
104 for &from in pkg_crates.get(&pkg).into_iter().flatten() {
105 if let Some(to) = lib_tgt {
106 if to != from {
107 if let Err(_) =
108 crate_graph.add_dep(from, pkg.name(&ws.cargo).into(), to)
109 {
110 log::error!(
111 "cyclic dependency between targets of {}",
112 pkg.name(&ws.cargo)
113 )
114 }
115 }
116 }
117 if let Some(std) = libstd {
118 if let Err(_) = crate_graph.add_dep(from, "std".into(), std) {
119 log::error!("cyclic dependency on std for {}", pkg.name(&ws.cargo))
120 }
121 }
122 }
123 }
124
125 // Now add a dep ednge from all targets of upstream to the lib
126 // target of downstream.
127 for pkg in ws.cargo.packages() {
128 for dep in pkg.dependencies(&ws.cargo) {
129 if let Some(&to) = pkg_to_lib_crate.get(&dep.pkg) {
130 for &from in pkg_crates.get(&pkg).into_iter().flatten() {
131 if let Err(_) = crate_graph.add_dep(from, dep.name.clone(), to) {
132 log::error!(
133 "cyclic dependency {} -> {}",
134 pkg.name(&ws.cargo),
135 dep.pkg.name(&ws.cargo)
136 )
137 }
138 }
139 }
140 }
141 }
142 } 63 }
143 change.set_crate_graph(crate_graph); 64 change.set_crate_graph(crate_graph);
144 65