Skip to content

Commit 17ad9b4

Browse files
simplify DocumentableSymbolFinder
1 parent 74cb30e commit 17ad9b4

File tree

1 file changed

+41
-37
lines changed

1 file changed

+41
-37
lines changed

Sources/SourceKitLSP/Documentation/DocumentationManager.swift

Lines changed: 41 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -150,19 +150,22 @@ fileprivate final class DocumentableSymbolFinder: SyntaxAnyVisitor {
150150
struct Symbol {
151151
let position: AbsolutePosition
152152
let documentationComments: [String]
153+
let depth: Int
153154
}
154155

155156
private let cursorPosition: AbsolutePosition
156157

157158
/// Accumulating the result in here.
158159
private var result: Symbol? = nil
159160

161+
private var depth: Int = 0
162+
160163
private init(_ cursorPosition: AbsolutePosition) {
161164
self.cursorPosition = cursorPosition
162165
super.init(viewMode: .sourceAccurate)
163166
}
164167

165-
/// Designated entry point for `DocumentableSymbolFinder`.
168+
/// Designated entry point for ``DocumentableSymbolFinder``.
166169
static func find(
167170
in nodes: some Sequence<Syntax>,
168171
at cursorPosition: AbsolutePosition
@@ -176,7 +179,7 @@ fileprivate final class DocumentableSymbolFinder: SyntaxAnyVisitor {
176179

177180
private func setResult(node: some SyntaxProtocol, position: AbsolutePosition) {
178181
setResult(
179-
result: Symbol(
182+
symbol: Symbol(
180183
position: position,
181184
documentationComments: node.leadingTrivia.flatMap { trivia -> [String] in
182185
switch trivia {
@@ -190,71 +193,74 @@ fileprivate final class DocumentableSymbolFinder: SyntaxAnyVisitor {
190193
default:
191194
return []
192195
}
193-
}
196+
},
197+
depth: depth
194198
)
195199
)
196200
}
197201

198-
private func setResult(result symbol: Symbol) {
199-
if result == nil {
200-
result = symbol
202+
private func setResult(symbol: Symbol) {
203+
guard symbol.depth > result?.depth ?? -1 else {
204+
return
201205
}
206+
result = symbol
202207
}
203208

204-
private func visitNamedDeclWithMemberBlock(
205-
node: some SyntaxProtocol,
206-
name: TokenSyntax,
207-
memberBlock: MemberBlockSyntax
208-
) -> SyntaxVisitorContinueKind {
209-
if cursorPosition <= memberBlock.leftBrace.positionAfterSkippingLeadingTrivia {
210-
setResult(node: node, position: name.positionAfterSkippingLeadingTrivia)
211-
} else if let child = DocumentableSymbolFinder.find(
212-
in: memberBlock.children(viewMode: .sourceAccurate),
213-
at: cursorPosition
214-
) {
215-
setResult(result: child)
216-
} else if node.range.contains(cursorPosition) {
217-
setResult(node: node, position: name.positionAfterSkippingLeadingTrivia)
209+
override func visitAny(_ node: Syntax) -> SyntaxVisitorContinueKind {
210+
guard depth > result?.depth ?? -1 else {
211+
return .skipChildren
218212
}
219-
return .skipChildren
213+
return .visitChildren
214+
}
215+
216+
private func visitNamedDecl(node: some NamedDeclSyntax) -> SyntaxVisitorContinueKind {
217+
if cursorPosition < node.range.upperBound {
218+
setResult(node: node, position: node.name.positionAfterSkippingLeadingTrivia)
219+
}
220+
return .visitChildren
220221
}
221222

222223
override func visit(_ node: StructDeclSyntax) -> SyntaxVisitorContinueKind {
223-
visitNamedDeclWithMemberBlock(node: node, name: node.name, memberBlock: node.memberBlock)
224+
visitNamedDecl(node: node)
224225
}
225226

226227
override func visit(_ node: ClassDeclSyntax) -> SyntaxVisitorContinueKind {
227-
visitNamedDeclWithMemberBlock(node: node, name: node.name, memberBlock: node.memberBlock)
228+
visitNamedDecl(node: node)
228229
}
229230

230231
override func visit(_ node: ActorDeclSyntax) -> SyntaxVisitorContinueKind {
231-
visitNamedDeclWithMemberBlock(node: node, name: node.name, memberBlock: node.memberBlock)
232+
visitNamedDecl(node: node)
232233
}
233234

234235
override func visit(_ node: EnumDeclSyntax) -> SyntaxVisitorContinueKind {
235-
visitNamedDeclWithMemberBlock(node: node, name: node.name, memberBlock: node.memberBlock)
236+
visitNamedDecl(node: node)
236237
}
237238

238239
override func visit(_ node: ProtocolDeclSyntax) -> SyntaxVisitorContinueKind {
239-
visitNamedDeclWithMemberBlock(node: node, name: node.name, memberBlock: node.memberBlock)
240-
}
241-
242-
override func visit(_ node: FunctionDeclSyntax) -> SyntaxVisitorContinueKind {
243-
let symbolPosition = node.name.positionAfterSkippingLeadingTrivia
244-
if node.range.contains(cursorPosition) || cursorPosition < symbolPosition {
245-
setResult(node: node, position: symbolPosition)
246-
}
247-
return .skipChildren
240+
visitNamedDecl(node: node)
248241
}
249242

250243
override func visit(_ node: MemberBlockSyntax) -> SyntaxVisitorContinueKind {
244+
depth += 1
251245
let range = node.leftBrace.endPositionBeforeTrailingTrivia..<node.rightBrace.positionAfterSkippingLeadingTrivia
252246
guard range.contains(cursorPosition) else {
253247
return .skipChildren
254248
}
255249
return .visitChildren
256250
}
257251

252+
override func visitPost(_ node: MemberBlockSyntax) {
253+
depth -= 1;
254+
}
255+
256+
override func visit(_ node: FunctionDeclSyntax) -> SyntaxVisitorContinueKind {
257+
let symbolPosition = node.name.positionAfterSkippingLeadingTrivia
258+
if cursorPosition < node.range.upperBound {
259+
setResult(node: node, position: symbolPosition)
260+
}
261+
return .skipChildren
262+
}
263+
258264
override func visit(_ node: InitializerDeclSyntax) -> SyntaxVisitorContinueKind {
259265
let symbolPosition = node.initKeyword.positionAfterSkippingLeadingTrivia
260266
if node.range.contains(cursorPosition) || cursorPosition < symbolPosition {
@@ -275,9 +281,7 @@ fileprivate final class DocumentableSymbolFinder: SyntaxAnyVisitor {
275281

276282
override func visit(_ node: VariableDeclSyntax) -> SyntaxVisitorContinueKind {
277283
// A variable declaration is only documentable if there is only one pattern binding
278-
guard node.bindings.count == 1,
279-
let identifier = node.bindings.first!.pattern.as(IdentifierPatternSyntax.self)
280-
else {
284+
guard let identifier = node.bindings.only?.pattern.as(IdentifierPatternSyntax.self) else {
281285
return .skipChildren
282286
}
283287
let symbolPosition = identifier.positionAfterSkippingLeadingTrivia

0 commit comments

Comments
 (0)