@@ -110,21 +110,36 @@ extension SyntaxProtocol {
110110 /// (or at least an expression that's very close to constructing this node, the addition of a few manual upcast by hand is still needed).
111111 /// The intended use case for this is to print a syntax tree and create a substructure assertion from the generated expression.
112112 /// When `includeTrivia` is set to `false`, the token's leading and trailing trivia will not be included in the generated expression.
113+ ///
114+ /// - Warning: This is only designed for use in the debugger. Do not call it outside of the debugger.
115+ @available ( * , deprecated, message: " For use in debugger only " )
113116 public func debugInitCall( includeTrivia: Bool = true ) -> String {
114117 return self . debugInitCallExpr ( includeTrivia: includeTrivia) . formatted ( using: InitializerExprFormat ( ) ) . description
115118 }
116119
117120 private func debugInitCallExpr( includeTrivia: Bool ) -> ExprSyntax {
118- let mirror = Mirror ( reflecting: self )
119- if self . kind. isSyntaxCollection {
121+ if type ( of: self ) != self . syntaxNodeType {
122+ let nestedInitCall = Syntax ( self ) . asProtocol ( SyntaxProtocol . self) . debugInitCallExpr ( includeTrivia: includeTrivia)
123+ var typeName = " \( type ( of: self ) ) "
124+ // If the type is `SyntaxChildChoices`, it is a nested type that needs to be qualified.
125+ if self is SyntaxChildChoices , let parent = parent {
126+ typeName = " \( parent. syntaxNodeType) . \( typeName) "
127+ }
128+ return ExprSyntax (
129+ FunctionCallExprSyntax ( callee: ExprSyntax ( " \( raw: typeName) " ) ) {
130+ TupleExprElementSyntax ( expression: nestedInitCall)
131+ }
132+ )
133+ }
134+
135+ if case . collection( let collectionElementType) = self . syntaxNodeType. structure {
120136 let typeName = String ( describing: type ( of: self ) )
121137 return ExprSyntax (
122138 FunctionCallExprSyntax ( callee: IdentifierExprSyntax ( identifier: . identifier( typeName) ) ) {
123139 TupleExprElementSyntax (
124140 expression: ArrayExprSyntax {
125- for child in mirror. children {
126- let value = child. value as! SyntaxProtocol ?
127- ArrayElementSyntax ( expression: value? . debugInitCallExpr ( includeTrivia: includeTrivia) ?? ExprSyntax ( NilLiteralExprSyntax ( ) ) )
141+ for child in self . children ( viewMode: . all) {
142+ ArrayElementSyntax ( expression: child. as ( collectionElementType) !. debugInitCallExpr ( includeTrivia: includeTrivia) )
128143 }
129144 }
130145 )
@@ -134,12 +149,12 @@ extension SyntaxProtocol {
134149 let tokenKind = token. tokenKind
135150 let tokenInitializerName : String
136151 let tokenKindArgument : ExprSyntax ?
137- if tokenKind. isLexerClassifiedKeyword || tokenKind == . eof {
138- tokenInitializerName = String ( describing: tokenKind)
139- tokenKindArgument = nil
140- } else if case . keyword( let keyword) = tokenKind {
152+ if case . keyword( let keyword) = tokenKind {
141153 tokenInitializerName = " keyword "
142154 tokenKindArgument = ExprSyntax ( " . \( raw: keyword) " )
155+ } else if tokenKind. isLexerClassifiedKeyword || tokenKind == . eof {
156+ tokenInitializerName = String ( describing: tokenKind)
157+ tokenKindArgument = nil
143158 } else if tokenKind. decomposeToRaw ( ) . rawKind. defaultText != nil {
144159 tokenInitializerName = " \( String ( describing: tokenKind) ) Token "
145160 tokenKindArgument = nil
@@ -176,15 +191,15 @@ extension SyntaxProtocol {
176191 }
177192 }
178193 )
179- } else {
194+ } else if case . layout ( let layout ) = self . syntaxNodeType . structure {
180195 let typeName = String ( describing: type ( of: self ) )
181196 return ExprSyntax (
182197 FunctionCallExprSyntax ( callee: IdentifierExprSyntax ( identifier: . identifier( typeName) ) ) {
183- for child in mirror . children {
184- let label = child . label!
185- let value = child . value as! SyntaxProtocol ?
198+ for keyPath in layout {
199+ let label = childName ( keyPath ) ?? " "
200+ let value = self [ keyPath : keyPath as! PartialKeyPath < Self > ] as! SyntaxProtocol ?
186201 let isUnexpected = label. hasPrefix ( " unexpected " )
187- if !isUnexpected || value != nil {
202+ if value != nil {
188203 TupleExprElementSyntax (
189204 label: isUnexpected ? nil : . identifier( label) ,
190205 colon: isUnexpected ? nil : . colonToken( ) ,
@@ -194,6 +209,8 @@ extension SyntaxProtocol {
194209 }
195210 }
196211 )
212+ } else {
213+ fatalError ( )
197214 }
198215 }
199216}
0 commit comments