aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_project_model/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_project_model/src/lib.rs')
-rw-r--r--crates/ra_project_model/src/lib.rs135
1 files changed, 57 insertions, 78 deletions
diff --git a/crates/ra_project_model/src/lib.rs b/crates/ra_project_model/src/lib.rs
index 444d3bb3f..0ab64a1e0 100644
--- a/crates/ra_project_model/src/lib.rs
+++ b/crates/ra_project_model/src/lib.rs
@@ -19,7 +19,7 @@ use rustc_hash::FxHashMap;
19use serde_json::from_reader; 19use serde_json::from_reader;
20 20
21pub use crate::{ 21pub use crate::{
22 cargo_workspace::{CargoFeatures, CargoWorkspace, Package, Target, TargetKind}, 22 cargo_workspace::{CargoConfig, CargoWorkspace, Package, Target, TargetKind},
23 json_project::JsonProject, 23 json_project::JsonProject,
24 sysroot::Sysroot, 24 sysroot::Sysroot,
25}; 25};
@@ -62,30 +62,30 @@ pub struct PackageRoot {
62 /// Is a member of the current workspace 62 /// Is a member of the current workspace
63 is_member: bool, 63 is_member: bool,
64} 64}
65
66impl PackageRoot { 65impl PackageRoot {
67 pub fn new(path: PathBuf, is_member: bool) -> PackageRoot { 66 pub fn new_member(path: PathBuf) -> PackageRoot {
68 PackageRoot { path, is_member } 67 Self { path, is_member: true }
69 } 68 }
70 69 pub fn new_non_member(path: PathBuf) -> PackageRoot {
71 pub fn path(&self) -> &PathBuf { 70 Self { path, is_member: false }
71 }
72 pub fn path(&self) -> &Path {
72 &self.path 73 &self.path
73 } 74 }
74
75 pub fn is_member(&self) -> bool { 75 pub fn is_member(&self) -> bool {
76 self.is_member 76 self.is_member
77 } 77 }
78} 78}
79 79
80impl ProjectWorkspace { 80impl ProjectWorkspace {
81 pub fn discover(path: &Path, cargo_features: &CargoFeatures) -> Result<ProjectWorkspace> { 81 pub fn discover(path: &Path, cargo_features: &CargoConfig) -> Result<ProjectWorkspace> {
82 ProjectWorkspace::discover_with_sysroot(path, true, cargo_features) 82 ProjectWorkspace::discover_with_sysroot(path, true, cargo_features)
83 } 83 }
84 84
85 pub fn discover_with_sysroot( 85 pub fn discover_with_sysroot(
86 path: &Path, 86 path: &Path,
87 with_sysroot: bool, 87 with_sysroot: bool,
88 cargo_features: &CargoFeatures, 88 cargo_features: &CargoConfig,
89 ) -> Result<ProjectWorkspace> { 89 ) -> Result<ProjectWorkspace> {
90 match find_rust_project_json(path) { 90 match find_rust_project_json(path) {
91 Some(json_path) => { 91 Some(json_path) => {
@@ -130,70 +130,45 @@ impl ProjectWorkspace {
130 pub fn to_roots(&self) -> Vec<PackageRoot> { 130 pub fn to_roots(&self) -> Vec<PackageRoot> {
131 match self { 131 match self {
132 ProjectWorkspace::Json { project } => { 132 ProjectWorkspace::Json { project } => {
133 let mut roots = Vec::with_capacity(project.roots.len()); 133 project.roots.iter().map(|r| PackageRoot::new_member(r.path.clone())).collect()
134 for root in &project.roots {
135 roots.push(PackageRoot::new(root.path.clone(), true));
136 }
137 roots
138 }
139 ProjectWorkspace::Cargo { cargo, sysroot } => {
140 let mut roots = Vec::with_capacity(cargo.packages().len() + sysroot.crates().len());
141 for pkg in cargo.packages() {
142 let root = cargo[pkg].root().to_path_buf();
143 let member = cargo[pkg].is_member;
144 roots.push(PackageRoot::new(root, member));
145 }
146 for krate in sysroot.crates() {
147 roots.push(PackageRoot::new(sysroot[krate].root_dir().to_path_buf(), false))
148 }
149 roots
150 } 134 }
135 ProjectWorkspace::Cargo { cargo, sysroot } => cargo
136 .packages()
137 .map(|pkg| PackageRoot {
138 path: cargo[pkg].root().to_path_buf(),
139 is_member: cargo[pkg].is_member,
140 })
141 .chain(sysroot.crates().map(|krate| {
142 PackageRoot::new_non_member(sysroot[krate].root_dir().to_path_buf())
143 }))
144 .collect(),
151 } 145 }
152 } 146 }
153 147
154 pub fn out_dirs(&self) -> Vec<PathBuf> { 148 pub fn out_dirs(&self) -> Vec<PathBuf> {
155 match self { 149 match self {
156 ProjectWorkspace::Json { project } => { 150 ProjectWorkspace::Json { project } => {
157 let mut out_dirs = Vec::with_capacity(project.crates.len()); 151 project.crates.iter().filter_map(|krate| krate.out_dir.as_ref()).cloned().collect()
158 for krate in &project.crates {
159 if let Some(out_dir) = &krate.out_dir {
160 out_dirs.push(out_dir.to_path_buf());
161 }
162 }
163 out_dirs
164 } 152 }
165 ProjectWorkspace::Cargo { cargo, sysroot: _sysroot } => { 153 ProjectWorkspace::Cargo { cargo, sysroot: _ } => {
166 let mut out_dirs = Vec::with_capacity(cargo.packages().len()); 154 cargo.packages().filter_map(|pkg| cargo[pkg].out_dir.as_ref()).cloned().collect()
167 for pkg in cargo.packages() {
168 if let Some(out_dir) = &cargo[pkg].out_dir {
169 out_dirs.push(out_dir.to_path_buf());
170 }
171 }
172 out_dirs
173 } 155 }
174 } 156 }
175 } 157 }
176 158
177 pub fn proc_macro_dylib_paths(&self) -> Vec<PathBuf> { 159 pub fn proc_macro_dylib_paths(&self) -> Vec<PathBuf> {
178 match self { 160 match self {
179 ProjectWorkspace::Json { project } => { 161 ProjectWorkspace::Json { project } => project
180 let mut proc_macro_dylib_paths = Vec::with_capacity(project.crates.len()); 162 .crates
181 for krate in &project.crates { 163 .iter()
182 if let Some(out_dir) = &krate.proc_macro_dylib_path { 164 .filter_map(|krate| krate.proc_macro_dylib_path.as_ref())
183 proc_macro_dylib_paths.push(out_dir.to_path_buf()); 165 .cloned()
184 } 166 .collect(),
185 } 167 ProjectWorkspace::Cargo { cargo, sysroot: _sysroot } => cargo
186 proc_macro_dylib_paths 168 .packages()
187 } 169 .filter_map(|pkg| cargo[pkg].proc_macro_dylib_path.as_ref())
188 ProjectWorkspace::Cargo { cargo, sysroot: _sysroot } => { 170 .cloned()
189 let mut proc_macro_dylib_paths = Vec::with_capacity(cargo.packages().len()); 171 .collect(),
190 for pkg in cargo.packages() {
191 if let Some(dylib_path) = &cargo[pkg].proc_macro_dylib_path {
192 proc_macro_dylib_paths.push(dylib_path.to_path_buf());
193 }
194 }
195 proc_macro_dylib_paths
196 }
197 } 172 }
198 } 173 }
199 174
@@ -216,10 +191,12 @@ impl ProjectWorkspace {
216 let mut crate_graph = CrateGraph::default(); 191 let mut crate_graph = CrateGraph::default();
217 match self { 192 match self {
218 ProjectWorkspace::Json { project } => { 193 ProjectWorkspace::Json { project } => {
219 let mut crates = FxHashMap::default(); 194 let crates: FxHashMap<_, _> = project
220 for (id, krate) in project.crates.iter().enumerate() { 195 .crates
221 let crate_id = json_project::CrateId(id); 196 .iter()
222 if let Some(file_id) = load(&krate.root_module) { 197 .enumerate()
198 .filter_map(|(seq_index, krate)| {
199 let file_id = load(&krate.root_module)?;
223 let edition = match krate.edition { 200 let edition = match krate.edition {
224 json_project::Edition::Edition2015 => Edition::Edition2015, 201 json_project::Edition::Edition2015 => Edition::Edition2015,
225 json_project::Edition::Edition2018 => Edition::Edition2018, 202 json_project::Edition::Edition2018 => Edition::Edition2018,
@@ -249,8 +226,8 @@ impl ProjectWorkspace {
249 .clone() 226 .clone()
250 .map(|it| proc_macro_client.by_dylib_path(&it)); 227 .map(|it| proc_macro_client.by_dylib_path(&it));
251 // FIXME: No crate name in json definition such that we cannot add OUT_DIR to env 228 // FIXME: No crate name in json definition such that we cannot add OUT_DIR to env
252 crates.insert( 229 Some((
253 crate_id, 230 json_project::CrateId(seq_index),
254 crate_graph.add_crate_root( 231 crate_graph.add_crate_root(
255 file_id, 232 file_id,
256 edition, 233 edition,
@@ -261,9 +238,9 @@ impl ProjectWorkspace {
261 extern_source, 238 extern_source,
262 proc_macro.unwrap_or_default(), 239 proc_macro.unwrap_or_default(),
263 ), 240 ),
264 ); 241 ))
265 } 242 })
266 } 243 .collect();
267 244
268 for (id, krate) in project.crates.iter().enumerate() { 245 for (id, krate) in project.crates.iter().enumerate() {
269 for dep in &krate.deps { 246 for dep in &krate.deps {
@@ -287,9 +264,11 @@ impl ProjectWorkspace {
287 } 264 }
288 } 265 }
289 ProjectWorkspace::Cargo { cargo, sysroot } => { 266 ProjectWorkspace::Cargo { cargo, sysroot } => {
290 let mut sysroot_crates = FxHashMap::default(); 267 let sysroot_crates: FxHashMap<_, _> = sysroot
291 for krate in sysroot.crates() { 268 .crates()
292 if let Some(file_id) = load(&sysroot[krate].root) { 269 .filter_map(|krate| {
270 let file_id = load(&sysroot[krate].root)?;
271
293 // Crates from sysroot have `cfg(test)` disabled 272 // Crates from sysroot have `cfg(test)` disabled
294 let cfg_options = { 273 let cfg_options = {
295 let mut opts = default_cfg_options.clone(); 274 let mut opts = default_cfg_options.clone();
@@ -300,22 +279,22 @@ impl ProjectWorkspace {
300 let env = Env::default(); 279 let env = Env::default();
301 let extern_source = ExternSource::default(); 280 let extern_source = ExternSource::default();
302 let proc_macro = vec![]; 281 let proc_macro = vec![];
282 let crate_name = CrateName::new(&sysroot[krate].name)
283 .expect("Sysroot crate names should not contain dashes");
303 284
304 let crate_id = crate_graph.add_crate_root( 285 let crate_id = crate_graph.add_crate_root(
305 file_id, 286 file_id,
306 Edition::Edition2018, 287 Edition::Edition2018,
307 Some( 288 Some(crate_name),
308 CrateName::new(&sysroot[krate].name)
309 .expect("Sysroot crate names should not contain dashes"),
310 ),
311 cfg_options, 289 cfg_options,
312 env, 290 env,
313 extern_source, 291 extern_source,
314 proc_macro, 292 proc_macro,
315 ); 293 );
316 sysroot_crates.insert(krate, crate_id); 294 Some((krate, crate_id))
317 } 295 })
318 } 296 .collect();
297
319 for from in sysroot.crates() { 298 for from in sysroot.crates() {
320 for &to in sysroot[from].deps.iter() { 299 for &to in sysroot[from].deps.iter() {
321 let name = &sysroot[to].name; 300 let name = &sysroot[to].name;