Skip to content

Commit dbf0267

Browse files
committed
SourceKitLSP: properly handle paths on Windows
This corrects the path identification to include Windows paths properly. Although this is not entirely ideal due to the platform specific code, but avoids crashing the SourceKit LSP server if it encounters a space in the path.
1 parent a4e0f48 commit dbf0267

File tree

1 file changed

+21
-1
lines changed

1 file changed

+21
-1
lines changed

Sources/SourceKitLSP/Swift/SwiftLanguageServer.swift

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ import SKCore
1818
import SKSupport
1919
import SourceKitD
2020
import TSCBasic
21+
#if os(Windows)
22+
import WinSDK
23+
#endif
2124

2225
fileprivate extension Range {
2326
/// Checks if this range overlaps with the other range, counting an overlap with an empty range as a valid overlap.
@@ -1130,7 +1133,24 @@ extension SwiftLanguageServer: SKDNotificationHandler {
11301133

11311134
self.queue.async {
11321135
let uri: DocumentURI
1133-
if name.starts(with: "/") {
1136+
1137+
// Paths are expected to be absolute; on Windows, this means that the
1138+
// path is either drive letter prefixed (and thus `PathGetDriveNumberW`
1139+
// will provide the driver number OR it is a UNC path and `PathIsUNCW`
1140+
// will return `true`. On Unix platforms, the path will start with `/`
1141+
// which takes care of both a regular absolute path and a POSIX
1142+
// alternate root path.
1143+
1144+
// TODO: this is not completely portable, e.g. MacOS 9 HFS paths are
1145+
// unhandled.
1146+
#if os(Windows)
1147+
let isPath: Bool = !name.withCString(encodedAs: UTF16.self) {
1148+
PathIsUNCW($0) || (0...25) ~= PathGetDriveNumberW($0)
1149+
}
1150+
#else
1151+
let isPath: Bool = name.starts(with: "/")
1152+
#endif
1153+
if isPath {
11341154
// If sourcekitd returns us a path, translate it back into a URL
11351155
uri = DocumentURI(URL(fileURLWithPath: name))
11361156
} else {

0 commit comments

Comments
 (0)