Skip to content

Commit 7fac292

Browse files
committed
Only render inlay hints after variable bindings
Use a document symbols query to figure out where variable bindings are located, then only render the inlay hints there.
1 parent 4e60dac commit 7fac292

File tree

1 file changed

+37
-20
lines changed

1 file changed

+37
-20
lines changed

Sources/SourceKitLSP/Swift/SwiftLanguageServer.swift

Lines changed: 37 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1058,27 +1058,44 @@ extension SwiftLanguageServer {
10581058

10591059
public func inlayHints(_ req: Request<InlayHintsRequest>) {
10601060
let uri = req.params.textDocument.uri
1061-
expressionTypeInfos(uri) { result in
1062-
switch result {
1063-
case .success(let infos):
1064-
let hints = infos
1065-
.lazy
1066-
.map { info in
1067-
InlayHint(
1068-
position: info.range.upperBound,
1069-
category: .type,
1070-
label: info.printedType
1071-
)
1072-
}
1073-
.filter { hint in
1074-
// TODO: Compute inlay hints only for the requested range/categories
1075-
// instead of filtering them afterwards.
1076-
(req.params.range?.contains(hint.position) ?? true)
1077-
&& (hint.category.flatMap { req.params.only?.contains($0) } ?? true)
1061+
documentSymbols(uri) { symbolsResult in
1062+
do {
1063+
func bindings(_ symbols: [DocumentSymbol]) -> [DocumentSymbol] {
1064+
symbols
1065+
.flatMap { bindings($0.children ?? []) + ($0.kind == .variable ? [$0] : []) }
1066+
}
1067+
1068+
let symbols = try symbolsResult.get()
1069+
let bindingPositions = Set(bindings(symbols).map { $0.range.upperBound })
1070+
1071+
self.expressionTypeInfos(uri) { infosResult in
1072+
do {
1073+
let infos = try infosResult.get()
1074+
let hints = infos
1075+
.lazy
1076+
.filter { bindingPositions.contains($0.range.upperBound) }
1077+
.map { info in
1078+
InlayHint(
1079+
position: info.range.upperBound,
1080+
category: .type,
1081+
label: info.printedType
1082+
)
1083+
}
1084+
.filter { hint in
1085+
// TODO: Compute inlay hints only for the requested range/categories
1086+
// instead of filtering them afterwards.
1087+
(req.params.range?.contains(hint.position) ?? true)
1088+
&& (hint.category.flatMap { req.params.only?.contains($0) } ?? true)
1089+
}
1090+
req.reply(.success(Array(hints)))
1091+
} catch {
1092+
let message = "expression types for inlay hints failed for \(uri): \(error)"
1093+
log(message, level: .warning)
1094+
req.reply(.failure(.unknown(message)))
10781095
}
1079-
req.reply(.success(Array(hints)))
1080-
case .failure(let error):
1081-
let message = "inlay hints failed \(uri): \(error)"
1096+
}
1097+
} catch {
1098+
let message = "document symbols for inlay hints failed for \(uri): \(error)"
10821099
log(message, level: .warning)
10831100
req.reply(.failure(.unknown(message)))
10841101
}

0 commit comments

Comments
 (0)