@@ -150,19 +150,22 @@ fileprivate final class DocumentableSymbolFinder: SyntaxAnyVisitor {
150
150
struct Symbol {
151
151
let position : AbsolutePosition
152
152
let documentationComments : [ String ]
153
+ let depth : Int
153
154
}
154
155
155
156
private let cursorPosition : AbsolutePosition
156
157
157
158
/// Accumulating the result in here.
158
159
private var result : Symbol ? = nil
159
160
161
+ private var depth : Int = 0
162
+
160
163
private init ( _ cursorPosition: AbsolutePosition ) {
161
164
self . cursorPosition = cursorPosition
162
165
super. init ( viewMode: . sourceAccurate)
163
166
}
164
167
165
- /// Designated entry point for `DocumentableSymbolFinder`.
168
+ /// Designated entry point for `` DocumentableSymbolFinder` `.
166
169
static func find(
167
170
in nodes: some Sequence < Syntax > ,
168
171
at cursorPosition: AbsolutePosition
@@ -176,7 +179,7 @@ fileprivate final class DocumentableSymbolFinder: SyntaxAnyVisitor {
176
179
177
180
private func setResult( node: some SyntaxProtocol , position: AbsolutePosition ) {
178
181
setResult (
179
- result : Symbol (
182
+ symbol : Symbol (
180
183
position: position,
181
184
documentationComments: node. leadingTrivia. flatMap { trivia -> [ String ] in
182
185
switch trivia {
@@ -190,71 +193,74 @@ fileprivate final class DocumentableSymbolFinder: SyntaxAnyVisitor {
190
193
default :
191
194
return [ ]
192
195
}
193
- }
196
+ } ,
197
+ depth: depth
194
198
)
195
199
)
196
200
}
197
201
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
201
205
}
206
+ result = symbol
202
207
}
203
208
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
218
212
}
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
220
221
}
221
222
222
223
override func visit( _ node: StructDeclSyntax ) -> SyntaxVisitorContinueKind {
223
- visitNamedDeclWithMemberBlock ( node: node, name : node . name , memberBlock : node . memberBlock )
224
+ visitNamedDecl ( node: node)
224
225
}
225
226
226
227
override func visit( _ node: ClassDeclSyntax ) -> SyntaxVisitorContinueKind {
227
- visitNamedDeclWithMemberBlock ( node: node, name : node . name , memberBlock : node . memberBlock )
228
+ visitNamedDecl ( node: node)
228
229
}
229
230
230
231
override func visit( _ node: ActorDeclSyntax ) -> SyntaxVisitorContinueKind {
231
- visitNamedDeclWithMemberBlock ( node: node, name : node . name , memberBlock : node . memberBlock )
232
+ visitNamedDecl ( node: node)
232
233
}
233
234
234
235
override func visit( _ node: EnumDeclSyntax ) -> SyntaxVisitorContinueKind {
235
- visitNamedDeclWithMemberBlock ( node: node, name : node . name , memberBlock : node . memberBlock )
236
+ visitNamedDecl ( node: node)
236
237
}
237
238
238
239
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)
248
241
}
249
242
250
243
override func visit( _ node: MemberBlockSyntax ) -> SyntaxVisitorContinueKind {
244
+ depth += 1
251
245
let range = node. leftBrace. endPositionBeforeTrailingTrivia..< node. rightBrace. positionAfterSkippingLeadingTrivia
252
246
guard range. contains ( cursorPosition) else {
253
247
return . skipChildren
254
248
}
255
249
return . visitChildren
256
250
}
257
251
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
+
258
264
override func visit( _ node: InitializerDeclSyntax ) -> SyntaxVisitorContinueKind {
259
265
let symbolPosition = node. initKeyword. positionAfterSkippingLeadingTrivia
260
266
if node. range. contains ( cursorPosition) || cursorPosition < symbolPosition {
@@ -275,9 +281,7 @@ fileprivate final class DocumentableSymbolFinder: SyntaxAnyVisitor {
275
281
276
282
override func visit( _ node: VariableDeclSyntax ) -> SyntaxVisitorContinueKind {
277
283
// 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 {
281
285
return . skipChildren
282
286
}
283
287
let symbolPosition = identifier. positionAfterSkippingLeadingTrivia
0 commit comments