Unify processing of removed files for JS and JVM IC

This commit is contained in:
Alexey Tsvetkov
2017-12-07 03:11:10 +03:00
parent d0ca0dca2b
commit e8162cd99d
9 changed files with 222 additions and 128 deletions
@@ -28,18 +28,20 @@ import java.io.File
/**
* Incremental cache common for JVM and JS
*/
abstract class IncrementalCacheCommon(workingDir: File) : BasicMapsOwner(workingDir) {
abstract class IncrementalCacheCommon<ClassName>(workingDir: File) : BasicMapsOwner(workingDir) {
companion object {
private val SUBTYPES = "subtypes"
private val SUPERTYPES = "supertypes"
private val CLASS_FQ_NAME_TO_SOURCE = "class-fq-name-to-source"
@JvmStatic protected val SOURCE_TO_CLASSES = "source-to-classes"
@JvmStatic protected val DIRTY_OUTPUT_CLASSES = "dirty-output-classes"
}
private val dependents = arrayListOf<IncrementalCacheCommon>()
fun addDependentCache(cache: IncrementalCacheCommon) {
private val dependents = arrayListOf<IncrementalCacheCommon<ClassName>>()
fun addDependentCache(cache: IncrementalCacheCommon<ClassName>) {
dependents.add(cache)
}
val thisWithDependentCaches: Iterable<IncrementalCacheCommon> by lazy {
val thisWithDependentCaches: Iterable<IncrementalCacheCommon<ClassName>> by lazy {
val result = arrayListOf(this)
result.addAll(dependents)
result
@@ -48,6 +50,8 @@ abstract class IncrementalCacheCommon(workingDir: File) : BasicMapsOwner(working
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))
internal abstract val sourceToClassesMap: AbstractSourceToOutputMap<ClassName>
internal abstract val dirtyOutputClassesMap: AbstractDirtyClassesMap<ClassName>
fun getSubtypesOf(className: FqName): Sequence<FqName> =
subtypesMap[className].asSequence()
@@ -55,7 +59,16 @@ abstract class IncrementalCacheCommon(workingDir: File) : BasicMapsOwner(working
fun getSourceFileIfClass(fqName: FqName): File? =
classFqNameToSourceMap[fqName]
abstract fun markDirty(removedAndCompiledSources: List<File>)
open fun markDirty(removedAndCompiledSources: List<File>) {
for (sourceFile in removedAndCompiledSources) {
val classes = sourceToClassesMap[sourceFile]
classes.forEach {
dirtyOutputClassesMap.markDirty(it)
}
sourceToClassesMap.clearOutputsForSource(sourceFile)
}
}
protected fun addToClassStorage(proto: ProtoBuf.Class, nameResolver: NameResolver, srcFile: File) {
val supertypes = proto.supertypes(TypeTable(proto.typeTable))
@@ -73,6 +86,8 @@ abstract class IncrementalCacheCommon(workingDir: File) : BasicMapsOwner(working
classFqNameToSourceMap[child] = srcFile
}
abstract fun clearCacheForRemovedClasses(changesCollector: ChangesCollector)
protected fun removeAllFromClassStorage(removedClasses: Collection<FqName>) {
if (removedClasses.isEmpty()) return
@@ -31,19 +31,20 @@ import java.io.DataInput
import java.io.DataOutput
import java.io.File
open class IncrementalJsCache(cachesDir: File) : IncrementalCacheCommon(cachesDir) {
open class IncrementalJsCache(cachesDir: File) : IncrementalCacheCommon<FqName>(cachesDir) {
companion object {
private val TRANSLATION_RESULT_MAP = "translation-result"
private val SOURCES_TO_CLASSES_FQNS = "sources-to-classes"
private val INLINE_FUNCTIONS = "inline-functions"
private val HEADER_FILE_NAME = "header.meta"
}
private val dirtySources = arrayListOf<File>()
override val sourceToClassesMap = registerMap(SourceToFqNameMap(SOURCE_TO_CLASSES.storageFile))
override val dirtyOutputClassesMap = registerMap(DirtyClassesFqNameMap(DIRTY_OUTPUT_CLASSES.storageFile))
private val translationResults = registerMap(TranslationResultMap(TRANSLATION_RESULT_MAP.storageFile))
private val sourcesToClasses = registerMap(SourceToClassesMap(SOURCES_TO_CLASSES_FQNS.storageFile))
private val inlineFunctions = registerMap(InlineFunctionsMap(INLINE_FUNCTIONS.storageFile))
private val dirtySources = hashSetOf<File>()
private val headerFile: File
get() = File(cachesDir, HEADER_FILE_NAME)
@@ -55,30 +56,23 @@ open class IncrementalJsCache(cachesDir: File) : IncrementalCacheCommon(cachesDi
}
override fun markDirty(removedAndCompiledSources: List<File>) {
super.markDirty(removedAndCompiledSources)
dirtySources.addAll(removedAndCompiledSources)
}
fun compareAndUpdate(incrementalResults: IncrementalResultsConsumerImpl, changesCollector: ChangesCollector) {
val translatedFiles = incrementalResults.packageParts
dirtySources.forEach {
if (it !in translatedFiles) {
translationResults.remove(it, changesCollector)
inlineFunctions.remove(it)
}
removeAllFromClassStorage(sourcesToClasses[it])
sourcesToClasses.clearOutputsForSource(it)
}
dirtySources.clear()
for ((srcFile, data) in translatedFiles) {
dirtySources.remove(srcFile)
val (binaryMetadata, binaryAst) = data
val oldProtoMap = translationResults[srcFile]?.metadata?.let { getProtoData(srcFile, it) } ?: emptyMap()
val newProtoMap = getProtoData(srcFile, binaryMetadata)
for (protoData in newProtoMap.values) {
for ((classId, protoData) in newProtoMap) {
registerOutputForFile(srcFile, classId.asSingleFqName())
if (protoData is ClassProtoData) {
addToClassStorage(protoData.proto, protoData.nameResolver, srcFile)
}
@@ -96,6 +90,21 @@ open class IncrementalJsCache(cachesDir: File) : IncrementalCacheCommon(cachesDi
}
}
private fun registerOutputForFile(srcFile: File, name: FqName) {
sourceToClassesMap.add(srcFile, name)
dirtyOutputClassesMap.notDirty(name)
}
override fun clearCacheForRemovedClasses(changesCollector: ChangesCollector) {
dirtySources.forEach {
translationResults.remove(it, changesCollector)
inlineFunctions.remove(it)
}
removeAllFromClassStorage(dirtyOutputClassesMap.getDirtyOutputClasses())
dirtySources.clear()
dirtyOutputClassesMap.clean()
}
fun nonDirtyPackageParts(): Map<File, TranslationResultValue> =
hashMapOf<File, TranslationResultValue>().apply {
for (path in translationResults.keys()) {
@@ -107,25 +116,6 @@ open class IncrementalJsCache(cachesDir: File) : IncrementalCacheCommon(cachesDi
}
}
private class SourceToClassesMap(storageFile: File) : BasicStringMap<Collection<String>>(storageFile, PathStringDescriptor, StringCollectionExternalizer) {
fun clearOutputsForSource(sourceFile: File) {
remove(sourceFile.canonicalPath)
}
fun add(sourceFile: File, className: FqName) {
storage.append(sourceFile.canonicalPath, className.asString())
}
operator fun get(sourceFile: File): Collection<FqName> =
storage[sourceFile.canonicalPath].orEmpty().map { FqName(it) }
override fun dumpValue(value: Collection<String>) = value.dumpCollection()
private fun remove(path: String) {
storage.remove(path)
}
}
private object TranslationResultValueExternalizer : DataExternalizer<TranslationResultValue> {
override fun save(output: DataOutput, value: TranslationResultValue) {
output.writeInt(value.metadata.size)
@@ -44,15 +44,13 @@ val KOTLIN_CACHE_DIRECTORY_NAME = "kotlin"
open class IncrementalJvmCache(
private val targetDataRoot: File,
targetOutputDir: File?
) : IncrementalCacheCommon(File(targetDataRoot, KOTLIN_CACHE_DIRECTORY_NAME)), IncrementalCache {
) : IncrementalCacheCommon<JvmClassName>(File(targetDataRoot, KOTLIN_CACHE_DIRECTORY_NAME)), IncrementalCache {
companion object {
private val PROTO_MAP = "proto"
private val CONSTANTS_MAP = "constants"
private val PACKAGE_PARTS = "package-parts"
private val MULTIFILE_CLASS_FACADES = "multifile-class-facades"
private val MULTIFILE_CLASS_PARTS = "multifile-class-parts"
private val SOURCE_TO_CLASSES = "source-to-classes"
private val DIRTY_OUTPUT_CLASSES = "dirty-output-classes"
private val INLINE_FUNCTIONS = "inline-functions"
private val INTERNAL_NAME_TO_SOURCE = "internal-name-to-source"
private val JAVA_SOURCES_PROTO_MAP = "java-sources-proto-map"
@@ -60,13 +58,14 @@ open class IncrementalJvmCache(
private val MODULE_MAPPING_FILE_NAME = "." + ModuleMapping.MAPPING_FILE_EXT
}
override val sourceToClassesMap = registerMap(SourceToJvmNameMap(SOURCE_TO_CLASSES.storageFile))
override val dirtyOutputClassesMap = registerMap(DirtyClassesJvmNameMap(DIRTY_OUTPUT_CLASSES.storageFile))
private val protoMap = registerMap(ProtoMap(PROTO_MAP.storageFile))
private val constantsMap = registerMap(ConstantsMap(CONSTANTS_MAP.storageFile))
private val packagePartMap = registerMap(PackagePartMap(PACKAGE_PARTS.storageFile))
private val multifileFacadeToParts = registerMap(MultifileClassFacadeMap(MULTIFILE_CLASS_FACADES.storageFile))
private val partToMultifileFacade = registerMap(MultifileClassPartMap(MULTIFILE_CLASS_PARTS.storageFile))
private val sourceToClassesMap = registerMap(SourceToClassesMap(SOURCE_TO_CLASSES.storageFile))
private val dirtyOutputClassesMap = registerMap(DirtyOutputClassesMap(DIRTY_OUTPUT_CLASSES.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))
@@ -76,17 +75,6 @@ open class IncrementalJvmCache(
protected open fun debugLog(message: String) {}
override fun markDirty(removedAndCompiledSources: List<File>) {
for (sourceFile in removedAndCompiledSources) {
val classes = sourceToClassesMap[sourceFile]
classes.forEach {
dirtyOutputClassesMap.markDirty(it.internalName)
}
sourceToClassesMap.clearOutputsForSource(sourceFile)
}
}
fun isTrackedFile(file: File) = sourceToClassesMap.contains(file)
// used in gradle
@@ -98,7 +86,7 @@ open class IncrementalJvmCache(
internalNameToSource[internalName]
fun isMultifileFacade(className: JvmClassName): Boolean =
className.internalName in multifileFacadeToParts
className in multifileFacadeToParts
override fun getClassFilePath(internalClassName: String): String {
return toSystemIndependentName(File(outputDir, "$internalClassName.class").canonicalPath)
@@ -107,7 +95,7 @@ open class IncrementalJvmCache(
fun saveModuleMappingToCache(sourceFiles: Collection<File>, file: File) {
val jvmClassName = JvmClassName.byInternalName(MODULE_MAPPING_FILE_NAME)
protoMap.storeModuleMapping(jvmClassName, file.readBytes())
dirtyOutputClassesMap.notDirty(MODULE_MAPPING_FILE_NAME)
dirtyOutputClassesMap.notDirty(jvmClassName)
sourceFiles.forEach { sourceToClassesMap.add(it, jvmClassName) }
}
@@ -116,7 +104,7 @@ open class IncrementalJvmCache(
val kotlinClass: LocalFileKotlinClass = generatedClass.outputClass
val className = kotlinClass.className
dirtyOutputClassesMap.notDirty(className.internalName)
dirtyOutputClassesMap.notDirty(className)
sourceFiles.forEach {
sourceToClassesMap.add(it, className)
}
@@ -181,7 +169,7 @@ open class IncrementalJvmCache(
val (proto, nameResolver) = serializedJavaClass.toProtoData()
addToClassStorage(proto, nameResolver, source)
dirtyOutputClassesMap.notDirty(jvmClassName.internalName)
dirtyOutputClassesMap.notDirty(jvmClassName)
}
fun getObsoleteJavaClasses(): Collection<ClassId> =
@@ -192,31 +180,28 @@ open class IncrementalJvmCache(
fun isJavaClassToTrack(classId: ClassId): Boolean {
val jvmClassName = JvmClassName.byClassId(classId)
return dirtyOutputClassesMap.isDirty(jvmClassName.internalName) ||
javaSourcesProtoMap[jvmClassName.internalName] == null
return dirtyOutputClassesMap.isDirty(jvmClassName) ||
jvmClassName !in javaSourcesProtoMap
}
fun isJavaClassAlreadyInCache(classId: ClassId): Boolean {
val jvmClassName = JvmClassName.byClassId(classId)
return javaSourcesProtoMap[jvmClassName.internalName] != null
return jvmClassName in javaSourcesProtoMap
}
fun clearCacheForRemovedClasses(changesCollector: ChangesCollector) {
val dirtyClasses = dirtyOutputClassesMap
.getDirtyOutputClasses()
.map(JvmClassName::byInternalName)
.toList()
override fun clearCacheForRemovedClasses(changesCollector: ChangesCollector) {
val dirtyClasses = dirtyOutputClassesMap.getDirtyOutputClasses()
val facadesWithRemovedParts = hashMapOf<JvmClassName, MutableSet<String>>()
for (dirtyClass in dirtyClasses) {
val facade = partToMultifileFacade.get(dirtyClass.internalName) ?: continue
val facade = partToMultifileFacade.get(dirtyClass) ?: continue
val facadeClassName = JvmClassName.byInternalName(facade)
val removedParts = facadesWithRemovedParts.getOrPut(facadeClassName) { hashSetOf() }
removedParts.add(dirtyClass.internalName)
}
for ((facade, removedParts) in facadesWithRemovedParts.entries) {
val allParts = multifileFacadeToParts[facade.internalName] ?: continue
val allParts = multifileFacadeToParts[facade] ?: continue
val notRemovedParts = allParts.filter { it !in removedParts }
if (notRemovedParts.isEmpty()) {
@@ -239,15 +224,13 @@ open class IncrementalJvmCache(
}
removeAllFromClassStorage(dirtyClasses.map { it.fqNameForClassNameWithoutDollars })
dirtyOutputClassesMap.clean()
}
override fun getObsoletePackageParts(): Collection<String> {
val obsoletePackageParts =
dirtyOutputClassesMap.getDirtyOutputClasses().filter { packagePartMap.isPackagePart(JvmClassName.byInternalName(it)) }
val obsoletePackageParts = dirtyOutputClassesMap.getDirtyOutputClasses().filter(packagePartMap::isPackagePart)
debugLog("Obsolete package parts: $obsoletePackageParts")
return obsoletePackageParts
return obsoletePackageParts.map { it.internalName }
}
override fun getPackagePartData(partInternalName: String): JvmPackagePartProto? {
@@ -267,8 +250,9 @@ open class IncrementalJvmCache(
}
override fun getStableMultifileFacadeParts(facadeInternalName: String): Collection<String>? {
val partNames = multifileFacadeToParts.get(facadeInternalName) ?: return null
return partNames.filter { !dirtyOutputClassesMap.isDirty(it) }
val jvmClassName = JvmClassName.byInternalName(facadeInternalName)
val partNames = multifileFacadeToParts[jvmClassName] ?: return null
return partNames.filter { !dirtyOutputClassesMap.isDirty(JvmClassName.byInternalName(it)) }
}
override fun getModuleMappingData(): ByteArray? {
@@ -351,7 +335,11 @@ open class IncrementalJvmCache(
changesCollector.collectProtoChanges(oldValue.toProtoData(), newData = null)
}
operator fun get(internalName: String) = storage[internalName]
operator fun get(className: JvmClassName): SerializedJavaClass? =
storage[className.internalName]
operator fun contains(className: JvmClassName): Boolean =
className.internalName in storage
override fun dumpValue(value: SerializedJavaClass): String =
java.lang.Long.toHexString(value.proto.toByteArray().md5())
@@ -419,13 +407,15 @@ open class IncrementalJvmCache(
}
private inner class MultifileClassFacadeMap(storageFile: File) : BasicStringMap<Collection<String>>(storageFile, StringCollectionExternalizer) {
operator fun set(facadeName: JvmClassName, partNames: Collection<String>) {
storage[facadeName.internalName] = partNames
operator fun set(className: JvmClassName, partNames: Collection<String>) {
storage[className.internalName] = partNames
}
operator fun get(internalName: String): Collection<String>? = storage[internalName]
operator fun get(className: JvmClassName): Collection<String>? =
storage[className.internalName]
operator fun contains(internalName: String): Boolean = internalName in storage
operator fun contains(className: JvmClassName): Boolean =
className.internalName in storage
fun remove(className: JvmClassName) {
storage.remove(className.internalName)
@@ -439,9 +429,8 @@ open class IncrementalJvmCache(
storage[partName] = facadeName
}
fun get(partName: String): String? {
return storage.get(partName)
}
fun get(partName: JvmClassName): String? =
storage[partName.internalName]
fun remove(className: JvmClassName) {
storage.remove(className.internalName)
@@ -450,27 +439,6 @@ open class IncrementalJvmCache(
override fun dumpValue(value: String): String = value
}
inner class SourceToClassesMap(storageFile: File) : BasicStringMap<Collection<String>>(storageFile, PathStringDescriptor, StringCollectionExternalizer) {
fun clearOutputsForSource(sourceFile: File) {
remove(sourceFile.absolutePath)
}
fun add(sourceFile: File, className: JvmClassName) {
storage.append(sourceFile.absolutePath, className.internalName)
}
fun contains(sourceFile: File) = sourceFile.absolutePath in storage
operator fun get(sourceFile: File): Collection<JvmClassName> =
storage[sourceFile.absolutePath].orEmpty().map { JvmClassName.byInternalName(it) }
override fun dumpValue(value: Collection<String>) = value.dumpCollection()
private fun remove(path: String) {
storage.remove(path)
}
}
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 }
@@ -492,24 +460,6 @@ open class IncrementalJvmCache(
addToClassStorage(proto, nameResolver, srcFile)
}
private inner class DirtyOutputClassesMap(storageFile: File) : BasicStringMap<Boolean>(storageFile, BooleanDataDescriptor.INSTANCE) {
fun markDirty(className: String) {
storage[className] = true
}
fun notDirty(className: String) {
storage.remove(className)
}
fun getDirtyOutputClasses(): Collection<String> =
storage.keys
fun isDirty(className: String): Boolean =
storage.contains(className)
override fun dumpValue(value: Boolean) = ""
}
private inner class InlineFunctionsMap(storageFile: File) : BasicStringMap<Map<String, Long>>(storageFile, StringToLongMapExternalizer) {
private fun getInlineFunctionsMap(header: KotlinClassHeader, bytes: ByteArray): Map<String, Long> {
val inlineFunctions = inlineFunctionsJvmNames(header)
@@ -116,7 +116,7 @@ data class DirtyData(
)
fun ChangesCollector.getDirtyData(
caches: Iterable<IncrementalCacheCommon>,
caches: Iterable<IncrementalCacheCommon<*>>,
reporter: ICReporter
): DirtyData {
val dirtyLookupSymbols = HashSet<LookupSymbol>()
@@ -170,7 +170,7 @@ fun mapLookupSymbolsToFiles(
}
fun mapClassesFqNamesToFiles(
caches: Iterable<IncrementalCacheCommon>,
caches: Iterable<IncrementalCacheCommon<*>>,
classesFqNames: Iterable<FqName>,
reporter: ICReporter,
excludes: Set<File> = emptySet()
@@ -192,7 +192,7 @@ fun mapClassesFqNamesToFiles(
fun withSubtypes(
typeFqName: FqName,
caches: Iterable<IncrementalCacheCommon>
caches: Iterable<IncrementalCacheCommon<*>>
): Set<FqName> {
val types = LinkedList(listOf(typeFqName))
val subtypes = hashSetOf<FqName>()
@@ -0,0 +1,46 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.incremental.storage
import com.intellij.util.io.BooleanDataDescriptor
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
import java.io.File
internal class DirtyClassesJvmNameMap(storageFile: File) : AbstractDirtyClassesMap<JvmClassName>(JvmClassNameTransformer, storageFile)
internal class DirtyClassesFqNameMap(storageFile: File) : AbstractDirtyClassesMap<FqName>(FqNameTransformer, storageFile)
internal abstract class AbstractDirtyClassesMap<Name>(
private val nameTransformer: NameTransformer<Name>,
storageFile: File
) : BasicStringMap<Boolean>(storageFile, BooleanDataDescriptor.INSTANCE) {
fun markDirty(className: Name) {
storage[nameTransformer.asString(className)] = true
}
fun notDirty(className: Name) {
storage.remove(nameTransformer.asString(className))
}
fun getDirtyOutputClasses(): Collection<Name> =
storage.keys.map { nameTransformer.asName(it) }
fun isDirty(className: Name): Boolean =
storage.contains(nameTransformer.asString(className))
override fun dumpValue(value: Boolean) = ""
}
@@ -0,0 +1,41 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.incremental.storage
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
internal interface NameTransformer<Name> {
fun asString(name: Name): String
fun asName(string: String): Name
}
internal object FqNameTransformer : NameTransformer<FqName> {
override fun asString(name: FqName): String =
name.asString()
override fun asName(string: String): FqName =
FqName(string)
}
internal object JvmClassNameTransformer : NameTransformer<JvmClassName> {
override fun asString(name: JvmClassName): String =
name.internalName
override fun asName(string: String): JvmClassName =
JvmClassName.byInternalName(string)
}
@@ -0,0 +1,51 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.incremental.storage
import org.jetbrains.kotlin.incremental.dumpCollection
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 abstract class AbstractSourceToOutputMap<Name>(
private val nameTransformer: NameTransformer<Name>,
storageFile: File
) : BasicStringMap<Collection<String>>(storageFile, PathStringDescriptor, StringCollectionExternalizer) {
fun clearOutputsForSource(sourceFile: File) {
remove(sourceFile.absolutePath)
}
fun add(sourceFile: File, className: Name) {
storage.append(sourceFile.absolutePath, nameTransformer.asString(className))
}
fun contains(sourceFile: File): Boolean =
sourceFile.absolutePath in storage
operator fun get(sourceFile: File): Collection<Name> =
storage[sourceFile.absolutePath].orEmpty().map(nameTransformer::asName)
override fun dumpValue(value: Collection<String>) =
value.dumpCollection()
private fun remove(path: String) {
storage.remove(path)
}
}
@@ -19,7 +19,7 @@ package org.jetbrains.kotlin.incremental
import org.jetbrains.kotlin.incremental.storage.BasicMapsOwner
import java.io.File
abstract class IncrementalCachesManager<PlatformCache : IncrementalCacheCommon>(
abstract class IncrementalCachesManager<PlatformCache : IncrementalCacheCommon<*>>(
protected val cachesRootDir: File,
protected val reporter: ICReporter
) {
@@ -121,7 +121,8 @@ class IncrementalJsCompilerRunner(
val jsCache = caches.platformCache
jsCache.header = incrementalResults.headerMetadata
return jsCache.compareAndUpdate(incrementalResults, changesCollector)
jsCache.compareAndUpdate(incrementalResults, changesCollector)
jsCache.clearCacheForRemovedClasses(changesCollector)
}
override fun runCompiler(