Do not read module mappings more than once

This commit is contained in:
Denis Zharkov
2016-02-23 12:41:10 +03:00
parent 3652cd9c18
commit 26ebf46e3e
@@ -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()
} }
} }