Skip to content

Commit 134073d

Browse files
committed
Implement sourcekitd to VariableTypeInfo deserialization
1 parent 2e2ae18 commit 134073d

File tree

2 files changed

+76
-0
lines changed

2 files changed

+76
-0
lines changed

Sources/SourceKitD/sourcekitd_uids.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ public struct sourcekitd_keys {
6868
public let variable_length: sourcekitd_uid_t
6969
public let variable_type: sourcekitd_uid_t
7070
public let variable_type_explicit: sourcekitd_uid_t
71+
public let variable_type_list: sourcekitd_uid_t
7172

7273
// Code Completion options.
7374
public let codecomplete_options: sourcekitd_uid_t
@@ -137,6 +138,7 @@ public struct sourcekitd_keys {
137138
variable_length = api.uid_get_from_cstr("key.variable_length")!
138139
variable_type = api.uid_get_from_cstr("key.variable_type")!
139140
variable_type_explicit = api.uid_get_from_cstr("key.variable_type_explicit")!
141+
variable_type_list = api.uid_get_from_cstr("key.variable_type_list")!
140142

141143
// Code Completion options
142144
codecomplete_options = api.uid_get_from_cstr("key.codecomplete.options")!

Sources/SourceKitLSP/Swift/VariableTypeInfo.swift

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,77 @@ struct VariableTypeInfo {
3636
self.printedType = printedType
3737
}
3838
}
39+
40+
enum VariableTypeInfoError: Error, Equatable {
41+
/// The given URL is not a known document.
42+
case unknownDocument(DocumentURI)
43+
44+
/// The underlying sourcekitd request failed with the given error.
45+
case responseError(ResponseError)
46+
}
47+
48+
extension SwiftLanguageServer {
49+
/// Must be called on self.queue.
50+
private func _variableTypeInfos(
51+
_ uri: DocumentURI,
52+
_ completion: @escaping (Swift.Result<[VariableTypeInfo], VariableTypeInfoError>) -> Void
53+
) {
54+
dispatchPrecondition(condition: .onQueue(queue))
55+
56+
guard let snapshot = documentManager.latestSnapshot(uri) else {
57+
return completion(.failure(.unknownDocument(uri)))
58+
}
59+
60+
let keys = self.keys
61+
62+
let skreq = SKDRequestDictionary(sourcekitd: sourcekitd)
63+
skreq[keys.request] = requests.variable_type
64+
skreq[keys.sourcefile] = snapshot.document.uri.pseudoPath
65+
66+
// FIXME: SourceKit should probably cache this for us
67+
if let compileCommand = self.commandsByFile[uri] {
68+
skreq[keys.compilerargs] = compileCommand.compilerArgs
69+
}
70+
71+
let handle = self.sourcekitd.send(skreq, self.queue) { result in
72+
guard let dict = result.success else {
73+
return completion(.failure(.responseError(ResponseError(result.failure!))))
74+
}
75+
76+
guard let skVariableTypeInfos: SKDResponseArray = dict[keys.variable_type_list] else {
77+
return completion(.success([]))
78+
}
79+
80+
var variableTypeInfos: [VariableTypeInfo] = []
81+
variableTypeInfos.reserveCapacity(skVariableTypeInfos.count)
82+
83+
skVariableTypeInfos.forEach { (_, skVariableTypeInfo) -> Bool in
84+
guard let info = VariableTypeInfo(skVariableTypeInfo, in: snapshot) else {
85+
assertionFailure("VariableTypeInfo failed to deserialize")
86+
return true
87+
}
88+
variableTypeInfos.append(info)
89+
return true
90+
}
91+
92+
completion(.success(variableTypeInfos))
93+
}
94+
95+
// FIXME: cancellation
96+
_ = handle
97+
}
98+
99+
/// Provides typed variable declarations in a document.
100+
///
101+
/// - Parameters:
102+
/// - url: Document URL in which to perform the request. Must be an open document.
103+
/// - completion: Completion block to asynchronously receive the VariableTypeInfos, or error.
104+
func variableTypeInfos(
105+
_ uri: DocumentURI,
106+
_ completion: @escaping (Swift.Result<[VariableTypeInfo], VariableTypeInfoError>) -> Void
107+
) {
108+
queue.async {
109+
self._variableTypeInfos(uri, completion)
110+
}
111+
}
112+
}

0 commit comments

Comments
 (0)