Extract common caches
This commit is contained in:
@@ -0,0 +1,117 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
|
||||||
|
import com.intellij.util.io.EnumeratorStringDescriptor
|
||||||
|
import org.jetbrains.kotlin.incremental.storage.*
|
||||||
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
import org.jetbrains.kotlin.serialization.ProtoBuf
|
||||||
|
import org.jetbrains.kotlin.serialization.deserialization.NameResolver
|
||||||
|
import org.jetbrains.kotlin.serialization.deserialization.TypeTable
|
||||||
|
import org.jetbrains.kotlin.serialization.deserialization.supertypes
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Incremental cache common for JVM and JS
|
||||||
|
*/
|
||||||
|
open class IncrementalCacheCommon(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"
|
||||||
|
}
|
||||||
|
|
||||||
|
private val dependents = arrayListOf<IncrementalCacheCommon>()
|
||||||
|
fun addDependentCache(cache: IncrementalCacheCommon) {
|
||||||
|
dependents.add(cache)
|
||||||
|
}
|
||||||
|
val thisWithDependentCaches: Iterable<IncrementalCacheCommon> by lazy {
|
||||||
|
val result = arrayListOf(this)
|
||||||
|
result.addAll(dependents)
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
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))
|
||||||
|
|
||||||
|
fun getSubtypesOf(className: FqName): Sequence<FqName> =
|
||||||
|
subtypesMap[className].asSequence()
|
||||||
|
|
||||||
|
fun getSourceFileIfClass(fqName: FqName): File? =
|
||||||
|
classFqNameToSourceMap[fqName]
|
||||||
|
|
||||||
|
protected fun addToClassStorage(proto: ProtoBuf.Class, nameResolver: NameResolver, srcFile: File) {
|
||||||
|
val supertypes = proto.supertypes(TypeTable(proto.typeTable))
|
||||||
|
val parents = supertypes.map { nameResolver.getClassId(it.className).asSingleFqName() }
|
||||||
|
.filter { it.asString() != "kotlin.Any" }
|
||||||
|
.toSet()
|
||||||
|
val child = nameResolver.getClassId(proto.fqName).asSingleFqName()
|
||||||
|
|
||||||
|
parents.forEach { subtypesMap.add(it, child) }
|
||||||
|
|
||||||
|
val removedSupertypes = supertypesMap[child].filter { it !in parents }
|
||||||
|
removedSupertypes.forEach { subtypesMap.removeValues(it, setOf(child)) }
|
||||||
|
|
||||||
|
supertypesMap[child] = parents
|
||||||
|
classFqNameToSourceMap[child] = srcFile
|
||||||
|
}
|
||||||
|
|
||||||
|
protected fun removeAllFromClassStorage(removedClasses: Collection<FqName>) {
|
||||||
|
if (removedClasses.isEmpty()) return
|
||||||
|
|
||||||
|
val removedFqNames = removedClasses.toSet()
|
||||||
|
|
||||||
|
for (cache in thisWithDependentCaches) {
|
||||||
|
val parentsFqNames = hashSetOf<FqName>()
|
||||||
|
val childrenFqNames = hashSetOf<FqName>()
|
||||||
|
|
||||||
|
for (removedFqName in removedFqNames) {
|
||||||
|
parentsFqNames.addAll(cache.supertypesMap[removedFqName])
|
||||||
|
childrenFqNames.addAll(cache.subtypesMap[removedFqName])
|
||||||
|
|
||||||
|
cache.supertypesMap.remove(removedFqName)
|
||||||
|
cache.subtypesMap.remove(removedFqName)
|
||||||
|
}
|
||||||
|
|
||||||
|
for (child in childrenFqNames) {
|
||||||
|
cache.supertypesMap.removeValues(child, removedFqNames)
|
||||||
|
}
|
||||||
|
|
||||||
|
for (parent in parentsFqNames) {
|
||||||
|
cache.subtypesMap.removeValues(parent, removedFqNames)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
removedFqNames.forEach { classFqNameToSourceMap.remove(it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
protected class ClassFqNameToSourceMap(storageFile: File) : BasicStringMap<String>(storageFile, EnumeratorStringDescriptor(), PathStringDescriptor) {
|
||||||
|
operator fun set(fqName: FqName, sourceFile: File) {
|
||||||
|
storage[fqName.asString()] = sourceFile.canonicalPath
|
||||||
|
}
|
||||||
|
|
||||||
|
operator fun get(fqName: FqName): File? =
|
||||||
|
storage[fqName.asString()]?.let(::File)
|
||||||
|
|
||||||
|
fun remove(fqName: FqName) {
|
||||||
|
storage.remove(fqName.asString())
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun dumpValue(value: String) = value
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -38,8 +38,6 @@ import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
|||||||
import org.jetbrains.kotlin.serialization.Flags
|
import org.jetbrains.kotlin.serialization.Flags
|
||||||
import org.jetbrains.kotlin.serialization.ProtoBuf
|
import org.jetbrains.kotlin.serialization.ProtoBuf
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.NameResolver
|
import org.jetbrains.kotlin.serialization.deserialization.NameResolver
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.TypeTable
|
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.supertypes
|
|
||||||
import org.jetbrains.kotlin.serialization.jvm.BitEncoding
|
import org.jetbrains.kotlin.serialization.jvm.BitEncoding
|
||||||
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBufUtil
|
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBufUtil
|
||||||
import org.jetbrains.org.objectweb.asm.*
|
import org.jetbrains.org.objectweb.asm.*
|
||||||
@@ -53,7 +51,7 @@ open class IncrementalCacheImpl<Target>(
|
|||||||
private val targetDataRoot: File,
|
private val targetDataRoot: File,
|
||||||
targetOutputDir: File?,
|
targetOutputDir: File?,
|
||||||
target: Target
|
target: Target
|
||||||
) : BasicMapsOwner(), IncrementalCache {
|
) : IncrementalCacheCommon(File(targetDataRoot, KOTLIN_CACHE_DIRECTORY_NAME)), IncrementalCache {
|
||||||
companion object {
|
companion object {
|
||||||
private val PROTO_MAP = "proto"
|
private val PROTO_MAP = "proto"
|
||||||
private val CONSTANTS_MAP = "constants"
|
private val CONSTANTS_MAP = "constants"
|
||||||
@@ -63,19 +61,11 @@ open class IncrementalCacheImpl<Target>(
|
|||||||
private val SOURCE_TO_CLASSES = "source-to-classes"
|
private val SOURCE_TO_CLASSES = "source-to-classes"
|
||||||
private val DIRTY_OUTPUT_CLASSES = "dirty-output-classes"
|
private val DIRTY_OUTPUT_CLASSES = "dirty-output-classes"
|
||||||
private val INLINE_FUNCTIONS = "inline-functions"
|
private val INLINE_FUNCTIONS = "inline-functions"
|
||||||
private val SUBTYPES = "subtypes"
|
|
||||||
private val SUPERTYPES = "supertypes"
|
|
||||||
private val CLASS_FQ_NAME_TO_SOURCE = "class-fq-name-to-source"
|
|
||||||
private val INTERNAL_NAME_TO_SOURCE = "internal-name-to-source"
|
private val INTERNAL_NAME_TO_SOURCE = "internal-name-to-source"
|
||||||
|
|
||||||
private val MODULE_MAPPING_FILE_NAME = "." + ModuleMapping.MAPPING_FILE_EXT
|
private val MODULE_MAPPING_FILE_NAME = "." + ModuleMapping.MAPPING_FILE_EXT
|
||||||
}
|
}
|
||||||
|
|
||||||
private val baseDir = File(targetDataRoot, KOTLIN_CACHE_DIRECTORY_NAME)
|
|
||||||
|
|
||||||
protected val String.storageFile: File
|
|
||||||
get() = File(baseDir, this + "." + CACHE_EXTENSION)
|
|
||||||
|
|
||||||
private val protoMap = registerMap(ProtoMap(PROTO_MAP.storageFile))
|
private val protoMap = registerMap(ProtoMap(PROTO_MAP.storageFile))
|
||||||
private val constantsMap = registerMap(ConstantsMap(CONSTANTS_MAP.storageFile))
|
private val constantsMap = registerMap(ConstantsMap(CONSTANTS_MAP.storageFile))
|
||||||
private val packagePartMap = registerMap(PackagePartMap(PACKAGE_PARTS.storageFile))
|
private val packagePartMap = registerMap(PackagePartMap(PACKAGE_PARTS.storageFile))
|
||||||
@@ -84,27 +74,13 @@ open class IncrementalCacheImpl<Target>(
|
|||||||
private val sourceToClassesMap = registerMap(SourceToClassesMap(SOURCE_TO_CLASSES.storageFile))
|
private val sourceToClassesMap = registerMap(SourceToClassesMap(SOURCE_TO_CLASSES.storageFile))
|
||||||
private val dirtyOutputClassesMap = registerMap(DirtyOutputClassesMap(DIRTY_OUTPUT_CLASSES.storageFile))
|
private val dirtyOutputClassesMap = registerMap(DirtyOutputClassesMap(DIRTY_OUTPUT_CLASSES.storageFile))
|
||||||
private val inlineFunctionsMap = registerMap(InlineFunctionsMap(INLINE_FUNCTIONS.storageFile))
|
private val inlineFunctionsMap = registerMap(InlineFunctionsMap(INLINE_FUNCTIONS.storageFile))
|
||||||
private val subtypesMap = registerMap(SubtypesMap(SUBTYPES.storageFile))
|
|
||||||
private val supertypesMap = registerMap(SupertypesMap(SUPERTYPES.storageFile))
|
|
||||||
private val classFqNameToSourceMap = registerMap(ClassFqNameToSourceMap(CLASS_FQ_NAME_TO_SOURCE.storageFile))
|
|
||||||
// todo: try to use internal names only?
|
// 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))
|
||||||
|
|
||||||
private val dependents = arrayListOf<IncrementalCacheImpl<Target>>()
|
|
||||||
private val outputDir by lazy(LazyThreadSafetyMode.NONE) { requireNotNull(targetOutputDir) { "Target is expected to have output directory: $target" } }
|
private val outputDir by lazy(LazyThreadSafetyMode.NONE) { requireNotNull(targetOutputDir) { "Target is expected to have output directory: $target" } }
|
||||||
|
|
||||||
val thisWithDependentCaches: Iterable<IncrementalCacheImpl<Target>> by lazy {
|
|
||||||
val result = arrayListOf(this)
|
|
||||||
result.addAll(dependents)
|
|
||||||
result
|
|
||||||
}
|
|
||||||
|
|
||||||
protected open fun debugLog(message: String) {}
|
protected open fun debugLog(message: String) {}
|
||||||
|
|
||||||
fun addDependentCache(cache: IncrementalCacheImpl<Target>) {
|
|
||||||
dependents.add(cache)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun markOutputClassesDirty(removedAndCompiledSources: List<File>) {
|
fun markOutputClassesDirty(removedAndCompiledSources: List<File>) {
|
||||||
for (sourceFile in removedAndCompiledSources) {
|
for (sourceFile in removedAndCompiledSources) {
|
||||||
val classes = sourceToClassesMap[sourceFile]
|
val classes = sourceToClassesMap[sourceFile]
|
||||||
@@ -121,12 +97,6 @@ open class IncrementalCacheImpl<Target>(
|
|||||||
fun classesBySources(sources: Iterable<File>): Iterable<JvmClassName> =
|
fun classesBySources(sources: Iterable<File>): Iterable<JvmClassName> =
|
||||||
sources.flatMap { sourceToClassesMap[it] }
|
sources.flatMap { sourceToClassesMap[it] }
|
||||||
|
|
||||||
fun getSubtypesOf(className: FqName): Sequence<FqName> =
|
|
||||||
subtypesMap[className].asSequence()
|
|
||||||
|
|
||||||
fun getSourceFileIfClass(fqName: FqName): File? =
|
|
||||||
classFqNameToSourceMap[fqName]
|
|
||||||
|
|
||||||
fun sourcesByInternalName(internalName: String): Collection<File> =
|
fun sourcesByInternalName(internalName: String): Collection<File> =
|
||||||
internalNameToSource[internalName]
|
internalNameToSource[internalName]
|
||||||
|
|
||||||
@@ -310,7 +280,7 @@ open class IncrementalCacheImpl<Target>(
|
|||||||
internalNameToSource.remove(it.internalName)
|
internalNameToSource.remove(it.internalName)
|
||||||
}
|
}
|
||||||
|
|
||||||
removeAllFromClassStorage(dirtyClasses)
|
removeAllFromClassStorage(dirtyClasses.map { it.fqNameForClassNameWithoutDollars })
|
||||||
|
|
||||||
dirtyOutputClassesMap.clean()
|
dirtyOutputClassesMap.clean()
|
||||||
return changesInfo
|
return changesInfo
|
||||||
@@ -555,22 +525,6 @@ open class IncrementalCacheImpl<Target>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inner class ClassFqNameToSourceMap(storageFile: File) : BasicStringMap<String>(storageFile, EnumeratorStringDescriptor(), PathStringDescriptor) {
|
|
||||||
operator fun set(fqName: FqName, sourceFile: File) {
|
|
||||||
storage[fqName.asString()] = sourceFile.canonicalPath
|
|
||||||
}
|
|
||||||
|
|
||||||
operator fun get(fqName: FqName): File? =
|
|
||||||
storage[fqName.asString()]?.let(::File)
|
|
||||||
|
|
||||||
fun remove(fqName: FqName) {
|
|
||||||
storage.remove(fqName.asString())
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun dumpValue(value: String) = value
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inner class InternalNameToSourcesMap(storageFile: File) : BasicStringMap<Collection<String>>(storageFile, EnumeratorStringDescriptor(), PathCollectionExternalizer) {
|
inner class InternalNameToSourcesMap(storageFile: File) : BasicStringMap<Collection<String>>(storageFile, EnumeratorStringDescriptor(), PathCollectionExternalizer) {
|
||||||
operator fun set(internalName: String, sourceFiles: Iterable<File>) {
|
operator fun set(internalName: String, sourceFiles: Iterable<File>) {
|
||||||
storage[internalName] = sourceFiles.map { it.canonicalPath }
|
storage[internalName] = sourceFiles.map { it.canonicalPath }
|
||||||
@@ -588,49 +542,8 @@ open class IncrementalCacheImpl<Target>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun addToClassStorage(kotlinClass: LocalFileKotlinClass, srcFile: File) {
|
private fun addToClassStorage(kotlinClass: LocalFileKotlinClass, srcFile: File) {
|
||||||
val classData = JvmProtoBufUtil.readClassDataFrom(kotlinClass.classHeader.data!!, kotlinClass.classHeader.strings!!)
|
val (nameResolver, proto) = JvmProtoBufUtil.readClassDataFrom(kotlinClass.classHeader.data!!, kotlinClass.classHeader.strings!!)
|
||||||
val supertypes = classData.classProto.supertypes(TypeTable(classData.classProto.typeTable))
|
addToClassStorage(proto, nameResolver, srcFile)
|
||||||
val parents = supertypes.map { classData.nameResolver.getClassId(it.className).asSingleFqName() }
|
|
||||||
.filter { it.asString() != "kotlin.Any" }
|
|
||||||
.toSet()
|
|
||||||
val child = kotlinClass.classId.asSingleFqName()
|
|
||||||
|
|
||||||
parents.forEach { subtypesMap.add(it, child) }
|
|
||||||
|
|
||||||
val removedSupertypes = supertypesMap[child].filter { it !in parents }
|
|
||||||
removedSupertypes.forEach { subtypesMap.removeValues(it, setOf(child)) }
|
|
||||||
|
|
||||||
supertypesMap[child] = parents
|
|
||||||
classFqNameToSourceMap[kotlinClass.className.fqNameForClassNameWithoutDollars] = srcFile
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun removeAllFromClassStorage(removedClasses: Collection<JvmClassName>) {
|
|
||||||
if (removedClasses.isEmpty()) return
|
|
||||||
|
|
||||||
val removedFqNames = removedClasses.map { it.fqNameForClassNameWithoutDollars }.toSet()
|
|
||||||
|
|
||||||
for (cache in thisWithDependentCaches) {
|
|
||||||
val parentsFqNames = hashSetOf<FqName>()
|
|
||||||
val childrenFqNames = hashSetOf<FqName>()
|
|
||||||
|
|
||||||
for (removedFqName in removedFqNames) {
|
|
||||||
parentsFqNames.addAll(cache.supertypesMap[removedFqName])
|
|
||||||
childrenFqNames.addAll(cache.subtypesMap[removedFqName])
|
|
||||||
|
|
||||||
cache.supertypesMap.remove(removedFqName)
|
|
||||||
cache.subtypesMap.remove(removedFqName)
|
|
||||||
}
|
|
||||||
|
|
||||||
for (child in childrenFqNames) {
|
|
||||||
cache.supertypesMap.removeValues(child, removedFqNames)
|
|
||||||
}
|
|
||||||
|
|
||||||
for (parent in parentsFqNames) {
|
|
||||||
cache.subtypesMap.removeValues(parent, removedFqNames)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
removedFqNames.forEach { classFqNameToSourceMap.remove(it) }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private inner class DirtyOutputClassesMap(storageFile: File) : BasicStringMap<Boolean>(storageFile, BooleanDataDescriptor.INSTANCE) {
|
private inner class DirtyOutputClassesMap(storageFile: File) : BasicStringMap<Boolean>(storageFile, BooleanDataDescriptor.INSTANCE) {
|
||||||
|
|||||||
@@ -29,15 +29,12 @@ import java.io.File
|
|||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
|
|
||||||
open class LookupStorage(private val targetDataDir: File) : BasicMapsOwner() {
|
open class LookupStorage(targetDataDir: File) : BasicMapsOwner(targetDataDir) {
|
||||||
companion object {
|
companion object {
|
||||||
private val DELETED_TO_SIZE_TRESHOLD = 0.5
|
private val DELETED_TO_SIZE_TRESHOLD = 0.5
|
||||||
private val MINIMUM_GARBAGE_COLLECTIBLE_SIZE = 10000
|
private val MINIMUM_GARBAGE_COLLECTIBLE_SIZE = 10000
|
||||||
}
|
}
|
||||||
|
|
||||||
private val String.storageFile: File
|
|
||||||
get() = File(targetDataDir, this + "." + CACHE_EXTENSION)
|
|
||||||
|
|
||||||
private val countersFile = "counters".storageFile
|
private val countersFile = "counters".storageFile
|
||||||
private val idToFile = registerMap(IdToFileMap("id-to-file".storageFile))
|
private val idToFile = registerMap(IdToFileMap("id-to-file".storageFile))
|
||||||
private val fileToId = registerMap(FileToIdMap("file-to-id".storageFile))
|
private val fileToId = registerMap(FileToIdMap("file-to-id".storageFile))
|
||||||
|
|||||||
@@ -187,8 +187,8 @@ data class DirtyData(
|
|||||||
val dirtyClassesFqNames: Collection<FqName> = emptyList()
|
val dirtyClassesFqNames: Collection<FqName> = emptyList()
|
||||||
)
|
)
|
||||||
|
|
||||||
fun <Target> CompilationResult.getDirtyData(
|
fun CompilationResult.getDirtyData(
|
||||||
caches: Iterable<IncrementalCacheImpl<Target>>,
|
caches: Iterable<IncrementalCacheCommon>,
|
||||||
reporter: ICReporter
|
reporter: ICReporter
|
||||||
): DirtyData {
|
): DirtyData {
|
||||||
val dirtyLookupSymbols = HashSet<LookupSymbol>()
|
val dirtyLookupSymbols = HashSet<LookupSymbol>()
|
||||||
@@ -241,8 +241,8 @@ fun mapLookupSymbolsToFiles(
|
|||||||
return dirtyFiles
|
return dirtyFiles
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <Target> mapClassesFqNamesToFiles(
|
fun mapClassesFqNamesToFiles(
|
||||||
caches: Iterable<IncrementalCacheImpl<Target>>,
|
caches: Iterable<IncrementalCacheCommon>,
|
||||||
classesFqNames: Iterable<FqName>,
|
classesFqNames: Iterable<FqName>,
|
||||||
reporter: ICReporter,
|
reporter: ICReporter,
|
||||||
excludes: Set<File> = emptySet()
|
excludes: Set<File> = emptySet()
|
||||||
@@ -265,9 +265,9 @@ fun <Target> mapClassesFqNamesToFiles(
|
|||||||
private fun findSrcDirRoot(file: File, roots: Iterable<File>): File? =
|
private fun findSrcDirRoot(file: File, roots: Iterable<File>): File? =
|
||||||
roots.firstOrNull { FileUtil.isAncestor(it, file, false) }
|
roots.firstOrNull { FileUtil.isAncestor(it, file, false) }
|
||||||
|
|
||||||
fun <Target> withSubtypes(
|
fun withSubtypes(
|
||||||
typeFqName: FqName,
|
typeFqName: FqName,
|
||||||
caches: Iterable<IncrementalCacheImpl<Target>>
|
caches: Iterable<IncrementalCacheCommon>
|
||||||
): Set<FqName> {
|
): Set<FqName> {
|
||||||
val types = LinkedList(listOf(typeFqName))
|
val types = LinkedList(listOf(typeFqName))
|
||||||
val subtypes = hashSetOf<FqName>()
|
val subtypes = hashSetOf<FqName>()
|
||||||
|
|||||||
@@ -17,14 +17,18 @@
|
|||||||
package org.jetbrains.kotlin.incremental.storage
|
package org.jetbrains.kotlin.incremental.storage
|
||||||
|
|
||||||
import org.jetbrains.annotations.TestOnly
|
import org.jetbrains.annotations.TestOnly
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
open class BasicMapsOwner {
|
open class BasicMapsOwner(private val baseDir: File) {
|
||||||
private val maps = arrayListOf<BasicMap<*, *>>()
|
private val maps = arrayListOf<BasicMap<*, *>>()
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
val CACHE_EXTENSION = "tab"
|
val CACHE_EXTENSION = "tab"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected val String.storageFile: File
|
||||||
|
get() = File(baseDir, this + "." + CACHE_EXTENSION)
|
||||||
|
|
||||||
protected fun <K, V, M : BasicMap<K, V>> registerMap(map: M): M {
|
protected fun <K, V, M : BasicMap<K, V>> registerMap(map: M): M {
|
||||||
maps.add(map)
|
maps.add(map)
|
||||||
return map
|
return map
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ class LazyStorage<K, V>(
|
|||||||
try {
|
try {
|
||||||
storage?.close()
|
storage?.close()
|
||||||
}
|
}
|
||||||
catch (ignored: IOException) {
|
catch (ignored: Throwable) {
|
||||||
}
|
}
|
||||||
|
|
||||||
PersistentHashMap.deleteFilesStartingWith(storageFile)
|
PersistentHashMap.deleteFilesStartingWith(storageFile)
|
||||||
|
|||||||
+45
-40
@@ -16,59 +16,64 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.incremental
|
package org.jetbrains.kotlin.incremental
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.incremental.storage.BasicMapsOwner
|
||||||
import org.jetbrains.kotlin.modules.TargetId
|
import org.jetbrains.kotlin.modules.TargetId
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
class IncrementalCachesManager (
|
abstract class IncrementalCachesManager (
|
||||||
private val targetId: TargetId,
|
protected val cachesRootDir: File,
|
||||||
private val cacheDirectory: File,
|
protected val reporter: ICReporter
|
||||||
private val outputDir: File,
|
|
||||||
private val reporter: ICReporter
|
|
||||||
) {
|
) {
|
||||||
private val incrementalCacheDir = File(cacheDirectory, "increCache.${targetId.name}")
|
private val caches = arrayListOf<BasicMapsOwner>()
|
||||||
private val lookupCacheDir = File(cacheDirectory, "lookups")
|
protected fun <T : BasicMapsOwner> T.registerCache() {
|
||||||
private var incrementalCacheField: GradleIncrementalCacheImpl? = null
|
caches.add(this)
|
||||||
private var lookupCacheField: LookupStorage? = null
|
}
|
||||||
|
|
||||||
val incrementalCache: GradleIncrementalCacheImpl
|
private val inputSnapshotsCacheDir = File(cachesRootDir, "inputs").apply { mkdirs() }
|
||||||
get() {
|
private val lookupCacheDir = File(cachesRootDir, "lookups").apply { mkdirs() }
|
||||||
if (incrementalCacheField == null) {
|
|
||||||
val targetDataRoot = incrementalCacheDir.apply { mkdirs() }
|
|
||||||
incrementalCacheField = GradleIncrementalCacheImpl(targetDataRoot, outputDir, targetId, reporter)
|
|
||||||
}
|
|
||||||
|
|
||||||
return incrementalCacheField!!
|
val inputsCache: InputsCache = InputsCache(inputSnapshotsCacheDir, reporter).apply { registerCache() }
|
||||||
}
|
val lookupCache: LookupStorage = LookupStorage(lookupCacheDir).apply { registerCache() }
|
||||||
|
|
||||||
val lookupCache: LookupStorage
|
|
||||||
get() {
|
|
||||||
if (lookupCacheField == null) {
|
|
||||||
lookupCacheField = LookupStorage(lookupCacheDir.apply { mkdirs() })
|
|
||||||
}
|
|
||||||
|
|
||||||
return lookupCacheField!!
|
|
||||||
}
|
|
||||||
|
|
||||||
fun clean() {
|
fun clean() {
|
||||||
close(flush = false)
|
caches.forEach { it.clean() }
|
||||||
cacheDirectory.deleteRecursively()
|
cachesRootDir.deleteRecursively()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun close(flush: Boolean = false) {
|
fun close(flush: Boolean = false): Boolean {
|
||||||
incrementalCacheField?.let {
|
var successful = true
|
||||||
|
|
||||||
|
for (cache in caches) {
|
||||||
if (flush) {
|
if (flush) {
|
||||||
it.flush(false)
|
try {
|
||||||
|
cache.flush(false)
|
||||||
|
}
|
||||||
|
catch (e: Throwable) {
|
||||||
|
successful = false
|
||||||
|
reporter.report { "Exception when flushing cache ${cache.javaClass}: $e" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
cache.close()
|
||||||
|
}
|
||||||
|
catch (e: Throwable) {
|
||||||
|
successful = false
|
||||||
|
reporter.report { "Exception when closing cache ${cache.javaClass}: $e" }
|
||||||
}
|
}
|
||||||
it.close()
|
|
||||||
incrementalCacheField = null
|
|
||||||
}
|
}
|
||||||
|
|
||||||
lookupCacheField?.let {
|
return successful
|
||||||
if (flush) {
|
|
||||||
it.flush(false)
|
|
||||||
}
|
|
||||||
it.close()
|
|
||||||
lookupCacheField = null
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class IncrementalJvmCachesManager(
|
||||||
|
targetId: TargetId,
|
||||||
|
cacheDirectory: File,
|
||||||
|
outputDir: File,
|
||||||
|
reporter: ICReporter
|
||||||
|
) : IncrementalCachesManager(cacheDirectory, reporter) {
|
||||||
|
|
||||||
|
private val jvmCacheFile = File(cacheDirectory, "jvm").apply { mkdirs() }
|
||||||
|
val jvmCache = IncrementalCacheImpl(jvmCacheFile, outputDir, targetId).apply { registerCache() }
|
||||||
}
|
}
|
||||||
+42
-41
@@ -16,7 +16,6 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.incremental
|
package org.jetbrains.kotlin.incremental
|
||||||
|
|
||||||
import com.intellij.util.io.PersistentEnumeratorBase
|
|
||||||
import org.jetbrains.kotlin.annotation.AnnotationFileUpdater
|
import org.jetbrains.kotlin.annotation.AnnotationFileUpdater
|
||||||
import org.jetbrains.kotlin.build.GeneratedFile
|
import org.jetbrains.kotlin.build.GeneratedFile
|
||||||
import org.jetbrains.kotlin.build.GeneratedJvmClass
|
import org.jetbrains.kotlin.build.GeneratedJvmClass
|
||||||
@@ -40,7 +39,6 @@ import org.jetbrains.kotlin.modules.TargetId
|
|||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.progress.CompilationCanceledStatus
|
import org.jetbrains.kotlin.progress.CompilationCanceledStatus
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.IOException
|
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
fun makeIncrementally(
|
fun makeIncrementally(
|
||||||
@@ -64,7 +62,7 @@ fun makeIncrementally(
|
|||||||
sourceRoots.map { JvmSourceRoot(it, null) }.toSet(),
|
sourceRoots.map { JvmSourceRoot(it, null) }.toSet(),
|
||||||
versions, reporter)
|
versions, reporter)
|
||||||
compiler.compile(kotlinFiles, args, messageCollector) {
|
compiler.compile(kotlinFiles, args, messageCollector) {
|
||||||
it.incrementalCache.sourceSnapshotMap.compareAndUpdate(sourceFiles)
|
it.inputsCache.sourceSnapshotMap.compareAndUpdate(sourceFiles)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -107,16 +105,15 @@ class IncrementalJvmCompilerRunner(
|
|||||||
getChangedFiles: (IncrementalCachesManager)->ChangedFiles
|
getChangedFiles: (IncrementalCachesManager)->ChangedFiles
|
||||||
): ExitCode {
|
): ExitCode {
|
||||||
val targetId = TargetId(name = args.moduleName!!, type = "java-production")
|
val targetId = TargetId(name = args.moduleName!!, type = "java-production")
|
||||||
var caches = IncrementalCachesManager(targetId, cacheDirectory, File(args.destination), reporter)
|
var caches = IncrementalJvmCachesManager(targetId, cacheDirectory, File(args.destination), reporter)
|
||||||
|
|
||||||
fun onError(e: Exception): ExitCode {
|
fun rebuild(): ExitCode {
|
||||||
caches.clean()
|
caches.clean()
|
||||||
|
dirtySourcesSinceLastTimeFile.delete()
|
||||||
|
args.destinationAsFile.deleteRecursively()
|
||||||
|
|
||||||
// todo: warn?
|
|
||||||
reporter.report { "Possible cache corruption. Rebuilding. $e" }
|
|
||||||
// try to rebuild
|
|
||||||
val javaFilesProcessor = ChangedJavaFilesProcessor(reporter)
|
val javaFilesProcessor = ChangedJavaFilesProcessor(reporter)
|
||||||
caches = IncrementalCachesManager(targetId, cacheDirectory, args.destinationAsFile, reporter)
|
caches = IncrementalJvmCachesManager(targetId, cacheDirectory, args.destinationAsFile, reporter)
|
||||||
return compileIncrementally(args, caches, javaFilesProcessor, allKotlinSources, targetId, CompilationMode.Rebuild, messageCollector)
|
return compileIncrementally(args, caches, javaFilesProcessor, allKotlinSources, targetId, CompilationMode.Rebuild, messageCollector)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,17 +121,24 @@ class IncrementalJvmCompilerRunner(
|
|||||||
val javaFilesProcessor = ChangedJavaFilesProcessor(reporter)
|
val javaFilesProcessor = ChangedJavaFilesProcessor(reporter)
|
||||||
val changedFiles = getChangedFiles(caches)
|
val changedFiles = getChangedFiles(caches)
|
||||||
val compilationMode = calculateSourcesToCompile(javaFilesProcessor, caches, changedFiles, args)
|
val compilationMode = calculateSourcesToCompile(javaFilesProcessor, caches, changedFiles, args)
|
||||||
compileIncrementally(args, caches, javaFilesProcessor, allKotlinSources, targetId, compilationMode, messageCollector)
|
|
||||||
|
val exitCode = when (compilationMode) {
|
||||||
|
is CompilationMode.Incremental -> {
|
||||||
|
compileIncrementally(args, caches, javaFilesProcessor, allKotlinSources, targetId, compilationMode, messageCollector)
|
||||||
|
}
|
||||||
|
is CompilationMode.Rebuild -> {
|
||||||
|
rebuild()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!caches.close(flush = true)) throw RuntimeException("Could not flush caches")
|
||||||
|
|
||||||
|
return exitCode
|
||||||
}
|
}
|
||||||
catch (e: PersistentEnumeratorBase.CorruptedException) {
|
catch (e: Exception) {
|
||||||
onError(e)
|
// todo: warn?
|
||||||
}
|
reporter.report { "Possible cache corruption. Rebuilding. $e" }
|
||||||
catch (e: IOException) {
|
rebuild()
|
||||||
onError(e)
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
caches.close(flush = true)
|
|
||||||
reporter.report { "flushed incremental caches" }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -147,15 +151,12 @@ class IncrementalJvmCompilerRunner(
|
|||||||
|
|
||||||
private fun calculateSourcesToCompile(
|
private fun calculateSourcesToCompile(
|
||||||
javaFilesProcessor: ChangedJavaFilesProcessor,
|
javaFilesProcessor: ChangedJavaFilesProcessor,
|
||||||
caches: IncrementalCachesManager,
|
caches: IncrementalJvmCachesManager,
|
||||||
changedFiles: ChangedFiles,
|
changedFiles: ChangedFiles,
|
||||||
args: K2JVMCompilerArguments
|
args: K2JVMCompilerArguments
|
||||||
): CompilationMode {
|
): CompilationMode {
|
||||||
fun rebuild(reason: ()->String): CompilationMode {
|
fun rebuild(reason: ()->String): CompilationMode {
|
||||||
reporter.report {"Non-incremental compilation will be performed: ${reason()}"}
|
reporter.report {"Non-incremental compilation will be performed: ${reason()}"}
|
||||||
caches.clean()
|
|
||||||
dirtySourcesSinceLastTimeFile.delete()
|
|
||||||
args.destinationAsFile.deleteRecursively()
|
|
||||||
return CompilationMode.Rebuild
|
return CompilationMode.Rebuild
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -196,9 +197,9 @@ class IncrementalJvmCompilerRunner(
|
|||||||
dirtyFiles.addAll(dirtyFilesFromLookups)
|
dirtyFiles.addAll(dirtyFilesFromLookups)
|
||||||
}
|
}
|
||||||
|
|
||||||
val dirtyClassesFqNames = classpathChanges.fqNames.flatMap {withSubtypes(it, listOf(caches.incrementalCache))}
|
val dirtyClassesFqNames = classpathChanges.fqNames.flatMap { withSubtypes(it, listOf(caches.jvmCache)) }
|
||||||
if (dirtyClassesFqNames.any()) {
|
if (dirtyClassesFqNames.any()) {
|
||||||
val dirtyFilesFromFqNames = mapClassesFqNamesToFiles(listOf(caches.incrementalCache), dirtyClassesFqNames, reporter)
|
val dirtyFilesFromFqNames = mapClassesFqNamesToFiles(listOf(caches.jvmCache), dirtyClassesFqNames, reporter)
|
||||||
dirtyFiles.addAll(dirtyFilesFromFqNames)
|
dirtyFiles.addAll(dirtyFilesFromFqNames)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -250,7 +251,7 @@ class IncrementalJvmCompilerRunner(
|
|||||||
|
|
||||||
private fun compileIncrementally(
|
private fun compileIncrementally(
|
||||||
args: K2JVMCompilerArguments,
|
args: K2JVMCompilerArguments,
|
||||||
caches: IncrementalCachesManager,
|
caches: IncrementalJvmCachesManager,
|
||||||
javaFilesProcessor: ChangedJavaFilesProcessor,
|
javaFilesProcessor: ChangedJavaFilesProcessor,
|
||||||
allKotlinSources: List<File>,
|
allKotlinSources: List<File>,
|
||||||
targetId: TargetId,
|
targetId: TargetId,
|
||||||
@@ -283,9 +284,9 @@ class IncrementalJvmCompilerRunner(
|
|||||||
var exitCode = ExitCode.OK
|
var exitCode = ExitCode.OK
|
||||||
while (dirtySources.any()) {
|
while (dirtySources.any()) {
|
||||||
val lookupTracker = LookupTrackerImpl(LookupTracker.DO_NOTHING)
|
val lookupTracker = LookupTrackerImpl(LookupTracker.DO_NOTHING)
|
||||||
val outdatedClasses = caches.incrementalCache.classesBySources(dirtySources)
|
val outdatedClasses = caches.jvmCache.classesBySources(dirtySources)
|
||||||
caches.incrementalCache.markOutputClassesDirty(dirtySources)
|
caches.jvmCache.markOutputClassesDirty(dirtySources)
|
||||||
caches.incrementalCache.removeOutputForSourceFiles(dirtySources)
|
caches.inputsCache.removeOutputForSourceFiles(dirtySources)
|
||||||
|
|
||||||
val (sourcesToCompile, removedKotlinSources) = dirtySources.partition(File::exists)
|
val (sourcesToCompile, removedKotlinSources) = dirtySources.partition(File::exists)
|
||||||
|
|
||||||
@@ -295,7 +296,7 @@ class IncrementalJvmCompilerRunner(
|
|||||||
val text = allSourcesToCompile.joinToString(separator = System.getProperty("line.separator")) { it.canonicalPath }
|
val text = allSourcesToCompile.joinToString(separator = System.getProperty("line.separator")) { it.canonicalPath }
|
||||||
dirtySourcesSinceLastTimeFile.writeText(text)
|
dirtySourcesSinceLastTimeFile.writeText(text)
|
||||||
|
|
||||||
val compilerOutput = compileChanged(listOf(targetId), sourcesToCompile.toSet(), args, { caches.incrementalCache }, lookupTracker, messageCollector)
|
val compilerOutput = compileChanged(listOf(targetId), sourcesToCompile.toSet(), args, caches.jvmCache, lookupTracker, messageCollector)
|
||||||
exitCode = compilerOutput.exitCode
|
exitCode = compilerOutput.exitCode
|
||||||
val generatedFiles = compilerOutput.generatedFiles
|
val generatedFiles = compilerOutput.generatedFiles
|
||||||
anyClassesCompiled = anyClassesCompiled || generatedFiles.isNotEmpty() || removedKotlinSources.isNotEmpty()
|
anyClassesCompiled = anyClassesCompiled || generatedFiles.isNotEmpty() || removedKotlinSources.isNotEmpty()
|
||||||
@@ -310,7 +311,7 @@ class IncrementalJvmCompilerRunner(
|
|||||||
|
|
||||||
if (compilationMode is CompilationMode.Incremental) {
|
if (compilationMode is CompilationMode.Incremental) {
|
||||||
val dirtySourcesSet = dirtySources.toHashSet()
|
val dirtySourcesSet = dirtySources.toHashSet()
|
||||||
val additionalDirtyFiles = additionalDirtyFiles(caches, generatedFiles).filter { it !in dirtySourcesSet }
|
val additionalDirtyFiles = additionalDirtyFiles(caches.jvmCache, generatedFiles).filter { it !in dirtySourcesSet }
|
||||||
if (additionalDirtyFiles.isNotEmpty()) {
|
if (additionalDirtyFiles.isNotEmpty()) {
|
||||||
dirtySources.addAll(additionalDirtyFiles)
|
dirtySources.addAll(additionalDirtyFiles)
|
||||||
continue
|
continue
|
||||||
@@ -318,10 +319,10 @@ class IncrementalJvmCompilerRunner(
|
|||||||
}
|
}
|
||||||
|
|
||||||
allGeneratedFiles.addAll(generatedFiles)
|
allGeneratedFiles.addAll(generatedFiles)
|
||||||
caches.incrementalCache.registerOutputForSourceFiles(generatedFiles)
|
caches.inputsCache.registerOutputForSourceFiles(generatedFiles)
|
||||||
val compilationResult = updateIncrementalCaches(listOf(targetId), generatedFiles,
|
val compilationResult = updateIncrementalCaches(listOf(targetId), generatedFiles,
|
||||||
compiledWithErrors = exitCode != ExitCode.OK,
|
compiledWithErrors = exitCode != ExitCode.OK,
|
||||||
getIncrementalCache = { caches.incrementalCache })
|
getIncrementalCache = { caches.jvmCache })
|
||||||
|
|
||||||
caches.lookupCache.update(lookupTracker, sourcesToCompile, removedKotlinSources)
|
caches.lookupCache.update(lookupTracker, sourcesToCompile, removedKotlinSources)
|
||||||
|
|
||||||
@@ -329,13 +330,13 @@ class IncrementalJvmCompilerRunner(
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
val (dirtyLookupSymbols, dirtyClassFqNames) = compilationResult.getDirtyData(listOf(caches.incrementalCache), reporter)
|
val (dirtyLookupSymbols, dirtyClassFqNames) = compilationResult.getDirtyData(listOf(caches.jvmCache), reporter)
|
||||||
val compiledInThisIterationSet = sourcesToCompile.toHashSet()
|
val compiledInThisIterationSet = sourcesToCompile.toHashSet()
|
||||||
|
|
||||||
with (dirtySources) {
|
with (dirtySources) {
|
||||||
clear()
|
clear()
|
||||||
addAll(mapLookupSymbolsToFiles(caches.lookupCache, dirtyLookupSymbols, reporter, excludes = compiledInThisIterationSet))
|
addAll(mapLookupSymbolsToFiles(caches.lookupCache, dirtyLookupSymbols, reporter, excludes = compiledInThisIterationSet))
|
||||||
addAll(mapClassesFqNamesToFiles(listOf(caches.incrementalCache), dirtyClassFqNames, reporter, excludes = compiledInThisIterationSet))
|
addAll(mapClassesFqNamesToFiles(listOf(caches.jvmCache), dirtyClassFqNames, reporter, excludes = compiledInThisIterationSet))
|
||||||
}
|
}
|
||||||
|
|
||||||
buildDirtyLookupSymbols.addAll(dirtyLookupSymbols)
|
buildDirtyLookupSymbols.addAll(dirtyLookupSymbols)
|
||||||
@@ -364,14 +365,14 @@ class IncrementalJvmCompilerRunner(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun additionalDirtyFiles(
|
private fun additionalDirtyFiles(
|
||||||
caches: IncrementalCachesManager,
|
cache: IncrementalCacheImpl<TargetId>,
|
||||||
generatedFiles: List<GeneratedFile<TargetId>>
|
generatedFiles: List<GeneratedFile<TargetId>>
|
||||||
): Collection<File> {
|
): Collection<File> {
|
||||||
val result = HashSet<File>()
|
val result = HashSet<File>()
|
||||||
|
|
||||||
fun partsByFacadeName(facadeInternalName: String): List<File> {
|
fun partsByFacadeName(facadeInternalName: String): List<File> {
|
||||||
val parts = caches.incrementalCache.getStableMultifileFacadeParts(facadeInternalName) ?: emptyList()
|
val parts = cache.getStableMultifileFacadeParts(facadeInternalName) ?: emptyList()
|
||||||
return parts.flatMap { caches.incrementalCache.sourcesByInternalName(it) }
|
return parts.flatMap { cache.sourcesByInternalName(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
for (generatedFile in generatedFiles) {
|
for (generatedFile in generatedFiles) {
|
||||||
@@ -382,7 +383,7 @@ class IncrementalJvmCompilerRunner(
|
|||||||
when (outputClass.classHeader.kind) {
|
when (outputClass.classHeader.kind) {
|
||||||
KotlinClassHeader.Kind.CLASS -> {
|
KotlinClassHeader.Kind.CLASS -> {
|
||||||
val fqName = outputClass.className.fqNameForClassNameWithoutDollars
|
val fqName = outputClass.className.fqNameForClassNameWithoutDollars
|
||||||
val cachedSourceFile = caches.incrementalCache.getSourceFileIfClass(fqName)
|
val cachedSourceFile = cache.getSourceFileIfClass(fqName)
|
||||||
|
|
||||||
if (cachedSourceFile != null) {
|
if (cachedSourceFile != null) {
|
||||||
result.add(cachedSourceFile)
|
result.add(cachedSourceFile)
|
||||||
@@ -405,7 +406,7 @@ class IncrementalJvmCompilerRunner(
|
|||||||
targets: List<TargetId>,
|
targets: List<TargetId>,
|
||||||
sourcesToCompile: Set<File>,
|
sourcesToCompile: Set<File>,
|
||||||
args: K2JVMCompilerArguments,
|
args: K2JVMCompilerArguments,
|
||||||
getIncrementalCache: (TargetId)->GradleIncrementalCacheImpl,
|
cache: IncrementalCacheImpl<TargetId>,
|
||||||
lookupTracker: LookupTracker,
|
lookupTracker: LookupTracker,
|
||||||
messageCollector: MessageCollector
|
messageCollector: MessageCollector
|
||||||
): CompileChangedResults {
|
): CompileChangedResults {
|
||||||
@@ -428,7 +429,7 @@ class IncrementalJvmCompilerRunner(
|
|||||||
val messageCollector = MessageCollectorWrapper(messageCollector, outputItemCollector)
|
val messageCollector = MessageCollectorWrapper(messageCollector, outputItemCollector)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
val incrementalCaches = makeIncrementalCachesMap(targets, { listOf<TargetId>() }, getIncrementalCache, { this })
|
val incrementalCaches = makeIncrementalCachesMap(targets, { listOf<TargetId>() }, { cache }, { this })
|
||||||
val compilationCanceledStatus = object : CompilationCanceledStatus {
|
val compilationCanceledStatus = object : CompilationCanceledStatus {
|
||||||
override fun checkCanceled() {
|
override fun checkCanceled() {
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-5
@@ -19,18 +19,17 @@ package org.jetbrains.kotlin.incremental
|
|||||||
import com.intellij.util.containers.MultiMap
|
import com.intellij.util.containers.MultiMap
|
||||||
import org.jetbrains.kotlin.build.GeneratedFile
|
import org.jetbrains.kotlin.build.GeneratedFile
|
||||||
import org.jetbrains.kotlin.incremental.snapshots.FileSnapshotMap
|
import org.jetbrains.kotlin.incremental.snapshots.FileSnapshotMap
|
||||||
|
import org.jetbrains.kotlin.incremental.storage.BasicMapsOwner
|
||||||
import org.jetbrains.kotlin.incremental.storage.BasicStringMap
|
import org.jetbrains.kotlin.incremental.storage.BasicStringMap
|
||||||
import org.jetbrains.kotlin.incremental.storage.PathStringDescriptor
|
import org.jetbrains.kotlin.incremental.storage.PathStringDescriptor
|
||||||
import org.jetbrains.kotlin.incremental.storage.StringCollectionExternalizer
|
import org.jetbrains.kotlin.incremental.storage.StringCollectionExternalizer
|
||||||
import org.jetbrains.kotlin.modules.TargetId
|
import org.jetbrains.kotlin.modules.TargetId
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
class GradleIncrementalCacheImpl(
|
class InputsCache(
|
||||||
targetDataRoot: File,
|
workingDir: File,
|
||||||
targetOutputDir: File?,
|
|
||||||
target: TargetId,
|
|
||||||
private val reporter: ICReporter
|
private val reporter: ICReporter
|
||||||
) : IncrementalCacheImpl<TargetId>(targetDataRoot, targetOutputDir, target) {
|
) : BasicMapsOwner(workingDir) {
|
||||||
companion object {
|
companion object {
|
||||||
private val SOURCE_TO_OUTPUT_FILES = "source-to-output"
|
private val SOURCE_TO_OUTPUT_FILES = "source-to-output"
|
||||||
private val SOURCE_SNAPSHOTS = "source-snapshot"
|
private val SOURCE_SNAPSHOTS = "source-snapshot"
|
||||||
+4
-8
@@ -29,15 +29,14 @@ import java.io.File
|
|||||||
/**
|
/**
|
||||||
* "Global" cache holder. Should be created once per root project.
|
* "Global" cache holder. Should be created once per root project.
|
||||||
*/
|
*/
|
||||||
internal class BuildCacheStorage(workingDir: File) : BasicMapsOwner(), ArtifactDifferenceRegistryProvider {
|
internal class BuildCacheStorage(private val workingDir: File) : BasicMapsOwner(workingDir), ArtifactDifferenceRegistryProvider {
|
||||||
companion object {
|
companion object {
|
||||||
private val OWN_VERSION = 0
|
private val OWN_VERSION = 0
|
||||||
private val ARTIFACT_DIFFERENCE = "artifact-difference"
|
private val ARTIFACT_DIFFERENCE = "artifact-difference"
|
||||||
}
|
}
|
||||||
|
|
||||||
private val log = Logging.getLogger(this.javaClass)
|
private val log = Logging.getLogger(this.javaClass)
|
||||||
private val cachesDir: File = File(workingDir, "caches").apply { mkdirs() }
|
private val versionFile = File(workingDir, "version.txt")
|
||||||
private val versionFile = File(cachesDir, "version.txt")
|
|
||||||
private val version = CacheVersion(
|
private val version = CacheVersion(
|
||||||
OWN_VERSION,
|
OWN_VERSION,
|
||||||
versionFile,
|
versionFile,
|
||||||
@@ -50,9 +49,6 @@ internal class BuildCacheStorage(workingDir: File) : BasicMapsOwner(), ArtifactD
|
|||||||
@Volatile
|
@Volatile
|
||||||
private var artifactDifferenceRegistry: ArtifactDifferenceRegistryImpl? = null
|
private var artifactDifferenceRegistry: ArtifactDifferenceRegistryImpl? = null
|
||||||
|
|
||||||
private val String.storageFile: File
|
|
||||||
get() = File(cachesDir, this + "." + CACHE_EXTENSION)
|
|
||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
override fun <T> withRegistry(report: (String)->Unit, fn: (ArtifactDifferenceRegistry)->T): T? {
|
override fun <T> withRegistry(report: (String)->Unit, fn: (ArtifactDifferenceRegistry)->T): T? {
|
||||||
try {
|
try {
|
||||||
@@ -95,8 +91,8 @@ internal class BuildCacheStorage(workingDir: File) : BasicMapsOwner(), ArtifactD
|
|||||||
log.kotlinDebug { "Exception while closing caches: ${e.stackTraceStr}" }
|
log.kotlinDebug { "Exception while closing caches: ${e.stackTraceStr}" }
|
||||||
}
|
}
|
||||||
|
|
||||||
cachesDir.deleteRecursively()
|
workingDir.deleteRecursively()
|
||||||
cachesDir.mkdirs()
|
workingDir.mkdirs()
|
||||||
versionFile.delete()
|
versionFile.delete()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user