Skip to content

Commit 5d31273

Browse files
authored
Refuse to provide a statement range in the face of parse errors (#837)
Instead, the frontend will send code to the console one line at a time, which is the best we can probably offer, and is somewhat similar to how RStudio works
1 parent 98e1aa1 commit 5d31273

File tree

1 file changed

+45
-20
lines changed

1 file changed

+45
-20
lines changed

crates/ark/src/lsp/statement_range.rs

Lines changed: 45 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ use tree_sitter::Point;
2222
use crate::lsp::encoding::convert_point_to_position;
2323
use crate::lsp::traits::cursor::TreeCursorExt;
2424
use crate::lsp::traits::rope::RopeExt;
25+
use crate::treesitter::node_has_error_or_missing;
2526
use crate::treesitter::NodeType;
2627
use crate::treesitter::NodeTypeExt;
2728

@@ -96,6 +97,12 @@ fn find_roxygen_comment_at_point<'tree>(
9697
contents: &Rope,
9798
point: Point,
9899
) -> 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+
99106
let mut cursor = root.walk();
100107

101108
// 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 {
230237
}
231238

232239
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+
233248
let mut cursor = root.walk();
234249

235250
let children = root.children(&mut cursor);
@@ -1402,18 +1417,6 @@ test_that('stuff', {
14021417
);
14031418
}
14041419

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-
14171420
#[test]
14181421
fn test_binary_op_with_braces_respects_that_you_can_put_the_cursor_inside_the_braces() {
14191422
statement_range_test(
@@ -1557,15 +1560,19 @@ list({
15571560
}
15581561

15591562
#[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+
{
15651567
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);
15691576
}
15701577

15711578
#[test]
@@ -1680,5 +1687,23 @@ list({
16801687
let (node, code) = find_roxygen_comment_at_point(&root, contents, point).unwrap();
16811688
assert_eq!(get_text(&node, &contents), String::from("###' @returns"));
16821689
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);
16831708
}
16841709
}

0 commit comments

Comments
 (0)