Stop change state from being public on Syntax

remove_eq_on_syntax
Wilfred Hughes 2022-04-24 11:03:13 +07:00
parent f644e7a5f0
commit 625e9935e1
5 changed files with 65 additions and 40 deletions

@ -564,7 +564,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]);
let change_map = new_change_map(); let mut change_map = new_change_map();
mark_syntax(Some(lhs), Some(rhs), &mut change_map); mark_syntax(Some(lhs), Some(rhs), &mut change_map);
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)));
@ -577,7 +577,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]);
let change_map = new_change_map(); let mut change_map = new_change_map();
mark_syntax(Some(lhs), Some(rhs), &mut change_map); mark_syntax(Some(lhs), Some(rhs), &mut change_map);
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));

@ -306,7 +306,7 @@ 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 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())]
@ -340,8 +340,8 @@ fn diff_file_content(
); );
let language = language.unwrap(); let language = language.unwrap();
fix_all_sliders(language, &lhs_section_nodes); fix_all_sliders(language, &lhs_section_nodes, &mut change_map);
fix_all_sliders(language, &rhs_section_nodes); fix_all_sliders(language, &rhs_section_nodes, &mut change_map);
} }
let lhs_positions = syntax::change_positions(&lhs); let lhs_positions = syntax::change_positions(&lhs);

