diff --git a/cli/src/tests/query_test.rs b/cli/src/tests/query_test.rs index 32b6136f..7b0029a0 100644 --- a/cli/src/tests/query_test.rs +++ b/cli/src/tests/query_test.rs @@ -5,8 +5,9 @@ use lazy_static::lazy_static; use rand::{prelude::StdRng, SeedableRng}; use streaming_iterator::StreamingIterator; use tree_sitter::{ - CaptureQuantifier, Language, Node, Parser, Point, Query, QueryCursor, QueryCursorOptions, - QueryError, QueryErrorKind, QueryPredicate, QueryPredicateArg, QueryProperty, + CaptureQuantifier, InputEdit, Language, Node, Parser, Point, Query, QueryCursor, + QueryCursorOptions, QueryError, QueryErrorKind, QueryPredicate, QueryPredicateArg, + QueryProperty, Range, }; use tree_sitter_generate::generate_parser_for_grammar; use unindent::Unindent; @@ -5334,3 +5335,72 @@ fn test_query_execution_with_timeout() { .count(); assert_eq!(matches, 1000); } + +#[test] +fn idk() { + let language = get_language("rust"); + let mut parser = Parser::new(); + parser.set_language(&language).unwrap(); + + let code = r#"fn main() { + println!("{:?}", foo()); +}"#; + parser + .set_included_ranges(&[Range { + start_byte: 24, + end_byte: 39, + start_point: Point::new(0, 0), // 5, 12 + end_point: Point::new(0, 0), // 5, 27 + }]) + .unwrap(); + + let query = Query::new(&language, "(call_expression) @cap").unwrap(); + let mut cursor = QueryCursor::new(); + + let mut tree = parser.parse(code, None).unwrap(); + + let matches = { + let root_node = tree.root_node(); + let matches = cursor.matches(&query, root_node, code.as_bytes()); + collect_matches(matches, &query, code) + .into_iter() + .map(|(i, m)| { + ( + i, + m.into_iter() + .map(|(k, v)| (k.to_string(), v.to_string())) + .collect::>(), + ) + }) + .collect::>() + }; + + tree.edit(&InputEdit { + start_byte: 40, + old_end_byte: 40, + new_end_byte: 41, + start_position: Point::new(1, 28), + old_end_position: Point::new(1, 28), + new_end_position: Point::new(2, 0), + }); + + let tree2 = parser.parse(code, Some(&tree)).unwrap(); + + let matches2 = { + let root_node = tree2.root_node(); + let matches = cursor.matches(&query, root_node, code.as_bytes()); + collect_matches(matches, &query, code) + .into_iter() + .map(|(i, m)| { + ( + i, + m.into_iter() + .map(|(k, v)| (k.to_string(), v.to_string())) + .collect::>(), + ) + }) + .collect::>() + }; + + assert_eq!(matches, matches2); +} diff --git a/lib/src/length.h b/lib/src/length.h index 42d61ef3..ddf156ce 100644 --- a/lib/src/length.h +++ b/lib/src/length.h @@ -31,7 +31,7 @@ static inline Length length_add(Length len1, Length len2) { static inline Length length_sub(Length len1, Length len2) { Length result; - result.bytes = len1.bytes - len2.bytes; + result.bytes = (len1.bytes >= len2.bytes) ? len1.bytes - len2.bytes : 0; result.extent = point_sub(len1.extent, len2.extent); return result; } diff --git a/lib/src/point.h b/lib/src/point.h index 37346c8d..06c16f57 100644 --- a/lib/src/point.h +++ b/lib/src/point.h @@ -22,7 +22,7 @@ static inline TSPoint point_sub(TSPoint a, TSPoint b) { if (a.row > b.row) return point__new(a.row - b.row, a.column); else - return point__new(0, a.column - b.column); + return point__new(0, (a.column >= b.column) ? a.column - b.column : 0); } static inline bool point_lte(TSPoint a, TSPoint b) {