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
|
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2019 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
//
//===----------------------------------------------------------------------===//
public import LanguageServerProtocol
/// The build target sources request is sent from the client to the server to
/// query for the list of text documents and directories that belong to a
/// build target. The sources response must not include sources that are
/// external to the workspace.
public struct BuildTargetSourcesRequest: RequestType, Hashable {
public static let method: String = "buildTarget/sources"
public typealias Response = BuildTargetSourcesResponse
public var targets: [BuildTargetIdentifier]
public init(targets: [BuildTargetIdentifier]) {
self.targets = targets
}
}
public struct BuildTargetSourcesResponse: ResponseType, Hashable {
public var items: [SourcesItem]
public init(items: [SourcesItem]) {
self.items = items
}
}
public struct SourcesItem: Codable, Hashable, Sendable {
public var target: BuildTargetIdentifier
/// The text documents and directories that belong to this build target.
public var sources: [SourceItem]
/// The root directories from where source files should be relativized.
/// Example: ["file://Users/name/dev/metals/src/main/scala"]
public var roots: [URI]?
public init(target: BuildTargetIdentifier, sources: [SourceItem], roots: [URI]? = nil) {
self.target = target
self.sources = sources
self.roots = roots
}
}
public struct SourceItem: Codable, Hashable, Sendable {
/// Either a text document or a directory. A directory entry must end with a
/// forward slash "/" and a directory entry implies that every nested text
/// document within the directory belongs to this source item.
public var uri: URI
/// Type of file of the source item, such as whether it is file or directory.
public var kind: SourceItemKind
/// Indicates if this source is automatically generated by the build and is
/// not intended to be manually edited by the user.
public var generated: Bool
/// Kind of data to expect in the `data` field. If this field is not set, the kind of data is not specified.
public var dataKind: SourceItemDataKind?
/// Language-specific metadata about this source item.
public var data: LSPAny?
/// If `dataKind` is `sourceKit`, the `data` interpreted as `SourceKitSourceItemData`, otherwise `nil`.
public var sourceKitData: SourceKitSourceItemData? {
guard dataKind == .sourceKit else {
return nil
}
return SourceKitSourceItemData(fromLSPAny: data)
}
public init(
uri: URI,
kind: SourceItemKind,
generated: Bool,
dataKind: SourceItemDataKind? = nil,
data: LSPAny? = nil
) {
self.uri = uri
self.kind = kind
self.generated = generated
self.dataKind = dataKind
self.data = data
}
}
public enum SourceItemKind: Int, Codable, Hashable, Sendable {
/// The source item references a normal file.
case file = 1
/// The source item references a directory.
case directory = 2
}
public struct SourceItemDataKind: RawRepresentable, Codable, Hashable, Sendable {
public var rawValue: String
public init(rawValue: String) {
self.rawValue = rawValue
}
/// `data` field must contain a JvmSourceItemData object.
public static let jvm = SourceItemDataKind(rawValue: "jvm")
/// `data` field must contain a `SourceKitSourceItemData` object.
///
/// **(BSP Extension)**
public static let sourceKit = SourceItemDataKind(rawValue: "sourceKit")
}
/// **(BSP Extension)**
public enum SourceKitSourceItemKind: String, Codable {
/// A source file that belongs to the target
case source = "source"
/// A header file that is clearly associated with one target.
///
/// For example header files in SwiftPM projects are always associated to one target and SwiftPM can provide build
/// settings for that header file.
///
/// In general, build systems don't need to list all header files in the `buildTarget/sources` request: Semantic
/// functionality for header files is usually provided by finding a main file that includes the header file and
/// inferring build settings from it. Listing header files in `buildTarget/sources` allows SourceKit-LSP to provide
/// semantic functionality for header files if they haven't been included by any main file.
case header = "header"
/// A SwiftDocC documentation catalog usually ending in the ".docc" extension.
case doccCatalog = "doccCatalog"
}
public struct SourceKitSourceItemData: LSPAnyCodable, Codable {
/// The language of the source file. If `nil`, the language is inferred from the file extension.
public var language: Language?
/// The kind of source file that this source item represents. If omitted, the item is assumed to be a normal source file,
/// ie. omitting this key is equivalent to specifying it as `source`.
public var kind: SourceKitSourceItemKind?
/// The output path that is used during indexing for this file, ie. the `-index-unit-output-path`, if it is specified
/// in the compiler arguments or the file that is passed as `-o`, if `-index-unit-output-path` is not specified.
///
/// This allows SourceKit-LSP to remove index entries for source files that are removed from a target but remain
/// present on disk.
///
/// The server communicates during the initialize handshake whether it populates this property by setting
/// `outputPathsProvider: true` in `SourceKitInitializeBuildResponseData`.
public var outputPath: String?
public init(language: Language? = nil, kind: SourceKitSourceItemKind? = nil, outputPath: String? = nil) {
self.language = language
self.kind = kind
self.outputPath = outputPath
}
public init?(fromLSPDictionary dictionary: [String: LanguageServerProtocol.LSPAny]) {
if case .string(let language) = dictionary[CodingKeys.language.stringValue] {
self.language = Language(rawValue: language)
}
if case .string(let rawKind) = dictionary[CodingKeys.kind.stringValue] {
self.kind = SourceKitSourceItemKind(rawValue: rawKind)
}
// Backwards compatibility for isHeader
if case .bool(let isHeader) = dictionary["isHeader"], isHeader {
self.kind = .header
}
if case .string(let outputFilePath) = dictionary[CodingKeys.outputPath.stringValue] {
self.outputPath = outputFilePath
}
}
public func encodeToLSPAny() -> LanguageServerProtocol.LSPAny {
var result: [String: LSPAny] = [:]
if let language {
result[CodingKeys.language.stringValue] = .string(language.rawValue)
}
if let kind {
result[CodingKeys.kind.stringValue] = .string(kind.rawValue)
}
if let outputPath {
result[CodingKeys.outputPath.stringValue] = .string(outputPath)
}
return .dictionary(result)
}
}
|