Skip to content

Implement StatementRangeSuccess and StatementRangeRejection#1040

Merged
DavisVaughan merged 9 commits intofeature/statement-range-errorfrom
feature/statement-range-error-2
Feb 24, 2026
Merged

Implement StatementRangeSuccess and StatementRangeRejection#1040
DavisVaughan merged 9 commits intofeature/statement-range-errorfrom
feature/statement-range-error-2

Conversation

@DavisVaughan
Copy link
Contributor

@DavisVaughan DavisVaughan commented Feb 13, 2026

Branched from #1028
Goes with posit-dev/positron#11907, and all documentation is there

@DavisVaughan DavisVaughan changed the title Return structured StatementRangeError from statement_range() Implement StatementRangeSuccess and StatementRangeRejection Feb 18, 2026
@DavisVaughan DavisVaughan requested a review from lionel- February 18, 2026 19:20

#[derive(Debug, Eq, PartialEq)]
struct ArkStatementRangeSuccess {
range: tree_sitter::Range,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It got very annoying to try and have a StatementRangeSuccess with a LSP Range deep within the roxygen2 code path that I had to convert back to a tree-sitter Range to perform the "subdocument adjustment" on.

I think it is better to have our own Ark* types here that use our internal data structure, and only convert to and from the LSP types once at the boundaries.

This feels similar to what rust-analyzer does?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yep I think that's generally our ideal pattern in Ark/Air

(Ideally that'd be something based on TextPos, now that we've started using Rowan, but it does seem fine to have a TS type for now since that's what being consumed downstream.)

Comment on lines +435 to 449
fn adjust_roxygen_examples_rejection(
subdocument_rejection: ArkStatementRangeRejection,
row_adjustment: usize,
) -> Option<ArkStatementRangeRejection> {
match subdocument_rejection {
ArkStatementRangeRejection::Syntax(subdocument_rejection) => {
// Adjust line number of the syntax rejection to reflect original document
Some(ArkStatementRangeRejection::Syntax(
ArkStatementRangeSyntaxRejection {
line: subdocument_rejection.line + row_adjustment as u32,
},
))
},
}
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Small bit of magic here, but it's not really that fancy!

Comment on lines -392 to 517
// anywhere past the first parse error, returning `None`, so that the frontend
// sends code to the console one line at a time (posit-dev/positron#5023,
// posit-dev/positron#8350).
// anywhere past the first parse error, returning a syntax rejection that points
// to the first line in this child node, which the frontend will show the user
// (posit-dev/positron#5023, posit-dev/positron#8350).
if node_has_error_or_missing(&child) {
return None;
let line = child.start_position().row as u32;
return Ok(Some(ArkStatementRangeResponse::Rejection(
ArkStatementRangeRejection::Syntax(ArkStatementRangeSyntaxRejection { line }),
)));
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here's where we newly switch from None to a StatementRangeSyntaxRejection, which propagates up through both the normal R code path and the roxygen2 code path

Comment on lines -1837 to +2011
assert!(range.is_none());
assert_matches::assert_matches!(
rejection,
ArkStatementRangeRejection::Syntax(ArkStatementRangeSyntaxRejection { line: 1 })
);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a lot of churn in the tests, but changes like this one in our existing tests are the meaningful bits


#[derive(Debug, Eq, PartialEq)]
struct ArkStatementRangeSuccess {
range: tree_sitter::Range,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yep I think that's generally our ideal pattern in Ark/Air

(Ideally that'd be something based on TextPos, now that we've started using Rowan, but it does seem fine to have a TS type for now since that's what being consumed downstream.)

@DavisVaughan DavisVaughan merged commit f29cfdb into feature/statement-range-error Feb 24, 2026
8 checks passed
@DavisVaughan DavisVaughan deleted the feature/statement-range-error-2 branch February 24, 2026 18:53
@github-actions github-actions bot locked and limited conversation to collaborators Feb 24, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants