Refactoring: introduce class ChangedFiles
This commit is contained in:
+22
@@ -0,0 +1,22 @@
|
|||||||
|
package org.jetbrains.kotlin.gradle.tasks
|
||||||
|
|
||||||
|
import org.gradle.api.tasks.incremental.IncrementalTaskInputs
|
||||||
|
import java.io.File
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
internal sealed class ChangedFiles {
|
||||||
|
class Known(val modified: List<File>, val removed: List<File>) : ChangedFiles()
|
||||||
|
class Unknown : ChangedFiles()
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun ChangedFiles(taskInputs: IncrementalTaskInputs): ChangedFiles {
|
||||||
|
if (!taskInputs.isIncremental) return ChangedFiles.Unknown()
|
||||||
|
|
||||||
|
val modified = ArrayList<File>()
|
||||||
|
val removed = ArrayList<File>()
|
||||||
|
|
||||||
|
taskInputs.outOfDate { modified.add(it.file) }
|
||||||
|
taskInputs.removed { removed.add(it.file) }
|
||||||
|
|
||||||
|
return ChangedFiles.Known(modified, removed)
|
||||||
|
}
|
||||||
+26
-35
@@ -77,31 +77,29 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments>() : AbstractCo
|
|||||||
|
|
||||||
@TaskAction
|
@TaskAction
|
||||||
fun execute(inputs: IncrementalTaskInputs): Unit {
|
fun execute(inputs: IncrementalTaskInputs): Unit {
|
||||||
logger.kotlinDebug("all sources ${getSource().joinToString { it.path }}")
|
val allKotlinSources = getKotlinSources()
|
||||||
logger.kotlinDebug("is incremental == ${inputs.isIncremental}")
|
logger.kotlinDebug { "all kotlin sources: ${filesToString(allKotlinSources)}" }
|
||||||
val modified = arrayListOf<File>()
|
|
||||||
val removed = arrayListOf<File>()
|
if (allKotlinSources.isEmpty()) {
|
||||||
if (inputs.isIncremental) {
|
|
||||||
inputs.outOfDate { modified.add(it.file) }
|
|
||||||
inputs.removed { removed.add(it.file) }
|
|
||||||
}
|
|
||||||
logger.kotlinDebug("modified ${modified.joinToString { it.path }}")
|
|
||||||
logger.kotlinDebug("removed ${removed.joinToString { it.path }}")
|
|
||||||
val sources = getKotlinSources()
|
|
||||||
if (sources.isEmpty()) {
|
|
||||||
logger.kotlinDebug { "No Kotlin files found, skipping Kotlin compiler task" }
|
logger.kotlinDebug { "No Kotlin files found, skipping Kotlin compiler task" }
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
val args = populateCompilerArguments()
|
val args = populateCompilerArguments()
|
||||||
compilerCalled = true
|
compilerCalled = true
|
||||||
callCompiler(args, sources, inputs.isIncremental, modified, removed)
|
callCompiler(args, allKotlinSources, ChangedFiles(inputs))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getKotlinSources(): List<File> = (getSource() as Iterable<File>).filter { it.isKotlinFile() }
|
private fun getKotlinSources(): List<File> = (getSource() as Iterable<File>).filter(File::isKotlinFile)
|
||||||
|
|
||||||
protected abstract fun callCompiler(args: T, allKotlinSources: List<File>, isIncremental: Boolean, modified: List<File>, removed: List<File>)
|
internal abstract fun callCompiler(args: T, allKotlinSources: List<File>, changedFiles: ChangedFiles)
|
||||||
|
|
||||||
|
internal fun relativePathOrCanonical(file: File): String =
|
||||||
|
file.relativeToOrNull(project.rootProject.projectDir)?.path
|
||||||
|
?: file.canonicalPath
|
||||||
|
|
||||||
|
internal fun filesToString(files: Iterable<File>) =
|
||||||
|
"[" + files.map { relativePathOrCanonical(it) }.sorted().joinToString(separator = ", \n") + "]"
|
||||||
}
|
}
|
||||||
|
|
||||||
open class KotlinCompile : AbstractKotlinCompile<K2JVMCompilerArguments>(), KotlinJvmCompile {
|
open class KotlinCompile : AbstractKotlinCompile<K2JVMCompilerArguments>(), KotlinJvmCompile {
|
||||||
@@ -175,9 +173,8 @@ open class KotlinCompile : AbstractKotlinCompile<K2JVMCompilerArguments>(), Kotl
|
|||||||
return args
|
return args
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun callCompiler(args: K2JVMCompilerArguments, allKotlinSources: List<File>, isIncrementalRequested: Boolean, modified: List<File>, removed: List<File>) {
|
override fun callCompiler(args: K2JVMCompilerArguments, allKotlinSources: List<File>, changedFiles: ChangedFiles) {
|
||||||
val outputDir = destinationDir
|
val outputDir = destinationDir
|
||||||
var currentRemoved = removed.filter { it.isKotlinFile() }
|
|
||||||
val logAction = { logStr: String -> logger.kotlinInfo(logStr) }
|
val logAction = { logStr: String -> logger.kotlinInfo(logStr) }
|
||||||
val relativePathOrCanonical = { file: File -> relativePathOrCanonical(file) }
|
val relativePathOrCanonical = { file: File -> relativePathOrCanonical(file) }
|
||||||
|
|
||||||
@@ -221,7 +218,7 @@ open class KotlinCompile : AbstractKotlinCompile<K2JVMCompilerArguments>(), Kotl
|
|||||||
return ChangesEither.Known(symbols, fqNames)
|
return ChangesEither.Known(symbols, fqNames)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun calculateSourcesToCompile(javaFilesProcessor: ChangedJavaFilesProcessor, caches: IncrementalCachesManager, lastBuildInfo: BuildInfo?): Pair<Set<File>, Boolean> {
|
fun calculateSourcesToCompile(javaFilesProcessor: ChangedJavaFilesProcessor, caches: IncrementalCachesManager, lastBuildInfo: BuildInfo?, changedFiles: ChangedFiles): Pair<Set<File>, Boolean> {
|
||||||
fun rebuild(reason: String): Pair<Set<File>, Boolean> {
|
fun rebuild(reason: String): Pair<Set<File>, Boolean> {
|
||||||
logger.kotlinInfo("Non-incremental compilation will be performed: $reason")
|
logger.kotlinInfo("Non-incremental compilation will be performed: $reason")
|
||||||
caches.clean()
|
caches.clean()
|
||||||
@@ -230,15 +227,15 @@ open class KotlinCompile : AbstractKotlinCompile<K2JVMCompilerArguments>(), Kotl
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!incremental) return rebuild("incremental compilation is not enabled")
|
if (!incremental) return rebuild("incremental compilation is not enabled")
|
||||||
if (!isIncrementalRequested) return rebuild("inputs' changes are unknown (first or clean build)")
|
if (changedFiles !is ChangedFiles.Known) return rebuild("inputs' changes are unknown (first or clean build)")
|
||||||
|
|
||||||
val removedClassFiles = removed.filter(File::isClassFile)
|
val removedClassFiles = changedFiles.removed.filter(File::isClassFile)
|
||||||
if (removedClassFiles.any()) return rebuild("Removed class files: ${filesToString(removedClassFiles)}")
|
if (removedClassFiles.any()) return rebuild("Removed class files: ${filesToString(removedClassFiles)}")
|
||||||
|
|
||||||
val modifiedClassFiles = modified.filter(File::isClassFile)
|
val modifiedClassFiles = changedFiles.modified.filter(File::isClassFile)
|
||||||
if (modifiedClassFiles.any()) return rebuild("Modified class files: ${filesToString(modifiedClassFiles)}")
|
if (modifiedClassFiles.any()) return rebuild("Modified class files: ${filesToString(modifiedClassFiles)}")
|
||||||
|
|
||||||
val modifiedClasspathEntries = modified.filter { it in classpath }
|
val modifiedClasspathEntries = changedFiles.modified.filter { it in classpath }
|
||||||
val classpathChanges = getClasspathChanges(modifiedClasspathEntries, lastBuildInfo)
|
val classpathChanges = getClasspathChanges(modifiedClasspathEntries, lastBuildInfo)
|
||||||
if (classpathChanges is ChangesEither.Unknown) {
|
if (classpathChanges is ChangesEither.Unknown) {
|
||||||
return rebuild("could not get changes from modified classpath entries: ${filesToString(modifiedClasspathEntries)}")
|
return rebuild("could not get changes from modified classpath entries: ${filesToString(modifiedClasspathEntries)}")
|
||||||
@@ -247,15 +244,15 @@ open class KotlinCompile : AbstractKotlinCompile<K2JVMCompilerArguments>(), Kotl
|
|||||||
throw AssertionError("Unknown implementation of ChangesEither: ${classpathChanges.javaClass}")
|
throw AssertionError("Unknown implementation of ChangesEither: ${classpathChanges.javaClass}")
|
||||||
}
|
}
|
||||||
val javaFilesDiff = FileCollectionDiff(
|
val javaFilesDiff = FileCollectionDiff(
|
||||||
newOrModified = modified.filter { it.isJavaFile() },
|
newOrModified = changedFiles.modified.filter(File::isJavaFile),
|
||||||
removed = removed.filter { it.isJavaFile() })
|
removed = changedFiles.removed.filter(File::isJavaFile))
|
||||||
val javaFilesChanges = javaFilesProcessor.process(javaFilesDiff)
|
val javaFilesChanges = javaFilesProcessor.process(javaFilesDiff)
|
||||||
val affectedJavaSymbols = when (javaFilesChanges) {
|
val affectedJavaSymbols = when (javaFilesChanges) {
|
||||||
is ChangesEither.Known -> javaFilesChanges.lookupSymbols
|
is ChangesEither.Known -> javaFilesChanges.lookupSymbols
|
||||||
is ChangesEither.Unknown -> return rebuild("Could not get changes for java files")
|
is ChangesEither.Unknown -> return rebuild("Could not get changes for java files")
|
||||||
}
|
}
|
||||||
|
|
||||||
val dirtyFiles = modified.filter { it.isKotlinFile() }.toMutableSet()
|
val dirtyFiles = changedFiles.modified.filter(File::isKotlinFile).toMutableSet()
|
||||||
val lookupSymbols = HashSet<LookupSymbol>()
|
val lookupSymbols = HashSet<LookupSymbol>()
|
||||||
lookupSymbols.addAll(affectedJavaSymbols)
|
lookupSymbols.addAll(affectedJavaSymbols)
|
||||||
lookupSymbols.addAll(classpathChanges.lookupSymbols)
|
lookupSymbols.addAll(classpathChanges.lookupSymbols)
|
||||||
@@ -299,8 +296,9 @@ open class KotlinCompile : AbstractKotlinCompile<K2JVMCompilerArguments>(), Kotl
|
|||||||
val caches = IncrementalCachesManager(targetId, cacheDirectory, outputDir)
|
val caches = IncrementalCachesManager(targetId, cacheDirectory, outputDir)
|
||||||
|
|
||||||
// TODO: decide what to do if no files are considered dirty - rebuild or skip the module
|
// TODO: decide what to do if no files are considered dirty - rebuild or skip the module
|
||||||
var (sourcesToCompile, isIncrementalDecided) = calculateSourcesToCompile(javaFilesProcessor, caches, lastBuildInfo)
|
var (sourcesToCompile, isIncrementalDecided) = calculateSourcesToCompile(javaFilesProcessor, caches, lastBuildInfo, changedFiles)
|
||||||
compileIncrementally(allGeneratedFiles, args, caches, currentRemoved, isIncrementalDecided, javaFilesProcessor, logAction, lookupTracker, outputDir, relativePathOrCanonical, allKotlinSources, sourcesToCompile, targetId)
|
val currentRemoved = (changedFiles as? ChangedFiles.Known)?.removed?.filter(File::isKotlinFile) ?: emptyList()
|
||||||
|
compileIncrementally(args, caches, currentRemoved, isIncrementalDecided, javaFilesProcessor, logAction, lookupTracker, outputDir, relativePathOrCanonical, allKotlinSources, sourcesToCompile, targetId)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun compileIncrementally(
|
private fun compileIncrementally(
|
||||||
@@ -424,13 +422,6 @@ open class KotlinCompile : AbstractKotlinCompile<K2JVMCompilerArguments>(), Kotl
|
|||||||
processCompilerExitCode(exitCode)
|
processCompilerExitCode(exitCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun relativePathOrCanonical(file: File): String =
|
|
||||||
file.relativeToOrNull(project.rootProject.projectDir)?.path
|
|
||||||
?: file.canonicalPath
|
|
||||||
|
|
||||||
private fun filesToString(files: Iterable<File>) =
|
|
||||||
"[" + files.map { relativePathOrCanonical(it) }.sorted().joinToString(separator = ", \n") + "]"
|
|
||||||
|
|
||||||
private fun cleanupOnError() {
|
private fun cleanupOnError() {
|
||||||
logger.kotlinInfo("deleting $destinationDir on error")
|
logger.kotlinInfo("deleting $destinationDir on error")
|
||||||
destinationDir.deleteRecursively()
|
destinationDir.deleteRecursively()
|
||||||
@@ -639,7 +630,7 @@ open class Kotlin2JsCompile() : AbstractKotlinCompile<K2JSCompilerArguments>(),
|
|||||||
return args
|
return args
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun callCompiler(args: K2JSCompilerArguments, allKotlinSources: List<File>, isIncremental: Boolean, modified: List<File>, removed: List<File>) {
|
override fun callCompiler(args: K2JSCompilerArguments, allKotlinSources: List<File>, changedFiles: ChangedFiles) {
|
||||||
val messageCollector = GradleMessageCollector(logger)
|
val messageCollector = GradleMessageCollector(logger)
|
||||||
logger.debug("Calling compiler")
|
logger.debug("Calling compiler")
|
||||||
destinationDir.mkdirs()
|
destinationDir.mkdirs()
|
||||||
|
|||||||
Reference in New Issue
Block a user