@ -29,13 +29,22 @@
//! forwards or backwards when the before and after nodes are the same //! forwards or backwards when the before and after nodes are the same
//! (B in this example). //! (B in this example).
use crate::{changes::ChangeKind::*, guess_language, positions::SingleLineSpan, syntax::Syntax}; use crate::{
changes::{ChangeKind::*, ChangeMap},
guess_language,
positions::SingleLineSpan,
syntax::Syntax,
};
use Syntax::*; use Syntax::*;
pub fn fix_all_sliders<'a>(language: guess_language::Language, nodes: &[&'a Syntax<'a>]) { pub fn fix_all_sliders<'a>(
language: guess_language::Language,
nodes: &[&'a Syntax<'a>],
change_map: &mut ChangeMap<'a>,
) {
// TODO: fix sliders that require more than two steps. // TODO: fix sliders that require more than two steps.
fix_all_sliders_one_step(nodes); fix_all_sliders_one_step(nodes, change_map);
fix_all_sliders_one_step(nodes); fix_all_sliders_one_step(nodes, change_map);
if !prefer_outer_delimiter(language) { if !prefer_outer_delimiter(language) {
fix_all_nested_sliders(nodes); fix_all_nested_sliders(nodes);
@ -62,13 +71,13 @@ fn prefer_outer_delimiter(language: guess_language::Language) -> bool {
} }
} }
fn fix_all_sliders_one_step<'a>(nodes: &[&'a Syntax<'a>]) { fn fix_all_sliders_one_step<'a>(nodes: &[&'a Syntax<'a>], change_map: &mut ChangeMap<'a>) {
for node in nodes { for node in nodes {
if let List { children, .. } = node { if let List { children, .. } = node {
fix_all_sliders_one_step(children); fix_all_sliders_one_step(children, change_map);
} }
} }
fix_sliders(nodes); fix_sliders(nodes, change_map);
} }
/// Correct sliders in middle insertions. /// Correct sliders in middle insertions.
@ -163,12 +172,12 @@ fn push_unchanged_to_ancestor<'a>(root: &'a Syntax<'a>, inner: &'a Syntax<'a>) {
} }
} }
fn fix_sliders<'a>(nodes: &[&'a Syntax<'a>]) { fn fix_sliders<'a>(nodes: &[&'a Syntax<'a>], change_map: &mut ChangeMap<'a>) {
for (region_start, region_end) in novel_regions_after_unchanged(nodes) { for (region_start, region_end) in novel_regions_after_unchanged(nodes) {
slide_to_prev_node(nodes, region_start, region_end); slide_to_prev_node(nodes, change_map, region_start, region_end);
} }
for (region_start, region_end) in novel_regions_before_unchanged(nodes) { for (region_start, region_end) in novel_regions_before_unchanged(nodes) {
slide_to_next_node(nodes, region_start, region_end); slide_to_next_node(nodes, change_map, region_start, region_end);
} }
} }
@ -251,43 +260,48 @@ fn novel_regions_before_unchanged<'a>(nodes: &[&'a Syntax<'a>]) -> Vec<(usize, u
.collect() .collect()
} }
fn is_novel_deep(node: &Syntax) -> bool { fn is_novel_deep<'a>(node: &Syntax<'a>, change_map: &ChangeMap<'a>) -> bool {
match node { match node {
List { info, children, .. } => { List { children, .. } => {
if !matches!(info.change.get(), Some(Novel)) { if !matches!(change_map.get(node), Some(Novel)) {
return false; return false;
} }
for child in children { for child in children {
if !is_novel_deep(child) { if !is_novel_deep(child, change_map) {
return false; return false;
} }
} }
true true
} }
Atom { info, .. } => matches!(info.change.get(), Some(Novel)), Atom { .. } => matches!(change_map.get(node), Some(Novel)),
} }
} }
fn is_unchanged_deep(node: &Syntax) -> bool { fn is_unchanged_deep<'a>(node: &Syntax<'a>, change_map: &ChangeMap<'a>) -> bool {
match node { match node {
List { info, children, .. } => { List { children, .. } => {
if !matches!(info.change.get(), Some(Unchanged(_))) { if !matches!(change_map.get(node), Some(Unchanged(_))) {
return false; return false;
} }
for child in children { for child in children {
if !is_unchanged_deep(child) { if !is_unchanged_deep(child, change_map) {
return false; return false;
} }
} }
true true
} }
Atom { info, .. } => matches!(info.change.get(), Some(Unchanged(_))), Atom { .. } => matches!(change_map.get(node), Some(Unchanged(_))),
} }
} }
fn slide_to_prev_node<'a>(nodes: &[&'a Syntax<'a>], start_idx: usize, end_idx: usize) { fn slide_to_prev_node<'a>(
nodes: &[&'a Syntax<'a>],
change_map: &mut ChangeMap<'a>,
start_idx: usize,
end_idx: usize,
) {
if start_idx == 0 { if start_idx == 0 {
return; return;
} }
@ -309,11 +323,11 @@ fn slide_to_prev_node<'a>(nodes: &[&'a Syntax<'a>], start_idx: usize, end_idx: u
if distance_to_before_start <= distance_to_last { if distance_to_before_start <= distance_to_last {
// Deep checks walk the whole tree, so do these last. // Deep checks walk the whole tree, so do these last.
if !is_unchanged_deep(before_start_node) { if !is_unchanged_deep(before_start_node, change_map) {
return; return;
} }
for node in &nodes[start_idx..=end_idx] { for node in &nodes[start_idx..=end_idx] {
if !is_novel_deep(node) { if !is_novel_deep(node, change_map) {
return; return;
} }
} }
@ -332,7 +346,12 @@ fn slide_to_prev_node<'a>(nodes: &[&'a Syntax<'a>], start_idx: usize, end_idx: u
} }
} }
fn slide_to_next_node<'a>(nodes: &[&'a Syntax<'a>], start_idx: usize, end_idx: usize) { fn slide_to_next_node<'a>(
nodes: &[&'a Syntax<'a>],
change_map: &mut ChangeMap<'a>,
start_idx: usize,
end_idx: usize,
) {
if end_idx == nodes.len() - 1 { if end_idx == nodes.len() - 1 {
return; return;
} }
@ -354,11 +373,11 @@ fn slide_to_next_node<'a>(nodes: &[&'a Syntax<'a>], start_idx: usize, end_idx: u
if distance_to_after_last < distance_to_start { if distance_to_after_last < distance_to_start {
// Deep checks walk the whole tree, so do these last. // Deep checks walk the whole tree, so do these last.
if !is_unchanged_deep(after_last_node) { if !is_unchanged_deep(after_last_node, change_map) {
return; return;
} }
for node in &nodes[start_idx..=end_idx] { for node in &nodes[start_idx..=end_idx] {
if !is_novel_deep(node) { if !is_novel_deep(node, change_map) {
return; return;
} }
} }
@ -448,7 +467,7 @@ mod tests {
use crate::{ use crate::{
guess_language, guess_language,
syntax::{init_all_info, AtomKind}, syntax::{init_all_info, AtomKind},
tree_sitter_parser::{from_language, parse}, tree_sitter_parser::{from_language, parse}, changes::new_change_map,
}; };
use pretty_assertions::assert_eq; use pretty_assertions::assert_eq;
use typed_arena::Arena; use typed_arena::Arena;
@ -494,7 +513,8 @@ mod tests {
lhs[1].set_change(Novel); lhs[1].set_change(Novel);
lhs[2].set_change(Novel); lhs[2].set_change(Novel);
fix_all_sliders(guess_language::Language::EmacsLisp, &lhs); let mut change_map = new_change_map();
fix_all_sliders(guess_language::Language::EmacsLisp, &lhs, &mut change_map);
assert_eq!(lhs[0].change(), Some(Novel)); assert_eq!(lhs[0].change(), Some(Novel));
assert_eq!(lhs[1].change(), Some(Novel)); assert_eq!(lhs[1].change(), Some(Novel));
assert_eq!(lhs[2].change(), Some(Unchanged(rhs[0]))); assert_eq!(lhs[2].change(), Some(Unchanged(rhs[0])));
@ -542,7 +562,8 @@ mod tests {
lhs[1].set_change(Novel); lhs[1].set_change(Novel);
lhs[2].set_change(Unchanged(rhs[0])); lhs[2].set_change(Unchanged(rhs[0]));
fix_all_sliders(guess_language::Language::EmacsLisp, &lhs); let mut change_map = new_change_map();
fix_all_sliders(guess_language::Language::EmacsLisp, &lhs, &mut change_map);
assert_eq!(rhs[0].change(), Some(Unchanged(lhs[0]))); assert_eq!(rhs[0].change(), Some(Unchanged(lhs[0])));
assert_eq!(lhs[0].change(), Some(Unchanged(rhs[0]))); assert_eq!(lhs[0].change(), Some(Unchanged(rhs[0])));
assert_eq!(lhs[1].change(), Some(Novel)); assert_eq!(lhs[1].change(), Some(Novel));
@ -563,7 +584,8 @@ mod tests {
rhs[3].set_change(Novel); rhs[3].set_change(Novel);
rhs[4].set_change(Novel); rhs[4].set_change(Novel);
fix_all_sliders(guess_language::Language::EmacsLisp, &rhs); let mut change_map = new_change_map();
fix_all_sliders(guess_language::Language::EmacsLisp, &rhs, &mut change_map);
assert_eq!(rhs[0].change(), Some(Novel)); assert_eq!(rhs[0].change(), Some(Novel));
assert_eq!(rhs[1].change(), Some(Novel)); assert_eq!(rhs[1].change(), Some(Novel));
assert_eq!(rhs[2].change(), Some(Novel)); assert_eq!(rhs[2].change(), Some(Novel));

@ -56,7 +56,7 @@ pub struct SyntaxInfo<'a> {
prev_is_contiguous: Cell<bool>, prev_is_contiguous: Cell<bool>,
/// Whether or not this syntax node has changed. This value is set /// Whether or not this syntax node has changed. This value is set
/// when computing the diff with another syntax tree. /// when computing the diff with another syntax tree.
pub change: Cell<Option<ChangeKind<'a>>>, change: Cell<Option<ChangeKind<'a>>>,
/// The number of nodes that are ancestors of this one. /// The number of nodes that are ancestors of this one.
num_ancestors: Cell<u32>, num_ancestors: Cell<u32>,
/// A number that uniquely identifies this syntax node. /// A number that uniquely identifies this syntax node.

@ -429,7 +429,7 @@ mod tests {
use crate::{ use crate::{
guess_language, guess_language,
syntax::init_all_info, syntax::init_all_info,
tree_sitter_parser::{from_language, parse}, tree_sitter_parser::{from_language, parse}, changes::new_change_map,
}; };
use typed_arena::Arena; use typed_arena::Arena;
@ -442,7 +442,8 @@ mod tests {
let rhs_nodes = parse(&arena, "unchanged X", &config); let rhs_nodes = parse(&arena, "unchanged X", &config);
init_all_info(&lhs_nodes, &rhs_nodes); init_all_info(&lhs_nodes, &rhs_nodes);
let (_, lhs_after_skip, rhs_after_skip) = shrink_unchanged_at_ends(&lhs_nodes, &rhs_nodes); let mut change_map = new_change_map();
let (_, lhs_after_skip, rhs_after_skip) = shrink_unchanged_at_ends(&lhs_nodes, &rhs_nodes, &mut change_map);
assert_eq!( assert_eq!(
lhs_nodes[0].change(), lhs_nodes[0].change(),
@ -466,7 +467,8 @@ mod tests {
let rhs_nodes = parse(&arena, "X unchanged", &config); let rhs_nodes = parse(&arena, "X unchanged", &config);
init_all_info(&lhs_nodes, &rhs_nodes); init_all_info(&lhs_nodes, &rhs_nodes);
let (_, lhs_after_skip, rhs_after_skip) = shrink_unchanged_at_ends(&lhs_nodes, &rhs_nodes); let mut change_map = new_change_map();
let (_, lhs_after_skip, rhs_after_skip) = shrink_unchanged_at_ends(&lhs_nodes, &rhs_nodes, &mut change_map);
assert_eq!( assert_eq!(
lhs_nodes[2].change(), lhs_nodes[2].change(),
@ -490,7 +492,8 @@ mod tests {
let rhs_nodes = parse(&arena, "unchanged-before (more-unchanged (B))", &config); let rhs_nodes = parse(&arena, "unchanged-before (more-unchanged (B))", &config);
init_all_info(&lhs_nodes, &rhs_nodes); init_all_info(&lhs_nodes, &rhs_nodes);
let (_, lhs_after_skip, rhs_after_skip) = shrink_unchanged_at_ends(&lhs_nodes, &rhs_nodes); let mut change_map = new_change_map();
let (_, lhs_after_skip, rhs_after_skip) = shrink_unchanged_at_ends(&lhs_nodes, &rhs_nodes, &mut change_map);
// The only possibly changed nodes are inside the lists. // The only possibly changed nodes are inside the lists.
assert_eq!(lhs_after_skip.len(), 1); assert_eq!(lhs_after_skip.len(), 1);