@@ -46,7 +46,7 @@ extension SwiftLanguageService {
46
46
let nearestDocumentableSymbol = DocumentableSymbol . findNearestSymbol (
47
47
syntaxTree: syntaxTree,
48
48
position: snapshot. absolutePosition ( of: position)
49
- ) ?? DocumentableSymbol . findTopLevelSymbol ( syntaxTree : syntaxTree )
49
+ )
50
50
else {
51
51
throw ResponseError . requestFailed ( doccDocumentationError: . noDocumentableSymbols)
52
52
}
@@ -152,34 +152,31 @@ fileprivate struct DocumentableSymbol {
152
152
}
153
153
}
154
154
155
- static func findTopLevelSymbol( syntaxTree: SourceFileSyntax ) -> DocumentableSymbol ? {
156
- class Visitor : SyntaxAnyVisitor {
157
- var topLevelSymbol : DocumentableSymbol ? = nil
158
-
159
- override func visitAny( _ node: Syntax ) -> SyntaxVisitorContinueKind {
160
- guard topLevelSymbol == nil else {
161
- return . skipChildren
162
- }
163
-
164
- if let symbol = DocumentableSymbol ( node: node) {
165
- topLevelSymbol = symbol
166
- return . skipChildren
167
- }
168
- return . visitChildren
155
+ static func findNearestSymbol( syntaxTree: SourceFileSyntax , position: AbsolutePosition ) -> DocumentableSymbol ? {
156
+ // 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.
157
+ let token = syntaxTree. token ( at: position) ?? syntaxTree. lastToken ( viewMode: . all)
158
+ // Check if the current token is within a valid documentable symbol
159
+ if let token, let symbol = token. ancestorOrSelf ( mapping: { DocumentableSymbol ( node: $0) } ) {
160
+ return symbol
161
+ }
162
+ // Walk forward through the tokens until we find a documentable symbol
163
+ var previousToken = token
164
+ while let nextToken = previousToken? . nextToken ( viewMode: . all) {
165
+ if let symbol = nextToken. ancestorOrSelf ( mapping: { DocumentableSymbol ( node: $0) } ) {
166
+ return symbol
169
167
}
168
+ previousToken = nextToken
170
169
}
171
-
172
- let visitor = Visitor ( viewMode: . all)
173
- visitor. walk ( syntaxTree)
174
- return visitor. topLevelSymbol
175
- }
176
-
177
- static func findNearestSymbol( syntaxTree: SourceFileSyntax , position: AbsolutePosition ) -> DocumentableSymbol ? {
178
- guard let token = syntaxTree. token ( at: position) else {
179
- return nil
170
+ // Walk backwards through the tokens until we find a documentable symbol
171
+ previousToken = token
172
+ while let nextToken = previousToken? . previousToken ( viewMode: . all) {
173
+ if let symbol = nextToken. ancestorOrSelf ( mapping: { DocumentableSymbol ( node: $0) } ) {
174
+ return symbol
175
+ }
176
+ previousToken = nextToken
180
177
}
181
- // Walk up the tree until we find a documentable symbol
182
- return token . ancestorOrSelf { DocumentableSymbol ( node : $0 ) }
178
+ // We couldn't find anything
179
+ return nil
183
180
}
184
181
}
185
182
#endif
0 commit comments