blob: 01cbcba61493614d239612e251ce4c840f326c53 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
|
use crate::*;
use std::collections::HashSet;
pub struct MergeError<'a> {
pub resolver: &'a Resolver,
/// A list of source units involved in a cycle.
pub cyclic_unit_ids: Vec<usize>,
}
impl MergeError<'_> {
pub fn report(&self) {
let message = "A cyclic dependency was found between the following files:";
let mut details = InkedString::new();
for id in &self.cyclic_unit_ids {
let unit = &self.resolver.source_units[*id];
let path = &unit.source_unit.path();
match unit.source_unit.name() {
Some(name) => {
details.push(ink!("{name}"));
details.push(ink!(" ({path})\n").dim());
}
None => {
details.push(ink!("{path}\n"));
}
};
// Print each parent involved in the dependency cycle.
for parent_id in &unit.parent_ids {
if !self.cyclic_unit_ids.contains(parent_id) { continue; }
let parent_unit = &self.resolver.source_units[*parent_id];
let parent_path = &parent_unit.source_unit.path();
match parent_unit.source_unit.name() {
Some(parent_name) => {
details.push(ink!(" => {parent_name}"));
details.push(ink!(" ({parent_path})\n").dim());
}
None => {
details.push(ink!(" => {parent_path}\n"));
}
};
// Report all referenced symbols that are defined by this parent.
let mut reported_definition_ids = HashSet::new();
for reference in &self.resolver.resolved {
if reference.tracked.source_id == *id {
if reported_definition_ids.insert(reference.definition) {
let definition = &self.resolver.definitions[reference.definition];
if definition.tracked.source_id == *parent_id {
details.push(ink!(" {:?}\n", definition.tracked.symbol));
}
}
}
}
}
}
log_error(message, Some(details));
}
}
|