Do not read module mappings more than once
This commit is contained in:
@@ -17,6 +17,7 @@
|
|||||||
package org.jetbrains.kotlin.cli.jvm.compiler
|
package org.jetbrains.kotlin.cli.jvm.compiler
|
||||||
|
|
||||||
import com.intellij.openapi.vfs.VirtualFile
|
import com.intellij.openapi.vfs.VirtualFile
|
||||||
|
import com.intellij.util.SmartList
|
||||||
import org.jetbrains.kotlin.cli.jvm.config.JvmClasspathRoot
|
import org.jetbrains.kotlin.cli.jvm.config.JvmClasspathRoot
|
||||||
import org.jetbrains.kotlin.config.CommonConfigurationKeys
|
import org.jetbrains.kotlin.config.CommonConfigurationKeys
|
||||||
import org.jetbrains.kotlin.descriptors.PackagePartProvider
|
import org.jetbrains.kotlin.descriptors.PackagePartProvider
|
||||||
@@ -24,18 +25,29 @@ import org.jetbrains.kotlin.load.kotlin.ModuleMapping
|
|||||||
import java.io.EOFException
|
import java.io.EOFException
|
||||||
|
|
||||||
class JvmPackagePartProvider(val env: KotlinCoreEnvironment) : PackagePartProvider {
|
class JvmPackagePartProvider(val env: KotlinCoreEnvironment) : PackagePartProvider {
|
||||||
|
private val notLoadedRoots by lazy(LazyThreadSafetyMode.NONE) {
|
||||||
val roots by lazy {
|
|
||||||
env.configuration.getList(CommonConfigurationKeys.CONTENT_ROOTS).
|
env.configuration.getList(CommonConfigurationKeys.CONTENT_ROOTS).
|
||||||
filterIsInstance<JvmClasspathRoot>().
|
filterIsInstance<JvmClasspathRoot>().
|
||||||
mapNotNull {
|
mapNotNull {
|
||||||
env.contentRootToVirtualFile(it);
|
env.contentRootToVirtualFile(it);
|
||||||
}.filter { it.findChild("META-INF") != null }
|
}.filter { it.findChild("META-INF") != null }.toMutableList()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val loadedModules: MutableList<ModuleMapping> = SmartList()
|
||||||
|
|
||||||
|
@Synchronized
|
||||||
override fun findPackageParts(packageFqName: String): List<String> {
|
override fun findPackageParts(packageFqName: String): List<String> {
|
||||||
|
processNotLoadedRelevantRoots(packageFqName)
|
||||||
|
|
||||||
|
return loadedModules.flatMap { it.findPackageParts(packageFqName)?.parts ?: emptySet<String>() }.distinct()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun processNotLoadedRelevantRoots(packageFqName: String) {
|
||||||
|
if (notLoadedRoots.isEmpty()) return
|
||||||
|
|
||||||
val pathParts = packageFqName.split('.')
|
val pathParts = packageFqName.split('.')
|
||||||
val mappings = roots.filter {
|
|
||||||
|
val relevantRoots = notLoadedRoots.filter {
|
||||||
//filter all roots by package path existing
|
//filter all roots by package path existing
|
||||||
pathParts.fold(it) {
|
pathParts.fold(it) {
|
||||||
parent, part ->
|
parent, part ->
|
||||||
@@ -43,7 +55,10 @@ class JvmPackagePartProvider(val env: KotlinCoreEnvironment) : PackagePartProvid
|
|||||||
else parent.findChild(part) ?: return@filter false
|
else parent.findChild(part) ?: return@filter false
|
||||||
}
|
}
|
||||||
true
|
true
|
||||||
}.mapNotNull {
|
}
|
||||||
|
notLoadedRoots.removeAll(relevantRoots)
|
||||||
|
|
||||||
|
loadedModules.addAll(relevantRoots.mapNotNull {
|
||||||
it.findChild("META-INF")
|
it.findChild("META-INF")
|
||||||
}.flatMap {
|
}.flatMap {
|
||||||
it.children.filter<VirtualFile> { it.name.endsWith(ModuleMapping.MAPPING_FILE_EXT) }
|
it.children.filter<VirtualFile> { it.name.endsWith(ModuleMapping.MAPPING_FILE_EXT) }
|
||||||
@@ -51,10 +66,8 @@ class JvmPackagePartProvider(val env: KotlinCoreEnvironment) : PackagePartProvid
|
|||||||
try {
|
try {
|
||||||
ModuleMapping.create(it.contentsToByteArray())
|
ModuleMapping.create(it.contentsToByteArray())
|
||||||
} catch (e: EOFException) {
|
} catch (e: EOFException) {
|
||||||
throw RuntimeException("Error on reading package parts for '$packageFqName' package in '$it', roots: $roots", e)
|
throw RuntimeException("Error on reading package parts for '$packageFqName' package in '$it', roots: $notLoadedRoots", e)
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
|
|
||||||
return mappings.mapNotNull { it.findPackageParts(packageFqName) }.flatMap { it.parts }.distinct()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user