Skip to content

Commit 3b568ea

Browse files
committed
fix dfs iterator when same file imported multiple times into another
1 parent 27d1d7b commit 3b568ea

File tree

4 files changed

+64
-82
lines changed

4 files changed

+64
-82
lines changed

server/main/src/dfs.rs

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -63,25 +63,22 @@ impl<'a> Iterator for Dfs<'a> {
6363
touch: 1,
6464
});
6565

66-
let mut children: Vec<NodeIndex> = self.graph.child_node_indexes(child).collect();
66+
let mut children: Vec<_> = self
67+
.graph
68+
.get_all_child_positions(child)
69+
.collect();
70+
children.reverse();
6771

6872
if !children.is_empty() {
69-
// sort by line number in parent
70-
children.sort_by(|x, y| {
71-
let graph = &self.graph.graph;
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();
7473

75-
edge2.line.cmp(&edge1.line)
76-
});
77-
78-
match self.check_for_cycle(&children) {
74+
let child_indexes: Vec<_> = children.iter().map(|c| c.0).collect();
75+
match self.check_for_cycle(&child_indexes) {
7976
Ok(_) => {}
8077
Err(e) => return Some(Err(e)),
8178
};
8279

8380
for child in children {
84-
self.stack.push(child);
81+
self.stack.push(child.0);
8582
}
8683
} else {
8784
self.reset_path_to_branch();
@@ -314,10 +311,10 @@ mod dfs_test {
314311
// \ / \
315312
// 6 - 7
316313

317-
assert!(is_cyclic_directed(&graph.graph));
318-
319314
let next = dfs.next().unwrap();
320315
assert_that!(next, err());
316+
317+
assert!(is_cyclic_directed(&graph.graph));
321318
}
322319
{
323320
let mut graph = CachedStableGraph::new();

server/main/src/graph.rs

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,9 @@ impl CachedStableGraph {
5959
PathBuf::from_str(&self.graph[node]).unwrap()
6060
}
6161

62-
/// returns an iterator over all the `IncludePosition`'s between a parent and its child for all the positions
62+
/// Returns an iterator over all the `IncludePosition`'s between a parent and its child for all the positions
6363
/// 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> + '_ {
64+
pub fn get_child_positions(&self, parent: NodeIndex, child: NodeIndex) -> impl Iterator<Item = IncludePosition> + '_ {
6565
let mut edges = self
6666
.graph
6767
.edges(parent)
@@ -77,6 +77,18 @@ impl CachedStableGraph {
7777
edges.into_iter()
7878
}
7979

80+
/// Returns an iterator over all the `(NodeIndex, IncludePosition)` tuples between a node and all its children, in order
81+
/// of import.
82+
pub fn get_all_child_positions(&self, node: NodeIndex) -> impl Iterator<Item = (NodeIndex, IncludePosition)> + '_ {
83+
let mut edges = self.graph.edges(node).map(|edge| {
84+
let child = self.graph.edge_endpoints(edge.id()).unwrap().1;
85+
(child, self.graph[edge.id()])
86+
})
87+
.collect::<Vec<_>>();
88+
edges.sort_by(|x, y| x.1.line.cmp(&y.1.line));
89+
edges.into_iter()
90+
}
91+
8092
pub fn add_node(&mut self, name: &Path) -> NodeIndex {
8193
if let Some(idx) = self.cache.get(name) {
8294
return *idx;
@@ -99,14 +111,6 @@ impl CachedStableGraph {
99111
.and_then(|edge| self.graph.remove_edge(edge));
100112
}
101113

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-
})
108-
}
109-
110114
pub fn child_node_indexes(&self, node: NodeIndex) -> impl Iterator<Item = NodeIndex> + '_ {
111115
self.graph.neighbors(node)
112116
}
@@ -236,9 +240,9 @@ mod graph_test {
236240
// / \
237241
// 1 1
238242

239-
assert_eq!(2, graph.get_edge_metas(idx0, idx1).count());
243+
assert_eq!(2, graph.get_child_positions(idx0, idx1).count());
240244

241-
let mut edge_metas = graph.get_edge_metas(idx0, idx1);
245+
let mut edge_metas = graph.get_child_positions(idx0, idx1);
242246
assert_eq!(Some(IncludePosition { line: 2, start: 0, end: 0 }), edge_metas.next());
243247
assert_eq!(Some(IncludePosition { line: 4, start: 0, end: 0 }), edge_metas.next());
244248
}

