KAPT: Fix error reporting

When incremental analysis is unable to run, handle
failure gracefully. More info will be provided by
compiler diagnostics.

Fixes KT-36302
This commit is contained in:
Ivan Gavrilovic
2020-06-26 23:02:06 +01:00
committed by Yan Zhulanow
parent 11251a93ac
commit 111a2ece72
7 changed files with 50 additions and 28 deletions
@@ -13,10 +13,9 @@ import com.sun.tools.javac.processing.JavacFiler
import com.sun.tools.javac.processing.JavacProcessingEnvironment
import com.sun.tools.javac.tree.JCTree
import org.jetbrains.kotlin.base.kapt3.KaptFlag
import org.jetbrains.kotlin.kapt3.base.incremental.GeneratedTypesTaskListener
import org.jetbrains.kotlin.kapt3.base.incremental.IncrementalProcessor
import org.jetbrains.kotlin.kapt3.base.incremental.MentionedTypesTaskListener
import org.jetbrains.kotlin.kapt3.base.incremental.*
import org.jetbrains.kotlin.kapt3.base.util.KaptBaseError
import org.jetbrains.kotlin.kapt3.base.util.KaptLogger
import org.jetbrains.kotlin.kapt3.base.util.isJava9OrLater
import org.jetbrains.kotlin.kapt3.base.util.measureTimeMillisWithResult
import java.io.File
@@ -84,23 +83,14 @@ fun KaptContext.doAnnotationProcessing(
throw KaptBaseError(KaptBaseError.Kind.EXCEPTION, e.cause ?: e)
}
cacheManager?.updateCache(processors)
cacheManager?.updateCache(processors, sourcesStructureListener?.failureReason != null)
sourcesStructureListener?.let {
if (logger.isVerbose) {
logger.info("Analyzing sources structure took ${it.time}[ms].")
}
}
if (cacheManager != null) {
val missingIncrementalSupport = processors.filter { it.isMissingIncrementalSupport() }
if (missingIncrementalSupport.isNotEmpty()) {
val nonIncremental = missingIncrementalSupport.map { "${it.processorName} (${it.incrementalSupportType})" }
logger.warn(
"Incremental annotation processing requested, but support is disabled because the following " +
"processors are not incremental: ${nonIncremental.joinToString()}."
)
}
}
reportIfRunningNonIncrementally(sourcesStructureListener, cacheManager, logger, processors)
val log = compilerAfterAP.log
@@ -138,6 +128,30 @@ private fun showProcessorTimings(wrappedProcessors: List<ProcessorWrapper>, logg
}
}
private fun reportIfRunningNonIncrementally(
listener: MentionedTypesTaskListener?,
cacheManager: JavaClassCacheManager?,
logger: KaptLogger,
processors: List<IncrementalProcessor>
) {
listener ?: return
cacheManager ?: return
listener.failureReason?.let { failure ->
logger.warn("\n$failure")
return
}
val missingIncrementalSupport = processors.filter { it.isMissingIncrementalSupport() }
if (missingIncrementalSupport.isNotEmpty()) {
val nonIncremental = missingIncrementalSupport.map { "${it.processorName} (${it.incrementalSupportType})" }
logger.warn(
"Incremental annotation processing requested, but support is disabled because the following " +
"processors are not incremental: ${nonIncremental.joinToString()}."
)
}
}
private class ProcessorWrapper(private val delegate: IncrementalProcessor) : Processor by delegate {
private var initTime: Long = 0
private val roundTime = mutableListOf<Long>()
@@ -18,8 +18,8 @@ class JavaClassCacheManager(val file: File) : Closeable {
private var closed = false
fun updateCache(processors: List<IncrementalProcessor>) {
if (!aptCache.updateCache(processors)) {
fun updateCache(processors: List<IncrementalProcessor>, failedToAnalyzeSources: Boolean) {
if (failedToAnalyzeSources || !aptCache.updateCache(processors)) {
javaCache.invalidateAll()
}
}
@@ -22,24 +22,32 @@ class MentionedTypesTaskListener(
) : TaskListener {
var time = 0L
var failureReason: String? = null
override fun started(e: TaskEvent) {
// do nothing, we just process on finish
}
override fun finished(e: TaskEvent) {
if (failureReason != null) return // stop processing if we failed to analyze some sources
if (e.kind != TaskEvent.Kind.ENTER || cache.isAlreadyProcessed(e.sourceFile.toUri())) return
val l = System.currentTimeMillis()
val compilationUnit = e.compilationUnit
try {
val l = System.currentTimeMillis()
val compilationUnit = e.compilationUnit
val structure = SourceFileStructure(e.sourceFile.toUri())
val structure = SourceFileStructure(e.sourceFile.toUri())
val treeVisitor = TypeTreeVisitor(elementUtils, trees, compilationUnit, structure)
compilationUnit.typeDecls.forEach {
it.accept(treeVisitor, Visibility.ABI)
val treeVisitor = TypeTreeVisitor(elementUtils, trees, compilationUnit, structure)
compilationUnit.typeDecls.forEach {
it.accept(treeVisitor, Visibility.ABI)
}
cache.addSourceStructure(structure)
time += System.currentTimeMillis() - l
} catch (t: Throwable) {
failureReason = "Running non-incrementally because analyzing ${e.sourceFile.toUri()} failed."
}
cache.addSourceStructure(structure)
time += System.currentTimeMillis() - l
}
}
@@ -45,7 +45,7 @@ class TestInheritedAnnotation {
listOf(processor),
generatedSources
) { elementUtils, trees -> MentionedTypesTaskListener(cache.javaCache, elementUtils, trees) }
cache.updateCache(listOf(processor))
cache.updateCache(listOf(processor), false)
}
}
@@ -48,7 +48,7 @@ class ReferencedConstantsTest {
generatedSources,
listOf(compiledClasses)
) { elements, trees -> MentionedTypesTaskListener(cache.javaCache, elements, trees) }
cache.updateCache(listOf(processor))
cache.updateCache(listOf(processor), false)
}
}
@@ -47,7 +47,7 @@ class TestComplexIncrementalAptCache {
listOf(processor),
generatedSources
) { elements, trees -> MentionedTypesTaskListener(cache.javaCache, elements, trees) }
cache.updateCache(listOf(processor))
cache.updateCache(listOf(processor), false)
}
}
@@ -72,6 +72,6 @@ class TestSimpleIncrementalAptCache {
listOf(processor),
generatedSources
) { elementUtils, trees -> MentionedTypesTaskListener(cache.javaCache, elementUtils, trees) }
cache.updateCache(listOf(processor))
cache.updateCache(listOf(processor), false)
}
}