From 78a3dae31478bf0c6d5327a3c560cf96a222098b Mon Sep 17 00:00:00 2001 From: Yan Zhulanow Date: Wed, 28 Dec 2016 18:22:44 +0300 Subject: [PATCH] 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). --- .../internal/Kapt3KotlinGradleSubplugin.kt | 2 +- .../jetbrains/kotlin/kapt3/Kapt3Extension.kt | 19 ++++++++----------- .../org/jetbrains/kotlin/kapt3/Kapt3Plugin.kt | 12 +++++++++--- .../kapt3/test/KotlinKapt3IntegrationTests.kt | 2 +- 4 files changed, 19 insertions(+), 16 deletions(-) diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/Kapt3KotlinGradleSubplugin.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/Kapt3KotlinGradleSubplugin.kt index 6c615b0e860..e5edd28bb02 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/Kapt3KotlinGradleSubplugin.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/Kapt3KotlinGradleSubplugin.kt @@ -180,10 +180,10 @@ class Kapt3KotlinGradleSubplugin : KotlinGradleSubplugin { } 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) } } diff --git a/plugins/kapt3/src/org/jetbrains/kotlin/kapt3/Kapt3Extension.kt b/plugins/kapt3/src/org/jetbrains/kotlin/kapt3/Kapt3Extension.kt index f888e551807..9423625e102 100644 --- a/plugins/kapt3/src/org/jetbrains/kotlin/kapt3/Kapt3Extension.kt +++ b/plugins/kapt3/src/org/jetbrains/kotlin/kapt3/Kapt3Extension.kt @@ -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, sourcesOutputDir: File, classFilesOutputDir: File, - stubsOutputDir: File?, + stubsOutputDir: File, incrementalDataOutputDir: File?, options: Map, aptOnly: Boolean, @@ -98,7 +97,7 @@ abstract class AbstractKapt3Extension( val javaSourceRoots: List, val sourcesOutputDir: File, val classFilesOutputDir: File, - val stubsOutputDir: File?, + val stubsOutputDir: File, val incrementalDataOutputDir: File?, val options: Map, 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 { + 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 { - 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) { - 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, diff --git a/plugins/kapt3/src/org/jetbrains/kotlin/kapt3/Kapt3Plugin.kt b/plugins/kapt3/src/org/jetbrains/kotlin/kapt3/Kapt3Plugin.kt index f5804470e02..40e320dc765 100644 --- a/plugins/kapt3/src/org/jetbrains/kotlin/kapt3/Kapt3Plugin.kt +++ b/plugins/kapt3/src/org/jetbrains/kotlin/kapt3/Kapt3Plugin.kt @@ -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 diff --git a/plugins/kapt3/test/org/jetbrains/kotlin/kapt3/test/KotlinKapt3IntegrationTests.kt b/plugins/kapt3/test/org/jetbrains/kotlin/kapt3/test/KotlinKapt3IntegrationTests.kt index 9edacf53729..0c17b7da2b8 100644 --- a/plugins/kapt3/test/org/jetbrains/kotlin/kapt3/test/KotlinKapt3IntegrationTests.kt +++ b/plugins/kapt3/test/org/jetbrains/kotlin/kapt3/test/KotlinKapt3IntegrationTests.kt @@ -71,7 +71,7 @@ class KotlinKapt3IntegrationTests : AbstractKotlinKapt3IntegrationTest() { val bindings = kaptExtension.savedBindings!! - test(stubsOutputDir!!, incrementalDataOutputDir!!, bindings) + test(stubsOutputDir, incrementalDataOutputDir!!, bindings) } }