Skip to content

Commit fb2c293

Browse files
support documentation block comments
1 parent d6be00c commit fb2c293

File tree

2 files changed

+66
-22
lines changed

2 files changed

+66
-22
lines changed

Sources/SourceKitLSP/Documentation/DocumentationManager.swift

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -156,31 +156,31 @@ fileprivate final class DocumentableSymbolFinder: SyntaxAnyVisitor {
156156
return visitor.result
157157
}
158158

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
159+
private func setResult(node: some SyntaxProtocol, position: AbsolutePosition) {
160+
setResult(
161+
result: Symbol(
162+
position: position,
163+
documentationComments: node.leadingTrivia.flatMap { trivia -> [String] in
164+
switch trivia {
165+
case .docLineComment(let comment):
166+
return [String(comment.dropFirst(3).trimmingCharacters(in: .whitespaces))]
167+
case .docBlockComment(let comment):
168+
return comment.dropFirst(3)
169+
.dropLast(2)
170+
.split(separator: "\n")
171+
.map { String($0).trimmingCharacters(in: .whitespaces) }
172+
default:
173+
return []
174+
}
171175
}
172-
}
176+
)
173177
)
174178
}
175179

176-
@discardableResult private func setResult(
177-
_ symbolPosition: AbsolutePosition,
178-
_ documentationComments: [String]
179-
) -> SyntaxVisitorContinueKind {
180+
private func setResult(result symbol: Symbol) {
180181
if result == nil {
181-
result = Symbol(position: symbolPosition, documentationComments: documentationComments)
182+
result = symbol
182183
}
183-
return .skipChildren
184184
}
185185

186186
private func visitNamedDeclWithMemberBlock(
@@ -195,7 +195,7 @@ fileprivate final class DocumentableSymbolFinder: SyntaxAnyVisitor {
195195
in: memberBlock.children(viewMode: .sourceAccurate),
196196
at: cursorPosition
197197
) {
198-
setResult(child.position, child.documentationComments)
198+
setResult(result: child)
199199
} else if node.range.contains(cursorPosition) {
200200
setResult(node: node, position: name.positionAfterSkippingLeadingTrivia)
201201
}

Tests/SourceKitLSPTests/ConvertDocumentationTests.swift

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,7 @@ final class ConvertDocumentationTests: XCTestCase {
292292
)
293293
}
294294

295-
func testEditCommentInSwiftFile() async throws {
295+
func testEditDocLineCommentInSwiftFile() async throws {
296296
let testClient = try await TestSourceKitLSPClient()
297297
let uri = DocumentURI(for: .swift)
298298
let positions = testClient.openDocument(
@@ -332,7 +332,7 @@ final class ConvertDocumentationTests: XCTestCase {
332332
)
333333
}
334334

335-
func testEditMultiLineCommentInSwiftFile() async throws {
335+
func testEditMultipleDocLineCommentsInSwiftFile() async throws {
336336
let testClient = try await TestSourceKitLSPClient()
337337
let uri = DocumentURI(for: .swift)
338338
let positions = testClient.openDocument(
@@ -373,6 +373,50 @@ final class ConvertDocumentationTests: XCTestCase {
373373
expectedResponses: [.renderNode(kind: .symbol, containing: "This is an amazing description")]
374374
)
375375
}
376+
377+
func testEditDocBlockCommentInSwiftFile() async throws {
378+
let testClient = try await TestSourceKitLSPClient()
379+
let uri = DocumentURI(for: .swift)
380+
let positions = testClient.openDocument(
381+
"""
382+
/**
383+
A structure containing important information
384+
385+
This is a0️⃣ description
386+
*/
387+
public struct Structure {
388+
let number: Int
389+
}
390+
""",
391+
uri: uri
392+
)
393+
394+
// Make sure that the initial documentation comment is present in the response
395+
await convertDocumentation(
396+
testClient: testClient,
397+
uri: uri,
398+
positions: positions,
399+
expectedResponses: [.renderNode(kind: .symbol, containing: "This is a description")]
400+
)
401+
402+
// Change the content of the documentation comment
403+
testClient.send(
404+
DidChangeTextDocumentNotification(
405+
textDocument: VersionedTextDocumentIdentifier(uri, version: 2),
406+
contentChanges: [
407+
TextDocumentContentChangeEvent(range: positions["0️⃣"]..<positions["0️⃣"], text: "n amazing")
408+
]
409+
)
410+
)
411+
412+
// Make sure that the new documentation comment is present in the response
413+
await convertDocumentation(
414+
testClient: testClient,
415+
uri: uri,
416+
positions: positions,
417+
expectedResponses: [.renderNode(kind: .symbol, containing: "This is an amazing description")]
418+
)
419+
}
376420
}
377421

378422
fileprivate enum PartialConvertResponse {

0 commit comments

Comments
 (0)