Skip to content

Conversation

@Clemo97
Copy link
Contributor

@Clemo97 Clemo97 commented Dec 18, 2025

Fixes #2368

This PR suppresses jump-to-definition for literal values (strings, integers, floats, booleans, arrays, dictionaries, and nil).

Implementation:

  • Added isPositionOnLiteral() method to LanguageService protocol with default implementation
  • Implemented literal detection in SwiftLanguageService using SwiftSyntax tree traversal
  • Added early return check in indexBasedDefinition() to skip literals

Testing:

  • Added testDefinitionOnLiteralsShouldReturnEmpty() covering string, integer, boolean, and array literals

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.

Thanks for opening the PR. Looks like the right direction, I left a few comments inline.

Comment on lines +1320 to +1334
while let node = currentNode {
// Check all literal expression types
if node.is(StringLiteralExprSyntax.self)
|| node.is(IntegerLiteralExprSyntax.self)
|| node.is(FloatLiteralExprSyntax.self)
|| node.is(BooleanLiteralExprSyntax.self)
|| node.is(ArrayExprSyntax.self)
|| node.is(DictionaryExprSyntax.self)
|| node.is(NilLiteralExprSyntax.self)
{
return true
}
currentNode = node.parent
}
return false
Copy link
Member

Choose a reason for hiding this comment

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

This will also prevent all jump-to-definition functionality for code inside literals, eg. jump-to-definition will no longer work inside literals, eg. you couldn’t jump to the definition of foo anymore in "Value: \(foo)" or [foo]. Instead, what I think we should do, is to check if the tokenKind is stringSegment, integerLiteral or floatLiteral. Maybe you can find other token kinds as well that we should suppress as well, I didn’t walk through all of them.

Comment on lines +1344 to +1351
// Also check the token before the cursor position, as users might click right after a literal
if absolutePosition.utf8Offset > 0,
let tokenBefore = tree.token(at: AbsolutePosition(utf8Offset: absolutePosition.utf8Offset - 1))
{
if isTokenInLiteral(tokenBefore) {
return true
}
}
Copy link
Member

Choose a reason for hiding this comment

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

Hmm, that’s quite unfortunate. I would prefer if we could find this previous token using token.previousToken(viewMode: .sourceAccurate) because it will not need to do a tree traversal to find the token again and should thus be more efficient. It likely won’t matter much in practice but still.

Comment on lines +2047 to +2050
// Check if the position is on a literal value (string, integer, etc.)
if await languageService.isPositionOnLiteral(req.position, in: req.textDocument.uri) {
return []
}
Copy link
Member

Choose a reason for hiding this comment

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

I think we should do this check in SwiftLanguageService.symbolInfo. I think we want to suppress the jump-to-definition kind of behavior as well for all the callers of symbolInfo (implementation, definition, call hierarchy, type hierarchy, find references).

@Clemo97
Copy link
Contributor Author

Clemo97 commented Dec 18, 2025

Thank you for the feedback @ahoppen.
Let me make the necessary changes 👍.

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.

Do not offer jump-to-definition for literals

2 participants