Kapt: Annotation processors should not be discovered when the processor fqNames are set by user (#KT-22939)
This commit is contained in:
@@ -31,6 +31,12 @@ interface CommandLineProcessor {
|
|||||||
put(option, paths)
|
put(option, paths)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun <T> CompilerConfiguration.appendList(option: CompilerConfigurationKey<List<T>>, values: List<T>) {
|
||||||
|
val paths = getList(option).toMutableList()
|
||||||
|
paths.addAll(values)
|
||||||
|
put(option, paths)
|
||||||
|
}
|
||||||
|
|
||||||
fun CompilerConfiguration.applyOptionsFrom(map: Map<String, List<String>>, pluginOptions: Collection<CliOption>) {
|
fun CompilerConfiguration.applyOptionsFrom(map: Map<String, List<String>>, pluginOptions: Collection<CliOption>) {
|
||||||
for ((key, values) in map) {
|
for ((key, values) in map) {
|
||||||
val option = pluginOptions.firstOrNull { it.name == key } ?: continue
|
val option = pluginOptions.firstOrNull { it.name == key } ?: continue
|
||||||
|
|||||||
+2
@@ -69,6 +69,7 @@ open class Kapt3IT : Kapt3BaseIT() {
|
|||||||
assertContains("example.JavaTest PASSED")
|
assertContains("example.JavaTest PASSED")
|
||||||
assertClassFilesNotContain(File(project.projectDir, "build/classes"), "ExampleSourceAnnotation")
|
assertClassFilesNotContain(File(project.projectDir, "build/classes"), "ExampleSourceAnnotation")
|
||||||
assertNotContains("warning: The following options were not recognized by any processor")
|
assertNotContains("warning: The following options were not recognized by any processor")
|
||||||
|
assertContains("Need to discovery annotation processors in the AP classpath")
|
||||||
}
|
}
|
||||||
|
|
||||||
project.build("build") {
|
project.build("build") {
|
||||||
@@ -135,6 +136,7 @@ open class Kapt3IT : Kapt3BaseIT() {
|
|||||||
assertFileExists("build/generated/source/kapt/main/example/TestClassCustomized.java")
|
assertFileExists("build/generated/source/kapt/main/example/TestClassCustomized.java")
|
||||||
assertFileExists(kotlinClassesDir() + "example/TestClass.class")
|
assertFileExists(kotlinClassesDir() + "example/TestClass.class")
|
||||||
assertFileExists(javaClassesDir() + "example/TestClassCustomized.class")
|
assertFileExists(javaClassesDir() + "example/TestClassCustomized.class")
|
||||||
|
assertContains("Annotation processor class names are set, skip AP discovery")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
@@ -44,4 +44,6 @@ kapt {
|
|||||||
javacOptions {
|
javacOptions {
|
||||||
option("-Xlint:all")
|
option("-Xlint:all")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
annotationProcessor("example.ExampleAnnotationProcessor")
|
||||||
}
|
}
|
||||||
@@ -67,7 +67,7 @@ class ClasspathBasedKapt3Extension(
|
|||||||
incrementalDataOutputDir: File?,
|
incrementalDataOutputDir: File?,
|
||||||
options: Map<String, String>,
|
options: Map<String, String>,
|
||||||
javacOptions: Map<String, String>,
|
javacOptions: Map<String, String>,
|
||||||
annotationProcessors: String,
|
annotationProcessorFqNames: List<String>,
|
||||||
aptMode: AptMode,
|
aptMode: AptMode,
|
||||||
val useLightAnalysis: Boolean,
|
val useLightAnalysis: Boolean,
|
||||||
correctErrorTypes: Boolean,
|
correctErrorTypes: Boolean,
|
||||||
@@ -76,7 +76,7 @@ class ClasspathBasedKapt3Extension(
|
|||||||
logger: KaptLogger,
|
logger: KaptLogger,
|
||||||
compilerConfiguration: CompilerConfiguration
|
compilerConfiguration: CompilerConfiguration
|
||||||
) : AbstractKapt3Extension(compileClasspath, annotationProcessingClasspath, javaSourceRoots, sourcesOutputDir,
|
) : AbstractKapt3Extension(compileClasspath, annotationProcessingClasspath, javaSourceRoots, sourcesOutputDir,
|
||||||
classFilesOutputDir, stubsOutputDir, incrementalDataOutputDir, options, javacOptions, annotationProcessors,
|
classFilesOutputDir, stubsOutputDir, incrementalDataOutputDir, options, javacOptions, annotationProcessorFqNames,
|
||||||
aptMode, pluginInitializedTime, logger, correctErrorTypes, mapDiagnosticLocations, compilerConfiguration) {
|
aptMode, pluginInitializedTime, logger, correctErrorTypes, mapDiagnosticLocations, compilerConfiguration) {
|
||||||
override val analyzePartially: Boolean
|
override val analyzePartially: Boolean
|
||||||
get() = useLightAnalysis
|
get() = useLightAnalysis
|
||||||
@@ -103,7 +103,14 @@ class ClasspathBasedKapt3Extension(
|
|||||||
val classpath = annotationProcessingClasspath + compileClasspath
|
val classpath = annotationProcessingClasspath + compileClasspath
|
||||||
val classLoader = URLClassLoader(classpath.map { it.toURI().toURL() }.toTypedArray())
|
val classLoader = URLClassLoader(classpath.map { it.toURI().toURL() }.toTypedArray())
|
||||||
this.annotationProcessingClassLoader = classLoader
|
this.annotationProcessingClassLoader = classLoader
|
||||||
val processors = ServiceLoader.load(Processor::class.java, classLoader).toList()
|
|
||||||
|
val processors = if (annotationProcessorFqNames.isNotEmpty()) {
|
||||||
|
logger.info("Annotation processor class names are set, skip AP discovery")
|
||||||
|
annotationProcessorFqNames.mapNotNull { tryLoadProcessor(it, classLoader) }
|
||||||
|
} else {
|
||||||
|
logger.info("Need to discovery annotation processors in the AP classpath")
|
||||||
|
ServiceLoader.load(Processor::class.java, classLoader).toList()
|
||||||
|
}
|
||||||
|
|
||||||
if (processors.isEmpty()) {
|
if (processors.isEmpty()) {
|
||||||
logger.info("No annotation processors available, aborting")
|
logger.info("No annotation processors available, aborting")
|
||||||
@@ -113,6 +120,28 @@ class ClasspathBasedKapt3Extension(
|
|||||||
|
|
||||||
return processors
|
return processors
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun tryLoadProcessor(fqName: String, classLoader: ClassLoader): Processor? {
|
||||||
|
val annotationProcessorClass = try {
|
||||||
|
Class.forName(fqName, true, classLoader)
|
||||||
|
} catch (e: Throwable) {
|
||||||
|
logger.warn("Can't find annotation processor class $fqName: ${e.message}")
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
val annotationProcessorInstance = annotationProcessorClass.newInstance()
|
||||||
|
if (annotationProcessorInstance !is Processor) {
|
||||||
|
logger.warn("$fqName is not an instance of 'Processor'")
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
return annotationProcessorInstance
|
||||||
|
} catch (e: Throwable) {
|
||||||
|
logger.warn("Can't load annotation processor class $fqName: ${e.message}")
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class AbstractKapt3Extension(
|
abstract class AbstractKapt3Extension(
|
||||||
@@ -125,7 +154,7 @@ abstract class AbstractKapt3Extension(
|
|||||||
val incrementalDataOutputDir: File?,
|
val incrementalDataOutputDir: File?,
|
||||||
val options: Map<String, String>,
|
val options: Map<String, String>,
|
||||||
val javacOptions: Map<String, String>,
|
val javacOptions: Map<String, String>,
|
||||||
val annotationProcessors: String,
|
val annotationProcessorFqNames: List<String>,
|
||||||
val aptMode: AptMode,
|
val aptMode: AptMode,
|
||||||
val pluginInitializedTime: Long,
|
val pluginInitializedTime: Long,
|
||||||
val logger: KaptLogger,
|
val logger: KaptLogger,
|
||||||
@@ -224,8 +253,7 @@ abstract class AbstractKapt3Extension(
|
|||||||
|
|
||||||
val (annotationProcessingTime) = measureTimeMillis {
|
val (annotationProcessingTime) = measureTimeMillis {
|
||||||
kaptContext.doAnnotationProcessing(
|
kaptContext.doAnnotationProcessing(
|
||||||
javaSourceFiles, processors, compileClasspath, annotationProcessingClasspath,
|
javaSourceFiles, processors, compileClasspath, annotationProcessingClasspath, sourcesOutputDir, classFilesOutputDir)
|
||||||
annotationProcessors, sourcesOutputDir, classFilesOutputDir)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.info { "Annotation processing took $annotationProcessingTime ms" }
|
logger.info { "Annotation processing took $annotationProcessingTime ms" }
|
||||||
|
|||||||
@@ -84,8 +84,8 @@ object Kapt3ConfigurationKeys {
|
|||||||
val JAVAC_CLI_OPTIONS: CompilerConfigurationKey<String> =
|
val JAVAC_CLI_OPTIONS: CompilerConfigurationKey<String> =
|
||||||
CompilerConfigurationKey.create<String>(JAVAC_CLI_OPTIONS_OPTION.description)
|
CompilerConfigurationKey.create<String>(JAVAC_CLI_OPTIONS_OPTION.description)
|
||||||
|
|
||||||
val ANNOTATION_PROCESSORS: CompilerConfigurationKey<String> =
|
val ANNOTATION_PROCESSORS: CompilerConfigurationKey<List<String>> =
|
||||||
CompilerConfigurationKey.create<String>(ANNOTATION_PROCESSORS_OPTION.description)
|
CompilerConfigurationKey.create<List<String>>(ANNOTATION_PROCESSORS_OPTION.description)
|
||||||
|
|
||||||
val VERBOSE_MODE: CompilerConfigurationKey<String> =
|
val VERBOSE_MODE: CompilerConfigurationKey<String> =
|
||||||
CompilerConfigurationKey.create<String>(VERBOSE_MODE_OPTION.description)
|
CompilerConfigurationKey.create<String>(VERBOSE_MODE_OPTION.description)
|
||||||
@@ -174,7 +174,8 @@ class Kapt3CommandLineProcessor : CommandLineProcessor {
|
|||||||
override fun processOption(option: CliOption, value: String, configuration: CompilerConfiguration) {
|
override fun processOption(option: CliOption, value: String, configuration: CompilerConfiguration) {
|
||||||
when (option) {
|
when (option) {
|
||||||
ANNOTATION_PROCESSOR_CLASSPATH_OPTION -> configuration.appendList(ANNOTATION_PROCESSOR_CLASSPATH, value)
|
ANNOTATION_PROCESSOR_CLASSPATH_OPTION -> configuration.appendList(ANNOTATION_PROCESSOR_CLASSPATH, value)
|
||||||
ANNOTATION_PROCESSORS_OPTION -> configuration.put(Kapt3ConfigurationKeys.ANNOTATION_PROCESSORS, value)
|
ANNOTATION_PROCESSORS_OPTION -> configuration.appendList(
|
||||||
|
Kapt3ConfigurationKeys.ANNOTATION_PROCESSORS, value.split(',').map { it.trim() }.filter { it.isNotEmpty() })
|
||||||
APT_OPTIONS_OPTION -> configuration.put(Kapt3ConfigurationKeys.APT_OPTIONS, value)
|
APT_OPTIONS_OPTION -> configuration.put(Kapt3ConfigurationKeys.APT_OPTIONS, value)
|
||||||
JAVAC_CLI_OPTIONS_OPTION -> configuration.put(Kapt3ConfigurationKeys.JAVAC_CLI_OPTIONS, value)
|
JAVAC_CLI_OPTIONS_OPTION -> configuration.put(Kapt3ConfigurationKeys.JAVAC_CLI_OPTIONS, value)
|
||||||
SOURCE_OUTPUT_DIR_OPTION -> configuration.put(Kapt3ConfigurationKeys.SOURCE_OUTPUT_DIR, value)
|
SOURCE_OUTPUT_DIR_OPTION -> configuration.put(Kapt3ConfigurationKeys.SOURCE_OUTPUT_DIR, value)
|
||||||
@@ -237,7 +238,7 @@ class Kapt3ComponentRegistrar : ComponentRegistrar {
|
|||||||
val stubsOutputDir = configuration.get(Kapt3ConfigurationKeys.STUBS_OUTPUT_DIR)?.let(::File)
|
val stubsOutputDir = configuration.get(Kapt3ConfigurationKeys.STUBS_OUTPUT_DIR)?.let(::File)
|
||||||
val incrementalDataOutputDir = configuration.get(Kapt3ConfigurationKeys.INCREMENTAL_DATA_OUTPUT_DIR)?.let(::File)
|
val incrementalDataOutputDir = configuration.get(Kapt3ConfigurationKeys.INCREMENTAL_DATA_OUTPUT_DIR)?.let(::File)
|
||||||
|
|
||||||
val annotationProcessors = configuration.get(Kapt3ConfigurationKeys.ANNOTATION_PROCESSORS) ?: ""
|
val annotationProcessors = configuration.get(Kapt3ConfigurationKeys.ANNOTATION_PROCESSORS) ?: emptyList()
|
||||||
|
|
||||||
val apClasspath = configuration.get(ANNOTATION_PROCESSOR_CLASSPATH)?.map(::File) ?: emptyList()
|
val apClasspath = configuration.get(ANNOTATION_PROCESSOR_CLASSPATH)?.map(::File) ?: emptyList()
|
||||||
|
|
||||||
@@ -289,7 +290,7 @@ class Kapt3ComponentRegistrar : ComponentRegistrar {
|
|||||||
logger.info("Incremental data output directory: $incrementalDataOutputDir")
|
logger.info("Incremental data output directory: $incrementalDataOutputDir")
|
||||||
logger.info("Compile classpath: " + compileClasspath.joinToString())
|
logger.info("Compile classpath: " + compileClasspath.joinToString())
|
||||||
logger.info("Annotation processing classpath: " + apClasspath.joinToString())
|
logger.info("Annotation processing classpath: " + apClasspath.joinToString())
|
||||||
logger.info("Annotation processors: " + annotationProcessors)
|
logger.info("Annotation processors: " + annotationProcessors.joinToString())
|
||||||
logger.info("Java source roots: " + javaSourceRoots.joinToString())
|
logger.info("Java source roots: " + javaSourceRoots.joinToString())
|
||||||
logger.info("Options: $apOptions")
|
logger.info("Options: $apOptions")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,7 +39,6 @@ fun KaptContext<*>.doAnnotationProcessing(
|
|||||||
processors: List<Processor>,
|
processors: List<Processor>,
|
||||||
compileClasspath: List<File>,
|
compileClasspath: List<File>,
|
||||||
annotationProcessingClasspath: List<File>,
|
annotationProcessingClasspath: List<File>,
|
||||||
annotationProcessors: String,
|
|
||||||
sourcesOutputDir: File,
|
sourcesOutputDir: File,
|
||||||
classesOutputDir: File,
|
classesOutputDir: File,
|
||||||
additionalSources: JavacList<JCTree.JCCompilationUnit> = JavacList.nil(),
|
additionalSources: JavacList<JCTree.JCCompilationUnit> = JavacList.nil(),
|
||||||
@@ -54,7 +53,6 @@ fun KaptContext<*>.doAnnotationProcessing(
|
|||||||
|
|
||||||
putJavacOption("CLASSPATH", "CLASS_PATH", compileClasspath.joinToString(File.pathSeparator) { it.canonicalPath })
|
putJavacOption("CLASSPATH", "CLASS_PATH", compileClasspath.joinToString(File.pathSeparator) { it.canonicalPath })
|
||||||
putJavacOption("PROCESSORPATH", "PROCESSOR_PATH", annotationProcessingClasspath.joinToString(File.pathSeparator) { it.canonicalPath })
|
putJavacOption("PROCESSORPATH", "PROCESSOR_PATH", annotationProcessingClasspath.joinToString(File.pathSeparator) { it.canonicalPath })
|
||||||
put(Option.PROCESSOR, annotationProcessors)
|
|
||||||
put(Option.S, sourcesOutputDir.canonicalPath)
|
put(Option.S, sourcesOutputDir.canonicalPath)
|
||||||
put(Option.D, classesOutputDir.canonicalPath)
|
put(Option.D, classesOutputDir.canonicalPath)
|
||||||
put(Option.ENCODING, "UTF-8")
|
put(Option.ENCODING, "UTF-8")
|
||||||
|
|||||||
+1
-1
@@ -164,7 +164,7 @@ abstract class AbstractKotlinKapt3IntegrationTest : CodegenTestCase() {
|
|||||||
incrementalDataOutputDir: File
|
incrementalDataOutputDir: File
|
||||||
) : AbstractKapt3Extension(PathUtil.getJdkClassesRootsFromCurrentJre() + PathUtil.kotlinPathsForIdeaPlugin.stdlibPath,
|
) : AbstractKapt3Extension(PathUtil.getJdkClassesRootsFromCurrentJre() + PathUtil.kotlinPathsForIdeaPlugin.stdlibPath,
|
||||||
emptyList(), javaSourceRoots, outputDir, outputDir,
|
emptyList(), javaSourceRoots, outputDir, outputDir,
|
||||||
stubsOutputDir, incrementalDataOutputDir, options, emptyMap(), "", STUBS_AND_APT, System.currentTimeMillis(),
|
stubsOutputDir, incrementalDataOutputDir, options, emptyMap(), emptyList(), STUBS_AND_APT, System.currentTimeMillis(),
|
||||||
KaptLogger(true), correctErrorTypes = true, mapDiagnosticLocations = true,
|
KaptLogger(true), correctErrorTypes = true, mapDiagnosticLocations = true,
|
||||||
compilerConfiguration = CompilerConfiguration.EMPTY
|
compilerConfiguration = CompilerConfiguration.EMPTY
|
||||||
) {
|
) {
|
||||||
|
|||||||
+3
-2
@@ -285,9 +285,10 @@ abstract class AbstractKotlinKaptContextTest : AbstractKotlinKapt3Test() {
|
|||||||
try {
|
try {
|
||||||
kaptContext.doAnnotationProcessing(emptyList(), listOf(JavaKaptContextTest.simpleProcessor()),
|
kaptContext.doAnnotationProcessing(emptyList(), listOf(JavaKaptContextTest.simpleProcessor()),
|
||||||
compileClasspath = PathUtil.getJdkClassesRootsFromCurrentJre() + PathUtil.kotlinPathsForIdeaPlugin.stdlibPath,
|
compileClasspath = PathUtil.getJdkClassesRootsFromCurrentJre() + PathUtil.kotlinPathsForIdeaPlugin.stdlibPath,
|
||||||
annotationProcessingClasspath = emptyList(), annotationProcessors = "",
|
annotationProcessingClasspath = emptyList(),
|
||||||
sourcesOutputDir = sourceOutputDir, classesOutputDir = sourceOutputDir,
|
sourcesOutputDir = sourceOutputDir, classesOutputDir = sourceOutputDir,
|
||||||
additionalSources = compilationUnits, withJdk = true)
|
additionalSources = compilationUnits, withJdk = true
|
||||||
|
)
|
||||||
|
|
||||||
val javaFiles = sourceOutputDir.walkTopDown().filter { it.isFile && it.extension == "java" }
|
val javaFiles = sourceOutputDir.walkTopDown().filter { it.isFile && it.extension == "java" }
|
||||||
val actualRaw = javaFiles.sortedBy { it.name }.joinToString(FILE_SEPARATOR) { it.name + ":\n\n" + it.readText() }
|
val actualRaw = javaFiles.sortedBy { it.name }.joinToString(FILE_SEPARATOR) { it.name + ":\n\n" + it.readText() }
|
||||||
|
|||||||
-1
@@ -93,7 +93,6 @@ class JavaKaptContextTest {
|
|||||||
listOf(processor),
|
listOf(processor),
|
||||||
emptyList(), // compile classpath
|
emptyList(), // compile classpath
|
||||||
emptyList(), // annotation processing classpath
|
emptyList(), // annotation processing classpath
|
||||||
"", // list of annotation processor qualified names
|
|
||||||
outputDir,
|
outputDir,
|
||||||
outputDir,
|
outputDir,
|
||||||
withJdk = true)
|
withJdk = true)
|
||||||
|
|||||||
Reference in New Issue
Block a user