CLI: load module-info from META-INF/versions/... for any version

Not just 9, since at least some libraries are putting module-info to
META-INF/versions/11 nowadays.

 #KT-48027 Fixed
This commit is contained in:
Alexander Udalov
2021-12-15 23:19:40 +01:00
parent f38e1b218d
commit 6acb0c3d06
2 changed files with 43 additions and 24 deletions
@@ -156,13 +156,11 @@ class ClasspathRootsResolver(
private fun modularBinaryRoot(root: VirtualFile): JavaModule? {
val isJar = root.fileSystem.protocol == StandardFileSystems.JAR_PROTOCOL
val manifest: Attributes? by lazy(NONE) { readManifestAttributes(root) }
val manifest = lazy(NONE) { readManifestAttributes(root) }
val moduleInfoFile =
root.findChild(PsiJavaModule.MODULE_INFO_CLS_FILE)
?: root.takeIf { isJar }?.findFileByRelativePath(MULTI_RELEASE_MODULE_INFO_CLS_FILE)?.takeIf {
manifest?.getValue(IS_MULTI_RELEASE)?.equals("true", ignoreCase = true) == true
}
?: if (isJar) tryLoadVersionSpecificModuleInfo(root, manifest) else null
if (moduleInfoFile != null) {
val moduleInfo = JavaModuleInfo.read(moduleInfoFile, javaFileManager, searchScope) ?: return null
@@ -173,7 +171,7 @@ class ClasspathRootsResolver(
if (isJar) {
val moduleRoot = listOf(JavaModule.Root(root, isBinary = true))
val automaticModuleName = manifest?.getValue(AUTOMATIC_MODULE_NAME)
val automaticModuleName = manifest.value?.getValue(AUTOMATIC_MODULE_NAME)
if (automaticModuleName != null) {
return JavaModule.Automatic(automaticModuleName, moduleRoot)
}
@@ -190,6 +188,23 @@ class ClasspathRootsResolver(
return null
}
private fun tryLoadVersionSpecificModuleInfo(root: VirtualFile, manifest: Lazy<Attributes?>): VirtualFile? {
val versionsDir = root.findChild("META-INF")?.findChild("versions") ?: return null
val isMultiReleaseJar = manifest.value?.getValue(IS_MULTI_RELEASE)?.equals("true", ignoreCase = true)
if (isMultiReleaseJar != true) return null
val versions = versionsDir.children.filter {
val version = it.name.toIntOrNull()
version != null && version >= 9
}.sortedBy { it.name.toInt() }
for (version in versions) {
val file = version.findChild(PsiJavaModule.MODULE_INFO_CLS_FILE)
if (file != null) return file
}
return null
}
private fun readManifestAttributes(jarRoot: VirtualFile): Attributes? {
val manifestFile = jarRoot.findChild("META-INF")?.findChild("MANIFEST.MF")
return try {
@@ -323,7 +338,6 @@ class ClasspathRootsResolver(
}
private companion object {
const val MULTI_RELEASE_MODULE_INFO_CLS_FILE = "META-INF/versions/9/${PsiJavaModule.MODULE_INFO_CLS_FILE}"
const val AUTOMATIC_MODULE_NAME = "Automatic-Module-Name"
const val IS_MULTI_RELEASE = "Multi-Release"
}