kapt: Pass annotation declarations options via Java APT options

This commit is contained in:
Yan Zhulanow
2015-06-18 15:24:11 +03:00
parent 205585c63e
commit d9ac8c9d22
4 changed files with 63 additions and 45 deletions
@@ -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) {
@@ -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("")
}
@@ -80,9 +80,4 @@ public class AnnotationListParseTest {
assertEquals(expectedText, actualText)
}
public class FileKotlinAnnotationProvider(val annotationsFile: File): KotlinAnnotationProvider() {
override val serializedAnnotations: String
get() = annotationsFile.readText()
}
}
@@ -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())