File: AttributedCodeListing.swift

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (146 lines) | stat: -rw-r--r-- 5,547 bytes parent folder | download
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
/*
 This source file is part of the Swift.org open source project

 Copyright (c) 2021 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 Swift project authors
*/

/// A code block represented as lines of lexical tokens.
///
/// Use attributed code listings to represent code written in a specific programming language.
public struct AttributedCodeListing: Hashable {
    /// The source-code language for this code listing.
    public let sourceLanguage: SourceLanguage?

    /// The lines of code in the listing.
    public let codeLines: [Line]

    /// An identifiable title for this code listing.
    public let title: String?

    /// Indicates whether the code listing is empty or contains exclusively empty code.
    public var isEmpty: Bool {
        for codeLine in codeLines where !codeLine.isEmpty {
            return false
        }
        return true
    }
}

extension AttributedCodeListing {
    /// A single line of tokenized code in an attributed code listing.
    public struct Line: Hashable {
        /// The code elements in this line.
        ///
        /// Tokens form a line's contents. A code line can be empty, to allow for line breaks between blocks of code.
        /// An empty code line is indicated by a ``AttributedCodeListing/Line`` with an empty `tokens` array.
        public var tokens: [Token]

        /// Creates a new empty line.
        ///
        /// Empty lines have no tokens.
        public init() { self.tokens = [] }

        /// Creates a line consisting of the given tokens.
        public init(_ tokens: [Token]) { self.tokens = tokens }

        /// Indicates whether the code line is empty, which means it contains no code elements.
        public var isEmpty: Bool { return tokens.isEmpty }
    }
    
    /// Creates an attributed code listing from plain text.
    ///
    /// This initializer splits the given plain text by newline characters and represents each line in a plain-text lexical token. Use this API
    /// if you don't have a tokenized version of your code block.
    ///
    /// - Parameters:
    ///   - sourceLanguage: The source-code language in which the code is written in.
    ///   - plainText: The code as plain text.
    ///   - title: The title of the code listing.
    public init(sourceLanguage: SourceLanguage?, plainText: String, title: String?) {
        let codeLines = plainText.split(separator: "\n").map { Line([.plain(String($0))]) }
        self.init(sourceLanguage: sourceLanguage, codeLines: codeLines, title: title)
    }
}

extension AttributedCodeListing.Line {
    /// An element in a line of code.
    public enum Token: Hashable, CustomStringConvertible {
        /// Text in a code line with no indicated semantic meaning.
        case plain(String)
        
        /// A keyword reserved by the language.
        ///
        /// Example keywords in the Swift programming language are `func` and `typealias`.
        case keyword(String)
        
        /// An identifier name, such as the name of a symbol.
        case identifier(String)
        
        /// A number literal as written in code.
        case numberLiteral(String)
        
        /// A string literal as written in code.
        case stringLiteral(String)
        
        /// The name of a parameter in a function-like construct.
        case parameterName(String)
        
        /// The name of a generic type parameter.
        case genericTypeParameterName(String)
        
        /// An attribute, typically associated with the declaration of a symbol.
        ///
        /// An attribute consists of a name and a content. The name of the attribute includes syntactic markers, such as the `@` in
        /// Swift. The contents of an attribute are the text that follows the name in the attribute's declaration.
        case attribute(name: String, contents: String?)
        
        /// An annotation in code that indicates the type name of an identifier.
        ///
        /// A type annotation has a name and a unique identifier for the type, if known.
        case typeAnnotation(name: String, usr: String?)
        
        public var description: String {
            switch self {
            case .plain(let string):
                return string
            case .keyword(let string):
                return string
            case .identifier(let string):
                return string
            case .numberLiteral(let string):
                return string
            case .stringLiteral(let string):
                return string
            case .parameterName(let string):
                return string
            case .genericTypeParameterName(let string):
                return string
            case .attribute(let name, let contents):
                if let contents {
                    return "@\(name)(\(contents))"
                } else {
                    return "@\(name)"
                }
            case .typeAnnotation(let name, _):
                return name
            }
        }
    }
}


/// A reference to a code listing that hasn't been resolved yet.
public struct UnresolvedCodeListingReference {
    /// The name identifier of the code listing.
    public var identifier: String
    
    /// Creates an unresolved code listing reference given its name identifier.
    public init(identifier: String) {
        self.identifier = identifier
    }
}