| %{ |
| 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 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 |