diff --git a/build-common/src/org/jetbrains/kotlin/incremental/buildUtil.kt b/build-common/src/org/jetbrains/kotlin/incremental/buildUtil.kt index cb64541e762..1460048c7ba 100644 --- a/build-common/src/org/jetbrains/kotlin/incremental/buildUtil.kt +++ b/build-common/src/org/jetbrains/kotlin/incremental/buildUtil.kt @@ -19,13 +19,9 @@ package org.jetbrains.kotlin.incremental -import com.intellij.ide.highlighter.JavaFileType import com.intellij.openapi.util.io.FileUtil import com.intellij.openapi.util.text.StringUtil -import org.jetbrains.kotlin.build.GeneratedFile -import org.jetbrains.kotlin.build.GeneratedJvmClass -import org.jetbrains.kotlin.build.JvmSourceRoot -import org.jetbrains.kotlin.build.isModuleMappingFile +import org.jetbrains.kotlin.build.* import org.jetbrains.kotlin.compilerRunner.OutputItemsCollectorImpl import org.jetbrains.kotlin.config.IncrementalCompilation import org.jetbrains.kotlin.config.Services @@ -168,10 +164,11 @@ fun OutputItemsCollectorImpl.generatedFiles( outputItem.sourceFiles.firstOrNull()?.let { sourceToTarget[it] } ?: targets.filter { getOutputDir(it)?.let { outputItem.outputFile.startsWith(it) } ?: false }.singleOrNull() ?: representativeTarget - if (outputItem.outputFile.name.endsWith(".class")) - GeneratedJvmClass(target, outputItem.sourceFiles, outputItem.outputFile) - else - GeneratedFile(target, outputItem.sourceFiles, outputItem.outputFile) + + when (outputItem.outputFile.extension) { + "class" -> GeneratedJvmClass(target, outputItem.sourceFiles, outputItem.outputFile) + else -> GeneratedFile(target, outputItem.sourceFiles, outputItem.outputFile) + } } } diff --git a/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/GradleIncrementalCacheImpl.kt b/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/GradleIncrementalCacheImpl.kt index cb457d8ab4f..36397150dde 100644 --- a/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/GradleIncrementalCacheImpl.kt +++ b/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/GradleIncrementalCacheImpl.kt @@ -16,7 +16,8 @@ package org.jetbrains.kotlin.incremental -import org.jetbrains.kotlin.build.GeneratedJvmClass +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.BasicStringMap import org.jetbrains.kotlin.incremental.storage.PathStringDescriptor @@ -31,26 +32,36 @@ class GradleIncrementalCacheImpl( private val reporter: ICReporter ) : IncrementalCacheImpl(targetDataRoot, targetOutputDir, target) { companion object { - private val SOURCES_TO_CLASSFILES = "sources-to-classfiles" - private val GENERATED_SOURCE_SNAPSHOTS = "generated-source-snapshot" + private val SOURCE_TO_OUTPUT_FILES = "source-to-output" private val SOURCE_SNAPSHOTS = "source-snapshot" } - internal val sourceToClassfilesMap = registerMap(SourceToClassfilesMap(SOURCES_TO_CLASSFILES.storageFile)) - internal val generatedSourceSnapshotMap = registerMap(FileSnapshotMap(GENERATED_SOURCE_SNAPSHOTS.storageFile)) + internal val sourceToOutputMap = registerMap(SourceToOutputFilesMap(SOURCE_TO_OUTPUT_FILES.storageFile)) internal val sourceSnapshotMap = registerMap(FileSnapshotMap(SOURCE_SNAPSHOTS.storageFile)) - fun removeClassfilesBySources(sources: Iterable): Unit = - sources.forEach { sourceToClassfilesMap.remove(it) } + // generatedFiles can contain multiple entries with the same source file + // for example Kapt3 IC will generate a .java stub and .class stub for each source file + fun registerOutputForSourceFiles(generatedFiles: List>) { + val sourceToOutput = MultiMap() - override fun saveFileToCache(generatedClass: GeneratedJvmClass): CompilationResult { - generatedClass.sourceFiles.forEach { sourceToClassfilesMap.add(it, generatedClass.outputFile) } - return super.saveFileToCache(generatedClass) + for (generatedFile in generatedFiles) { + for (source in generatedFile.sourceFiles) { + sourceToOutput.putValue(source, generatedFile.outputFile) + } + } + + for ((source, outputs) in sourceToOutput.entrySet()) { + sourceToOutputMap[source] = outputs + } } - inner class SourceToClassfilesMap(storageFile: File) : BasicStringMap>(storageFile, PathStringDescriptor, StringCollectionExternalizer) { - fun add(sourceFile: File, classFile: File) { - storage.append(sourceFile.absolutePath, classFile.absolutePath) + fun removeOutputForSourceFiles(sources: Iterable) { + sources.forEach { sourceToOutputMap.remove(it) } + } + + inner class SourceToOutputFilesMap(storageFile: File) : BasicStringMap>(storageFile, PathStringDescriptor, StringCollectionExternalizer) { + operator fun set(sourceFile: File, outputFiles: Collection) { + storage[sourceFile.absolutePath] = outputFiles.map { it.absolutePath } } operator fun get(sourceFile: File): Collection = 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 f8ebae18756..0ba5c66754a 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 @@ -288,7 +288,7 @@ class IncrementalJvmCompilerRunner( val lookupTracker = LookupTrackerImpl(LookupTracker.DO_NOTHING) val outdatedClasses = caches.incrementalCache.classesBySources(dirtySources) caches.incrementalCache.markOutputClassesDirty(dirtySources) - caches.incrementalCache.removeClassfilesBySources(dirtySources) + caches.incrementalCache.removeOutputForSourceFiles(dirtySources) val (sourcesToCompile, removedKotlinSources) = dirtySources.partition(File::exists) @@ -300,8 +300,8 @@ class IncrementalJvmCompilerRunner( val compilerOutput = compileChanged(listOf(targetId), sourcesToCompile.toSet(), args, { caches.incrementalCache }, lookupTracker, messageCollector) exitCode = compilerOutput.exitCode - val generatedClassFiles = compilerOutput.generatedFiles - anyClassesCompiled = anyClassesCompiled || generatedClassFiles.isNotEmpty() || removedKotlinSources.isNotEmpty() + val generatedFiles = compilerOutput.generatedFiles + anyClassesCompiled = anyClassesCompiled || generatedFiles.isNotEmpty() || removedKotlinSources.isNotEmpty() if (exitCode == ExitCode.OK) { dirtySourcesSinceLastTimeFile.delete() @@ -313,15 +313,16 @@ class IncrementalJvmCompilerRunner( if (compilationMode is CompilationMode.Incremental) { val dirtySourcesSet = dirtySources.toHashSet() - val additionalDirtyFiles = additionalDirtyFiles(caches, generatedClassFiles).filter { it !in dirtySourcesSet } + val additionalDirtyFiles = additionalDirtyFiles(caches, generatedFiles).filter { it !in dirtySourcesSet } if (additionalDirtyFiles.isNotEmpty()) { dirtySources.addAll(additionalDirtyFiles) continue } } - allGeneratedFiles.addAll(generatedClassFiles) - val compilationResult = updateIncrementalCaches(listOf(targetId), generatedClassFiles, + allGeneratedFiles.addAll(generatedFiles) + caches.incrementalCache.registerOutputForSourceFiles(generatedFiles) + val compilationResult = updateIncrementalCaches(listOf(targetId), generatedFiles, compiledWithErrors = exitCode != ExitCode.OK, getIncrementalCache = { caches.incrementalCache }) diff --git a/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/cacheVersions.kt b/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/cacheVersions.kt index 07c03d3f515..3c8c6b33312 100644 --- a/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/cacheVersions.kt +++ b/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/cacheVersions.kt @@ -19,7 +19,7 @@ package org.jetbrains.kotlin.incremental import org.jetbrains.kotlin.config.IncrementalCompilation import java.io.File -internal const val STANDALONE_CACHE_VERSION = 0 +internal const val STANDALONE_CACHE_VERSION = 1 internal const val STANDALONE_VERSION_FILE_NAME = "standalone-ic-format-version.txt" fun standaloneCacheVersion(dataRoot: File): CacheVersion =