diff options
-rw-r--r-- | crates/ra_db/src/fixture.rs | 6 | ||||
-rw-r--r-- | crates/ra_db/src/input.rs | 52 | ||||
-rw-r--r-- | crates/ra_db/src/lib.rs | 4 | ||||
-rw-r--r-- | crates/ra_ide/src/mock_analysis.rs | 6 | ||||
-rw-r--r-- | crates/ra_project_model/src/lib.rs | 43 |
5 files changed, 84 insertions, 27 deletions
diff --git a/crates/ra_db/src/fixture.rs b/crates/ra_db/src/fixture.rs index 30b598e9a..17cd138c2 100644 --- a/crates/ra_db/src/fixture.rs +++ b/crates/ra_db/src/fixture.rs | |||
@@ -8,8 +8,8 @@ use rustc_hash::FxHashMap; | |||
8 | use test_utils::{extract_offset, parse_fixture, CURSOR_MARKER}; | 8 | use test_utils::{extract_offset, parse_fixture, CURSOR_MARKER}; |
9 | 9 | ||
10 | use crate::{ | 10 | use crate::{ |
11 | CrateGraph, CrateId, Edition, Env, FileId, FilePosition, RelativePathBuf, SourceDatabaseExt, | 11 | input::CrateName, CrateGraph, CrateId, Edition, Env, FileId, FilePosition, RelativePathBuf, |
12 | SourceRoot, SourceRootId, | 12 | SourceDatabaseExt, SourceRoot, SourceRootId, |
13 | }; | 13 | }; |
14 | 14 | ||
15 | pub const WORKSPACE: SourceRootId = SourceRootId(0); | 15 | pub const WORKSPACE: SourceRootId = SourceRootId(0); |
@@ -139,7 +139,7 @@ fn with_files(db: &mut dyn SourceDatabaseExt, fixture: &str) -> Option<FilePosit | |||
139 | for (from, to) in crate_deps { | 139 | for (from, to) in crate_deps { |
140 | let from_id = crates[&from]; | 140 | let from_id = crates[&from]; |
141 | let to_id = crates[&to]; | 141 | let to_id = crates[&to]; |
142 | crate_graph.add_dep(from_id, to.into(), to_id).unwrap(); | 142 | crate_graph.add_dep(from_id, CrateName::new(&to).unwrap(), to_id).unwrap(); |
143 | } | 143 | } |
144 | } | 144 | } |
145 | 145 | ||
diff --git a/crates/ra_db/src/input.rs b/crates/ra_db/src/input.rs index 07269237a..1f1dcea42 100644 --- a/crates/ra_db/src/input.rs +++ b/crates/ra_db/src/input.rs | |||
@@ -83,6 +83,26 @@ pub struct CrateGraph { | |||
83 | #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] | 83 | #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] |
84 | pub struct CrateId(pub u32); | 84 | pub struct CrateId(pub u32); |
85 | 85 | ||
86 | pub struct CrateName(SmolStr); | ||
87 | |||
88 | impl CrateName { | ||
89 | /// Crates a crate name, checking for dashes in the string provided. | ||
90 | /// Dashes are not allowed in the crate names, | ||
91 | /// hence the input string is returned as `Err` for those cases. | ||
92 | pub fn new(name: &str) -> Result<CrateName, &str> { | ||
93 | if name.contains('-') { | ||
94 | Err(name) | ||
95 | } else { | ||
96 | Ok(Self(SmolStr::new(name))) | ||
97 | } | ||
98 | } | ||
99 | |||
100 | /// Crates a crate name, unconditionally replacing the dashes with underscores. | ||
101 | pub fn normalize_dashes(name: &str) -> CrateName { | ||
102 | Self(SmolStr::new(name.replace('-', "_"))) | ||
103 | } | ||
104 | } | ||
105 | |||
86 | #[derive(Debug, Clone, PartialEq, Eq)] | 106 | #[derive(Debug, Clone, PartialEq, Eq)] |
87 | struct CrateData { | 107 | struct CrateData { |
88 | file_id: FileId, | 108 | file_id: FileId, |
@@ -131,13 +151,13 @@ impl CrateGraph { | |||
131 | pub fn add_dep( | 151 | pub fn add_dep( |
132 | &mut self, | 152 | &mut self, |
133 | from: CrateId, | 153 | from: CrateId, |
134 | name: SmolStr, | 154 | name: CrateName, |
135 | to: CrateId, | 155 | to: CrateId, |
136 | ) -> Result<(), CyclicDependenciesError> { | 156 | ) -> Result<(), CyclicDependenciesError> { |
137 | if self.dfs_find(from, to, &mut FxHashSet::default()) { | 157 | if self.dfs_find(from, to, &mut FxHashSet::default()) { |
138 | return Err(CyclicDependenciesError); | 158 | return Err(CyclicDependenciesError); |
139 | } | 159 | } |
140 | self.arena.get_mut(&from).unwrap().add_dep(name, to); | 160 | self.arena.get_mut(&from).unwrap().add_dep(name.0, to); |
141 | Ok(()) | 161 | Ok(()) |
142 | } | 162 | } |
143 | 163 | ||
@@ -268,7 +288,7 @@ pub struct CyclicDependenciesError; | |||
268 | 288 | ||
269 | #[cfg(test)] | 289 | #[cfg(test)] |
270 | mod tests { | 290 | mod tests { |
271 | use super::{CfgOptions, CrateGraph, Edition::Edition2018, Env, FileId, SmolStr}; | 291 | use super::{CfgOptions, CrateGraph, CrateName, Dependency, Edition::Edition2018, Env, FileId}; |
272 | 292 | ||
273 | #[test] | 293 | #[test] |
274 | fn it_should_panic_because_of_cycle_dependencies() { | 294 | fn it_should_panic_because_of_cycle_dependencies() { |
@@ -279,9 +299,9 @@ mod tests { | |||
279 | graph.add_crate_root(FileId(2u32), Edition2018, CfgOptions::default(), Env::default()); | 299 | graph.add_crate_root(FileId(2u32), Edition2018, CfgOptions::default(), Env::default()); |
280 | let crate3 = | 300 | let crate3 = |
281 | graph.add_crate_root(FileId(3u32), Edition2018, CfgOptions::default(), Env::default()); | 301 | graph.add_crate_root(FileId(3u32), Edition2018, CfgOptions::default(), Env::default()); |
282 | assert!(graph.add_dep(crate1, SmolStr::new("crate2"), crate2).is_ok()); | 302 | assert!(graph.add_dep(crate1, CrateName::new("crate2").unwrap(), crate2).is_ok()); |
283 | assert!(graph.add_dep(crate2, SmolStr::new("crate3"), crate3).is_ok()); | 303 | assert!(graph.add_dep(crate2, CrateName::new("crate3").unwrap(), crate3).is_ok()); |
284 | assert!(graph.add_dep(crate3, SmolStr::new("crate1"), crate1).is_err()); | 304 | assert!(graph.add_dep(crate3, CrateName::new("crate1").unwrap(), crate1).is_err()); |
285 | } | 305 | } |
286 | 306 | ||
287 | #[test] | 307 | #[test] |
@@ -293,7 +313,23 @@ mod tests { | |||
293 | graph.add_crate_root(FileId(2u32), Edition2018, CfgOptions::default(), Env::default()); | 313 | graph.add_crate_root(FileId(2u32), Edition2018, CfgOptions::default(), Env::default()); |
294 | let crate3 = | 314 | let crate3 = |
295 | graph.add_crate_root(FileId(3u32), Edition2018, CfgOptions::default(), Env::default()); | 315 | graph.add_crate_root(FileId(3u32), Edition2018, CfgOptions::default(), Env::default()); |
296 | assert!(graph.add_dep(crate1, SmolStr::new("crate2"), crate2).is_ok()); | 316 | assert!(graph.add_dep(crate1, CrateName::new("crate2").unwrap(), crate2).is_ok()); |
297 | assert!(graph.add_dep(crate2, SmolStr::new("crate3"), crate3).is_ok()); | 317 | assert!(graph.add_dep(crate2, CrateName::new("crate3").unwrap(), crate3).is_ok()); |
318 | } | ||
319 | |||
320 | #[test] | ||
321 | fn dashes_are_normalized() { | ||
322 | let mut graph = CrateGraph::default(); | ||
323 | let crate1 = | ||
324 | graph.add_crate_root(FileId(1u32), Edition2018, CfgOptions::default(), Env::default()); | ||
325 | let crate2 = | ||
326 | graph.add_crate_root(FileId(2u32), Edition2018, CfgOptions::default(), Env::default()); | ||
327 | assert!(graph | ||
328 | .add_dep(crate1, CrateName::normalize_dashes("crate-name-with-dashes"), crate2) | ||
329 | .is_ok()); | ||
330 | assert_eq!( | ||
331 | graph.dependencies(crate1).collect::<Vec<_>>(), | ||
332 | vec![&Dependency { crate_id: crate2, name: "crate_name_with_dashes".into() }] | ||
333 | ); | ||
298 | } | 334 | } |
299 | } | 335 | } |
diff --git a/crates/ra_db/src/lib.rs b/crates/ra_db/src/lib.rs index 21341b769..fb002d717 100644 --- a/crates/ra_db/src/lib.rs +++ b/crates/ra_db/src/lib.rs | |||
@@ -10,7 +10,9 @@ use ra_syntax::{ast, Parse, SourceFile, TextRange, TextUnit}; | |||
10 | 10 | ||
11 | pub use crate::{ | 11 | pub use crate::{ |
12 | cancellation::Canceled, | 12 | cancellation::Canceled, |
13 | input::{CrateGraph, CrateId, Dependency, Edition, Env, FileId, SourceRoot, SourceRootId}, | 13 | input::{ |
14 | CrateGraph, CrateId, CrateName, Dependency, Edition, Env, FileId, SourceRoot, SourceRootId, | ||
15 | }, | ||
14 | }; | 16 | }; |
15 | pub use relative_path::{RelativePath, RelativePathBuf}; | 17 | pub use relative_path::{RelativePath, RelativePathBuf}; |
16 | pub use salsa; | 18 | pub use salsa; |
diff --git a/crates/ra_ide/src/mock_analysis.rs b/crates/ra_ide/src/mock_analysis.rs index bf8a54932..081aaee8c 100644 --- a/crates/ra_ide/src/mock_analysis.rs +++ b/crates/ra_ide/src/mock_analysis.rs | |||
@@ -3,7 +3,7 @@ | |||
3 | use std::sync::Arc; | 3 | use std::sync::Arc; |
4 | 4 | ||
5 | use ra_cfg::CfgOptions; | 5 | use ra_cfg::CfgOptions; |
6 | use ra_db::{Env, RelativePathBuf}; | 6 | use ra_db::{CrateName, Env, RelativePathBuf}; |
7 | use test_utils::{extract_offset, extract_range, parse_fixture, CURSOR_MARKER}; | 7 | use test_utils::{extract_offset, extract_range, parse_fixture, CURSOR_MARKER}; |
8 | 8 | ||
9 | use crate::{ | 9 | use crate::{ |
@@ -107,7 +107,9 @@ impl MockAnalysis { | |||
107 | crate_graph.add_crate_root(file_id, Edition2018, cfg_options, Env::default()); | 107 | crate_graph.add_crate_root(file_id, Edition2018, cfg_options, Env::default()); |
108 | let crate_name = path.parent().unwrap().file_name().unwrap(); | 108 | let crate_name = path.parent().unwrap().file_name().unwrap(); |
109 | if let Some(root_crate) = root_crate { | 109 | if let Some(root_crate) = root_crate { |
110 | crate_graph.add_dep(root_crate, crate_name.into(), other_crate).unwrap(); | 110 | crate_graph |
111 | .add_dep(root_crate, CrateName::new(crate_name).unwrap(), other_crate) | ||
112 | .unwrap(); | ||
111 | } | 113 | } |
112 | } | 114 | } |
113 | change.add_file(source_root, file_id, path, Arc::new(contents)); | 115 | change.add_file(source_root, file_id, path, Arc::new(contents)); |
diff --git a/crates/ra_project_model/src/lib.rs b/crates/ra_project_model/src/lib.rs index 6a104e6f2..bc1d15406 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 | ||
15 | use ra_cfg::CfgOptions; | 15 | use ra_cfg::CfgOptions; |
16 | use ra_db::{CrateGraph, CrateId, Edition, Env, FileId}; | 16 | use ra_db::{CrateGraph, CrateId, CrateName, Edition, Env, FileId}; |
17 | use rustc_hash::FxHashMap; | 17 | use rustc_hash::FxHashMap; |
18 | use serde_json::from_reader; | 18 | use serde_json::from_reader; |
19 | 19 | ||
@@ -177,7 +177,9 @@ impl ProjectWorkspace { | |||
177 | if let (Some(&from), Some(&to)) = | 177 | if let (Some(&from), Some(&to)) = |
178 | (crates.get(&from_crate_id), crates.get(&to_crate_id)) | 178 | (crates.get(&from_crate_id), crates.get(&to_crate_id)) |
179 | { | 179 | { |
180 | if let Err(_) = crate_graph.add_dep(from, dep.name.clone().into(), to) { | 180 | if let Err(_) = |
181 | crate_graph.add_dep(from, CrateName::new(&dep.name).unwrap(), to) | ||
182 | { | ||
181 | log::error!( | 183 | log::error!( |
182 | "cyclic dependency {:?} -> {:?}", | 184 | "cyclic dependency {:?} -> {:?}", |
183 | from_crate_id, | 185 | from_crate_id, |
@@ -215,7 +217,9 @@ impl ProjectWorkspace { | |||
215 | if let (Some(&from), Some(&to)) = | 217 | if let (Some(&from), Some(&to)) = |
216 | (sysroot_crates.get(&from), sysroot_crates.get(&to)) | 218 | (sysroot_crates.get(&from), sysroot_crates.get(&to)) |
217 | { | 219 | { |
218 | if let Err(_) = crate_graph.add_dep(from, name.into(), to) { | 220 | if let Err(_) = |
221 | crate_graph.add_dep(from, CrateName::new(name).unwrap(), to) | ||
222 | { | ||
219 | log::error!("cyclic dependency between sysroot crates") | 223 | log::error!("cyclic dependency between sysroot crates") |
220 | } | 224 | } |
221 | } | 225 | } |
@@ -257,7 +261,7 @@ impl ProjectWorkspace { | |||
257 | if let Some(proc_macro) = libproc_macro { | 261 | if let Some(proc_macro) = libproc_macro { |
258 | if let Err(_) = crate_graph.add_dep( | 262 | if let Err(_) = crate_graph.add_dep( |
259 | crate_id, | 263 | crate_id, |
260 | "proc_macro".into(), | 264 | CrateName::new("proc_macro").unwrap(), |
261 | proc_macro, | 265 | proc_macro, |
262 | ) { | 266 | ) { |
263 | log::error!( | 267 | log::error!( |
@@ -276,9 +280,14 @@ impl ProjectWorkspace { | |||
276 | for &from in pkg_crates.get(&pkg).into_iter().flatten() { | 280 | for &from in pkg_crates.get(&pkg).into_iter().flatten() { |
277 | if let Some(to) = lib_tgt { | 281 | if let Some(to) = lib_tgt { |
278 | if to != from { | 282 | if to != from { |
279 | if let Err(_) = | 283 | if let Err(_) = crate_graph.add_dep( |
280 | crate_graph.add_dep(from, pkg.name(&cargo).into(), to) | 284 | from, |
281 | { | 285 | // For root projects with dashes in their name, |
286 | // cargo metadata does not do any normalization, | ||
287 | // so we do it ourselves currently | ||
288 | CrateName::normalize_dashes(pkg.name(&cargo)), | ||
289 | to, | ||
290 | ) { | ||
282 | log::error!( | 291 | log::error!( |
283 | "cyclic dependency between targets of {}", | 292 | "cyclic dependency between targets of {}", |
284 | pkg.name(&cargo) | 293 | pkg.name(&cargo) |
@@ -289,17 +298,23 @@ impl ProjectWorkspace { | |||
289 | // core is added as a dependency before std in order to | 298 | // core is added as a dependency before std in order to |
290 | // mimic rustcs dependency order | 299 | // mimic rustcs dependency order |
291 | if let Some(core) = libcore { | 300 | if let Some(core) = libcore { |
292 | if let Err(_) = crate_graph.add_dep(from, "core".into(), core) { | 301 | if let Err(_) = |
302 | crate_graph.add_dep(from, CrateName::new("core").unwrap(), core) | ||
303 | { | ||
293 | log::error!("cyclic dependency on core for {}", pkg.name(&cargo)) | 304 | log::error!("cyclic dependency on core for {}", pkg.name(&cargo)) |
294 | } | 305 | } |
295 | } | 306 | } |
296 | if let Some(alloc) = liballoc { | 307 | if let Some(alloc) = liballoc { |
297 | if let Err(_) = crate_graph.add_dep(from, "alloc".into(), alloc) { | 308 | if let Err(_) = |
309 | crate_graph.add_dep(from, CrateName::new("alloc").unwrap(), alloc) | ||
310 | { | ||
298 | log::error!("cyclic dependency on alloc for {}", pkg.name(&cargo)) | 311 | log::error!("cyclic dependency on alloc for {}", pkg.name(&cargo)) |
299 | } | 312 | } |
300 | } | 313 | } |
301 | if let Some(std) = libstd { | 314 | if let Some(std) = libstd { |
302 | if let Err(_) = crate_graph.add_dep(from, "std".into(), std) { | 315 | if let Err(_) = |
316 | crate_graph.add_dep(from, CrateName::new("std").unwrap(), std) | ||
317 | { | ||
303 | log::error!("cyclic dependency on std for {}", pkg.name(&cargo)) | 318 | log::error!("cyclic dependency on std for {}", pkg.name(&cargo)) |
304 | } | 319 | } |
305 | } | 320 | } |
@@ -312,9 +327,11 @@ impl ProjectWorkspace { | |||
312 | for dep in pkg.dependencies(&cargo) { | 327 | for dep in pkg.dependencies(&cargo) { |
313 | if let Some(&to) = pkg_to_lib_crate.get(&dep.pkg) { | 328 | if let Some(&to) = pkg_to_lib_crate.get(&dep.pkg) { |
314 | for &from in pkg_crates.get(&pkg).into_iter().flatten() { | 329 | for &from in pkg_crates.get(&pkg).into_iter().flatten() { |
315 | if let Err(_) = | 330 | if let Err(_) = crate_graph.add_dep( |
316 | crate_graph.add_dep(from, dep.name.clone().into(), to) | 331 | from, |
317 | { | 332 | CrateName::new(&dep.name).unwrap(), |
333 | to, | ||
334 | ) { | ||
318 | log::error!( | 335 | log::error!( |
319 | "cyclic dependency {} -> {}", | 336 | "cyclic dependency {} -> {}", |
320 | pkg.name(&cargo), | 337 | pkg.name(&cargo), |