Skip to content

Commit 773db1d

Browse files
committed
Factor out ClassPathSourceJarProvider
1 parent 06f8ba9 commit 773db1d

File tree

7 files changed

+45
-34
lines changed

7 files changed

+45
-34
lines changed

server/src/main/kotlin/org/javacs/kt/KotlinLanguageServer.kt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import org.eclipse.lsp4j.services.LanguageClientAware
88
import org.eclipse.lsp4j.services.LanguageServer
99
import org.javacs.kt.commands.ALL_COMMANDS
1010
import org.javacs.kt.externalsources.JarClassContentProvider
11+
import org.javacs.kt.externalsources.ClassPathSourceJarProvider
1112
import org.javacs.kt.util.AsyncExecutor
1213
import org.javacs.kt.util.TemporaryDirectory
1314
import org.javacs.kt.util.parseURI
@@ -24,11 +25,11 @@ class KotlinLanguageServer : LanguageServer, LanguageClientAware, Closeable {
2425
val classPath = CompilerClassPath(config.compiler)
2526

2627
private val tempDirectory = TemporaryDirectory()
27-
private val uriContentProvider = URIContentProvider(JarClassContentProvider(config.externalSources, classPath, tempDirectory))
28+
private val uriContentProvider = URIContentProvider(JarClassContentProvider(config.externalSources, classPath, tempDirectory, ClassPathSourceJarProvider(classPath)))
2829
val sourcePath = SourcePath(classPath, uriContentProvider, config.indexing)
2930
val sourceFiles = SourceFiles(sourcePath, uriContentProvider)
3031

31-
private val textDocuments = KotlinTextDocumentService(sourceFiles, sourcePath, classPath, config, tempDirectory, uriContentProvider)
32+
private val textDocuments = KotlinTextDocumentService(sourceFiles, sourcePath, config, tempDirectory, uriContentProvider)
3233
private val workspaces = KotlinWorkspaceService(sourceFiles, sourcePath, classPath, textDocuments, config)
3334
private val protocolExtensions = KotlinProtocolExtensionService(uriContentProvider)
3435

server/src/main/kotlin/org/javacs/kt/KotlinTextDocumentService.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ import java.util.concurrent.CompletableFuture
3636
class KotlinTextDocumentService(
3737
private val sf: SourceFiles,
3838
private val sp: SourcePath,
39-
private val classPath: CompilerClassPath,
4039
private val config: Configuration,
4140
private val tempDirectory: TemporaryDirectory,
4241
private val uriContentProvider: URIContentProvider
@@ -125,7 +124,7 @@ class KotlinTextDocumentService(
125124
LOG.info("Go-to-definition at {}", describePosition(position))
126125

127126
val (file, cursor) = recover(position, Recompile.NEVER)
128-
goToDefinition(file, cursor, uriContentProvider.jarClassContentProvider, tempDirectory, config.externalSources, classPath.classPath)
127+
goToDefinition(file, cursor, uriContentProvider.jarClassContentProvider, tempDirectory, config.externalSources)
129128
?.let(::listOf)
130129
?.let { Either.forLeft<List<Location>, List<LocationLink>>(it) }
131130
?: noResult("Couldn't find definition at ${describePosition(position)}", Either.forLeft(emptyList()))

server/src/main/kotlin/org/javacs/kt/definition/GoToDefinition.kt

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,7 @@ fun goToDefinition(
2828
cursor: Int,
2929
jarClassContentProvider: JarClassContentProvider,
3030
tempDir: TemporaryDirectory,
31-
config: ExternalSourcesConfiguration,
32-
compilerClassPath: Set<ClassPathEntry>
31+
config: ExternalSourcesConfiguration
3332
): Location? {
3433
val (_, target) = file.referenceAtPoint(cursor) ?: return null
3534

@@ -45,9 +44,7 @@ fun goToDefinition(
4544
val rawClassURI = destination.uri
4645

4746
if (isInsideJar(rawClassURI)) {
48-
val sourceURI = getSourceURI(rawClassURI, compilerClassPath)
49-
val actualClassURI = sourceURI ?: rawClassURI
50-
parseURI(actualClassURI).toKlsURI()?.let { klsURI ->
47+
parseURI(rawClassURI).toKlsURI()?.let { klsURI ->
5148
val (klsSourceURI, content) = jarClassContentProvider.contentOf(klsURI)
5249

5350
if (config.useKlsScheme) {
@@ -90,13 +87,4 @@ fun goToDefinition(
9087
return destination
9188
}
9289

93-
private fun getSourceURI(rawClassURI: String, compilerClassPath: Set<ClassPathEntry>): String? {
94-
val rawClassPath = parseURI(rawClassURI).path.toString()
95-
val jarUri = rawClassPath.substring(0, rawClassPath.indexOf("!"))
96-
val classPartUri = rawClassPath.substring(rawClassPath.indexOf("!"))
97-
val sourceJar = compilerClassPath.find { it.compiledJar.toUri().path == jarUri }?.sourceJar
98-
99-
return if (sourceJar != null) sourceJar.toUri().toString() + classPartUri else null
100-
}
101-
10290
private fun isInsideJar(uri: String) = uri.contains(".jar!")
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package org.javacs.kt.externalsources
2+
3+
import org.javacs.kt.CompilerClassPath
4+
import java.nio.file.Path
5+
6+
class ClassPathSourceJarProvider(
7+
private val cp: CompilerClassPath
8+
) : SourceJarProvider {
9+
override fun fetchSourceJar(compiledJar: Path): Path? =
10+
cp.classPath.firstOrNull { it.compiledJar == compiledJar }?.sourceJar
11+
}

server/src/main/kotlin/org/javacs/kt/externalsources/JarClassContentProvider.kt

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ class JarClassContentProvider(
2020
private val config: ExternalSourcesConfiguration,
2121
private val cp: CompilerClassPath,
2222
private val tempDir: TemporaryDirectory,
23+
private val sourceJarProvider: SourceJarProvider,
2324
private val decompiler: Decompiler = FernflowerDecompiler()
2425
) {
2526
/** Maps recently used (source-)KLS-URIs to their source contents (e.g. decompiled code) and the file extension. */
@@ -34,17 +35,18 @@ class JarClassContentProvider(
3435
* If the file is inside a source JAR, the source code is returned as is.
3536
*/
3637
public fun contentOf(uri: KlsURI): Pair<KlsURI, String> {
37-
val key = uri.toString()
38+
val resolvedUri = sourceJarProvider.fetchSourceJar(uri.jarPath)?.let(uri::withJarPath) ?: uri
39+
val key = resolvedUri.toString()
3840
val (contents, extension) = cachedContents[key] ?: run {
3941
LOG.info("Finding contents of {}", describeURI(uri.fileUri))
40-
tryReadContentOf(uri)
41-
?: tryReadContentOf(uri.withFileExtension("class"))
42-
?: tryReadContentOf(uri.withFileExtension("java"))
43-
?: tryReadContentOf(uri.withFileExtension("kt"))
42+
tryReadContentOf(resolvedUri)
43+
?: tryReadContentOf(resolvedUri.withFileExtension("class"))
44+
?: tryReadContentOf(resolvedUri.withFileExtension("java"))
45+
?: tryReadContentOf(resolvedUri.withFileExtension("kt"))
4446
?: throw KotlinLSException("Could not find $uri")
4547
}.also { cachedContents[key] = it }
46-
val sourceURI = uri.withFileExtension(extension)
47-
return Pair(sourceURI, contents)
48+
val sourceUri = resolvedUri.withFileExtension(extension)
49+
return Pair(sourceUri, contents)
4850
}
4951

5052
private fun convertToKotlinIfNeeded(javaCode: String): String = if (config.autoConvertToKotlin) {

server/src/main/kotlin/org/javacs/kt/externalsources/KlsURI.kt

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import java.net.JarURLConnection
88
import java.io.BufferedReader
99
import java.nio.file.Path
1010
import java.nio.file.Files
11+
import java.nio.file.Paths
1112

1213
fun URI.toKlsURI(): KlsURI? = when (scheme) {
1314
"kls" -> KlsURI(URI("kls:$schemeSpecificPart"))
@@ -41,21 +42,32 @@ data class KlsURI(val fileUri: URI, val query: Map<QueryParam, Any>) {
4142
}
4243
}
4344

45+
private val queryString: String
46+
get() = if (query.isEmpty()) "" else query.entries.fold("?") { accum, next -> "$accum${next.key}=${next.value}" }
47+
4448
val fileName: String
4549
get() = fileUri.toString().substringAfterLast("/")
4650
val fileExtension: String?
4751
get() = fileName
4852
.split(".")
4953
.takeIf { it.size > 1 }
5054
?.lastOrNull()
51-
private val queryString get() = if (query.isEmpty()) "" else query.entries.fold("?") { accum, next -> "$accum${next.key}=${next.value}" }
52-
private val uri: URI get() = URI(fileUri.toString() + queryString)
53-
val source: Boolean get() = query[QueryParam.SOURCE] as? Boolean ?: false
55+
56+
val jarPath: Path
57+
get() = Paths.get(fileUri.path.split("!")[0])
58+
val innerPath: String?
59+
get() = fileUri.path.split("!", limit = 2).get(1)
60+
61+
val source: Boolean
62+
get() = query[QueryParam.SOURCE] as? Boolean ?: false
5463
val isCompiled: Boolean
5564
get() = fileExtension == "class"
5665

5766
constructor(uri: URI) : this(parseKlsURIFileURI(uri), parseKlsURIQuery(uri))
5867

68+
fun withJarPath(newJarPath: Path): KlsURI =
69+
KlsURI(URI(newJarPath.toUri().toString() + (innerPath?.let { "!$it" } ?: "")), query)
70+
5971
fun withFileExtension(newExtension: String): KlsURI {
6072
val (parentUri, fileName) = fileUri.toString().partitionAroundLast("/")
6173
val newUri = URI("$parentUri${fileName.split(".").first()}.$newExtension")
@@ -69,11 +81,9 @@ data class KlsURI(val fileUri: URI, val query: Map<QueryParam, Any>) {
6981
return KlsURI(fileUri, newQuery)
7082
}
7183

72-
fun withoutQuery(): KlsURI = KlsURI(fileUri, mapOf())
73-
74-
fun toFileURI(): URI = URI(uri.schemeSpecificPart)
84+
fun toURI(): URI = URI(fileUri.toString() + queryString)
7585

76-
private fun toJarURL(): URL = URL("jar:${uri.schemeSpecificPart}")
86+
private fun toJarURL(): URL = URL("jar:${toURI().schemeSpecificPart}")
7787

7888
private fun openJarURLConnection() = toJarURL().openConnection() as JarURLConnection
7989

@@ -105,7 +115,7 @@ data class KlsURI(val fileUri: URI, val query: Map<QueryParam, Any>) {
105115
tmpFile
106116
}
107117

108-
override fun toString(): String = uri.toString()
118+
override fun toString(): String = toURI().toString()
109119
}
110120

111121
private fun parseKlsURIFileURI(uri: URI): URI = URI(uri.toString().split("?")[0])

server/src/main/kotlin/org/javacs/kt/externalsources/SourceJarProvider.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@ package org.javacs.kt.externalsources
33
import java.nio.file.Path
44

55
interface SourceJarProvider {
6-
fun fetchSourceJar(compiledJar: Path): Path
6+
fun fetchSourceJar(compiledJar: Path): Path?
77
}

0 commit comments

Comments
 (0)