Set deep in changes.rs

remove_eq_on_syntax
Wilfred Hughes 2022-04-24 10:49:49 +07:00
parent d460ce4dcc
commit 715d71b6b4
5 changed files with 53 additions and 68 deletions

@ -2,8 +2,6 @@ use rustc_hash::FxHashMap;
use crate::syntax::Syntax; use crate::syntax::Syntax;
#[derive(PartialEq, Eq, Clone, Copy)] #[derive(PartialEq, Eq, Clone, Copy)]
pub enum ChangeKind<'a> { pub enum ChangeKind<'a> {
Unchanged(&'a Syntax<'a>), Unchanged(&'a Syntax<'a>),
@ -16,3 +14,30 @@ pub type ChangeMap<'a> = FxHashMap<&'a Syntax<'a>, ChangeKind<'a>>;
pub fn new_change_map<'a>() -> ChangeMap<'a> { pub fn new_change_map<'a>() -> ChangeMap<'a> {
FxHashMap::default() FxHashMap::default()
} }
pub fn insert_deep_unchanged<'a>(
node: &'a Syntax<'a>,
opposite_node: &'a Syntax<'a>,
change_map: &mut ChangeMap<'a>,
) {
change_map.insert(node, ChangeKind::Unchanged(opposite_node));
match (node, opposite_node) {
(
Syntax::List {
children: node_children,
..
},
Syntax::List {
children: opposite_children,
..
},
) => {
for (child, opposite_child) in node_children.iter().zip(opposite_children) {
insert_deep_unchanged(child, opposite_child, change_map);
}
}
(Syntax::Atom { .. }, Syntax::Atom { .. }) => {}
_ => unreachable!("Unchanged nodes should be both lists, or both atoms"),
}
}

@ -4,8 +4,8 @@
use std::{cmp::Reverse, env}; use std::{cmp::Reverse, env};
use crate::{ use crate::{
changes::ChangeKind, changes::ChangeMap,
graph::{change_kinds, mark_route, neighbours, Edge, Vertex}, graph::{mark_route, neighbours, populate_change_map, Edge, Vertex},
syntax::Syntax, syntax::Syntax,
}; };
use itertools::Itertools; use itertools::Itertools;
@ -138,24 +138,10 @@ fn tree_count(root: Option<&Syntax>) -> u32 {
count count
} }
pub fn syntax_changed<'a>( pub fn mark_syntax<'a>(
lhs_syntax: Option<&'a Syntax<'a>>, lhs_syntax: Option<&'a Syntax<'a>>,
rhs_syntax: Option<&'a Syntax<'a>>, rhs_syntax: Option<&'a Syntax<'a>>,
) -> FxHashMap<&'a Syntax<'a>, ChangeKind<'a>> { ) -> ChangeMap<'a> {
info!(
"LHS nodes: {} ({} toplevel), RHS nodes: {} ({} toplevel)",
node_count(lhs_syntax),
tree_count(lhs_syntax),
node_count(rhs_syntax),
tree_count(rhs_syntax),
);
let start = Vertex::new(lhs_syntax, rhs_syntax);
let route = shortest_path(start);
change_kinds(&route)
}
pub fn mark_syntax<'a>(lhs_syntax: Option<&'a Syntax<'a>>, rhs_syntax: Option<&'a Syntax<'a>>) {
info!( info!(
"LHS nodes: {} ({} toplevel), RHS nodes: {} ({} toplevel)", "LHS nodes: {} ({} toplevel), RHS nodes: {} ({} toplevel)",
node_count(lhs_syntax), node_count(lhs_syntax),
@ -167,15 +153,18 @@ pub fn mark_syntax<'a>(lhs_syntax: Option<&'a Syntax<'a>>, rhs_syntax: Option<&'
let start = Vertex::new(lhs_syntax, rhs_syntax); let start = Vertex::new(lhs_syntax, rhs_syntax);
let route = shortest_path(start); let route = shortest_path(start);
mark_route(&route); mark_route(&route);
populate_change_map(&route)
} }
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use crate::{ use crate::{
changes::ChangeKind,
graph::Edge::*, graph::Edge::*,
positions::SingleLineSpan, positions::SingleLineSpan,
syntax::{init_all_info, AtomKind, ChangeKind}, syntax::{init_all_info, AtomKind},
}; };
use itertools::Itertools; use itertools::Itertools;
@ -574,7 +563,7 @@ mod tests {
let rhs = Syntax::new_atom(&arena, pos_helper(1), "foo", AtomKind::Normal); let rhs = Syntax::new_atom(&arena, pos_helper(1), "foo", AtomKind::Normal);
init_all_info(&[lhs], &[rhs]); init_all_info(&[lhs], &[rhs]);
mark_syntax(Some(lhs), Some(rhs)); let _change_map = mark_syntax(Some(lhs), Some(rhs));
assert_eq!(lhs.change(), Some(ChangeKind::Unchanged(rhs))); assert_eq!(lhs.change(), Some(ChangeKind::Unchanged(rhs)));
assert_eq!(rhs.change(), Some(ChangeKind::Unchanged(lhs))); assert_eq!(rhs.change(), Some(ChangeKind::Unchanged(lhs)));
} }
@ -586,7 +575,7 @@ mod tests {
let rhs = Syntax::new_atom(&arena, pos_helper(1), "bar", AtomKind::Normal); let rhs = Syntax::new_atom(&arena, pos_helper(1), "bar", AtomKind::Normal);
init_all_info(&[lhs], &[rhs]); init_all_info(&[lhs], &[rhs]);
mark_syntax(Some(lhs), Some(rhs)); let _change_map = mark_syntax(Some(lhs), Some(rhs));
assert_eq!(lhs.change(), Some(ChangeKind::Novel)); assert_eq!(lhs.change(), Some(ChangeKind::Novel));
assert_eq!(rhs.change(), Some(ChangeKind::Novel)); assert_eq!(rhs.change(), Some(ChangeKind::Novel));
} }

