| %{ |
| # -*- mode: Swift -*- |
| from gyb_syntax_support.Trivia import TRIVIAS |
| # Ignore the following admonition it applies to the resulting .swift file only |
| }% |
| //// Automatically Generated From Trivia.swift.gyb. |
| //// Do Not Edit Directly! |
| //===------------------- Trivia.swift - Source Trivia Enum ----------------===// |
| // |
| // 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 |
| |
| /// A contiguous stretch of a single kind of trivia. The constituent part of |
| /// a `Trivia` collection. |
| /// |
| /// For example, four spaces would be represented by |
| /// `.spaces(4)` |
| /// |
| /// In general, you should deal with the actual Trivia collection instead |
| /// of individual pieces whenever possible. |
| public enum TriviaPiece: Codable { |
| enum CodingKeys: CodingKey { |
| case kind, value |
| } |
| public init(from decoder: Decoder) throws { |
| let container = try decoder.container(keyedBy: CodingKeys.self) |
| let kind = try container.decode(String.self, forKey: .kind) |
| switch kind { |
| % for trivia in TRIVIAS: |
| case "${trivia.name}": |
| % if trivia.is_collection(): |
| let value = try container.decode(Int.self, forKey: .value) |
| self = .${trivia.lower_name}s(value) |
| % else: |
| let value = try container.decode(String.self, forKey: .value) |
| self = .${trivia.lower_name}(value) |
| % end |
| % end |
| default: |
| let context = |
| DecodingError.Context(codingPath: [CodingKeys.kind], |
| debugDescription: "invalid TriviaPiece kind \(kind)") |
| throw DecodingError.valueNotFound(String.self, context) |
| } |
| } |
| |
| public func encode(to encoder: Encoder) throws { |
| var container = encoder.container(keyedBy: CodingKeys.self) |
| switch self { |
| % for trivia in TRIVIAS: |
| % if trivia.is_collection(): |
| case .${trivia.lower_name}s(let count): |
| try container.encode("${trivia.name}", forKey: .kind) |
| try container.encode(count, forKey: .value) |
| % else: |
| case .${trivia.lower_name}(let text): |
| try container.encode("${trivia.name}", forKey: .kind) |
| try container.encode(text, forKey: .value) |
| % end |
| % end |
| } |
| } |
| |
| % for trivia in TRIVIAS: |
| /// ${trivia.comment} |
| % if trivia.is_collection(): |
| case ${trivia.lower_name}s(Int) |
| % else: |
| case ${trivia.lower_name}(String) |
| % end |
| % end |
| } |
| |
| extension TriviaPiece: TextOutputStreamable { |
| /// Prints the provided trivia as they would be written in a source file. |
| /// |
| /// - Parameter stream: The stream to which to print the trivia. |
| public func write<Target>(to target: inout Target) |
| where Target: TextOutputStream { |
| func printRepeated(_ character: String, count: Int) { |
| for _ in 0..<count { target.write(character) } |
| } |
| switch self { |
| % for trivia in TRIVIAS: |
| % if trivia.is_collection(): |
| % joined = ''.join(trivia.swift_characters) |
| case let .${trivia.lower_name}s(count): |
| printRepeated("${joined}", count: count) |
| % else: |
| case let .${trivia.lower_name}(text): |
| target.write(text) |
| % end |
| % end |
| } |
| } |
| } |
| |
| /// A collection of leading or trailing trivia. This is the main data structure |
| /// for thinking about trivia. |
| public struct Trivia: Codable { |
| let pieces: [TriviaPiece] |
| |
| /// Creates Trivia with the provided underlying pieces. |
| public init(pieces: [TriviaPiece]) { |
| self.pieces = pieces |
| } |
| |
| public init(from decoder: Decoder) throws { |
| var container = try decoder.unkeyedContainer() |
| var pieces = [TriviaPiece]() |
| while let piece = try container.decodeIfPresent(TriviaPiece.self) { |
| pieces.append(piece) |
| } |
| self.pieces = pieces |
| } |
| |
| public func encode(to encoder: Encoder) throws { |
| var container = encoder.unkeyedContainer() |
| for piece in pieces { |
| try container.encode(piece) |
| } |
| } |
| |
| /// Creates Trivia with no pieces. |
| public static var zero: Trivia { |
| return Trivia(pieces: []) |
| } |
| |
| /// Creates a new `Trivia` by appending the provided `TriviaPiece` to the end. |
| public func appending(_ piece: TriviaPiece) -> Trivia { |
| var copy = pieces |
| copy.append(piece) |
| return Trivia(pieces: copy) |
| } |
| |
| public var sourceLength: SourceLength { |
| return pieces.map({ $0.sourceLength }).reduce(.zero, +) |
| } |
| |
| /// Get the byteSize of this trivia |
| public var byteSize: Int { |
| return sourceLength.utf8Length |
| } |
| |
| % for trivia in TRIVIAS: |
| % if trivia.is_collection(): |
| % joined = ''.join(trivia.swift_characters) |
| /// Return a piece of trivia for some number of '${joined}' characters. |
| public static func ${trivia.lower_name}s(_ count: Int) -> Trivia { |
| return [.${trivia.lower_name}s(count)] |
| } |
| % else: |
| /// Return a piece of trivia for ${trivia.name}. |
| public static func ${trivia.lower_name}(_ text: String) -> Trivia { |
| return [.${trivia.lower_name}(text)] |
| } |
| % end |
| % end |
| } |
| |
| /// Conformance for Trivia to the Collection protocol. |
| extension Trivia: Collection { |
| public var startIndex: Int { |
| return pieces.startIndex |
| } |
| |
| public var endIndex: Int { |
| return pieces.endIndex |
| } |
| |
| public func index(after i: Int) -> Int { |
| return pieces.index(after: i) |
| } |
| |
| public subscript(_ index: Int) -> TriviaPiece { |
| return pieces[index] |
| } |
| } |
| |
| |
| extension Trivia: ExpressibleByArrayLiteral { |
| /// Creates Trivia from the provided pieces. |
| public init(arrayLiteral elements: TriviaPiece...) { |
| self.pieces = elements |
| } |
| } |
| |
| /// Concatenates two collections of `Trivia` into one collection. |
| public func +(lhs: Trivia, rhs: Trivia) -> Trivia { |
| return Trivia(pieces: lhs.pieces + rhs.pieces) |
| } |
| |
| extension TriviaPiece { |
| public var sourceLength: SourceLength { |
| switch self { |
| % for trivia in TRIVIAS: |
| % if trivia.is_new_line: |
| case let .${trivia.lower_name}s(count): |
| return SourceLength(newlines: count, columnsAtLastLine: 0, |
| utf8Length: count * ${trivia.characters_len()}) |
| % elif trivia.is_collection(): |
| case let .${trivia.lower_name}s(count): |
| return SourceLength(newlines: 0, columnsAtLastLine: count, |
| utf8Length: count) |
| % else: |
| case let .${trivia.lower_name}(text): |
| return SourceLength(of: text) |
| % end |
| % end |
| } |
| } |
| } |
| |
| extension Trivia: ByteTreeObjectDecodable { |
| static func read(from reader: ByteTreeObjectReader, numFields: Int) -> Trivia { |
| let pieces = [TriviaPiece].read(from: reader, numFields: numFields) |
| return Trivia(pieces: pieces) |
| } |
| } |
| |
| extension TriviaPiece: ByteTreeObjectDecodable { |
| static func read(from reader: ByteTreeObjectReader, numFields: Int) -> TriviaPiece { |
| let kind = reader.readField(UInt8.self, index: 0) |
| switch kind { |
| % for trivia in TRIVIAS: |
| case ${trivia.serialization_code}: |
| % if trivia.is_collection(): |
| let count = Int(reader.readField(UInt32.self, index: 1)) |
| return .${trivia.lower_name}s(count) |
| % else: |
| let text = reader.readField(String.self, index: 1) |
| return .${trivia.lower_name}(text) |
| % end |
| % end |
| default: |
| fatalError("Unknown trivia piece kind \(kind)") |
| } |
| } |
| } |