Kapt: load all annotations, even if annotation processors does not require it explicitly. Some annotation processors may want to process some more annotations (see DbFlow, Database annotation).

Blacklist some common-used Java and Kotlin annotations instead (like Deprecated, Nullable or Metadata).
(cherry picked from commit 6856a7c)
This commit is contained in:
Yan Zhulanow
2016-09-02 22:53:25 +03:00
committed by Yan Zhulanow
parent 975364b2ed
commit c6c1673902
18 changed files with 132 additions and 18 deletions
@@ -164,14 +164,12 @@ abstract class AbstractAnnotationProcessingExtension(
}
private fun KotlinProcessingEnvironment.doAnnotationProcessing(files: Collection<KtFile>): ProcessingResult {
val allSupportedAnnotationFqNames = run initializeProcessors@ {
run initializeProcessors@ {
processors.forEach { it.init(this) }
log { "Initialized processors: " + processors.joinToString { it.javaClass.name } }
processors.flatMapTo(mutableSetOf()) { it.supportedAnnotationTypes }
}
val firstRoundAnnotations = RoundAnnotations(
allSupportedAnnotationFqNames,
incrementalCompilationComponents?.getSourceRetentionAnnotationHandler(),
bindingContext,
createTypeMapper())
@@ -29,23 +29,29 @@ import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.resolve.BindingContext
internal class RoundAnnotations(
val supportedAnnotationFqNames: Set<String>,
val sourceRetentionAnnotationHandler: SourceRetentionAnnotationHandler?,
val bindingContext: BindingContext,
val typeMapper: KotlinTypeMapper
) {
private companion object {
private val BLACKLISTED_ANNOTATATIONS = listOf(
"java.lang.Deprecated", "kotlin.Deprecated", // Deprecated annotations
"java.lang.annotation.", // Java annotations
"org.jetbrains.annotations.", // Nullable/NotNull, ReadOnly, Mutable
"kotlin.jvm.", "kotlin.Metadata" // Kotlin annotations from runtime
)
}
private val mutableAnnotationsMap = mutableMapOf<String, MutableList<PsiModifierListOwner>>()
private val mutableAnalyzedClasses = mutableSetOf<String>()
private val acceptsAnyAnnotation = "*" in supportedAnnotationFqNames
val annotationsMap: Map<String, List<PsiModifierListOwner>>
get() = mutableAnnotationsMap
val analyzedClasses: Set<String>
get() = mutableAnalyzedClasses
fun copy() = RoundAnnotations(supportedAnnotationFqNames, sourceRetentionAnnotationHandler, bindingContext, typeMapper)
fun copy() = RoundAnnotations(sourceRetentionAnnotationHandler, bindingContext, typeMapper)
fun analyzeFiles(files: Collection<KtFile>) = files.forEach { analyzeFile(it) }
@@ -105,7 +111,7 @@ internal class RoundAnnotations(
}
}
if (!acceptsAnyAnnotation && fqName !in supportedAnnotationFqNames) continue
if (BLACKLISTED_ANNOTATATIONS.any { fqName.startsWith(it) }) continue
mutableAnnotationsMap.getOrPut(fqName, { mutableListOf() }).add(declaration)
// Add only top-level classes
@@ -1,4 +1,6 @@
@Deprecated("")
annotation class Anno
@Anno
class MyClass {
var myProperty: String = "A"
@@ -1,6 +1,8 @@
package test
@Deprecated("")
annotation class Anno
@Anno
class MyClass
interface MyInterface
@@ -1,3 +1,6 @@
annotation class Anno
@Anno
@Deprecated("")
class Depr
@@ -1,3 +1,6 @@
annotation class Anno
@Anno
class A {
interface AA {
fun onClick(o: Any)
@@ -1,4 +1,6 @@
@Deprecated("")
annotation class Anno
@Anno
open class Parent {
open fun a() {}
}
@@ -1,4 +1,6 @@
@Deprecated("")
annotation class Anno
@Anno
interface Intf {
fun a()
}
@@ -0,0 +1,22 @@
// Test
class Test {
@kotlin.jvm.Transient
val f: String = ""
// explicitly
@org.jetbrains.annotations.NotNull
fun a() {}
@kotlin.jvm.Synchronized
fun b() {}
@kotlin.jvm.JvmOverloads
fun c(a: Int = 3, b: String = "") {}
@java.lang.Deprecated
fun d() {}
@kotlin.Deprecated("")
fun e() {}
}
@@ -0,0 +1,31 @@
public final class Test {
@kotlin.jvm.Transient
@org.jetbrains.annotations.NotNull
private final transient java.lang.String f
@org.jetbrains.annotations.NotNull
public final java.lang.String getF()
@org.jetbrains.annotations.NotNull
public final void a()
@kotlin.jvm.Synchronized
public final synchronized void b()
@kotlin.jvm.JvmOverloads
public final void c(int a, java.lang.String b)
@kotlin.jvm.JvmOverloads
public void c(int a)
@kotlin.jvm.JvmOverloads
public void c()
@java.lang.Deprecated
public final void d()
@kotlin.Deprecated(message = "")
public final void e()
public void <init>()
}
@@ -2,7 +2,9 @@ abstract class Base<A> {
fun baseF(): A = null!!
}
@Deprecated("")
annotation class Anno
@Anno
class Test<T> : Base<Int>() {
fun a(): String = ""
fun b(i: String, b: CharSequence) {}
@@ -1,4 +1,6 @@
@Deprecated("")
annotation class Anno
@Anno
class Test {
fun a(): Int = 5
fun b(): Unit {}
@@ -0,0 +1,25 @@
annotation class Anno
@Anno
class AnnoAnnotated
class Test {
@kotlin.jvm.Transient
val f: String = ""
// explicitly
@org.jetbrains.annotations.NotNull
fun a() {}
@kotlin.jvm.Synchronized
fun b() {}
@kotlin.jvm.JvmOverloads
fun c(a: Int = 3, b: String = "") {}
@java.lang.Deprecated
fun d() {}
@kotlin.Deprecated("")
fun e() {}
}
@@ -1,4 +1,6 @@
@Deprecated("")
annotation class Anno
@Anno
class A : B<Int>(), C<Int>
open class B<T>
@@ -2,7 +2,9 @@ interface I<T>
abstract class A<T> : I<T>
@Deprecated("")
annotation class Anno
@Anno
class B : A<String>()
class C<T : CharSequence> : A<T>()
@@ -127,7 +127,7 @@ class ElementsTests : AbstractProcessorTest() {
assertEquals(packageElement, testPackageElement)
assertFalse(packageElement.isUnnamed)
val classes = packageElement.enclosedElements.filterIsInstance<JeTypeElement>()
assertEquals(2, classes.size)
assertEquals(3, classes.size)
}
fun testGetArrayType() = test("GetPackageOf", "*") { set, roundEnv, env ->
@@ -190,7 +190,11 @@ class ProcessorTests : AbstractProcessorTest() {
fun testIncrementalDataSimple() = incrementalDataTest(
"IncrementalDataSimple",
"i Intf, i Test, i Test2, i Test3, i Test8")
"i Intf, i Test, i Test2, i Test3, i Test6, i Test7, i Test8")
fun testIncrementalDataKotlinAnnotations() = incrementalDataTest(
"KotlinAnnotations",
"i AnnoAnnotated")
private fun getKapt2Extension() = AnalysisCompletedHandlerExtension.getInstances(myEnvironment.project)
.firstIsInstance<AnnotationProcessingExtensionForTests>()
@@ -47,6 +47,12 @@ public class KotlinModelWrappersTestGenerated extends AbstractKotlinModelWrapper
doTest(fileName);
}
@TestMetadata("kotlinAnnotations.kt")
public void testKotlinAnnotations() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("plugins/annotation-processing/testData/kotlinWrappers/kotlinAnnotations.kt");
doTest(fileName);
}
@TestMetadata("metaAnnotations.kt")
public void testMetaAnnotations() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("plugins/annotation-processing/testData/kotlinWrappers/metaAnnotations.kt");