diff options
Diffstat (limited to 'crates/ra_lsp_server')
-rw-r--r-- | crates/ra_lsp_server/src/server_world.rs | 85 |
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 | }; |
11 | use ra_vfs::{Vfs, VfsChange, VfsFile, VfsRoot}; | 11 | use ra_vfs::{Vfs, VfsChange, VfsFile, VfsRoot}; |
12 | use rustc_hash::FxHashMap; | ||
13 | use relative_path::RelativePathBuf; | 12 | use relative_path::RelativePathBuf; |
14 | use parking_lot::RwLock; | 13 | use parking_lot::RwLock; |
15 | use failure::format_err; | 14 | use failure::format_err; |
16 | 15 | ||
17 | use crate::{ | 16 | use 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 | ||