diff options
Diffstat (limited to 'crates/ra_lsp_server/src/server_world.rs')
-rw-r--r-- | crates/ra_lsp_server/src/server_world.rs | 75 |
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; | |||
15 | use failure::format_err; | 15 | use failure::format_err; |
16 | 16 | ||
17 | use crate::{ | 17 | use 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::{ | |||
23 | pub struct ServerWorldState { | 23 | pub 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 | ||
31 | pub struct ServerWorld { | 31 | pub 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 | ||
37 | impl ServerWorldState { | 37 | impl 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); |