aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_project_model
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_project_model')
-rw-r--r--crates/ra_project_model/src/cargo_workspace.rs12
-rw-r--r--crates/ra_project_model/src/lib.rs48
-rw-r--r--crates/ra_project_model/src/sysroot.rs10
3 files changed, 60 insertions, 10 deletions
diff --git a/crates/ra_project_model/src/cargo_workspace.rs b/crates/ra_project_model/src/cargo_workspace.rs
index cf88911b7..351997dcd 100644
--- a/crates/ra_project_model/src/cargo_workspace.rs
+++ b/crates/ra_project_model/src/cargo_workspace.rs
@@ -1,7 +1,6 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2 2
3use std::path::{Path, PathBuf}; 3use std::path::{Path, PathBuf};
4use std::str::FromStr;
5 4
6use cargo_metadata::{CargoOpt, MetadataCommand}; 5use cargo_metadata::{CargoOpt, MetadataCommand};
7use ra_arena::{impl_arena_id, Arena, RawId}; 6use ra_arena::{impl_arena_id, Arena, RawId};
@@ -55,11 +54,13 @@ struct TargetData {
55 name: String, 54 name: String,
56 root: PathBuf, 55 root: PathBuf,
57 kind: TargetKind, 56 kind: TargetKind,
57 is_proc_macro: bool,
58} 58}
59 59
60#[derive(Debug, Clone, Copy, PartialEq, Eq)] 60#[derive(Debug, Clone, Copy, PartialEq, Eq)]
61pub enum TargetKind { 61pub enum TargetKind {
62 Bin, 62 Bin,
63 /// Any kind of Cargo lib crate-type (dylib, rlib, proc-macro, ...).
63 Lib, 64 Lib,
64 Example, 65 Example,
65 Test, 66 Test,
@@ -75,6 +76,7 @@ impl TargetKind {
75 "test" => TargetKind::Test, 76 "test" => TargetKind::Test,
76 "bench" => TargetKind::Bench, 77 "bench" => TargetKind::Bench,
77 "example" => TargetKind::Example, 78 "example" => TargetKind::Example,
79 "proc-macro" => TargetKind::Lib,
78 _ if kind.contains("lib") => TargetKind::Lib, 80 _ if kind.contains("lib") => TargetKind::Lib,
79 _ => continue, 81 _ => continue,
80 }; 82 };
@@ -124,6 +126,9 @@ impl Target {
124 pub fn kind(self, ws: &CargoWorkspace) -> TargetKind { 126 pub fn kind(self, ws: &CargoWorkspace) -> TargetKind {
125 ws.targets[self].kind 127 ws.targets[self].kind
126 } 128 }
129 pub fn is_proc_macro(self, ws: &CargoWorkspace) -> bool {
130 ws.targets[self].is_proc_macro
131 }
127} 132}
128 133
129impl CargoWorkspace { 134impl CargoWorkspace {
@@ -143,8 +148,7 @@ impl CargoWorkspace {
143 for meta_pkg in meta.packages { 148 for meta_pkg in meta.packages {
144 let cargo_metadata::Package { id, edition, name, manifest_path, .. } = meta_pkg; 149 let cargo_metadata::Package { id, edition, name, manifest_path, .. } = meta_pkg;
145 let is_member = ws_members.contains(&id); 150 let is_member = ws_members.contains(&id);
146 let edition = Edition::from_str(&edition) 151 let edition = edition.parse::<Edition>()?;
147 .map_err(|e| (format!("metadata for package {} failed: {}", &name, e.msg)))?;
148 let pkg = packages.alloc(PackageData { 152 let pkg = packages.alloc(PackageData {
149 name, 153 name,
150 manifest: manifest_path, 154 manifest: manifest_path,
@@ -157,11 +161,13 @@ impl CargoWorkspace {
157 let pkg_data = &mut packages[pkg]; 161 let pkg_data = &mut packages[pkg];
158 pkg_by_id.insert(id, pkg); 162 pkg_by_id.insert(id, pkg);
159 for meta_tgt in meta_pkg.targets { 163 for meta_tgt in meta_pkg.targets {
164 let is_proc_macro = meta_tgt.kind.as_slice() == &["proc-macro"];
160 let tgt = targets.alloc(TargetData { 165 let tgt = targets.alloc(TargetData {
161 pkg, 166 pkg,
162 name: meta_tgt.name, 167 name: meta_tgt.name,
163 root: meta_tgt.src_path.clone(), 168 root: meta_tgt.src_path.clone(),
164 kind: TargetKind::new(meta_tgt.kind.as_slice()), 169 kind: TargetKind::new(meta_tgt.kind.as_slice()),
170 is_proc_macro,
165 }); 171 });
166 pkg_data.targets.push(tgt); 172 pkg_data.targets.push(tgt);
167 } 173 }
diff --git a/crates/ra_project_model/src/lib.rs b/crates/ra_project_model/src/lib.rs
index 0e14f1b70..55ff4d6ef 100644
--- a/crates/ra_project_model/src/lib.rs
+++ b/crates/ra_project_model/src/lib.rs
@@ -13,7 +13,7 @@ use std::{
13}; 13};
14 14
15use ra_cfg::CfgOptions; 15use ra_cfg::CfgOptions;
16use ra_db::{CrateGraph, CrateId, Edition, FileId}; 16use ra_db::{CrateGraph, CrateId, Edition, Env, FileId};
17use rustc_hash::FxHashMap; 17use rustc_hash::FxHashMap;
18use serde_json::from_reader; 18use serde_json::from_reader;
19 19
@@ -146,7 +146,12 @@ impl ProjectWorkspace {
146 }; 146 };
147 crates.insert( 147 crates.insert(
148 crate_id, 148 crate_id,
149 crate_graph.add_crate_root(file_id, edition, cfg_options), 149 crate_graph.add_crate_root(
150 file_id,
151 edition,
152 cfg_options,
153 Env::default(),
154 ),
150 ); 155 );
151 } 156 }
152 } 157 }
@@ -180,8 +185,12 @@ impl ProjectWorkspace {
180 opts 185 opts
181 }; 186 };
182 187
183 let crate_id = 188 let crate_id = crate_graph.add_crate_root(
184 crate_graph.add_crate_root(file_id, Edition::Edition2018, cfg_options); 189 file_id,
190 Edition::Edition2018,
191 cfg_options,
192 Env::default(),
193 );
185 sysroot_crates.insert(krate, crate_id); 194 sysroot_crates.insert(krate, crate_id);
186 names.insert(crate_id, krate.name(&sysroot).to_string()); 195 names.insert(crate_id, krate.name(&sysroot).to_string());
187 } 196 }
@@ -200,7 +209,10 @@ impl ProjectWorkspace {
200 } 209 }
201 210
202 let libcore = sysroot.core().and_then(|it| sysroot_crates.get(&it).copied()); 211 let libcore = sysroot.core().and_then(|it| sysroot_crates.get(&it).copied());
212 let liballoc = sysroot.alloc().and_then(|it| sysroot_crates.get(&it).copied());
203 let libstd = sysroot.std().and_then(|it| sysroot_crates.get(&it).copied()); 213 let libstd = sysroot.std().and_then(|it| sysroot_crates.get(&it).copied());
214 let libproc_macro =
215 sysroot.proc_macro().and_then(|it| sysroot_crates.get(&it).copied());
204 216
205 let mut pkg_to_lib_crate = FxHashMap::default(); 217 let mut pkg_to_lib_crate = FxHashMap::default();
206 let mut pkg_crates = FxHashMap::default(); 218 let mut pkg_crates = FxHashMap::default();
@@ -216,13 +228,32 @@ impl ProjectWorkspace {
216 opts.insert_features(pkg.features(&cargo).iter().map(Into::into)); 228 opts.insert_features(pkg.features(&cargo).iter().map(Into::into));
217 opts 229 opts
218 }; 230 };
219 let crate_id = 231 let crate_id = crate_graph.add_crate_root(
220 crate_graph.add_crate_root(file_id, edition, cfg_options); 232 file_id,
233 edition,
234 cfg_options,
235 Env::default(),
236 );
221 names.insert(crate_id, pkg.name(&cargo).to_string()); 237 names.insert(crate_id, pkg.name(&cargo).to_string());
222 if tgt.kind(&cargo) == TargetKind::Lib { 238 if tgt.kind(&cargo) == TargetKind::Lib {
223 lib_tgt = Some(crate_id); 239 lib_tgt = Some(crate_id);
224 pkg_to_lib_crate.insert(pkg, crate_id); 240 pkg_to_lib_crate.insert(pkg, crate_id);
225 } 241 }
242 if tgt.is_proc_macro(&cargo) {
243 if let Some(proc_macro) = libproc_macro {
244 if let Err(_) = crate_graph.add_dep(
245 crate_id,
246 "proc_macro".into(),
247 proc_macro,
248 ) {
249 log::error!(
250 "cyclic dependency on proc_macro for {}",
251 pkg.name(&cargo)
252 )
253 }
254 }
255 }
256
226 pkg_crates.entry(pkg).or_insert_with(Vec::new).push(crate_id); 257 pkg_crates.entry(pkg).or_insert_with(Vec::new).push(crate_id);
227 } 258 }
228 } 259 }
@@ -248,6 +279,11 @@ impl ProjectWorkspace {
248 log::error!("cyclic dependency on core for {}", pkg.name(&cargo)) 279 log::error!("cyclic dependency on core for {}", pkg.name(&cargo))
249 } 280 }
250 } 281 }
282 if let Some(alloc) = liballoc {
283 if let Err(_) = crate_graph.add_dep(from, "alloc".into(), alloc) {
284 log::error!("cyclic dependency on alloc for {}", pkg.name(&cargo))
285 }
286 }
251 if let Some(std) = libstd { 287 if let Some(std) = libstd {
252 if let Err(_) = crate_graph.add_dep(from, "std".into(), std) { 288 if let Err(_) = crate_graph.add_dep(from, "std".into(), std) {
253 log::error!("cyclic dependency on std for {}", pkg.name(&cargo)) 289 log::error!("cyclic dependency on std for {}", pkg.name(&cargo))
diff --git a/crates/ra_project_model/src/sysroot.rs b/crates/ra_project_model/src/sysroot.rs
index 3d827809e..10ca391b6 100644
--- a/crates/ra_project_model/src/sysroot.rs
+++ b/crates/ra_project_model/src/sysroot.rs
@@ -31,10 +31,18 @@ impl Sysroot {
31 self.by_name("core") 31 self.by_name("core")
32 } 32 }
33 33
34 pub fn alloc(&self) -> Option<SysrootCrate> {
35 self.by_name("alloc")
36 }
37
34 pub fn std(&self) -> Option<SysrootCrate> { 38 pub fn std(&self) -> Option<SysrootCrate> {
35 self.by_name("std") 39 self.by_name("std")
36 } 40 }
37 41
42 pub fn proc_macro(&self) -> Option<SysrootCrate> {
43 self.by_name("proc_macro")
44 }
45
38 pub fn crates<'a>(&'a self) -> impl Iterator<Item = SysrootCrate> + ExactSizeIterator + 'a { 46 pub fn crates<'a>(&'a self) -> impl Iterator<Item = SysrootCrate> + ExactSizeIterator + 'a {
39 self.crates.iter().map(|(id, _data)| id) 47 self.crates.iter().map(|(id, _data)| id)
40 } 48 }
@@ -70,7 +78,7 @@ impl Sysroot {
70 } 78 }
71 } 79 }
72 if let Some(alloc) = sysroot.by_name("alloc") { 80 if let Some(alloc) = sysroot.by_name("alloc") {
73 if let Some(core) = sysroot.by_name("core") { 81 if let Some(core) = sysroot.core() {
74 sysroot.crates[alloc].deps.push(core); 82 sysroot.crates[alloc].deps.push(core);
75 } 83 }
76 } 84 }