@@ -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