Clean up fall-back logic in IncrementalCompilerRunner

Make it clear that there 3 distinct cases:
   1. Incremental compilation completed with an ExitCode.
   2. Incremental compilation was not possible for some valid reason
      (e.g., for a clean build), and we will perform non-incremental
      compilation.
   3. Incremental compilation failed with an exception.
      In this case, we will:
        - Print a warning with a stack trace
        - Ask the user to file a bug
        - Collect rebuild reason enum for analytics
           + TODO: Collect the stack trace too
        - Fall back to non-incremental compilation

Test: Existing BaseIncrementalCompilationMultiProjectIT.testFailureHandling_UserError,
      Updated BaseIncrementalCompilationMultiProjectIT.testFailureHandling_ToolError

^KT-53015: In progress
This commit is contained in:
Hung Nguyen
2022-06-20 13:41:40 +01:00
committed by Andrey Uskov
parent 57bbc335f4
commit def886cd31
24 changed files with 409 additions and 341 deletions
@@ -16,7 +16,10 @@
package org.jetbrains.kotlin.daemon.common
import org.jetbrains.kotlin.cli.common.repl.*
import org.jetbrains.kotlin.cli.common.repl.ReplCheckResult
import org.jetbrains.kotlin.cli.common.repl.ReplCodeLine
import org.jetbrains.kotlin.cli.common.repl.ReplCompileResult
import org.jetbrains.kotlin.cli.common.repl.ReplEvalResult
import java.io.File
import java.io.Serializable
import java.rmi.Remote
@@ -46,20 +49,26 @@ interface CompileService : Remote {
override fun equals(other: Any?): Boolean = other is Good<*> && this.result == other.result
override fun hashCode(): Int = this::class.java.hashCode() + (result?.hashCode() ?: 1)
}
class Ok : CallResult<Nothing>() {
override fun get(): Nothing = throw IllegalStateException("Get is inapplicable to Ok call result")
override fun equals(other: Any?): Boolean = other is Ok
override fun hashCode(): Int = this::class.java.hashCode() + 1 // avoiding clash with the hash of class itself
}
class Dying : CallResult<Nothing>() {
override fun get(): Nothing = throw IllegalStateException("Service is dying")
override fun equals(other: Any?): Boolean = other is Dying
override fun hashCode(): Int = this::class.java.hashCode() + 1 // see comment to Ok.hashCode
}
class Error(val message: String) : CallResult<Nothing>() {
override fun get(): Nothing = throw Exception(message)
override fun equals(other: Any?): Boolean = other is Error && this.message == other.message
override fun hashCode(): Int = this::class.java.hashCode() + message.hashCode()
class Error(val message: String?, val cause: Throwable?) : CallResult<Nothing>() {
constructor(cause: Throwable) : this(message = null, cause = cause)
constructor(message: String) : this(message = message, cause = null)
override fun get(): Nothing = throw Exception(message, cause)
override fun equals(other: Any?): Boolean = other is Error && this.message == other.message && this.cause == other.cause
override fun hashCode(): Int = this::class.java.hashCode() + (cause?.hashCode() ?: 1) + (message?.hashCode() ?: 2) // see comment to Ok.hashCode
}
val isGood: Boolean get() = this is Good<*>
@@ -781,7 +781,7 @@ class CompilerDaemonTest : KotlinIntegrationTestBase() {
} catch (e: Exception) {
TestCase.assertEquals(
"Unable to use scripting/REPL in the daemon: no scripting plugin loaded",
e.message
e.cause?.message
)
isErrorThrown = true
} finally {
@@ -47,8 +47,8 @@ import org.jetbrains.kotlin.daemon.report.getBuildReporter
import org.jetbrains.kotlin.incremental.*
import org.jetbrains.kotlin.incremental.components.EnumWhenTracker
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
import org.jetbrains.kotlin.incremental.components.LookupTracker
import org.jetbrains.kotlin.incremental.components.InlineConstTracker
import org.jetbrains.kotlin.incremental.components.LookupTracker
import org.jetbrains.kotlin.incremental.js.IncrementalDataProvider
import org.jetbrains.kotlin.incremental.js.IncrementalResultsConsumer
import org.jetbrains.kotlin.incremental.multiproject.ModulesApiHistoryAndroid
@@ -507,7 +507,7 @@ abstract class CompileServiceImplBase(
body()
} catch (e: Throwable) {
log.log(Level.SEVERE, "Exception", e)
CompileService.CallResult.Error(e.message ?: "unknown")
CompileService.CallResult.Error(e)
}
}
}
@@ -614,7 +614,7 @@ abstract class CompileServiceImplBase(
workingDir,
reporter,
buildHistoryFile = incrementalCompilationOptions.multiModuleICSettings.buildHistoryFile,
outputFiles = incrementalCompilationOptions.outputFiles,
outputDirs = incrementalCompilationOptions.outputFiles,
usePreciseJavaTracking = incrementalCompilationOptions.usePreciseJavaTracking,
modulesApiHistory = modulesApiHistory,
kotlinSourceFilesExtensions = allKotlinExtensions,
@@ -23,7 +23,6 @@ import org.jetbrains.kotlin.cli.common.repl.ReplCompileResult
import org.jetbrains.kotlin.cli.js.K2JSCompiler
import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
import org.jetbrains.kotlin.cli.jvm.compiler.jarfs.FastJarFileSystem
import org.jetbrains.kotlin.cli.metadata.K2MetadataCompiler
import org.jetbrains.kotlin.config.KotlinCompilerVersion
import org.jetbrains.kotlin.config.Services
@@ -749,7 +748,7 @@ class CompileServiceServerSideImpl(
body()
} catch (e: Throwable) {
log.log(Level.SEVERE, "Exception", e)
CompileService.CallResult.Error(e.message ?: "unknown")
CompileService.CallResult.Error(e)
}
}
}