Skip to content

Commit

Permalink
Improve documentation of SyntaxProtocol.tracked and write entry in …
Browse files Browse the repository at this point in the history
…release notes
  • Loading branch information
ahoppen committed Sep 1, 2023
1 parent a26a5bb commit 489827b
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 5 deletions.
5 changes: 5 additions & 0 deletions Release Notes/510.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@
- `SyntaxCollection.index(at:)`
- Description: Returns the index of the n-th element in a `SyntaxCollection`. This computation is in O(n) and `SyntaxCollection` is not subscriptable by an integer.
- Pull Request: https://github.com/apple/swift-syntax/pull/2014
- `SyntaxProtocol.tracked` / `SyntaxProtocol.originalNode(in:)`
- Description: `tracked` enables node tracking of a tree. For every tree derived from a tracked tree, `originalNode(in:)` returns the original node in the tracked tree. This allows clients to e.g. get the original location of a node in a source file after a tree has been modified.
- Issue: rdar://112679655
- Pull Request: https://github.com/apple/swift-syntax/pull/2118


## API Behavior Changes

Expand Down
31 changes: 26 additions & 5 deletions Sources/SwiftSyntax/SyntaxTracking.swift
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ extension SyntaxData {
fileprivate var tracked: SyntaxData {
if let parent {
let parentTracked = parent.tracked
return parentTracked.child(at: self.indexInParent, parent: Syntax(parentTracked))!
return parentTracked.child(at: self.indexInParent)!
} else {
let result = SyntaxData.forRoot(self.raw, rawNodeArena: self.raw.arena)
let syntaxTracking = SyntaxTracking(
Expand Down Expand Up @@ -267,18 +267,39 @@ class IndexInTreeFinder: SyntaxAnyVisitor {
}

extension SyntaxProtocol {
/// The same `SyntaxData` but with tracking enabled in the entire tree.
/// Start tracking this syntax tree as the original tree for all trees derived
/// from it.
///
/// All syntax nodes derived from this will be able to find their
/// corresponding location in this original tree.
/// All syntax nodes derived from the returned, tracked, tree will be able to
/// find the corresponding node in the original tree by calling
/// ``SyntaxProtocol/originalNode(in:)``.
///
/// Derived nodes are
/// - Nodes that contain a node from this tree as a subtree.
/// - Nodes that resulted from modification of a node in this tree (e.g.
/// modification of a child node or insertion of an element into a
/// collection).
/// - Detached subtrees of this tree (see ``SyntaxProtocol/detached``).
///
/// Node tracking is not enabled by default because maintaining the mapping
/// back to the tracked tree has a performance cost that.
///
/// A tree can only track a single original tree. I.e. it is not possible to
/// create a node that has one child in tracked tree A and another child in
/// tracked tree B. In practice, this should seldom pose an issue because the
/// most common use case is to mark the tree obtained from a file on disk as
/// the tracked tree and trees from separate source files will rarely be
/// merged.
///
/// - SeeAlso: ``SyntaxProtocol/originalNode(in:)``
/// - Complexity: O(number of ancestors)
public var tracked: Self {
return Syntax(self.data.tracked).cast(Self.self)
}

/// If this syntax node is tracking `originalTree` and this node originated
/// in that tree, return the corresponding corresponding node in `originalTree`.
/// from that tree, return the corresponding corresponding node in
/// `originalTree`.
///
/// The original node will have the same structure as this node but the parent
/// might be different since it's anchored in `originalTree`.
Expand Down

0 comments on commit 489827b

Please sign in to comment.