@ -9,7 +9,7 @@ use std::{
}; };
use strsim::normalized_levenshtein; use strsim::normalized_levenshtein;
use crate::changes::{ChangeKind, ChangeMap, new_change_map}; use crate::changes::{insert_deep_unchanged, new_change_map, ChangeKind, ChangeMap};
use crate::syntax::{AtomKind, Syntax}; use crate::syntax::{AtomKind, Syntax};
use Edge::*; use Edge::*;
@ -589,34 +589,7 @@ pub fn neighbours<'a>(v: &Vertex<'a>, buf: &mut [Option<(Edge, Vertex<'a>)>]) {
); );
} }
fn set_deep_unchanged<'a>( pub fn populate_change_map<'a>(route: &[(Edge, Vertex<'a>)]) -> ChangeMap<'a> {
node: &'a Syntax<'a>,
opposite_node: &'a Syntax<'a>,
changes: &mut ChangeMap<'a>,
) {
changes.insert(node, ChangeKind::Unchanged(opposite_node));
match (node, opposite_node) {
(
Syntax::List {
children: node_children,
..
},
Syntax::List {
children: opposite_children,
..
},
) => {
for (child, opposite_child) in node_children.iter().zip(opposite_children) {
set_deep_unchanged(child, opposite_child, changes);
}
}
(Syntax::Atom { .. }, Syntax::Atom { .. }) => {}
_ => unreachable!("Unchanged nodes should be both lists, or both atoms"),
}
}
pub fn change_kinds<'a>(route: &[(Edge, Vertex<'a>)]) -> ChangeMap<'a> {
let mut res = new_change_map(); let mut res = new_change_map();
for (e, v) in route { for (e, v) in route {
@ -629,8 +602,8 @@ pub fn change_kinds<'a>(route: &[(Edge, Vertex<'a>)]) -> ChangeMap<'a> {
let lhs = v.lhs_syntax.unwrap(); let lhs = v.lhs_syntax.unwrap();
let rhs = v.rhs_syntax.unwrap(); let rhs = v.rhs_syntax.unwrap();
set_deep_unchanged(lhs, rhs, &mut res); insert_deep_unchanged(lhs, rhs, &mut res);
set_deep_unchanged(rhs, lhs, &mut res); insert_deep_unchanged(rhs, lhs, &mut res);
} }
EnterUnchangedDelimiter { .. } => { EnterUnchangedDelimiter { .. } => {
// No change on the outer delimiter, but children may // No change on the outer delimiter, but children may

@ -39,6 +39,7 @@ mod unchanged;
extern crate log; extern crate log;
use crate::hunks::{matched_pos_to_hunks, merge_adjacent}; use crate::hunks::{matched_pos_to_hunks, merge_adjacent};
use changes::new_change_map;
use context::opposite_positions; use context::opposite_positions;
use files::read_files_or_die; use files::read_files_or_die;
use guess_language::guess; use guess_language::guess;
@ -305,11 +306,12 @@ fn diff_file_content(
let rhs = tsp::parse(&arena, &rhs_src, &ts_lang); let rhs = tsp::parse(&arena, &rhs_src, &ts_lang);
init_all_info(&lhs, &rhs); init_all_info(&lhs, &rhs);
let mut change_map = new_change_map();
let possibly_changed = if env::var("DFT_DBG_KEEP_UNCHANGED").is_ok() { let possibly_changed = if env::var("DFT_DBG_KEEP_UNCHANGED").is_ok() {
vec![(lhs.clone(), rhs.clone())] vec![(lhs.clone(), rhs.clone())]
} else { } else {
unchanged::mark_unchanged(&lhs, &rhs) unchanged::mark_unchanged(&lhs, &rhs, &mut change_map)
}; };
let possibly_changed_max = max_num_nodes(&possibly_changed); let possibly_changed_max = max_num_nodes(&possibly_changed);

@ -1,6 +1,4 @@
use rustc_hash::FxHashMap; use crate::changes::{ChangeKind, ChangeMap};
use crate::changes::{new_change_map, ChangeKind, ChangeMap};
use crate::myers_diff; use crate::myers_diff;
use crate::syntax::Syntax; use crate::syntax::Syntax;
@ -14,16 +12,14 @@ const MOSTLY_UNCHANGED_MIN_COMMON_CHILDREN: usize = 4;
pub fn mark_unchanged<'a>( pub fn mark_unchanged<'a>(
lhs_nodes: &[&'a Syntax<'a>], lhs_nodes: &[&'a Syntax<'a>],
rhs_nodes: &[&'a Syntax<'a>], rhs_nodes: &[&'a Syntax<'a>],
change_map: &mut ChangeMap<'a>,
) -> Vec<(Vec<&'a Syntax<'a>>, Vec<&'a Syntax<'a>>)> { ) -> Vec<(Vec<&'a Syntax<'a>>, Vec<&'a Syntax<'a>>)> {
let mut change_kinds = new_change_map(); let (_, lhs_nodes, rhs_nodes) = shrink_unchanged_at_ends(lhs_nodes, rhs_nodes, change_map);
let (_, lhs_nodes, rhs_nodes) =
shrink_unchanged_at_ends(lhs_nodes, rhs_nodes, &mut change_kinds);
let mut res = vec![]; let mut res = vec![];
for (lhs_nodes, rhs_nodes) in split_mostly_unchanged_toplevel(&lhs_nodes, &rhs_nodes) { for (lhs_nodes, rhs_nodes) in split_mostly_unchanged_toplevel(&lhs_nodes, &rhs_nodes) {
let (_, lhs_nodes, rhs_nodes) = let (_, lhs_nodes, rhs_nodes) =
shrink_unchanged_at_ends(&lhs_nodes, &rhs_nodes, &mut change_kinds); shrink_unchanged_at_ends(&lhs_nodes, &rhs_nodes, change_map);
res.extend(split_unchanged(&lhs_nodes, &rhs_nodes)); res.extend(split_unchanged(&lhs_nodes, &rhs_nodes));
} }
@ -343,7 +339,7 @@ fn as_singleton_list_children<'a>(
fn shrink_unchanged_delimiters<'a>( fn shrink_unchanged_delimiters<'a>(
lhs_nodes: &[&'a Syntax<'a>], lhs_nodes: &[&'a Syntax<'a>],
rhs_nodes: &[&'a Syntax<'a>], rhs_nodes: &[&'a Syntax<'a>],
changes: &mut ChangeMap<'a>, change_map: &mut ChangeMap<'a>,
) -> (bool, Vec<&'a Syntax<'a>>, Vec<&'a Syntax<'a>>) { ) -> (bool, Vec<&'a Syntax<'a>>, Vec<&'a Syntax<'a>>) {
if let ( if let (
[Syntax::List { [Syntax::List {
@ -362,7 +358,7 @@ fn shrink_unchanged_delimiters<'a>(
{ {
if lhs_open == rhs_open && lhs_close == rhs_close { if lhs_open == rhs_open && lhs_close == rhs_close {
let (changed_later, lhs_shrunk_nodes, rhs_shrunk_nodes) = let (changed_later, lhs_shrunk_nodes, rhs_shrunk_nodes) =
shrink_unchanged_at_ends(lhs_children, rhs_children, changes); shrink_unchanged_at_ends(lhs_children, rhs_children, change_map);
if changed_later { if changed_later {
lhs_nodes[0].set_change(ChangeKind::Unchanged(rhs_nodes[0])); lhs_nodes[0].set_change(ChangeKind::Unchanged(rhs_nodes[0]));
rhs_nodes[0].set_change(ChangeKind::Unchanged(lhs_nodes[0])); rhs_nodes[0].set_change(ChangeKind::Unchanged(lhs_nodes[0]));
@ -382,7 +378,7 @@ fn shrink_unchanged_delimiters<'a>(
fn shrink_unchanged_at_ends<'a>( fn shrink_unchanged_at_ends<'a>(
lhs_nodes: &[&'a Syntax<'a>], lhs_nodes: &[&'a Syntax<'a>],
rhs_nodes: &[&'a Syntax<'a>], rhs_nodes: &[&'a Syntax<'a>],
changes: &mut ChangeMap<'a>, change_map: &mut ChangeMap<'a>,
) -> (bool, Vec<&'a Syntax<'a>>, Vec<&'a Syntax<'a>>) { ) -> (bool, Vec<&'a Syntax<'a>>, Vec<&'a Syntax<'a>>) {
let mut lhs_nodes = lhs_nodes; let mut lhs_nodes = lhs_nodes;
let mut rhs_nodes = rhs_nodes; let mut rhs_nodes = rhs_nodes;
@ -420,7 +416,7 @@ fn shrink_unchanged_at_ends<'a>(
if lhs_nodes.len() == 1 && rhs_nodes.len() == 1 { if lhs_nodes.len() == 1 && rhs_nodes.len() == 1 {
let (changed_later, lhs_nodes, rhs_nodes) = let (changed_later, lhs_nodes, rhs_nodes) =
shrink_unchanged_delimiters(lhs_nodes, rhs_nodes, changes); shrink_unchanged_delimiters(lhs_nodes, rhs_nodes, change_map);
(changed || changed_later, lhs_nodes, rhs_nodes) (changed || changed_later, lhs_nodes, rhs_nodes)
} else { } else {
(changed, Vec::from(lhs_nodes), Vec::from(rhs_nodes)) (changed, Vec::from(lhs_nodes), Vec::from(rhs_nodes))