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