Kapt3: Always write Kotlin stubs to .java files, and make javac always parse them from source files, not from JCTree (in order to support incremental compilation).
This commit is contained in:
committed by
Yan Zhulanow
parent
9b9b36e332
commit
78a3dae314
+1
-1
@@ -180,10 +180,10 @@ class Kapt3KotlinGradleSubplugin : KotlinGradleSubplugin<KotlinCompile> {
|
||||
}
|
||||
|
||||
pluginOptions += SubpluginOption("useLightAnalysis", "${kaptExtension.useLightAnalysis}")
|
||||
pluginOptions += SubpluginOption("stubs", getKaptStubsDir(project, sourceSetName).canonicalPath)
|
||||
|
||||
if (project.hasProperty(VERBOSE_OPTION_NAME) && project.property(VERBOSE_OPTION_NAME) == "true") {
|
||||
pluginOptions += SubpluginOption("verbose", "true")
|
||||
pluginOptions += SubpluginOption("stubs", getKaptStubsDir(project, sourceSetName).canonicalPath)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,6 @@ package org.jetbrains.kotlin.kapt3
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.sun.tools.javac.tree.JCTree
|
||||
import com.sun.tools.javac.tree.JCTree.JCCompilationUnit
|
||||
import org.jetbrains.kotlin.analyzer.AnalysisResult
|
||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation
|
||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
|
||||
@@ -49,7 +48,7 @@ class ClasspathBasedKapt3Extension(
|
||||
javaSourceRoots: List<File>,
|
||||
sourcesOutputDir: File,
|
||||
classFilesOutputDir: File,
|
||||
stubsOutputDir: File?,
|
||||
stubsOutputDir: File,
|
||||
incrementalDataOutputDir: File?,
|
||||
options: Map<String, String>,
|
||||
aptOnly: Boolean,
|
||||
@@ -98,7 +97,7 @@ abstract class AbstractKapt3Extension(
|
||||
val javaSourceRoots: List<File>,
|
||||
val sourcesOutputDir: File,
|
||||
val classFilesOutputDir: File,
|
||||
val stubsOutputDir: File?,
|
||||
val stubsOutputDir: File,
|
||||
val incrementalDataOutputDir: File?,
|
||||
val options: Map<String, String>,
|
||||
val aptOnly: Boolean,
|
||||
@@ -141,13 +140,13 @@ abstract class AbstractKapt3Extension(
|
||||
val (kaptContext, generationState) = compileStubs(project, module, bindingTrace.bindingContext, files.toList())
|
||||
|
||||
try {
|
||||
generateKotlinSourceStubs(kaptContext, generationState)
|
||||
val javaSourceFiles = collectJavaSourceFiles()
|
||||
val kotlinSourceStubs = generateKotlinSourceStubs(kaptContext, generationState)
|
||||
|
||||
val (annotationProcessingTime) = measureTimeMillis {
|
||||
kaptContext.doAnnotationProcessing(
|
||||
javaSourceFiles, processors, compileClasspath, annotationProcessingClasspath,
|
||||
sourcesOutputDir, classFilesOutputDir, kotlinSourceStubs)
|
||||
sourcesOutputDir, classFilesOutputDir)
|
||||
}
|
||||
|
||||
logger.info { "Annotation processing took $annotationProcessingTime ms" }
|
||||
@@ -202,7 +201,7 @@ abstract class AbstractKapt3Extension(
|
||||
return Pair(KaptContext(logger, compiledClasses, origins, options), generationState)
|
||||
}
|
||||
|
||||
private fun generateKotlinSourceStubs(kaptContext: KaptContext, generationState: GenerationState): JavacList<JCCompilationUnit> {
|
||||
private fun generateKotlinSourceStubs(kaptContext: KaptContext, generationState: GenerationState) {
|
||||
val converter = ClassFileToSourceStubConverter(kaptContext, generationState.typeMapper, generateNonExistentClass = true)
|
||||
|
||||
val (stubGenerationTime, kotlinSourceStubs) = measureTimeMillis {
|
||||
@@ -214,11 +213,10 @@ abstract class AbstractKapt3Extension(
|
||||
|
||||
saveStubs(kotlinSourceStubs)
|
||||
saveIncrementalData(generationState, logger.messageCollector, converter)
|
||||
return kotlinSourceStubs
|
||||
}
|
||||
|
||||
private fun collectJavaSourceFiles(): List<File> {
|
||||
val javaFilesFromJavaSourceRoots = javaSourceRoots.flatMap {
|
||||
val javaFilesFromJavaSourceRoots = (javaSourceRoots + stubsOutputDir).flatMap {
|
||||
root -> root.walk().filter { it.isFile && it.extension == "java" }.toList()
|
||||
}
|
||||
logger.info { "Java source files: " + javaFilesFromJavaSourceRoots.joinToString { it.canonicalPath } }
|
||||
@@ -227,12 +225,11 @@ abstract class AbstractKapt3Extension(
|
||||
}
|
||||
|
||||
protected open fun saveStubs(stubs: JavacList<JCTree.JCCompilationUnit>) {
|
||||
val outputDir = stubsOutputDir ?: return
|
||||
for (stub in stubs) {
|
||||
val className = (stub.defs.first { it is JCTree.JCClassDecl } as JCTree.JCClassDecl).simpleName.toString()
|
||||
|
||||
val packageName = stub.packageName?.toString() ?: ""
|
||||
val packageDir = if (packageName.isEmpty()) outputDir else File(outputDir, packageName.replace('.', '/'))
|
||||
val packageDir = if (packageName.isEmpty()) stubsOutputDir else File(stubsOutputDir, packageName.replace('.', '/'))
|
||||
packageDir.mkdirs()
|
||||
File(packageDir, className + ".java").writeText(stub.toString())
|
||||
}
|
||||
@@ -246,7 +243,7 @@ abstract class AbstractKapt3Extension(
|
||||
|
||||
generationState.factory.writeAll(incrementalDataOutputDir) { file, sources, output ->
|
||||
val stubFileObject = converter.bindings[file.relativePath.substringBeforeLast(".class", missingDelimiterValue = "")]
|
||||
if (stubFileObject != null && stubsOutputDir != null) {
|
||||
if (stubFileObject != null) {
|
||||
val stubFile = File(stubsOutputDir, stubFileObject.name)
|
||||
if (stubFile.exists()) {
|
||||
messageCollector.report(CompilerMessageSeverity.OUTPUT,
|
||||
|
||||
@@ -153,10 +153,16 @@ class Kapt3ComponentRegistrar : ComponentRegistrar {
|
||||
|
||||
val apClasspath = configuration.get(ANNOTATION_PROCESSOR_CLASSPATH)?.map(::File)
|
||||
|
||||
if (sourcesOutputDir == null || classFilesOutputDir == null || apClasspath == null) {
|
||||
if (sourcesOutputDir == null || classFilesOutputDir == null || apClasspath == null || stubsOutputDir == null) {
|
||||
if (isAptOnly) {
|
||||
val subject = if (apClasspath == null) "Annotation processing classpath" else "Generated files output directories"
|
||||
logger.warn("$subject is not specified, skipping annotation processing")
|
||||
val nonExistentOptionName = when {
|
||||
sourcesOutputDir == null -> "Sources output directory"
|
||||
classFilesOutputDir == null -> "Classes output directory"
|
||||
apClasspath == null -> "Annotation processing classpath"
|
||||
stubsOutputDir == null -> "Stubs output directory"
|
||||
else -> throw IllegalStateException()
|
||||
}
|
||||
logger.warn("$nonExistentOptionName is not specified, skipping annotation processing")
|
||||
AnalysisHandlerExtension.registerExtension(project, AbortAnalysisHandlerExtension())
|
||||
}
|
||||
return
|
||||
|
||||
@@ -71,7 +71,7 @@ class KotlinKapt3IntegrationTests : AbstractKotlinKapt3IntegrationTest() {
|
||||
|
||||
val bindings = kaptExtension.savedBindings!!
|
||||
|
||||
test(stubsOutputDir!!, incrementalDataOutputDir!!, bindings)
|
||||
test(stubsOutputDir, incrementalDataOutputDir!!, bindings)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user