Skip to content

Commit 73a28b1

Browse files
authored
Merge pull request #1787 from ahoppen/ahoppen/collection-conformance
Replace most generated code in SyntaxCollections.swift by default protocol implementations
2 parents 80cf536 + f8d304c commit 73a28b1

File tree

7 files changed

+814
-10200
lines changed

7 files changed

+814
-10200
lines changed

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

Lines changed: 2 additions & 304 deletions
Original file line numberDiff line numberDiff line change
@@ -16,41 +16,10 @@ import SyntaxSupport
1616
import Utils
1717

1818
let syntaxCollectionsFile = SourceFileSyntax(leadingTrivia: copyrightHeader) {
19-
DeclSyntax(
20-
"""
21-
public protocol SyntaxCollection: SyntaxProtocol, Sequence where Element: SyntaxProtocol {
22-
/// Creates a new collection with the elements.
23-
init(_ children: [Element])
24-
/// The number of elements, `present` or `missing`, in this collection.
25-
var count: Int { get }
26-
}
27-
"""
28-
)
29-
30-
DeclSyntax(
31-
"""
32-
public extension SyntaxCollection {
33-
static var structure: SyntaxNodeStructure {
34-
return .collection(Element.self)
35-
}
36-
}
37-
"""
38-
)
39-
4019
for node in SYNTAX_NODES.compactMap(\.collectionNode) {
41-
let documentation =
42-
!node.documentation.isEmpty
43-
? node.documentation
44-
: """
45-
/// ``\(node.kind.syntaxType)`` represents a collection of one or more
46-
/// ``\(node.collectionElementType.syntaxBaseName)`` nodes. ``\(node.kind.syntaxType)`` behaves
47-
/// as a regular Swift collection, and has accessors that return new
48-
/// versions of the collection with different children.
49-
"""
50-
5120
try! StructDeclSyntax(
5221
"""
53-
\(raw: documentation)
22+
\(raw: node.documentation)
5423
public struct \(raw: node.kind.syntaxType): SyntaxCollection, SyntaxHashable
5524
"""
5625
) {
@@ -136,14 +105,6 @@ let syntaxCollectionsFile = SourceFileSyntax(leadingTrivia: copyrightHeader) {
136105

137106
DeclSyntax("public let _syntaxNode: Syntax")
138107

139-
DeclSyntax(
140-
"""
141-
private var layoutView: RawSyntaxLayoutView {
142-
data.raw.layoutView!
143-
}
144-
"""
145-
)
146-
147108
DeclSyntax(
148109
"""
149110
public init?(_ node: some SyntaxProtocol) {
@@ -153,270 +114,7 @@ let syntaxCollectionsFile = SourceFileSyntax(leadingTrivia: copyrightHeader) {
153114
"""
154115
)
155116

156-
DeclSyntax(
157-
"""
158-
/// Creates a Syntax node from the provided root and data. This assumes
159-
/// that the `SyntaxData` is of the correct kind. If it is not, the behaviour
160-
/// is undefined.
161-
internal init(_ data: SyntaxData) {
162-
precondition(data.raw.kind == .\(node.varOrCaseName))
163-
self._syntaxNode = Syntax(data)
164-
}
165-
"""
166-
)
167-
168-
DeclSyntax(
169-
"""
170-
public init(_ children: [Element]) {
171-
let data: SyntaxData = withExtendedLifetime(SyntaxArena()) { arena in
172-
let raw = RawSyntax.makeLayout(kind: SyntaxKind.\(node.varOrCaseName),
173-
from: children.map { $0.raw }, arena: arena)
174-
return SyntaxData.forRoot(raw)
175-
}
176-
self.init(data)
177-
}
178-
"""
179-
)
180-
181-
DeclSyntax(
182-
"""
183-
/// The number of elements, `present` or `missing`, in this collection.
184-
public var count: Int { return layoutView.children.count }
185-
"""
186-
)
187-
188-
DeclSyntax(
189-
"""
190-
/// Creates a new ``\(node.kind.syntaxType)`` by replacing the underlying layout with
191-
/// a different set of raw syntax nodes.
192-
///
193-
/// - Parameter layout: The new list of raw syntax nodes underlying this
194-
/// collection.
195-
/// - Returns: A new ``\(node.kind.syntaxType)`` with the new layout underlying it.
196-
internal func replacingLayout(_ layout: [RawSyntax?]) -> \(node.kind.syntaxType) {
197-
let arena = SyntaxArena()
198-
let newRaw = layoutView.replacingLayout(with: layout, arena: arena)
199-
let newData = data.replacingSelf(newRaw, arena: arena)
200-
return \(node.kind.syntaxType)(newData)
201-
}
202-
"""
203-
)
204-
205-
DeclSyntax(
206-
"""
207-
/// Creates a new ``\(node.kind.syntaxType)`` by appending the provided syntax element
208-
/// to the children.
209-
///
210-
/// - Parameter syntax: The element to append.
211-
/// - Returns: A new ``\(node.kind.syntaxType)`` with that element appended to the end.
212-
public func appending(_ syntax: Element) -> \(node.kind.syntaxType) {
213-
var newLayout = layoutView.formLayoutArray()
214-
newLayout.append(syntax.raw)
215-
return replacingLayout(newLayout)
216-
}
217-
"""
218-
)
219-
220-
DeclSyntax(
221-
"""
222-
/// Creates a new ``\(node.kind.syntaxType)`` by prepending the provided syntax element
223-
/// to the children.
224-
///
225-
/// - Parameter syntax: The element to prepend.
226-
/// - Returns: A new ``\(node.kind.syntaxType)`` with that element prepended to the
227-
/// beginning.
228-
public func prepending(_ syntax: Element) -> \(node.kind.syntaxType) {
229-
return inserting(syntax, at: 0)
230-
}
231-
"""
232-
)
233-
234-
DeclSyntax(
235-
"""
236-
/// Creates a new ``\(node.kind.syntaxType)`` by inserting the provided syntax element
237-
/// at the provided index in the children.
238-
///
239-
/// - Parameters:
240-
/// - syntax: The element to insert.
241-
/// - index: The index at which to insert the element in the collection.
242-
///
243-
/// - Returns: A new ``\(node.kind.syntaxType)`` with that element appended to the end.
244-
public func inserting(_ syntax: Element, at index: Int) -> \(node.kind.syntaxType) {
245-
var newLayout = layoutView.formLayoutArray()
246-
/// Make sure the index is a valid insertion index (0 to 1 past the end)
247-
precondition((newLayout.startIndex...newLayout.endIndex).contains(index),
248-
"inserting node at invalid index \\(index)")
249-
newLayout.insert(syntax.raw, at: index)
250-
return replacingLayout(newLayout)
251-
}
252-
"""
253-
)
254-
255-
DeclSyntax(
256-
"""
257-
/// Creates a new ``\(node.kind.syntaxType)`` by replacing the syntax element
258-
/// at the provided index.
259-
///
260-
/// - Parameters:
261-
/// - index: The index at which to replace the element in the collection.
262-
/// - syntax: The element to replace with.
263-
///
264-
/// - Returns: A new ``\(node.kind.syntaxType)`` with the new element at the provided index.
265-
public func replacing(childAt index: Int, with syntax: Element) -> \(node.kind.syntaxType) {
266-
var newLayout = layoutView.formLayoutArray()
267-
/// Make sure the index is a valid index for replacing
268-
precondition((newLayout.startIndex..<newLayout.endIndex).contains(index),
269-
"replacing node at invalid index \\(index)")
270-
newLayout[index] = syntax.raw
271-
return replacingLayout(newLayout)
272-
}
273-
"""
274-
)
275-
276-
DeclSyntax(
277-
"""
278-
/// Creates a new ``\(node.kind.syntaxType)`` by removing the syntax element at the
279-
/// provided index.
280-
///
281-
/// - Parameter index: The index of the element to remove from the collection.
282-
/// - Returns: A new ``\(node.kind.syntaxType)`` with the element at the provided index
283-
/// removed.
284-
public func removing(childAt index: Int) -> \(node.kind.syntaxType) {
285-
var newLayout = layoutView.formLayoutArray()
286-
newLayout.remove(at: index)
287-
return replacingLayout(newLayout)
288-
}
289-
"""
290-
)
291-
292-
DeclSyntax(
293-
"""
294-
/// Creates a new ``\(node.kind.syntaxType)`` by removing the first element.
295-
///
296-
/// - Returns: A new ``\(node.kind.syntaxType)`` with the first element removed.
297-
public func removingFirst() -> \(node.kind.syntaxType) {
298-
var newLayout = layoutView.formLayoutArray()
299-
newLayout.removeFirst()
300-
return replacingLayout(newLayout)
301-
}
302-
"""
303-
)
304-
305-
DeclSyntax(
306-
"""
307-
/// Creates a new ``\(node.kind.syntaxType)`` by removing the last element.
308-
///
309-
/// - Returns: A new ``\(node.kind.syntaxType)`` with the last element removed.
310-
public func removingLast() -> \(node.kind.syntaxType) {
311-
var newLayout = layoutView.formLayoutArray()
312-
newLayout.removeLast()
313-
return replacingLayout(newLayout)
314-
}
315-
"""
316-
)
317-
}
318-
319-
try! ExtensionDeclSyntax(
320-
"""
321-
/// Conformance for ``\(node.kind.syntaxType)`` to the `BidirectionalCollection` protocol.
322-
extension \(node.kind.syntaxType): BidirectionalCollection
323-
"""
324-
) {
325-
DeclSyntax("public typealias Index = SyntaxChildrenIndex")
326-
327-
DeclSyntax(
328-
"""
329-
public struct Iterator: IteratorProtocol {
330-
private let parent: Syntax
331-
private var iterator: RawSyntaxChildren.Iterator
332-
333-
init(parent: Syntax, rawChildren: RawSyntaxChildren) {
334-
self.parent = parent
335-
self.iterator = rawChildren.makeIterator()
336-
}
337-
338-
public mutating func next() -> Element? {
339-
guard let (raw, info) = self.iterator.next() else {
340-
return nil
341-
}
342-
let absoluteRaw = AbsoluteRawSyntax(raw: raw!, info: info)
343-
let data = SyntaxData(absoluteRaw, parent: parent)
344-
return Element(data)
345-
}
346-
}
347-
"""
348-
)
349-
350-
DeclSyntax(
351-
"""
352-
public func makeIterator() -> Iterator {
353-
return Iterator(parent: Syntax(self), rawChildren: rawChildren)
354-
}
355-
"""
356-
)
357-
358-
DeclSyntax(
359-
"""
360-
private var rawChildren: RawSyntaxChildren {
361-
// We know children in a syntax collection cannot be missing. So we can
362-
// use the low-level and faster RawSyntaxChildren collection instead of
363-
// NonNilRawSyntaxChildren.
364-
return RawSyntaxChildren(self.data.absoluteRaw)
365-
}
366-
"""
367-
)
368-
369-
DeclSyntax(
370-
"""
371-
public var startIndex: SyntaxChildrenIndex {
372-
return rawChildren.startIndex
373-
}
374-
"""
375-
)
376-
377-
DeclSyntax(
378-
"""
379-
public var endIndex: SyntaxChildrenIndex {
380-
return rawChildren.endIndex
381-
}
382-
"""
383-
)
384-
385-
DeclSyntax(
386-
"""
387-
public func index(after index: SyntaxChildrenIndex) -> SyntaxChildrenIndex {
388-
return rawChildren.index(after: index)
389-
}
390-
"""
391-
)
392-
393-
DeclSyntax(
394-
"""
395-
public func index(before index: SyntaxChildrenIndex) -> SyntaxChildrenIndex {
396-
return rawChildren.index(before: index)
397-
}
398-
"""
399-
)
400-
401-
DeclSyntax(
402-
"""
403-
public func distance(from start: SyntaxChildrenIndex, to end: SyntaxChildrenIndex)
404-
-> Int {
405-
return rawChildren.distance(from: start, to: end)
406-
}
407-
"""
408-
)
409-
410-
DeclSyntax(
411-
"""
412-
public subscript(position: SyntaxChildrenIndex) -> Element {
413-
let (raw, info) = rawChildren[position]
414-
let absoluteRaw = AbsoluteRawSyntax(raw: raw!, info: info)
415-
let data = SyntaxData(absoluteRaw, parent: Syntax(self))
416-
return Element(data)
417-
}
418-
"""
419-
)
117+
DeclSyntax("public static let syntaxKind = SyntaxKind.\(node.varOrCaseName)")
420118
}
421119
}
422120
}

CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntaxbuilder/BuildableCollectionNodesFile.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ let buildableCollectionNodesFile = SourceFileSyntax(leadingTrivia: copyrightHead
4040
public init(_ elements: \(ArrayTypeSyntax(elementType: elementType.parameterType))) {
4141
self = \(raw: node.type.syntaxBaseName)(elements.map {
4242
\(elementType.syntax)(fromProtocol: $0)
43-
})
43+
} as [\(elementType.syntax)])
4444
}
4545
"""
4646
)

Sources/SwiftSyntax/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ add_swift_host_library(SwiftSyntax
2121
Syntax.swift
2222
SyntaxArena.swift
2323
SyntaxChildren.swift
24+
SyntaxCollection.swift
2425
SyntaxData.swift
2526
SyntaxText.swift
2627
SyntaxTreeViewMode.swift

0 commit comments

Comments
 (0)