Skip to content

Commit 7a02b13

Browse files
committed
Improve debug description of syntax nodes
This improves the description generated by the `debugDescription` function to something like the following which is easier to read IMO ``` SourceFileSyntax ├─CodeBlockItemListSyntax │ ╰─CodeBlockItemSyntax │ ╰─MacroExpansionExprSyntax │ ├─pound │ ├─identifier("stringify") │ ├─leftParen │ ├─TupleExprElementListSyntax │ │ ╰─TupleExprElementSyntax │ │ ╰─InfixOperatorExprSyntax │ │ ├─IntegerLiteralExprSyntax │ │ │ ╰─integerLiteral("2") │ │ ├─BinaryOperatorExprSyntax │ │ │ ╰─binaryOperator("+") │ │ ╰─IntegerLiteralExprSyntax │ │ ╰─integerLiteral("3") │ ╰─rightParen ╰─eof ``` Since we now have this nice representation, it also removes the conformances to `CustomReflectable` (deleting 3000 lines of code :hooray:) and doing some new `CustomReflectable` hackery to make the debugger just print `debugDescription` and not try to print the node’s children itself. This way you an now do `po node` in the debugger to get the debug description from above, instead of having to do `e print(node.recursiveDescription)`
1 parent d6e54c8 commit 7a02b13

17 files changed

+45
-3773
lines changed

CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntax/SyntaxBaseNodesFile.swift

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -233,18 +233,6 @@ let syntaxBaseNodesFile = SourceFileSyntax(leadingTrivia: copyrightHeader) {
233233
StmtSyntax("return .choices(\(choices))")
234234
}
235235
}
236-
237-
DeclSyntax(
238-
"""
239-
extension \(raw: node.name): CustomReflectable {
240-
/// Reconstructs the real syntax type for this type from the node's kind and
241-
/// provides a mirror that reflects this type.
242-
public var customMirror: Mirror {
243-
return Mirror(reflecting: Syntax(self).asProtocol(SyntaxProtocol.self))
244-
}
245-
}
246-
"""
247-
)
248236
}
249237

250238
try! ExtensionDeclSyntax("extension Syntax") {

CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntax/SyntaxCollectionsFile.swift

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -418,16 +418,4 @@ let syntaxCollectionsFile = SourceFileSyntax(leadingTrivia: copyrightHeader) {
418418
)
419419
}
420420
}
421-
422-
for node in SYNTAX_NODES where node.isSyntaxCollection {
423-
DeclSyntax(
424-
"""
425-
extension \(raw: node.name): CustomReflectable {
426-
public var customMirror: Mirror {
427-
return Mirror(self, unlabeledChildren: self.map{ $0 })
428-
}
429-
}
430-
"""
431-
)
432-
}
433421
}

CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntax/SyntaxNodeFile.swift

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -259,27 +259,6 @@ func syntaxNode(emitKind: String) -> SourceFileSyntax {
259259
StmtSyntax("return .layout(\(layout))")
260260
}
261261
}
262-
263-
try! ExtensionDeclSyntax("extension \(raw: node.name): CustomReflectable") {
264-
let children = DictionaryExprSyntax {
265-
for child in node.children {
266-
DictionaryElementSyntax(
267-
leadingTrivia: .newline,
268-
keyExpression: ExprSyntax(#""\#(raw: child.swiftName)""#),
269-
valueExpression: child.isOptional
270-
? ExprSyntax("\(raw: child.swiftName).map(Syntax.init)?.asProtocol(SyntaxProtocol.self) as Any")
271-
: ExprSyntax("Syntax(\(raw: child.swiftName)).asProtocol(SyntaxProtocol.self)")
272-
)
273-
}
274-
}
275-
DeclSyntax(
276-
"""
277-
public var customMirror: Mirror {
278-
return Mirror(self, children: \(children))
279-
}
280-
"""
281-
)
282-
}
283262
}
284263
}
285264
}

Sources/SwiftSyntax/Syntax.swift

Lines changed: 21 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -104,14 +104,6 @@ public struct Syntax: SyntaxProtocol, SyntaxHashable {
104104
}
105105
}
106106

