@@ -20,7 +20,7 @@ public enum SyntaxNodeStructure {
2020 /// The node contains a fixed number of children which can be accessed by these key paths.
2121 case layout( [ AnyKeyPath ] )
2222
23- /// The node is a `SyntaxCollection` of the given type.
23+ /// The node is a `SyntaxCollection` with elements of the given type.
2424 case collection( SyntaxProtocol . Type )
2525
2626 /// The node can contain a single node with one of the listed types.
@@ -299,10 +299,14 @@ public extension SyntaxProtocol {
299299 guard let parent = self . parent else {
300300 return nil
301301 }
302- guard case . layout( let childrenKeyPaths) = parent. kind. syntaxNodeType. structure else {
303- return nil
302+ switch parent. kind. syntaxNodeType. structure {
303+ case . layout( let childrenKeyPaths) :
304+ return childrenKeyPaths [ data. indexInParent]
305+ case . collection( _) :
306+ return ( parent. asProtocol ( SyntaxProtocol . self) as! any SyntaxCollection ) . keyPath ( for: self . indexInParent)
307+ case . choices:
308+ preconditionFailure ( " The parent of a syntax node should always be a concrete node and not one with choices " )
304309 }
305- return childrenKeyPaths [ data. indexInParent]
306310 }
307311
308312 @available ( * , deprecated, message: " Use previousToken(viewMode:) instead " )
@@ -823,3 +827,12 @@ extension ReversedTokenSequence: CustomReflectable {
823827/// replaced by the ``Syntax`` type.
824828@available ( * , unavailable, message: " use 'Syntax' instead " )
825829public struct SyntaxNode { }
830+
831+ extension SyntaxCollection {
832+ /// Implementation detail of ``SyntaxProtocol/keyPathInParent``.
833+ ///
834+ /// I couldn't find a way to express this without an extension on ``SyntaxCollection``.
835+ fileprivate func keyPath( for index: SyntaxChildrenIndex ) -> AnyKeyPath {
836+ return \Self [ index]
837+ }
838+ }
0 commit comments