diff --git a/build-common/src/org/jetbrains/kotlin/incremental/IncrementalCacheCommon.kt b/build-common/src/org/jetbrains/kotlin/incremental/IncrementalCacheCommon.kt new file mode 100644 index 00000000000..6d27e6b0869 --- /dev/null +++ b/build-common/src/org/jetbrains/kotlin/incremental/IncrementalCacheCommon.kt @@ -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() + fun addDependentCache(cache: IncrementalCacheCommon) { + dependents.add(cache) + } + val thisWithDependentCaches: Iterable 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 = + 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) { + if (removedClasses.isEmpty()) return + + val removedFqNames = removedClasses.toSet() + + for (cache in thisWithDependentCaches) { + val parentsFqNames = hashSetOf() + val childrenFqNames = hashSetOf() + + 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(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 + } +} \ No newline at end of file diff --git a/build-common/src/org/jetbrains/kotlin/incremental/IncrementalCacheImpl.kt b/build-common/src/org/jetbrains/kotlin/incremental/IncrementalCacheImpl.kt index 1b61dafdf83..458d80f085d 100644 --- a/build-common/src/org/jetbrains/kotlin/incremental/IncrementalCacheImpl.kt +++ b/build-common/src/org/jetbrains/kotlin/incremental/IncrementalCacheImpl.kt @@ -38,8 +38,6 @@ import org.jetbrains.kotlin.resolve.jvm.JvmClassName import org.jetbrains.kotlin.serialization.Flags 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 org.jetbrains.kotlin.serialization.jvm.BitEncoding import org.jetbrains.kotlin.serialization.jvm.JvmProtoBufUtil import org.jetbrains.org.objectweb.asm.* @@ -53,7 +51,7 @@ open class IncrementalCacheImpl( private val targetDataRoot: File, targetOutputDir: File?, target: Target -) : BasicMapsOwner(), IncrementalCache { +) : IncrementalCacheCommon(File(targetDataRoot, KOTLIN_CACHE_DIRECTORY_NAME)), IncrementalCache { companion object { private val PROTO_MAP = "proto" private val CONSTANTS_MAP = "constants" @@ -63,19 +61,11 @@ open class IncrementalCacheImpl( private val SOURCE_TO_CLASSES = "source-to-classes" private val DIRTY_OUTPUT_CLASSES = "dirty-output-classes" 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 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 constantsMap = registerMap(ConstantsMap(CONSTANTS_MAP.storageFile)) private val packagePartMap = registerMap(PackagePartMap(PACKAGE_PARTS.storageFile)) @@ -84,27 +74,13 @@ open class IncrementalCacheImpl( 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)) - 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? private val internalNameToSource = registerMap(InternalNameToSourcesMap(INTERNAL_NAME_TO_SOURCE.storageFile)) - private val dependents = arrayListOf>() private val outputDir by lazy(LazyThreadSafetyMode.NONE) { requireNotNull(targetOutputDir) { "Target is expected to have output directory: $target" } } - val thisWithDependentCaches: Iterable> by lazy { - val result = arrayListOf(this) - result.addAll(dependents) - result - } - protected open fun debugLog(message: String) {} - fun addDependentCache(cache: IncrementalCacheImpl) { - dependents.add(cache) - } - fun markOutputClassesDirty(removedAndCompiledSources: List) { for (sourceFile in removedAndCompiledSources) { val classes = sourceToClassesMap[sourceFile] @@ -121,12 +97,6 @@ open class IncrementalCacheImpl( fun classesBySources(sources: Iterable): Iterable = sources.flatMap { sourceToClassesMap[it] } - fun getSubtypesOf(className: FqName): Sequence = - subtypesMap[className].asSequence() - - fun getSourceFileIfClass(fqName: FqName): File? = - classFqNameToSourceMap[fqName] - fun sourcesByInternalName(internalName: String): Collection = internalNameToSource[internalName] @@ -310,7 +280,7 @@ open class IncrementalCacheImpl( internalNameToSource.remove(it.internalName) } - removeAllFromClassStorage(dirtyClasses) + removeAllFromClassStorage(dirtyClasses.map { it.fqNameForClassNameWithoutDollars }) dirtyOutputClassesMap.clean() return changesInfo @@ -555,22 +525,6 @@ open class IncrementalCacheImpl( } } - inner class ClassFqNameToSourceMap(storageFile: File) : BasicStringMap(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>(storageFile, EnumeratorStringDescriptor(), PathCollectionExternalizer) { operator fun set(internalName: String, sourceFiles: Iterable) { storage[internalName] = sourceFiles.map { it.canonicalPath } @@ -588,49 +542,8 @@ open class IncrementalCacheImpl( } private fun addToClassStorage(kotlinClass: LocalFileKotlinClass, srcFile: File) { - val classData = JvmProtoBufUtil.readClassDataFrom(kotlinClass.classHeader.data!!, kotlinClass.classHeader.strings!!) - val supertypes = classData.classProto.supertypes(TypeTable(classData.classProto.typeTable)) - 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) { - if (removedClasses.isEmpty()) return - - val removedFqNames = removedClasses.map { it.fqNameForClassNameWithoutDollars }.toSet() - - for (cache in thisWithDependentCaches) { - val parentsFqNames = hashSetOf() - val childrenFqNames = hashSetOf() - - 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) } + val (nameResolver, proto) = JvmProtoBufUtil.readClassDataFrom(kotlinClass.classHeader.data!!, kotlinClass.classHeader.strings!!) + addToClassStorage(proto, nameResolver, srcFile) } private inner class DirtyOutputClassesMap(storageFile: File) : BasicStringMap(storageFile, BooleanDataDescriptor.INSTANCE) { diff --git a/build-common/src/org/jetbrains/kotlin/incremental/LookupStorage.kt b/build-common/src/org/jetbrains/kotlin/incremental/LookupStorage.kt index 42b33870c4e..9783b7928cd 100644 --- a/build-common/src/org/jetbrains/kotlin/incremental/LookupStorage.kt +++ b/build-common/src/org/jetbrains/kotlin/incremental/LookupStorage.kt @@ -29,15 +29,12 @@ import java.io.File import java.util.* -open class LookupStorage(private val targetDataDir: File) : BasicMapsOwner() { +open class LookupStorage(targetDataDir: File) : BasicMapsOwner(targetDataDir) { companion object { private val DELETED_TO_SIZE_TRESHOLD = 0.5 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 idToFile = registerMap(IdToFileMap("id-to-file".storageFile)) private val fileToId = registerMap(FileToIdMap("file-to-id".storageFile)) diff --git a/build-common/src/org/jetbrains/kotlin/incremental/buildUtil.kt b/build-common/src/org/jetbrains/kotlin/incremental/buildUtil.kt index b96c9010e36..cface9d482d 100644 --- a/build-common/src/org/jetbrains/kotlin/incremental/buildUtil.kt +++ b/build-common/src/org/jetbrains/kotlin/incremental/buildUtil.kt @@ -187,8 +187,8 @@ data class DirtyData( val dirtyClassesFqNames: Collection = emptyList() ) -fun CompilationResult.getDirtyData( - caches: Iterable>, +fun CompilationResult.getDirtyData( + caches: Iterable, reporter: ICReporter ): DirtyData { val dirtyLookupSymbols = HashSet() @@ -241,8 +241,8 @@ fun mapLookupSymbolsToFiles( return dirtyFiles } -fun mapClassesFqNamesToFiles( - caches: Iterable>, +fun mapClassesFqNamesToFiles( + caches: Iterable, classesFqNames: Iterable, reporter: ICReporter, excludes: Set = emptySet() @@ -265,9 +265,9 @@ fun mapClassesFqNamesToFiles( private fun findSrcDirRoot(file: File, roots: Iterable): File? = roots.firstOrNull { FileUtil.isAncestor(it, file, false) } -fun withSubtypes( +fun withSubtypes( typeFqName: FqName, - caches: Iterable> + caches: Iterable ): Set { val types = LinkedList(listOf(typeFqName)) val subtypes = hashSetOf() diff --git a/build-common/src/org/jetbrains/kotlin/incremental/storage/BasicMapsOwner.kt b/build-common/src/org/jetbrains/kotlin/incremental/storage/BasicMapsOwner.kt index bebe53556b7..35b46cbadd2 100644 --- a/build-common/src/org/jetbrains/kotlin/incremental/storage/BasicMapsOwner.kt +++ b/build-common/src/org/jetbrains/kotlin/incremental/storage/BasicMapsOwner.kt @@ -17,14 +17,18 @@ package org.jetbrains.kotlin.incremental.storage import org.jetbrains.annotations.TestOnly +import java.io.File -open class BasicMapsOwner { +open class BasicMapsOwner(private val baseDir: File) { private val maps = arrayListOf>() companion object { val CACHE_EXTENSION = "tab" } + protected val String.storageFile: File + get() = File(baseDir, this + "." + CACHE_EXTENSION) + protected fun > registerMap(map: M): M { maps.add(map) return map diff --git a/build-common/src/org/jetbrains/kotlin/incremental/storage/LazyStorage.kt b/build-common/src/org/jetbrains/kotlin/incremental/storage/LazyStorage.kt index 55eddd43592..6ea64af872e 100644 --- a/build-common/src/org/jetbrains/kotlin/incremental/storage/LazyStorage.kt +++ b/build-common/src/org/jetbrains/kotlin/incremental/storage/LazyStorage.kt @@ -87,7 +87,7 @@ class LazyStorage( try { storage?.close() } - catch (ignored: IOException) { + catch (ignored: Throwable) { } PersistentHashMap.deleteFilesStartingWith(storageFile) diff --git a/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalCachesManager.kt b/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalCachesManager.kt index 17697047d1b..9124155d845 100644 --- a/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalCachesManager.kt +++ b/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalCachesManager.kt @@ -16,59 +16,64 @@ package org.jetbrains.kotlin.incremental +import org.jetbrains.kotlin.incremental.storage.BasicMapsOwner import org.jetbrains.kotlin.modules.TargetId import java.io.File -class IncrementalCachesManager ( - private val targetId: TargetId, - private val cacheDirectory: File, - private val outputDir: File, - private val reporter: ICReporter +abstract class IncrementalCachesManager ( + protected val cachesRootDir: File, + protected val reporter: ICReporter ) { - private val incrementalCacheDir = File(cacheDirectory, "increCache.${targetId.name}") - private val lookupCacheDir = File(cacheDirectory, "lookups") - private var incrementalCacheField: GradleIncrementalCacheImpl? = null - private var lookupCacheField: LookupStorage? = null + private val caches = arrayListOf() + protected fun T.registerCache() { + caches.add(this) + } - val incrementalCache: GradleIncrementalCacheImpl - get() { - if (incrementalCacheField == null) { - val targetDataRoot = incrementalCacheDir.apply { mkdirs() } - incrementalCacheField = GradleIncrementalCacheImpl(targetDataRoot, outputDir, targetId, reporter) - } + private val inputSnapshotsCacheDir = File(cachesRootDir, "inputs").apply { mkdirs() } + private val lookupCacheDir = File(cachesRootDir, "lookups").apply { mkdirs() } - return incrementalCacheField!! - } - - val lookupCache: LookupStorage - get() { - if (lookupCacheField == null) { - lookupCacheField = LookupStorage(lookupCacheDir.apply { mkdirs() }) - } - - return lookupCacheField!! - } + val inputsCache: InputsCache = InputsCache(inputSnapshotsCacheDir, reporter).apply { registerCache() } + val lookupCache: LookupStorage = LookupStorage(lookupCacheDir).apply { registerCache() } fun clean() { - close(flush = false) - cacheDirectory.deleteRecursively() + caches.forEach { it.clean() } + cachesRootDir.deleteRecursively() } - fun close(flush: Boolean = false) { - incrementalCacheField?.let { + fun close(flush: Boolean = false): Boolean { + var successful = true + + for (cache in caches) { 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 { - if (flush) { - it.flush(false) - } - it.close() - lookupCacheField = null - } + return successful } +} + +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() } } \ No newline at end of file diff --git a/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalJvmCompilerRunner.kt b/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalJvmCompilerRunner.kt index 467389317a8..169d764b311 100644 --- a/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalJvmCompilerRunner.kt +++ b/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalJvmCompilerRunner.kt @@ -16,7 +16,6 @@ package org.jetbrains.kotlin.incremental -import com.intellij.util.io.PersistentEnumeratorBase import org.jetbrains.kotlin.annotation.AnnotationFileUpdater import org.jetbrains.kotlin.build.GeneratedFile 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.progress.CompilationCanceledStatus import java.io.File -import java.io.IOException import java.util.* fun makeIncrementally( @@ -64,7 +62,7 @@ fun makeIncrementally( sourceRoots.map { JvmSourceRoot(it, null) }.toSet(), versions, reporter) compiler.compile(kotlinFiles, args, messageCollector) { - it.incrementalCache.sourceSnapshotMap.compareAndUpdate(sourceFiles) + it.inputsCache.sourceSnapshotMap.compareAndUpdate(sourceFiles) } } } @@ -107,16 +105,15 @@ class IncrementalJvmCompilerRunner( getChangedFiles: (IncrementalCachesManager)->ChangedFiles ): ExitCode { 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() + dirtySourcesSinceLastTimeFile.delete() + args.destinationAsFile.deleteRecursively() - // todo: warn? - reporter.report { "Possible cache corruption. Rebuilding. $e" } - // try to rebuild 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) } @@ -124,17 +121,24 @@ class IncrementalJvmCompilerRunner( val javaFilesProcessor = ChangedJavaFilesProcessor(reporter) val changedFiles = getChangedFiles(caches) 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) { - onError(e) - } - catch (e: IOException) { - onError(e) - } - finally { - caches.close(flush = true) - reporter.report { "flushed incremental caches" } + catch (e: Exception) { + // todo: warn? + reporter.report { "Possible cache corruption. Rebuilding. $e" } + rebuild() } } @@ -147,15 +151,12 @@ class IncrementalJvmCompilerRunner( private fun calculateSourcesToCompile( javaFilesProcessor: ChangedJavaFilesProcessor, - caches: IncrementalCachesManager, + caches: IncrementalJvmCachesManager, changedFiles: ChangedFiles, args: K2JVMCompilerArguments ): CompilationMode { fun rebuild(reason: ()->String): CompilationMode { reporter.report {"Non-incremental compilation will be performed: ${reason()}"} - caches.clean() - dirtySourcesSinceLastTimeFile.delete() - args.destinationAsFile.deleteRecursively() return CompilationMode.Rebuild } @@ -196,9 +197,9 @@ class IncrementalJvmCompilerRunner( 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()) { - val dirtyFilesFromFqNames = mapClassesFqNamesToFiles(listOf(caches.incrementalCache), dirtyClassesFqNames, reporter) + val dirtyFilesFromFqNames = mapClassesFqNamesToFiles(listOf(caches.jvmCache), dirtyClassesFqNames, reporter) dirtyFiles.addAll(dirtyFilesFromFqNames) } @@ -250,7 +251,7 @@ class IncrementalJvmCompilerRunner( private fun compileIncrementally( args: K2JVMCompilerArguments, - caches: IncrementalCachesManager, + caches: IncrementalJvmCachesManager, javaFilesProcessor: ChangedJavaFilesProcessor, allKotlinSources: List, targetId: TargetId, @@ -283,9 +284,9 @@ class IncrementalJvmCompilerRunner( var exitCode = ExitCode.OK while (dirtySources.any()) { val lookupTracker = LookupTrackerImpl(LookupTracker.DO_NOTHING) - val outdatedClasses = caches.incrementalCache.classesBySources(dirtySources) - caches.incrementalCache.markOutputClassesDirty(dirtySources) - caches.incrementalCache.removeOutputForSourceFiles(dirtySources) + val outdatedClasses = caches.jvmCache.classesBySources(dirtySources) + caches.jvmCache.markOutputClassesDirty(dirtySources) + caches.inputsCache.removeOutputForSourceFiles(dirtySources) val (sourcesToCompile, removedKotlinSources) = dirtySources.partition(File::exists) @@ -295,7 +296,7 @@ class IncrementalJvmCompilerRunner( val text = allSourcesToCompile.joinToString(separator = System.getProperty("line.separator")) { it.canonicalPath } 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 val generatedFiles = compilerOutput.generatedFiles anyClassesCompiled = anyClassesCompiled || generatedFiles.isNotEmpty() || removedKotlinSources.isNotEmpty() @@ -310,7 +311,7 @@ class IncrementalJvmCompilerRunner( if (compilationMode is CompilationMode.Incremental) { 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()) { dirtySources.addAll(additionalDirtyFiles) continue @@ -318,10 +319,10 @@ class IncrementalJvmCompilerRunner( } allGeneratedFiles.addAll(generatedFiles) - caches.incrementalCache.registerOutputForSourceFiles(generatedFiles) + caches.inputsCache.registerOutputForSourceFiles(generatedFiles) val compilationResult = updateIncrementalCaches(listOf(targetId), generatedFiles, compiledWithErrors = exitCode != ExitCode.OK, - getIncrementalCache = { caches.incrementalCache }) + getIncrementalCache = { caches.jvmCache }) caches.lookupCache.update(lookupTracker, sourcesToCompile, removedKotlinSources) @@ -329,13 +330,13 @@ class IncrementalJvmCompilerRunner( break } - val (dirtyLookupSymbols, dirtyClassFqNames) = compilationResult.getDirtyData(listOf(caches.incrementalCache), reporter) + val (dirtyLookupSymbols, dirtyClassFqNames) = compilationResult.getDirtyData(listOf(caches.jvmCache), reporter) val compiledInThisIterationSet = sourcesToCompile.toHashSet() with (dirtySources) { clear() 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) @@ -364,14 +365,14 @@ class IncrementalJvmCompilerRunner( } private fun additionalDirtyFiles( - caches: IncrementalCachesManager, + cache: IncrementalCacheImpl, generatedFiles: List> ): Collection { val result = HashSet() fun partsByFacadeName(facadeInternalName: String): List { - val parts = caches.incrementalCache.getStableMultifileFacadeParts(facadeInternalName) ?: emptyList() - return parts.flatMap { caches.incrementalCache.sourcesByInternalName(it) } + val parts = cache.getStableMultifileFacadeParts(facadeInternalName) ?: emptyList() + return parts.flatMap { cache.sourcesByInternalName(it) } } for (generatedFile in generatedFiles) { @@ -382,7 +383,7 @@ class IncrementalJvmCompilerRunner( when (outputClass.classHeader.kind) { KotlinClassHeader.Kind.CLASS -> { val fqName = outputClass.className.fqNameForClassNameWithoutDollars - val cachedSourceFile = caches.incrementalCache.getSourceFileIfClass(fqName) + val cachedSourceFile = cache.getSourceFileIfClass(fqName) if (cachedSourceFile != null) { result.add(cachedSourceFile) @@ -405,7 +406,7 @@ class IncrementalJvmCompilerRunner( targets: List, sourcesToCompile: Set, args: K2JVMCompilerArguments, - getIncrementalCache: (TargetId)->GradleIncrementalCacheImpl, + cache: IncrementalCacheImpl, lookupTracker: LookupTracker, messageCollector: MessageCollector ): CompileChangedResults { @@ -428,7 +429,7 @@ class IncrementalJvmCompilerRunner( val messageCollector = MessageCollectorWrapper(messageCollector, outputItemCollector) try { - val incrementalCaches = makeIncrementalCachesMap(targets, { listOf() }, getIncrementalCache, { this }) + val incrementalCaches = makeIncrementalCachesMap(targets, { listOf() }, { cache }, { this }) val compilationCanceledStatus = object : CompilationCanceledStatus { override fun checkCanceled() { } diff --git a/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/GradleIncrementalCacheImpl.kt b/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/InputsCache.kt similarity index 94% rename from compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/GradleIncrementalCacheImpl.kt rename to compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/InputsCache.kt index 36397150dde..801ce1f8c16 100644 --- a/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/GradleIncrementalCacheImpl.kt +++ b/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/InputsCache.kt @@ -19,18 +19,17 @@ package org.jetbrains.kotlin.incremental import com.intellij.util.containers.MultiMap import org.jetbrains.kotlin.build.GeneratedFile 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.PathStringDescriptor import org.jetbrains.kotlin.incremental.storage.StringCollectionExternalizer import org.jetbrains.kotlin.modules.TargetId import java.io.File -class GradleIncrementalCacheImpl( - targetDataRoot: File, - targetOutputDir: File?, - target: TargetId, +class InputsCache( + workingDir: File, private val reporter: ICReporter -) : IncrementalCacheImpl(targetDataRoot, targetOutputDir, target) { +) : BasicMapsOwner(workingDir) { companion object { private val SOURCE_TO_OUTPUT_FILES = "source-to-output" private val SOURCE_SNAPSHOTS = "source-snapshot" diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/incremental/BuildCacheStorage.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/incremental/BuildCacheStorage.kt index 31389eda6fc..a01d1857c9d 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/incremental/BuildCacheStorage.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/incremental/BuildCacheStorage.kt @@ -29,15 +29,14 @@ import java.io.File /** * "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 { private val OWN_VERSION = 0 private val ARTIFACT_DIFFERENCE = "artifact-difference" } private val log = Logging.getLogger(this.javaClass) - private val cachesDir: File = File(workingDir, "caches").apply { mkdirs() } - private val versionFile = File(cachesDir, "version.txt") + private val versionFile = File(workingDir, "version.txt") private val version = CacheVersion( OWN_VERSION, versionFile, @@ -50,9 +49,6 @@ internal class BuildCacheStorage(workingDir: File) : BasicMapsOwner(), ArtifactD @Volatile private var artifactDifferenceRegistry: ArtifactDifferenceRegistryImpl? = null - private val String.storageFile: File - get() = File(cachesDir, this + "." + CACHE_EXTENSION) - @Synchronized override fun withRegistry(report: (String)->Unit, fn: (ArtifactDifferenceRegistry)->T): T? { try { @@ -95,8 +91,8 @@ internal class BuildCacheStorage(workingDir: File) : BasicMapsOwner(), ArtifactD log.kotlinDebug { "Exception while closing caches: ${e.stackTraceStr}" } } - cachesDir.deleteRecursively() - cachesDir.mkdirs() + workingDir.deleteRecursively() + workingDir.mkdirs() versionFile.delete() }