Pass syntax_ids through

syntax_id
Wilfred Hughes 2023-08-16 15:25:16 +07:00
parent 18b96ebdab
commit 6e7518e680
4 changed files with 89 additions and 13 deletions

@ -7,7 +7,7 @@ use crate::{
diff::changes::ChangeMap,
diff::graph::{populate_change_map, set_neighbours, Edge, Vertex},
hash::DftHashMap,
parse::syntax::Syntax,
parse::syntax::{Syntax, SyntaxId},
};
use bumpalo::Bump;
use itertools::Itertools;
@ -19,6 +19,7 @@ pub struct ExceededGraphLimit {}
/// Return the shortest route from `start` to the end vertex.
fn shortest_vertex_path<'s, 'b>(
start: &'b Vertex<'s, 'b>,
syntax_ids: &DftHashMap<SyntaxId, &'s Syntax<'s>>,
vertex_arena: &'b Bump,
size_hint: usize,
graph_limit: usize,
@ -40,7 +41,7 @@ fn shortest_vertex_path<'s, 'b>(
break current;
}
set_neighbours(current, vertex_arena, &mut seen);
set_neighbours(current, vertex_arena, syntax_ids, &mut seen);
for neighbour in current.neighbours.borrow().as_ref().unwrap() {
let (edge, next) = neighbour;
let distance_to_next = distance + edge.cost();
@ -113,12 +114,14 @@ fn shortest_path_with_edges<'s, 'b>(
/// necessary because a route of N vertices only has N-1 edges.
fn shortest_path<'s, 'b>(
start: Vertex<'s, 'b>,
syntax_ids: &DftHashMap<SyntaxId, &'s Syntax<'s>>,
vertex_arena: &'b Bump,
size_hint: usize,
graph_limit: usize,
) -> Result<Vec<(Edge, &'b Vertex<'s, 'b>)>, ExceededGraphLimit> {
let start: &'b Vertex<'s, 'b> = vertex_arena.alloc(start);
let vertex_path = shortest_vertex_path(start, vertex_arena, size_hint, graph_limit)?;
let vertex_path =
shortest_vertex_path(start, syntax_ids, vertex_arena, size_hint, graph_limit)?;
Ok(shortest_path_with_edges(&vertex_path))
}
@ -188,6 +191,7 @@ fn tree_count(root: Option<&Syntax>) -> u32 {
pub fn mark_syntax<'a>(
lhs_syntax: Option<&'a Syntax<'a>>,
rhs_syntax: Option<&'a Syntax<'a>>,
syntax_ids: &DftHashMap<SyntaxId, &'a Syntax<'a>>,
change_map: &mut ChangeMap<'a>,
graph_limit: usize,
) -> Result<(), ExceededGraphLimit> {
@ -215,7 +219,7 @@ pub fn mark_syntax<'a>(
let start = Vertex::new(lhs_syntax, rhs_syntax);
let vertex_arena = Bump::new();
let route = shortest_path(start, &vertex_arena, size_hint, graph_limit)?;
let route = shortest_path(start, syntax_ids, &vertex_arena, size_hint, graph_limit)?;
let print_length = if env::var("DFT_VERBOSE").is_ok() {
50
@ -277,9 +281,12 @@ mod tests {
let rhs = Syntax::new_atom(&arena, pos_helper(0), "foo", AtomKind::Normal);
init_all_info(&[lhs], &[rhs]);
let syntax_ids = crate::parse::syntax::syntax_ids(&[lhs], &[rhs]);
let start = Vertex::new(Some(lhs), Some(rhs));
let vertex_arena = Bump::new();
let route = shortest_path(start, &vertex_arena, 0, DEFAULT_GRAPH_LIMIT).unwrap();
let route =
shortest_path(start, &syntax_ids, &vertex_arena, 0, DEFAULT_GRAPH_LIMIT).unwrap();
let actions = route.iter().map(|(action, _)| *action).collect_vec();
assert_eq!(
@ -319,9 +326,12 @@ mod tests {
)];
init_all_info(&lhs, &rhs);
let syntax_ids = crate::parse::syntax::syntax_ids(&lhs, &rhs);
let start = Vertex::new(lhs.get(0).copied(), rhs.get(0).copied());
let vertex_arena = Bump::new();
let route = shortest_path(start, &vertex_arena, 0, DEFAULT_GRAPH_LIMIT).unwrap();
let route =
shortest_path(start, &syntax_ids, &vertex_arena, 0, DEFAULT_GRAPH_LIMIT).unwrap();
let actions = route.iter().map(|(action, _)| *action).collect_vec();
assert_eq!(
@ -361,9 +371,12 @@ mod tests {
)];
init_all_info(&lhs, &rhs);
let syntax_ids = crate::parse::syntax::syntax_ids(&lhs, &rhs);
let start = Vertex::new(lhs.get(0).copied(), rhs.get(0).copied());
let vertex_arena = Bump::new();
let route = shortest_path(start, &vertex_arena, 0, DEFAULT_GRAPH_LIMIT).unwrap();
let route =
shortest_path(start, &syntax_ids, &vertex_arena, 0, DEFAULT_GRAPH_LIMIT).unwrap();
let actions = route.iter().map(|(action, _)| *action).collect_vec();
assert_eq!(
@ -407,9 +420,12 @@ mod tests {
)];
init_all_info(&lhs, &rhs);
let syntax_ids = crate::parse::syntax::syntax_ids(&lhs, &rhs);
let start = Vertex::new(lhs.get(0).copied(), rhs.get(0).copied());
let vertex_arena = Bump::new();
let route = shortest_path(start, &vertex_arena, 0, DEFAULT_GRAPH_LIMIT).unwrap();
let route =
shortest_path(start, &syntax_ids, &vertex_arena, 0, DEFAULT_GRAPH_LIMIT).unwrap();
let actions = route.iter().map(|(action, _)| *action).collect_vec();
assert_eq!(
@ -448,9 +464,12 @@ mod tests {
)];
init_all_info(&lhs, &rhs);
let syntax_ids = crate::parse::syntax::syntax_ids(&lhs, &rhs);
let start = Vertex::new(lhs.get(0).copied(), rhs.get(0).copied());
let vertex_arena = Bump::new();
let route = shortest_path(start, &vertex_arena, 0, DEFAULT_GRAPH_LIMIT).unwrap();
let route =
shortest_path(start, &syntax_ids, &vertex_arena, 0, DEFAULT_GRAPH_LIMIT).unwrap();
let actions = route.iter().map(|(action, _)| *action).collect_vec();
assert_eq!(
@ -480,9 +499,12 @@ mod tests {
)];
init_all_info(&lhs, &rhs);
let syntax_ids = crate::parse::syntax::syntax_ids(&lhs, &rhs);
let start = Vertex::new(lhs.get(0).copied(), rhs.get(0).copied());
let vertex_arena = Bump::new();
let route = shortest_path(start, &vertex_arena, 0, DEFAULT_GRAPH_LIMIT).unwrap();
let route =
shortest_path(start, &syntax_ids, &vertex_arena, 0, DEFAULT_GRAPH_LIMIT).unwrap();
let actions = route.iter().map(|(action, _)| *action).collect_vec();
assert_eq!(
@ -520,9 +542,12 @@ mod tests {
)];
init_all_info(&lhs, &rhs);
let syntax_ids = crate::parse::syntax::syntax_ids(&lhs, &rhs);
let start = Vertex::new(lhs.get(0).copied(), rhs.get(0).copied());
let vertex_arena = Bump::new();
let route = shortest_path(start, &vertex_arena, 0, DEFAULT_GRAPH_LIMIT).unwrap();
let route =
shortest_path(start, &syntax_ids, &vertex_arena, 0, DEFAULT_GRAPH_LIMIT).unwrap();
let actions = route.iter().map(|(action, _)| *action).collect_vec();
assert_eq!(
@ -543,8 +568,17 @@ mod tests {
let rhs = Syntax::new_atom(&arena, pos_helper(1), "foo", AtomKind::Normal);
init_all_info(&[lhs], &[rhs]);
let syntax_ids = crate::parse::syntax::syntax_ids(&[lhs], &[rhs]);
let mut change_map = ChangeMap::default();
mark_syntax(Some(lhs), Some(rhs), &mut change_map, DEFAULT_GRAPH_LIMIT).unwrap();
mark_syntax(
Some(lhs),
Some(rhs),
&syntax_ids,
&mut change_map,
DEFAULT_GRAPH_LIMIT,
)
.unwrap();
assert_eq!(change_map.get(lhs), Some(ChangeKind::Unchanged(rhs)));
assert_eq!(change_map.get(rhs), Some(ChangeKind::Unchanged(lhs)));
@ -557,8 +591,17 @@ mod tests {
let rhs = Syntax::new_atom(&arena, pos_helper(1), "bar", AtomKind::Normal);
init_all_info(&[lhs], &[rhs]);
let syntax_ids = crate::parse::syntax::syntax_ids(&[lhs], &[rhs]);
let mut change_map = ChangeMap::default();
mark_syntax(Some(lhs), Some(rhs), &mut change_map, DEFAULT_GRAPH_LIMIT).unwrap();
mark_syntax(
Some(lhs),
Some(rhs),
&syntax_ids,
&mut change_map,
DEFAULT_GRAPH_LIMIT,
)
.unwrap();
assert_eq!(change_map.get(lhs), Some(ChangeKind::Novel));
assert_eq!(change_map.get(rhs), Some(ChangeKind::Novel));
}

@ -482,6 +482,7 @@ fn pop_all_parents<'s>(
pub fn set_neighbours<'s, 'b>(
v: &Vertex<'s, 'b>,
alloc: &'b Bump,
syntax_ids: &DftHashMap<SyntaxId, &'s Syntax<'s>>,
seen: &mut DftHashMap<&Vertex<'s, 'b>, Vec<&'b Vertex<'s, 'b>>>,
) {
if v.neighbours.borrow().is_some() {

@ -485,6 +485,8 @@ fn diff_file_content(
diff_options,
) {
Ok((lhs, rhs)) => {
let syntax_ids = syntax::syntax_ids(&lhs, &rhs);
if diff_options.check_only {
let file_format = match language {
Some(language) => FileFormat::SupportedLanguage(language),
@ -522,6 +524,7 @@ fn diff_file_content(
match mark_syntax(
lhs_section_nodes.get(0).copied(),
rhs_section_nodes.get(0).copied(),
&syntax_ids,
&mut change_map,
diff_options.graph_limit,
) {

@ -361,6 +361,35 @@ pub fn init_all_info<'a>(lhs_roots: &[&'a Syntax<'a>], rhs_roots: &[&'a Syntax<'
init_next_prev(rhs_roots);
}
pub fn syntax_ids<'a>(
lhs_roots: &[&'a Syntax<'a>],
rhs_roots: &[&'a Syntax<'a>],
) -> DftHashMap<SyntaxId, &'a Syntax<'a>> {
let mut res = DftHashMap::default();
for node in lhs_roots {
syntax_ids_from_node(node, &mut res);
}
for node in rhs_roots {
syntax_ids_from_node(node, &mut res);
}
res
}
fn syntax_ids_from_node<'a>(
node: &'a Syntax<'a>,
syntax_ids: &mut DftHashMap<SyntaxId, &'a Syntax<'a>>,
) {
syntax_ids.insert(node.id(), node);
if let List { children, .. } = node {
for child in children {
syntax_ids_from_node(child, syntax_ids);
}
}
}
fn init_info<'a>(lhs_roots: &[&'a Syntax<'a>], rhs_roots: &[&'a Syntax<'a>]) {
let mut id = NonZeroU32::new(1).unwrap();
init_info_on_side(lhs_roots, &mut id);