Skip to content

Commit bfbbb2f

Browse files
improve token searching in findNearestSymbol(syntaxTree:position:)
1 parent 6b6703e commit bfbbb2f

File tree

1 file changed

+16
-6
lines changed

1 file changed

+16
-6
lines changed

Sources/SourceKitLSP/Swift/DoccDocumentation.swift

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -157,23 +157,33 @@ fileprivate struct DocumentableSymbol {
157157
}
158158

159159
static func findNearestSymbol(syntaxTree: SourceFileSyntax, position: AbsolutePosition) -> DocumentableSymbol? {
160-
// token(at:) can return nil if the position is at the end of the document. Fall back to using the last token in this case.
161-
let token = syntaxTree.token(at: position) ?? syntaxTree.lastToken(viewMode: .all)
160+
let token: TokenSyntax
161+
if let tokenAtPosition = syntaxTree.token(at: position) {
162+
token = tokenAtPosition
163+
} else if position >= syntaxTree.endPosition, let lastToken = syntaxTree.lastToken(viewMode: .sourceAccurate) {
164+
// token(at:) returns nil if position is at the end of the document.
165+
token = lastToken
166+
} else if position < syntaxTree.position, let firstToken = syntaxTree.firstToken(viewMode: .sourceAccurate) {
167+
// No case in practice where this happens but good to cover anyway
168+
token = firstToken
169+
} else {
170+
return nil
171+
}
162172
// Check if the current token is within a valid documentable symbol
163-
if let token, let symbol = token.ancestorOrSelf(mapping: { DocumentableSymbol(node: $0) }) {
173+
if let symbol = token.ancestorOrSelf(mapping: { DocumentableSymbol(node: $0) }) {
164174
return symbol
165175
}
166176
// Walk forward through the tokens until we find a documentable symbol
167-
var previousToken = token
168-
while let nextToken = previousToken?.nextToken(viewMode: .all) {
177+
var previousToken: TokenSyntax? = token
178+
while let nextToken = previousToken?.nextToken(viewMode: .sourceAccurate) {
169179
if let symbol = nextToken.ancestorOrSelf(mapping: { DocumentableSymbol(node: $0) }) {
170180
return symbol
171181
}
172182
previousToken = nextToken
173183
}
174184
// Walk backwards through the tokens until we find a documentable symbol
175185
previousToken = token
176-
while let nextToken = previousToken?.previousToken(viewMode: .all) {
186+
while let nextToken = previousToken?.previousToken(viewMode: .sourceAccurate) {
177187
if let symbol = nextToken.ancestorOrSelf(mapping: { DocumentableSymbol(node: $0) }) {
178188
return symbol
179189
}

0 commit comments

Comments
 (0)