-
Notifications
You must be signed in to change notification settings - Fork 10.5k
/
Copy pathSyntaxCollections.swift.gyb
197 lines (174 loc) · 6.65 KB
/
SyntaxCollections.swift.gyb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
%{
from gyb_syntax_support import *
# -*- mode: Swift -*-
# Ignore the following admonition it applies to the resulting .swift file only
}%
//// Automatically Generated From SyntaxCollections.swift.gyb.
//// Do Not Edit Directly!
//===------------ SyntaxCollections.swift.gyb - Syntax Collection ---------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
import Foundation
% for node in SYNTAX_NODES:
% if node.collection_element:
/// `${node.name}` represents a collection of one or more
/// `${node.collection_element_type}` nodes. ${node.name} behaves
/// as a regular Swift collection, and has accessors that return new
/// versions of the collection with different children.
public struct ${node.name}: _SyntaxBase {
let _root: SyntaxData
unowned let _data: SyntaxData
/// Creates a Syntax node from the provided root and data.
internal init(root: SyntaxData, data: SyntaxData) {
self._root = root
self._data = data
#if DEBUG
validate()
#endif
}
/// Creates a new `${node.name}` by replacing the underlying layout with
/// a different set of raw syntax nodes.
///
/// - Parameter layout: The new list of raw syntax nodes underlying this
/// collection.
/// - Returns: A new `${node.name}` with the new layout underlying it.
internal func replacingLayout(
_ layout: [RawSyntax?]) -> ${node.name} {
let newRaw = data.raw.replacingLayout(layout)
let (newRoot, newData) = data.replacingSelf(newRaw)
return ${node.name}(root: newRoot, data: newData)
}
/// Creates a new `${node.name}` by appending the provided syntax element
/// to the children.
///
/// - Parameter syntax: The element to append.
/// - Returns: A new `${node.name}` with that element appended to the end.
public func appending(
_ syntax: ${node.collection_element_type}) -> ${node.name} {
var newLayout = data.raw.layout
newLayout.append(syntax.raw)
return replacingLayout(newLayout)
}
/// Creates a new `${node.name}` by prepending the provided syntax element
/// to the children.
///
/// - Parameter syntax: The element to prepend.
/// - Returns: A new `${node.name}` with that element prepended to the
/// beginning.
public func prepending(
_ syntax: ${node.collection_element_type}) -> ${node.name} {
return inserting(syntax, at: 0)
}
/// Creates a new `${node.name}` by inserting the provided syntax element
/// at the provided index in the children.
///
/// - Parameters:
/// - syntax: The element to insert.
/// - index: The index at which to insert the element in the collection.
///
/// - Returns: A new `${node.name}` with that element appended to the end.
public func inserting(_ syntax: ${node.collection_element_type},
at index: Int) -> ${node.name} {
var newLayout = data.raw.layout
/// Make sure the index is a valid insertion index (0 to 1 past the end)
precondition((newLayout.startIndex...newLayout.endIndex).contains(index),
"inserting node at invalid index \(index)")
newLayout.insert(syntax.raw, at: index)
return replacingLayout(newLayout)
}
/// Creates a new `${node.name}` by replacing the syntax element
/// at the provided index.
///
/// - Parameters:
/// - index: The index at which to replace the element in the collection.
/// - syntax: The element to replace with.
///
/// - Returns: A new `${node.name}` with the new element at the provided index.
public func replacing(childAt index: Int,
with syntax: ${node.collection_element_type}) -> ${node.name} {
var newLayout = data.raw.layout
/// Make sure the index is a valid index for replacing
precondition((newLayout.startIndex..<newLayout.endIndex).contains(index),
"replacing node at invalid index \(index)")
newLayout[index] = syntax.raw
return replacingLayout(newLayout)
}
/// Creates a new `${node.name}` by removing the syntax element at the
/// provided index.
///
/// - Parameter index: The index of the element to remove from the collection.
/// - Returns: A new `${node.name}` with the element at the provided index
/// removed.
public func removing(childAt index: Int) -> ${node.name} {
var newLayout = data.raw.layout
newLayout.remove(at: index)
return replacingLayout(newLayout)
}
/// Creates a new `${node.name}` by removing the first element.
///
/// - Returns: A new `${node.name}` with the first element removed.
public func removingFirst() -> ${node.name} {
var newLayout = data.raw.layout
newLayout.removeFirst()
return replacingLayout(newLayout)
}
/// Creates a new `${node.name}` by removing the last element.
///
/// - Returns: A new `${node.name}` with the last element removed.
public func removingLast() -> ${node.name} {
var newLayout = data.raw.layout
newLayout.removeLast()
return replacingLayout(newLayout)
}
/// Returns an iterator over the elements of this syntax collection.
public func makeIterator() -> ${node.name}Iterator {
return ${node.name}Iterator(collection: self)
}
}
/// Conformance for `${node.name}`` to the Collection protocol.
extension ${node.name}: Collection {
public var startIndex: Int {
return data.childCaches.startIndex
}
public var endIndex: Int {
return data.childCaches.endIndex
}
public func index(after i: Int) -> Int {
return data.childCaches.index(after: i)
}
public subscript(_ index: Int) -> ${node.collection_element_type} {
% cast = '' if node.collection_element_type == 'Syntax' \
% else 'as! ' + node.collection_element_type
return child(at: index)! ${cast}
}
}
/// A type that iterates over a `${node.name}` using its indices.
public struct ${node.name}Iterator: IteratorProtocol {
public typealias Element = ${node.collection_element_type}
private let collection: ${node.name}
private var index: ${node.name}.Index
fileprivate init(collection: ${node.name}) {
self.collection = collection
self.index = collection.startIndex
}
public mutating func next() -> Element? {
guard
!(self.collection.isEmpty || self.index == self.collection.endIndex)
else {
return nil
}
let result = collection[index]
collection.formIndex(after: &index)
return result
}
}
% end
% end