107-
extension Syntax: CustomReflectable {
108-
/// Reconstructs the real syntax type for this type from the node's kind and
109-
/// provides a mirror that reflects this type.
110-
public var customMirror: Mirror {
111-
return Mirror(reflecting: self.asProtocol(SyntaxProtocol.self))
112-
}
113-
}
114-
115107
extension Syntax: Identifiable {
116108
public typealias ID = SyntaxIdentifier
117109
}
@@ -157,7 +149,7 @@ public extension SyntaxHashable {
157149
/// protocol to provide common functionality for all syntax nodes.
158150
/// DO NOT CONFORM TO THIS PROTOCOL YOURSELF!
159151
public protocol SyntaxProtocol: CustomStringConvertible,
160-
CustomDebugStringConvertible, TextOutputStreamable
152+
CustomDebugStringConvertible, TextOutputStreamable, CustomReflectable
161153
{
162154

163155
/// Retrieve the generic syntax node that is represented by this node.
@@ -565,14 +557,14 @@ public extension SyntaxProtocol {
565557
debugDescription()
566558
}
567559

568-
/// Same as `debugDescription` but includes all children.
569-
var recursiveDescription: String {
570-
debugDescription(includeChildren: true)
560+
var customMirror: Mirror {
561+
// Suppress printing of children when doing `po node` in the debugger.
562+
// `debugDescription` already prints them in a nicer way.
563+
return Mirror(self, children: [:])
571564
}
572565

573566
/// Returns a summarized dump of this node.
574567
/// - Parameters:
575-
/// - includeChildren: Whether to also dump children, false by default.
576568
/// - includeTrivia: Add trivia to each dumped node, which the default
577569
/// dump skips.
578570
/// - converter: The location converter for the root of the tree. Adds
@@ -582,31 +574,28 @@ public extension SyntaxProtocol {
582574
/// - indentLevel: The starting indent level, 0 by default. Each level is 2
583575
/// spaces.
584576
func debugDescription(
585-
includeChildren: Bool = false,
586577
includeTrivia: Bool = false,
587578
converter: SourceLocationConverter? = nil,
588579
mark: SyntaxProtocol? = nil,
589-
indentLevel: Int = 0
580+
indentString: String = ""
590581
) -> String {
591582
var str = ""
592583
debugWrite(
593584
to: &str,
594-
includeChildren: includeChildren,
595585
includeTrivia: includeTrivia,
596586
converter: converter,
597587
mark: mark,
598-
indentLevel: indentLevel
588+
indentString: indentString
599589
)
600590
return str
601591
}
602592

603593
private func debugWrite<Target: TextOutputStream>(
604594
to target: inout Target,
605-
includeChildren: Bool,
606595
includeTrivia: Bool,
607596
converter: SourceLocationConverter? = nil,
608597
mark: SyntaxProtocol? = nil,
609-
indentLevel: Int
598+
indentString: String
610599
) {
611600
if let mark = mark, self.id == mark.id {
612601
target.write("*** ")
@@ -627,11 +616,6 @@ public extension SyntaxProtocol {
627616
}
628617

629618
let allChildren = children(viewMode: .all)
630-
if includeChildren {
631-
if !allChildren.isEmpty {
632-
target.write(" children=\(allChildren.count)")
633-
}
634-
}
635619

636620
if let converter = converter {
637621
let range = sourceRange(converter: converter)
@@ -646,21 +630,19 @@ public extension SyntaxProtocol {
646630
target.write(" ***")
647631
}
648632

649-
if includeChildren {
650-
let childIndentLevel = indentLevel + 1
651-
for (num, child) in allChildren.enumerated() {
652-
target.write("\n")
653-
target.write(String(repeating: " ", count: childIndentLevel * 2))
654-
target.write("\(num): ")
655-
child.debugWrite(
656-
to: &target,
657-
includeChildren: includeChildren,
658-
includeTrivia: includeTrivia,
659-
converter: converter,
660-
mark: mark,
661-
indentLevel: childIndentLevel
662-
)
663-
}
633+
for (num, child) in allChildren.enumerated() {
634+
let isLastChild = num == allChildren.count - 1
635+
target.write("\n")
636+
target.write(indentString)
637+
target.write(isLastChild ? "╰─" : "├─")
638+
let childIndentString = indentString + (isLastChild ? " " : "")
639+
child.debugWrite(
640+
to: &target,
641+
includeTrivia: includeTrivia,
642+
converter: converter,
643+
mark: mark,
644+
indentString: childIndentString
645+
)
664646
}
665647
}
666648
}
@@ -763,14 +745,5 @@ extension ReversedTokenSequence: CustomReflectable {
763745
}
764746
}
765747

766-
/// Expose `recursiveDescription` on raw nodes for debugging purposes.
767-
extension RawSyntaxNodeProtocol {
768-
/// Print this raw syntax node including all of its children.
769-
/// Intended for debugging purposes only.
770-
var recursiveDescription: String {
771-
return Syntax(raw: raw).recursiveDescription
772-
}
773-
}
774-
775748
@available(*, unavailable, message: "use 'Syntax' instead")
776749
public struct SyntaxNode {}

Sources/SwiftSyntax/generated/SyntaxBaseNodes.swift

Lines changed: 0 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -149,14 +149,6 @@ public struct DeclSyntax: DeclSyntaxProtocol, SyntaxHashable {
149149
}
150150
}
151151

152-
extension DeclSyntax: CustomReflectable {
153-
/// Reconstructs the real syntax type for this type from the node's kind and
154-
/// provides a mirror that reflects this type.
155-
public var customMirror: Mirror {
156-
return Mirror(reflecting: Syntax(self).asProtocol(SyntaxProtocol.self))
157-
}
158-
}
159-
160152
// MARK: - ExprSyntax
161153

162154
/// Protocol to which all `ExprSyntax` nodes conform. Extension point to add
@@ -318,14 +310,6 @@ public struct ExprSyntax: ExprSyntaxProtocol, SyntaxHashable {
318310
}
319311
}
320312

321-
extension ExprSyntax: CustomReflectable {
322-
/// Reconstructs the real syntax type for this type from the node's kind and
323-
/// provides a mirror that reflects this type.
324-
public var customMirror: Mirror {
325-
return Mirror(reflecting: Syntax(self).asProtocol(SyntaxProtocol.self))
326-
}
327-
}
328-
329313
// MARK: - PatternSyntax
330314

331315
/// Protocol to which all `PatternSyntax` nodes conform. Extension point to add
@@ -446,14 +430,6 @@ public struct PatternSyntax: PatternSyntaxProtocol, SyntaxHashable {
446430
}
447431
}
448432

449-
extension PatternSyntax: CustomReflectable {
450-
/// Reconstructs the real syntax type for this type from the node's kind and
451-
/// provides a mirror that reflects this type.
452-
public var customMirror: Mirror {
453-
return Mirror(reflecting: Syntax(self).asProtocol(SyntaxProtocol.self))
454-
}
455-
}
456-
457433
// MARK: - StmtSyntax
458434

459435
/// Protocol to which all `StmtSyntax` nodes conform. Extension point to add
@@ -583,14 +559,6 @@ public struct StmtSyntax: StmtSyntaxProtocol, SyntaxHashable {
583559
}
584560
}
585561

586-
extension StmtSyntax: CustomReflectable {
587-
/// Reconstructs the real syntax type for this type from the node's kind and
588-
/// provides a mirror that reflects this type.
589-
public var customMirror: Mirror {
590-
return Mirror(reflecting: Syntax(self).asProtocol(SyntaxProtocol.self))
591-
}
592-
}
593-
594562
// MARK: - TypeSyntax
595563

596564
/// Protocol to which all `TypeSyntax` nodes conform. Extension point to add
@@ -721,14 +689,6 @@ public struct TypeSyntax: TypeSyntaxProtocol, SyntaxHashable {
721689
}
722690
}
723691

724-
extension TypeSyntax: CustomReflectable {
725-
/// Reconstructs the real syntax type for this type from the node's kind and
726-
/// provides a mirror that reflects this type.
727-
public var customMirror: Mirror {
728-
return Mirror(reflecting: Syntax(self).asProtocol(SyntaxProtocol.self))
729-
}
730-
}
731-
732692
extension Syntax {
733693
public static var structure: SyntaxNodeStructure {
734694
return .choices([

0 commit comments

Comments
 (0)