Recompile files depending on changed inline function between modules

Original commit: 10a330f67a
This commit is contained in:
Alexey Tsvetkov
2015-08-04 08:37:16 +03:00
parent bb14bb8d09
commit 89098a9ff8
3 changed files with 76 additions and 14 deletions
@@ -22,7 +22,10 @@ import com.intellij.openapi.util.io.FileUtil
import com.intellij.util.containers.MultiMap
import gnu.trove.THashSet
import org.jetbrains.jps.ModuleChunk
import org.jetbrains.jps.builders.BuildTarget
import org.jetbrains.jps.builders.DirtyFilesHolder
import org.jetbrains.jps.builders.impl.BuildTargetRegistryImpl
import org.jetbrains.jps.builders.impl.TargetOutputIndexImpl
import org.jetbrains.jps.builders.java.JavaBuilderUtil
import org.jetbrains.jps.builders.java.JavaSourceRootDescriptor
import org.jetbrains.jps.builders.java.dependencyView.Mappings
@@ -102,9 +105,7 @@ public class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR
outputConsumer: ModuleLevelBuilder.OutputConsumer
): ModuleLevelBuilder.ExitCode {
val messageCollector = MessageCollectorAdapter(context)
val dataManager = context.projectDescriptor.dataManager
val targets = chunk.targets
val incrementalCaches = targets.keysToMap { dataManager.getKotlinCache(it) }
val incrementalCaches = getIncrementalCaches(chunk, context)
try {
return doBuild(chunk, context, dirtyFilesHolder, messageCollector, outputConsumer, incrementalCaches)
@@ -609,6 +610,44 @@ public class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR
}
}
private val Iterable<BuildTarget<*>>.moduleTargets: Iterable<ModuleBuildTarget>
get() = filterIsInstance(javaClass<ModuleBuildTarget>())
private fun getIncrementalCaches(chunk: ModuleChunk, context: CompileContext): Map<ModuleBuildTarget, IncrementalCacheImpl> {
val dataManager = context.projectDescriptor.dataManager
val targets = chunk.targets
val buildRegistry = BuildTargetRegistryImpl(context.projectDescriptor.model)
val outputIndex = TargetOutputIndexImpl(targets, context)
val allTargets = buildRegistry.allTargets.moduleTargets
val allDependencies = allTargets.keysToMap { target ->
target.computeDependencies(buildRegistry, outputIndex).moduleTargets
}
val dependents = targets.keysToMap { hashSetOf<ModuleBuildTarget>() }
val targetsWithDependents = HashSet<ModuleBuildTarget>(targets)
for ((target, dependencies) in allDependencies) {
for (dependency in dependencies) {
if (dependency !in targets) continue
dependents[dependency]!!.add(target)
targetsWithDependents.add(target)
}
}
val caches = targetsWithDependents.keysToMap { dataManager.getKotlinCache(it) }
for ((target, cache) in caches) {
dependents[target]?.forEach {
cache.addDependentCache(caches[it]!!)
}
}
return caches
}
private val ALL_COMPILED_FILES_KEY = Key.create<MutableSet<File>>("_all_kotlin_compiled_files_")
private fun getAllCompiledFilesContainer(context: CompileContext): MutableSet<File> {
var allCompiledFiles = ALL_COMPILED_FILES_KEY.get(context)
@@ -27,6 +27,7 @@ import org.jetbrains.annotations.TestOnly
import org.jetbrains.jps.builders.BuildTarget
import org.jetbrains.jps.builders.storage.BuildDataPaths
import org.jetbrains.jps.builders.storage.StorageProvider
import org.jetbrains.jps.incremental.ModuleBuildTarget
import org.jetbrains.jps.incremental.storage.BuildDataManager
import org.jetbrains.jps.incremental.storage.PathStringDescriptor
import org.jetbrains.jps.incremental.storage.StorageOwner
@@ -104,7 +105,10 @@ class CacheFormatVersion(targetDataRoot: File) {
}
}
public class IncrementalCacheImpl(targetDataRoot: File) : StorageOwner, IncrementalCache {
public class IncrementalCacheImpl(
targetDataRoot: File,
private val target: ModuleBuildTarget
) : StorageOwner, IncrementalCache {
companion object {
val PROTO_MAP = "proto.tab"
val CONSTANTS_MAP = "constants.tab"
@@ -143,6 +147,7 @@ public class IncrementalCacheImpl(targetDataRoot: File) : StorageOwner, Incremen
hasInlineTo)
private val cacheFormatVersion = CacheFormatVersion(targetDataRoot)
private val dependents = arrayListOf<IncrementalCacheImpl>()
private val inlineRegistering = object : InlineRegistering {
override fun registerInline(fromPath: String, jvmSignature: String, toPath: String) {
@@ -152,6 +157,10 @@ public class IncrementalCacheImpl(targetDataRoot: File) : StorageOwner, Incremen
override fun getInlineRegistering(): InlineRegistering = inlineRegistering
public fun addDependentCache(cache: IncrementalCacheImpl) {
dependents.add(cache)
}
TestOnly
public fun dump(): String {
return maps.map { it.dump() }.join("\n\n")
@@ -171,6 +180,7 @@ public class IncrementalCacheImpl(targetDataRoot: File) : StorageOwner, Incremen
public fun getFilesToReinline(): Collection<File> {
val result = THashSet(FileUtil.PATH_HASHING_STRATEGY)
val outPath = target?.outputDir!!
for ((className, functions) in dirtyInlineFunctionsMap.getEntries()) {
val sourceFiles = classToSourcesMap[className]
@@ -179,6 +189,14 @@ public class IncrementalCacheImpl(targetDataRoot: File) : StorageOwner, Incremen
val targetFiles = functions.flatMap { hasInlineTo[sourceFile, it] }
result.addAll(targetFiles)
}
val classFile = File(outPath, "${className.internalName}.class")
val classFileName = classFile.normalizedPath
for (dependent in dependents) {
val targetFiles = functions.flatMap { dependent.hasInlineTo[classFileName, it] }
result.addAll(targetFiles)
}
}
dirtyInlineFunctionsMap.clean()
@@ -724,15 +742,17 @@ public class IncrementalCacheImpl(targetDataRoot: File) : StorageOwner, Incremen
}
}
private val storageProvider = object : StorageProvider<IncrementalCacheImpl>() {
override fun createStorage(targetDataDir: File): IncrementalCacheImpl {
return IncrementalCacheImpl(targetDataDir)
}
}
public fun BuildDataPaths.getKotlinCacheVersion(target: BuildTarget<*>): CacheFormatVersion = CacheFormatVersion(getTargetDataRoot(target))
public fun BuildDataManager.getKotlinCache(target: BuildTarget<*>): IncrementalCacheImpl = getStorage(target, storageProvider)
private data class KotlinIncrementalStorageProvider(
private val target: ModuleBuildTarget
) : StorageProvider<IncrementalCacheImpl>() {
override fun createStorage(targetDataDir: File): IncrementalCacheImpl =
IncrementalCacheImpl(targetDataDir, target)
}
public fun BuildDataManager.getKotlinCache(target: ModuleBuildTarget): IncrementalCacheImpl =
getStorage(target, KotlinIncrementalStorageProvider(target))
private fun ByteArray.md5(): Long {
val d = MessageDigest.getInstance("MD5").digest(this)!!
@@ -37,6 +37,7 @@ import org.jetbrains.jps.builders.logging.BuildLoggingManager
import org.jetbrains.jps.cmdline.ProjectDescriptor
import org.jetbrains.jps.incremental.BuilderRegistry
import org.jetbrains.jps.incremental.IncProjectBuilder
import org.jetbrains.jps.incremental.ModuleBuildTarget
import org.jetbrains.jps.incremental.messages.BuildMessage
import org.jetbrains.jps.model.JpsElementFactory
import org.jetbrains.jps.model.JpsModuleRootModificationUtil
@@ -51,8 +52,7 @@ import org.jetbrains.kotlin.utils.keysToMap
import java.io.ByteArrayOutputStream
import java.io.File
import java.io.PrintStream
import java.util.ArrayList
import java.util.HashMap
import java.util.*
import kotlin.properties.Delegates
import kotlin.test.assertEquals
import kotlin.test.assertFalse
@@ -290,7 +290,10 @@ public abstract class AbstractIncrementalJpsTest(
private fun createKotlinIncrementalCacheDump(project: ProjectDescriptor): String {
return StringBuilder {
for (target in project.buildTargetIndex.allTargets.sortBy { it.presentableName }) {
val allTargets = project.buildTargetIndex.allTargets
val moduleTargets = allTargets.filterIsInstance(ModuleBuildTarget::class.java)
for (target in moduleTargets.sortedBy { it.presentableName }) {
append("<target $target>\n")
append(project.dataManager.getKotlinCache(target).dump())
append("</target $target>\n\n\n")