not visit the same crateId only once

This commit is contained in:
gfreezy 2018-12-22 15:30:58 +08:00
parent 66d15bb2da
commit 0267df3815

View file

@ -12,6 +12,7 @@ use rustc_hash::FxHashMap;
use salsa; use salsa;
use ra_syntax::SmolStr; use ra_syntax::SmolStr;
use rustc_hash::FxHashSet;
/// `FileId` is an integer which uniquely identifies a file. File paths are /// `FileId` is an integer which uniquely identifies a file. File paths are
/// messy and system-dependent, so most of the code should work directly with /// messy and system-dependent, so most of the code should work directly with
@ -94,7 +95,8 @@ impl CrateGraph {
crate_id crate_id
} }
pub fn add_dep(&mut self, from: CrateId, name: SmolStr, to: CrateId) { pub fn add_dep(&mut self, from: CrateId, name: SmolStr, to: CrateId) {
if self.dfs_find(from, to) { let mut visited = FxHashSet::default();
if self.dfs_find(from, to, &mut visited) {
panic!("Cycle dependencies found.") panic!("Cycle dependencies found.")
} }
self.arena.get_mut(&from).unwrap().add_dep(name, to) self.arena.get_mut(&from).unwrap().add_dep(name, to)
@ -115,32 +117,33 @@ impl CrateGraph {
) -> impl Iterator<Item = &'a Dependency> + 'a { ) -> impl Iterator<Item = &'a Dependency> + 'a {
self.arena[&crate_id].dependencies.iter() self.arena[&crate_id].dependencies.iter()
} }
fn dfs_find(&self, target: CrateId, from: CrateId) -> bool { fn dfs_find(&self, target: CrateId, from: CrateId, visited: &mut FxHashSet<CrateId>) -> bool {
if visited.contains(&from) {
return false;
}
for dep in self.dependencies(from) { for dep in self.dependencies(from) {
let crate_id = dep.crate_id(); let crate_id = dep.crate_id();
if crate_id == target { if crate_id == target {
return true; return true;
} }
if self.arena.contains_key(&crate_id) {
if self.dfs_find(target, crate_id) { if self.dfs_find(target, crate_id, visited) {
return true; return true;
} }
} }
} visited.insert(from);
return false; return false;
} }
} }
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::{CrateGraph, FxHashMap, FileId, SmolStr}; use super::{CrateGraph, FxHashMap, FileId, SmolStr};
#[test] #[test]
#[should_panic] #[should_panic]
fn it_should_painc_because_of_cycle_dependencies() { fn it_should_painc_because_of_cycle_dependencies() {
let mut graph = CrateGraph { let mut graph = CrateGraph::default();
arena: FxHashMap::default()
};
let crate1 = graph.add_crate_root(FileId(1u32)); let crate1 = graph.add_crate_root(FileId(1u32));
let crate2 = graph.add_crate_root(FileId(2u32)); let crate2 = graph.add_crate_root(FileId(2u32));
let crate3 = graph.add_crate_root(FileId(3u32)); let crate3 = graph.add_crate_root(FileId(3u32));
@ -152,7 +155,7 @@ mod tests {
#[test] #[test]
fn it_works() { fn it_works() {
let mut graph = CrateGraph { let mut graph = CrateGraph {
arena: FxHashMap::default() arena: FxHashMap::default(),
}; };
let crate1 = graph.add_crate_root(FileId(1u32)); let crate1 = graph.add_crate_root(FileId(1u32));
let crate2 = graph.add_crate_root(FileId(2u32)); let crate2 = graph.add_crate_root(FileId(2u32));
@ -162,7 +165,6 @@ mod tests {
} }
} }
salsa::query_group! { salsa::query_group! {
pub trait FilesDatabase: salsa::Database { pub trait FilesDatabase: salsa::Database {
/// Text of the file. /// Text of the file.