@@ -976,7 +976,7 @@ open class KotlinJpsBuildTest : AbstractKotlinJpsBuildTestCase() {
|
|||||||
project.setTestingContext(TestingContext(LookupTracker.DO_NOTHING, object : BuildLogger {
|
project.setTestingContext(TestingContext(LookupTracker.DO_NOTHING, object : BuildLogger {
|
||||||
override fun buildStarted(context: CompileContext, chunk: ModuleChunk) {
|
override fun buildStarted(context: CompileContext, chunk: ModuleChunk) {
|
||||||
actual.append("Targets dependent on ${chunk.targets.joinToString() }:\n")
|
actual.append("Targets dependent on ${chunk.targets.joinToString() }:\n")
|
||||||
actual.append(getDependentTargets(chunk, context).map { it.toString() }.sorted().joinToString("\n"))
|
actual.append(getDependentTargets(chunk.targets, context).map { it.toString() }.sorted().joinToString("\n"))
|
||||||
actual.append("\n---------\n")
|
actual.append("\n---------\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -975,7 +975,7 @@ open class KotlinJpsBuildTest : AbstractKotlinJpsBuildTestCase() {
|
|||||||
project.setTestingContext(TestingContext(LookupTracker.DO_NOTHING, object : BuildLogger {
|
project.setTestingContext(TestingContext(LookupTracker.DO_NOTHING, object : BuildLogger {
|
||||||
override fun buildStarted(context: CompileContext, chunk: ModuleChunk) {
|
override fun buildStarted(context: CompileContext, chunk: ModuleChunk) {
|
||||||
actual.append("Targets dependent on ${chunk.targets.joinToString() }:\n")
|
actual.append("Targets dependent on ${chunk.targets.joinToString() }:\n")
|
||||||
actual.append(getDependentTargets(chunk, context).map { it.toString() }.sorted().joinToString("\n"))
|
actual.append(getDependentTargets(chunk.targets, context).map { it.toString() }.sorted().joinToString("\n"))
|
||||||
actual.append("\n---------\n")
|
actual.append("\n---------\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,13 +23,18 @@ import org.jetbrains.jps.builders.BuildTarget
|
|||||||
import org.jetbrains.jps.builders.java.dependencyView.Mappings
|
import org.jetbrains.jps.builders.java.dependencyView.Mappings
|
||||||
import org.jetbrains.jps.incremental.CompileContext
|
import org.jetbrains.jps.incremental.CompileContext
|
||||||
import org.jetbrains.jps.incremental.FSOperations
|
import org.jetbrains.jps.incremental.FSOperations
|
||||||
|
import org.jetbrains.jps.incremental.ModuleBuildTarget
|
||||||
import org.jetbrains.jps.incremental.fs.CompilationRound
|
import org.jetbrains.jps.incremental.fs.CompilationRound
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.util.HashMap
|
import java.util.HashMap
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Entry point for safely marking files as dirty.
|
||||||
|
*/
|
||||||
class FSOperationsHelper(
|
class FSOperationsHelper(
|
||||||
private val compileContext: CompileContext,
|
private val compileContext: CompileContext,
|
||||||
private val chunk: ModuleChunk,
|
private val chunk: ModuleChunk,
|
||||||
|
private val dirtyFilesHolder: KotlinDirtySourceFilesHolder,
|
||||||
private val log: Logger
|
private val log: Logger
|
||||||
) {
|
) {
|
||||||
private val moduleBasedFilter = ModulesBasedFileFilter(compileContext, chunk)
|
private val moduleBasedFilter = ModulesBasedFileFilter(compileContext, chunk)
|
||||||
@@ -56,27 +61,46 @@ class FSOperationsHelper(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun markFilesBeforeInitialRound(files: Iterable<File>) {
|
internal fun markFilesForCurrentRound(files: Iterable<File>) {
|
||||||
markFilesImpl(files, beforeRound = true) { it.exists() && moduleBasedFilter.accept(it) }
|
files.forEach {
|
||||||
|
val root = compileContext.projectDescriptor.buildRootIndex.findJavaRootDescriptor(compileContext, it)
|
||||||
|
if (root != null) dirtyFilesHolder.byTarget[root.target]?._markDirty(it)
|
||||||
|
}
|
||||||
|
|
||||||
|
markFilesImpl(files, currentRound = true) { it.exists() && moduleBasedFilter.accept(it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Marks given [files] as dirty for current round and given [target] of [chunk].
|
||||||
|
*/
|
||||||
|
fun markFilesForCurrentRound(target: ModuleBuildTarget, files: Iterable<File>) {
|
||||||
|
require(target in chunk.targets)
|
||||||
|
|
||||||
|
val targetDirtyFiles = dirtyFilesHolder.byTarget[target]!!
|
||||||
|
files.forEach {
|
||||||
|
targetDirtyFiles._markDirty(it)
|
||||||
|
}
|
||||||
|
|
||||||
|
markFilesImpl(files, currentRound = true) { it.exists() }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun markFiles(files: Iterable<File>) {
|
fun markFiles(files: Iterable<File>) {
|
||||||
markFilesImpl(files, beforeRound = false) { it.exists() }
|
markFilesImpl(files, currentRound = false) { it.exists() }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun markInChunkOrDependents(files: Iterable<File>, excludeFiles: Set<File>) {
|
fun markInChunkOrDependents(files: Iterable<File>, excludeFiles: Set<File>) {
|
||||||
markFilesImpl(files, beforeRound = false) { it !in excludeFiles && it.exists() && moduleBasedFilter.accept(it) }
|
markFilesImpl(files, currentRound = false) { it !in excludeFiles && it.exists() && moduleBasedFilter.accept(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
private inline fun markFilesImpl(
|
private inline fun markFilesImpl(
|
||||||
files: Iterable<File>,
|
files: Iterable<File>,
|
||||||
beforeRound: Boolean,
|
currentRound: Boolean,
|
||||||
shouldMark: (File) -> Boolean
|
shouldMark: (File) -> Boolean
|
||||||
) {
|
) {
|
||||||
val filesToMark = files.filterTo(HashSet(), shouldMark)
|
val filesToMark = files.filterTo(HashSet(), shouldMark)
|
||||||
if (filesToMark.isEmpty()) return
|
if (filesToMark.isEmpty()) return
|
||||||
|
|
||||||
val compilationRound = if (beforeRound) {
|
val compilationRound = if (currentRound) {
|
||||||
buildLogger?.markedAsDirtyBeforeRound(filesToMark)
|
buildLogger?.markedAsDirtyBeforeRound(filesToMark)
|
||||||
CompilationRound.CURRENT
|
CompilationRound.CURRENT
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -118,7 +118,16 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
|
|||||||
|
|
||||||
if (targets.none { hasKotlin[it] == true }) return
|
if (targets.none { hasKotlin[it] == true }) return
|
||||||
|
|
||||||
val fsOperations = FSOperationsHelper(context, chunk, LOG)
|
val roundDirtyFiles = KotlinDirtySourceFilesHolder(
|
||||||
|
chunk,
|
||||||
|
context,
|
||||||
|
object : DirtyFilesHolderBase<JavaSourceRootDescriptor, ModuleBuildTarget>(context) {
|
||||||
|
override fun processDirtyFiles(processor: FileProcessor<JavaSourceRootDescriptor, ModuleBuildTarget>) {
|
||||||
|
FSOperations.processFilesToRecompile(context, chunk, processor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
val fsOperations = FSOperationsHelper(context, chunk, roundDirtyFiles, LOG)
|
||||||
|
|
||||||
if (System.getProperty(SKIP_CACHE_VERSION_CHECK_PROPERTY) == null) {
|
if (System.getProperty(SKIP_CACHE_VERSION_CHECK_PROPERTY) == null) {
|
||||||
val cacheVersionsProvider = CacheVersionProvider(dataManager.dataPaths)
|
val cacheVersionsProvider = CacheVersionProvider(dataManager.dataPaths)
|
||||||
@@ -142,25 +151,16 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
markAdditionalFilesForInitialRound(chunk, context, fsOperations)
|
markAdditionalFilesForInitialRound(chunk, context, fsOperations, roundDirtyFiles)
|
||||||
buildLogger?.afterBuildStarted(context, chunk)
|
buildLogger?.afterBuildStarted(context, chunk)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun markAdditionalFilesForInitialRound(
|
private fun markAdditionalFilesForInitialRound(
|
||||||
chunk: ModuleChunk,
|
chunk: ModuleChunk,
|
||||||
context: CompileContext,
|
context: CompileContext,
|
||||||
fsOperations: FSOperationsHelper
|
fsOperations: FSOperationsHelper,
|
||||||
|
dirtyFilesHolder: KotlinDirtySourceFilesHolder
|
||||||
) {
|
) {
|
||||||
val roundDirtyFiles = KotlinDirtySourceFilesHolder(
|
|
||||||
chunk,
|
|
||||||
context,
|
|
||||||
fsOperations,
|
|
||||||
object : DirtyFilesHolderBase<JavaSourceRootDescriptor, ModuleBuildTarget>(context) {
|
|
||||||
override fun processDirtyFiles(processor: FileProcessor<JavaSourceRootDescriptor, ModuleBuildTarget>) {
|
|
||||||
FSOperations.processFilesToRecompile(context, chunk, processor)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
val representativeTarget = context.kotlinBuildTargets[chunk.representativeTarget()] ?: return
|
val representativeTarget = context.kotlinBuildTargets[chunk.representativeTarget()] ?: return
|
||||||
|
|
||||||
val incrementalCaches = getIncrementalCaches(chunk, context)
|
val incrementalCaches = getIncrementalCaches(chunk, context)
|
||||||
@@ -177,8 +177,8 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
|
|||||||
val removedClasses = HashSet<String>()
|
val removedClasses = HashSet<String>()
|
||||||
for (target in chunk.targets) {
|
for (target in chunk.targets) {
|
||||||
val cache = incrementalCaches[target] ?: continue
|
val cache = incrementalCaches[target] ?: continue
|
||||||
val dirtyFiles = roundDirtyFiles.getDirtyFiles(target)
|
val dirtyFiles = dirtyFilesHolder.getDirtyFiles(target)
|
||||||
val removedFiles = roundDirtyFiles.getRemovedFilesSet(target)
|
val removedFiles = dirtyFilesHolder.getRemovedFiles(target)
|
||||||
|
|
||||||
val existingClasses = JpsKotlinCompilerRunner().classesFqNamesByFiles(environment, dirtyFiles)
|
val existingClasses = JpsKotlinCompilerRunner().classesFqNamesByFiles(environment, dirtyFiles)
|
||||||
val previousClasses = cache.classesFqNamesBySources(dirtyFiles + removedFiles)
|
val previousClasses = cache.classesFqNamesBySources(dirtyFiles + removedFiles)
|
||||||
@@ -194,7 +194,7 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
|
|||||||
removedClasses.forEach { changesCollector.collectSignature(FqName(it), areSubclassesAffected = true) }
|
removedClasses.forEach { changesCollector.collectSignature(FqName(it), areSubclassesAffected = true) }
|
||||||
val affectedByRemovedClasses = changesCollector.getDirtyFiles(incrementalCaches.values, context.projectDescriptor.dataManager)
|
val affectedByRemovedClasses = changesCollector.getDirtyFiles(incrementalCaches.values, context.projectDescriptor.dataManager)
|
||||||
|
|
||||||
fsOperations.markFilesBeforeInitialRound(affectedByRemovedClasses)
|
fsOperations.markFilesForCurrentRound(affectedByRemovedClasses)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun checkCachesVersions(
|
private fun checkCachesVersions(
|
||||||
@@ -234,10 +234,11 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
|
|||||||
val kotlinTarget = context.kotlinBuildTargets[chunk.representativeTarget()] ?: return OK
|
val kotlinTarget = context.kotlinBuildTargets[chunk.representativeTarget()] ?: return OK
|
||||||
|
|
||||||
val messageCollector = MessageCollectorAdapter(context, kotlinTarget)
|
val messageCollector = MessageCollectorAdapter(context, kotlinTarget)
|
||||||
val fsOperations = FSOperationsHelper(context, chunk, LOG)
|
val kotlinDirtyFilesHolder = KotlinDirtySourceFilesHolder(chunk, context, dirtyFilesHolder)
|
||||||
|
val fsOperations = FSOperationsHelper(context, chunk, kotlinDirtyFilesHolder, LOG)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
val proposedExitCode = doBuild(chunk, kotlinTarget, context, dirtyFilesHolder, messageCollector, outputConsumer, fsOperations)
|
val proposedExitCode = doBuild(chunk, kotlinTarget, context, kotlinDirtyFilesHolder, messageCollector, outputConsumer, fsOperations)
|
||||||
|
|
||||||
val actualExitCode = if (proposedExitCode == OK && fsOperations.hasMarkedDirty) ADDITIONAL_PASS_REQUIRED else proposedExitCode
|
val actualExitCode = if (proposedExitCode == OK && fsOperations.hasMarkedDirty) ADDITIONAL_PASS_REQUIRED else proposedExitCode
|
||||||
|
|
||||||
@@ -260,7 +261,7 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
|
|||||||
chunk: ModuleChunk,
|
chunk: ModuleChunk,
|
||||||
representativeTarget: KotlinModuleBuildTarget,
|
representativeTarget: KotlinModuleBuildTarget,
|
||||||
context: CompileContext,
|
context: CompileContext,
|
||||||
dirtyFilesHolder: DirtyFilesHolder<JavaSourceRootDescriptor, ModuleBuildTarget>,
|
kotlinDirtyFilesHolder: KotlinDirtySourceFilesHolder,
|
||||||
messageCollector: MessageCollectorAdapter,
|
messageCollector: MessageCollectorAdapter,
|
||||||
outputConsumer: OutputConsumer,
|
outputConsumer: OutputConsumer,
|
||||||
fsOperations: FSOperationsHelper
|
fsOperations: FSOperationsHelper
|
||||||
@@ -271,7 +272,6 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
|
|||||||
return NOTHING_DONE
|
return NOTHING_DONE
|
||||||
}
|
}
|
||||||
|
|
||||||
val roundDirtyFilesHolder = KotlinDirtySourceFilesHolder(chunk, context, fsOperations, dirtyFilesHolder)
|
|
||||||
val projectDescriptor = context.projectDescriptor
|
val projectDescriptor = context.projectDescriptor
|
||||||
val dataManager = projectDescriptor.dataManager
|
val dataManager = projectDescriptor.dataManager
|
||||||
val targets = chunk.targets
|
val targets = chunk.targets
|
||||||
@@ -280,7 +280,7 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
|
|||||||
val isChunkRebuilding = JavaBuilderUtil.isForcedRecompilationAllJavaModules(context)
|
val isChunkRebuilding = JavaBuilderUtil.isForcedRecompilationAllJavaModules(context)
|
||||||
|| targets.any { rebuildAfterCacheVersionChanged[it] == true }
|
|| targets.any { rebuildAfterCacheVersionChanged[it] == true }
|
||||||
|
|
||||||
if (roundDirtyFilesHolder.hasDirtyOrRemovedFiles) {
|
if (kotlinDirtyFilesHolder.hasDirtyOrRemovedFiles) {
|
||||||
if (!isChunkRebuilding && !IncrementalCompilation.isEnabled()) {
|
if (!isChunkRebuilding && !IncrementalCompilation.isEnabled()) {
|
||||||
targets.forEach { rebuildAfterCacheVersionChanged[it] = true }
|
targets.forEach { rebuildAfterCacheVersionChanged[it] = true }
|
||||||
return CHUNK_REBUILD_REQUIRED
|
return CHUNK_REBUILD_REQUIRED
|
||||||
@@ -319,13 +319,13 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (LOG.isDebugEnabled) {
|
if (LOG.isDebugEnabled) {
|
||||||
LOG.debug("Compiling files: ${roundDirtyFilesHolder.dirtyFiles}")
|
LOG.debug("Compiling files: ${kotlinDirtyFilesHolder.allDirtyFiles}")
|
||||||
}
|
}
|
||||||
|
|
||||||
val start = System.nanoTime()
|
val start = System.nanoTime()
|
||||||
val outputItemCollector = doCompileModuleChunk(
|
val outputItemCollector = doCompileModuleChunk(
|
||||||
chunk, representativeTarget, commonArguments, context, roundDirtyFilesHolder, environment,
|
chunk, representativeTarget, commonArguments, context, kotlinDirtyFilesHolder, fsOperations,
|
||||||
incrementalCaches
|
environment, incrementalCaches
|
||||||
)
|
)
|
||||||
|
|
||||||
statisticsLogger.registerStatistic(chunk, System.nanoTime() - start)
|
statisticsLogger.registerStatistic(chunk, System.nanoTime() - start)
|
||||||
@@ -348,7 +348,7 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
|
|||||||
saveVersions(context, chunk, commonArguments)
|
saveVersions(context, chunk, commonArguments)
|
||||||
|
|
||||||
if (targets.any { hasKotlin[it] == null }) {
|
if (targets.any { hasKotlin[it] == null }) {
|
||||||
fsOperations.markChunk(recursively = false, kotlinOnly = true, excludeFiles = roundDirtyFilesHolder.dirtyFiles)
|
fsOperations.markChunk(recursively = false, kotlinOnly = true, excludeFiles = kotlinDirtyFilesHolder.allDirtyFiles)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (target in targets) {
|
for (target in targets) {
|
||||||
@@ -362,7 +362,7 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
|
|||||||
|
|
||||||
representativeTarget.updateChunkMappings(
|
representativeTarget.updateChunkMappings(
|
||||||
chunk,
|
chunk,
|
||||||
roundDirtyFilesHolder,
|
kotlinDirtyFilesHolder,
|
||||||
generatedFiles,
|
generatedFiles,
|
||||||
incrementalCaches
|
incrementalCaches
|
||||||
)
|
)
|
||||||
@@ -383,11 +383,11 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
|
|||||||
kotlinModuleBuilderTarget.updateCaches(incrementalCaches[target]!!, files, changesCollector, environment)
|
kotlinModuleBuilderTarget.updateCaches(incrementalCaches[target]!!, files, changesCollector, environment)
|
||||||
}
|
}
|
||||||
|
|
||||||
updateLookupStorage(lookupTracker, dataManager, roundDirtyFilesHolder)
|
updateLookupStorage(lookupTracker, dataManager, kotlinDirtyFilesHolder)
|
||||||
|
|
||||||
if (!isChunkRebuilding) {
|
if (!isChunkRebuilding) {
|
||||||
changesCollector.processChangesUsingLookups(
|
changesCollector.processChangesUsingLookups(
|
||||||
roundDirtyFilesHolder.dirtyFiles,
|
kotlinDirtyFilesHolder.allDirtyFiles,
|
||||||
dataManager,
|
dataManager,
|
||||||
fsOperations,
|
fsOperations,
|
||||||
incrementalCaches.values
|
incrementalCaches.values
|
||||||
@@ -499,6 +499,7 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
|
|||||||
commonArguments: CommonCompilerArguments,
|
commonArguments: CommonCompilerArguments,
|
||||||
context: CompileContext,
|
context: CompileContext,
|
||||||
dirtyFilesHolder: KotlinDirtySourceFilesHolder,
|
dirtyFilesHolder: KotlinDirtySourceFilesHolder,
|
||||||
|
fsOperations: FSOperationsHelper,
|
||||||
environment: JpsCompilerEnvironment,
|
environment: JpsCompilerEnvironment,
|
||||||
incrementalCaches: Map<ModuleBuildTarget, JpsIncrementalCache>
|
incrementalCaches: Map<ModuleBuildTarget, JpsIncrementalCache>
|
||||||
): OutputItemsCollector? {
|
): OutputItemsCollector? {
|
||||||
@@ -528,15 +529,10 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
|
|||||||
val targetDirtyFiles = dirtyFilesHolder.byTarget[target]
|
val targetDirtyFiles = dirtyFilesHolder.byTarget[target]
|
||||||
|
|
||||||
if (cache != null && targetDirtyFiles != null) {
|
if (cache != null && targetDirtyFiles != null) {
|
||||||
val removedAndDirtyFiles: MutableSet<File> = mutableSetOf()
|
val complementaryFiles = cache.clearComplementaryFilesMapping(targetDirtyFiles.dirty + targetDirtyFiles.removed)
|
||||||
|
fsOperations.markFilesForCurrentRound(target, complementaryFiles)
|
||||||
|
|
||||||
removedAndDirtyFiles.addAll(dirtyFilesHolder.getDirtyFiles(target))
|
cache.markDirty(targetDirtyFiles.dirty + targetDirtyFiles.removed)
|
||||||
removedAndDirtyFiles.addAll(dirtyFilesHolder.getRemovedFilesSet(target))
|
|
||||||
|
|
||||||
val complementaryFiles = cache.clearComplementaryFilesMapping(targetDirtyFiles.dirtyOrRemovedFiles)
|
|
||||||
targetDirtyFiles.markDirtyForCurrentRound(complementaryFiles)
|
|
||||||
|
|
||||||
cache.markDirty(targetDirtyFiles.dirtyOrRemovedFiles)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -644,7 +640,7 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
|
|||||||
throw AssertionError("Lookup tracker is expected to be LookupTrackerImpl, got ${lookupTracker::class.java}")
|
throw AssertionError("Lookup tracker is expected to be LookupTrackerImpl, got ${lookupTracker::class.java}")
|
||||||
|
|
||||||
dataManager.withLookupStorage { lookupStorage ->
|
dataManager.withLookupStorage { lookupStorage ->
|
||||||
lookupStorage.removeLookupsFrom(dirtyFilesHolder.dirtyOrRemovedFilesSet.asSequence())
|
lookupStorage.removeLookupsFrom(dirtyFilesHolder.allDirtyFiles.asSequence() + dirtyFilesHolder.allRemovedFilesFiles.asSequence())
|
||||||
lookupStorage.addAll(lookupTracker.lookups.entrySet(), lookupTracker.pathInterner.values)
|
lookupStorage.addAll(lookupTracker.lookups.entrySet(), lookupTracker.pathInterner.values)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,8 +19,6 @@ package org.jetbrains.kotlin.jps.build
|
|||||||
import com.intellij.openapi.util.io.FileUtilRt
|
import com.intellij.openapi.util.io.FileUtilRt
|
||||||
import org.jetbrains.jps.ModuleChunk
|
import org.jetbrains.jps.ModuleChunk
|
||||||
import org.jetbrains.jps.builders.DirtyFilesHolder
|
import org.jetbrains.jps.builders.DirtyFilesHolder
|
||||||
import org.jetbrains.jps.builders.FileProcessor
|
|
||||||
import org.jetbrains.jps.builders.impl.DirtyFilesHolderBase
|
|
||||||
import org.jetbrains.jps.builders.java.JavaSourceRootDescriptor
|
import org.jetbrains.jps.builders.java.JavaSourceRootDescriptor
|
||||||
import org.jetbrains.jps.incremental.CompileContext
|
import org.jetbrains.jps.incremental.CompileContext
|
||||||
import org.jetbrains.jps.incremental.ModuleBuildTarget
|
import org.jetbrains.jps.incremental.ModuleBuildTarget
|
||||||
@@ -30,59 +28,44 @@ import java.io.File
|
|||||||
* Holding kotlin dirty files list for particular build round.
|
* Holding kotlin dirty files list for particular build round.
|
||||||
* Dirty and removed files set are initialized from [delegate].
|
* Dirty and removed files set are initialized from [delegate].
|
||||||
*
|
*
|
||||||
* Probably should be merged with [FSOperationsHelper]
|
* Additional dirty files should be added only through [FSOperationsHelper.markFilesForCurrentRound]
|
||||||
*/
|
*/
|
||||||
class KotlinDirtySourceFilesHolder(
|
class KotlinDirtySourceFilesHolder(
|
||||||
val chunk: ModuleChunk,
|
val chunk: ModuleChunk,
|
||||||
val context: CompileContext,
|
val context: CompileContext,
|
||||||
val fsOperations: FSOperationsHelper,
|
|
||||||
delegate: DirtyFilesHolder<JavaSourceRootDescriptor, ModuleBuildTarget>
|
delegate: DirtyFilesHolder<JavaSourceRootDescriptor, ModuleBuildTarget>
|
||||||
) : DirtyFilesHolderBase<JavaSourceRootDescriptor, ModuleBuildTarget>(context) {
|
) {
|
||||||
val byTarget: Map<ModuleBuildTarget, TargetFiles>
|
val byTarget: Map<ModuleBuildTarget, TargetFiles>
|
||||||
|
|
||||||
inner class TargetFiles(val target: ModuleBuildTarget, val removed: Collection<String>) {
|
inner class TargetFiles(val target: ModuleBuildTarget, val removed: Collection<File>) {
|
||||||
val dirty: MutableSet<DirtyFile> = mutableSetOf()
|
private val _dirty: MutableSet<File> = mutableSetOf()
|
||||||
|
|
||||||
val dirtyOrRemovedFiles: Set<File>
|
val dirty: Set<File>
|
||||||
get() {
|
get() = _dirty
|
||||||
val result = mutableSetOf<File>()
|
|
||||||
dirty.forEach { result.add(it.file) }
|
|
||||||
removed.forEach { result.add(File(it)) }
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
fun markDirtyForCurrentRound(files: Collection<File>) {
|
/**
|
||||||
fsOperations.markFilesBeforeInitialRound(files)
|
* Should be called only from [FSOperationsHelper.markFilesForCurrentRound]
|
||||||
files.forEach {
|
* and during KotlinDirtySourceFilesHolder initialization.
|
||||||
dirty.add(DirtyFile(it, null))
|
*/
|
||||||
}
|
internal fun _markDirty(file: File) {
|
||||||
|
_dirty.add(file)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data class DirtyFile(val file: File, val root: JavaSourceRootDescriptor?)
|
|
||||||
|
|
||||||
val hasRemovedFiles: Boolean
|
val hasRemovedFiles: Boolean
|
||||||
|
get() = byTarget.any { it.value.removed.isNotEmpty() }
|
||||||
override fun hasRemovedFiles(): Boolean = hasRemovedFiles
|
|
||||||
|
|
||||||
val hasDirtyFiles: Boolean
|
val hasDirtyFiles: Boolean
|
||||||
|
get() = byTarget.any { it.value.dirty.isNotEmpty() }
|
||||||
override fun hasDirtyFiles(): Boolean = hasDirtyFiles
|
|
||||||
|
|
||||||
val hasDirtyOrRemovedFiles: Boolean
|
val hasDirtyOrRemovedFiles: Boolean
|
||||||
get() = hasRemovedFiles || hasDirtyFiles
|
get() = hasRemovedFiles || hasDirtyFiles
|
||||||
|
|
||||||
init {
|
init {
|
||||||
val byTarget = mutableMapOf<ModuleBuildTarget, TargetFiles>()
|
val byTarget = mutableMapOf<ModuleBuildTarget, TargetFiles>()
|
||||||
var hasDirtyFiles = false
|
|
||||||
var hasRemovedFiles = false
|
|
||||||
|
|
||||||
chunk.targets.forEach { target ->
|
chunk.targets.forEach { target ->
|
||||||
val removedFiles = delegate.getRemovedFiles(target)
|
val removedFiles = delegate.getRemovedFiles(target).map { File(it) }
|
||||||
if (removedFiles.isNotEmpty()) {
|
|
||||||
hasRemovedFiles = true
|
|
||||||
}
|
|
||||||
|
|
||||||
byTarget[target] = TargetFiles(target, removedFiles)
|
byTarget[target] = TargetFiles(target, removedFiles)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -91,50 +74,26 @@ class KotlinDirtySourceFilesHolder(
|
|||||||
?: error("processDirtyFiles should callback only on chunk `$chunk` targets (`$target` is not)")
|
?: error("processDirtyFiles should callback only on chunk `$chunk` targets (`$target` is not)")
|
||||||
|
|
||||||
if (file.isKotlinSourceFile) {
|
if (file.isKotlinSourceFile) {
|
||||||
targetInfo.dirty.add(DirtyFile(file, root))
|
targetInfo._markDirty(file)
|
||||||
hasDirtyFiles = true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
this.byTarget = byTarget
|
this.byTarget = byTarget
|
||||||
this.hasRemovedFiles = hasRemovedFiles
|
|
||||||
this.hasDirtyFiles = hasDirtyFiles
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun processDirtyFiles(processor: FileProcessor<JavaSourceRootDescriptor, ModuleBuildTarget>) {
|
|
||||||
for ((target, info) in byTarget) {
|
|
||||||
info.dirty.forEach {
|
|
||||||
if (!processor.apply(target, it.file, it.root)) return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getDirtyFiles(target: ModuleBuildTarget): Set<File> =
|
fun getDirtyFiles(target: ModuleBuildTarget): Set<File> =
|
||||||
byTarget[target]?.dirty?.mapTo(mutableSetOf()) { it.file } ?: setOf()
|
byTarget[target]?.dirty ?: setOf()
|
||||||
|
|
||||||
fun getRemovedFilesSet(target: ModuleBuildTarget): Set<File> =
|
fun getRemovedFiles(target: ModuleBuildTarget): Collection<File> =
|
||||||
byTarget[target]?.removed?.mapTo(mutableSetOf()) { File(it) } ?: setOf()
|
byTarget[target]?.removed ?: listOf()
|
||||||
|
|
||||||
override fun getRemovedFiles(target: ModuleBuildTarget): Collection<String> =
|
val allDirtyFiles: Set<File>
|
||||||
byTarget.flatMap { it.value.removed }
|
get() = byTarget.flatMapTo(mutableSetOf()) { it.value.dirty }
|
||||||
|
|
||||||
val removedFilesCount
|
val allRemovedFilesFiles
|
||||||
get() = byTarget.values.flatMapTo(mutableSetOf()) { it.removed }.size
|
get() = byTarget.flatMapTo(mutableSetOf()) { it.value.removed }
|
||||||
|
|
||||||
val dirtyFiles: Set<File>
|
|
||||||
get() = byTarget.flatMapTo(mutableSetOf()) { it.value.dirty.map { it.file } }
|
|
||||||
|
|
||||||
val dirtyOrRemovedFilesSet: Set<File>
|
|
||||||
get() {
|
|
||||||
val result = mutableSetOf<File>()
|
|
||||||
byTarget.forEach {
|
|
||||||
it.value.dirty.forEach { result.add(it.file) }
|
|
||||||
it.value.removed.forEach { result.add(File(it)) }
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val File.isKotlinSourceFile: Boolean
|
val File.isKotlinSourceFile: Boolean
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import java.io.File
|
|||||||
|
|
||||||
class MessageCollectorAdapter(
|
class MessageCollectorAdapter(
|
||||||
private val context: CompileContext,
|
private val context: CompileContext,
|
||||||
val kotlinTarget: KotlinModuleBuildTarget?
|
private val kotlinTarget: KotlinModuleBuildTarget?
|
||||||
) : MessageCollector {
|
) : MessageCollector {
|
||||||
private var hasErrors = false
|
private var hasErrors = false
|
||||||
|
|
||||||
|
|||||||
@@ -133,7 +133,7 @@ class KotlinJvmModuleBuildTarget(compileContext: CompileContext, jpsModuleBuildT
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
val filesSet = dirtyFilesHolder.dirtyFiles
|
val filesSet = dirtyFilesHolder.allDirtyFiles
|
||||||
|
|
||||||
val moduleFile = generateModuleDescription(chunk, dirtyFilesHolder)
|
val moduleFile = generateModuleDescription(chunk, dirtyFilesHolder)
|
||||||
if (moduleFile == null) {
|
if (moduleFile == null) {
|
||||||
@@ -150,7 +150,7 @@ class KotlinJvmModuleBuildTarget(compileContext: CompileContext, jpsModuleBuildT
|
|||||||
val module = chunk.representativeTarget().module
|
val module = chunk.representativeTarget().module
|
||||||
|
|
||||||
if (KotlinBuilder.LOG.isDebugEnabled) {
|
if (KotlinBuilder.LOG.isDebugEnabled) {
|
||||||
val totalRemovedFiles = dirtyFilesHolder.removedFilesCount
|
val totalRemovedFiles = dirtyFilesHolder.allRemovedFilesFiles.size
|
||||||
KotlinBuilder.LOG.debug("Compiling to JVM ${filesSet.size} files"
|
KotlinBuilder.LOG.debug("Compiling to JVM ${filesSet.size} files"
|
||||||
+ (if (totalRemovedFiles == 0) "" else " ($totalRemovedFiles removed files)")
|
+ (if (totalRemovedFiles == 0) "" else " ($totalRemovedFiles removed files)")
|
||||||
+ " in " + chunk.targets.joinToString { it.presentableName })
|
+ " in " + chunk.targets.joinToString { it.presentableName })
|
||||||
@@ -303,7 +303,7 @@ class KotlinJvmModuleBuildTarget(compileContext: CompileContext, jpsModuleBuildT
|
|||||||
|
|
||||||
val targetDirtyFiles: Map<ModuleBuildTarget, Set<File>> = chunk.targets.keysToMap {
|
val targetDirtyFiles: Map<ModuleBuildTarget, Set<File>> = chunk.targets.keysToMap {
|
||||||
val files = HashSet<File>()
|
val files = HashSet<File>()
|
||||||
dirtyFilesHolder.getRemovedFiles(it).mapTo(files, ::File)
|
files.addAll(dirtyFilesHolder.getRemovedFiles(it))
|
||||||
files.addAll(dirtyFilesHolder.getDirtyFiles(it))
|
files.addAll(dirtyFilesHolder.getDirtyFiles(it))
|
||||||
files
|
files
|
||||||
}
|
}
|
||||||
@@ -336,7 +336,7 @@ class KotlinJvmModuleBuildTarget(compileContext: CompileContext, jpsModuleBuildT
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val allCompiled = dirtyFilesHolder.dirtyFiles
|
val allCompiled = dirtyFilesHolder.allDirtyFiles
|
||||||
JavaBuilderUtil.registerFilesToCompile(context, allCompiled)
|
JavaBuilderUtil.registerFilesToCompile(context, allCompiled)
|
||||||
JavaBuilderUtil.registerSuccessfullyCompiled(context, allCompiled)
|
JavaBuilderUtil.registerSuccessfullyCompiled(context, allCompiled)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user