Kapt3: Output stubs to .java files in verbose mode
This commit is contained in:
committed by
Yan Zhulanow
parent
aa15e0ad67
commit
6b1fc6fc39
+20
-2
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.kotlin.kapt3
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.sun.tools.javac.tree.JCTree
|
||||
import org.jetbrains.kotlin.analyzer.AnalysisResult
|
||||
import org.jetbrains.kotlin.codegen.*
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
@@ -36,12 +37,14 @@ import java.io.File
|
||||
import java.net.URLClassLoader
|
||||
import java.util.*
|
||||
import javax.annotation.processing.Processor
|
||||
import com.sun.tools.javac.util.List as JavacList
|
||||
|
||||
class Kapt3AnalysisCompletedHandlerExtension(
|
||||
val annotationProcessingClasspath: List<File>,
|
||||
val javaSourceRoots: List<File>,
|
||||
val sourcesOutputDir: File,
|
||||
val classesOutputDir: File,
|
||||
val classFilesOutputDir: File,
|
||||
val stubsOutputDir: File?,
|
||||
val options: Map<String, String>, //TODO
|
||||
val aptOnly: Boolean,
|
||||
val logger: Logger
|
||||
@@ -102,9 +105,13 @@ class Kapt3AnalysisCompletedHandlerExtension(
|
||||
val jcCompilationUnitsForKotlinClasses = treeConverter.convert()
|
||||
logger.info { "Stubs for Kotlin classes: " + jcCompilationUnitsForKotlinClasses.joinToString { it.sourcefile.name } }
|
||||
|
||||
if (stubsOutputDir != null) {
|
||||
saveStubs(stubsOutputDir, jcCompilationUnitsForKotlinClasses)
|
||||
}
|
||||
|
||||
kaptRunner.doAnnotationProcessing(
|
||||
javaFilesFromJavaSourceRoots, processors,
|
||||
annotationProcessingClasspath, sourcesOutputDir, classesOutputDir, jcCompilationUnitsForKotlinClasses)
|
||||
annotationProcessingClasspath, sourcesOutputDir, classFilesOutputDir, jcCompilationUnitsForKotlinClasses)
|
||||
} catch (thr: Throwable) {
|
||||
if (thr !is KaptError || thr.kind != KaptError.Kind.ERROR_RAISED) {
|
||||
logger.exception(thr)
|
||||
@@ -126,6 +133,17 @@ class Kapt3AnalysisCompletedHandlerExtension(
|
||||
}
|
||||
}
|
||||
|
||||
private fun saveStubs(outputDir: File, stubs: JavacList<JCTree.JCCompilationUnit>) {
|
||||
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('.', '/'))
|
||||
packageDir.mkdirs()
|
||||
File(packageDir, className + ".java").writeText(stub.toString())
|
||||
}
|
||||
}
|
||||
|
||||
private fun loadProcessors(classpath: List<File>): List<Processor> {
|
||||
val classLoader = URLClassLoader(classpath.map { it.toURI().toURL() }.toTypedArray())
|
||||
return ServiceLoader.load(Processor::class.java, classLoader).toList()
|
||||
|
||||
@@ -30,18 +30,20 @@ import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
import org.jetbrains.kotlin.config.CompilerConfigurationKey
|
||||
import org.jetbrains.kotlin.config.JVMConfigurationKeys
|
||||
import org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages
|
||||
import org.jetbrains.kotlin.kapt3.Kapt3ConfigurationKeys.APT_ONLY
|
||||
import org.jetbrains.kotlin.kapt3.diagnostic.DefaultErrorMessagesKapt3
|
||||
import org.jetbrains.kotlin.resolve.jvm.extensions.AnalysisCompletedHandlerExtension
|
||||
import java.io.File
|
||||
|
||||
object Kapt3ConfigurationKeys {
|
||||
val GENERATED_OUTPUT_DIR: CompilerConfigurationKey<String> =
|
||||
CompilerConfigurationKey.create<String>("generated files output directory")
|
||||
val SOURCE_OUTPUT_DIR: CompilerConfigurationKey<String> =
|
||||
CompilerConfigurationKey.create<String>("source files output directory")
|
||||
|
||||
val CLASS_FILES_OUTPUT_DIR: CompilerConfigurationKey<String> =
|
||||
val CLASS_OUTPUT_DIR: CompilerConfigurationKey<String> =
|
||||
CompilerConfigurationKey.create<String>("class files output directory")
|
||||
|
||||
val STUBS_OUTPUT_DIR: CompilerConfigurationKey<String> =
|
||||
CompilerConfigurationKey.create<String>("stubs output directory")
|
||||
|
||||
val ANNOTATION_PROCESSOR_CLASSPATH: CompilerConfigurationKey<List<String>> =
|
||||
CompilerConfigurationKey.create<List<String>>("annotation processor classpath")
|
||||
|
||||
@@ -59,12 +61,15 @@ class Kapt3CommandLineProcessor : CommandLineProcessor {
|
||||
companion object {
|
||||
val ANNOTATION_PROCESSING_COMPILER_PLUGIN_ID: String = "org.jetbrains.kotlin.kapt3"
|
||||
|
||||
val GENERATED_OUTPUT_DIR_OPTION: CliOption =
|
||||
CliOption("generated", "<path>", "Output path for the generated files", required = false)
|
||||
val SOURCE_OUTPUT_DIR_OPTION: CliOption =
|
||||
CliOption("sources", "<path>", "Output path for the generated files", required = false)
|
||||
|
||||
val CLASS_FILES_OUTPUT_DIR_OPTION: CliOption =
|
||||
val CLASS_OUTPUT_DIR_OPTION: CliOption =
|
||||
CliOption("classes", "<path>", "Output path for the class files", required = false)
|
||||
|
||||
val STUBS_OUTPUT_DIR_OPTION: CliOption =
|
||||
CliOption("stubs", "<path>", "Output path for the Java stubs", required = false)
|
||||
|
||||
val ANNOTATION_PROCESSOR_CLASSPATH_OPTION: CliOption =
|
||||
CliOption("apclasspath", "<classpath>", "Annotation processor classpath",
|
||||
required = false, allowMultipleOccurrences = true)
|
||||
@@ -83,8 +88,8 @@ class Kapt3CommandLineProcessor : CommandLineProcessor {
|
||||
override val pluginId: String = ANNOTATION_PROCESSING_COMPILER_PLUGIN_ID
|
||||
|
||||
override val pluginOptions: Collection<CliOption> =
|
||||
listOf(GENERATED_OUTPUT_DIR_OPTION, ANNOTATION_PROCESSOR_CLASSPATH_OPTION, APT_OPTIONS_OPTION,
|
||||
CLASS_FILES_OUTPUT_DIR_OPTION, VERBOSE_MODE_OPTION)
|
||||
listOf(SOURCE_OUTPUT_DIR_OPTION, ANNOTATION_PROCESSOR_CLASSPATH_OPTION, APT_OPTIONS_OPTION,
|
||||
CLASS_OUTPUT_DIR_OPTION, VERBOSE_MODE_OPTION, STUBS_OUTPUT_DIR_OPTION)
|
||||
|
||||
private fun <T> CompilerConfiguration.appendList(option: CompilerConfigurationKey<List<T>>, value: T) {
|
||||
val paths = getList(option).toMutableList()
|
||||
@@ -96,8 +101,9 @@ class Kapt3CommandLineProcessor : CommandLineProcessor {
|
||||
when (option) {
|
||||
ANNOTATION_PROCESSOR_CLASSPATH_OPTION -> configuration.appendList(ANNOTATION_PROCESSOR_CLASSPATH, value)
|
||||
APT_OPTIONS_OPTION -> configuration.appendList(APT_OPTIONS, value)
|
||||
GENERATED_OUTPUT_DIR_OPTION -> configuration.put(Kapt3ConfigurationKeys.GENERATED_OUTPUT_DIR, value)
|
||||
CLASS_FILES_OUTPUT_DIR_OPTION -> configuration.put(Kapt3ConfigurationKeys.CLASS_FILES_OUTPUT_DIR, value)
|
||||
SOURCE_OUTPUT_DIR_OPTION -> configuration.put(Kapt3ConfigurationKeys.SOURCE_OUTPUT_DIR, value)
|
||||
CLASS_OUTPUT_DIR_OPTION -> configuration.put(Kapt3ConfigurationKeys.CLASS_OUTPUT_DIR, value)
|
||||
STUBS_OUTPUT_DIR_OPTION -> configuration.put(Kapt3ConfigurationKeys.STUBS_OUTPUT_DIR, value)
|
||||
VERBOSE_MODE_OPTION -> configuration.put(Kapt3ConfigurationKeys.VERBOSE_MODE, value)
|
||||
APT_ONLY_OPTION -> configuration.put(Kapt3ConfigurationKeys.APT_ONLY, value)
|
||||
else -> throw CliOptionProcessingException("Unknown option: ${option.name}")
|
||||
@@ -107,7 +113,10 @@ class Kapt3CommandLineProcessor : CommandLineProcessor {
|
||||
|
||||
class Kapt3ComponentRegistrar : ComponentRegistrar {
|
||||
override fun registerProjectComponents(project: MockProject, configuration: CompilerConfiguration) {
|
||||
val generatedOutputDir = configuration.get(Kapt3ConfigurationKeys.GENERATED_OUTPUT_DIR) ?: return
|
||||
val sourcesOutputDir = configuration.get(Kapt3ConfigurationKeys.SOURCE_OUTPUT_DIR)?.let(::File) ?: return
|
||||
val classFilesOutputDir = configuration.get(Kapt3ConfigurationKeys.CLASS_OUTPUT_DIR)?.let(::File) ?: return
|
||||
val stubsOutputDir = configuration.get(Kapt3ConfigurationKeys.STUBS_OUTPUT_DIR)?.let(::File)
|
||||
|
||||
val apClasspath = configuration.get(ANNOTATION_PROCESSOR_CLASSPATH)?.map(::File) ?: return
|
||||
|
||||
val apOptions = (configuration.get(APT_OPTIONS) ?: listOf())
|
||||
@@ -116,7 +125,6 @@ class Kapt3ComponentRegistrar : ComponentRegistrar {
|
||||
.map { it[0] to it[1] }
|
||||
.toMap()
|
||||
|
||||
val sourcesOutputDir = File(generatedOutputDir)
|
||||
sourcesOutputDir.mkdirs()
|
||||
|
||||
val contentRoots = configuration[JVMConfigurationKeys.CONTENT_ROOTS] ?: emptyList()
|
||||
@@ -126,9 +134,6 @@ class Kapt3ComponentRegistrar : ComponentRegistrar {
|
||||
|
||||
val javaSourceRoots = contentRoots.filterIsInstance<JavaSourceRoot>().map { it.file }
|
||||
|
||||
val classesOutputDir = File(configuration.get(Kapt3ConfigurationKeys.CLASS_FILES_OUTPUT_DIR)
|
||||
?: configuration[JVMConfigurationKeys.MODULES]!!.first().getOutputDirectory())
|
||||
|
||||
val isVerbose = configuration.get(Kapt3ConfigurationKeys.VERBOSE_MODE) == "true"
|
||||
val isAptOnly = configuration.get(Kapt3ConfigurationKeys.APT_ONLY) == "true"
|
||||
|
||||
@@ -139,14 +144,15 @@ class Kapt3ComponentRegistrar : ComponentRegistrar {
|
||||
logger.info("Kapt3 is enabled.")
|
||||
logger.info("Do annotation processing only: $isAptOnly")
|
||||
logger.info("Source output directory: $sourcesOutputDir")
|
||||
logger.info("Classes output directory: $classesOutputDir")
|
||||
logger.info("Classes output directory: $classFilesOutputDir")
|
||||
logger.info("Stubs output directory: $stubsOutputDir")
|
||||
logger.info("Annotation processing classpath: " + classpath.joinToString())
|
||||
logger.info("Java source roots: " + javaSourceRoots.joinToString())
|
||||
logger.info("Options: $apOptions")
|
||||
}
|
||||
|
||||
val kapt3AnalysisCompletedHandlerExtension = Kapt3AnalysisCompletedHandlerExtension(
|
||||
classpath, javaSourceRoots, sourcesOutputDir, classesOutputDir, apOptions, isAptOnly, logger)
|
||||
classpath, javaSourceRoots, sourcesOutputDir, classFilesOutputDir, stubsOutputDir, apOptions, isAptOnly, logger)
|
||||
AnalysisCompletedHandlerExtension.registerExtension(project, kapt3AnalysisCompletedHandlerExtension)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user