From ec90c215ae8ee833440bf743ab69fca10c55b541 Mon Sep 17 00:00:00 2001 From: Daumantas Kavolis Date: Fri, 16 Jun 2023 10:47:10 +0300 Subject: [PATCH] Add tests for bidirectional cursor --- cli/src/tests/tree_test.rs | 45 +++++++++++++++++++++++++++++++++++++- lib/src/tree_cursor.c | 15 +++++++++++-- 2 files changed, 57 insertions(+), 3 deletions(-) diff --git a/cli/src/tests/tree_test.rs b/cli/src/tests/tree_test.rs index be0c4ff1..7d091c3f 100644 --- a/cli/src/tests/tree_test.rs +++ b/cli/src/tests/tree_test.rs @@ -306,7 +306,7 @@ fn test_tree_cursor() { .parse( " struct Stuff { - a: A; + a: A, b: Option, } ", @@ -331,6 +331,49 @@ fn test_tree_cursor() { assert!(cursor.goto_next_sibling()); assert_eq!(cursor.node().kind(), "field_declaration_list"); assert_eq!(cursor.node().is_named(), true); + + assert!(cursor.goto_last_child()); + assert_eq!(cursor.node().kind(), "}"); + assert_eq!(cursor.node().is_named(), false); + assert_eq!(cursor.node().start_position(), Point { row: 4, column: 16 }); + + assert!(cursor.goto_previous_sibling()); + assert_eq!(cursor.node().kind(), ","); + assert_eq!(cursor.node().is_named(), false); + assert_eq!(cursor.node().start_position(), Point { row: 3, column: 32 }); + + assert!(cursor.goto_previous_sibling()); + assert_eq!(cursor.node().kind(), "field_declaration"); + assert_eq!(cursor.node().is_named(), true); + assert_eq!(cursor.node().start_position(), Point { row: 3, column: 20 }); + + assert!(cursor.goto_previous_sibling()); + assert_eq!(cursor.node().kind(), ","); + assert_eq!(cursor.node().is_named(), false); + assert_eq!(cursor.node().start_position(), Point { row: 2, column: 24 }); + + assert!(cursor.goto_previous_sibling()); + assert_eq!(cursor.node().kind(), "field_declaration"); + assert_eq!(cursor.node().is_named(), true); + assert_eq!(cursor.node().start_position(), Point { row: 2, column: 20 }); + + assert!(cursor.goto_previous_sibling()); + assert_eq!(cursor.node().kind(), "{"); + assert_eq!(cursor.node().is_named(), false); + assert_eq!(cursor.node().start_position(), Point { row: 1, column: 29 }); + + let mut copy = tree.walk(); + copy.reset_to(cursor); + + assert_eq!(copy.node().kind(), "{"); + assert_eq!(copy.node().is_named(), false); + + assert!(copy.goto_parent()); + assert_eq!(copy.node().kind(), "field_declaration_list"); + assert_eq!(copy.node().is_named(), true); + + assert!(copy.goto_parent()); + assert_eq!(copy.node().kind(), "struct_item"); } #[test] diff --git a/lib/src/tree_cursor.c b/lib/src/tree_cursor.c index 702088ad..0512b914 100644 --- a/lib/src/tree_cursor.c +++ b/lib/src/tree_cursor.c @@ -97,6 +97,16 @@ static inline bool ts_tree_cursor_child_iterator_next( return true; } +static inline Length length_sub_zero(Length a, Length b) { + // length_sub doesn't account for 0 row subtraction, i.e. only columns + // should be subtracted, but changing point_sub breaks other tests + Length result = length_sub(a, b); + if (b.extent.row == 0) { + result.extent.column -= b.extent.column; + } + return result; +} + static inline bool ts_tree_cursor_child_iterator_previous( CursorChildIterator *self, TreeCursorEntry *result, @@ -119,13 +129,14 @@ static inline bool ts_tree_cursor_child_iterator_previous( self->structural_child_index--; } - self->position = length_sub(self->position, ts_subtree_padding(*child)); + self->position = length_sub_zero(self->position, ts_subtree_padding(*child)); self->child_index--; // unsigned can underflow so compare it to child_count if (self->child_index < self->parent.ptr->child_count) { Subtree previous_child = ts_subtree_children(self->parent)[self->child_index]; - self->position = length_sub(self->position, ts_subtree_size(previous_child)); + Length size = ts_subtree_size(previous_child); + self->position = length_sub_zero(self->position, size); } return true;