kapt: Pass annotation declarations options via Java APT options
This commit is contained in:
+17
-6
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.annotation
|
||||
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
import javax.annotation.processing.*
|
||||
import javax.lang.model.SourceVersion
|
||||
@@ -43,6 +44,10 @@ public abstract class AnnotationProcessorWrapper(
|
||||
private val taskQualifier: String
|
||||
) : Processor {
|
||||
|
||||
private companion object {
|
||||
val KAPT_ANNOTATION_OPTION = "kapt.annotations"
|
||||
}
|
||||
|
||||
private val processor: Processor by Delegates.lazy {
|
||||
try {
|
||||
val instance = Class.forName(processorFqName).newInstance() as? Processor
|
||||
@@ -76,12 +81,16 @@ public abstract class AnnotationProcessorWrapper(
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
val annotationsTxt = processingEnv.getFiler().getResource(StandardLocation.CLASS_PATH, "", "annotations.$taskQualifier.txt")
|
||||
kotlinAnnotationsProvider = FileObjectKotlinAnnotationProvider(annotationsTxt)
|
||||
} catch (e: IOException) {
|
||||
kotlinAnnotationsProvider = EmptyKotlinAnnotationsProvider()
|
||||
val annotationsFile = processingEnv.getOptions().get(KAPT_ANNOTATION_OPTION)
|
||||
if (annotationsFile != null) {
|
||||
try {
|
||||
kotlinAnnotationsProvider = FileKotlinAnnotationProvider(File(annotationsFile))
|
||||
}
|
||||
catch (e: IOException) {
|
||||
kotlinAnnotationsProvider = EmptyKotlinAnnotationsProvider()
|
||||
}
|
||||
}
|
||||
else kotlinAnnotationsProvider = EmptyKotlinAnnotationsProvider()
|
||||
|
||||
processor.init(processingEnv)
|
||||
}
|
||||
@@ -106,7 +115,9 @@ public abstract class AnnotationProcessorWrapper(
|
||||
}
|
||||
|
||||
override fun getSupportedOptions(): MutableSet<String> {
|
||||
return processor.getSupportedOptions()
|
||||
val supportedOptions = processor.getSupportedOptions().toHashSet()
|
||||
supportedOptions.add(KAPT_ANNOTATION_OPTION)
|
||||
return supportedOptions
|
||||
}
|
||||
|
||||
private fun ProcessingEnvironment.err(message: String) {
|
||||
|
||||
+38
-33
@@ -16,6 +16,9 @@
|
||||
|
||||
package org.jetbrains.kotlin.annotation
|
||||
|
||||
import java.io.File
|
||||
import java.io.Reader
|
||||
import java.io.StringReader
|
||||
import javax.tools.FileObject
|
||||
import kotlin.properties.Delegates
|
||||
|
||||
@@ -34,7 +37,7 @@ public abstract class KotlinAnnotationProvider {
|
||||
readAnnotations()
|
||||
}
|
||||
|
||||
protected abstract val serializedAnnotations: String
|
||||
protected abstract val serializedAnnotations: Reader
|
||||
|
||||
private fun readAnnotations(): MutableMap<String, MutableSet<AnnotatedElementDescriptor>> {
|
||||
val shortenedAnnotationCache = hashMapOf<String, String>()
|
||||
@@ -53,40 +56,42 @@ public abstract class KotlinAnnotationProvider {
|
||||
|
||||
val annotatedKotlinElements: MutableMap<String, MutableSet<AnnotatedElementDescriptor>> = hashMapOf()
|
||||
|
||||
for (line in serializedAnnotations.lines()) {
|
||||
if (line.isEmpty()) continue
|
||||
val lineParts = line.split(' ')
|
||||
serializedAnnotations.useLines { lines ->
|
||||
for (line in lines) {
|
||||
if (line.isEmpty()) continue
|
||||
val lineParts = line.split(' ')
|
||||
|
||||
val type = lineParts[0]
|
||||
when (type) {
|
||||
SHORTENED_ANNOTATION -> handleShortenedName(shortenedAnnotationCache, lineParts)
|
||||
SHORTENED_PACKAGE_NAME -> handleShortenedName(shortenedPackageNameCache, lineParts)
|
||||
val type = lineParts[0]
|
||||
when (type) {
|
||||
SHORTENED_ANNOTATION -> handleShortenedName(shortenedAnnotationCache, lineParts)
|
||||
SHORTENED_PACKAGE_NAME -> handleShortenedName(shortenedPackageNameCache, lineParts)
|
||||
|
||||
ANNOTATED_CLASS, ANNOTATED_FIELD, ANNOTATED_METHOD -> {
|
||||
val annotationName = expandAnnotation(lineParts[1])
|
||||
val classFqName = expandClassName(lineParts[2]).replace('$', '.')
|
||||
val elementName = if (lineParts.size() == 4) lineParts[3] else null
|
||||
ANNOTATED_CLASS, ANNOTATED_FIELD, ANNOTATED_METHOD -> {
|
||||
val annotationName = expandAnnotation(lineParts[1])
|
||||
val classFqName = expandClassName(lineParts[2]).replace('$', '.')
|
||||
val elementName = if (lineParts.size() == 4) lineParts[3] else null
|
||||
|
||||
val set = annotatedKotlinElements.getOrPut(annotationName) { hashSetOf() }
|
||||
set.add(when (type) {
|
||||
ANNOTATED_CLASS -> AnnotatedClassDescriptor(classFqName)
|
||||
ANNOTATED_FIELD -> {
|
||||
val name = elementName ?: throw AssertionError("Name for field must be provided")
|
||||
AnnotatedFieldDescriptor(classFqName, name)
|
||||
}
|
||||
ANNOTATED_METHOD -> {
|
||||
val name = elementName ?: throw AssertionError("Name for method must be provided")
|
||||
val set = annotatedKotlinElements.getOrPut(annotationName) { hashSetOf() }
|
||||
set.add(when (type) {
|
||||
ANNOTATED_CLASS -> AnnotatedClassDescriptor(classFqName)
|
||||
ANNOTATED_FIELD -> {
|
||||
val name = elementName ?: throw AssertionError("Name for field must be provided")
|
||||
AnnotatedFieldDescriptor(classFqName, name)
|
||||
}
|
||||
ANNOTATED_METHOD -> {
|
||||
val name = elementName ?: throw AssertionError("Name for method must be provided")
|
||||
|
||||
if ("<init>" == name)
|
||||
AnnotatedConstructorDescriptor(classFqName)
|
||||
else
|
||||
AnnotatedMethodDescriptor(classFqName, name)
|
||||
}
|
||||
else -> throw AssertionError("Unknown type: $type")
|
||||
})
|
||||
if ("<init>" == name)
|
||||
AnnotatedConstructorDescriptor(classFqName)
|
||||
else
|
||||
AnnotatedMethodDescriptor(classFqName, name)
|
||||
}
|
||||
else -> throw AssertionError("Unknown type: $type")
|
||||
})
|
||||
|
||||
}
|
||||
else -> throw AssertionError("Unknown type: $type")
|
||||
}
|
||||
else -> throw AssertionError("Unknown type: $type")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,11 +106,11 @@ public abstract class KotlinAnnotationProvider {
|
||||
|
||||
}
|
||||
|
||||
public class FileObjectKotlinAnnotationProvider(val annotationsFileObject: FileObject): KotlinAnnotationProvider() {
|
||||
override val serializedAnnotations: String
|
||||
get() = annotationsFileObject.getCharContent(false).toString()
|
||||
public class FileKotlinAnnotationProvider(val annotationsFile: File): KotlinAnnotationProvider() {
|
||||
override val serializedAnnotations: Reader
|
||||
get() = annotationsFile.reader().buffered()
|
||||
}
|
||||
|
||||
public class EmptyKotlinAnnotationsProvider : KotlinAnnotationProvider() {
|
||||
override val serializedAnnotations = ""
|
||||
override val serializedAnnotations = StringReader("")
|
||||
}
|
||||
-5
@@ -80,9 +80,4 @@ public class AnnotationListParseTest {
|
||||
assertEquals(expectedText, actualText)
|
||||
}
|
||||
|
||||
public class FileKotlinAnnotationProvider(val annotationsFile: File): KotlinAnnotationProvider() {
|
||||
override val serializedAnnotations: String
|
||||
get() = annotationsFile.readText()
|
||||
}
|
||||
|
||||
}
|
||||
+8
-1
@@ -50,7 +50,7 @@ public class AnnotationProcessingManager(
|
||||
}
|
||||
|
||||
fun getAnnotationFile(): File {
|
||||
aptWorkingDir.mkdirs()
|
||||
if (!aptWorkingDir.exists()) aptWorkingDir.mkdirs()
|
||||
return File(aptWorkingDir, "$WRAPPERS_DIRECTORY/annotations.$taskQualifier.txt")
|
||||
}
|
||||
|
||||
@@ -72,6 +72,7 @@ public class AnnotationProcessingManager(
|
||||
|
||||
addGeneratedSourcesOutputToCompilerArgs(javaTask, aptOutputDir)
|
||||
|
||||
appendAnnotationsFileLocationArgument()
|
||||
appendAdditionalComplerArgs()
|
||||
}
|
||||
|
||||
@@ -99,6 +100,12 @@ public class AnnotationProcessingManager(
|
||||
javaTask.source(javaAptSourceDir)
|
||||
}
|
||||
|
||||
private fun appendAnnotationsFileLocationArgument() {
|
||||
javaTask.modifyCompilerArguments { list ->
|
||||
list.add("-Akapt.annotations=" + getAnnotationFile())
|
||||
}
|
||||
}
|
||||
|
||||
private fun appendAdditionalComplerArgs() {
|
||||
val kaptExtension = project.getExtensions().getByType(javaClass<KaptExtension>())
|
||||
val args = kaptExtension.getAdditionalArguments(project, androidVariant, getAndroidExtension())
|
||||
|
||||
Reference in New Issue
Block a user