Do not use USER_DATA to preserve data between compilation rounds

Original commit: 60a8db1c6c
This commit is contained in:
Alexey Tsvetkov
2015-11-27 20:01:50 +03:00
parent 1a401183b2
commit 2f253f0c3a
7 changed files with 19 additions and 85 deletions
@@ -74,27 +74,12 @@ import java.util.*
public class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) { public class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
companion object { companion object {
private val TARGETS_WITH_CLEARED_CACHES = Key<Set<ModuleBuildTarget>>("Targets with cleared Kotlin caches")
private val HAS_KOTLIN_FILE_NAME = "has-kotlin.txt" private val HAS_KOTLIN_FILE_NAME = "has-kotlin.txt"
public val KOTLIN_BUILDER_NAME: String = "Kotlin Builder" public val KOTLIN_BUILDER_NAME: String = "Kotlin Builder"
public val LOOKUP_TRACKER: JpsElementChildRoleBase<JpsSimpleElement<out LookupTracker>> = JpsElementChildRoleBase.create("lookup tracker") public val LOOKUP_TRACKER: JpsElementChildRoleBase<JpsSimpleElement<out LookupTracker>> = JpsElementChildRoleBase.create("lookup tracker")
val LOG = Logger.getInstance("#org.jetbrains.kotlin.jps.build.KotlinBuilder") val LOG = Logger.getInstance("#org.jetbrains.kotlin.jps.build.KotlinBuilder")
private fun registerTargetsWithClearedCaches(context: CompileContext, targets: Set<ModuleBuildTarget>) {
synchronized(TARGETS_WITH_CLEARED_CACHES) {
val data = (context.getUserData(TARGETS_WITH_CLEARED_CACHES) ?: setOf()) + targets
context.putUserData(TARGETS_WITH_CLEARED_CACHES, data)
}
}
private fun unregisterTargetsWithClearedCaches(context: CompileContext, targets: Set<ModuleBuildTarget>) {
synchronized(TARGETS_WITH_CLEARED_CACHES) {
val data = (context.getUserData(TARGETS_WITH_CLEARED_CACHES) ?: setOf()) - targets
context.putUserData(TARGETS_WITH_CLEARED_CACHES, data)
}
}
private fun hasKotlin(target: ModuleBuildTarget, paths: BuildDataPaths): Boolean { private fun hasKotlin(target: ModuleBuildTarget, paths: BuildDataPaths): Boolean {
val hasKotlinFile = File(paths.getTargetDataRoot(target), HAS_KOTLIN_FILE_NAME) val hasKotlinFile = File(paths.getTargetDataRoot(target), HAS_KOTLIN_FILE_NAME)
return hasKotlinFile.exists() return hasKotlinFile.exists()
@@ -174,21 +159,21 @@ public class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR
val projectDescriptor = context.projectDescriptor val projectDescriptor = context.projectDescriptor
val dataManager = projectDescriptor.dataManager val dataManager = projectDescriptor.dataManager
val targets = chunk.targets val targets = chunk.targets
val requestedToRebuild = context.getUserData(TARGETS_WITH_CLEARED_CACHES) ?: setOf()
val isFullRebuild = JavaBuilderUtil.isForcedRecompilationAllJavaModules(context) val isFullRebuild = JavaBuilderUtil.isForcedRecompilationAllJavaModules(context)
val hasDirtyKotlin = (dirtyFilesHolder.hasDirtyFiles() || dirtyFilesHolder.hasRemovedFiles()) &&
hasKotlinDirtyOrRemovedFiles(dirtyFilesHolder, chunk)
if (!isFullRebuild && if (!isFullRebuild &&
!requestedToRebuild.containsAll(targets) && targets.any { hasKotlin(it, dataManager.dataPaths) } &&
(hasDirtyKotlin || targets.any { hasKotlin(it, dataManager.dataPaths) }) &&
shouldRebuildBecauseVersionChanged(context, dataManager, targets) shouldRebuildBecauseVersionChanged(context, dataManager, targets)
) { ) {
FSOperations.markDirtyRecursively(context, CompilationRound.NEXT, chunk) { KotlinSourceFileCollector.isKotlinSourceFile(it) } FSOperations.markDirtyRecursively(context, CompilationRound.NEXT, chunk) { KotlinSourceFileCollector.isKotlinSourceFile(it) }
val targetsWithDependents = getIncrementalCaches(chunk, context).keys
targetsWithDependents.forEach { clearHasKotlin(it, dataManager.dataPaths) }
return CHUNK_REBUILD_REQUIRED return CHUNK_REBUILD_REQUIRED
} }
if (hasDirtyKotlin) { if ((dirtyFilesHolder.hasDirtyFiles() || dirtyFilesHolder.hasRemovedFiles()) &&
hasKotlinDirtyOrRemovedFiles(dirtyFilesHolder, chunk)
) {
targets.forEach { setHasKotlin(it, dataManager.dataPaths) } targets.forEach { setHasKotlin(it, dataManager.dataPaths) }
} }
else { else {
@@ -372,20 +357,15 @@ public class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR
for (target in allTargets) { for (target in allTargets) {
dataManager.getKotlinCache(target).clean() dataManager.getKotlinCache(target).clean()
// prevents excessive version checking in parallel compilation (user data is not shared in parallel compilation)
clearHasKotlin(target, dataManager.dataPaths)
} }
dataManager.getStorage(KotlinDataContainerTarget, LookupStorageProvider).clean() dataManager.getStorage(KotlinDataContainerTarget, LookupStorageProvider).clean()
registerTargetsWithClearedCaches(context, allTargets)
return true return true
} }
CacheVersion.Action.REBUILD_CHUNK -> { CacheVersion.Action.REBUILD_CHUNK -> {
LOG.info("Clearing caches for " + targets.joinToString { it.presentableName }) LOG.info("Clearing caches for " + targets.joinToString { it.presentableName })
targets.forEach { dataManager.getKotlinCache(it).clean() } targets.forEach { dataManager.getKotlinCache(it).clean() }
registerTargetsWithClearedCaches(context, targets)
return true return true
} }
CacheVersion.Action.CLEAN_NORMAL_CACHES -> { CacheVersion.Action.CLEAN_NORMAL_CACHES -> {
@@ -421,7 +401,6 @@ public class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR
val targets = chunk.targets val targets = chunk.targets
val cacheVersionsProvider = CacheVersionProvider(dataManager.dataPaths) val cacheVersionsProvider = CacheVersionProvider(dataManager.dataPaths)
cacheVersionsProvider.allVersions(targets).forEach { it.saveIfNeeded() } cacheVersionsProvider.allVersions(targets).forEach { it.saveIfNeeded() }
unregisterTargetsWithClearedCaches(context, targets)
} }
private fun doCompileModuleChunk( private fun doCompileModuleChunk(
@@ -235,7 +235,7 @@ public class KotlinJpsBuildTest : AbstractKotlinJpsBuildTestCase() {
val buildResult = makeAll() val buildResult = makeAll()
buildResult.assertSuccessful() buildResult.assertSuccessful()
val warnings = buildResult.getMessages(BuildMessage.Kind.WARNING) val warnings = buildResult.getMessages(BuildMessage.Kind.WARNING)
assertEquals("Warning about invalid package prefix in module 2 is expected: $warnings", 1, warnings.size) assertEquals("Warning about invalid package prefix in module 2 is expected: $warnings", 2, warnings.size)
assertEquals("Invalid package prefix name is ignored: invalid-prefix.test", warnings.first().messageText) assertEquals("Invalid package prefix name is ignored: invalid-prefix.test", warnings.first().messageText)
} }
@@ -9,28 +9,6 @@ End of files
Cleaning output files: Cleaning output files:
out/production/module1/A.class out/production/module1/A.class
End of files End of files
Cleaning output files:
out/production/module1/B.class
out/production/module1/C.class
out/production/module1/D.class
End of files
Compiling files: Compiling files:
module1/src/module1_A.kt module1/src/module1_A.kt
module1/src/module1_B.kt
End of files
Compiling files:
module1/src/module1_C.java
module1/src/module1_D.java
End of files
Cleaning output files:
out/production/module2/E.class
End of files
Compiling files:
module2/src/module2_E.kt
End of files
Cleaning output files:
out/production/module3/F.class
End of files
Compiling files:
module3/src/module3_F.kt
End of files End of files
@@ -9,28 +9,6 @@ End of files
Cleaning output files: Cleaning output files:
out/production/module1/A.class out/production/module1/A.class
End of files End of files
Cleaning output files:
out/production/module1/B.class
out/production/module1/C.class
out/production/module1/D.class
End of files
Compiling files: Compiling files:
module1/src/module1_A.kt module1/src/module1_A.kt
module1/src/module1_B.kt End of files
End of files
Compiling files:
module1/src/module1_C.java
module1/src/module1_D.java
End of files
Cleaning output files:
out/production/module2/E.class
End of files
Compiling files:
module2/src/module2_E.kt
End of files
Cleaning output files:
out/production/module3/F.class
End of files
Compiling files:
module3/src/module3_F.kt
End of files
@@ -8,12 +8,6 @@ End of files
Cleaning output files: Cleaning output files:
out/production/module2/b/B.class out/production/module2/b/B.class
End of files End of files
Cleaning output files:
out/production/module2/b/C.class
End of files
Compiling files: Compiling files:
module2/src/module2_B.kt module2/src/module2_B.kt
End of files
Compiling files:
module2/src/module2_C.java
End of files End of files
@@ -9,12 +9,6 @@ End of files
Cleaning output files: Cleaning output files:
out/production/module2/b/B.class out/production/module2/b/B.class
End of files End of files
Cleaning output files:
out/production/module2/b/C.class
End of files
Compiling files: Compiling files:
module2/src/module2_B.kt module2/src/module2_B.kt
End of files
Compiling files:
module2/src/module2_C.java
End of files End of files
@@ -27,6 +27,17 @@ module2/src/module2_b.kt
module2/src/module2_c.kt module2/src/module2_c.kt
End of files End of files
Cleaning output files: Cleaning output files:
out/production/module2/META-INF/module2.kotlin_module
out/production/module2/foo/Module2_aKt.class
out/production/module2/foo/Module2_bKt.class
out/production/module2/foo/Module2_cKt.class
End of files
Compiling files:
module2/src/module2_a.kt
module2/src/module2_b.kt
module2/src/module2_c.kt
End of files
Cleaning output files:
out/production/module3/foo/D.class out/production/module3/foo/D.class
End of files End of files
Compiling files: Compiling files: