Skip to content

Conversation

@lokesh-tr
Copy link
Contributor

@lokesh-tr lokesh-tr commented Dec 22, 2025

⚠️ Under Progress ⚠️

  • Explanation:
    Upgrades textDocument/documentHighlight to highlight various return / throw statements corresponding to a function / closure / accessor / init / deinit, and break / continue statements corresponding to a loop, thereby allowing us to not wonder about which statements could cause an exit from a function or loop.

This also makes use of a new API introduced in SwiftLexicalLookup Library in Swift Syntax.

…e/accessor/init/deinit) and break / continue (for/while/repeat...while)
@lokesh-tr lokesh-tr changed the title Implement Document Highlight for all return / throws (function/closure/accessor/init/deinit) and break / continue (for/while/repeat...while) 🚥 Implement Document Highlight for all return / throws (function/closure/accessor/init/deinit) and break / continue (for/while/repeat...while) Dec 22, 2025
@lokesh-tr
Copy link
Contributor Author

This is how it looks:

Inner function return statements are highlighted Outer function return statements are highlighted

Copy link
Member

@ahoppen ahoppen left a comment

Choose a reason for hiding this comment

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

Very nice and excited for this. 😍

A preliminary review, as you already noted in the PR description, a few tests would be good 😉

}
}

override func visit(_ node: BreakStmtSyntax) -> SyntaxVisitorContinueKind {
Copy link
Member

Choose a reason for hiding this comment

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

You shouldn’t need to repeat the list of control flow nodes if this is a SyntaxAnyVisitor and you add a visitAny override.

}

private func addHighlightIfMatches(_ node: some SyntaxProtocol) {
if node.lookupControlStructure() == targetStructure {
Copy link
Member

Choose a reason for hiding this comment

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

This could be a guard to avoid the nesting level.

if node.lookupControlStructure() == targetStructure {
highlights.append(
DocumentHighlight(
range: snapshot.absolutePositionRange(of: node.firstToken(viewMode: .sourceAccurate).map { $0.positionAfterSkippingLeadingTrivia..<$0.endPositionBeforeTrailingTrivia } ?? node.positionAfterSkippingLeadingTrivia..<node.endPositionBeforeTrailingTrivia),
Copy link
Member

Choose a reason for hiding this comment

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

Could you run swift-format on your changes?

if node.lookupControlStructure() == targetStructure {
highlights.append(
DocumentHighlight(
range: snapshot.absolutePositionRange(of: node.firstToken(viewMode: .sourceAccurate).map { $0.positionAfterSkippingLeadingTrivia..<$0.endPositionBeforeTrailingTrivia } ?? node.positionAfterSkippingLeadingTrivia..<node.endPositionBeforeTrailingTrivia),
Copy link
Member

Choose a reason for hiding this comment

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

While currently the return/break etc keyword is always the first token in the syntax node, this may change in the future. I’d prefer if we explicitly pass in the token to highlight.

if node.lookupControlStructure() == targetStructure {
highlights.append(
DocumentHighlight(
range: snapshot.absolutePositionRange(of: node.firstToken(viewMode: .sourceAccurate).map { $0.positionAfterSkippingLeadingTrivia..<$0.endPositionBeforeTrailingTrivia } ?? node.positionAfterSkippingLeadingTrivia..<node.endPositionBeforeTrailingTrivia),
Copy link
Member

Choose a reason for hiding this comment

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

Instead of $0.positionAfterSkippingLeadingTrivia..<$0.endPositionBeforeTrailingTrivia you should be able to do $0.trimmedRange or something like that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Highlight related identifiers for control flow keywords

2 participants