diff --git a/CodeGeneration/Sources/generate-swift-syntax/templates/swiftsyntax/SyntaxVisitorFile.swift b/CodeGeneration/Sources/generate-swift-syntax/templates/swiftsyntax/SyntaxVisitorFile.swift index 06d0811fd5f..1516c583335 100644 --- a/CodeGeneration/Sources/generate-swift-syntax/templates/swiftsyntax/SyntaxVisitorFile.swift +++ b/CodeGeneration/Sources/generate-swift-syntax/templates/swiftsyntax/SyntaxVisitorFile.swift @@ -32,6 +32,32 @@ let syntaxVisitorFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { try! ClassDeclSyntax("open class SyntaxVisitor") { DeclSyntax("public let viewMode: SyntaxTreeViewMode") + DeclSyntax( + """ + /// `Syntax.Info` objects created in `visitChildren` but whose `Syntax` nodes were not retained by the `visit` + /// functions implemented by a subclass of `SyntaxVisitor`. + /// + /// Instead of deallocating them and allocating memory for new syntax nodes, store the allocated memory in an array. + /// We can then re-use them to create new syntax nodes. + /// + /// The array's size should be a typical nesting depth of a Swift file. That way we can store all allocated syntax + /// nodes when unwinding the visitation stack. + /// + /// The actual `info` stored in the `Syntax.Info` objects is garbage. It needs to be set when any of the `Syntax.Info` + /// objects get re-used. + private var recyclableNodeInfos: ContiguousArray = ContiguousArray(repeating: nil, count: 64) + """ + ) + + DeclSyntax( + """ + /// A bit is set to 1 if the corresponding index in `recyclableNodeInfos` is occupied and ready to be reused. + /// + /// The last bit in this UInt64 corresponds to index 0 in `recyclableNodeInfos`. + private var recyclableNodeInfosUsageBitmap: UInt64 = 0 + """ + ) + DeclSyntax( """ public init(viewMode: SyntaxTreeViewMode) { @@ -45,7 +71,8 @@ let syntaxVisitorFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { /// Walk all nodes of the given syntax tree, calling the corresponding `visit` /// function for every node that is being visited. public func walk(_ node: some SyntaxProtocol) { - visit(Syntax(node)) + var syntaxNode = Syntax(node) + visit(&syntaxNode) } """ ) @@ -94,21 +121,30 @@ let syntaxVisitorFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { DeclSyntax( """ - /// Interpret `data` as a node of type `nodeType`, visit it, calling + /// Cast `node` to a node of type `nodeType`, visit it, calling /// the `visit` and `visitPost` functions during visitation. + /// + /// - Note: node is an `inout` parameter so that callers don't have to retain it before passing it to `visitImpl`. + /// With it being an `inout` parameter, the caller and `visitImpl` can work on the same reference of `node` without + /// any reference counting. + /// - Note: Inline so that the optimizer can look through the calles to `visit` and `visitPost`, which means it + /// doesn't need to retain `self` when forming closures to the unapplied function references on `self`. + @inline(__always) private func visitImpl( - _ node: Syntax, + _ node: inout Syntax, _ nodeType: NodeType.Type, _ visit: (NodeType) -> SyntaxVisitorContinueKind, _ visitPost: (NodeType) -> Void ) { - let node = node.cast(NodeType.self) - let needsChildren = (visit(node) == .visitChildren) + let castedNode = node.cast(NodeType.self) + // We retain castedNode.info here before passing it to visit. + // I don't think that's necessary because castedNode is already retained but don't know how to prevent it. + let needsChildren = (visit(castedNode) == .visitChildren) // Avoid calling into visitChildren if possible. if needsChildren && !node.raw.layoutView!.children.isEmpty { - visitChildren(node) + visitChildren(&node) } - visitPost(node) + visitPost(castedNode) } """ ) @@ -149,7 +185,7 @@ let syntaxVisitorFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { /// that determines the correct visitation function will be popped of the /// stack before the function is being called, making the switch's stack /// space transient instead of having it linger in the call stack. - private func visitationFunc(for node: Syntax) -> ((Syntax) -> Void) + private func visitationFunc(for node: Syntax) -> ((inout Syntax) -> Void) """ ) { try SwitchExprSyntax("switch node.raw.kind") { @@ -168,7 +204,7 @@ let syntaxVisitorFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { for node in NON_BASE_SYNTAX_NODES { SwitchCaseSyntax("case .\(node.varOrCaseName):") { - StmtSyntax("return { self.visitImpl($0, \(node.kind.syntaxType).self, self.visit, self.visitPost) }") + StmtSyntax("return { self.visitImpl(&$0, \(node.kind.syntaxType).self, self.visit, self.visitPost) }") } } } @@ -176,8 +212,8 @@ let syntaxVisitorFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { DeclSyntax( """ - private func visit(_ node: Syntax) { - return visitationFunc(for: node)(node) + private func visit(_ node: inout Syntax) { + return visitationFunc(for: node)(&node) } """ ) @@ -188,7 +224,12 @@ let syntaxVisitorFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { poundKeyword: .poundElseToken(), elements: .statements( CodeBlockItemListSyntax { - try! FunctionDeclSyntax("private func visit(_ node: Syntax)") { + try! FunctionDeclSyntax( + """ + /// - Note: `node` is `inout` to avoid ref-counting. See comment in `visitImpl` + private func visit(_ node: inout Syntax) + """ + ) { try SwitchExprSyntax("switch node.raw.kind") { SwitchCaseSyntax("case .token:") { DeclSyntax("let node = node.cast(TokenSyntax.self)") @@ -203,7 +244,7 @@ let syntaxVisitorFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { for node in NON_BASE_SYNTAX_NODES { SwitchCaseSyntax("case .\(node.varOrCaseName):") { - ExprSyntax("visitImpl(node, \(node.kind.syntaxType).self, visit, visitPost)") + ExprSyntax("visitImpl(&node, \(node.kind.syntaxType).self, visit, visitPost)") } } } @@ -217,13 +258,66 @@ let syntaxVisitorFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { DeclSyntax( """ - private func visitChildren(_ node: some SyntaxProtocol) { - let syntaxNode = Syntax(node) + /// - Note: `node` is `inout` to avoid reference counting. See comment in `visitImpl`. + private func visitChildren(_ syntaxNode: inout Syntax) { for childRaw in NonNilRawSyntaxChildren(syntaxNode, viewMode: viewMode) { - visit(Syntax(childRaw, parent: syntaxNode)) + // syntaxNode gets retained here. That seems unnecessary but I don't know how to remove it. + var childNode: Syntax + if let recycledInfoIndex = recyclableNodeInfosUsageBitmap.indexOfRightmostOne { + var recycledInfo: Syntax.Info? = nil + // Use `swap` to extract the recyclable syntax node without incurring ref-counting. + swap(&recycledInfo, &recyclableNodeInfos[recycledInfoIndex]) + assert(recycledInfo != nil, "Slot indicated by the bitmap did not contain a value") + recyclableNodeInfosUsageBitmap.setBitToZero(at: recycledInfoIndex) + // syntaxNode.info gets retained here. This is necessary because we build up the parent tree. + recycledInfo!.info = .nonRoot(.init(parent: syntaxNode, absoluteInfo: childRaw.info)) + childNode = Syntax(childRaw.raw, info: recycledInfo!) + } else { + childNode = Syntax(childRaw, parent: syntaxNode) + } + visit(&childNode) + if isKnownUniquelyReferenced(&childNode.info) { + // The node didn't get stored by the subclass's visit method. We can re-use the memory of its `Syntax.Info` + // for future syntax nodes. + childNode.info.info = nil + if let emptySlot = recyclableNodeInfosUsageBitmap.indexOfRightmostZero { + // Use `swap` to store the recyclable syntax node without incurring ref-counting. + swap(&recyclableNodeInfos[emptySlot], &childNode.info) + assert(childNode.info == nil, "Slot should not have contained a value") + recyclableNodeInfosUsageBitmap.setBitToOne(at: emptySlot) + } + } } } """ ) } + + DeclSyntax( + """ + fileprivate extension UInt64 { + var indexOfRightmostZero: Int? { + return (~self).indexOfRightmostOne + } + + var indexOfRightmostOne: Int? { + let trailingZeroCount = self.trailingZeroBitCount + if trailingZeroCount == Self.bitWidth { + // All indicies are 0 + return nil + } + return trailingZeroCount + } + + mutating func setBitToZero(at index: Int) { + self &= ~(1 << index) + } + + mutating func setBitToOne(at index: Int) { + self |= 1 << index + } + } + + """ + ) } diff --git a/Sources/SwiftSyntax/Syntax.swift b/Sources/SwiftSyntax/Syntax.swift index 4fce60526fe..0940ee2dbe6 100644 --- a/Sources/SwiftSyntax/Syntax.swift +++ b/Sources/SwiftSyntax/Syntax.swift @@ -14,10 +14,9 @@ /// Each node has accessors for its known children, and allows efficient /// iteration over the children through its `children` property. public struct Syntax: SyntaxProtocol, SyntaxHashable { - fileprivate enum Info: Sendable { - case root(Root) - indirect case nonRoot(NonRoot) - + /// We need a heap indirection to store a syntax node's parent. We could use an indirect enum here but explicitly + /// modelling it using a class allows us to re-use these heap-allocated objects in `SyntaxVisitor`. + final class Info: Sendable { // For root node. struct Root: Sendable { private var arena: RetainedSyntaxArena @@ -32,27 +31,50 @@ public struct Syntax: SyntaxProtocol, SyntaxHashable { var parent: Syntax var absoluteInfo: AbsoluteSyntaxInfo } + + enum InfoImpl: Sendable { + case root(Root) + case nonRoot(NonRoot) + } + + init(_ info: InfoImpl) { + self.info = info + } + + /// The actual stored information that references the parent or the tree's root. + /// + /// - Important: Must only be set to `nil` when `Syntax.Info` is used in a memory recycling pool + /// (eg. in `SyntaxVisitor`). In that case the `Syntax.Info` is considered garbage memory that can be re-used + /// later. `info` needs to be set to a real value when `Syntax.Info` is recycled from the memory recycling pool. + var info: InfoImpl! } - private let info: Info + /// Reference to the node's parent or, if this node is the root of a tree, a reference to the `SyntaxArena` to keep + /// the syntax tree alive. + /// + /// - Important: In almost all use cases you should not access this directly. Prefer accessors like `parent`. + /// - Important: Must only be set to `nil` when this `Syntax` node is known to get destroyed and the `Info` should be + /// stored in a memory recycling pool (eg. in `SyntaxVisitor`). After setting `info` to `nil`, this `Syntax` node + /// is considered garbage and should not be accessed anymore in any way. + var info: Info! let raw: RawSyntax private var rootInfo: Info.Root { - switch info { + switch info.info! { case .root(let info): return info case .nonRoot(let info): return info.parent.rootInfo } } private var nonRootInfo: Info.NonRoot? { - switch info { + switch info.info! { case .root(_): return nil case .nonRoot(let info): return info } } private var root: Syntax { - switch info { + switch info.info! { case .root(_): return self case .nonRoot(let info): return info.parent.root } @@ -99,13 +121,13 @@ public struct Syntax: SyntaxProtocol, SyntaxHashable { } /// "designated" memberwise initializer of `Syntax`. - private init(_ raw: RawSyntax, info: Info) { + init(_ raw: RawSyntax, info: Info) { self.raw = raw self.info = info } init(_ raw: RawSyntax, parent: Syntax, absoluteInfo: AbsoluteSyntaxInfo) { - self.init(raw, info: .nonRoot(.init(parent: parent, absoluteInfo: absoluteInfo))) + self.init(raw, info: Info(.nonRoot(.init(parent: parent, absoluteInfo: absoluteInfo)))) } /// Creates a `Syntax` with the provided raw syntax and parent. @@ -125,12 +147,12 @@ public struct Syntax: SyntaxProtocol, SyntaxHashable { /// has a chance to retain it. static func forRoot(_ raw: RawSyntax, rawNodeArena: RetainedSyntaxArena) -> Syntax { precondition(rawNodeArena == raw.arenaReference) - return Syntax(raw, info: .root(.init(arena: rawNodeArena))) + return Syntax(raw, info: Info(.root(.init(arena: rawNodeArena)))) } static func forRoot(_ raw: RawSyntax, rawNodeArena: SyntaxArena) -> Syntax { precondition(rawNodeArena == raw.arenaReference) - return Syntax(raw, info: .root(.init(arena: RetainedSyntaxArena(rawNodeArena)))) + return Syntax(raw, info: Info(.root(.init(arena: RetainedSyntaxArena(rawNodeArena))))) } /// Returns the child data at the provided index in this data's layout. @@ -252,6 +274,9 @@ public struct Syntax: SyntaxProtocol, SyntaxHashable { } /// Create a ``Syntax`` node from a specialized syntax node. + // Inline always so the optimizer can optimize this to a member access on `syntax` without having to go through + // generics. + @inline(__always) public init(_ syntax: some SyntaxProtocol) { self = syntax._syntaxNode } diff --git a/Sources/SwiftSyntax/SyntaxChildren.swift b/Sources/SwiftSyntax/SyntaxChildren.swift index db14ccb672b..c7649e71475 100644 --- a/Sources/SwiftSyntax/SyntaxChildren.swift +++ b/Sources/SwiftSyntax/SyntaxChildren.swift @@ -411,6 +411,8 @@ struct NonNilRawSyntaxChildren: BidirectionalCollection, Sendable { self.viewMode = viewMode } + /// - Note: Inline so we don't retain `Syntax.Info` when creating `NonNilRawSyntaxChildren` from a `Syntax`. + @inline(__always) init(_ node: Syntax, viewMode: SyntaxTreeViewMode) { self.init(node.absoluteRaw, viewMode: viewMode) } diff --git a/Sources/SwiftSyntax/generated/SyntaxVisitor.swift b/Sources/SwiftSyntax/generated/SyntaxVisitor.swift index 3b40df48540..5dc746e4720 100644 --- a/Sources/SwiftSyntax/generated/SyntaxVisitor.swift +++ b/Sources/SwiftSyntax/generated/SyntaxVisitor.swift @@ -24,6 +24,24 @@ public enum SyntaxVisitorContinueKind { open class SyntaxVisitor { public let viewMode: SyntaxTreeViewMode + /// `Syntax.Info` objects created in `visitChildren` but whose `Syntax` nodes were not retained by the `visit` + /// functions implemented by a subclass of `SyntaxVisitor`. + /// + /// Instead of deallocating them and allocating memory for new syntax nodes, store the allocated memory in an array. + /// We can then re-use them to create new syntax nodes. + /// + /// The array's size should be a typical nesting depth of a Swift file. That way we can store all allocated syntax + /// nodes when unwinding the visitation stack. + /// + /// The actual `info` stored in the `Syntax.Info` objects is garbage. It needs to be set when any of the `Syntax.Info` + /// objects get re-used. + private var recyclableNodeInfos: ContiguousArray = ContiguousArray(repeating: nil, count: 64) + + /// A bit is set to 1 if the corresponding index in `recyclableNodeInfos` is occupied and ready to be reused. + /// + /// The last bit in this UInt64 corresponds to index 0 in `recyclableNodeInfos`. + private var recyclableNodeInfosUsageBitmap: UInt64 = 0 + public init(viewMode: SyntaxTreeViewMode) { self.viewMode = viewMode } @@ -31,7 +49,8 @@ open class SyntaxVisitor { /// Walk all nodes of the given syntax tree, calling the corresponding `visit` /// function for every node that is being visited. public func walk(_ node: some SyntaxProtocol) { - visit(Syntax(node)) + var syntaxNode = Syntax(node) + visit(&syntaxNode) } /// Visiting ``AccessorBlockSyntax`` specifically. @@ -3490,21 +3509,30 @@ open class SyntaxVisitor { open func visitPost(_ node: TokenSyntax) { } - /// Interpret `data` as a node of type `nodeType`, visit it, calling + /// Cast `node` to a node of type `nodeType`, visit it, calling /// the `visit` and `visitPost` functions during visitation. + /// + /// - Note: node is an `inout` parameter so that callers don't have to retain it before passing it to `visitImpl`. + /// With it being an `inout` parameter, the caller and `visitImpl` can work on the same reference of `node` without + /// any reference counting. + /// - Note: Inline so that the optimizer can look through the calles to `visit` and `visitPost`, which means it + /// doesn't need to retain `self` when forming closures to the unapplied function references on `self`. + @inline(__always) private func visitImpl( - _ node: Syntax, + _ node: inout Syntax, _ nodeType: NodeType.Type, _ visit: (NodeType) -> SyntaxVisitorContinueKind, _ visitPost: (NodeType) -> Void ) { - let node = node.cast(NodeType.self) - let needsChildren = (visit(node) == .visitChildren) + let castedNode = node.cast(NodeType.self) + // We retain castedNode.info here before passing it to visit. + // I don't think that's necessary because castedNode is already retained but don't know how to prevent it. + let needsChildren = (visit(castedNode) == .visitChildren) // Avoid calling into visitChildren if possible. if needsChildren && !node.raw.layoutView!.children.isEmpty { - visitChildren(node) + visitChildren(&node) } - visitPost(node) + visitPost(castedNode) } // SwiftSyntax requires a lot of stack space in debug builds for syntax tree @@ -3531,7 +3559,7 @@ open class SyntaxVisitor { /// that determines the correct visitation function will be popped of the /// stack before the function is being called, making the switch's stack /// space transient instead of having it linger in the call stack. - private func visitationFunc(for node: Syntax) -> ((Syntax) -> Void) { + private func visitationFunc(for node: Syntax) -> ((inout Syntax) -> Void) { switch node.raw.kind { case .token: return { @@ -3542,1147 +3570,1148 @@ open class SyntaxVisitor { } case .accessorBlock: return { - self.visitImpl($0, AccessorBlockSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, AccessorBlockSyntax.self, self.visit, self.visitPost) } case .accessorDeclList: return { - self.visitImpl($0, AccessorDeclListSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, AccessorDeclListSyntax.self, self.visit, self.visitPost) } case .accessorDecl: return { - self.visitImpl($0, AccessorDeclSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, AccessorDeclSyntax.self, self.visit, self.visitPost) } case .accessorEffectSpecifiers: return { - self.visitImpl($0, AccessorEffectSpecifiersSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, AccessorEffectSpecifiersSyntax.self, self.visit, self.visitPost) } case .accessorParameters: return { - self.visitImpl($0, AccessorParametersSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, AccessorParametersSyntax.self, self.visit, self.visitPost) } case .actorDecl: return { - self.visitImpl($0, ActorDeclSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, ActorDeclSyntax.self, self.visit, self.visitPost) } case .arrayElementList: return { - self.visitImpl($0, ArrayElementListSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, ArrayElementListSyntax.self, self.visit, self.visitPost) } case .arrayElement: return { - self.visitImpl($0, ArrayElementSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, ArrayElementSyntax.self, self.visit, self.visitPost) } case .arrayExpr: return { - self.visitImpl($0, ArrayExprSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, ArrayExprSyntax.self, self.visit, self.visitPost) } case .arrayType: return { - self.visitImpl($0, ArrayTypeSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, ArrayTypeSyntax.self, self.visit, self.visitPost) } case .arrowExpr: return { - self.visitImpl($0, ArrowExprSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, ArrowExprSyntax.self, self.visit, self.visitPost) } case .asExpr: return { - self.visitImpl($0, AsExprSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, AsExprSyntax.self, self.visit, self.visitPost) } case .assignmentExpr: return { - self.visitImpl($0, AssignmentExprSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, AssignmentExprSyntax.self, self.visit, self.visitPost) } case .associatedTypeDecl: return { - self.visitImpl($0, AssociatedTypeDeclSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, AssociatedTypeDeclSyntax.self, self.visit, self.visitPost) } case .attributeList: return { - self.visitImpl($0, AttributeListSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, AttributeListSyntax.self, self.visit, self.visitPost) } case .attribute: return { - self.visitImpl($0, AttributeSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, AttributeSyntax.self, self.visit, self.visitPost) } case .attributedType: return { - self.visitImpl($0, AttributedTypeSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, AttributedTypeSyntax.self, self.visit, self.visitPost) } case .availabilityArgumentList: return { - self.visitImpl($0, AvailabilityArgumentListSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, AvailabilityArgumentListSyntax.self, self.visit, self.visitPost) } case .availabilityArgument: return { - self.visitImpl($0, AvailabilityArgumentSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, AvailabilityArgumentSyntax.self, self.visit, self.visitPost) } case .availabilityCondition: return { - self.visitImpl($0, AvailabilityConditionSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, AvailabilityConditionSyntax.self, self.visit, self.visitPost) } case .availabilityLabeledArgument: return { - self.visitImpl($0, AvailabilityLabeledArgumentSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, AvailabilityLabeledArgumentSyntax.self, self.visit, self.visitPost) } case .awaitExpr: return { - self.visitImpl($0, AwaitExprSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, AwaitExprSyntax.self, self.visit, self.visitPost) } case .backDeployedAttributeArguments: return { - self.visitImpl($0, BackDeployedAttributeArgumentsSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, BackDeployedAttributeArgumentsSyntax.self, self.visit, self.visitPost) } case .binaryOperatorExpr: return { - self.visitImpl($0, BinaryOperatorExprSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, BinaryOperatorExprSyntax.self, self.visit, self.visitPost) } case .booleanLiteralExpr: return { - self.visitImpl($0, BooleanLiteralExprSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, BooleanLiteralExprSyntax.self, self.visit, self.visitPost) } case .borrowExpr: return { - self.visitImpl($0, BorrowExprSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, BorrowExprSyntax.self, self.visit, self.visitPost) } case .breakStmt: return { - self.visitImpl($0, BreakStmtSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, BreakStmtSyntax.self, self.visit, self.visitPost) } case .canImportExpr: return { - self.visitImpl($0, CanImportExprSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, CanImportExprSyntax.self, self.visit, self.visitPost) } case .canImportVersionInfo: return { - self.visitImpl($0, CanImportVersionInfoSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, CanImportVersionInfoSyntax.self, self.visit, self.visitPost) } case .catchClauseList: return { - self.visitImpl($0, CatchClauseListSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, CatchClauseListSyntax.self, self.visit, self.visitPost) } case .catchClause: return { - self.visitImpl($0, CatchClauseSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, CatchClauseSyntax.self, self.visit, self.visitPost) } case .catchItemList: return { - self.visitImpl($0, CatchItemListSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, CatchItemListSyntax.self, self.visit, self.visitPost) } case .catchItem: return { - self.visitImpl($0, CatchItemSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, CatchItemSyntax.self, self.visit, self.visitPost) } case .classDecl: return { - self.visitImpl($0, ClassDeclSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, ClassDeclSyntax.self, self.visit, self.visitPost) } case .classRestrictionType: return { - self.visitImpl($0, ClassRestrictionTypeSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, ClassRestrictionTypeSyntax.self, self.visit, self.visitPost) } case .closureCaptureClause: return { - self.visitImpl($0, ClosureCaptureClauseSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, ClosureCaptureClauseSyntax.self, self.visit, self.visitPost) } case .closureCaptureList: return { - self.visitImpl($0, ClosureCaptureListSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, ClosureCaptureListSyntax.self, self.visit, self.visitPost) } case .closureCaptureSpecifier: return { - self.visitImpl($0, ClosureCaptureSpecifierSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, ClosureCaptureSpecifierSyntax.self, self.visit, self.visitPost) } case .closureCapture: return { - self.visitImpl($0, ClosureCaptureSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, ClosureCaptureSyntax.self, self.visit, self.visitPost) } case .closureExpr: return { - self.visitImpl($0, ClosureExprSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, ClosureExprSyntax.self, self.visit, self.visitPost) } case .closureParameterClause: return { - self.visitImpl($0, ClosureParameterClauseSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, ClosureParameterClauseSyntax.self, self.visit, self.visitPost) } case .closureParameterList: return { - self.visitImpl($0, ClosureParameterListSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, ClosureParameterListSyntax.self, self.visit, self.visitPost) } case .closureParameter: return { - self.visitImpl($0, ClosureParameterSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, ClosureParameterSyntax.self, self.visit, self.visitPost) } case .closureShorthandParameterList: return { - self.visitImpl($0, ClosureShorthandParameterListSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, ClosureShorthandParameterListSyntax.self, self.visit, self.visitPost) } case .closureShorthandParameter: return { - self.visitImpl($0, ClosureShorthandParameterSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, ClosureShorthandParameterSyntax.self, self.visit, self.visitPost) } case .closureSignature: return { - self.visitImpl($0, ClosureSignatureSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, ClosureSignatureSyntax.self, self.visit, self.visitPost) } case .codeBlockItemList: return { - self.visitImpl($0, CodeBlockItemListSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, CodeBlockItemListSyntax.self, self.visit, self.visitPost) } case .codeBlockItem: return { - self.visitImpl($0, CodeBlockItemSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, CodeBlockItemSyntax.self, self.visit, self.visitPost) } case .codeBlock: return { - self.visitImpl($0, CodeBlockSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, CodeBlockSyntax.self, self.visit, self.visitPost) } case .compositionTypeElementList: return { - self.visitImpl($0, CompositionTypeElementListSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, CompositionTypeElementListSyntax.self, self.visit, self.visitPost) } case .compositionTypeElement: return { - self.visitImpl($0, CompositionTypeElementSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, CompositionTypeElementSyntax.self, self.visit, self.visitPost) } case .compositionType: return { - self.visitImpl($0, CompositionTypeSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, CompositionTypeSyntax.self, self.visit, self.visitPost) } case .conditionElementList: return { - self.visitImpl($0, ConditionElementListSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, ConditionElementListSyntax.self, self.visit, self.visitPost) } case .conditionElement: return { - self.visitImpl($0, ConditionElementSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, ConditionElementSyntax.self, self.visit, self.visitPost) } case .conformanceRequirement: return { - self.visitImpl($0, ConformanceRequirementSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, ConformanceRequirementSyntax.self, self.visit, self.visitPost) } case .consumeExpr: return { - self.visitImpl($0, ConsumeExprSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, ConsumeExprSyntax.self, self.visit, self.visitPost) } case .continueStmt: return { - self.visitImpl($0, ContinueStmtSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, ContinueStmtSyntax.self, self.visit, self.visitPost) } case .conventionAttributeArguments: return { - self.visitImpl($0, ConventionAttributeArgumentsSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, ConventionAttributeArgumentsSyntax.self, self.visit, self.visitPost) } case .conventionWitnessMethodAttributeArguments: return { - self.visitImpl($0, ConventionWitnessMethodAttributeArgumentsSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, ConventionWitnessMethodAttributeArgumentsSyntax.self, self.visit, self.visitPost) } case .copyExpr: return { - self.visitImpl($0, CopyExprSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, CopyExprSyntax.self, self.visit, self.visitPost) } case .declModifierDetail: return { - self.visitImpl($0, DeclModifierDetailSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, DeclModifierDetailSyntax.self, self.visit, self.visitPost) } case .declModifierList: return { - self.visitImpl($0, DeclModifierListSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, DeclModifierListSyntax.self, self.visit, self.visitPost) } case .declModifier: return { - self.visitImpl($0, DeclModifierSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, DeclModifierSyntax.self, self.visit, self.visitPost) } case .declNameArgumentList: return { - self.visitImpl($0, DeclNameArgumentListSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, DeclNameArgumentListSyntax.self, self.visit, self.visitPost) } case .declNameArgument: return { - self.visitImpl($0, DeclNameArgumentSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, DeclNameArgumentSyntax.self, self.visit, self.visitPost) } case .declNameArguments: return { - self.visitImpl($0, DeclNameArgumentsSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, DeclNameArgumentsSyntax.self, self.visit, self.visitPost) } case .declReferenceExpr: return { - self.visitImpl($0, DeclReferenceExprSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, DeclReferenceExprSyntax.self, self.visit, self.visitPost) } case .deferStmt: return { - self.visitImpl($0, DeferStmtSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, DeferStmtSyntax.self, self.visit, self.visitPost) } case .deinitializerDecl: return { - self.visitImpl($0, DeinitializerDeclSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, DeinitializerDeclSyntax.self, self.visit, self.visitPost) } case .deinitializerEffectSpecifiers: return { - self.visitImpl($0, DeinitializerEffectSpecifiersSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, DeinitializerEffectSpecifiersSyntax.self, self.visit, self.visitPost) } case .derivativeAttributeArguments: return { - self.visitImpl($0, DerivativeAttributeArgumentsSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, DerivativeAttributeArgumentsSyntax.self, self.visit, self.visitPost) } case .designatedTypeList: return { - self.visitImpl($0, DesignatedTypeListSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, DesignatedTypeListSyntax.self, self.visit, self.visitPost) } case .designatedType: return { - self.visitImpl($0, DesignatedTypeSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, DesignatedTypeSyntax.self, self.visit, self.visitPost) } case .dictionaryElementList: return { - self.visitImpl($0, DictionaryElementListSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, DictionaryElementListSyntax.self, self.visit, self.visitPost) } case .dictionaryElement: return { - self.visitImpl($0, DictionaryElementSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, DictionaryElementSyntax.self, self.visit, self.visitPost) } case .dictionaryExpr: return { - self.visitImpl($0, DictionaryExprSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, DictionaryExprSyntax.self, self.visit, self.visitPost) } case .dictionaryType: return { - self.visitImpl($0, DictionaryTypeSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, DictionaryTypeSyntax.self, self.visit, self.visitPost) } case .differentiabilityArgumentList: return { - self.visitImpl($0, DifferentiabilityArgumentListSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, DifferentiabilityArgumentListSyntax.self, self.visit, self.visitPost) } case .differentiabilityArgument: return { - self.visitImpl($0, DifferentiabilityArgumentSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, DifferentiabilityArgumentSyntax.self, self.visit, self.visitPost) } case .differentiabilityArguments: return { - self.visitImpl($0, DifferentiabilityArgumentsSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, DifferentiabilityArgumentsSyntax.self, self.visit, self.visitPost) } case .differentiabilityWithRespectToArgument: return { - self.visitImpl($0, DifferentiabilityWithRespectToArgumentSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, DifferentiabilityWithRespectToArgumentSyntax.self, self.visit, self.visitPost) } case .differentiableAttributeArguments: return { - self.visitImpl($0, DifferentiableAttributeArgumentsSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, DifferentiableAttributeArgumentsSyntax.self, self.visit, self.visitPost) } case .discardAssignmentExpr: return { - self.visitImpl($0, DiscardAssignmentExprSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, DiscardAssignmentExprSyntax.self, self.visit, self.visitPost) } case .discardStmt: return { - self.visitImpl($0, DiscardStmtSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, DiscardStmtSyntax.self, self.visit, self.visitPost) } case .doExpr: return { - self.visitImpl($0, DoExprSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, DoExprSyntax.self, self.visit, self.visitPost) } case .doStmt: return { - self.visitImpl($0, DoStmtSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, DoStmtSyntax.self, self.visit, self.visitPost) } case .documentationAttributeArgumentList: return { - self.visitImpl($0, DocumentationAttributeArgumentListSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, DocumentationAttributeArgumentListSyntax.self, self.visit, self.visitPost) } case .documentationAttributeArgument: return { - self.visitImpl($0, DocumentationAttributeArgumentSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, DocumentationAttributeArgumentSyntax.self, self.visit, self.visitPost) } case .dynamicReplacementAttributeArguments: return { - self.visitImpl($0, DynamicReplacementAttributeArgumentsSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, DynamicReplacementAttributeArgumentsSyntax.self, self.visit, self.visitPost) } case .editorPlaceholderDecl: return { - self.visitImpl($0, EditorPlaceholderDeclSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, EditorPlaceholderDeclSyntax.self, self.visit, self.visitPost) } case .editorPlaceholderExpr: return { - self.visitImpl($0, EditorPlaceholderExprSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, EditorPlaceholderExprSyntax.self, self.visit, self.visitPost) } case .effectsAttributeArgumentList: return { - self.visitImpl($0, EffectsAttributeArgumentListSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, EffectsAttributeArgumentListSyntax.self, self.visit, self.visitPost) } case .enumCaseDecl: return { - self.visitImpl($0, EnumCaseDeclSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, EnumCaseDeclSyntax.self, self.visit, self.visitPost) } case .enumCaseElementList: return { - self.visitImpl($0, EnumCaseElementListSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, EnumCaseElementListSyntax.self, self.visit, self.visitPost) } case .enumCaseElement: return { - self.visitImpl($0, EnumCaseElementSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, EnumCaseElementSyntax.self, self.visit, self.visitPost) } case .enumCaseParameterClause: return { - self.visitImpl($0, EnumCaseParameterClauseSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, EnumCaseParameterClauseSyntax.self, self.visit, self.visitPost) } case .enumCaseParameterList: return { - self.visitImpl($0, EnumCaseParameterListSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, EnumCaseParameterListSyntax.self, self.visit, self.visitPost) } case .enumCaseParameter: return { - self.visitImpl($0, EnumCaseParameterSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, EnumCaseParameterSyntax.self, self.visit, self.visitPost) } case .enumDecl: return { - self.visitImpl($0, EnumDeclSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, EnumDeclSyntax.self, self.visit, self.visitPost) } case .exposeAttributeArguments: return { - self.visitImpl($0, ExposeAttributeArgumentsSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, ExposeAttributeArgumentsSyntax.self, self.visit, self.visitPost) } case .exprList: return { - self.visitImpl($0, ExprListSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, ExprListSyntax.self, self.visit, self.visitPost) } case .expressionPattern: return { - self.visitImpl($0, ExpressionPatternSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, ExpressionPatternSyntax.self, self.visit, self.visitPost) } case .expressionSegment: return { - self.visitImpl($0, ExpressionSegmentSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, ExpressionSegmentSyntax.self, self.visit, self.visitPost) } case .expressionStmt: return { - self.visitImpl($0, ExpressionStmtSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, ExpressionStmtSyntax.self, self.visit, self.visitPost) } case .extensionDecl: return { - self.visitImpl($0, ExtensionDeclSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, ExtensionDeclSyntax.self, self.visit, self.visitPost) } case .fallThroughStmt: return { - self.visitImpl($0, FallThroughStmtSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, FallThroughStmtSyntax.self, self.visit, self.visitPost) } case .floatLiteralExpr: return { - self.visitImpl($0, FloatLiteralExprSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, FloatLiteralExprSyntax.self, self.visit, self.visitPost) } case .forStmt: return { - self.visitImpl($0, ForStmtSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, ForStmtSyntax.self, self.visit, self.visitPost) } case .forceUnwrapExpr: return { - self.visitImpl($0, ForceUnwrapExprSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, ForceUnwrapExprSyntax.self, self.visit, self.visitPost) } case .functionCallExpr: return { - self.visitImpl($0, FunctionCallExprSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, FunctionCallExprSyntax.self, self.visit, self.visitPost) } case .functionDecl: return { - self.visitImpl($0, FunctionDeclSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, FunctionDeclSyntax.self, self.visit, self.visitPost) } case .functionEffectSpecifiers: return { - self.visitImpl($0, FunctionEffectSpecifiersSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, FunctionEffectSpecifiersSyntax.self, self.visit, self.visitPost) } case .functionParameterClause: return { - self.visitImpl($0, FunctionParameterClauseSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, FunctionParameterClauseSyntax.self, self.visit, self.visitPost) } case .functionParameterList: return { - self.visitImpl($0, FunctionParameterListSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, FunctionParameterListSyntax.self, self.visit, self.visitPost) } case .functionParameter: return { - self.visitImpl($0, FunctionParameterSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, FunctionParameterSyntax.self, self.visit, self.visitPost) } case .functionSignature: return { - self.visitImpl($0, FunctionSignatureSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, FunctionSignatureSyntax.self, self.visit, self.visitPost) } case .functionType: return { - self.visitImpl($0, FunctionTypeSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, FunctionTypeSyntax.self, self.visit, self.visitPost) } case .genericArgumentClause: return { - self.visitImpl($0, GenericArgumentClauseSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, GenericArgumentClauseSyntax.self, self.visit, self.visitPost) } case .genericArgumentList: return { - self.visitImpl($0, GenericArgumentListSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, GenericArgumentListSyntax.self, self.visit, self.visitPost) } case .genericArgument: return { - self.visitImpl($0, GenericArgumentSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, GenericArgumentSyntax.self, self.visit, self.visitPost) } case .genericParameterClause: return { - self.visitImpl($0, GenericParameterClauseSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, GenericParameterClauseSyntax.self, self.visit, self.visitPost) } case .genericParameterList: return { - self.visitImpl($0, GenericParameterListSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, GenericParameterListSyntax.self, self.visit, self.visitPost) } case .genericParameter: return { - self.visitImpl($0, GenericParameterSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, GenericParameterSyntax.self, self.visit, self.visitPost) } case .genericRequirementList: return { - self.visitImpl($0, GenericRequirementListSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, GenericRequirementListSyntax.self, self.visit, self.visitPost) } case .genericRequirement: return { - self.visitImpl($0, GenericRequirementSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, GenericRequirementSyntax.self, self.visit, self.visitPost) } case .genericSpecializationExpr: return { - self.visitImpl($0, GenericSpecializationExprSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, GenericSpecializationExprSyntax.self, self.visit, self.visitPost) } case .genericWhereClause: return { - self.visitImpl($0, GenericWhereClauseSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, GenericWhereClauseSyntax.self, self.visit, self.visitPost) } case .guardStmt: return { - self.visitImpl($0, GuardStmtSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, GuardStmtSyntax.self, self.visit, self.visitPost) } case .identifierPattern: return { - self.visitImpl($0, IdentifierPatternSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, IdentifierPatternSyntax.self, self.visit, self.visitPost) } case .identifierType: return { - self.visitImpl($0, IdentifierTypeSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, IdentifierTypeSyntax.self, self.visit, self.visitPost) } case .ifConfigClauseList: return { - self.visitImpl($0, IfConfigClauseListSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, IfConfigClauseListSyntax.self, self.visit, self.visitPost) } case .ifConfigClause: return { - self.visitImpl($0, IfConfigClauseSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, IfConfigClauseSyntax.self, self.visit, self.visitPost) } case .ifConfigDecl: return { - self.visitImpl($0, IfConfigDeclSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, IfConfigDeclSyntax.self, self.visit, self.visitPost) } case .ifExpr: return { - self.visitImpl($0, IfExprSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, IfExprSyntax.self, self.visit, self.visitPost) } case .implementsAttributeArguments: return { - self.visitImpl($0, ImplementsAttributeArgumentsSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, ImplementsAttributeArgumentsSyntax.self, self.visit, self.visitPost) } case .implicitlyUnwrappedOptionalType: return { - self.visitImpl($0, ImplicitlyUnwrappedOptionalTypeSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, ImplicitlyUnwrappedOptionalTypeSyntax.self, self.visit, self.visitPost) } case .importDecl: return { - self.visitImpl($0, ImportDeclSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, ImportDeclSyntax.self, self.visit, self.visitPost) } case .importPathComponentList: return { - self.visitImpl($0, ImportPathComponentListSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, ImportPathComponentListSyntax.self, self.visit, self.visitPost) } case .importPathComponent: return { - self.visitImpl($0, ImportPathComponentSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, ImportPathComponentSyntax.self, self.visit, self.visitPost) } case .inOutExpr: return { - self.visitImpl($0, InOutExprSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, InOutExprSyntax.self, self.visit, self.visitPost) } case .infixOperatorExpr: return { - self.visitImpl($0, InfixOperatorExprSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, InfixOperatorExprSyntax.self, self.visit, self.visitPost) } case .inheritanceClause: return { - self.visitImpl($0, InheritanceClauseSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, InheritanceClauseSyntax.self, self.visit, self.visitPost) } case .inheritedTypeList: return { - self.visitImpl($0, InheritedTypeListSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, InheritedTypeListSyntax.self, self.visit, self.visitPost) } case .inheritedType: return { - self.visitImpl($0, InheritedTypeSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, InheritedTypeSyntax.self, self.visit, self.visitPost) } case .initializerClause: return { - self.visitImpl($0, InitializerClauseSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, InitializerClauseSyntax.self, self.visit, self.visitPost) } case .initializerDecl: return { - self.visitImpl($0, InitializerDeclSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, InitializerDeclSyntax.self, self.visit, self.visitPost) } case .integerLiteralExpr: return { - self.visitImpl($0, IntegerLiteralExprSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, IntegerLiteralExprSyntax.self, self.visit, self.visitPost) } case .isExpr: return { - self.visitImpl($0, IsExprSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, IsExprSyntax.self, self.visit, self.visitPost) } case .isTypePattern: return { - self.visitImpl($0, IsTypePatternSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, IsTypePatternSyntax.self, self.visit, self.visitPost) } case .keyPathComponentList: return { - self.visitImpl($0, KeyPathComponentListSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, KeyPathComponentListSyntax.self, self.visit, self.visitPost) } case .keyPathComponent: return { - self.visitImpl($0, KeyPathComponentSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, KeyPathComponentSyntax.self, self.visit, self.visitPost) } case .keyPathExpr: return { - self.visitImpl($0, KeyPathExprSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, KeyPathExprSyntax.self, self.visit, self.visitPost) } case .keyPathOptionalComponent: return { - self.visitImpl($0, KeyPathOptionalComponentSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, KeyPathOptionalComponentSyntax.self, self.visit, self.visitPost) } case .keyPathPropertyComponent: return { - self.visitImpl($0, KeyPathPropertyComponentSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, KeyPathPropertyComponentSyntax.self, self.visit, self.visitPost) } case .keyPathSubscriptComponent: return { - self.visitImpl($0, KeyPathSubscriptComponentSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, KeyPathSubscriptComponentSyntax.self, self.visit, self.visitPost) } case .labeledExprList: return { - self.visitImpl($0, LabeledExprListSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, LabeledExprListSyntax.self, self.visit, self.visitPost) } case .labeledExpr: return { - self.visitImpl($0, LabeledExprSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, LabeledExprSyntax.self, self.visit, self.visitPost) } case .labeledSpecializeArgument: return { - self.visitImpl($0, LabeledSpecializeArgumentSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, LabeledSpecializeArgumentSyntax.self, self.visit, self.visitPost) } case .labeledStmt: return { - self.visitImpl($0, LabeledStmtSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, LabeledStmtSyntax.self, self.visit, self.visitPost) } case .layoutRequirement: return { - self.visitImpl($0, LayoutRequirementSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, LayoutRequirementSyntax.self, self.visit, self.visitPost) } case .lifetimeSpecifierArgumentList: return { - self.visitImpl($0, LifetimeSpecifierArgumentListSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, LifetimeSpecifierArgumentListSyntax.self, self.visit, self.visitPost) } case .lifetimeSpecifierArgument: return { - self.visitImpl($0, LifetimeSpecifierArgumentSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, LifetimeSpecifierArgumentSyntax.self, self.visit, self.visitPost) } case .lifetimeSpecifierArguments: return { - self.visitImpl($0, LifetimeSpecifierArgumentsSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, LifetimeSpecifierArgumentsSyntax.self, self.visit, self.visitPost) } case .lifetimeTypeSpecifier: return { - self.visitImpl($0, LifetimeTypeSpecifierSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, LifetimeTypeSpecifierSyntax.self, self.visit, self.visitPost) } case .macroDecl: return { - self.visitImpl($0, MacroDeclSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, MacroDeclSyntax.self, self.visit, self.visitPost) } case .macroExpansionDecl: return { - self.visitImpl($0, MacroExpansionDeclSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, MacroExpansionDeclSyntax.self, self.visit, self.visitPost) } case .macroExpansionExpr: return { - self.visitImpl($0, MacroExpansionExprSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, MacroExpansionExprSyntax.self, self.visit, self.visitPost) } case .matchingPatternCondition: return { - self.visitImpl($0, MatchingPatternConditionSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, MatchingPatternConditionSyntax.self, self.visit, self.visitPost) } case .memberAccessExpr: return { - self.visitImpl($0, MemberAccessExprSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, MemberAccessExprSyntax.self, self.visit, self.visitPost) } case .memberBlockItemList: return { - self.visitImpl($0, MemberBlockItemListSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, MemberBlockItemListSyntax.self, self.visit, self.visitPost) } case .memberBlockItem: return { - self.visitImpl($0, MemberBlockItemSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, MemberBlockItemSyntax.self, self.visit, self.visitPost) } case .memberBlock: return { - self.visitImpl($0, MemberBlockSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, MemberBlockSyntax.self, self.visit, self.visitPost) } case .memberType: return { - self.visitImpl($0, MemberTypeSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, MemberTypeSyntax.self, self.visit, self.visitPost) } case .metatypeType: return { - self.visitImpl($0, MetatypeTypeSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, MetatypeTypeSyntax.self, self.visit, self.visitPost) } case .missingDecl: return { - self.visitImpl($0, MissingDeclSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, MissingDeclSyntax.self, self.visit, self.visitPost) } case .missingExpr: return { - self.visitImpl($0, MissingExprSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, MissingExprSyntax.self, self.visit, self.visitPost) } case .missingPattern: return { - self.visitImpl($0, MissingPatternSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, MissingPatternSyntax.self, self.visit, self.visitPost) } case .missingStmt: return { - self.visitImpl($0, MissingStmtSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, MissingStmtSyntax.self, self.visit, self.visitPost) } case .missing: return { - self.visitImpl($0, MissingSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, MissingSyntax.self, self.visit, self.visitPost) } case .missingType: return { - self.visitImpl($0, MissingTypeSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, MissingTypeSyntax.self, self.visit, self.visitPost) } case .multipleTrailingClosureElementList: return { - self.visitImpl($0, MultipleTrailingClosureElementListSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, MultipleTrailingClosureElementListSyntax.self, self.visit, self.visitPost) } case .multipleTrailingClosureElement: return { - self.visitImpl($0, MultipleTrailingClosureElementSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, MultipleTrailingClosureElementSyntax.self, self.visit, self.visitPost) } case .namedOpaqueReturnType: return { - self.visitImpl($0, NamedOpaqueReturnTypeSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, NamedOpaqueReturnTypeSyntax.self, self.visit, self.visitPost) } case .nilLiteralExpr: return { - self.visitImpl($0, NilLiteralExprSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, NilLiteralExprSyntax.self, self.visit, self.visitPost) } case .objCSelectorPieceList: return { - self.visitImpl($0, ObjCSelectorPieceListSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, ObjCSelectorPieceListSyntax.self, self.visit, self.visitPost) } case .objCSelectorPiece: return { - self.visitImpl($0, ObjCSelectorPieceSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, ObjCSelectorPieceSyntax.self, self.visit, self.visitPost) } case .opaqueReturnTypeOfAttributeArguments: return { - self.visitImpl($0, OpaqueReturnTypeOfAttributeArgumentsSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, OpaqueReturnTypeOfAttributeArgumentsSyntax.self, self.visit, self.visitPost) } case .operatorDecl: return { - self.visitImpl($0, OperatorDeclSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, OperatorDeclSyntax.self, self.visit, self.visitPost) } case .operatorPrecedenceAndTypes: return { - self.visitImpl($0, OperatorPrecedenceAndTypesSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, OperatorPrecedenceAndTypesSyntax.self, self.visit, self.visitPost) } case .optionalBindingCondition: return { - self.visitImpl($0, OptionalBindingConditionSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, OptionalBindingConditionSyntax.self, self.visit, self.visitPost) } case .optionalChainingExpr: return { - self.visitImpl($0, OptionalChainingExprSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, OptionalChainingExprSyntax.self, self.visit, self.visitPost) } case .optionalType: return { - self.visitImpl($0, OptionalTypeSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, OptionalTypeSyntax.self, self.visit, self.visitPost) } case .originallyDefinedInAttributeArguments: return { - self.visitImpl($0, OriginallyDefinedInAttributeArgumentsSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, OriginallyDefinedInAttributeArgumentsSyntax.self, self.visit, self.visitPost) } case .packElementExpr: return { - self.visitImpl($0, PackElementExprSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, PackElementExprSyntax.self, self.visit, self.visitPost) } case .packElementType: return { - self.visitImpl($0, PackElementTypeSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, PackElementTypeSyntax.self, self.visit, self.visitPost) } case .packExpansionExpr: return { - self.visitImpl($0, PackExpansionExprSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, PackExpansionExprSyntax.self, self.visit, self.visitPost) } case .packExpansionType: return { - self.visitImpl($0, PackExpansionTypeSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, PackExpansionTypeSyntax.self, self.visit, self.visitPost) } case .patternBindingList: return { - self.visitImpl($0, PatternBindingListSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, PatternBindingListSyntax.self, self.visit, self.visitPost) } case .patternBinding: return { - self.visitImpl($0, PatternBindingSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, PatternBindingSyntax.self, self.visit, self.visitPost) } case .patternExpr: return { - self.visitImpl($0, PatternExprSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, PatternExprSyntax.self, self.visit, self.visitPost) } case .platformVersionItemList: return { - self.visitImpl($0, PlatformVersionItemListSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, PlatformVersionItemListSyntax.self, self.visit, self.visitPost) } case .platformVersionItem: return { - self.visitImpl($0, PlatformVersionItemSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, PlatformVersionItemSyntax.self, self.visit, self.visitPost) } case .platformVersion: return { - self.visitImpl($0, PlatformVersionSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, PlatformVersionSyntax.self, self.visit, self.visitPost) } case .postfixIfConfigExpr: return { - self.visitImpl($0, PostfixIfConfigExprSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, PostfixIfConfigExprSyntax.self, self.visit, self.visitPost) } case .postfixOperatorExpr: return { - self.visitImpl($0, PostfixOperatorExprSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, PostfixOperatorExprSyntax.self, self.visit, self.visitPost) } case .poundSourceLocationArguments: return { - self.visitImpl($0, PoundSourceLocationArgumentsSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, PoundSourceLocationArgumentsSyntax.self, self.visit, self.visitPost) } case .poundSourceLocation: return { - self.visitImpl($0, PoundSourceLocationSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, PoundSourceLocationSyntax.self, self.visit, self.visitPost) } case .precedenceGroupAssignment: return { - self.visitImpl($0, PrecedenceGroupAssignmentSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, PrecedenceGroupAssignmentSyntax.self, self.visit, self.visitPost) } case .precedenceGroupAssociativity: return { - self.visitImpl($0, PrecedenceGroupAssociativitySyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, PrecedenceGroupAssociativitySyntax.self, self.visit, self.visitPost) } case .precedenceGroupAttributeList: return { - self.visitImpl($0, PrecedenceGroupAttributeListSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, PrecedenceGroupAttributeListSyntax.self, self.visit, self.visitPost) } case .precedenceGroupDecl: return { - self.visitImpl($0, PrecedenceGroupDeclSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, PrecedenceGroupDeclSyntax.self, self.visit, self.visitPost) } case .precedenceGroupNameList: return { - self.visitImpl($0, PrecedenceGroupNameListSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, PrecedenceGroupNameListSyntax.self, self.visit, self.visitPost) } case .precedenceGroupName: return { - self.visitImpl($0, PrecedenceGroupNameSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, PrecedenceGroupNameSyntax.self, self.visit, self.visitPost) } case .precedenceGroupRelation: return { - self.visitImpl($0, PrecedenceGroupRelationSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, PrecedenceGroupRelationSyntax.self, self.visit, self.visitPost) } case .prefixOperatorExpr: return { - self.visitImpl($0, PrefixOperatorExprSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, PrefixOperatorExprSyntax.self, self.visit, self.visitPost) } case .primaryAssociatedTypeClause: return { - self.visitImpl($0, PrimaryAssociatedTypeClauseSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, PrimaryAssociatedTypeClauseSyntax.self, self.visit, self.visitPost) } case .primaryAssociatedTypeList: return { - self.visitImpl($0, PrimaryAssociatedTypeListSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, PrimaryAssociatedTypeListSyntax.self, self.visit, self.visitPost) } case .primaryAssociatedType: return { - self.visitImpl($0, PrimaryAssociatedTypeSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, PrimaryAssociatedTypeSyntax.self, self.visit, self.visitPost) } case .protocolDecl: return { - self.visitImpl($0, ProtocolDeclSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, ProtocolDeclSyntax.self, self.visit, self.visitPost) } case .regexLiteralExpr: return { - self.visitImpl($0, RegexLiteralExprSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, RegexLiteralExprSyntax.self, self.visit, self.visitPost) } case .repeatStmt: return { - self.visitImpl($0, RepeatStmtSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, RepeatStmtSyntax.self, self.visit, self.visitPost) } case .returnClause: return { - self.visitImpl($0, ReturnClauseSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, ReturnClauseSyntax.self, self.visit, self.visitPost) } case .returnStmt: return { - self.visitImpl($0, ReturnStmtSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, ReturnStmtSyntax.self, self.visit, self.visitPost) } case .sameTypeRequirement: return { - self.visitImpl($0, SameTypeRequirementSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, SameTypeRequirementSyntax.self, self.visit, self.visitPost) } case .sequenceExpr: return { - self.visitImpl($0, SequenceExprSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, SequenceExprSyntax.self, self.visit, self.visitPost) } case .simpleStringLiteralExpr: return { - self.visitImpl($0, SimpleStringLiteralExprSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, SimpleStringLiteralExprSyntax.self, self.visit, self.visitPost) } case .simpleStringLiteralSegmentList: return { - self.visitImpl($0, SimpleStringLiteralSegmentListSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, SimpleStringLiteralSegmentListSyntax.self, self.visit, self.visitPost) } case .simpleTypeSpecifier: return { - self.visitImpl($0, SimpleTypeSpecifierSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, SimpleTypeSpecifierSyntax.self, self.visit, self.visitPost) } case .someOrAnyType: return { - self.visitImpl($0, SomeOrAnyTypeSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, SomeOrAnyTypeSyntax.self, self.visit, self.visitPost) } case .sourceFile: return { - self.visitImpl($0, SourceFileSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, SourceFileSyntax.self, self.visit, self.visitPost) } case .specializeAttributeArgumentList: return { - self.visitImpl($0, SpecializeAttributeArgumentListSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, SpecializeAttributeArgumentListSyntax.self, self.visit, self.visitPost) } case .specializeAvailabilityArgument: return { - self.visitImpl($0, SpecializeAvailabilityArgumentSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, SpecializeAvailabilityArgumentSyntax.self, self.visit, self.visitPost) } case .specializeTargetFunctionArgument: return { - self.visitImpl($0, SpecializeTargetFunctionArgumentSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, SpecializeTargetFunctionArgumentSyntax.self, self.visit, self.visitPost) } case .stringLiteralExpr: return { - self.visitImpl($0, StringLiteralExprSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, StringLiteralExprSyntax.self, self.visit, self.visitPost) } case .stringLiteralSegmentList: return { - self.visitImpl($0, StringLiteralSegmentListSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, StringLiteralSegmentListSyntax.self, self.visit, self.visitPost) } case .stringSegment: return { - self.visitImpl($0, StringSegmentSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, StringSegmentSyntax.self, self.visit, self.visitPost) } case .structDecl: return { - self.visitImpl($0, StructDeclSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, StructDeclSyntax.self, self.visit, self.visitPost) } case .subscriptCallExpr: return { - self.visitImpl($0, SubscriptCallExprSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, SubscriptCallExprSyntax.self, self.visit, self.visitPost) } case .subscriptDecl: return { - self.visitImpl($0, SubscriptDeclSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, SubscriptDeclSyntax.self, self.visit, self.visitPost) } case .superExpr: return { - self.visitImpl($0, SuperExprSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, SuperExprSyntax.self, self.visit, self.visitPost) } case .suppressedType: return { - self.visitImpl($0, SuppressedTypeSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, SuppressedTypeSyntax.self, self.visit, self.visitPost) } case .switchCaseItemList: return { - self.visitImpl($0, SwitchCaseItemListSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, SwitchCaseItemListSyntax.self, self.visit, self.visitPost) } case .switchCaseItem: return { - self.visitImpl($0, SwitchCaseItemSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, SwitchCaseItemSyntax.self, self.visit, self.visitPost) } case .switchCaseLabel: return { - self.visitImpl($0, SwitchCaseLabelSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, SwitchCaseLabelSyntax.self, self.visit, self.visitPost) } case .switchCaseList: return { - self.visitImpl($0, SwitchCaseListSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, SwitchCaseListSyntax.self, self.visit, self.visitPost) } case .switchCase: return { - self.visitImpl($0, SwitchCaseSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, SwitchCaseSyntax.self, self.visit, self.visitPost) } case .switchDefaultLabel: return { - self.visitImpl($0, SwitchDefaultLabelSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, SwitchDefaultLabelSyntax.self, self.visit, self.visitPost) } case .switchExpr: return { - self.visitImpl($0, SwitchExprSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, SwitchExprSyntax.self, self.visit, self.visitPost) } case .ternaryExpr: return { - self.visitImpl($0, TernaryExprSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, TernaryExprSyntax.self, self.visit, self.visitPost) } case .thenStmt: return { - self.visitImpl($0, ThenStmtSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, ThenStmtSyntax.self, self.visit, self.visitPost) } case .throwStmt: return { - self.visitImpl($0, ThrowStmtSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, ThrowStmtSyntax.self, self.visit, self.visitPost) } case .throwsClause: return { - self.visitImpl($0, ThrowsClauseSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, ThrowsClauseSyntax.self, self.visit, self.visitPost) } case .tryExpr: return { - self.visitImpl($0, TryExprSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, TryExprSyntax.self, self.visit, self.visitPost) } case .tupleExpr: return { - self.visitImpl($0, TupleExprSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, TupleExprSyntax.self, self.visit, self.visitPost) } case .tuplePatternElementList: return { - self.visitImpl($0, TuplePatternElementListSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, TuplePatternElementListSyntax.self, self.visit, self.visitPost) } case .tuplePatternElement: return { - self.visitImpl($0, TuplePatternElementSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, TuplePatternElementSyntax.self, self.visit, self.visitPost) } case .tuplePattern: return { - self.visitImpl($0, TuplePatternSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, TuplePatternSyntax.self, self.visit, self.visitPost) } case .tupleTypeElementList: return { - self.visitImpl($0, TupleTypeElementListSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, TupleTypeElementListSyntax.self, self.visit, self.visitPost) } case .tupleTypeElement: return { - self.visitImpl($0, TupleTypeElementSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, TupleTypeElementSyntax.self, self.visit, self.visitPost) } case .tupleType: return { - self.visitImpl($0, TupleTypeSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, TupleTypeSyntax.self, self.visit, self.visitPost) } case .typeAliasDecl: return { - self.visitImpl($0, TypeAliasDeclSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, TypeAliasDeclSyntax.self, self.visit, self.visitPost) } case .typeAnnotation: return { - self.visitImpl($0, TypeAnnotationSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, TypeAnnotationSyntax.self, self.visit, self.visitPost) } case .typeEffectSpecifiers: return { - self.visitImpl($0, TypeEffectSpecifiersSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, TypeEffectSpecifiersSyntax.self, self.visit, self.visitPost) } case .typeExpr: return { - self.visitImpl($0, TypeExprSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, TypeExprSyntax.self, self.visit, self.visitPost) } case .typeInitializerClause: return { - self.visitImpl($0, TypeInitializerClauseSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, TypeInitializerClauseSyntax.self, self.visit, self.visitPost) } case .typeSpecifierList: return { - self.visitImpl($0, TypeSpecifierListSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, TypeSpecifierListSyntax.self, self.visit, self.visitPost) } case .unavailableFromAsyncAttributeArguments: return { - self.visitImpl($0, UnavailableFromAsyncAttributeArgumentsSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, UnavailableFromAsyncAttributeArgumentsSyntax.self, self.visit, self.visitPost) } case .underscorePrivateAttributeArguments: return { - self.visitImpl($0, UnderscorePrivateAttributeArgumentsSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, UnderscorePrivateAttributeArgumentsSyntax.self, self.visit, self.visitPost) } case .unexpectedNodes: return { - self.visitImpl($0, UnexpectedNodesSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, UnexpectedNodesSyntax.self, self.visit, self.visitPost) } case .unresolvedAsExpr: return { - self.visitImpl($0, UnresolvedAsExprSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, UnresolvedAsExprSyntax.self, self.visit, self.visitPost) } case .unresolvedIsExpr: return { - self.visitImpl($0, UnresolvedIsExprSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, UnresolvedIsExprSyntax.self, self.visit, self.visitPost) } case .unresolvedTernaryExpr: return { - self.visitImpl($0, UnresolvedTernaryExprSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, UnresolvedTernaryExprSyntax.self, self.visit, self.visitPost) } case .valueBindingPattern: return { - self.visitImpl($0, ValueBindingPatternSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, ValueBindingPatternSyntax.self, self.visit, self.visitPost) } case .variableDecl: return { - self.visitImpl($0, VariableDeclSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, VariableDeclSyntax.self, self.visit, self.visitPost) } case .versionComponentList: return { - self.visitImpl($0, VersionComponentListSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, VersionComponentListSyntax.self, self.visit, self.visitPost) } case .versionComponent: return { - self.visitImpl($0, VersionComponentSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, VersionComponentSyntax.self, self.visit, self.visitPost) } case .versionTuple: return { - self.visitImpl($0, VersionTupleSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, VersionTupleSyntax.self, self.visit, self.visitPost) } case .whereClause: return { - self.visitImpl($0, WhereClauseSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, WhereClauseSyntax.self, self.visit, self.visitPost) } case .whileStmt: return { - self.visitImpl($0, WhileStmtSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, WhileStmtSyntax.self, self.visit, self.visitPost) } case .wildcardPattern: return { - self.visitImpl($0, WildcardPatternSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, WildcardPatternSyntax.self, self.visit, self.visitPost) } case .yieldStmt: return { - self.visitImpl($0, YieldStmtSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, YieldStmtSyntax.self, self.visit, self.visitPost) } case .yieldedExpressionList: return { - self.visitImpl($0, YieldedExpressionListSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, YieldedExpressionListSyntax.self, self.visit, self.visitPost) } case .yieldedExpression: return { - self.visitImpl($0, YieldedExpressionSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, YieldedExpressionSyntax.self, self.visit, self.visitPost) } case .yieldedExpressionsClause: return { - self.visitImpl($0, YieldedExpressionsClauseSyntax.self, self.visit, self.visitPost) + self.visitImpl(&$0, YieldedExpressionsClauseSyntax.self, self.visit, self.visitPost) } } } - private func visit(_ node: Syntax) { - return visitationFunc(for: node)(node) + private func visit(_ node: inout Syntax) { + return visitationFunc(for: node)(&node) } #else - private func visit(_ node: Syntax) { + /// - Note: `node` is `inout` to avoid ref-counting. See comment in `visitImpl` + private func visit(_ node: inout Syntax) { switch node.raw.kind { case .token: let node = node.cast(TokenSyntax.self) @@ -4690,581 +4719,632 @@ open class SyntaxVisitor { // No children to visit. visitPost(node) case .accessorBlock: - visitImpl(node, AccessorBlockSyntax.self, visit, visitPost) + visitImpl(&node, AccessorBlockSyntax.self, visit, visitPost) case .accessorDeclList: - visitImpl(node, AccessorDeclListSyntax.self, visit, visitPost) + visitImpl(&node, AccessorDeclListSyntax.self, visit, visitPost) case .accessorDecl: - visitImpl(node, AccessorDeclSyntax.self, visit, visitPost) + visitImpl(&node, AccessorDeclSyntax.self, visit, visitPost) case .accessorEffectSpecifiers: - visitImpl(node, AccessorEffectSpecifiersSyntax.self, visit, visitPost) + visitImpl(&node, AccessorEffectSpecifiersSyntax.self, visit, visitPost) case .accessorParameters: - visitImpl(node, AccessorParametersSyntax.self, visit, visitPost) + visitImpl(&node, AccessorParametersSyntax.self, visit, visitPost) case .actorDecl: - visitImpl(node, ActorDeclSyntax.self, visit, visitPost) + visitImpl(&node, ActorDeclSyntax.self, visit, visitPost) case .arrayElementList: - visitImpl(node, ArrayElementListSyntax.self, visit, visitPost) + visitImpl(&node, ArrayElementListSyntax.self, visit, visitPost) case .arrayElement: - visitImpl(node, ArrayElementSyntax.self, visit, visitPost) + visitImpl(&node, ArrayElementSyntax.self, visit, visitPost) case .arrayExpr: - visitImpl(node, ArrayExprSyntax.self, visit, visitPost) + visitImpl(&node, ArrayExprSyntax.self, visit, visitPost) case .arrayType: - visitImpl(node, ArrayTypeSyntax.self, visit, visitPost) + visitImpl(&node, ArrayTypeSyntax.self, visit, visitPost) case .arrowExpr: - visitImpl(node, ArrowExprSyntax.self, visit, visitPost) + visitImpl(&node, ArrowExprSyntax.self, visit, visitPost) case .asExpr: - visitImpl(node, AsExprSyntax.self, visit, visitPost) + visitImpl(&node, AsExprSyntax.self, visit, visitPost) case .assignmentExpr: - visitImpl(node, AssignmentExprSyntax.self, visit, visitPost) + visitImpl(&node, AssignmentExprSyntax.self, visit, visitPost) case .associatedTypeDecl: - visitImpl(node, AssociatedTypeDeclSyntax.self, visit, visitPost) + visitImpl(&node, AssociatedTypeDeclSyntax.self, visit, visitPost) case .attributeList: - visitImpl(node, AttributeListSyntax.self, visit, visitPost) + visitImpl(&node, AttributeListSyntax.self, visit, visitPost) case .attribute: - visitImpl(node, AttributeSyntax.self, visit, visitPost) + visitImpl(&node, AttributeSyntax.self, visit, visitPost) case .attributedType: - visitImpl(node, AttributedTypeSyntax.self, visit, visitPost) + visitImpl(&node, AttributedTypeSyntax.self, visit, visitPost) case .availabilityArgumentList: - visitImpl(node, AvailabilityArgumentListSyntax.self, visit, visitPost) + visitImpl(&node, AvailabilityArgumentListSyntax.self, visit, visitPost) case .availabilityArgument: - visitImpl(node, AvailabilityArgumentSyntax.self, visit, visitPost) + visitImpl(&node, AvailabilityArgumentSyntax.self, visit, visitPost) case .availabilityCondition: - visitImpl(node, AvailabilityConditionSyntax.self, visit, visitPost) + visitImpl(&node, AvailabilityConditionSyntax.self, visit, visitPost) case .availabilityLabeledArgument: - visitImpl(node, AvailabilityLabeledArgumentSyntax.self, visit, visitPost) + visitImpl(&node, AvailabilityLabeledArgumentSyntax.self, visit, visitPost) case .awaitExpr: - visitImpl(node, AwaitExprSyntax.self, visit, visitPost) + visitImpl(&node, AwaitExprSyntax.self, visit, visitPost) case .backDeployedAttributeArguments: - visitImpl(node, BackDeployedAttributeArgumentsSyntax.self, visit, visitPost) + visitImpl(&node, BackDeployedAttributeArgumentsSyntax.self, visit, visitPost) case .binaryOperatorExpr: - visitImpl(node, BinaryOperatorExprSyntax.self, visit, visitPost) + visitImpl(&node, BinaryOperatorExprSyntax.self, visit, visitPost) case .booleanLiteralExpr: - visitImpl(node, BooleanLiteralExprSyntax.self, visit, visitPost) + visitImpl(&node, BooleanLiteralExprSyntax.self, visit, visitPost) case .borrowExpr: - visitImpl(node, BorrowExprSyntax.self, visit, visitPost) + visitImpl(&node, BorrowExprSyntax.self, visit, visitPost) case .breakStmt: - visitImpl(node, BreakStmtSyntax.self, visit, visitPost) + visitImpl(&node, BreakStmtSyntax.self, visit, visitPost) case .canImportExpr: - visitImpl(node, CanImportExprSyntax.self, visit, visitPost) + visitImpl(&node, CanImportExprSyntax.self, visit, visitPost) case .canImportVersionInfo: - visitImpl(node, CanImportVersionInfoSyntax.self, visit, visitPost) + visitImpl(&node, CanImportVersionInfoSyntax.self, visit, visitPost) case .catchClauseList: - visitImpl(node, CatchClauseListSyntax.self, visit, visitPost) + visitImpl(&node, CatchClauseListSyntax.self, visit, visitPost) case .catchClause: - visitImpl(node, CatchClauseSyntax.self, visit, visitPost) + visitImpl(&node, CatchClauseSyntax.self, visit, visitPost) case .catchItemList: - visitImpl(node, CatchItemListSyntax.self, visit, visitPost) + visitImpl(&node, CatchItemListSyntax.self, visit, visitPost) case .catchItem: - visitImpl(node, CatchItemSyntax.self, visit, visitPost) + visitImpl(&node, CatchItemSyntax.self, visit, visitPost) case .classDecl: - visitImpl(node, ClassDeclSyntax.self, visit, visitPost) + visitImpl(&node, ClassDeclSyntax.self, visit, visitPost) case .classRestrictionType: - visitImpl(node, ClassRestrictionTypeSyntax.self, visit, visitPost) + visitImpl(&node, ClassRestrictionTypeSyntax.self, visit, visitPost) case .closureCaptureClause: - visitImpl(node, ClosureCaptureClauseSyntax.self, visit, visitPost) + visitImpl(&node, ClosureCaptureClauseSyntax.self, visit, visitPost) case .closureCaptureList: - visitImpl(node, ClosureCaptureListSyntax.self, visit, visitPost) + visitImpl(&node, ClosureCaptureListSyntax.self, visit, visitPost) case .closureCaptureSpecifier: - visitImpl(node, ClosureCaptureSpecifierSyntax.self, visit, visitPost) + visitImpl(&node, ClosureCaptureSpecifierSyntax.self, visit, visitPost) case .closureCapture: - visitImpl(node, ClosureCaptureSyntax.self, visit, visitPost) + visitImpl(&node, ClosureCaptureSyntax.self, visit, visitPost) case .closureExpr: - visitImpl(node, ClosureExprSyntax.self, visit, visitPost) + visitImpl(&node, ClosureExprSyntax.self, visit, visitPost) case .closureParameterClause: - visitImpl(node, ClosureParameterClauseSyntax.self, visit, visitPost) + visitImpl(&node, ClosureParameterClauseSyntax.self, visit, visitPost) case .closureParameterList: - visitImpl(node, ClosureParameterListSyntax.self, visit, visitPost) + visitImpl(&node, ClosureParameterListSyntax.self, visit, visitPost) case .closureParameter: - visitImpl(node, ClosureParameterSyntax.self, visit, visitPost) + visitImpl(&node, ClosureParameterSyntax.self, visit, visitPost) case .closureShorthandParameterList: - visitImpl(node, ClosureShorthandParameterListSyntax.self, visit, visitPost) + visitImpl(&node, ClosureShorthandParameterListSyntax.self, visit, visitPost) case .closureShorthandParameter: - visitImpl(node, ClosureShorthandParameterSyntax.self, visit, visitPost) + visitImpl(&node, ClosureShorthandParameterSyntax.self, visit, visitPost) case .closureSignature: - visitImpl(node, ClosureSignatureSyntax.self, visit, visitPost) + visitImpl(&node, ClosureSignatureSyntax.self, visit, visitPost) case .codeBlockItemList: - visitImpl(node, CodeBlockItemListSyntax.self, visit, visitPost) + visitImpl(&node, CodeBlockItemListSyntax.self, visit, visitPost) case .codeBlockItem: - visitImpl(node, CodeBlockItemSyntax.self, visit, visitPost) + visitImpl(&node, CodeBlockItemSyntax.self, visit, visitPost) case .codeBlock: - visitImpl(node, CodeBlockSyntax.self, visit, visitPost) + visitImpl(&node, CodeBlockSyntax.self, visit, visitPost) case .compositionTypeElementList: - visitImpl(node, CompositionTypeElementListSyntax.self, visit, visitPost) + visitImpl(&node, CompositionTypeElementListSyntax.self, visit, visitPost) case .compositionTypeElement: - visitImpl(node, CompositionTypeElementSyntax.self, visit, visitPost) + visitImpl(&node, CompositionTypeElementSyntax.self, visit, visitPost) case .compositionType: - visitImpl(node, CompositionTypeSyntax.self, visit, visitPost) + visitImpl(&node, CompositionTypeSyntax.self, visit, visitPost) case .conditionElementList: - visitImpl(node, ConditionElementListSyntax.self, visit, visitPost) + visitImpl(&node, ConditionElementListSyntax.self, visit, visitPost) case .conditionElement: - visitImpl(node, ConditionElementSyntax.self, visit, visitPost) + visitImpl(&node, ConditionElementSyntax.self, visit, visitPost) case .conformanceRequirement: - visitImpl(node, ConformanceRequirementSyntax.self, visit, visitPost) + visitImpl(&node, ConformanceRequirementSyntax.self, visit, visitPost) case .consumeExpr: - visitImpl(node, ConsumeExprSyntax.self, visit, visitPost) + visitImpl(&node, ConsumeExprSyntax.self, visit, visitPost) case .continueStmt: - visitImpl(node, ContinueStmtSyntax.self, visit, visitPost) + visitImpl(&node, ContinueStmtSyntax.self, visit, visitPost) case .conventionAttributeArguments: - visitImpl(node, ConventionAttributeArgumentsSyntax.self, visit, visitPost) + visitImpl(&node, ConventionAttributeArgumentsSyntax.self, visit, visitPost) case .conventionWitnessMethodAttributeArguments: - visitImpl(node, ConventionWitnessMethodAttributeArgumentsSyntax.self, visit, visitPost) + visitImpl(&node, ConventionWitnessMethodAttributeArgumentsSyntax.self, visit, visitPost) case .copyExpr: - visitImpl(node, CopyExprSyntax.self, visit, visitPost) + visitImpl(&node, CopyExprSyntax.self, visit, visitPost) case .declModifierDetail: - visitImpl(node, DeclModifierDetailSyntax.self, visit, visitPost) + visitImpl(&node, DeclModifierDetailSyntax.self, visit, visitPost) case .declModifierList: - visitImpl(node, DeclModifierListSyntax.self, visit, visitPost) + visitImpl(&node, DeclModifierListSyntax.self, visit, visitPost) case .declModifier: - visitImpl(node, DeclModifierSyntax.self, visit, visitPost) + visitImpl(&node, DeclModifierSyntax.self, visit, visitPost) case .declNameArgumentList: - visitImpl(node, DeclNameArgumentListSyntax.self, visit, visitPost) + visitImpl(&node, DeclNameArgumentListSyntax.self, visit, visitPost) case .declNameArgument: - visitImpl(node, DeclNameArgumentSyntax.self, visit, visitPost) + visitImpl(&node, DeclNameArgumentSyntax.self, visit, visitPost) case .declNameArguments: - visitImpl(node, DeclNameArgumentsSyntax.self, visit, visitPost) + visitImpl(&node, DeclNameArgumentsSyntax.self, visit, visitPost) case .declReferenceExpr: - visitImpl(node, DeclReferenceExprSyntax.self, visit, visitPost) + visitImpl(&node, DeclReferenceExprSyntax.self, visit, visitPost) case .deferStmt: - visitImpl(node, DeferStmtSyntax.self, visit, visitPost) + visitImpl(&node, DeferStmtSyntax.self, visit, visitPost) case .deinitializerDecl: - visitImpl(node, DeinitializerDeclSyntax.self, visit, visitPost) + visitImpl(&node, DeinitializerDeclSyntax.self, visit, visitPost) case .deinitializerEffectSpecifiers: - visitImpl(node, DeinitializerEffectSpecifiersSyntax.self, visit, visitPost) + visitImpl(&node, DeinitializerEffectSpecifiersSyntax.self, visit, visitPost) case .derivativeAttributeArguments: - visitImpl(node, DerivativeAttributeArgumentsSyntax.self, visit, visitPost) + visitImpl(&node, DerivativeAttributeArgumentsSyntax.self, visit, visitPost) case .designatedTypeList: - visitImpl(node, DesignatedTypeListSyntax.self, visit, visitPost) + visitImpl(&node, DesignatedTypeListSyntax.self, visit, visitPost) case .designatedType: - visitImpl(node, DesignatedTypeSyntax.self, visit, visitPost) + visitImpl(&node, DesignatedTypeSyntax.self, visit, visitPost) case .dictionaryElementList: - visitImpl(node, DictionaryElementListSyntax.self, visit, visitPost) + visitImpl(&node, DictionaryElementListSyntax.self, visit, visitPost) case .dictionaryElement: - visitImpl(node, DictionaryElementSyntax.self, visit, visitPost) + visitImpl(&node, DictionaryElementSyntax.self, visit, visitPost) case .dictionaryExpr: - visitImpl(node, DictionaryExprSyntax.self, visit, visitPost) + visitImpl(&node, DictionaryExprSyntax.self, visit, visitPost) case .dictionaryType: - visitImpl(node, DictionaryTypeSyntax.self, visit, visitPost) + visitImpl(&node, DictionaryTypeSyntax.self, visit, visitPost) case .differentiabilityArgumentList: - visitImpl(node, DifferentiabilityArgumentListSyntax.self, visit, visitPost) + visitImpl(&node, DifferentiabilityArgumentListSyntax.self, visit, visitPost) case .differentiabilityArgument: - visitImpl(node, DifferentiabilityArgumentSyntax.self, visit, visitPost) + visitImpl(&node, DifferentiabilityArgumentSyntax.self, visit, visitPost) case .differentiabilityArguments: - visitImpl(node, DifferentiabilityArgumentsSyntax.self, visit, visitPost) + visitImpl(&node, DifferentiabilityArgumentsSyntax.self, visit, visitPost) case .differentiabilityWithRespectToArgument: - visitImpl(node, DifferentiabilityWithRespectToArgumentSyntax.self, visit, visitPost) + visitImpl(&node, DifferentiabilityWithRespectToArgumentSyntax.self, visit, visitPost) case .differentiableAttributeArguments: - visitImpl(node, DifferentiableAttributeArgumentsSyntax.self, visit, visitPost) + visitImpl(&node, DifferentiableAttributeArgumentsSyntax.self, visit, visitPost) case .discardAssignmentExpr: - visitImpl(node, DiscardAssignmentExprSyntax.self, visit, visitPost) + visitImpl(&node, DiscardAssignmentExprSyntax.self, visit, visitPost) case .discardStmt: - visitImpl(node, DiscardStmtSyntax.self, visit, visitPost) + visitImpl(&node, DiscardStmtSyntax.self, visit, visitPost) case .doExpr: - visitImpl(node, DoExprSyntax.self, visit, visitPost) + visitImpl(&node, DoExprSyntax.self, visit, visitPost) case .doStmt: - visitImpl(node, DoStmtSyntax.self, visit, visitPost) + visitImpl(&node, DoStmtSyntax.self, visit, visitPost) case .documentationAttributeArgumentList: - visitImpl(node, DocumentationAttributeArgumentListSyntax.self, visit, visitPost) + visitImpl(&node, DocumentationAttributeArgumentListSyntax.self, visit, visitPost) case .documentationAttributeArgument: - visitImpl(node, DocumentationAttributeArgumentSyntax.self, visit, visitPost) + visitImpl(&node, DocumentationAttributeArgumentSyntax.self, visit, visitPost) case .dynamicReplacementAttributeArguments: - visitImpl(node, DynamicReplacementAttributeArgumentsSyntax.self, visit, visitPost) + visitImpl(&node, DynamicReplacementAttributeArgumentsSyntax.self, visit, visitPost) case .editorPlaceholderDecl: - visitImpl(node, EditorPlaceholderDeclSyntax.self, visit, visitPost) + visitImpl(&node, EditorPlaceholderDeclSyntax.self, visit, visitPost) case .editorPlaceholderExpr: - visitImpl(node, EditorPlaceholderExprSyntax.self, visit, visitPost) + visitImpl(&node, EditorPlaceholderExprSyntax.self, visit, visitPost) case .effectsAttributeArgumentList: - visitImpl(node, EffectsAttributeArgumentListSyntax.self, visit, visitPost) + visitImpl(&node, EffectsAttributeArgumentListSyntax.self, visit, visitPost) case .enumCaseDecl: - visitImpl(node, EnumCaseDeclSyntax.self, visit, visitPost) + visitImpl(&node, EnumCaseDeclSyntax.self, visit, visitPost) case .enumCaseElementList: - visitImpl(node, EnumCaseElementListSyntax.self, visit, visitPost) + visitImpl(&node, EnumCaseElementListSyntax.self, visit, visitPost) case .enumCaseElement: - visitImpl(node, EnumCaseElementSyntax.self, visit, visitPost) + visitImpl(&node, EnumCaseElementSyntax.self, visit, visitPost) case .enumCaseParameterClause: - visitImpl(node, EnumCaseParameterClauseSyntax.self, visit, visitPost) + visitImpl(&node, EnumCaseParameterClauseSyntax.self, visit, visitPost) case .enumCaseParameterList: - visitImpl(node, EnumCaseParameterListSyntax.self, visit, visitPost) + visitImpl(&node, EnumCaseParameterListSyntax.self, visit, visitPost) case .enumCaseParameter: - visitImpl(node, EnumCaseParameterSyntax.self, visit, visitPost) + visitImpl(&node, EnumCaseParameterSyntax.self, visit, visitPost) case .enumDecl: - visitImpl(node, EnumDeclSyntax.self, visit, visitPost) + visitImpl(&node, EnumDeclSyntax.self, visit, visitPost) case .exposeAttributeArguments: - visitImpl(node, ExposeAttributeArgumentsSyntax.self, visit, visitPost) + visitImpl(&node, ExposeAttributeArgumentsSyntax.self, visit, visitPost) case .exprList: - visitImpl(node, ExprListSyntax.self, visit, visitPost) + visitImpl(&node, ExprListSyntax.self, visit, visitPost) case .expressionPattern: - visitImpl(node, ExpressionPatternSyntax.self, visit, visitPost) + visitImpl(&node, ExpressionPatternSyntax.self, visit, visitPost) case .expressionSegment: - visitImpl(node, ExpressionSegmentSyntax.self, visit, visitPost) + visitImpl(&node, ExpressionSegmentSyntax.self, visit, visitPost) case .expressionStmt: - visitImpl(node, ExpressionStmtSyntax.self, visit, visitPost) + visitImpl(&node, ExpressionStmtSyntax.self, visit, visitPost) case .extensionDecl: - visitImpl(node, ExtensionDeclSyntax.self, visit, visitPost) + visitImpl(&node, ExtensionDeclSyntax.self, visit, visitPost) case .fallThroughStmt: - visitImpl(node, FallThroughStmtSyntax.self, visit, visitPost) + visitImpl(&node, FallThroughStmtSyntax.self, visit, visitPost) case .floatLiteralExpr: - visitImpl(node, FloatLiteralExprSyntax.self, visit, visitPost) + visitImpl(&node, FloatLiteralExprSyntax.self, visit, visitPost) case .forStmt: - visitImpl(node, ForStmtSyntax.self, visit, visitPost) + visitImpl(&node, ForStmtSyntax.self, visit, visitPost) case .forceUnwrapExpr: - visitImpl(node, ForceUnwrapExprSyntax.self, visit, visitPost) + visitImpl(&node, ForceUnwrapExprSyntax.self, visit, visitPost) case .functionCallExpr: - visitImpl(node, FunctionCallExprSyntax.self, visit, visitPost) + visitImpl(&node, FunctionCallExprSyntax.self, visit, visitPost) case .functionDecl: - visitImpl(node, FunctionDeclSyntax.self, visit, visitPost) + visitImpl(&node, FunctionDeclSyntax.self, visit, visitPost) case .functionEffectSpecifiers: - visitImpl(node, FunctionEffectSpecifiersSyntax.self, visit, visitPost) + visitImpl(&node, FunctionEffectSpecifiersSyntax.self, visit, visitPost) case .functionParameterClause: - visitImpl(node, FunctionParameterClauseSyntax.self, visit, visitPost) + visitImpl(&node, FunctionParameterClauseSyntax.self, visit, visitPost) case .functionParameterList: - visitImpl(node, FunctionParameterListSyntax.self, visit, visitPost) + visitImpl(&node, FunctionParameterListSyntax.self, visit, visitPost) case .functionParameter: - visitImpl(node, FunctionParameterSyntax.self, visit, visitPost) + visitImpl(&node, FunctionParameterSyntax.self, visit, visitPost) case .functionSignature: - visitImpl(node, FunctionSignatureSyntax.self, visit, visitPost) + visitImpl(&node, FunctionSignatureSyntax.self, visit, visitPost) case .functionType: - visitImpl(node, FunctionTypeSyntax.self, visit, visitPost) + visitImpl(&node, FunctionTypeSyntax.self, visit, visitPost) case .genericArgumentClause: - visitImpl(node, GenericArgumentClauseSyntax.self, visit, visitPost) + visitImpl(&node, GenericArgumentClauseSyntax.self, visit, visitPost) case .genericArgumentList: - visitImpl(node, GenericArgumentListSyntax.self, visit, visitPost) + visitImpl(&node, GenericArgumentListSyntax.self, visit, visitPost) case .genericArgument: - visitImpl(node, GenericArgumentSyntax.self, visit, visitPost) + visitImpl(&node, GenericArgumentSyntax.self, visit, visitPost) case .genericParameterClause: - visitImpl(node, GenericParameterClauseSyntax.self, visit, visitPost) + visitImpl(&node, GenericParameterClauseSyntax.self, visit, visitPost) case .genericParameterList: - visitImpl(node, GenericParameterListSyntax.self, visit, visitPost) + visitImpl(&node, GenericParameterListSyntax.self, visit, visitPost) case .genericParameter: - visitImpl(node, GenericParameterSyntax.self, visit, visitPost) + visitImpl(&node, GenericParameterSyntax.self, visit, visitPost) case .genericRequirementList: - visitImpl(node, GenericRequirementListSyntax.self, visit, visitPost) + visitImpl(&node, GenericRequirementListSyntax.self, visit, visitPost) case .genericRequirement: - visitImpl(node, GenericRequirementSyntax.self, visit, visitPost) + visitImpl(&node, GenericRequirementSyntax.self, visit, visitPost) case .genericSpecializationExpr: - visitImpl(node, GenericSpecializationExprSyntax.self, visit, visitPost) + visitImpl(&node, GenericSpecializationExprSyntax.self, visit, visitPost) case .genericWhereClause: - visitImpl(node, GenericWhereClauseSyntax.self, visit, visitPost) + visitImpl(&node, GenericWhereClauseSyntax.self, visit, visitPost) case .guardStmt: - visitImpl(node, GuardStmtSyntax.self, visit, visitPost) + visitImpl(&node, GuardStmtSyntax.self, visit, visitPost) case .identifierPattern: - visitImpl(node, IdentifierPatternSyntax.self, visit, visitPost) + visitImpl(&node, IdentifierPatternSyntax.self, visit, visitPost) case .identifierType: - visitImpl(node, IdentifierTypeSyntax.self, visit, visitPost) + visitImpl(&node, IdentifierTypeSyntax.self, visit, visitPost) case .ifConfigClauseList: - visitImpl(node, IfConfigClauseListSyntax.self, visit, visitPost) + visitImpl(&node, IfConfigClauseListSyntax.self, visit, visitPost) case .ifConfigClause: - visitImpl(node, IfConfigClauseSyntax.self, visit, visitPost) + visitImpl(&node, IfConfigClauseSyntax.self, visit, visitPost) case .ifConfigDecl: - visitImpl(node, IfConfigDeclSyntax.self, visit, visitPost) + visitImpl(&node, IfConfigDeclSyntax.self, visit, visitPost) case .ifExpr: - visitImpl(node, IfExprSyntax.self, visit, visitPost) + visitImpl(&node, IfExprSyntax.self, visit, visitPost) case .implementsAttributeArguments: - visitImpl(node, ImplementsAttributeArgumentsSyntax.self, visit, visitPost) + visitImpl(&node, ImplementsAttributeArgumentsSyntax.self, visit, visitPost) case .implicitlyUnwrappedOptionalType: - visitImpl(node, ImplicitlyUnwrappedOptionalTypeSyntax.self, visit, visitPost) + visitImpl(&node, ImplicitlyUnwrappedOptionalTypeSyntax.self, visit, visitPost) case .importDecl: - visitImpl(node, ImportDeclSyntax.self, visit, visitPost) + visitImpl(&node, ImportDeclSyntax.self, visit, visitPost) case .importPathComponentList: - visitImpl(node, ImportPathComponentListSyntax.self, visit, visitPost) + visitImpl(&node, ImportPathComponentListSyntax.self, visit, visitPost) case .importPathComponent: - visitImpl(node, ImportPathComponentSyntax.self, visit, visitPost) + visitImpl(&node, ImportPathComponentSyntax.self, visit, visitPost) case .inOutExpr: - visitImpl(node, InOutExprSyntax.self, visit, visitPost) + visitImpl(&node, InOutExprSyntax.self, visit, visitPost) case .infixOperatorExpr: - visitImpl(node, InfixOperatorExprSyntax.self, visit, visitPost) + visitImpl(&node, InfixOperatorExprSyntax.self, visit, visitPost) case .inheritanceClause: - visitImpl(node, InheritanceClauseSyntax.self, visit, visitPost) + visitImpl(&node, InheritanceClauseSyntax.self, visit, visitPost) case .inheritedTypeList: - visitImpl(node, InheritedTypeListSyntax.self, visit, visitPost) + visitImpl(&node, InheritedTypeListSyntax.self, visit, visitPost) case .inheritedType: - visitImpl(node, InheritedTypeSyntax.self, visit, visitPost) + visitImpl(&node, InheritedTypeSyntax.self, visit, visitPost) case .initializerClause: - visitImpl(node, InitializerClauseSyntax.self, visit, visitPost) + visitImpl(&node, InitializerClauseSyntax.self, visit, visitPost) case .initializerDecl: - visitImpl(node, InitializerDeclSyntax.self, visit, visitPost) + visitImpl(&node, InitializerDeclSyntax.self, visit, visitPost) case .integerLiteralExpr: - visitImpl(node, IntegerLiteralExprSyntax.self, visit, visitPost) + visitImpl(&node, IntegerLiteralExprSyntax.self, visit, visitPost) case .isExpr: - visitImpl(node, IsExprSyntax.self, visit, visitPost) + visitImpl(&node, IsExprSyntax.self, visit, visitPost) case .isTypePattern: - visitImpl(node, IsTypePatternSyntax.self, visit, visitPost) + visitImpl(&node, IsTypePatternSyntax.self, visit, visitPost) case .keyPathComponentList: - visitImpl(node, KeyPathComponentListSyntax.self, visit, visitPost) + visitImpl(&node, KeyPathComponentListSyntax.self, visit, visitPost) case .keyPathComponent: - visitImpl(node, KeyPathComponentSyntax.self, visit, visitPost) + visitImpl(&node, KeyPathComponentSyntax.self, visit, visitPost) case .keyPathExpr: - visitImpl(node, KeyPathExprSyntax.self, visit, visitPost) + visitImpl(&node, KeyPathExprSyntax.self, visit, visitPost) case .keyPathOptionalComponent: - visitImpl(node, KeyPathOptionalComponentSyntax.self, visit, visitPost) + visitImpl(&node, KeyPathOptionalComponentSyntax.self, visit, visitPost) case .keyPathPropertyComponent: - visitImpl(node, KeyPathPropertyComponentSyntax.self, visit, visitPost) + visitImpl(&node, KeyPathPropertyComponentSyntax.self, visit, visitPost) case .keyPathSubscriptComponent: - visitImpl(node, KeyPathSubscriptComponentSyntax.self, visit, visitPost) + visitImpl(&node, KeyPathSubscriptComponentSyntax.self, visit, visitPost) case .labeledExprList: - visitImpl(node, LabeledExprListSyntax.self, visit, visitPost) + visitImpl(&node, LabeledExprListSyntax.self, visit, visitPost) case .labeledExpr: - visitImpl(node, LabeledExprSyntax.self, visit, visitPost) + visitImpl(&node, LabeledExprSyntax.self, visit, visitPost) case .labeledSpecializeArgument: - visitImpl(node, LabeledSpecializeArgumentSyntax.self, visit, visitPost) + visitImpl(&node, LabeledSpecializeArgumentSyntax.self, visit, visitPost) case .labeledStmt: - visitImpl(node, LabeledStmtSyntax.self, visit, visitPost) + visitImpl(&node, LabeledStmtSyntax.self, visit, visitPost) case .layoutRequirement: - visitImpl(node, LayoutRequirementSyntax.self, visit, visitPost) + visitImpl(&node, LayoutRequirementSyntax.self, visit, visitPost) case .lifetimeSpecifierArgumentList: - visitImpl(node, LifetimeSpecifierArgumentListSyntax.self, visit, visitPost) + visitImpl(&node, LifetimeSpecifierArgumentListSyntax.self, visit, visitPost) case .lifetimeSpecifierArgument: - visitImpl(node, LifetimeSpecifierArgumentSyntax.self, visit, visitPost) + visitImpl(&node, LifetimeSpecifierArgumentSyntax.self, visit, visitPost) case .lifetimeSpecifierArguments: - visitImpl(node, LifetimeSpecifierArgumentsSyntax.self, visit, visitPost) + visitImpl(&node, LifetimeSpecifierArgumentsSyntax.self, visit, visitPost) case .lifetimeTypeSpecifier: - visitImpl(node, LifetimeTypeSpecifierSyntax.self, visit, visitPost) + visitImpl(&node, LifetimeTypeSpecifierSyntax.self, visit, visitPost) case .macroDecl: - visitImpl(node, MacroDeclSyntax.self, visit, visitPost) + visitImpl(&node, MacroDeclSyntax.self, visit, visitPost) case .macroExpansionDecl: - visitImpl(node, MacroExpansionDeclSyntax.self, visit, visitPost) + visitImpl(&node, MacroExpansionDeclSyntax.self, visit, visitPost) case .macroExpansionExpr: - visitImpl(node, MacroExpansionExprSyntax.self, visit, visitPost) + visitImpl(&node, MacroExpansionExprSyntax.self, visit, visitPost) case .matchingPatternCondition: - visitImpl(node, MatchingPatternConditionSyntax.self, visit, visitPost) + visitImpl(&node, MatchingPatternConditionSyntax.self, visit, visitPost) case .memberAccessExpr: - visitImpl(node, MemberAccessExprSyntax.self, visit, visitPost) + visitImpl(&node, MemberAccessExprSyntax.self, visit, visitPost) case .memberBlockItemList: - visitImpl(node, MemberBlockItemListSyntax.self, visit, visitPost) + visitImpl(&node, MemberBlockItemListSyntax.self, visit, visitPost) case .memberBlockItem: - visitImpl(node, MemberBlockItemSyntax.self, visit, visitPost) + visitImpl(&node, MemberBlockItemSyntax.self, visit, visitPost) case .memberBlock: - visitImpl(node, MemberBlockSyntax.self, visit, visitPost) + visitImpl(&node, MemberBlockSyntax.self, visit, visitPost) case .memberType: - visitImpl(node, MemberTypeSyntax.self, visit, visitPost) + visitImpl(&node, MemberTypeSyntax.self, visit, visitPost) case .metatypeType: - visitImpl(node, MetatypeTypeSyntax.self, visit, visitPost) + visitImpl(&node, MetatypeTypeSyntax.self, visit, visitPost) case .missingDecl: - visitImpl(node, MissingDeclSyntax.self, visit, visitPost) + visitImpl(&node, MissingDeclSyntax.self, visit, visitPost) case .missingExpr: - visitImpl(node, MissingExprSyntax.self, visit, visitPost) + visitImpl(&node, MissingExprSyntax.self, visit, visitPost) case .missingPattern: - visitImpl(node, MissingPatternSyntax.self, visit, visitPost) + visitImpl(&node, MissingPatternSyntax.self, visit, visitPost) case .missingStmt: - visitImpl(node, MissingStmtSyntax.self, visit, visitPost) + visitImpl(&node, MissingStmtSyntax.self, visit, visitPost) case .missing: - visitImpl(node, MissingSyntax.self, visit, visitPost) + visitImpl(&node, MissingSyntax.self, visit, visitPost) case .missingType: - visitImpl(node, MissingTypeSyntax.self, visit, visitPost) + visitImpl(&node, MissingTypeSyntax.self, visit, visitPost) case .multipleTrailingClosureElementList: - visitImpl(node, MultipleTrailingClosureElementListSyntax.self, visit, visitPost) + visitImpl(&node, MultipleTrailingClosureElementListSyntax.self, visit, visitPost) case .multipleTrailingClosureElement: - visitImpl(node, MultipleTrailingClosureElementSyntax.self, visit, visitPost) + visitImpl(&node, MultipleTrailingClosureElementSyntax.self, visit, visitPost) case .namedOpaqueReturnType: - visitImpl(node, NamedOpaqueReturnTypeSyntax.self, visit, visitPost) + visitImpl(&node, NamedOpaqueReturnTypeSyntax.self, visit, visitPost) case .nilLiteralExpr: - visitImpl(node, NilLiteralExprSyntax.self, visit, visitPost) + visitImpl(&node, NilLiteralExprSyntax.self, visit, visitPost) case .objCSelectorPieceList: - visitImpl(node, ObjCSelectorPieceListSyntax.self, visit, visitPost) + visitImpl(&node, ObjCSelectorPieceListSyntax.self, visit, visitPost) case .objCSelectorPiece: - visitImpl(node, ObjCSelectorPieceSyntax.self, visit, visitPost) + visitImpl(&node, ObjCSelectorPieceSyntax.self, visit, visitPost) case .opaqueReturnTypeOfAttributeArguments: - visitImpl(node, OpaqueReturnTypeOfAttributeArgumentsSyntax.self, visit, visitPost) + visitImpl(&node, OpaqueReturnTypeOfAttributeArgumentsSyntax.self, visit, visitPost) case .operatorDecl: - visitImpl(node, OperatorDeclSyntax.self, visit, visitPost) + visitImpl(&node, OperatorDeclSyntax.self, visit, visitPost) case .operatorPrecedenceAndTypes: - visitImpl(node, OperatorPrecedenceAndTypesSyntax.self, visit, visitPost) + visitImpl(&node, OperatorPrecedenceAndTypesSyntax.self, visit, visitPost) case .optionalBindingCondition: - visitImpl(node, OptionalBindingConditionSyntax.self, visit, visitPost) + visitImpl(&node, OptionalBindingConditionSyntax.self, visit, visitPost) case .optionalChainingExpr: - visitImpl(node, OptionalChainingExprSyntax.self, visit, visitPost) + visitImpl(&node, OptionalChainingExprSyntax.self, visit, visitPost) case .optionalType: - visitImpl(node, OptionalTypeSyntax.self, visit, visitPost) + visitImpl(&node, OptionalTypeSyntax.self, visit, visitPost) case .originallyDefinedInAttributeArguments: - visitImpl(node, OriginallyDefinedInAttributeArgumentsSyntax.self, visit, visitPost) + visitImpl(&node, OriginallyDefinedInAttributeArgumentsSyntax.self, visit, visitPost) case .packElementExpr: - visitImpl(node, PackElementExprSyntax.self, visit, visitPost) + visitImpl(&node, PackElementExprSyntax.self, visit, visitPost) case .packElementType: - visitImpl(node, PackElementTypeSyntax.self, visit, visitPost) + visitImpl(&node, PackElementTypeSyntax.self, visit, visitPost) case .packExpansionExpr: - visitImpl(node, PackExpansionExprSyntax.self, visit, visitPost) + visitImpl(&node, PackExpansionExprSyntax.self, visit, visitPost) case .packExpansionType: - visitImpl(node, PackExpansionTypeSyntax.self, visit, visitPost) + visitImpl(&node, PackExpansionTypeSyntax.self, visit, visitPost) case .patternBindingList: - visitImpl(node, PatternBindingListSyntax.self, visit, visitPost) + visitImpl(&node, PatternBindingListSyntax.self, visit, visitPost) case .patternBinding: - visitImpl(node, PatternBindingSyntax.self, visit, visitPost) + visitImpl(&node, PatternBindingSyntax.self, visit, visitPost) case .patternExpr: - visitImpl(node, PatternExprSyntax.self, visit, visitPost) + visitImpl(&node, PatternExprSyntax.self, visit, visitPost) case .platformVersionItemList: - visitImpl(node, PlatformVersionItemListSyntax.self, visit, visitPost) + visitImpl(&node, PlatformVersionItemListSyntax.self, visit, visitPost) case .platformVersionItem: - visitImpl(node, PlatformVersionItemSyntax.self, visit, visitPost) + visitImpl(&node, PlatformVersionItemSyntax.self, visit, visitPost) case .platformVersion: - visitImpl(node, PlatformVersionSyntax.self, visit, visitPost) + visitImpl(&node, PlatformVersionSyntax.self, visit, visitPost) case .postfixIfConfigExpr: - visitImpl(node, PostfixIfConfigExprSyntax.self, visit, visitPost) + visitImpl(&node, PostfixIfConfigExprSyntax.self, visit, visitPost) case .postfixOperatorExpr: - visitImpl(node, PostfixOperatorExprSyntax.self, visit, visitPost) + visitImpl(&node, PostfixOperatorExprSyntax.self, visit, visitPost) case .poundSourceLocationArguments: - visitImpl(node, PoundSourceLocationArgumentsSyntax.self, visit, visitPost) + visitImpl(&node, PoundSourceLocationArgumentsSyntax.self, visit, visitPost) case .poundSourceLocation: - visitImpl(node, PoundSourceLocationSyntax.self, visit, visitPost) + visitImpl(&node, PoundSourceLocationSyntax.self, visit, visitPost) case .precedenceGroupAssignment: - visitImpl(node, PrecedenceGroupAssignmentSyntax.self, visit, visitPost) + visitImpl(&node, PrecedenceGroupAssignmentSyntax.self, visit, visitPost) case .precedenceGroupAssociativity: - visitImpl(node, PrecedenceGroupAssociativitySyntax.self, visit, visitPost) + visitImpl(&node, PrecedenceGroupAssociativitySyntax.self, visit, visitPost) case .precedenceGroupAttributeList: - visitImpl(node, PrecedenceGroupAttributeListSyntax.self, visit, visitPost) + visitImpl(&node, PrecedenceGroupAttributeListSyntax.self, visit, visitPost) case .precedenceGroupDecl: - visitImpl(node, PrecedenceGroupDeclSyntax.self, visit, visitPost) + visitImpl(&node, PrecedenceGroupDeclSyntax.self, visit, visitPost) case .precedenceGroupNameList: - visitImpl(node, PrecedenceGroupNameListSyntax.self, visit, visitPost) + visitImpl(&node, PrecedenceGroupNameListSyntax.self, visit, visitPost) case .precedenceGroupName: - visitImpl(node, PrecedenceGroupNameSyntax.self, visit, visitPost) + visitImpl(&node, PrecedenceGroupNameSyntax.self, visit, visitPost) case .precedenceGroupRelation: - visitImpl(node, PrecedenceGroupRelationSyntax.self, visit, visitPost) + visitImpl(&node, PrecedenceGroupRelationSyntax.self, visit, visitPost) case .prefixOperatorExpr: - visitImpl(node, PrefixOperatorExprSyntax.self, visit, visitPost) + visitImpl(&node, PrefixOperatorExprSyntax.self, visit, visitPost) case .primaryAssociatedTypeClause: - visitImpl(node, PrimaryAssociatedTypeClauseSyntax.self, visit, visitPost) + visitImpl(&node, PrimaryAssociatedTypeClauseSyntax.self, visit, visitPost) case .primaryAssociatedTypeList: - visitImpl(node, PrimaryAssociatedTypeListSyntax.self, visit, visitPost) + visitImpl(&node, PrimaryAssociatedTypeListSyntax.self, visit, visitPost) case .primaryAssociatedType: - visitImpl(node, PrimaryAssociatedTypeSyntax.self, visit, visitPost) + visitImpl(&node, PrimaryAssociatedTypeSyntax.self, visit, visitPost) case .protocolDecl: - visitImpl(node, ProtocolDeclSyntax.self, visit, visitPost) + visitImpl(&node, ProtocolDeclSyntax.self, visit, visitPost) case .regexLiteralExpr: - visitImpl(node, RegexLiteralExprSyntax.self, visit, visitPost) + visitImpl(&node, RegexLiteralExprSyntax.self, visit, visitPost) case .repeatStmt: - visitImpl(node, RepeatStmtSyntax.self, visit, visitPost) + visitImpl(&node, RepeatStmtSyntax.self, visit, visitPost) case .returnClause: - visitImpl(node, ReturnClauseSyntax.self, visit, visitPost) + visitImpl(&node, ReturnClauseSyntax.self, visit, visitPost) case .returnStmt: - visitImpl(node, ReturnStmtSyntax.self, visit, visitPost) + visitImpl(&node, ReturnStmtSyntax.self, visit, visitPost) case .sameTypeRequirement: - visitImpl(node, SameTypeRequirementSyntax.self, visit, visitPost) + visitImpl(&node, SameTypeRequirementSyntax.self, visit, visitPost) case .sequenceExpr: - visitImpl(node, SequenceExprSyntax.self, visit, visitPost) + visitImpl(&node, SequenceExprSyntax.self, visit, visitPost) case .simpleStringLiteralExpr: - visitImpl(node, SimpleStringLiteralExprSyntax.self, visit, visitPost) + visitImpl(&node, SimpleStringLiteralExprSyntax.self, visit, visitPost) case .simpleStringLiteralSegmentList: - visitImpl(node, SimpleStringLiteralSegmentListSyntax.self, visit, visitPost) + visitImpl(&node, SimpleStringLiteralSegmentListSyntax.self, visit, visitPost) case .simpleTypeSpecifier: - visitImpl(node, SimpleTypeSpecifierSyntax.self, visit, visitPost) + visitImpl(&node, SimpleTypeSpecifierSyntax.self, visit, visitPost) case .someOrAnyType: - visitImpl(node, SomeOrAnyTypeSyntax.self, visit, visitPost) + visitImpl(&node, SomeOrAnyTypeSyntax.self, visit, visitPost) case .sourceFile: - visitImpl(node, SourceFileSyntax.self, visit, visitPost) + visitImpl(&node, SourceFileSyntax.self, visit, visitPost) case .specializeAttributeArgumentList: - visitImpl(node, SpecializeAttributeArgumentListSyntax.self, visit, visitPost) + visitImpl(&node, SpecializeAttributeArgumentListSyntax.self, visit, visitPost) case .specializeAvailabilityArgument: - visitImpl(node, SpecializeAvailabilityArgumentSyntax.self, visit, visitPost) + visitImpl(&node, SpecializeAvailabilityArgumentSyntax.self, visit, visitPost) case .specializeTargetFunctionArgument: - visitImpl(node, SpecializeTargetFunctionArgumentSyntax.self, visit, visitPost) + visitImpl(&node, SpecializeTargetFunctionArgumentSyntax.self, visit, visitPost) case .stringLiteralExpr: - visitImpl(node, StringLiteralExprSyntax.self, visit, visitPost) + visitImpl(&node, StringLiteralExprSyntax.self, visit, visitPost) case .stringLiteralSegmentList: - visitImpl(node, StringLiteralSegmentListSyntax.self, visit, visitPost) + visitImpl(&node, StringLiteralSegmentListSyntax.self, visit, visitPost) case .stringSegment: - visitImpl(node, StringSegmentSyntax.self, visit, visitPost) + visitImpl(&node, StringSegmentSyntax.self, visit, visitPost) case .structDecl: - visitImpl(node, StructDeclSyntax.self, visit, visitPost) + visitImpl(&node, StructDeclSyntax.self, visit, visitPost) case .subscriptCallExpr: - visitImpl(node, SubscriptCallExprSyntax.self, visit, visitPost) + visitImpl(&node, SubscriptCallExprSyntax.self, visit, visitPost) case .subscriptDecl: - visitImpl(node, SubscriptDeclSyntax.self, visit, visitPost) + visitImpl(&node, SubscriptDeclSyntax.self, visit, visitPost) case .superExpr: - visitImpl(node, SuperExprSyntax.self, visit, visitPost) + visitImpl(&node, SuperExprSyntax.self, visit, visitPost) case .suppressedType: - visitImpl(node, SuppressedTypeSyntax.self, visit, visitPost) + visitImpl(&node, SuppressedTypeSyntax.self, visit, visitPost) case .switchCaseItemList: - visitImpl(node, SwitchCaseItemListSyntax.self, visit, visitPost) + visitImpl(&node, SwitchCaseItemListSyntax.self, visit, visitPost) case .switchCaseItem: - visitImpl(node, SwitchCaseItemSyntax.self, visit, visitPost) + visitImpl(&node, SwitchCaseItemSyntax.self, visit, visitPost) case .switchCaseLabel: - visitImpl(node, SwitchCaseLabelSyntax.self, visit, visitPost) + visitImpl(&node, SwitchCaseLabelSyntax.self, visit, visitPost) case .switchCaseList: - visitImpl(node, SwitchCaseListSyntax.self, visit, visitPost) + visitImpl(&node, SwitchCaseListSyntax.self, visit, visitPost) case .switchCase: - visitImpl(node, SwitchCaseSyntax.self, visit, visitPost) + visitImpl(&node, SwitchCaseSyntax.self, visit, visitPost) case .switchDefaultLabel: - visitImpl(node, SwitchDefaultLabelSyntax.self, visit, visitPost) + visitImpl(&node, SwitchDefaultLabelSyntax.self, visit, visitPost) case .switchExpr: - visitImpl(node, SwitchExprSyntax.self, visit, visitPost) + visitImpl(&node, SwitchExprSyntax.self, visit, visitPost) case .ternaryExpr: - visitImpl(node, TernaryExprSyntax.self, visit, visitPost) + visitImpl(&node, TernaryExprSyntax.self, visit, visitPost) case .thenStmt: - visitImpl(node, ThenStmtSyntax.self, visit, visitPost) + visitImpl(&node, ThenStmtSyntax.self, visit, visitPost) case .throwStmt: - visitImpl(node, ThrowStmtSyntax.self, visit, visitPost) + visitImpl(&node, ThrowStmtSyntax.self, visit, visitPost) case .throwsClause: - visitImpl(node, ThrowsClauseSyntax.self, visit, visitPost) + visitImpl(&node, ThrowsClauseSyntax.self, visit, visitPost) case .tryExpr: - visitImpl(node, TryExprSyntax.self, visit, visitPost) + visitImpl(&node, TryExprSyntax.self, visit, visitPost) case .tupleExpr: - visitImpl(node, TupleExprSyntax.self, visit, visitPost) + visitImpl(&node, TupleExprSyntax.self, visit, visitPost) case .tuplePatternElementList: - visitImpl(node, TuplePatternElementListSyntax.self, visit, visitPost) + visitImpl(&node, TuplePatternElementListSyntax.self, visit, visitPost) case .tuplePatternElement: - visitImpl(node, TuplePatternElementSyntax.self, visit, visitPost) + visitImpl(&node, TuplePatternElementSyntax.self, visit, visitPost) case .tuplePattern: - visitImpl(node, TuplePatternSyntax.self, visit, visitPost) + visitImpl(&node, TuplePatternSyntax.self, visit, visitPost) case .tupleTypeElementList: - visitImpl(node, TupleTypeElementListSyntax.self, visit, visitPost) + visitImpl(&node, TupleTypeElementListSyntax.self, visit, visitPost) case .tupleTypeElement: - visitImpl(node, TupleTypeElementSyntax.self, visit, visitPost) + visitImpl(&node, TupleTypeElementSyntax.self, visit, visitPost) case .tupleType: - visitImpl(node, TupleTypeSyntax.self, visit, visitPost) + visitImpl(&node, TupleTypeSyntax.self, visit, visitPost) case .typeAliasDecl: - visitImpl(node, TypeAliasDeclSyntax.self, visit, visitPost) + visitImpl(&node, TypeAliasDeclSyntax.self, visit, visitPost) case .typeAnnotation: - visitImpl(node, TypeAnnotationSyntax.self, visit, visitPost) + visitImpl(&node, TypeAnnotationSyntax.self, visit, visitPost) case .typeEffectSpecifiers: - visitImpl(node, TypeEffectSpecifiersSyntax.self, visit, visitPost) + visitImpl(&node, TypeEffectSpecifiersSyntax.self, visit, visitPost) case .typeExpr: - visitImpl(node, TypeExprSyntax.self, visit, visitPost) + visitImpl(&node, TypeExprSyntax.self, visit, visitPost) case .typeInitializerClause: - visitImpl(node, TypeInitializerClauseSyntax.self, visit, visitPost) + visitImpl(&node, TypeInitializerClauseSyntax.self, visit, visitPost) case .typeSpecifierList: - visitImpl(node, TypeSpecifierListSyntax.self, visit, visitPost) + visitImpl(&node, TypeSpecifierListSyntax.self, visit, visitPost) case .unavailableFromAsyncAttributeArguments: - visitImpl(node, UnavailableFromAsyncAttributeArgumentsSyntax.self, visit, visitPost) + visitImpl(&node, UnavailableFromAsyncAttributeArgumentsSyntax.self, visit, visitPost) case .underscorePrivateAttributeArguments: - visitImpl(node, UnderscorePrivateAttributeArgumentsSyntax.self, visit, visitPost) + visitImpl(&node, UnderscorePrivateAttributeArgumentsSyntax.self, visit, visitPost) case .unexpectedNodes: - visitImpl(node, UnexpectedNodesSyntax.self, visit, visitPost) + visitImpl(&node, UnexpectedNodesSyntax.self, visit, visitPost) case .unresolvedAsExpr: - visitImpl(node, UnresolvedAsExprSyntax.self, visit, visitPost) + visitImpl(&node, UnresolvedAsExprSyntax.self, visit, visitPost) case .unresolvedIsExpr: - visitImpl(node, UnresolvedIsExprSyntax.self, visit, visitPost) + visitImpl(&node, UnresolvedIsExprSyntax.self, visit, visitPost) case .unresolvedTernaryExpr: - visitImpl(node, UnresolvedTernaryExprSyntax.self, visit, visitPost) + visitImpl(&node, UnresolvedTernaryExprSyntax.self, visit, visitPost) case .valueBindingPattern: - visitImpl(node, ValueBindingPatternSyntax.self, visit, visitPost) + visitImpl(&node, ValueBindingPatternSyntax.self, visit, visitPost) case .variableDecl: - visitImpl(node, VariableDeclSyntax.self, visit, visitPost) + visitImpl(&node, VariableDeclSyntax.self, visit, visitPost) case .versionComponentList: - visitImpl(node, VersionComponentListSyntax.self, visit, visitPost) + visitImpl(&node, VersionComponentListSyntax.self, visit, visitPost) case .versionComponent: - visitImpl(node, VersionComponentSyntax.self, visit, visitPost) + visitImpl(&node, VersionComponentSyntax.self, visit, visitPost) case .versionTuple: - visitImpl(node, VersionTupleSyntax.self, visit, visitPost) + visitImpl(&node, VersionTupleSyntax.self, visit, visitPost) case .whereClause: - visitImpl(node, WhereClauseSyntax.self, visit, visitPost) + visitImpl(&node, WhereClauseSyntax.self, visit, visitPost) case .whileStmt: - visitImpl(node, WhileStmtSyntax.self, visit, visitPost) + visitImpl(&node, WhileStmtSyntax.self, visit, visitPost) case .wildcardPattern: - visitImpl(node, WildcardPatternSyntax.self, visit, visitPost) + visitImpl(&node, WildcardPatternSyntax.self, visit, visitPost) case .yieldStmt: - visitImpl(node, YieldStmtSyntax.self, visit, visitPost) + visitImpl(&node, YieldStmtSyntax.self, visit, visitPost) case .yieldedExpressionList: - visitImpl(node, YieldedExpressionListSyntax.self, visit, visitPost) + visitImpl(&node, YieldedExpressionListSyntax.self, visit, visitPost) case .yieldedExpression: - visitImpl(node, YieldedExpressionSyntax.self, visit, visitPost) + visitImpl(&node, YieldedExpressionSyntax.self, visit, visitPost) case .yieldedExpressionsClause: - visitImpl(node, YieldedExpressionsClauseSyntax.self, visit, visitPost) + visitImpl(&node, YieldedExpressionsClauseSyntax.self, visit, visitPost) } } #endif - private func visitChildren(_ node: some SyntaxProtocol) { - let syntaxNode = Syntax(node) + /// - Note: `node` is `inout` to avoid reference counting. See comment in `visitImpl`. + private func visitChildren(_ syntaxNode: inout Syntax) { for childRaw in NonNilRawSyntaxChildren(syntaxNode, viewMode: viewMode) { - visit(Syntax(childRaw, parent: syntaxNode)) + // syntaxNode gets retained here. That seems unnecessary but I don't know how to remove it. + var childNode: Syntax + if let recycledInfoIndex = recyclableNodeInfosUsageBitmap.indexOfRightmostOne { + var recycledInfo: Syntax.Info? = nil + // Use `swap` to extract the recyclable syntax node without incurring ref-counting. + swap(&recycledInfo, &recyclableNodeInfos[recycledInfoIndex]) + assert(recycledInfo != nil, "Slot indicated by the bitmap did not contain a value") + recyclableNodeInfosUsageBitmap.setBitToZero(at: recycledInfoIndex) + // syntaxNode.info gets retained here. This is necessary because we build up the parent tree. + recycledInfo!.info = .nonRoot(.init(parent: syntaxNode, absoluteInfo: childRaw.info)) + childNode = Syntax(childRaw.raw, info: recycledInfo!) + } else { + childNode = Syntax(childRaw, parent: syntaxNode) + } + visit(&childNode) + if isKnownUniquelyReferenced(&childNode.info) { + // The node didn't get stored by the subclass's visit method. We can re-use the memory of its `Syntax.Info` + // for future syntax nodes. + childNode.info.info = nil + if let emptySlot = recyclableNodeInfosUsageBitmap.indexOfRightmostZero { + // Use `swap` to store the recyclable syntax node without incurring ref-counting. + swap(&recyclableNodeInfos[emptySlot], &childNode.info) + assert(childNode.info == nil, "Slot should not have contained a value") + recyclableNodeInfosUsageBitmap.setBitToOne(at: emptySlot) + } + } } } } + +fileprivate extension UInt64 { + var indexOfRightmostZero: Int? { + return (~self).indexOfRightmostOne + } + + + var indexOfRightmostOne: Int? { + let trailingZeroCount = self.trailingZeroBitCount + if trailingZeroCount == Self.bitWidth { + // All indicies are 0 + return nil + } + return trailingZeroCount + } + + + mutating func setBitToZero(at index: Int) { + self &= ~(1 << index) + } + + + mutating func setBitToOne(at index: Int) { + self |= 1 << index + } +}