@@ -22,6 +22,7 @@ use tree_sitter::Point;
22
22
use crate :: lsp:: encoding:: convert_point_to_position;
23
23
use crate :: lsp:: traits:: cursor:: TreeCursorExt ;
24
24
use crate :: lsp:: traits:: rope:: RopeExt ;
25
+ use crate :: treesitter:: node_has_error_or_missing;
25
26
use crate :: treesitter:: NodeType ;
26
27
use crate :: treesitter:: NodeTypeExt ;
27
28
@@ -96,6 +97,12 @@ fn find_roxygen_comment_at_point<'tree>(
96
97
contents : & Rope ,
97
98
point : Point ,
98
99
) -> Option < ( Node < ' tree > , Option < String > ) > {
100
+ // Refuse to look for roxygen comments in the face of parse errors
101
+ // (posit-dev/positron#5023)
102
+ if node_has_error_or_missing ( root) {
103
+ return None ;
104
+ }
105
+
99
106
let mut cursor = root. walk ( ) ;
100
107
101
108
// Move cursor to first node that is at or extends past the `point`
@@ -230,6 +237,14 @@ fn expand_range_across_semicolons(mut node: Node) -> tree_sitter::Range {
230
237
}
231
238
232
239
fn find_statement_range_node < ' tree > ( root : & ' tree Node , row : usize ) -> Option < Node < ' tree > > {
240
+ // Refuse to provide a statement range in the face of parse errors, we are
241
+ // unlikely to be able to provide anything useful, and are more likely to provide
242
+ // something confusing. Instead, return `None` so that the frontend sends code to
243
+ // the console one line at a time (posit-dev/positron#5023).
244
+ if node_has_error_or_missing ( root) {
245
+ return None ;
246
+ }
247
+
233
248
let mut cursor = root. walk ( ) ;
234
249
235
250
let children = root. children ( & mut cursor) ;
@@ -1402,18 +1417,6 @@ test_that('stuff', {
1402
1417
) ;
1403
1418
}
1404
1419
1405
- #[ test]
1406
- fn test_unmatched_opening_braces_send_the_full_partial_statement ( ) {
1407
- statement_range_test (
1408
- "
1409
- @
1410
- <<{
1411
- 1 + 1
1412
-
1413
- >>" ,
1414
- ) ;
1415
- }
1416
-
1417
1420
#[ test]
1418
1421
fn test_binary_op_with_braces_respects_that_you_can_put_the_cursor_inside_the_braces ( ) {
1419
1422
statement_range_test (
@@ -1557,15 +1560,19 @@ list({
1557
1560
}
1558
1561
1559
1562
#[ test]
1560
- fn test_unmatched_opening_braces_partial_statement ( ) {
1561
- statement_range_test (
1562
- "
1563
- @
1564
- <<{
1563
+ fn test_returns_none_with_parse_errors ( ) {
1564
+ let row = 2 ;
1565
+ let contents = "
1566
+ {
1565
1567
1 + 1
1566
-
1567
- >>" ,
1568
- ) ;
1568
+ " ;
1569
+ let mut parser = Parser :: new ( ) ;
1570
+ parser
1571
+ . set_language ( & tree_sitter_r:: LANGUAGE . into ( ) )
1572
+ . expect ( "Failed to create parser" ) ;
1573
+ let ast = parser. parse ( contents, None ) . unwrap ( ) ;
1574
+ let root = ast. root_node ( ) ;
1575
+ assert_eq ! ( find_statement_range_node( & root, row) , None ) ;
1569
1576
}
1570
1577
1571
1578
#[ test]
@@ -1680,5 +1687,23 @@ list({
1680
1687
let ( node, code) = find_roxygen_comment_at_point ( & root, contents, point) . unwrap ( ) ;
1681
1688
assert_eq ! ( get_text( & node, & contents) , String :: from( "###' @returns" ) ) ;
1682
1689
assert ! ( code. is_none( ) ) ;
1690
+
1691
+ let text = "
1692
+ #' Hi
1693
+ #' @param x foo
1694
+ #' @examples
1695
+ #' 1 + 1
1696
+ #' 2 + 2
1697
+ #' @returns
1698
+ 1 +
1699
+ " ;
1700
+
1701
+ let document = Document :: new ( text, None ) ;
1702
+ let root = document. ast . root_node ( ) ;
1703
+ let contents = & document. contents ;
1704
+
1705
+ // With parse errors in the file, return `None`
1706
+ let point = Point { row : 4 , column : 1 } ;
1707
+ assert_eq ! ( find_roxygen_comment_at_point( & root, contents, point) , None ) ;
1683
1708
}
1684
1709
}
0 commit comments