kapt: Support inherited annotations in AP wrapper
This commit is contained in:
+2
-2
@@ -108,8 +108,8 @@ public abstract class AnnotationProcessorWrapper(
|
||||
override fun process(annotations: MutableSet<out TypeElement>?, roundEnv: RoundEnvironment): Boolean {
|
||||
roundCounter += 1
|
||||
|
||||
val annotatedKotlinElements = kotlinAnnotationsProvider.annotatedKotlinElements
|
||||
val roundEnvironmentWrapper = RoundEnvironmentWrapper(processingEnv, roundEnv, roundCounter, annotatedKotlinElements)
|
||||
val roundEnvironmentWrapper = RoundEnvironmentWrapper(
|
||||
processingEnv, roundEnv, roundCounter, kotlinAnnotationsProvider)
|
||||
processor.process(annotations, roundEnvironmentWrapper)
|
||||
return false
|
||||
}
|
||||
|
||||
+15
-2
@@ -20,7 +20,6 @@ import java.io.File
|
||||
import java.io.Reader
|
||||
import java.io.StringReader
|
||||
import javax.tools.FileObject
|
||||
import kotlin.properties.Delegates
|
||||
|
||||
public abstract class KotlinAnnotationProvider {
|
||||
|
||||
@@ -31,12 +30,22 @@ public abstract class KotlinAnnotationProvider {
|
||||
|
||||
val SHORTENED_ANNOTATION = "a"
|
||||
val SHORTENED_PACKAGE_NAME = "p"
|
||||
|
||||
val CLASS_DECLARATION = "d"
|
||||
}
|
||||
|
||||
public val annotatedKotlinElements: Map<String, Set<AnnotatedElementDescriptor>> by Delegates.lazy {
|
||||
public val annotatedKotlinElements: Map<String, Set<AnnotatedElementDescriptor>> by lazy {
|
||||
readAnnotations()
|
||||
}
|
||||
|
||||
private val kotlinClassesInternal = hashSetOf<String>()
|
||||
|
||||
public val kotlinClasses: Set<String>
|
||||
get() = kotlinClassesInternal
|
||||
|
||||
public val supportInheritedAnnotations: Boolean
|
||||
get() = kotlinClassesInternal.isNotEmpty()
|
||||
|
||||
protected abstract val serializedAnnotations: Reader
|
||||
|
||||
private fun readAnnotations(): MutableMap<String, MutableSet<AnnotatedElementDescriptor>> {
|
||||
@@ -65,6 +74,10 @@ public abstract class KotlinAnnotationProvider {
|
||||
when (type) {
|
||||
SHORTENED_ANNOTATION -> handleShortenedName(shortenedAnnotationCache, lineParts)
|
||||
SHORTENED_PACKAGE_NAME -> handleShortenedName(shortenedPackageNameCache, lineParts)
|
||||
CLASS_DECLARATION -> {
|
||||
val classFqName = expandClassName(lineParts[1]).replace('$', '.')
|
||||
kotlinClassesInternal.add(classFqName)
|
||||
}
|
||||
|
||||
ANNOTATED_CLASS, ANNOTATED_FIELD, ANNOTATED_METHOD -> {
|
||||
val annotationName = expandAnnotation(lineParts[1])
|
||||
|
||||
+34
-3
@@ -1,16 +1,19 @@
|
||||
package org.jetbrains.kotlin.annotation
|
||||
|
||||
import java.lang.annotation.Inherited
|
||||
import javax.annotation.processing.ProcessingEnvironment
|
||||
import javax.annotation.processing.RoundEnvironment
|
||||
import javax.lang.model.element.Element
|
||||
import javax.lang.model.element.ElementKind
|
||||
import javax.lang.model.element.TypeElement
|
||||
import javax.lang.model.type.NoType
|
||||
import javax.lang.model.type.TypeVisitor
|
||||
|
||||
private class RoundEnvironmentWrapper(
|
||||
val processingEnv: ProcessingEnvironment,
|
||||
val parent: RoundEnvironment,
|
||||
val roundNumber: Int,
|
||||
val annotatedElementDescriptors: Map<String, Set<AnnotatedElementDescriptor>>
|
||||
val kotlinAnnotationsProvider: KotlinAnnotationProvider
|
||||
) : RoundEnvironment {
|
||||
|
||||
override fun getRootElements(): MutableSet<out Element>? {
|
||||
@@ -45,11 +48,23 @@ private class RoundEnvironmentWrapper(
|
||||
return getAnnotationMirrors().any { annotationFqName == it.getAnnotationType().asElement().toString() }
|
||||
}
|
||||
|
||||
private fun TypeElement.hasInheritedAnnotation(annotationFqName: String): Boolean {
|
||||
if (hasAnnotation(annotationFqName)) return true
|
||||
|
||||
val superclassMirror = getSuperclass()
|
||||
if (superclassMirror is NoType) return false
|
||||
|
||||
val superClass = processingEnv.getTypeUtils().asElement(superclassMirror)
|
||||
if (superClass !is TypeElement) return false
|
||||
|
||||
return superClass.hasInheritedAnnotation(annotationFqName)
|
||||
}
|
||||
|
||||
private fun resolveKotlinElements(annotationFqName: String): Set<Element> {
|
||||
if (roundNumber > 1) return setOf()
|
||||
|
||||
val descriptors = annotatedElementDescriptors.get(annotationFqName) ?: setOf()
|
||||
return descriptors.fold(hashSetOf<Element>()) { set, descriptor ->
|
||||
val descriptors = kotlinAnnotationsProvider.annotatedKotlinElements.get(annotationFqName) ?: setOf()
|
||||
val descriptorsWithKotlin = descriptors.fold(hashSetOf<Element>()) { set, descriptor ->
|
||||
val clazz = processingEnv.getElementUtils().getTypeElement(descriptor.classFqName) ?: return@fold set
|
||||
when (descriptor) {
|
||||
is AnnotatedClassDescriptor -> set.add(clazz)
|
||||
@@ -68,5 +83,21 @@ private class RoundEnvironmentWrapper(
|
||||
}
|
||||
set
|
||||
}
|
||||
|
||||
if (kotlinAnnotationsProvider.supportInheritedAnnotations) {
|
||||
val isInherited = processingEnv.getElementUtils().getTypeElement(annotationFqName)
|
||||
?.hasAnnotation(javaClass<Inherited>().getCanonicalName()) ?: false
|
||||
|
||||
if (isInherited) {
|
||||
kotlinAnnotationsProvider.kotlinClasses.forEach { classFqName ->
|
||||
val clazz = processingEnv.getElementUtils().getTypeElement(classFqName) ?: return@forEach
|
||||
if (clazz.hasInheritedAnnotation(annotationFqName)) {
|
||||
descriptorsWithKotlin.add(clazz)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return descriptorsWithKotlin
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user