@@ -110,21 +110,36 @@ extension SyntaxProtocol {
110
110
/// (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).
111
111
/// The intended use case for this is to print a syntax tree and create a substructure assertion from the generated expression.
112
112
/// 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 " )
113
116
public func debugInitCall( includeTrivia: Bool = true ) -> String {
114
117
return self . debugInitCallExpr ( includeTrivia: includeTrivia) . formatted ( using: InitializerExprFormat ( ) ) . description
115
118
}
116
119
117
120
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 {
120
136
let typeName = String ( describing: type ( of: self ) )
121
137
return ExprSyntax (
122
138
FunctionCallExprSyntax ( callee: IdentifierExprSyntax ( identifier: . identifier( typeName) ) ) {
123
139
TupleExprElementSyntax (
124
140
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) )
128
143
}
129
144
}
130
145
)
@@ -134,12 +149,12 @@ extension SyntaxProtocol {
134
149
let tokenKind = token. tokenKind
135
150
let tokenInitializerName : String
136
151
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 {
141
153
tokenInitializerName = " keyword "
142
154
tokenKindArgument = ExprSyntax ( " . \( raw: keyword) " )
155
+ } else if tokenKind. isLexerClassifiedKeyword || tokenKind == . eof {
156
+ tokenInitializerName = String ( describing: tokenKind)
157
+ tokenKindArgument = nil
143
158
} else if tokenKind. decomposeToRaw ( ) . rawKind. defaultText != nil {
144
159
tokenInitializerName = " \( String ( describing: tokenKind) ) Token "
145
160
tokenKindArgument = nil
@@ -176,15 +191,15 @@ extension SyntaxProtocol {
176
191
}
177
192
}
178
193
)
179
- } else {
194
+ } else if case . layout ( let layout ) = self . syntaxNodeType . structure {
180
195
let typeName = String ( describing: type ( of: self ) )
181
196
return ExprSyntax (
182
197
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 ?
186
201
let isUnexpected = label. hasPrefix ( " unexpected " )
187
- if !isUnexpected || value != nil {
202
+ if value != nil {
188
203
TupleExprElementSyntax (
189
204
label: isUnexpected ? nil : . identifier( label) ,
190
205
colon: isUnexpected ? nil : . colonToken( ) ,
@@ -194,6 +209,8 @@ extension SyntaxProtocol {
194
209
}
195
210
}
196
211
)
212
+ } else {
213
+ fatalError ( )
197
214
}
198
215
}
199
216
}
0 commit comments