diff options
Diffstat (limited to 'crates/ra_project_model/src/sysroot.rs')
-rw-r--r-- | crates/ra_project_model/src/sysroot.rs | 136 |
1 files changed, 136 insertions, 0 deletions
diff --git a/crates/ra_project_model/src/sysroot.rs b/crates/ra_project_model/src/sysroot.rs new file mode 100644 index 000000000..8b87aa7bd --- /dev/null +++ b/crates/ra_project_model/src/sysroot.rs | |||
@@ -0,0 +1,136 @@ | |||
1 | use std::{ | ||
2 | path::{Path, PathBuf}, | ||
3 | process::Command, | ||
4 | }; | ||
5 | |||
6 | use ra_arena::{Arena, RawId, impl_arena_id}; | ||
7 | |||
8 | use crate::Result; | ||
9 | |||
10 | #[derive(Debug, Clone)] | ||
11 | pub struct Sysroot { | ||
12 | crates: Arena<SysrootCrate, SysrootCrateData>, | ||
13 | } | ||
14 | |||
15 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
16 | pub struct SysrootCrate(RawId); | ||
17 | impl_arena_id!(SysrootCrate); | ||
18 | |||
19 | #[derive(Debug, Clone)] | ||
20 | struct SysrootCrateData { | ||
21 | name: String, | ||
22 | root: PathBuf, | ||
23 | deps: Vec<SysrootCrate>, | ||
24 | } | ||
25 | |||
26 | impl Sysroot { | ||
27 | pub fn std(&self) -> Option<SysrootCrate> { | ||
28 | self.by_name("std") | ||
29 | } | ||
30 | |||
31 | pub fn crates<'a>(&'a self) -> impl Iterator<Item = SysrootCrate> + 'a { | ||
32 | self.crates.iter().map(|(id, _data)| id) | ||
33 | } | ||
34 | |||
35 | pub fn discover(cargo_toml: &Path) -> Result<Sysroot> { | ||
36 | let rustc_output = Command::new("rustc") | ||
37 | .current_dir(cargo_toml.parent().unwrap()) | ||
38 | .args(&["--print", "sysroot"]) | ||
39 | .output()?; | ||
40 | if !rustc_output.status.success() { | ||
41 | failure::bail!("failed to locate sysroot") | ||
42 | } | ||
43 | let stdout = String::from_utf8(rustc_output.stdout)?; | ||
44 | let sysroot_path = Path::new(stdout.trim()); | ||
45 | let src = sysroot_path.join("lib/rustlib/src/rust/src"); | ||
46 | if !src.exists() { | ||
47 | failure::bail!( | ||
48 | "can't load standard library from sysroot\n\ | ||
49 | {:?}\n\ | ||
50 | try running `rustup component add rust-src`", | ||
51 | src, | ||
52 | ); | ||
53 | } | ||
54 | |||
55 | let mut sysroot = Sysroot { crates: Arena::default() }; | ||
56 | for name in SYSROOT_CRATES.trim().lines() { | ||
57 | let root = src.join(format!("lib{}", name)).join("lib.rs"); | ||
58 | if root.exists() { | ||
59 | sysroot.crates.alloc(SysrootCrateData { | ||
60 | name: name.into(), | ||
61 | root, | ||
62 | deps: Vec::new(), | ||
63 | }); | ||
64 | } | ||
65 | } | ||
66 | if let Some(std) = sysroot.std() { | ||
67 | for dep in STD_DEPS.trim().lines() { | ||
68 | if let Some(dep) = sysroot.by_name(dep) { | ||
69 | sysroot.crates[std].deps.push(dep) | ||
70 | } | ||
71 | } | ||
72 | } | ||
73 | Ok(sysroot) | ||
74 | } | ||
75 | |||
76 | fn by_name(&self, name: &str) -> Option<SysrootCrate> { | ||
77 | self.crates.iter().find(|(_id, data)| data.name == name).map(|(id, _data)| id) | ||
78 | } | ||
79 | } | ||
80 | |||
81 | impl SysrootCrate { | ||
82 | pub fn name(self, sysroot: &Sysroot) -> &str { | ||
83 | &sysroot.crates[self].name | ||
84 | } | ||
85 | pub fn root(self, sysroot: &Sysroot) -> &Path { | ||
86 | sysroot.crates[self].root.as_path() | ||
87 | } | ||
88 | pub fn root_dir(self, sysroot: &Sysroot) -> &Path { | ||
89 | self.root(sysroot).parent().unwrap() | ||
90 | } | ||
91 | pub fn deps<'a>(self, sysroot: &'a Sysroot) -> impl Iterator<Item = SysrootCrate> + 'a { | ||
92 | sysroot.crates[self].deps.iter().map(|&it| it) | ||
93 | } | ||
94 | } | ||
95 | |||
96 | const SYSROOT_CRATES: &str = " | ||
97 | std | ||
98 | core | ||
99 | alloc | ||
100 | collections | ||
101 | libc | ||
102 | panic_unwind | ||
103 | proc_macro | ||
104 | rustc_unicode | ||
105 | std_unicode | ||
106 | test | ||
107 | alloc_jemalloc | ||
108 | alloc_system | ||
109 | compiler_builtins | ||
110 | getopts | ||
111 | panic_unwind | ||
112 | panic_abort | ||
113 | rand | ||
114 | term | ||
115 | unwind | ||
116 | build_helper | ||
117 | rustc_asan | ||
118 | rustc_lsan | ||
119 | rustc_msan | ||
120 | rustc_tsan | ||
121 | syntax"; | ||
122 | |||
123 | const STD_DEPS: &str = " | ||
124 | alloc | ||
125 | alloc_jemalloc | ||
126 | alloc_system | ||
127 | core | ||
128 | panic_abort | ||
129 | rand | ||
130 | compiler_builtins | ||
131 | unwind | ||
132 | rustc_asan | ||
133 | rustc_lsan | ||
134 | rustc_msan | ||
135 | rustc_tsan | ||
136 | build_helper"; | ||