Pass classpath changes from KotlinCompile task to Kotlin compiler

This commit wires necessary components only. The actual classpath
changes will be provided later.

Bug: KT-45777
Test: Existing IncrementalCompilationClasspathSnapshotJvmMultiProjectIT
      and IncrementalJavaChangeClasspathSnapshotIT
This commit is contained in:
Hung Nguyen
2021-05-20 11:28:23 +01:00
committed by nataliya.valtman
parent c8b3b6df9c
commit 41345b2c50
7 changed files with 132 additions and 20 deletions

View File

@@ -0,0 +1,76 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.incremental
import org.jetbrains.kotlin.name.FqName
import java.io.ObjectInputStream
import java.io.ObjectOutputStream
import java.io.Serializable
/**
* Changes to the classpath of the `KotlinCompile` task, used to compute the source files that need to be recompiled during an incremental
* run.
*/
sealed class ClasspathChanges : Serializable {
class Available() : ClasspathChanges() {
lateinit var lookupSymbols: List<LookupSymbol>
private set
lateinit var fqNames: List<FqName>
private set
constructor(lookupSymbols: List<LookupSymbol>, fqNames: List<FqName>) : this() {
this.lookupSymbols = lookupSymbols
this.fqNames = fqNames
}
private fun writeObject(out: ObjectOutputStream) {
out.writeInt(lookupSymbols.size)
lookupSymbols.forEach {
out.writeUTF(it.name)
out.writeUTF(it.scope)
}
out.writeInt(fqNames.size)
fqNames.forEach {
out.writeUTF(it.asString())
}
}
private fun readObject(ois: ObjectInputStream) {
val lookupSymbolsSize = ois.readInt()
val lookupSymbols = ArrayList<LookupSymbol>(lookupSymbolsSize)
repeat(lookupSymbolsSize) {
val name = ois.readUTF()
val scope = ois.readUTF()
lookupSymbols.add(LookupSymbol(name, scope))
}
this.lookupSymbols = lookupSymbols
val fqNamesSize = ois.readInt()
val fqNames = ArrayList<FqName>(fqNamesSize)
repeat(fqNamesSize) {
val fqNameString = ois.readUTF()
fqNames.add(FqName(fqNameString))
}
this.fqNames = fqNames
}
companion object {
private const val serialVersionUID = 0L
}
}
sealed class NotAvailable : ClasspathChanges() {
object UnableToCompute : NotAvailable()
object ForNonIncrementalRun : NotAvailable()
object ClasspathSnapshotIsDisabled : NotAvailable()
object ReservedForTestsOnly : NotAvailable()
object ForJSCompiler : NotAvailable()
}
}

View File

