Skip to content

Commit 4eb805c

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 ac4f8f3 commit 4eb805c

17 files changed

+41
-3767
lines changed

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

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -241,17 +241,5 @@ let syntaxBaseNodesFile = SourceFileSyntax(leadingTrivia: copyrightHeader) {
241241
"""
242242
)
243243
}
244-
245-
DeclSyntax(
246-
"""
247-
extension \(raw: node.name): CustomReflectable {
248-
/// Reconstructs the real syntax type for this type from the node's kind and
249-
/// provides a mirror that reflects this type.
250-
public var customMirror: Mirror {
251-
return Mirror(reflecting: Syntax(self).asProtocol(SyntaxProtocol.self))
252-
}
253-
}
254-
"""
255-
)
256244
}
257245
}

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

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -427,16 +427,4 @@ let syntaxCollectionsFile = SourceFileSyntax(leadingTrivia: copyrightHeader) {
427427
)
428428
}
429429
}
430-
431-
for node in SYNTAX_NODES where node.isSyntaxCollection {
432-
DeclSyntax(
433-
"""
434-
extension \(raw: node.name): CustomReflectable {
435-
public var customMirror: Mirror {
436-
return Mirror(self, unlabeledChildren: self.map{ $0 })
437-
}
438-
}
439-
"""
440-
)
441-
}
442430
}

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

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -280,27 +280,6 @@ func syntaxNode(emitKind: String) -> SourceFileSyntax {
280280
}
281281
}
282282
}
283-
284-
try! ExtensionDeclSyntax("extension \(raw: node.name): CustomReflectable") {
285-
let children = DictionaryExprSyntax {
286-
for child in node.children {
287-
DictionaryElementSyntax(
288-
leadingTrivia: .newline,
289-
keyExpression: ExprSyntax(#""\#(raw: child.swiftName)""#),
290-
valueExpression: child.isOptional
291-
? ExprSyntax("\(raw: child.swiftName).map(Syntax.init)?.asProtocol(SyntaxProtocol.self) as Any")
292-
: ExprSyntax("Syntax(\(raw: child.swiftName)).asProtocol(SyntaxProtocol.self)")
293-
)
294-
}
295-
}
296-
DeclSyntax(
297-
"""
298-
public var customMirror: Mirror {
299-
return Mirror(self, children: \(children))
300-
}
301-
"""
302-
)
303-
}
304283
}
305284
}
306285
}

Sources/SwiftSyntax/Syntax.swift

Lines changed: 21 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -108,14 +108,6 @@ public struct Syntax: SyntaxProtocol, SyntaxHashable {
108108
}
109109
}
110110

111-
extension Syntax: CustomReflectable {
112-
/// Reconstructs the real syntax type for this type from the node's kind and
113-
/// provides a mirror that reflects this type.
114-
public var customMirror: Mirror {
115-
return Mirror(reflecting: self.asProtocol(SyntaxProtocol.self))
116-
}
117-
}
118-
119111
extension Syntax: Identifiable {
120112
public typealias ID = SyntaxIdentifier
121113
}
@@ -161,7 +153,7 @@ public extension SyntaxHashable {
161153
/// protocol to provide common functionality for all syntax nodes.
162154
/// DO NOT CONFORM TO THIS PROTOCOL YOURSELF!
163155
public protocol SyntaxProtocol: CustomStringConvertible,
164-
CustomDebugStringConvertible, TextOutputStreamable
156+
CustomDebugStringConvertible, TextOutputStreamable, CustomReflectable
165157
{
166158

167159
/// Retrieve the generic syntax node that is represented by this node.
@@ -598,14 +590,14 @@ public extension SyntaxProtocol {
598590
debugDescription()
599591
}
600592

601-
/// Same as `debugDescription` but includes all children.
602-
var recursiveDescription: String {
603-
debugDescription(includeChildren: true)
593+
var customMirror: Mirror {
594+
// Suppress printing of children when doing `po node` in the debugger.
595+
// `debugDescription` already prints them in a nicer way.
596+
return Mirror(self, children: [:])
604597
}
605598

606599
/// Returns a summarized dump of this node.
607600
/// - Parameters:
608-
/// - includeChildren: Whether to also dump children, false by default.
609601
/// - includeTrivia: Add trivia to each dumped node, which the default
610602
/// dump skips.
611603
/// - converter: The location converter for the root of the tree. Adds
@@ -615,31 +607,28 @@ public extension SyntaxProtocol {
615607
/// - indentLevel: The starting indent level, 0 by default. Each level is 2
616608
/// spaces.
617609
func debugDescription(
618-
includeChildren: Bool = false,
619610
includeTrivia: Bool = false,
620611
converter: SourceLocationConverter? = nil,
621612
mark: SyntaxProtocol? = nil,
622-
indentLevel: Int = 0
613+
indentString: String = ""
623614
) -> String {
624615
var str = ""
625616
debugWrite(
626617
to: &str,
627-
includeChildren: includeChildren,
628618
includeTrivia: includeTrivia,
629619
converter: converter,
630620
mark: mark,
631-
indentLevel: indentLevel
621+
indentString: indentString
632622
)
633623
return str
634624
}
635625

636626
private func debugWrite<Target: TextOutputStream>(
637627
to target: inout Target,
638-
includeChildren: Bool,
639628
includeTrivia: Bool,
640629
converter: SourceLocationConverter? = nil,
641630
mark: SyntaxProtocol? = nil,
642-
indentLevel: Int
631+
indentString: String
643632
) {
644633
if let mark = mark, self.id == mark.id {
645634
target.write("*** ")
@@ -660,11 +649,6 @@ public extension SyntaxProtocol {
660649
}
661650

662651
let allChildren = children(viewMode: .all)
663-
if includeChildren {
664-
if !allChildren.isEmpty {
665-
target.write(" children=\(allChildren.count)")
666-
}
667-
}
668652

669653
if let converter = converter {
670654
let range = sourceRange(converter: converter)
@@ -679,21 +663,19 @@ public extension SyntaxProtocol {
679663
target.write(" ***")
680664
}
681665

682-
if includeChildren {
683-
let childIndentLevel = indentLevel + 1
684-
for (num, child) in allChildren.enumerated() {
685-
target.write("\n")
686-
target.write(String(repeating: " ", count: childIndentLevel * 2))
687-
target.write("\(num): ")
688-
child.debugWrite(
689-
to: &target,
690-
includeChildren: includeChildren,
691-
includeTrivia: includeTrivia,
692-
converter: converter,
693-
mark: mark,
694-
indentLevel: childIndentLevel
695-
)
696-
}
666+
for (num, child) in allChildren.enumerated() {
667+
let isLastChild = num == allChildren.count - 1
668+
target.write("\n")
669+
target.write(indentString)
670+
target.write(isLastChild ? "╰─" : "├─")
671+
let childIndentString = indentString + (isLastChild ? " " : "")
672+
child.debugWrite(
673+
to: &target,
674+
includeTrivia: includeTrivia,
675+
converter: converter,
676+
mark: mark,
677+
indentString: childIndentString
678+
)
697679
}
698680
}
699681
}
@@ -802,14 +784,5 @@ extension ReversedTokenSequence: CustomReflectable {
802784
}
803785
}
804786

805-
/// Expose `recursiveDescription` on raw nodes for debugging purposes.
806-
extension RawSyntaxNodeProtocol {
807-
/// Print this raw syntax node including all of its children.
808-
/// Intended for debugging purposes only.
809-
var recursiveDescription: String {
810-
return Syntax(raw: raw).recursiveDescription
811-
}
812-
}
813-
814787
@available(*, unavailable, message: "use 'Syntax' instead")
815788
public struct SyntaxNode {}

Sources/SwiftSyntax/generated/SyntaxBaseNodes.swift

Lines changed: 0 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -153,14 +153,6 @@ public struct DeclSyntax: DeclSyntaxProtocol, SyntaxHashable {
153153
}
154154
}
155155

156-
extension DeclSyntax: CustomReflectable {
157-
/// Reconstructs the real syntax type for this type from the node's kind and
158-
/// provides a mirror that reflects this type.
159-
public var customMirror: Mirror {
160-
return Mirror(reflecting: Syntax(self).asProtocol(SyntaxProtocol.self))
161-
}
162-
}
163-
164156
// MARK: - ExprSyntax
165157

166158
/// Protocol to which all `ExprSyntax` nodes conform. Extension point to add
@@ -326,14 +318,6 @@ public struct ExprSyntax: ExprSyntaxProtocol, SyntaxHashable {
326318
}
327319
}
328320

329-
extension ExprSyntax: CustomReflectable {
330-
/// Reconstructs the real syntax type for this type from the node's kind and
331-
/// provides a mirror that reflects this type.
332-
public var customMirror: Mirror {
333-
return Mirror(reflecting: Syntax(self).asProtocol(SyntaxProtocol.self))
334-
}
335-
}
336-
337321
// MARK: - PatternSyntax
338322

339323
/// Protocol to which all `PatternSyntax` nodes conform. Extension point to add
@@ -458,14 +442,6 @@ public struct PatternSyntax: PatternSyntaxProtocol, SyntaxHashable {
458442
}
459443
}
460444

461-
extension PatternSyntax: CustomReflectable {
462-
/// Reconstructs the real syntax type for this type from the node's kind and
463-
/// provides a mirror that reflects this type.
464-
public var customMirror: Mirror {
465-
return Mirror(reflecting: Syntax(self).asProtocol(SyntaxProtocol.self))
466-
}
467-
}
468-
469445
// MARK: - StmtSyntax
470446

471447
/// Protocol to which all `StmtSyntax` nodes conform. Extension point to add
@@ -599,14 +575,6 @@ public struct StmtSyntax: StmtSyntaxProtocol, SyntaxHashable {
599575
}
600576
}
601577

602-
extension StmtSyntax: CustomReflectable {
603-
/// Reconstructs the real syntax type for this type from the node's kind and
604-
/// provides a mirror that reflects this type.
605-
public var customMirror: Mirror {
606-
return Mirror(reflecting: Syntax(self).asProtocol(SyntaxProtocol.self))
607-
}
608-
}
609-
610578
// MARK: - TypeSyntax
611579

612580
/// Protocol to which all `TypeSyntax` nodes conform. Extension point to add
@@ -740,11 +708,3 @@ public struct TypeSyntax: TypeSyntaxProtocol, SyntaxHashable {
740708
return Syntax(self).childNameForDiagnostics(index)
741709
}
742710
}
743-
744-
extension TypeSyntax: CustomReflectable {
745-
/// Reconstructs the real syntax type for this type from the node's kind and
746-
/// provides a mirror that reflects this type.
747-
public var customMirror: Mirror {
748-
return Mirror(reflecting: Syntax(self).asProtocol(SyntaxProtocol.self))
749-
}
750-
}

0 commit comments

Comments
 (0)