Skip to content

Commit 1710f69

Browse files
committed
Allow rewrite to detach from the node's parent
`MissingMaker` and `MissingNodesBasicFormatter` do not require the returned node to have a parent. Avoid re-creating all the parent nodes in this case by detaching the rewritten node (or rather, not re-attaching it). Resolves rdar://111332992 (#1847).
1 parent fa0e5c9 commit 1710f69

File tree

3 files changed

+16
-10
lines changed

3 files changed

+16
-10
lines changed

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

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,13 @@ let syntaxRewriterFile = SourceFileSyntax(leadingTrivia: copyrightHeader) {
4242

4343
DeclSyntax(
4444
"""
45-
/// Rewrite `node` and anchor, making sure that the rewritten node also has
46-
/// a parent if `node` had one.
47-
public func rewrite(_ node: some SyntaxProtocol) -> Syntax {
45+
/// Rewrite `node`, keeping its parent unless `detach` is `true`.
46+
public func rewrite(_ node: some SyntaxProtocol, detach: Bool = false) -> Syntax {
4847
let rewritten = self.visit(node.data)
48+
if detach {
49+
return rewritten
50+
}
51+
4952
return withExtendedLifetime(rewritten) {
5053
return Syntax(node.data.replacingSelf(rewritten.raw, rawNodeArena: rewritten.raw.arena, allocationArena: SyntaxArena()))
5154
}
@@ -100,7 +103,7 @@ let syntaxRewriterFile = SourceFileSyntax(leadingTrivia: copyrightHeader) {
100103
/// Visit any Syntax node.
101104
/// - Parameter node: the node that is being visited
102105
/// - Returns: the rewritten node
103-
@available(*, deprecated, renamed: "rewrite(_:)")
106+
@available(*, deprecated, renamed: "rewrite(_:detach:)")
104107
public func visit(_ node: Syntax) -> Syntax {
105108
return visit(node.data)
106109
}

Sources/SwiftParserDiagnostics/DiagnosticExtensions.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ extension FixIt.MultiNodeChange {
7878
guard let node = node else {
7979
return FixIt.MultiNodeChange(primitiveChanges: [])
8080
}
81-
var changes = [FixIt.Change.replace(oldNode: Syntax(node), newNode: MissingMaker().rewrite(node))]
81+
var changes = [FixIt.Change.replace(oldNode: Syntax(node), newNode: MissingMaker().rewrite(node, detach: true))]
8282
if transferTrivia {
8383
changes += FixIt.MultiNodeChange.transferTriviaAtSides(from: [node]).primitiveChanges
8484
}
@@ -123,7 +123,7 @@ extension FixIt.MultiNodeChange {
123123
leadingTrivia: Trivia? = nil,
124124
trailingTrivia: Trivia? = nil
125125
) -> Self {
126-
var presentNode = MissingNodesBasicFormatter(viewMode: .fixedUp).rewrite(node)
126+
var presentNode = MissingNodesBasicFormatter(viewMode: .fixedUp).rewrite(node, detach: true)
127127
presentNode = PresentMaker().rewrite(presentNode)
128128

129129
if let leadingTrivia {

Sources/SwiftSyntax/generated/SyntaxRewriter.swift

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,13 @@ open class SyntaxRewriter {
2828
self.viewMode = viewMode
2929
}
3030

31-
/// Rewrite `node` and anchor, making sure that the rewritten node also has
32-
/// a parent if `node` had one.
33-
public func rewrite(_ node: some SyntaxProtocol) -> Syntax {
31+
/// Rewrite `node`, keeping its parent unless `detach` is `true`.
32+
public func rewrite(_ node: some SyntaxProtocol, detach: Bool = false) -> Syntax {
3433
let rewritten = self.visit(node.data)
34+
if detach {
35+
return rewritten
36+
}
37+
3538
return withExtendedLifetime(rewritten) {
3639
return Syntax(node.data.replacingSelf(rewritten.raw, rawNodeArena: rewritten.raw.arena, allocationArena: SyntaxArena()))
3740
}
@@ -68,7 +71,7 @@ open class SyntaxRewriter {
6871
/// Visit any Syntax node.
6972
/// - Parameter node: the node that is being visited
7073
/// - Returns: the rewritten node
71-
@available(*, deprecated, renamed: "rewrite(_:)")
74+
@available(*, deprecated, renamed: "rewrite(_:detach:)")
7275
public func visit(_ node: Syntax) -> Syntax {
7376
return visit(node.data)
7477
}

0 commit comments

Comments
 (0)