AA: restore JavaRoot from binary roots in JDK module
This commit is contained in:
committed by
Ilya Kirillov
parent
911963bafd
commit
814920b344
+41
-10
@@ -28,6 +28,7 @@ import org.jetbrains.kotlin.cli.jvm.index.JvmDependenciesIndexImpl
|
|||||||
import org.jetbrains.kotlin.cli.jvm.index.SingleJavaFileRootsIndex
|
import org.jetbrains.kotlin.cli.jvm.index.SingleJavaFileRootsIndex
|
||||||
import org.jetbrains.kotlin.cli.jvm.modules.CliJavaModuleFinder
|
import org.jetbrains.kotlin.cli.jvm.modules.CliJavaModuleFinder
|
||||||
import org.jetbrains.kotlin.cli.jvm.modules.CliJavaModuleResolver
|
import org.jetbrains.kotlin.cli.jvm.modules.CliJavaModuleResolver
|
||||||
|
import org.jetbrains.kotlin.cli.jvm.modules.CoreJrtFileSystem
|
||||||
import org.jetbrains.kotlin.cli.jvm.modules.JavaModuleGraph
|
import org.jetbrains.kotlin.cli.jvm.modules.JavaModuleGraph
|
||||||
import org.jetbrains.kotlin.config.*
|
import org.jetbrains.kotlin.config.*
|
||||||
import org.jetbrains.kotlin.load.kotlin.MetadataFinderFactory
|
import org.jetbrains.kotlin.load.kotlin.MetadataFinderFactory
|
||||||
@@ -155,16 +156,7 @@ object StandaloneProjectFactory {
|
|||||||
environment: KotlinCoreProjectEnvironment
|
environment: KotlinCoreProjectEnvironment
|
||||||
): List<JavaRoot> = withAllTransitiveDependencies(modules)
|
): List<JavaRoot> = withAllTransitiveDependencies(modules)
|
||||||
.filterIsInstance<KtBinaryModule>()
|
.filterIsInstance<KtBinaryModule>()
|
||||||
.flatMap { it.getBinaryRoots() }
|
.flatMap { it.getJavaRoots(environment) }
|
||||||
.mapNotNull { path ->
|
|
||||||
val pathString = path.toAbsolutePath().toString()
|
|
||||||
val jar =
|
|
||||||
if (pathString.endsWith(JAR_PROTOCOL))
|
|
||||||
environment.environment.jarFileSystem.findFileByPath(pathString + JAR_SEPARATOR)
|
|
||||||
else null
|
|
||||||
if (jar == null) return@mapNotNull null
|
|
||||||
JavaRoot(jar, JavaRoot.RootType.BINARY)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun withAllTransitiveDependencies(ktModules: List<KtModule>): List<KtModule> {
|
private fun withAllTransitiveDependencies(ktModules: List<KtModule>): List<KtModule> {
|
||||||
val visited = hashSetOf<KtModule>()
|
val visited = hashSetOf<KtModule>()
|
||||||
@@ -194,6 +186,45 @@ object StandaloneProjectFactory {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun KtBinaryModule.getJavaRoots(
|
||||||
|
environment: KotlinCoreProjectEnvironment,
|
||||||
|
): List<JavaRoot> {
|
||||||
|
return buildList {
|
||||||
|
getBinaryRoots().forEach { path ->
|
||||||
|
val pathString = path.toAbsolutePath().toString()
|
||||||
|
when {
|
||||||
|
pathString.endsWith(JAR_PROTOCOL) -> {
|
||||||
|
environment.environment.jarFileSystem.findFileByPath(pathString + JAR_SEPARATOR)
|
||||||
|
}
|
||||||
|
pathString.contains(JAR_SEPARATOR) -> {
|
||||||
|
environment.environment.jrtFileSystem?.findFileByPath(adjustModulePath(pathString))
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}?.let { root ->
|
||||||
|
add(JavaRoot(root, JavaRoot.RootType.BINARY))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun adjustModulePath(pathString: String): String {
|
||||||
|
return if (pathString.contains(JAR_SEPARATOR)) {
|
||||||
|
// URLs loaded from JDK point to module names in a JRT protocol format,
|
||||||
|
// e.g., "jrt:///path/to/jdk/home!/java.base" (JRT protocol prefix + JDK home path + JAR separator + module name)
|
||||||
|
// After protocol erasure, we will see "/path/to/jdk/home!/java.base" as a binary root.
|
||||||
|
// CoreJrtFileSystem.CoreJrtHandler#findFile, which uses Path#resolve, finds a virtual file path to the file itself,
|
||||||
|
// e.g., "/path/to/jdk/home!/modules/java.base". (JDK home path + JAR separator + actual file path)
|
||||||
|
// To work with that JRT handler, a hacky workaround here is to add "modules" before the module name so that it can
|
||||||
|
// find the actual file path.
|
||||||
|
// See [LLFirJavaFacadeForBinaries#getBinaryPath] for a similar hack.
|
||||||
|
val (libHomePath, pathInImage) = CoreJrtFileSystem.splitPath(pathString)
|
||||||
|
libHomePath + JAR_SEPARATOR + "modules/$pathInImage"
|
||||||
|
} else
|
||||||
|
pathString
|
||||||
|
}
|
||||||
|
|
||||||
fun createPackagePartsProvider(
|
fun createPackagePartsProvider(
|
||||||
project: MockProject,
|
project: MockProject,
|
||||||
libraryRoots: List<JavaRoot>,
|
libraryRoots: List<JavaRoot>,
|
||||||
|
|||||||
+1
@@ -48,6 +48,7 @@ internal class LLFirJavaFacadeForBinaries(
|
|||||||
// To work with LibraryPathFilter, a hacky workaround here is to remove "modules/" from actual file path.
|
// To work with LibraryPathFilter, a hacky workaround here is to remove "modules/" from actual file path.
|
||||||
// e.g. "/path/to/jdk/home!/java.base/java/lang/Object.class", which, from Path viewpoint, belongs to "/java.base",
|
// e.g. "/path/to/jdk/home!/java.base/java/lang/Object.class", which, from Path viewpoint, belongs to "/java.base",
|
||||||
// after splitting at the JAR separator, in a similar way.
|
// after splitting at the JAR separator, in a similar way.
|
||||||
|
// See [StandaloneProjectFactory#getAllBinaryRoots] for a similar hack.
|
||||||
Paths.get(path.replace("modules/", ""))
|
Paths.get(path.replace("modules/", ""))
|
||||||
}
|
}
|
||||||
else ->
|
else ->
|
||||||
|
|||||||
Reference in New Issue
Block a user