Skip to content

Commit d069a9f

Browse files
committed
Make SyntaxCollection conform to RangeReplaceableCollection and remove add* methods on syntax nodes that have a collection as child
Conforming `SyntaxCollection` to `RangeReplaceableCollection` gives it a lot of the functions you know from `Swift.Array`. And with those methods, we no longer need the `add*` methods on syntax nodes that have a syntax collection as their child.
1 parent 8105452 commit d069a9f

File tree

10 files changed

+129
-9
lines changed

10 files changed

+129
-9
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,7 @@ func syntaxNode(emitKind: SyntaxNodeKind) -> SourceFileSyntax {
203203
/// `\(child.varOrCaseName)` collection.
204204
/// - returns: A copy of the receiver with the provided `\(raw: childElt)`
205205
/// appended to its `\(child.varOrCaseName)` collection.
206+
@available(*, deprecated, message: "Use node.\(child.varOrCaseName).append(newElement) instead")
206207
public func add\(raw: childElt)(_ element: \(raw: childEltType)) -> \(node.kind.syntaxType) {
207208
var collection: RawSyntax
208209
let arena = SyntaxArena()

Sources/SwiftSyntax/SyntaxCollection.swift

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13-
public protocol SyntaxCollection: SyntaxProtocol, BidirectionalCollection, MutableCollection where Element: SyntaxProtocol {
13+
public protocol SyntaxCollection: SyntaxProtocol, BidirectionalCollection, MutableCollection, RangeReplaceableCollection where Element: SyntaxProtocol {
1414
associatedtype Iterator = SyntaxCollectionIterator<Element>
1515

1616
/// The ``SyntaxKind`` of the syntax node that conforms to ``SyntaxCollection``.
@@ -33,6 +33,11 @@ extension SyntaxCollection {
3333
self.init(Syntax(data))!
3434
}
3535

36+
/// Create an empty ``SyntaCollection`` with no children.
37+
public init() {
38+
self.init([])
39+
}
40+
3641
public init<Children: Sequence>(_ children: Children) where Children.Element == Element {
3742
let arena = SyntaxArena()
3843
// Extend the lifetime of children so their arenas don't get destroyed
@@ -89,6 +94,19 @@ extension SyntaxCollection {
8994
return node.indexInParent
9095
}
9196

97+
/// Replace the nodes in `subrange` by `newElements`.
98+
public mutating func replaceSubrange(_ subrange: Range<SyntaxChildrenIndex>, with newElements: some Collection<Element>) {
99+
// We only access the raw nodes of `newElements` below.
100+
// Keep `newElements` alive so their arena doesn't get deallocated.
101+
withExtendedLifetime(newElements) {
102+
var newLayout = layoutView.formLayoutArray()
103+
let layoutRangeLowerBound = (subrange.lowerBound.data?.indexInParent).map(Int.init) ?? newLayout.endIndex
104+
let layoutRangeUpperBound = (subrange.upperBound.data?.indexInParent).map(Int.init) ?? newLayout.endIndex
105+
newLayout.replaceSubrange(layoutRangeLowerBound..<layoutRangeUpperBound, with: newElements.map { $0.raw })
106+
self = replacingLayout(newLayout)
107+
}
108+
}
109+
92110
/// Creates a new collection by appending the provided syntax element
93111
/// to the children.
94112
///

Sources/SwiftSyntax/generated/syntaxNodes/SyntaxDeclNodes.swift

Lines changed: 48 additions & 0 deletions
Large diffs are not rendered by default.

Sources/SwiftSyntax/generated/syntaxNodes/SyntaxExprNodes.swift

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ public struct ArrayExprSyntax: ExprSyntaxProtocol, SyntaxHashable {
127127
/// `elements` collection.
128128
/// - returns: A copy of the receiver with the provided `Element`
129129
/// appended to its `elements` collection.
130+
@available(*, deprecated, message: "Use node.elements.append(newElement) instead")
130131
public func addElement(_ element: ArrayElementSyntax) -> ArrayExprSyntax {
131132
var collection: RawSyntax
132133
let arena = SyntaxArena()
@@ -1507,6 +1508,7 @@ public struct ClosureExprSyntax: ExprSyntaxProtocol, SyntaxHashable {
15071508
/// `statements` collection.
15081509
/// - returns: A copy of the receiver with the provided `Statement`
15091510
/// appended to its `statements` collection.
1511+
@available(*, deprecated, message: "Use node.statements.append(newElement) instead")
15101512
public func addStatement(_ element: CodeBlockItemSyntax) -> ClosureExprSyntax {
15111513
var collection: RawSyntax
15121514
let arena = SyntaxArena()
@@ -2527,6 +2529,7 @@ public struct FunctionCallExprSyntax: ExprSyntaxProtocol, SyntaxHashable {
25272529
/// `arguments` collection.
25282530
/// - returns: A copy of the receiver with the provided `Argument`
25292531
/// appended to its `arguments` collection.
2532+
@available(*, deprecated, message: "Use node.arguments.append(newElement) instead")
25302533
public func addArgument(_ element: LabeledExprSyntax) -> FunctionCallExprSyntax {
25312534
var collection: RawSyntax
25322535
let arena = SyntaxArena()
@@ -2605,6 +2608,7 @@ public struct FunctionCallExprSyntax: ExprSyntaxProtocol, SyntaxHashable {
26052608
/// `additionalTrailingClosures` collection.
26062609
/// - returns: A copy of the receiver with the provided `AdditionalTrailingClosure`
26072610
/// appended to its `additionalTrailingClosures` collection.
2611+
@available(*, deprecated, message: "Use node.additionalTrailingClosures.append(newElement) instead")
26082612
public func addAdditionalTrailingClosure(_ element: MultipleTrailingClosureElementSyntax) -> FunctionCallExprSyntax {
26092613
var collection: RawSyntax
26102614
let arena = SyntaxArena()
@@ -3070,6 +3074,7 @@ public struct IfExprSyntax: ExprSyntaxProtocol, SyntaxHashable {
30703074
/// `conditions` collection.
30713075
/// - returns: A copy of the receiver with the provided `Condition`
30723076
/// appended to its `conditions` collection.
3077+
@available(*, deprecated, message: "Use node.conditions.append(newElement) instead")
30733078
public func addCondition(_ element: ConditionElementSyntax) -> IfExprSyntax {
30743079
var collection: RawSyntax
30753080
let arena = SyntaxArena()
@@ -3818,6 +3823,7 @@ public struct KeyPathExprSyntax: ExprSyntaxProtocol, SyntaxHashable {
38183823
/// `components` collection.
38193824
/// - returns: A copy of the receiver with the provided `KeyPathComponent`
38203825
/// appended to its `components` collection.
3826+
@available(*, deprecated, message: "Use node.components.append(newElement) instead")
38213827
public func addKeyPathComponent(_ element: KeyPathComponentSyntax) -> KeyPathExprSyntax {
38223828
var collection: RawSyntax
38233829
let arena = SyntaxArena()
@@ -4064,6 +4070,7 @@ public struct MacroExpansionExprSyntax: ExprSyntaxProtocol, SyntaxHashable {
40644070
/// `arguments` collection.
40654071
/// - returns: A copy of the receiver with the provided `Argument`
40664072
/// appended to its `arguments` collection.
4073+
@available(*, deprecated, message: "Use node.arguments.append(newElement) instead")
40674074
public func addArgument(_ element: LabeledExprSyntax) -> MacroExpansionExprSyntax {
40684075
var collection: RawSyntax
40694076
let arena = SyntaxArena()
@@ -4142,6 +4149,7 @@ public struct MacroExpansionExprSyntax: ExprSyntaxProtocol, SyntaxHashable {
41424149
/// `additionalTrailingClosures` collection.
41434150
/// - returns: A copy of the receiver with the provided `AdditionalTrailingClosure`
41444151
/// appended to its `additionalTrailingClosures` collection.
4152+
@available(*, deprecated, message: "Use node.additionalTrailingClosures.append(newElement) instead")
41454153
public func addAdditionalTrailingClosure(_ element: MultipleTrailingClosureElementSyntax) -> MacroExpansionExprSyntax {
41464154
var collection: RawSyntax
41474155
let arena = SyntaxArena()
@@ -5633,6 +5641,7 @@ public struct SequenceExprSyntax: ExprSyntaxProtocol, SyntaxHashable {
56335641
/// `elements` collection.
56345642
/// - returns: A copy of the receiver with the provided `Element`
56355643
/// appended to its `elements` collection.
5644+
@available(*, deprecated, message: "Use node.elements.append(newElement) instead")
56365645
public func addElement(_ element: ExprSyntax) -> SequenceExprSyntax {
56375646
var collection: RawSyntax
56385647
let arena = SyntaxArena()
@@ -5825,6 +5834,7 @@ public struct StringLiteralExprSyntax: ExprSyntaxProtocol, SyntaxHashable {
58255834
/// `segments` collection.
58265835
/// - returns: A copy of the receiver with the provided `Segment`
58275836
/// appended to its `segments` collection.
5837+
@available(*, deprecated, message: "Use node.segments.append(newElement) instead")
58285838
public func addSegment(_ element: Syntax) -> StringLiteralExprSyntax {
58295839
var collection: RawSyntax
58305840
let arena = SyntaxArena()
@@ -6059,6 +6069,7 @@ public struct SubscriptCallExprSyntax: ExprSyntaxProtocol, SyntaxHashable {
60596069
/// `arguments` collection.
60606070
/// - returns: A copy of the receiver with the provided `Argument`
60616071
/// appended to its `arguments` collection.
6072+
@available(*, deprecated, message: "Use node.arguments.append(newElement) instead")
60626073
public func addArgument(_ element: LabeledExprSyntax) -> SubscriptCallExprSyntax {
60636074
var collection: RawSyntax
60646075
let arena = SyntaxArena()
@@ -6137,6 +6148,7 @@ public struct SubscriptCallExprSyntax: ExprSyntaxProtocol, SyntaxHashable {
61376148
/// `additionalTrailingClosures` collection.
61386149
/// - returns: A copy of the receiver with the provided `AdditionalTrailingClosure`
61396150
/// appended to its `additionalTrailingClosures` collection.
6151+
@available(*, deprecated, message: "Use node.additionalTrailingClosures.append(newElement) instead")
61406152
public func addAdditionalTrailingClosure(_ element: MultipleTrailingClosureElementSyntax) -> SubscriptCallExprSyntax {
61416153
var collection: RawSyntax
61426154
let arena = SyntaxArena()
@@ -6431,6 +6443,7 @@ public struct SwitchExprSyntax: ExprSyntaxProtocol, SyntaxHashable {
64316443
/// `cases` collection.
64326444
/// - returns: A copy of the receiver with the provided `Case`
64336445
/// appended to its `cases` collection.
6446+
@available(*, deprecated, message: "Use node.cases.append(newElement) instead")
64346447
public func addCase(_ element: Syntax) -> SwitchExprSyntax {
64356448
var collection: RawSyntax
64366449
let arena = SyntaxArena()
@@ -6960,6 +6973,7 @@ public struct TupleExprSyntax: ExprSyntaxProtocol, SyntaxHashable {
69606973
/// `elements` collection.
69616974
/// - returns: A copy of the receiver with the provided `Element`
69626975
/// appended to its `elements` collection.
6976+
@available(*, deprecated, message: "Use node.elements.append(newElement) instead")
69636977
public func addElement(_ element: LabeledExprSyntax) -> TupleExprSyntax {
69646978
var collection: RawSyntax
69656979
let arena = SyntaxArena()

0 commit comments

Comments
 (0)