server/main/src/main.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,9 @@ impl MinecraftShaderLanguageServer {
251251
Some(n) => n,
252252
};
253253

254-
let prev_children: HashSet<_> = HashSet::from_iter(self.graph.borrow().child_node_metas(idx));
254+
let prev_children: HashSet<_> = HashSet::from_iter(self.graph.borrow().get_all_child_positions(idx).map(|tup| {
255+
(self.graph.borrow().get_node(tup.0), tup.1)
256+
}));
255257
let new_children: HashSet<_> = includes.iter().cloned().collect();
256258

257259
let to_be_added = new_children.difference(&prev_children);
@@ -825,7 +827,7 @@ impl LanguageServerHandling for MinecraftShaderLanguageServer {
825827
.child_node_indexes(node)
826828
.filter_map::<Vec<DocumentLink>, _>(|child| {
827829
let graph = self.graph.borrow();
828-
graph.get_edge_metas(node, child).map(|value| {
830+
graph.get_child_positions(node, child).map(|value| {
829831
let path = graph.get_node(child);
830832
let url = match Url::from_file_path(&path) {
831833
Ok(url) => url,

server/main/src/merge_views.rs

Lines changed: 34 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use std::{
88
use core::slice::Iter;
99

1010
use petgraph::stable_graph::NodeIndex;
11+
use slog_scope::debug;
1112

1213
use crate::graph::CachedStableGraph;
1314
use crate::source_mapper::SourceMapper;
@@ -88,27 +89,16 @@ impl<'a> MergeViewBuilder<'a> {
8889
// );
8990

9091
// last_offset_set.insert((first, None), version_char_offsets.1);
91-
self.last_offset_set.insert(
92-
FilialTuple {
93-
child: first,
94-
parent: None,
95-
},
96-
0,
97-
);
92+
self.set_last_offset_for_tuple(None, first, 0);
9893

9994
// stack to keep track of the depth first traversal
10095
let mut stack = VecDeque::<NodeIndex>::new();
10196

10297
self.create_merge_views(&mut merge_list, &mut extra_lines, &mut stack);
10398

10499
// now we add a view of the remainder of the root file
105-
let offset = *self
106-
.last_offset_set
107-
.get(&FilialTuple {
108-
child: first,
109-
parent: None,
110-
})
111-
.unwrap();
100+
101+
let offset = self.get_last_offset_for_tuple(None, first).unwrap();
112102

113103
let len = first_source.len();
114104
merge_list.push_back(&first_source[min(offset, len)..]);
@@ -135,8 +125,8 @@ impl<'a> MergeViewBuilder<'a> {
135125
.parent_child_edge_iterator
136126
.entry(*n)
137127
.or_insert_with(|| {
138-
let edge_metas = self.graph.get_edge_metas(parent, child);
139-
Box::new(edge_metas)
128+
let child_positions = self.graph.get_child_positions(parent, child);
129+
Box::new(child_positions)
140130
})
141131
.next()
142132
.unwrap();
@@ -147,15 +137,16 @@ impl<'a> MergeViewBuilder<'a> {
147137
let (char_for_line, char_following_line) = self.char_offset_for_line(edge.line, parent_source);
148138

149139
let offset = *self
150-
.last_offset_set
151-
.insert(
152-
FilialTuple {
153-
child: parent,
154-
parent: stack.back().copied(),
155-
},
156-
char_following_line,
157-
)
140+
.set_last_offset_for_tuple(stack.back().copied(), parent, char_following_line)
158141
.get_or_insert(0);
142+
143+
debug!("creating view to start child file";
144+
"parent" => parent_path.to_str().unwrap(), "child" => child_path.to_str().unwrap(),
145+
"grandparent" => stack.back().copied().map(|g| self.graph.get_node(g).to_str().unwrap().to_string()), // self.graph.get_node().to_str().unwrap(),
146+
"last_parent_offset" => offset, "line" => edge.line, "char_for_line" => char_for_line,
147+
"char_following_line" => char_following_line,
148+
);
149+
159150
merge_list.push_back(&parent_source[offset..char_for_line]);
160151
self.add_opening_line_directive(&child_path, child, merge_list, extra_lines);
161152

@@ -173,13 +164,7 @@ impl<'a> MergeViewBuilder<'a> {
173164
}
174165
};
175166
merge_list.push_back(&child_source[..offset]);
176-
self.last_offset_set.insert(
177-
FilialTuple {
178-
child,
179-
parent: Some(parent),
180-
},
181-
0,
182-
);
167+
self.set_last_offset_for_tuple(Some(parent), child, 0);
183168
// +2 because edge.line is 0 indexed but #line is 1 indexed and references the *following* line
184169
self.add_closing_line_directive(edge.line + 2, &parent_path, parent, merge_list, extra_lines);
185170
// if the next pair's parent is not the current pair's parent, we need to bubble up
@@ -193,29 +178,17 @@ impl<'a> MergeViewBuilder<'a> {
193178
self.create_merge_views(merge_list, extra_lines, stack);
194179
stack.pop_back();
195180

196-
let offset = *self
197-
.last_offset_set
198-
.get(&FilialTuple {
199-
child,
200-
parent: Some(parent),
201-
})
202-
.unwrap();
181+
let offset = self.get_last_offset_for_tuple(Some(parent), child).unwrap();
203182
let child_source = self.sources.get(&child_path).unwrap();
204183
// this evaluates to false once the file contents have been exhausted aka offset = child_source.len() + 1
205184
let end_offset = match child_source.ends_with('\n') {
206-
true => 1, /* child_source.len()-1 */
207-
false => 0, /* child_source.len() */
185+
true => 1,
186+
false => 0,
208187
};
209188
if offset < child_source.len() - end_offset {
210189
// if ends in \n\n, we want to exclude the last \n for some reason. Ask optilad
211-
merge_list.push_back(&child_source[offset../* std::cmp::max( */child_source.len()-end_offset/* , offset) */]);
212-
self.last_offset_set.insert(
213-
FilialTuple {
214-
child,
215-
parent: Some(parent),
216-
},
217-
0,
218-
);
190+
merge_list.push_back(&child_source[offset..child_source.len() - end_offset]);
191+
self.set_last_offset_for_tuple(Some(parent), child, 0);
219192
}
220193

221194
// +2 because edge.line is 0 indexed but #line is 1 indexed and references the *following* line
@@ -234,20 +207,26 @@ impl<'a> MergeViewBuilder<'a> {
234207
false => child_source.len(),
235208
};
236209
merge_list.push_back(&child_source[..offset]);
237-
self.last_offset_set.insert(
238-
FilialTuple {
239-
child,
240-
parent: Some(parent),
241-
},
242-
0,
243-
);
210+
self.set_last_offset_for_tuple(Some(parent), child, 0);
244211
// +2 because edge.line is 0 indexed but #line is 1 indexed and references the *following* line
245212
self.add_closing_line_directive(edge.line + 2, &parent_path, parent, merge_list, extra_lines);
246213
}
247214
}
248215
}
249216
}
250217

218+
fn set_last_offset_for_tuple(&mut self, parent: Option<NodeIndex>, child: NodeIndex, offset: usize) -> Option<usize> {
219+
debug!("inserting last offset";
220+
"parent" => parent.map(|p| self.graph.get_node(p).to_str().unwrap().to_string()),
221+
"child" => self.graph.get_node(child).to_str().unwrap().to_string(),
222+
"offset" => offset);
223+
self.last_offset_set.insert(FilialTuple { child, parent }, offset)
224+
}
225+
226+
fn get_last_offset_for_tuple(&self, parent: Option<NodeIndex>, child: NodeIndex) -> Option<usize> {
227+
self.last_offset_set.get(&FilialTuple { child, parent }).copied()
228+
}
229+
251230
// returns the character offset + 1 of the end of line number `line` and the character
252231
// offset + 1 for the end of the line after the previous one
253232
fn char_offset_for_line(&self, line_num: usize, source: &str) -> (usize, usize) {

0 commit comments

Comments
 (0)