Skip to content

Commit c41f24c

Browse files
committed
Check that we are actually tracking the tree passed in as originalTree to originalNode
1 parent 0380245 commit c41f24c

File tree

2 files changed

+35
-0
lines changed

2 files changed

+35
-0
lines changed

Sources/SwiftSyntax/SyntaxTracking.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,9 @@ extension SyntaxProtocol {
289289
/// - SeeAlso: ``SyntaxProtocol/tracked``
290290
/// - Complexity: O(tracked ranges in this tree) + O(width * depth of original tree)
291291
public func originalNode(in originalTree: some SyntaxProtocol) -> Self? {
292+
guard self.data.syntaxTracking?.trackedTree == originalTree.id.rootId else {
293+
return nil
294+
}
292295
guard let originalIndexInTree = self.data.syntaxTracking?.originalIndexInTree(of: self.id.indexInTree) else {
293296
return nil
294297
}

Tests/SwiftSyntaxTest/SyntaxTrackingTests.swift

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,4 +105,36 @@ public class SyntaxTrackingTests: XCTestCase {
105105

106106
XCTAssertEqual(codeBlockItemList.last?.item.originalNode(in: originalFunction)?.id, originalFunction.id)
107107
}
108+
109+
func testTwoLayerModification() throws {
110+
let originalFunction = try FunctionDeclSyntax("func foo() {}").tracked
111+
let modifiedFunction = originalFunction.with(\.name, "bar")
112+
let secondModification = modifiedFunction.with(\.body, nil)
113+
114+
XCTAssertEqual(secondModification.funcKeyword.originalNode(in: originalFunction)?.id, originalFunction.funcKeyword.id)
115+
XCTAssertNil(secondModification.name.originalNode(in: originalFunction))
116+
XCTAssertNil(secondModification.name.originalNode(in: modifiedFunction))
117+
}
118+
119+
func testEditAndThenCreation() throws {
120+
let originalFunction = try FunctionDeclSyntax("func foo() {}").tracked
121+
let modifiedFunction = originalFunction.with(\.name, "bar")
122+
123+
let codeBlockItem = CodeBlockItemSyntax(item: .decl(DeclSyntax(modifiedFunction)))
124+
125+
XCTAssertEqual(codeBlockItem.item.as(FunctionDeclSyntax.self)?.funcKeyword.originalNode(in: originalFunction)?.id, originalFunction.funcKeyword.id)
126+
XCTAssertNil(codeBlockItem.item.as(FunctionDeclSyntax.self)?.name.originalNode(in: originalFunction)?.id)
127+
XCTAssertNil(codeBlockItem.item.as(FunctionDeclSyntax.self)?.name.originalNode(in: modifiedFunction)?.id)
128+
}
129+
130+
func testStartTrackingModifiedNode() throws {
131+
let originalFunction = try FunctionDeclSyntax("func foo() {}").tracked
132+
let modifiedFunction = originalFunction.with(\.name, "bar").tracked
133+
let secondModification = modifiedFunction.with(\.body, nil)
134+
135+
XCTAssertNil(secondModification.funcKeyword.originalNode(in: originalFunction))
136+
XCTAssertEqual(secondModification.funcKeyword.originalNode(in: modifiedFunction)?.id, modifiedFunction.funcKeyword.id)
137+
XCTAssertNil(secondModification.name.originalNode(in: originalFunction))
138+
XCTAssertEqual(secondModification.name.originalNode(in: modifiedFunction)?.id, modifiedFunction.name.id)
139+
}
108140
}

0 commit comments

Comments
 (0)