Tolerate tree edits whose old range extends beyond the end of the tree

This commit is contained in:
Max Brunsfeld 2022-08-25 10:20:40 -07:00
parent 477b667753
commit 53ed4cf037
4 changed files with 108 additions and 46 deletions

View file

@ -89,14 +89,11 @@ fn test_tree_edit() {
let child2 = expr.child(1).unwrap();
assert!(expr.has_changes());
assert_eq!(expr.start_byte(), 4);
assert_eq!(expr.end_byte(), 17);
assert_eq!(expr.byte_range(), 4..17);
assert!(child1.has_changes());
assert_eq!(child1.start_byte(), 4);
assert_eq!(child1.end_byte(), 7);
assert_eq!(child1.byte_range(), 4..7);
assert!(!child2.has_changes());
assert_eq!(child2.start_byte(), 9);
assert_eq!(child2.end_byte(), 12);
assert_eq!(child2.byte_range(), 9..12);
}
// replacement starting at the edge of the tree's padding:
@ -117,14 +114,11 @@ fn test_tree_edit() {
let child2 = expr.child(1).unwrap();
assert!(expr.has_changes());
assert_eq!(expr.start_byte(), 4);
assert_eq!(expr.end_byte(), 17);
assert_eq!(expr.byte_range(), 4..17);
assert!(child1.has_changes());
assert_eq!(child1.start_byte(), 4);
assert_eq!(child1.end_byte(), 7);
assert_eq!(child1.byte_range(), 4..7);
assert!(!child2.has_changes());
assert_eq!(child2.start_byte(), 9);
assert_eq!(child2.end_byte(), 12);
assert_eq!(child2.byte_range(), 9..12);
}
// deletion that spans more than one child node:
@ -146,17 +140,13 @@ fn test_tree_edit() {
let child3 = expr.child(2).unwrap();
assert!(expr.has_changes());
assert_eq!(expr.start_byte(), 4);
assert_eq!(expr.end_byte(), 8);
assert_eq!(expr.byte_range(), 4..8);
assert!(child1.has_changes());
assert_eq!(child1.start_byte(), 4);
assert_eq!(child1.end_byte(), 4);
assert_eq!(child1.byte_range(), 4..4);
assert!(child2.has_changes());
assert_eq!(child2.start_byte(), 4);
assert_eq!(child2.end_byte(), 4);
assert_eq!(child2.byte_range(), 4..4);
assert!(child3.has_changes());
assert_eq!(child3.start_byte(), 5);
assert_eq!(child3.end_byte(), 8);
assert_eq!(child3.byte_range(), 5..8);
}
// insertion at the end of the tree:
@ -178,14 +168,67 @@ fn test_tree_edit() {
let child3 = expr.child(2).unwrap();
assert!(expr.has_changes());
assert_eq!(expr.start_byte(), 2);
assert_eq!(expr.end_byte(), 16);
assert_eq!(expr.byte_range(), 2..16);
assert!(!child1.has_changes());
assert_eq!(child1.end_byte(), 5);
assert_eq!(child1.byte_range(), 2..5);
assert!(!child2.has_changes());
assert_eq!(child2.end_byte(), 10);
assert_eq!(child2.byte_range(), 7..10);
assert!(child3.has_changes());
assert_eq!(child3.byte_range(), 12..16);
}
// replacement that starts within a token and extends beyond the end of the tree:
// resize the token and empty out any subsequent child nodes.
{
let mut tree = tree.clone();
tree.edit(&InputEdit {
start_byte: 3,
old_end_byte: 90,
new_end_byte: 4,
start_position: Point::new(0, 3),
old_end_position: Point::new(0, 90),
new_end_position: Point::new(0, 4),
});
let expr = tree.root_node().child(0).unwrap().child(0).unwrap();
let child1 = expr.child(0).unwrap();
let child2 = expr.child(1).unwrap();
let child3 = expr.child(2).unwrap();
assert_eq!(expr.byte_range(), 2..4);
assert!(expr.has_changes());
assert_eq!(child1.byte_range(), 2..4);
assert!(child1.has_changes());
assert_eq!(child2.byte_range(), 4..4);
assert!(child2.has_changes());
assert_eq!(child3.byte_range(), 4..4);
assert!(child3.has_changes());
}
// replacement that starts in whitespace and extends beyond the end of the tree:
// shift the token's start position and empty out its content.
{
let mut tree = tree.clone();
tree.edit(&InputEdit {
start_byte: 6,
old_end_byte: 90,
new_end_byte: 8,
start_position: Point::new(0, 6),
old_end_position: Point::new(0, 90),
new_end_position: Point::new(0, 8),
});
let expr = tree.root_node().child(0).unwrap().child(0).unwrap();
let child1 = expr.child(0).unwrap();
let child2 = expr.child(1).unwrap();
let child3 = expr.child(2).unwrap();
assert_eq!(expr.byte_range(), 2..8);
assert!(expr.has_changes());
assert_eq!(child1.byte_range(), 2..5);
assert!(!child1.has_changes());
assert_eq!(child2.byte_range(), 8..8);
assert!(child2.has_changes());
assert_eq!(child3.byte_range(), 8..8);
assert!(child3.has_changes());
assert_eq!(child3.end_byte(), 16);
}
}