Skip to content

Commit fecc411

Browse files
committed
fix include merging for when a file imports another file more than once directly
1 parent 1529460 commit fecc411

File tree

10 files changed

+530
-384
lines changed

10 files changed

+530
-384
lines changed

server/main/src/commands/merged_includes.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ impl VirtualMergedDocument {
5151

5252
for node in nodes {
5353
let graph = self.graph.borrow();
54-
let path = graph.get_node(node.0);
54+
let path = graph.get_node(node.child);
5555

5656
if sources.contains_key(&path) {
5757
continue;
@@ -103,7 +103,7 @@ impl Invokeable for VirtualMergedDocument {
103103

104104
let mut source_mapper = SourceMapper::new(all_sources.len());
105105
let graph = self.graph.borrow();
106-
let view = merge_views::generate_merge_list(&tree, &all_sources, &graph, &mut source_mapper);
106+
let view = merge_views::MergeViewBuilder::new(&tree, &all_sources, &graph, &mut source_mapper).build();
107107
return Ok(serde_json::value::Value::String(view));
108108
}
109109
return Err(format_err!(

server/main/src/dfs.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -56,21 +56,21 @@ impl<'a> Iterator for Dfs<'a> {
5656
fn next(&mut self) -> Option<Result<FilialTuple, error::CycleError>> {
5757
let parent = self.cycle.last().map(|p| p.node);
5858

59-
if let Some(node) = self.stack.pop() {
59+
if let Some(child) = self.stack.pop() {
6060
self.cycle.push(VisitCount {
61-
node,
62-
children: self.graph.graph.edges(node).count(),
61+
node: child,
62+
children: self.graph.graph.edges(child).count(),
6363
touch: 1,
6464
});
6565

66-
let mut children = self.graph.child_node_indexes(node);
66+
let mut children: Vec<NodeIndex> = self.graph.child_node_indexes(child).collect();
6767

6868
if !children.is_empty() {
6969
// sort by line number in parent
7070
children.sort_by(|x, y| {
7171
let graph = &self.graph.graph;
72-
let edge1 = graph.edge_weight(graph.find_edge(node, *x).unwrap()).unwrap();
73-
let edge2 = graph.edge_weight(graph.find_edge(node, *y).unwrap()).unwrap();
72+
let edge1 = graph.edge_weight(graph.find_edge(child, *x).unwrap()).unwrap();
73+
let edge2 = graph.edge_weight(graph.find_edge(child, *y).unwrap()).unwrap();
7474

7575
edge2.line.cmp(&edge1.line)
7676
});
@@ -87,7 +87,7 @@ impl<'a> Iterator for Dfs<'a> {
8787
self.reset_path_to_branch();
8888
}
8989

90-
return Some(Ok((node, parent)));
90+
return Some(Ok(FilialTuple { child, parent }));
9191
}
9292
None
9393
}
@@ -189,8 +189,8 @@ mod dfs_test {
189189
collection.push(i.unwrap());
190190
}
191191

192-
let nodes: Vec<NodeIndex> = collection.iter().map(|n| n.0).collect();
193-
let parents: Vec<Option<NodeIndex>> = collection.iter().map(|n| n.1).collect();
192+
let nodes: Vec<NodeIndex> = collection.iter().map(|n| n.child).collect();
193+
let parents: Vec<Option<NodeIndex>> = collection.iter().map(|n| n.parent).collect();
194194
// 0
195195
// / \
196196
// 1 2
@@ -237,8 +237,8 @@ mod dfs_test {
237237
collection.push(i.unwrap());
238238
}
239239

240-
let nodes: Vec<NodeIndex> = collection.iter().map(|n| n.0).collect();
241-
let parents: Vec<Option<NodeIndex>> = collection.iter().map(|n| n.1).collect();
240+
let nodes: Vec<NodeIndex> = collection.iter().map(|n| n.child).collect();
241+
let parents: Vec<Option<NodeIndex>> = collection.iter().map(|n| n.parent).collect();
242242
// 0
243243
// / \
244244
// 1 2

server/main/src/graph.rs

Lines changed: 88 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use petgraph::stable_graph::EdgeIndex;
22
use petgraph::stable_graph::NodeIndex;
33
use petgraph::stable_graph::StableDiGraph;
4+
use petgraph::visit::EdgeRef;
45
use petgraph::Direction;
56

67
use std::{
@@ -53,20 +54,27 @@ impl CachedStableGraph {
5354
}
5455
}
5556

57+
// Returns the `PathBuf` for a given `NodeIndex`
5658
pub fn get_node(&self, node: NodeIndex) -> PathBuf {
5759
PathBuf::from_str(&self.graph[node]).unwrap()
5860
}
5961

60-
pub fn get_edge_meta(&self, parent: NodeIndex, child: NodeIndex) -> &IncludePosition {
61-
self.graph.edge_weight(self.graph.find_edge(parent, child).unwrap()).unwrap()
62-
}
63-
64-
#[allow(dead_code)]
65-
pub fn remove_node(&mut self, name: &Path) {
66-
let idx = self.cache.remove(name);
67-
if let Some(idx) = idx {
68-
self.graph.remove_node(idx);
69-
}
62+
/// returns an iterator over all the `IncludePosition`'s between a parent and its child for all the positions
63+
/// that the child may be imported into the parent, in order of import.
64+
pub fn get_edge_metas(&self, parent: NodeIndex, child: NodeIndex) -> impl Iterator<Item = IncludePosition> + '_ {
65+
let mut edges = self
66+
.graph
67+
.edges(parent)
68+
.filter_map(move |edge| {
69+
let target = self.graph.edge_endpoints(edge.id()).unwrap().1;
70+
if target != child {
71+
return None;
72+
}
73+
Some(self.graph[edge.id()])
74+
})
75+
.collect::<Vec<IncludePosition>>();
76+
edges.sort_by(|x, y| x.line.cmp(&y.line));
77+
edges.into_iter()
7078
}
7179

7280
pub fn add_node(&mut self, name: &Path) -> NodeIndex {
@@ -83,61 +91,36 @@ impl CachedStableGraph {
8391
self.graph.add_edge(parent, child, meta)
8492
}
8593

86-
pub fn remove_edge(&mut self, parent: NodeIndex, child: NodeIndex) {
87-
let edge = self.graph.find_edge(parent, child).unwrap();
88-
self.graph.remove_edge(edge);
89-
}
90-
91-
#[allow(dead_code)]
92-
pub fn edge_weights(&self, node: NodeIndex) -> Vec<IncludePosition> {
93-
self.graph.edges(node).map(|e| e.weight().clone()).collect()
94-
}
95-
96-
#[allow(dead_code)]
97-
pub fn child_node_names(&self, node: NodeIndex) -> Vec<PathBuf> {
98-
self.graph
99-
.neighbors(node)
100-
.map(|n| self.reverse_index.get(&n).unwrap().clone())
101-
.collect()
102-
}
103-
104-
pub fn child_node_meta(&self, node: NodeIndex) -> Vec<(PathBuf, IncludePosition)> {
94+
pub fn remove_edge(&mut self, parent: NodeIndex, child: NodeIndex, position: IncludePosition) {
10595
self.graph
106-
.neighbors(node)
107-
.map(|n| {
108-
let edge = self.graph.find_edge(node, n).unwrap();
109-
let edge_meta = self.graph.edge_weight(edge).unwrap();
110-
return (self.reverse_index.get(&n).unwrap().clone(), edge_meta.clone());
111-
})
112-
.collect()
96+
.edges(parent)
97+
.find(|edge| self.graph.edge_endpoints(edge.id()).unwrap().1 == child && *edge.weight() == position)
98+
.map(|edge| edge.id())
99+
.and_then(|edge| self.graph.remove_edge(edge));
113100
}
114101

115-
pub fn child_node_indexes(&self, node: NodeIndex) -> Vec<NodeIndex> {
116-
self.graph.neighbors(node).collect()
102+
pub fn child_node_metas(&self, node: NodeIndex) -> impl Iterator<Item = (PathBuf, IncludePosition)> + '_ {
103+
self.graph.neighbors(node).map(move |n| {
104+
let edge = self.graph.find_edge(node, n).unwrap();
105+
let edge_meta = self.graph.edge_weight(edge).unwrap();
106+
return (self.reverse_index.get(&n).unwrap().clone(), *edge_meta);
107+
})
117108
}
118109

119-
#[allow(dead_code)]
120-
pub fn parent_node_names(&self, node: NodeIndex) -> Vec<PathBuf> {
121-
self.graph
122-
.neighbors_directed(node, Direction::Incoming)
123-
.map(|n| self.reverse_index.get(&n).unwrap().clone())
124-
.collect()
125-
}
126-
127-
pub fn parent_node_indexes(&self, node: NodeIndex) -> Vec<NodeIndex> {
128-
self.graph.neighbors_directed(node, Direction::Incoming).collect()
129-
}
130-
131-
#[allow(dead_code)]
132-
pub fn get_include_meta(&self, node: NodeIndex) -> Vec<IncludePosition> {
133-
self.graph.edges(node).map(|e| e.weight().clone()).collect()
110+
pub fn child_node_indexes(&self, node: NodeIndex) -> impl Iterator<Item = NodeIndex> + '_ {
111+
self.graph.neighbors(node)
134112
}
135113

136114
pub fn collect_root_ancestors(&self, node: NodeIndex) -> Vec<NodeIndex> {
137115
let mut visited = HashSet::new();
138116
self.get_root_ancestors(node, node, &mut visited)
139117
}
140118

119+
// TODO: impl Iterator
120+
fn parent_node_indexes(&self, node: NodeIndex) -> Vec<NodeIndex> {
121+
self.graph.neighbors_directed(node, Direction::Incoming).collect()
122+
}
123+
141124
fn get_root_ancestors(&self, initial: NodeIndex, node: NodeIndex, visited: &mut HashSet<NodeIndex>) -> Vec<NodeIndex> {
142125
if node == initial && !visited.is_empty() {
143126
return vec![];
@@ -163,10 +146,36 @@ impl CachedStableGraph {
163146
}
164147
}
165148

149+
#[cfg(test)]
150+
impl CachedStableGraph {
151+
fn parent_node_names(&self, node: NodeIndex) -> Vec<PathBuf> {
152+
self.graph
153+
.neighbors_directed(node, Direction::Incoming)
154+
.map(|n| self.reverse_index.get(&n).unwrap().clone())
155+
.collect()
156+
}
157+
158+
fn child_node_names(&self, node: NodeIndex) -> Vec<PathBuf> {
159+
self.graph
160+
.neighbors(node)
161+
.map(|n| self.reverse_index.get(&n).unwrap().clone())
162+
.collect()
163+
}
164+
165+
fn remove_node(&mut self, name: &Path) {
166+
let idx = self.cache.remove(name);
167+
if let Some(idx) = idx {
168+
self.graph.remove_node(idx);
169+
}
170+
}
171+
}
172+
166173
#[cfg(test)]
167174
mod graph_test {
168175
use std::path::PathBuf;
169176

177+
use petgraph::graph::NodeIndex;
178+
170179
use crate::{graph::CachedStableGraph, IncludePosition};
171180

172181
#[test]
@@ -182,7 +191,7 @@ mod graph_test {
182191
assert_eq!(children.len(), 1);
183192
assert_eq!(children[0], Into::<PathBuf>::into("banana".to_string()));
184193

185-
let children = graph.child_node_indexes(idx1);
194+
let children: Vec<NodeIndex> = graph.child_node_indexes(idx1).collect();
186195
assert_eq!(children.len(), 1);
187196
assert_eq!(children[0], idx2);
188197

@@ -207,10 +216,33 @@ mod graph_test {
207216
graph.remove_node(&PathBuf::from("sample"));
208217
assert_eq!(graph.graph.node_count(), 1);
209218
assert!(graph.find_node(&PathBuf::from("sample")).is_none());
219+
210220
let neighbors = graph.child_node_names(idx2);
211221
assert_eq!(neighbors.len(), 0);
212222
}
213223

224+
#[test]
225+
#[logging_macro::log_scope]
226+
fn test_double_import() {
227+
let mut graph = CachedStableGraph::new();
228+
229+
let idx0 = graph.add_node(&PathBuf::from("0"));
230+
let idx1 = graph.add_node(&PathBuf::from("1"));
231+
232+
graph.add_edge(idx0, idx1, IncludePosition { line: 2, start: 0, end: 0 });
233+
graph.add_edge(idx0, idx1, IncludePosition { line: 4, start: 0, end: 0 });
234+
235+
// 0
236+
// / \
237+
// 1 1
238+
239+
assert_eq!(2, graph.get_edge_metas(idx0, idx1).count());
240+
241+
let mut edge_metas = graph.get_edge_metas(idx0, idx1);
242+
assert_eq!(Some(IncludePosition { line: 2, start: 0, end: 0 }), edge_metas.next());
243+
assert_eq!(Some(IncludePosition { line: 4, start: 0, end: 0 }), edge_metas.next());
244+
}
245+
214246
#[test]
215247
#[logging_macro::log_scope]
216248
fn test_collect_root_ancestors() {
@@ -287,10 +319,8 @@ mod graph_test {
287319
graph.add_edge(idx1, idx3, IncludePosition { line: 5, start: 0, end: 0 });
288320

289321
// 0
290-
// |
291-
// 1
292-
// \
293-
// 2 \
322+
// \
323+
// 2 1
294324
// \ /
295325
// 3
296326

0 commit comments

Comments
 (0)