@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.daemon.common
import org.jetbrains.kotlin.incremental.ClasspathChanges
import org.jetbrains.kotlin.incremental.IncrementalModuleInfo
import java.io.File
import java.io.Serializable
@@ -52,6 +53,7 @@ class IncrementalCompilationOptions(
val areFileChangesKnown: Boolean,
val modifiedFiles: List<File>?,
val deletedFiles: List<File>?,
val classpathChanges: ClasspathChanges,
val workingDir: File,
compilerMode: CompilerMode,
targetPlatform: CompileService.TargetPlatform,
@@ -87,6 +89,7 @@ class IncrementalCompilationOptions(
"areFileChangesKnown=$areFileChangesKnown, " +
"modifiedFiles=$modifiedFiles, " +
"deletedFiles=$deletedFiles, " +
"classpathChanges=$classpathChanges, " +
"workingDir=$workingDir, " +
"multiModuleICSettings=$multiModuleICSettings, " +
"usePreciseJavaTracking=$usePreciseJavaTracking" +

View File

@@ -601,7 +601,8 @@ abstract class CompileServiceImplBase(
outputFiles = incrementalCompilationOptions.outputFiles,
usePreciseJavaTracking = incrementalCompilationOptions.usePreciseJavaTracking,
modulesApiHistory = modulesApiHistory,
kotlinSourceFilesExtensions = allKotlinExtensions
kotlinSourceFilesExtensions = allKotlinExtensions,
classpathChanges = incrementalCompilationOptions.classpathChanges
)
return try {
compiler.compile(allKotlinFiles, k2jvmArgs, compilerMessageCollector, changedFiles, projectRoot)

View File

@@ -22,6 +22,7 @@ import com.intellij.psi.PsiClass
import com.intellij.psi.PsiFile
import com.intellij.psi.PsiFileFactory
import com.intellij.psi.PsiJavaFile
import org.jetbrains.annotations.TestOnly
import org.jetbrains.kotlin.build.DEFAULT_KOTLIN_SOURCE_FILES_EXTENSIONS
import org.jetbrains.kotlin.build.GeneratedFile
import org.jetbrains.kotlin.build.GeneratedJvmClass
@@ -46,6 +47,11 @@ import org.jetbrains.kotlin.incremental.multiproject.EmptyModulesApiHistory
import org.jetbrains.kotlin.incremental.multiproject.ModulesApiHistory
import org.jetbrains.kotlin.incremental.util.BufferingMessageCollector
import org.jetbrains.kotlin.incremental.util.Either
import org.jetbrains.kotlin.incremental.ClasspathChanges.NotAvailable.UnableToCompute
import org.jetbrains.kotlin.incremental.ClasspathChanges.NotAvailable.ForJSCompiler
import org.jetbrains.kotlin.incremental.ClasspathChanges.NotAvailable.ReservedForTestsOnly
import org.jetbrains.kotlin.incremental.ClasspathChanges.NotAvailable.ForNonIncrementalRun
import org.jetbrains.kotlin.incremental.ClasspathChanges.NotAvailable.ClasspathSnapshotIsDisabled
import org.jetbrains.kotlin.load.java.JavaClassesTracker
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents
@@ -55,6 +61,7 @@ import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import java.io.File
@TestOnly
fun makeIncrementally(
cachesDir: File,
sourceRoots: Iterable<File>,
@@ -80,7 +87,8 @@ fun makeIncrementally(
outputFiles = emptyList(),
buildHistoryFile = buildHistoryFile,
modulesApiHistory = EmptyModulesApiHistory,
kotlinSourceFilesExtensions = kotlinExtensions
kotlinSourceFilesExtensions = kotlinExtensions,
classpathChanges = ReservedForTestsOnly
)
//TODO set properly
compiler.compile(sourceFiles, args, messageCollector, providedChangedFiles = null)
@@ -116,7 +124,8 @@ class IncrementalJvmCompilerRunner(
buildHistoryFile: File,
outputFiles: Collection<File>,
private val modulesApiHistory: ModulesApiHistory,
override val kotlinSourceFilesExtensions: List<String> = DEFAULT_KOTLIN_SOURCE_FILES_EXTENSIONS
override val kotlinSourceFilesExtensions: List<String> = DEFAULT_KOTLIN_SOURCE_FILES_EXTENSIONS,
private val classpathChanges: ClasspathChanges,
) : IncrementalCompilerRunner<K2JVMCompilerArguments, IncrementalJvmCachesManager>(
workingDir,
"caches-jvm",
@@ -208,10 +217,23 @@ class IncrementalJvmCompilerRunner(
val lastBuildInfo = BuildInfo.read(lastBuildInfoFile) ?: return CompilationMode.Rebuild(BuildAttribute.NO_BUILD_HISTORY)
reporter.reportVerbose { "Last Kotlin Build info -- $lastBuildInfo" }
val classpathChanges = reporter.measure(BuildTime.IC_ANALYZE_CHANGES_IN_DEPENDENCIES) {
val scopes = caches.lookupCache.lookupMap.keys.map { if (it.scope.isBlank()) it.name else it.scope }.distinct()
getClasspathChanges(args.classpathAsList, changedFiles, lastBuildInfo, modulesApiHistory, reporter,
abiSnapshots, withSnapshot, caches.platformCache, scopes)
val classpathChanges = when (classpathChanges) {
// Note: classpathChanges is deserialized so they are no longer singleton objects and need to be compared using `is` (not `==`).
is ClasspathChanges.Available -> ChangesEither.Known(classpathChanges.lookupSymbols, classpathChanges.fqNames)
is ClasspathChanges.NotAvailable -> when (classpathChanges) {
is UnableToCompute, is ClasspathSnapshotIsDisabled, is ReservedForTestsOnly -> {
reporter.measure(BuildTime.IC_ANALYZE_CHANGES_IN_DEPENDENCIES) {
val scopes = caches.lookupCache.lookupMap.keys.map { if (it.scope.isBlank()) it.name else it.scope }.distinct()
getClasspathChanges(
args.classpathAsList, changedFiles, lastBuildInfo, modulesApiHistory, reporter, abiSnapshots, withSnapshot,
caches.platformCache, scopes
)
}
}
is ForNonIncrementalRun, is ForJSCompiler -> {
error("Unexpected type for this code path: ${classpathChanges.javaClass.name}.")
}
}
}
@Suppress("UNUSED_VARIABLE") // for sealed when

View File

@@ -271,6 +271,7 @@ internal class GradleKotlinCompilerWork @Inject constructor(
areFileChangesKnown = knownChangedFiles != null,
modifiedFiles = knownChangedFiles?.modified,
deletedFiles = knownChangedFiles?.removed,
classpathChanges = icEnv.classpathChanges,
workingDir = icEnv.workingDir,
reportCategories = reportCategories(isVerbose),
reportSeverity = reportSeverity(isVerbose),

View File

@@ -7,11 +7,13 @@ package org.jetbrains.kotlin.compilerRunner
import org.jetbrains.kotlin.daemon.common.MultiModuleICSettings
import org.jetbrains.kotlin.incremental.ChangedFiles
import org.jetbrains.kotlin.incremental.ClasspathChanges
import java.io.File
import java.io.Serializable
internal class IncrementalCompilationEnvironment(
val changedFiles: ChangedFiles,
val classpathChanges: ClasspathChanges,
val workingDir: File,
val usePreciseJavaTracking: Boolean = false,
val disableMultiModuleIC: Boolean = false,

View File

@@ -24,10 +24,7 @@ import org.gradle.api.tasks.compile.JavaCompile
import org.gradle.api.tasks.incremental.IncrementalTaskInputs
import org.gradle.workers.WorkerExecutor
import org.jetbrains.kotlin.build.DEFAULT_KOTLIN_SOURCE_FILES_EXTENSIONS
import org.jetbrains.kotlin.build.report.metrics.BuildMetricsReporter
import org.jetbrains.kotlin.build.report.metrics.BuildMetricsReporterImpl
import org.jetbrains.kotlin.build.report.metrics.BuildTime
import org.jetbrains.kotlin.build.report.metrics.measure
import org.jetbrains.kotlin.build.report.metrics.*
import org.jetbrains.kotlin.cli.common.CompilerSystemProperties
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
import org.jetbrains.kotlin.cli.common.arguments.CommonToolArguments
@@ -56,6 +53,7 @@ import org.jetbrains.kotlin.gradle.plugin.statistics.KotlinBuildStatsService
import org.jetbrains.kotlin.gradle.report.ReportingSettings
import org.jetbrains.kotlin.gradle.targets.js.ir.isProduceUnzippedKlib
import org.jetbrains.kotlin.gradle.utils.*
import org.jetbrains.kotlin.incremental.ClasspathChanges
import org.jetbrains.kotlin.incremental.ChangedFiles
import org.jetbrains.kotlin.incremental.IncrementalCompilerRunner
import org.jetbrains.kotlin.library.impl.isKotlinLibrary
@@ -627,14 +625,20 @@ abstract class KotlinCompile @Inject constructor(
val outputItemCollector = OutputItemsCollectorImpl()
val compilerRunner = compilerRunner.get()
if (classpathSnapshotProperties.useClasspathSnapshot.get()) {
getClasspathChanges()
}
val icEnv = if (isIncrementalCompilationEnabled()) {
val classpathChanges = when {
!classpathSnapshotProperties.useClasspathSnapshot.get() -> ClasspathChanges.NotAvailable.ClasspathSnapshotIsDisabled
else -> when (changedFiles) {
is ChangedFiles.Known -> getClasspathChanges()
is ChangedFiles.Unknown -> ClasspathChanges.NotAvailable.ForNonIncrementalRun
is ChangedFiles.Dependencies -> error("Unexpected type: ${changedFiles.javaClass.name}")
}
}
logger.info(USING_JVM_INCREMENTAL_COMPILATION_MESSAGE)
IncrementalCompilationEnvironment(
changedFiles,
taskBuildDirectory.get().asFile,
changedFiles = changedFiles,
classpathChanges = classpathChanges,
workingDir = taskBuildDirectory.get().asFile,
usePreciseJavaTracking = usePreciseJavaTracking,
disableMultiModuleIC = disableMultiModuleIC,
multiModuleICSettings = multiModuleICSettings
@@ -659,7 +663,7 @@ abstract class KotlinCompile @Inject constructor(
)
with(classpathSnapshotProperties) {
if (useClasspathSnapshot.get()) {
if (isIncrementalCompilationEnabled() && useClasspathSnapshot.get()) {
copyClasspathSnapshotFilesToDir(classpathSnapshot.files.toList(), classpathSnapshotDir.get().asFile)
}
}
@@ -722,10 +726,12 @@ abstract class KotlinCompile @Inject constructor(
return super.source(*sources)
}
private fun getClasspathChanges() {
private fun getClasspathChanges(): ClasspathChanges {
val currentSnapshotFiles = classpathSnapshotProperties.classpathSnapshot.files.toList()
val previousSnapshotFiles = getClasspathSnapshotFilesInDir(classpathSnapshotProperties.classpathSnapshotDir.get().asFile)
// TODO WORK-IN-PROGRESS
val currentClasspathSnapshotFiles = classpathSnapshotProperties.classpathSnapshot.files.toList()
val previousClasspathSnapshotFiles = getClasspathSnapshotFilesInDir(classpathSnapshotProperties.classpathSnapshotDir.get().asFile)
return ClasspathChanges.NotAvailable.UnableToCompute
}
/**
@@ -1034,6 +1040,7 @@ abstract class Kotlin2JsCompile @Inject constructor(
logger.info(USING_JS_INCREMENTAL_COMPILATION_MESSAGE)
IncrementalCompilationEnvironment(
changedFiles,
ClasspathChanges.NotAvailable.ForJSCompiler,
taskBuildDirectory.get().asFile,
multiModuleICSettings = multiModuleICSettings
)