Skip to content

Commit 31b1a5c

Browse files
gregshintellij-monorepo-bot
authored andcommitted
[lsp] Fix URI conversion on Windows
1. VSCode drive letters are lowercase 2. LSP spec allows unstable URI %-escaping Fixes LSP-307. GitOrigin-RevId: a030dbb9bdf7fae3bdfcc8484ec0bbeef81253e4
1 parent 87e3609 commit 31b1a5c

File tree

3 files changed

+16
-17
lines changed

3 files changed

+16
-17
lines changed

api.core/src/com/jetbrains/ls/api/core/util/LSUtil.kt

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,20 +12,16 @@ import com.intellij.openapi.vfs.VirtualFileManager
1212
import com.intellij.openapi.vfs.findPsiFile
1313
import com.intellij.platform.workspace.jps.entities.*
1414
import com.intellij.platform.workspace.storage.EntitySource
15-
import com.intellij.platform.workspace.storage.InternalEnvironmentName
1615
import com.intellij.platform.workspace.storage.MutableEntityStorage
1716
import com.intellij.platform.workspace.storage.entities
1817
import com.intellij.platform.workspace.storage.url.VirtualFileUrlManager
1918
import com.intellij.psi.PsiFile
20-
import com.intellij.workspaceModel.ide.impl.legacyBridge.sdk.SdkBridgeImpl
21-
import com.intellij.workspaceModel.ide.impl.legacyBridge.sdk.SdkBridgeImpl.Companion.mutableSdkMap
2219
import com.intellij.workspaceModel.ide.impl.legacyBridge.sdk.customName
2320
import com.jetbrains.ls.api.core.LSAnalysisContext
2421
import com.jetbrains.ls.api.core.project
2522
import com.jetbrains.lsp.protocol.*
2623
import java.nio.file.Path
2724
import kotlin.io.path.exists
28-
import kotlin.io.path.toPath
2925

3026
val VirtualFile.uri: URI
3127
get() = url.intellijUriToLspUri()
@@ -155,8 +151,8 @@ fun createSdkEntity(
155151

156152
@Suppress("DEPRECATION")
157153
fun workspaceFolderPaths(params: InitializeParams): List<Path> =
158-
params.workspaceFolders?.map { it.uri.asJavaUri().toPath() }
159-
?: params.rootUri?.let { listOf(it.uri.asJavaUri().toPath()) }
154+
params.workspaceFolders?.mapNotNull { it.uri.toPath() }
155+
?: params.rootUri?.let { listOfNotNull(it.uri.toPath()) }
160156
?: params.rootPath?.let { listOf(Path.of(it)) }
161157
?: emptyList()
162158

api.core/src/com/jetbrains/ls/api/core/util/UriConverter.kt

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,12 @@ package com.jetbrains.ls.api.core.util
33

44
import com.intellij.openapi.util.SystemInfoRt
55
import com.intellij.openapi.util.io.FileUtilRt
6+
import com.intellij.openapi.vfs.VfsUtilCore
67
import com.jetbrains.lsp.protocol.URI
78
import java.nio.file.Path
89
import java.nio.file.Paths
910
import kotlin.io.path.absolutePathString
1011
import kotlin.io.path.extension
11-
import kotlin.io.path.name
12-
import kotlin.io.path.toPath
1312
import java.net.URI as JavaUri
1413

1514
/**
@@ -121,7 +120,7 @@ object UriConverter {
121120
path = path.removePrefix("/")
122121
if (SystemInfoRt.isWindows && path.length > 2 && path[1] == ':') {
123122
// encode `:` with `%3A` as vscode does this to have consistent uris
124-
path = path[0].uppercase() + "%3A" + path.substring(2)
123+
path = path[0].lowercase() + "%3A" + path.substring(2)
125124
}
126125
path = "/$path"
127126
return path
@@ -138,6 +137,10 @@ fun Path.toLspUri(): URI {
138137
return URI(uriString)
139138
}
140139

140+
fun URI.toPath(): Path? {
141+
val url = UriConverter.lspUriToIntellijUri(uri) ?: return null
142+
return Path.of(FileUtilRt.toSystemDependentName(VfsUtilCore.urlToPath(url)))
143+
}
141144

142145
/**
143146
* Returns the URI's scheme without scheme delimiter (`://`)

api.core/test/com/jetbrains/ls/api/core/util/UriConverterTest.kt

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -120,12 +120,12 @@ class UriConverterTest {
120120
fun `should convert IntelliJ URI to LSP URI for Windows paths`() {
121121
onlyOnWindows {
122122
testIntellijToLsp(
123-
"file:///C%3A/Users/test/file.txt",
124-
"file://c:/Users/test/file.txt"
123+
"file:///c%3A/Users/test/file.txt",
124+
"file://C:/Users/test/file.txt"
125125
)
126126

127127
testIntellijToLsp(
128-
"file:///D%3A/Program%20Files/App/config.xml",
128+
"file:///d%3A/Program%20Files/App/config.xml",
129129
"file://d:/Program Files/App/config.xml"
130130
)
131131
}
@@ -135,7 +135,7 @@ class UriConverterTest {
135135
fun `should convert IntelliJ URI to LSP URI for JAR files`() {
136136
onlyOnWindows {
137137
testIntellijToLsp(
138-
"jar:///C%3A/libs/app.jar!/com/example/Main.class",
138+
"jar:///c%3A/libs/app.jar!/com/example/Main.class",
139139
"jar://C:/libs/app.jar!/com/example/Main.class"
140140
)
141141
}
@@ -163,12 +163,12 @@ class UriConverterTest {
163163

164164
onlyOnWindows {
165165
testIntellijToLsp(
166-
"file:///C%3A/path/with%20spaces/file.txt",
166+
"file:///c%3A/path/with%20spaces/file.txt",
167167
"file://c:/path/with spaces/file.txt"
168168
)
169169

170170
testIntellijToLsp(
171-
"file:///C%3A/path/with%23hash/file.txt",
171+
"file:///c%3A/path/with%23hash/file.txt",
172172
"file://c:/path/with#hash/file.txt"
173173
)
174174
}
@@ -340,12 +340,12 @@ class UriConverterTest {
340340
onlyOnWindows {
341341
run {
342342
val path = Path.of("c:\\path\\to\\jar.jar")
343-
assertEquals("jar:///C%3A/path/to/jar.jar!/", path.toLspUri().uri)
343+
assertEquals("jar:///c%3A/path/to/jar.jar!/", path.toLspUri().uri)
344344
}
345345

346346
run {
347347
val path = Path.of("d:\\path\\to\\nonJar.txt")
348-
assertEquals("file:///D%3A/path/to/nonJar.txt", path.toLspUri().uri)
348+
assertEquals("file:///d%3A/path/to/nonJar.txt", path.toLspUri().uri)
349349
}
350350
}
351351
}

0 commit comments

Comments
 (0)