Allow customizing source file path conversion in local IC caches

This commit is contained in:
Alexey Tsvetkov
2019-04-12 16:35:23 +03:00
parent 146eebdc7e
commit 79337a6b96
13 changed files with 191 additions and 74 deletions
@@ -45,7 +45,10 @@ interface IncrementalCacheCommon {
/**
* Incremental cache common for JVM and JS for specifit ClassName type
*/
abstract class AbstractIncrementalCache<ClassName>(workingDir: File) : BasicMapsOwner(workingDir), IncrementalCacheCommon {
abstract class AbstractIncrementalCache<ClassName>(
workingDir: File,
protected val sourcePathConverter: SourceFileToPathConverter
) : BasicMapsOwner(workingDir), IncrementalCacheCommon {
companion object {
private val SUBTYPES = "subtypes"
private val SUPERTYPES = "supertypes"
@@ -70,17 +73,16 @@ abstract class AbstractIncrementalCache<ClassName>(workingDir: File) : BasicMaps
private val subtypesMap = registerMap(SubtypesMap(SUBTYPES.storageFile))
private val supertypesMap = registerMap(SupertypesMap(SUPERTYPES.storageFile))
protected val classFqNameToSourceMap = registerMap(ClassFqNameToSourceMap(CLASS_FQ_NAME_TO_SOURCE.storageFile))
protected val classFqNameToSourceMap = registerMap(ClassFqNameToSourceMap(CLASS_FQ_NAME_TO_SOURCE.storageFile, sourcePathConverter))
internal abstract val sourceToClassesMap: AbstractSourceToOutputMap<ClassName>
internal abstract val dirtyOutputClassesMap: AbstractDirtyClassesMap<ClassName>
/**
* A file X is a complementary to a file Y if they contain corresponding expect/actual declarations.
* Complementary files should be compiled together during IC so the compiler does not complain
* about missing parts.
* TODO: provide a better solution (maintain an index of expect/actual declarations akin to IncrementalPackagePartProvider)
*/
private val complementaryFilesMap = registerMap(FilesMap(COMPLEMENTARY_FILES.storageFile))
private val complementaryFilesMap = registerMap(ComplementarySourceFilesMap(COMPLEMENTARY_FILES.storageFile, sourcePathConverter))
override fun classesFqNamesBySources(files: Iterable<File>): Collection<FqName> =
files.flatMapTo(HashSet()) { sourceToClassesMap.getFqNames(it) }
@@ -153,14 +155,17 @@ abstract class AbstractIncrementalCache<ClassName>(workingDir: File) : BasicMaps
removedFqNames.forEach { classFqNameToSourceMap.remove(it) }
}
protected class ClassFqNameToSourceMap(storageFile: File) :
protected class ClassFqNameToSourceMap(
storageFile: File,
private val sourcePathConverter: SourceFileToPathConverter
) :
BasicStringMap<String>(storageFile, EnumeratorStringDescriptor(), PathStringDescriptor) {
operator fun set(fqName: FqName, sourceFile: File) {
storage[fqName.asString()] = sourceFile.canonicalPath
storage[fqName.asString()] = sourcePathConverter.toPath(sourceFile)
}
operator fun get(fqName: FqName): File? =
storage[fqName.asString()]?.let(::File)
storage[fqName.asString()]?.let(sourcePathConverter::toFile)
fun remove(fqName: FqName) {
storage.remove(fqName.asString())
@@ -19,10 +19,7 @@ package org.jetbrains.kotlin.incremental
import com.intellij.util.io.DataExternalizer
import org.jetbrains.kotlin.incremental.js.IncrementalResultsConsumerImpl
import org.jetbrains.kotlin.incremental.js.TranslationResultValue
import org.jetbrains.kotlin.incremental.storage.BasicStringMap
import org.jetbrains.kotlin.incremental.storage.DirtyClassesFqNameMap
import org.jetbrains.kotlin.incremental.storage.SourceToFqNameMap
import org.jetbrains.kotlin.incremental.storage.StringToLongMapExternalizer
import org.jetbrains.kotlin.incremental.storage.*
import org.jetbrains.kotlin.metadata.ProtoBuf
import org.jetbrains.kotlin.metadata.deserialization.NameResolverImpl
import org.jetbrains.kotlin.metadata.deserialization.getExtensionOrNull
@@ -36,19 +33,22 @@ import java.io.DataInput
import java.io.DataOutput
import java.io.File
open class IncrementalJsCache(cachesDir: File) : AbstractIncrementalCache<FqName>(cachesDir) {
open class IncrementalJsCache(
cachesDir: File,
sourcePathConverter: SourceFileToPathConverter
) : AbstractIncrementalCache<FqName>(cachesDir, sourcePathConverter) {
companion object {
private val TRANSLATION_RESULT_MAP = "translation-result"
private val INLINE_FUNCTIONS = "inline-functions"
private val HEADER_FILE_NAME = "header.meta"
private const val TRANSLATION_RESULT_MAP = "translation-result"
private const val INLINE_FUNCTIONS = "inline-functions"
private const val HEADER_FILE_NAME = "header.meta"
fun hasHeaderFile(cachesDir: File) = File(cachesDir, HEADER_FILE_NAME).exists()
}
override val sourceToClassesMap = registerMap(SourceToFqNameMap(SOURCE_TO_CLASSES.storageFile))
override val sourceToClassesMap = registerMap(SourceToFqNameMap(SOURCE_TO_CLASSES.storageFile, sourcePathConverter))
override val dirtyOutputClassesMap = registerMap(DirtyClassesFqNameMap(DIRTY_OUTPUT_CLASSES.storageFile))
private val translationResults = registerMap(TranslationResultMap(TRANSLATION_RESULT_MAP.storageFile))
private val inlineFunctions = registerMap(InlineFunctionsMap(INLINE_FUNCTIONS.storageFile))
private val translationResults = registerMap(TranslationResultMap(TRANSLATION_RESULT_MAP.storageFile, sourcePathConverter))
private val inlineFunctions = registerMap(InlineFunctionsMap(INLINE_FUNCTIONS.storageFile, sourcePathConverter))
private val dirtySources = hashSetOf<File>()
@@ -113,14 +113,14 @@ open class IncrementalJsCache(cachesDir: File) : AbstractIncrementalCache<FqName
}
fun nonDirtyPackageParts(): Map<File, TranslationResultValue> =
hashMapOf<File, TranslationResultValue>().apply {
for (path in translationResults.keys()) {
val file = File(path)
if (file !in dirtySources) {
put(file, translationResults[path]!!)
}
hashMapOf<File, TranslationResultValue>().apply {
for (path in translationResults.keys()) {
val file = File(path)
if (file !in dirtySources) {
put(file, translationResults[file]!!)
}
}
}
}
private object TranslationResultValueExternalizer : DataExternalizer<TranslationResultValue> {
@@ -152,31 +152,33 @@ private object TranslationResultValueExternalizer : DataExternalizer<Translation
}
}
private class TranslationResultMap(storageFile: File) : BasicStringMap<TranslationResultValue>(storageFile, TranslationResultValueExternalizer) {
private class TranslationResultMap(
storageFile: File,
private val sourcePathConverter: SourceFileToPathConverter
) : BasicStringMap<TranslationResultValue>(storageFile, TranslationResultValueExternalizer) {
override fun dumpValue(value: TranslationResultValue): String =
"Metadata: ${value.metadata.md5()}, Binary AST: ${value.binaryAst.md5()}, InlineData: ${value.inlineData.md5()}"
"Metadata: ${value.metadata.md5()}, Binary AST: ${value.binaryAst.md5()}, InlineData: ${value.inlineData.md5()}"
fun put(file: File, newMetadata: ByteArray, newBinaryAst: ByteArray, newInlineData: ByteArray) {
storage[file.canonicalPath] = TranslationResultValue(metadata = newMetadata, binaryAst = newBinaryAst, inlineData = newInlineData)
fun put(sourceFile: File, newMetadata: ByteArray, newBinaryAst: ByteArray, newInlineData: ByteArray) {
storage[sourcePathConverter.toPath(sourceFile)] =
TranslationResultValue(metadata = newMetadata, binaryAst = newBinaryAst, inlineData = newInlineData)
}
operator fun get(file: File): TranslationResultValue? =
storage[file.canonicalPath]
operator fun get(key: String): TranslationResultValue? =
storage[key]
operator fun get(sourceFile: File): TranslationResultValue? =
storage[sourcePathConverter.toPath(sourceFile)]
fun keys(): Collection<String> =
storage.keys
storage.keys
fun remove(file: File, changesCollector: ChangesCollector) {
val protoBytes = storage[file.canonicalPath]!!.metadata
val protoMap = getProtoData(file, protoBytes)
fun remove(sourceFile: File, changesCollector: ChangesCollector) {
val path = sourcePathConverter.toPath(sourceFile)
val protoBytes = storage[path]!!.metadata
val protoMap = getProtoData(sourceFile, protoBytes)
for ((_, protoData) in protoMap) {
changesCollector.collectProtoChanges(oldData = protoData, newData = null)
}
storage.remove(file.canonicalPath)
storage.remove(path)
}
}
@@ -199,15 +201,17 @@ fun getProtoData(sourceFile: File, metadata: ByteArray): Map<ClassId, ProtoData>
return classes
}
private class InlineFunctionsMap(storageFile: File) : BasicStringMap<Map<String, Long>>(storageFile, StringToLongMapExternalizer) {
private class InlineFunctionsMap(
storageFile: File,
private val sourcePathConverter: SourceFileToPathConverter
) : BasicStringMap<Map<String, Long>>(storageFile, StringToLongMapExternalizer) {
fun process(srcFile: File, newMap: Map<String, Long>, changesCollector: ChangesCollector) {
val key = srcFile.canonicalPath
val key = sourcePathConverter.toPath(srcFile)
val oldMap = storage[key] ?: emptyMap()
if (newMap.isNotEmpty()) {
storage[key] = newMap
}
else {
} else {
storage.remove(key)
}
@@ -219,9 +223,9 @@ private class InlineFunctionsMap(storageFile: File) : BasicStringMap<Map<String,
}
fun remove(sourceFile: File) {
storage.remove(sourceFile.canonicalPath)
storage.remove(sourcePathConverter.toPath(sourceFile))
}
override fun dumpValue(value: Map<String, Long>): String =
value.dumpMap { java.lang.Long.toHexString(it) }
value.dumpMap { java.lang.Long.toHexString(it) }
}
@@ -43,8 +43,12 @@ val KOTLIN_CACHE_DIRECTORY_NAME = "kotlin"
open class IncrementalJvmCache(
private val targetDataRoot: File,
targetOutputDir: File?
) : AbstractIncrementalCache<JvmClassName>(File(targetDataRoot, KOTLIN_CACHE_DIRECTORY_NAME)), IncrementalCache {
targetOutputDir: File?,
sourcePathConverter: SourceFileToPathConverter
) : AbstractIncrementalCache<JvmClassName>(
workingDir = File(targetDataRoot, KOTLIN_CACHE_DIRECTORY_NAME),
sourcePathConverter = sourcePathConverter
), IncrementalCache {
companion object {
private val PROTO_MAP = "proto"
private val CONSTANTS_MAP = "constants"
@@ -58,7 +62,7 @@ open class IncrementalJvmCache(
private val MODULE_MAPPING_FILE_NAME = "." + ModuleMapping.MAPPING_FILE_EXT
}
override val sourceToClassesMap = registerMap(SourceToJvmNameMap(SOURCE_TO_CLASSES.storageFile))
override val sourceToClassesMap = registerMap(SourceToJvmNameMap(SOURCE_TO_CLASSES.storageFile, sourcePathConverter))
override val dirtyOutputClassesMap = registerMap(DirtyClassesJvmNameMap(DIRTY_OUTPUT_CLASSES.storageFile))
private val protoMap = registerMap(ProtoMap(PROTO_MAP.storageFile))
@@ -68,7 +72,8 @@ open class IncrementalJvmCache(
private val partToMultifileFacade = registerMap(MultifileClassPartMap(MULTIFILE_CLASS_PARTS.storageFile))
private val inlineFunctionsMap = registerMap(InlineFunctionsMap(INLINE_FUNCTIONS.storageFile))
// todo: try to use internal names only?
private val internalNameToSource = registerMap(InternalNameToSourcesMap(INTERNAL_NAME_TO_SOURCE.storageFile))
private val internalNameToSource = registerMap(InternalNameToSourcesMap(INTERNAL_NAME_TO_SOURCE.storageFile, sourcePathConverter))
// gradle only
private val javaSourcesProtoMap = registerMap(JavaSourcesProtoMap(JAVA_SOURCES_PROTO_MAP.storageFile))
private val outputDir by lazy(LazyThreadSafetyMode.NONE) { requireNotNull(targetOutputDir) { "Target is expected to have output directory" } }
@@ -440,14 +445,16 @@ open class IncrementalJvmCache(
override fun dumpValue(value: String): String = value
}
inner class InternalNameToSourcesMap(storageFile: File) :
BasicStringMap<Collection<String>>(storageFile, EnumeratorStringDescriptor(), PathCollectionExternalizer) {
operator fun set(internalName: String, sourceFiles: Iterable<File>) {
storage[internalName] = sourceFiles.map { it.canonicalPath }
inner class InternalNameToSourcesMap(
storageFile: File,
private val sourcePathConverter: SourceFileToPathConverter
) : BasicStringMap<Collection<String>>(storageFile, EnumeratorStringDescriptor(), PathCollectionExternalizer) {
operator fun set(internalName: String, sourceFiles: Collection<File>) {
storage[internalName] = sourcePathConverter.toPaths(sourceFiles)
}
operator fun get(internalName: String): Collection<File> =
(storage[internalName] ?: emptyList()).map(::File)
sourcePathConverter.toFiles(storage[internalName] ?: emptyList())
fun remove(internalName: String) {
storage.remove(internalName)
@@ -0,0 +1,30 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.incremental.storage
import org.jetbrains.kotlin.incremental.dumpCollection
import java.io.File
class ComplementarySourceFilesMap(
storageFile: File,
private val sourcePathConverter: SourceFileToPathConverter
) : BasicStringMap<Collection<String>>(storageFile, PathStringDescriptor, StringCollectionExternalizer) {
operator fun set(sourceFile: File, complementaryFiles: Collection<File>) {
storage[sourcePathConverter.toPath(sourceFile)] = sourcePathConverter.toPaths(complementaryFiles)
}
operator fun get(sourceFile: File): Collection<File> {
val paths = storage[sourcePathConverter.toPath(sourceFile)].orEmpty()
return sourcePathConverter.toFiles(paths)
}
override fun dumpValue(value: Collection<String>) =
value.dumpCollection()
fun remove(file: File): Collection<File> =
get(file).also { storage.remove(sourcePathConverter.toPath(file)) }
}
@@ -0,0 +1,25 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.incremental.storage
import java.io.File
interface SourceFileToPathConverter {
fun toPath(file: File): String
fun toFile(path: String): File
}
fun SourceFileToPathConverter.toPaths(files: Collection<File>): List<String> =
files.map { toPath(it) }
fun SourceFileToPathConverter.toFiles(paths: Collection<String>): List<File> =
paths.map { toFile(it) }
object SourceFileToCanonicalPathConverter : SourceFileToPathConverter {
override fun toPath(file: File): String = file.canonicalPath
override fun toFile(path: String): File = File(path)
}
@@ -21,32 +21,40 @@ import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
import java.io.File
internal class SourceToJvmNameMap(storageFile: File) : AbstractSourceToOutputMap<JvmClassName>(JvmClassNameTransformer, storageFile)
internal class SourceToFqNameMap(storageFile: File) : AbstractSourceToOutputMap<FqName>(FqNameTransformer, storageFile)
internal class SourceToJvmNameMap(
storageFile: File,
sourcePathConverter: SourceFileToPathConverter
) : AbstractSourceToOutputMap<JvmClassName>(JvmClassNameTransformer, storageFile, sourcePathConverter)
internal class SourceToFqNameMap(
storageFile: File,
sourcePathConverter: SourceFileToPathConverter
) : AbstractSourceToOutputMap<FqName>(FqNameTransformer, storageFile, sourcePathConverter)
internal abstract class AbstractSourceToOutputMap<Name>(
private val nameTransformer: NameTransformer<Name>,
storageFile: File
private val nameTransformer: NameTransformer<Name>,
storageFile: File,
private val sourcePathConverter: SourceFileToPathConverter
) : BasicStringMap<Collection<String>>(storageFile, PathStringDescriptor, StringCollectionExternalizer) {
fun clearOutputsForSource(sourceFile: File) {
remove(sourceFile.absolutePath)
remove(sourcePathConverter.toPath(sourceFile))
}
fun add(sourceFile: File, className: Name) {
storage.append(sourceFile.absolutePath, nameTransformer.asString(className))
storage.append(sourcePathConverter.toPath(sourceFile), nameTransformer.asString(className))
}
fun contains(sourceFile: File): Boolean =
sourceFile.absolutePath in storage
sourcePathConverter.toPath(sourceFile) in storage
operator fun get(sourceFile: File): Collection<Name> =
storage[sourceFile.absolutePath].orEmpty().map(nameTransformer::asName)
storage[sourcePathConverter.toPath(sourceFile)].orEmpty().map(nameTransformer::asName)
fun getFqNames(sourceFile: File): Collection<FqName> =
storage[sourceFile.absolutePath].orEmpty().map(nameTransformer::asFqName)
storage[sourcePathConverter.toPath(sourceFile)].orEmpty().map(nameTransformer::asFqName)
override fun dumpValue(value: Collection<String>) =
value.dumpCollection()
value.dumpCollection()
private fun remove(path: String) {
storage.remove(path)
@@ -17,8 +17,11 @@
package org.jetbrains.kotlin.incremental
import org.jetbrains.kotlin.incremental.storage.BasicMapsOwner
import org.jetbrains.kotlin.incremental.storage.SourceFileToCanonicalPathConverter
import java.io.File
private val PATH_CONVERTER = SourceFileToCanonicalPathConverter
abstract class IncrementalCachesManager<PlatformCache : AbstractIncrementalCache<*>>(
cachesRootDir: File,
protected val reporter: ICReporter
@@ -67,14 +70,14 @@ class IncrementalJvmCachesManager(
) : IncrementalCachesManager<IncrementalJvmCache>(cacheDirectory, reporter) {
private val jvmCacheDir = File(cacheDirectory, "jvm").apply { mkdirs() }
override val platformCache = IncrementalJvmCache(jvmCacheDir, outputDir).apply { registerCache() }
override val platformCache = IncrementalJvmCache(jvmCacheDir, outputDir, PATH_CONVERTER).apply { registerCache() }
}
class IncrementalJsCachesManager(
cachesRootDir: File,
reporter: ICReporter
cachesRootDir: File,
reporter: ICReporter
) : IncrementalCachesManager<IncrementalJsCache>(cachesRootDir, reporter) {
private val jsCacheFile = File(cachesRootDir, "js").apply { mkdirs() }
override val platformCache = IncrementalJsCache(jsCacheFile).apply { registerCache() }
override val platformCache = IncrementalJsCache(jsCacheFile, PATH_CONVERTER).apply { registerCache() }
}
@@ -34,7 +34,7 @@ class InputsCache(
}
internal val sourceSnapshotMap = registerMap(FileSnapshotMap(SOURCE_SNAPSHOTS.storageFile))
private val sourceToOutputMap = registerMap(FilesMap(SOURCE_TO_OUTPUT_FILES.storageFile))
private val sourceToOutputMap = registerMap(SourceToOutputFilesMap(SOURCE_TO_OUTPUT_FILES.storageFile))
fun removeOutputForSourceFiles(sources: Iterable<File>) {
for (sourceFile in sources) {
@@ -0,0 +1,27 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.incremental.storage
import org.jetbrains.kotlin.incremental.dumpCollection
import java.io.File
class SourceToOutputFilesMap(
storageFile: File
) : BasicStringMap<Collection<String>>(storageFile, PathStringDescriptor, StringCollectionExternalizer) {
operator fun set(sourceFile: File, outputFiles: Collection<File>) {
storage[sourceFile.absolutePath] = outputFiles.map { it.absolutePath }
}
operator fun get(sourceFile: File): Collection<File> =
storage[sourceFile.absolutePath].orEmpty().map(::File)
override fun dumpValue(value: Collection<String>) =
value.dumpCollection()
fun remove(file: File): Collection<File> =
get(file).also { storage.remove(file.absolutePath) }
}
@@ -14,6 +14,8 @@ import org.jetbrains.jps.incremental.messages.BuildMessage
import org.jetbrains.jps.incremental.messages.CompilerMessage
import org.jetbrains.kotlin.config.CompilerRunnerConstants
import org.jetbrains.kotlin.incremental.LookupSymbol
import org.jetbrains.kotlin.incremental.storage.SourceFileToCanonicalPathConverter
import org.jetbrains.kotlin.incremental.storage.SourceFileToPathConverter
import org.jetbrains.kotlin.jps.incremental.*
import org.jetbrains.kotlin.jps.targets.KotlinTargetsIndex
import org.jetbrains.kotlin.jps.targets.KotlinTargetsIndexBuilder
@@ -66,6 +68,8 @@ class KotlinCompileContext(val jpsContext: CompileContext) {
val hasKotlinMarker = HasKotlinMarker(dataManager)
val sourceFileToPathConverter: SourceFileToPathConverter = SourceFileToCanonicalPathConverter
/**
* Flag to prevent rebuilding twice.
*
@@ -24,6 +24,7 @@ import org.jetbrains.jps.incremental.storage.StorageOwner
import org.jetbrains.kotlin.incremental.IncrementalCacheCommon
import org.jetbrains.kotlin.incremental.IncrementalJsCache
import org.jetbrains.kotlin.incremental.IncrementalJvmCache
import org.jetbrains.kotlin.incremental.storage.SourceFileToPathConverter
import org.jetbrains.kotlin.jps.build.KotlinBuilder
import org.jetbrains.kotlin.jps.targets.KotlinModuleBuildTarget
import java.io.File
@@ -34,8 +35,9 @@ interface JpsIncrementalCache : IncrementalCacheCommon, StorageOwner {
class JpsIncrementalJvmCache(
target: ModuleBuildTarget,
paths: BuildDataPaths
) : IncrementalJvmCache(paths.getTargetDataRoot(target), target.outputDir), JpsIncrementalCache {
paths: BuildDataPaths,
sourcePathConverter: SourceFileToPathConverter
) : IncrementalJvmCache(paths.getTargetDataRoot(target), target.outputDir, sourcePathConverter), JpsIncrementalCache {
override fun addJpsDependentCache(cache: JpsIncrementalCache) {
if (cache is JpsIncrementalJvmCache) {
addDependentCache(cache)
@@ -49,8 +51,9 @@ class JpsIncrementalJvmCache(
class JpsIncrementalJsCache(
target: ModuleBuildTarget,
paths: BuildDataPaths
) : IncrementalJsCache(paths.getTargetDataRoot(target)), JpsIncrementalCache {
paths: BuildDataPaths,
sourcePathConverter: SourceFileToPathConverter
) : IncrementalJsCache(paths.getTargetDataRoot(target), sourcePathConverter), JpsIncrementalCache {
override fun addJpsDependentCache(cache: JpsIncrementalCache) {
if (cache is JpsIncrementalJsCache) {
addDependentCache(cache)
@@ -208,7 +208,7 @@ class KotlinJsModuleBuildTarget(kotlinContext: KotlinCompileContext, jpsModuleBu
}
override fun createCacheStorage(paths: BuildDataPaths) =
JpsIncrementalJsCache(jpsModuleBuildTarget, paths)
JpsIncrementalJsCache(jpsModuleBuildTarget, paths, kotlinContext.sourceFileToPathConverter)
override fun updateCaches(
dirtyFilesHolder: KotlinDirtySourceFilesHolder,
@@ -55,7 +55,8 @@ class KotlinJvmModuleBuildTarget(kotlinContext: KotlinCompileContext, jpsModuleB
override val isIncrementalCompilationEnabled: Boolean
get() = IncrementalCompilation.isEnabledForJvm()
override fun createCacheStorage(paths: BuildDataPaths) = JpsIncrementalJvmCache(jpsModuleBuildTarget, paths)
override fun createCacheStorage(paths: BuildDataPaths) =
JpsIncrementalJvmCache(jpsModuleBuildTarget, paths, kotlinContext.sourceFileToPathConverter)
override val buildMetaInfoFactory
get() = JvmBuildMetaInfo