@@ -49,6 +49,7 @@ package final actor DocumentationManager {
49
49
50
50
var externalIDsToConvert : [ String ] ?
51
51
var symbolGraphs = [ Data] ( )
52
+ var overridingDocumentationComments = [ String: [ String] ] ( )
52
53
switch snapshot. language {
53
54
case . swift:
54
55
guard let languageService = await sourceKitLSPServer. languageService ( for: documentURI, . swift, in: workspace) ,
@@ -59,7 +60,7 @@ package final actor DocumentationManager {
59
60
// Search for the nearest documentable symbol at this location
60
61
let syntaxTree = await swiftLanguageService. syntaxTreeManager. syntaxTree ( for: snapshot)
61
62
guard
62
- let absoluteSymbolPosition = DocumentableSymbolFinder . find (
63
+ let nearestDocumentableSymbol = DocumentableSymbolFinder . find (
63
64
in: [ Syntax ( syntaxTree) ] ,
64
65
at: snapshot. absolutePosition ( of: position)
65
66
)
@@ -68,7 +69,7 @@ package final actor DocumentationManager {
68
69
}
69
70
// Retrieve the symbol graph as well as information about the symbol
70
71
let position = await swiftLanguageService. adjustPositionToStartOfIdentifier (
71
- snapshot. position ( of: absoluteSymbolPosition ) ,
72
+ snapshot. position ( of: nearestDocumentableSymbol . position ) ,
72
73
in: snapshot
73
74
)
74
75
let ( cursorInfo, _, symbolGraph) = try await swiftLanguageService. cursorInfo (
@@ -88,6 +89,7 @@ package final actor DocumentationManager {
88
89
}
89
90
externalIDsToConvert = [ symbolUSR]
90
91
symbolGraphs. append ( rawSymbolGraph)
92
+ overridingDocumentationComments [ symbolUSR] = nearestDocumentableSymbol. documentationComments
91
93
default :
92
94
return . error( . noDocumentation)
93
95
}
@@ -101,6 +103,7 @@ package final actor DocumentationManager {
101
103
documentationBundleDisplayName: moduleName ?? " Unknown " ,
102
104
documentationBundleIdentifier: " unknown " ,
103
105
symbolGraphs: symbolGraphs,
106
+ overridingDocumentationComments: overridingDocumentationComments,
104
107
emitSymbolSourceFileURIs: false ,
105
108
markupFiles: [ ] ,
106
109
tutorialFiles: [ ] ,
@@ -126,10 +129,15 @@ package final actor DocumentationManager {
126
129
}
127
130
128
131
fileprivate final class DocumentableSymbolFinder : SyntaxAnyVisitor {
132
+ struct Symbol {
133
+ let position : AbsolutePosition
134
+ let documentationComments : [ String ]
135
+ }
136
+
129
137
private let cursorPosition : AbsolutePosition
130
138
131
139
/// Accumulating the result in here.
132
- private var result : AbsolutePosition ? = nil
140
+ private var result : Symbol ? = nil
133
141
134
142
private init ( _ cursorPosition: AbsolutePosition ) {
135
143
self . cursorPosition = cursorPosition
@@ -140,17 +148,37 @@ fileprivate final class DocumentableSymbolFinder: SyntaxAnyVisitor {
140
148
static func find(
141
149
in nodes: some Sequence < Syntax > ,
142
150
at cursorPosition: AbsolutePosition
143
- ) -> AbsolutePosition ? {
151
+ ) -> Symbol ? {
144
152
let visitor = DocumentableSymbolFinder ( cursorPosition)
145
153
for node in nodes {
146
154
visitor. walk ( node)
147
155
}
148
156
return visitor. result
149
157
}
150
158
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 {
152
180
if result == nil {
153
- result = symbolPosition
181
+ result = Symbol ( position : symbolPosition, documentationComments : documentationComments )
154
182
}
155
183
return . skipChildren
156
184
}
@@ -160,15 +188,16 @@ fileprivate final class DocumentableSymbolFinder: SyntaxAnyVisitor {
160
188
name: TokenSyntax ,
161
189
memberBlock: MemberBlockSyntax
162
190
) -> SyntaxVisitorContinueKind {
191
+
163
192
if cursorPosition <= memberBlock. leftBrace. positionAfterSkippingLeadingTrivia {
164
- setResult ( name. positionAfterSkippingLeadingTrivia)
193
+ setResult ( node : node , position : name. positionAfterSkippingLeadingTrivia)
165
194
} else if let child = DocumentableSymbolFinder . find (
166
195
in: memberBlock. children ( viewMode: . sourceAccurate) ,
167
196
at: cursorPosition
168
197
) {
169
- setResult ( child)
198
+ setResult ( child. position , child . documentationComments )
170
199
} else if node. range. contains ( cursorPosition) {
171
- setResult ( name. positionAfterSkippingLeadingTrivia)
200
+ setResult ( node : node , position : name. positionAfterSkippingLeadingTrivia)
172
201
}
173
202
return . skipChildren
174
203
}
@@ -196,7 +225,7 @@ fileprivate final class DocumentableSymbolFinder: SyntaxAnyVisitor {
196
225
override func visit( _ node: FunctionDeclSyntax ) -> SyntaxVisitorContinueKind {
197
226
let symbolPosition = node. name. positionAfterSkippingLeadingTrivia
198
227
if node. range. contains ( cursorPosition) || cursorPosition < symbolPosition {
199
- setResult ( symbolPosition)
228
+ setResult ( node : node , position : symbolPosition)
200
229
}
201
230
return . skipChildren
202
231
}
@@ -212,15 +241,15 @@ fileprivate final class DocumentableSymbolFinder: SyntaxAnyVisitor {
212
241
override func visit( _ node: InitializerDeclSyntax ) -> SyntaxVisitorContinueKind {
213
242
let symbolPosition = node. initKeyword. positionAfterSkippingLeadingTrivia
214
243
if node. range. contains ( cursorPosition) || cursorPosition < symbolPosition {
215
- setResult ( symbolPosition)
244
+ setResult ( node : node , position : symbolPosition)
216
245
}
217
246
return . skipChildren
218
247
}
219
248
220
249
override func visit( _ node: EnumCaseElementSyntax ) -> SyntaxVisitorContinueKind {
221
250
let symbolPosition = node. name. positionAfterSkippingLeadingTrivia
222
251
if node. range. contains ( cursorPosition) || cursorPosition < symbolPosition {
223
- setResult ( symbolPosition)
252
+ setResult ( node : node , position : symbolPosition)
224
253
}
225
254
return . skipChildren
226
255
}
@@ -234,7 +263,7 @@ fileprivate final class DocumentableSymbolFinder: SyntaxAnyVisitor {
234
263
}
235
264
let symbolPosition = identifier. positionAfterSkippingLeadingTrivia
236
265
if node. range. contains ( cursorPosition) || cursorPosition < symbolPosition {
237
- setResult ( symbolPosition)
266
+ setResult ( node : node , position : symbolPosition)
238
267
}
239
268
return . skipChildren
240
269
}
0 commit comments