File: BuildTargetSourcesRequest.swift

package info (click to toggle)
swiftlang 6.2.3-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 2,856,264 kB
  • sloc: cpp: 9,995,718; ansic: 2,234,019; asm: 1,092,167; python: 313,940; objc: 82,726; f90: 80,126; lisp: 38,373; pascal: 25,580; sh: 20,378; ml: 5,058; perl: 4,751; makefile: 4,725; awk: 3,535; javascript: 3,018; xml: 918; fortran: 664; cs: 573; ruby: 396
file content (195 lines) | stat: -rw-r--r-- 7,199 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
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)
  }
}