Skip to content

Commit d6be00c

Browse files
use overridingDocumentationComments to grab the latest comments directly from the snapshot
1 parent d4b63a2 commit d6be00c

File tree

3 files changed

+196
-83
lines changed

3 files changed

+196
-83
lines changed

Sources/SourceKitLSP/Documentation/DocCServer.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ package struct DocCServer {
3131
documentationBundleDisplayName: String,
3232
documentationBundleIdentifier: String,
3333
symbolGraphs: [Data],
34+
overridingDocumentationComments: [String: [String]] = [:],
3435
emitSymbolSourceFileURIs: Bool,
3536
markupFiles: [Data],
3637
tutorialFiles: [Data],
@@ -50,7 +51,9 @@ package struct DocCServer {
5051
includeRenderReferenceStore: includeRenderReferenceStore,
5152
bundleLocation: documentationBundleLocation,
5253
symbolGraphs: symbolGraphs,
53-
overridingDocumentationComments: nil,
54+
overridingDocumentationComments: overridingDocumentationComments.mapValues {
55+
$0.map { ConvertRequest.Line(text: $0) }
56+
},
5457
knownDisambiguatedSymbolPathComponents: nil,
5558
emitSymbolSourceFileURIs: emitSymbolSourceFileURIs,
5659
markupFiles: markupFiles,

Sources/SourceKitLSP/Documentation/DocumentationManager.swift

Lines changed: 42 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ package final actor DocumentationManager {
4949

5050
var externalIDsToConvert: [String]?
5151
var symbolGraphs = [Data]()
52+
var overridingDocumentationComments = [String: [String]]()
5253
switch snapshot.language {
5354
case .swift:
5455
guard let languageService = await sourceKitLSPServer.languageService(for: documentURI, .swift, in: workspace),
@@ -59,7 +60,7 @@ package final actor DocumentationManager {
5960
// Search for the nearest documentable symbol at this location
6061
let syntaxTree = await swiftLanguageService.syntaxTreeManager.syntaxTree(for: snapshot)
6162
guard
62-
let absoluteSymbolPosition = DocumentableSymbolFinder.find(
63+
let nearestDocumentableSymbol = DocumentableSymbolFinder.find(
6364
in: [Syntax(syntaxTree)],
6465
at: snapshot.absolutePosition(of: position)
6566
)
@@ -68,7 +69,7 @@ package final actor DocumentationManager {
6869
}
6970
// Retrieve the symbol graph as well as information about the symbol
7071
let position = await swiftLanguageService.adjustPositionToStartOfIdentifier(
71-
snapshot.position(of: absoluteSymbolPosition),
72+
snapshot.position(of: nearestDocumentableSymbol.position),
7273
in: snapshot
7374
)
7475
let (cursorInfo, _, symbolGraph) = try await swiftLanguageService.cursorInfo(
@@ -88,6 +89,7 @@ package final actor DocumentationManager {
8889
}
8990
externalIDsToConvert = [symbolUSR]
9091
symbolGraphs.append(rawSymbolGraph)
92+
overridingDocumentationComments[symbolUSR] = nearestDocumentableSymbol.documentationComments
9193
default:
9294
return .error(.noDocumentation)
9395
}
@@ -101,6 +103,7 @@ package final actor DocumentationManager {
101103
documentationBundleDisplayName: moduleName ?? "Unknown",
102104
documentationBundleIdentifier: "unknown",
103105
symbolGraphs: symbolGraphs,
106+
overridingDocumentationComments: overridingDocumentationComments,
104107
emitSymbolSourceFileURIs: false,
105108
markupFiles: [],
106109
tutorialFiles: [],
@@ -126,10 +129,15 @@ package final actor DocumentationManager {
126129
}
127130

128131
fileprivate final class DocumentableSymbolFinder: SyntaxAnyVisitor {
132+
struct Symbol {
133+
let position: AbsolutePosition
134+
let documentationComments: [String]
135+
}
136+
129137
private let cursorPosition: AbsolutePosition
130138

131139
/// Accumulating the result in here.
132-
private var result: AbsolutePosition? = nil
140+
private var result: Symbol? = nil
133141

134142
private init(_ cursorPosition: AbsolutePosition) {
135143
self.cursorPosition = cursorPosition
@@ -140,17 +148,37 @@ fileprivate final class DocumentableSymbolFinder: SyntaxAnyVisitor {
140148
static func find(
141149
in nodes: some Sequence<Syntax>,
142150
at cursorPosition: AbsolutePosition
143-
) -> AbsolutePosition? {
151+
) -> Symbol? {
144152
let visitor = DocumentableSymbolFinder(cursorPosition)
145153
for node in nodes {
146154
visitor.walk(node)
147155
}
148156
return visitor.result
149157
}
150158

151-
@discardableResult private func setResult(_ symbolPosition: AbsolutePosition) -> SyntaxVisitorContinueKind {
159+
@discardableResult private func setResult(
160+
node: some SyntaxProtocol,
161+
position: AbsolutePosition
162+
) -> SyntaxVisitorContinueKind {
163+
return setResult(
164+
position,
165+
node.leadingTrivia.compactMap { trivia in
166+
switch trivia {
167+
case .docLineComment(let comment):
168+
return String(comment.dropFirst(3).trimmingCharacters(in: .whitespaces))
169+
default:
170+
return nil
171+
}
172+
}
173+
)
174+
}
175+
176+
@discardableResult private func setResult(
177+
_ symbolPosition: AbsolutePosition,
178+
_ documentationComments: [String]
179+
) -> SyntaxVisitorContinueKind {
152180
if result == nil {
153-
result = symbolPosition
181+
result = Symbol(position: symbolPosition, documentationComments: documentationComments)
154182
}
155183
return .skipChildren
156184
}
@@ -160,15 +188,16 @@ fileprivate final class DocumentableSymbolFinder: SyntaxAnyVisitor {
160188
name: TokenSyntax,
161189
memberBlock: MemberBlockSyntax
162190
) -> SyntaxVisitorContinueKind {
191+
163192
if cursorPosition <= memberBlock.leftBrace.positionAfterSkippingLeadingTrivia {
164-
setResult(name.positionAfterSkippingLeadingTrivia)
193+
setResult(node: node, position: name.positionAfterSkippingLeadingTrivia)
165194
} else if let child = DocumentableSymbolFinder.find(
166195
in: memberBlock.children(viewMode: .sourceAccurate),
167196
at: cursorPosition
168197
) {
169-
setResult(child)
198+
setResult(child.position, child.documentationComments)
170199
} else if node.range.contains(cursorPosition) {
171-
setResult(name.positionAfterSkippingLeadingTrivia)
200+
setResult(node: node, position: name.positionAfterSkippingLeadingTrivia)
172201
}
173202
return .skipChildren
174203
}
@@ -196,7 +225,7 @@ fileprivate final class DocumentableSymbolFinder: SyntaxAnyVisitor {
196225
override func visit(_ node: FunctionDeclSyntax) -> SyntaxVisitorContinueKind {
197226
let symbolPosition = node.name.positionAfterSkippingLeadingTrivia
198227
if node.range.contains(cursorPosition) || cursorPosition < symbolPosition {
199-
setResult(symbolPosition)
228+
setResult(node: node, position: symbolPosition)
200229
}
201230
return .skipChildren
202231
}
@@ -212,15 +241,15 @@ fileprivate final class DocumentableSymbolFinder: SyntaxAnyVisitor {
212241
override func visit(_ node: InitializerDeclSyntax) -> SyntaxVisitorContinueKind {
213242
let symbolPosition = node.initKeyword.positionAfterSkippingLeadingTrivia
214243
if node.range.contains(cursorPosition) || cursorPosition < symbolPosition {
215-
setResult(symbolPosition)
244+
setResult(node: node, position: symbolPosition)
216245
}
217246
return .skipChildren
218247
}
219248

220249
override func visit(_ node: EnumCaseElementSyntax) -> SyntaxVisitorContinueKind {
221250
let symbolPosition = node.name.positionAfterSkippingLeadingTrivia
222251
if node.range.contains(cursorPosition) || cursorPosition < symbolPosition {
223-
setResult(symbolPosition)
252+
setResult(node: node, position: symbolPosition)
224253
}
225254
return .skipChildren
226255
}
@@ -234,7 +263,7 @@ fileprivate final class DocumentableSymbolFinder: SyntaxAnyVisitor {
234263
}
235264
let symbolPosition = identifier.positionAfterSkippingLeadingTrivia
236265
if node.range.contains(cursorPosition) || cursorPosition < symbolPosition {
237-
setResult(symbolPosition)
266+
setResult(node: node, position: symbolPosition)
238267
}
239268
return .skipChildren
240269
}

0 commit comments

Comments
 (0)