aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_lsp_server/src
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2019-01-10 21:37:10 +0000
committerAleksey Kladov <[email protected]>2019-01-10 21:51:34 +0000
commitcd00158b1db9dd8565d2db08b4b0ebab9d5c00b3 (patch)
tree2072596e298e76aa6d5a8896ef30f591d7c7051c /crates/ra_lsp_server/src
parente35374ec7c26be8de61ec7c6175c2385ee5c006f (diff)
wire sysroot into crate graph
Diffstat (limited to 'crates/ra_lsp_server/src')
-rw-r--r--crates/ra_lsp_server/src/project_model/sysroot.rs27
-rw-r--r--crates/ra_lsp_server/src/server_world.rs51
2 files changed, 72 insertions, 6 deletions
diff --git a/crates/ra_lsp_server/src/project_model/sysroot.rs b/crates/ra_lsp_server/src/project_model/sysroot.rs
index c4028a1fe..1dbab57f8 100644
--- a/crates/ra_lsp_server/src/project_model/sysroot.rs
+++ b/crates/ra_lsp_server/src/project_model/sysroot.rs
@@ -20,7 +20,7 @@ impl_arena_id!(SysrootCrate);
20#[derive(Debug, Clone)] 20#[derive(Debug, Clone)]
21struct SysrootCrateData { 21struct SysrootCrateData {
22 name: SmolStr, 22 name: SmolStr,
23 path: PathBuf, 23 root: PathBuf,
24 deps: Vec<SysrootCrate>, 24 deps: Vec<SysrootCrate>,
25} 25}
26 26
@@ -29,6 +29,10 @@ impl Sysroot {
29 self.by_name("std") 29 self.by_name("std")
30 } 30 }
31 31
32 pub(crate) fn crates<'a>(&'a self) -> impl Iterator<Item = SysrootCrate> + 'a {
33 self.crates.iter().map(|(id, _data)| id)
34 }
35
32 pub(super) fn discover(cargo_toml: &Path) -> Result<Sysroot> { 36 pub(super) fn discover(cargo_toml: &Path) -> Result<Sysroot> {
33 let rustc_output = Command::new("rustc") 37 let rustc_output = Command::new("rustc")
34 .current_dir(cargo_toml.parent().unwrap()) 38 .current_dir(cargo_toml.parent().unwrap())
@@ -45,11 +49,11 @@ impl Sysroot {
45 crates: Arena::default(), 49 crates: Arena::default(),
46 }; 50 };
47 for name in SYSROOT_CRATES.trim().lines() { 51 for name in SYSROOT_CRATES.trim().lines() {
48 let path = src.join(format!("lib{}", name)).join("lib.rs"); 52 let root = src.join(format!("lib{}", name)).join("lib.rs");
49 if path.exists() { 53 if root.exists() {
50 sysroot.crates.alloc(SysrootCrateData { 54 sysroot.crates.alloc(SysrootCrateData {
51 name: name.into(), 55 name: name.into(),
52 path, 56 root,
53 deps: Vec::new(), 57 deps: Vec::new(),
54 }); 58 });
55 } 59 }
@@ -72,6 +76,21 @@ impl Sysroot {
72 } 76 }
73} 77}
74 78
79impl SysrootCrate {
80 pub(crate) fn name(self, sysroot: &Sysroot) -> &SmolStr {
81 &sysroot.crates[self].name
82 }
83 pub(crate) fn root(self, sysroot: &Sysroot) -> &Path {
84 sysroot.crates[self].root.as_path()
85 }
86 pub(crate) fn root_dir(self, sysroot: &Sysroot) -> &Path {
87 self.root(sysroot).parent().unwrap()
88 }
89 pub(crate) fn deps<'a>(self, sysroot: &'a Sysroot) -> impl Iterator<Item = SysrootCrate> + 'a {
90 sysroot.crates[self].deps.iter().map(|&it| it)
91 }
92}
93
75const SYSROOT_CRATES: &str = " 94const SYSROOT_CRATES: &str = "
76std 95std
77core 96core
diff --git a/crates/ra_lsp_server/src/server_world.rs b/crates/ra_lsp_server/src/server_world.rs
index 2debbe557..4f3c231d3 100644
--- a/crates/ra_lsp_server/src/server_world.rs
+++ b/crates/ra_lsp_server/src/server_world.rs
@@ -44,7 +44,12 @@ impl ServerWorldState {
44 for pkg in ws.cargo.packages() { 44 for pkg in ws.cargo.packages() {
45 roots.push(pkg.root(&ws.cargo).to_path_buf()); 45 roots.push(pkg.root(&ws.cargo).to_path_buf());
46 } 46 }
47 for krate in ws.sysroot.crates() {
48 roots.push(krate.root_dir(&ws.sysroot).to_path_buf())
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() {
62 // First, load std
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 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
59 for pkg in ws.cargo.packages() { 89 for pkg in ws.cargo.packages() {
90 let mut lib_tgt = None;
60 for tgt in pkg.targets(&ws.cargo) { 91 for tgt in pkg.targets(&ws.cargo) {
61 let root = tgt.root(&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.cargo) == 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,7 +103,22 @@ 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 }
119
120 // Now add a dep ednge from all targets of upstream to the lib
121 // target of downstream.
75 for pkg in ws.cargo.packages() { 122 for pkg in ws.cargo.packages() {
76 for dep in pkg.dependencies(&ws.cargo) { 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) {