Skip to content

Deprecate SyntaxCollection.replacing(childAt:with:) in favor of a writable subscript #1880

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Sources/SwiftSyntax/SyntaxChildren.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

/// The data for an index in a syntax children collection that is not the end
/// index. See ``SyntaxChildrenIndex`` for the representation of the end index.
struct SyntaxChildrenIndexData: Comparable {
struct SyntaxChildrenIndexData: Hashable, Comparable {
/// The UTF-8 offset of the item at this index in the source file
/// See `AbsoluteSyntaxPosition.offset`
let offset: UInt32
Expand Down Expand Up @@ -50,7 +50,7 @@ struct SyntaxChildrenIndexData: Comparable {
}

/// An index in a syntax children collection.
public struct SyntaxChildrenIndex: Comparable, ExpressibleByNilLiteral {
public struct SyntaxChildrenIndex: Hashable, Comparable, ExpressibleByNilLiteral {
/// Construct the `endIndex` of a ``SyntaxChildren`` collection.
public init(nilLiteral: ()) {
self.data = nil
Expand Down
26 changes: 21 additions & 5 deletions Sources/SwiftSyntax/SyntaxCollection.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
//
//===----------------------------------------------------------------------===//

public protocol SyntaxCollection: SyntaxProtocol, BidirectionalCollection where Element: SyntaxProtocol {
public protocol SyntaxCollection: SyntaxProtocol, BidirectionalCollection, MutableCollection where Element: SyntaxProtocol {
associatedtype Iterator = SyntaxCollectionIterator<Element>

/// The ``SyntaxKind`` of the syntax node that conforms to ``SyntaxCollection``.
Expand Down Expand Up @@ -113,6 +113,7 @@ extension SyntaxCollection {
/// - syntax: The element to replace with.
///
/// - Returns: A new collection with the new element at the provided index.
@available(*, deprecated, message: "Use .with(\\.[index], newValue) instead")
public func replacing(childAt index: Int, with syntax: Element) -> Self {
var newLayout = layoutView.formLayoutArray()
/// Make sure the index is a valid index for replacing
Expand Down Expand Up @@ -211,9 +212,24 @@ extension SyntaxCollection {
}

public subscript(position: SyntaxChildrenIndex) -> Element {
let (raw, info) = rawChildren[position]
let absoluteRaw = AbsoluteRawSyntax(raw: raw!, info: info)
let data = SyntaxData(absoluteRaw, parent: Syntax(self))
return Syntax(data).cast(Element.self)
get {
let (raw, info) = rawChildren[position]
let absoluteRaw = AbsoluteRawSyntax(raw: raw!, info: info)
let data = SyntaxData(absoluteRaw, parent: Syntax(self))
return Syntax(data).cast(Element.self)
}
set {
guard let indexToReplace = (position.data?.indexInParent).map(Int.init) else {
preconditionFailure("Cannot replace element at the end index")
}
var newLayout = layoutView.formLayoutArray()
/// Make sure the index is a valid index for replacing
precondition(
(newLayout.startIndex..<newLayout.endIndex).contains(indexToReplace),
"replacing node at invalid index \(index)"
)
newLayout[indexToReplace] = newValue.raw
self = replacingLayout(newLayout)
}
}
}
6 changes: 3 additions & 3 deletions Sources/SwiftSyntaxMacroExpansion/MacroSystem.swift
Original file line number Diff line number Diff line change
Expand Up @@ -340,9 +340,9 @@ class MacroApplication<Context: MacroExpansionContext>: SyntaxRewriter {
return DeclSyntax(
visitedVarDecl.with(
\.bindings,
visitedVarDecl.bindings.replacing(
childAt: 0,
with: binding.with(
visitedVarDecl.bindings.with(
\.[visitedVarDecl.bindings.startIndex],
binding.with(
\.accessor,
.accessors(
.init(
Expand Down
6 changes: 3 additions & 3 deletions Tests/SwiftSyntaxMacroExpansionTest/MacroSystemTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,9 @@ private func replaceFirstLabel(
return tuple
}

return tuple.replacing(
childAt: 0,
with: firstElement.with(\.label, .identifier(newLabel))
return tuple.with(
\.[tuple.startIndex],
firstElement.with(\.label, .identifier(newLabel))
)
}

Expand Down
8 changes: 5 additions & 3 deletions Tests/SwiftSyntaxTest/SyntaxCollectionsTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,11 @@ public class SyntaxCollectionsTests: XCTestCase {
integerLiteralElement(2),
])

let newArrayElementList = arrayElementList.replacing(
childAt: 2,
with: integerLiteralElement(3)
let lastElementIndex = arrayElementList.index(arrayElementList.startIndex, offsetBy: 2)

let newArrayElementList = arrayElementList.with(
\.[lastElementIndex],
integerLiteralElement(3)
)

XCTAssertNotNil(newArrayElementList.child(at: 2))
Expand Down