KT-57135 Take into account annotations' allowed targets

- Check allowed targets
- Attach field annotations to the backing field
This commit is contained in:
Pavel Mikhailovskii
2023-03-21 15:07:49 +01:00
committed by Space Team
parent ea2145415d
commit 37ed7beda0
19 changed files with 445 additions and 25 deletions
@@ -0,0 +1,80 @@
@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
public abstract @interface AnotherUniversalAnnotation /* AnotherUniversalAnnotation*/ {
}
@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
@java.lang.annotation.Target(value = {java.lang.annotation.ElementType.FIELD})
@kotlin.annotation.Target(allowedTargets = {kotlin.annotation.AnnotationTarget.FIELD})
public abstract @interface FieldAnnotation /* FieldAnnotation*/ {
}
public final class MyClass /* MyClass*/ {
@AnotherUniversalAnnotation()
private final int x5;
@FieldAnnotation()
private final int x1;
@UniversalAnnotation()
private final int x6;
private final int x2;
private final int x3;
private final int x4;
private final int x7;
public MyClass(@AnotherUniversalAnnotation() @ParameterAnnotation() @UniversalAnnotation() int, int, @PropertyOrParameterAnnotation() int, @ParameterOrFieldAnnotation() int, int, @AnotherUniversalAnnotation() int, @UniversalAnnotation() int);// .ctor(int, int, int, int, int, int, int)
public final int getX1();// getX1()
public final int getX2();// getX2()
public final int getX3();// getX3()
public final int getX4();// getX4()
public final int getX5();// getX5()
public final int getX6();// getX6()
public final int getX7();// getX7()
}
@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
@java.lang.annotation.Target(value = {java.lang.annotation.ElementType.PARAMETER})
@kotlin.annotation.Target(allowedTargets = {kotlin.annotation.AnnotationTarget.VALUE_PARAMETER})
public abstract @interface ParameterAnnotation /* ParameterAnnotation*/ {
}
@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
@java.lang.annotation.Target(value = {java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.PARAMETER})
@kotlin.annotation.Target(allowedTargets = {kotlin.annotation.AnnotationTarget.FIELD, kotlin.annotation.AnnotationTarget.VALUE_PARAMETER})
public abstract @interface ParameterOrFieldAnnotation /* ParameterOrFieldAnnotation*/ {
}
@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
@java.lang.annotation.Target(value = {})
@kotlin.annotation.Target(allowedTargets = {kotlin.annotation.AnnotationTarget.PROPERTY})
public abstract @interface PropertyAnnotation /* PropertyAnnotation*/ {
}
@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
@java.lang.annotation.Target(value = {java.lang.annotation.ElementType.FIELD})
@kotlin.annotation.Target(allowedTargets = {kotlin.annotation.AnnotationTarget.PROPERTY, kotlin.annotation.AnnotationTarget.FIELD})
public abstract @interface PropertyOrFieldAnnotation /* PropertyOrFieldAnnotation*/ {
}
@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
@java.lang.annotation.Target(value = {java.lang.annotation.ElementType.PARAMETER})
@kotlin.annotation.Target(allowedTargets = {kotlin.annotation.AnnotationTarget.PROPERTY, kotlin.annotation.AnnotationTarget.VALUE_PARAMETER})
public abstract @interface PropertyOrParameterAnnotation /* PropertyOrParameterAnnotation*/ {
}
@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
@java.lang.annotation.Target(value = {java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.PARAMETER})
@kotlin.annotation.Target(allowedTargets = {kotlin.annotation.AnnotationTarget.PROPERTY, kotlin.annotation.AnnotationTarget.FIELD, kotlin.annotation.AnnotationTarget.VALUE_PARAMETER})
public abstract @interface UniversalAnnotation /* UniversalAnnotation*/ {
}
@@ -0,0 +1,80 @@
@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
public abstract @interface AnotherUniversalAnnotation /* AnotherUniversalAnnotation*/ {
}
@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
@java.lang.annotation.Target(value = {java.lang.annotation.ElementType.FIELD})
@kotlin.annotation.Target(allowedTargets = {kotlin.annotation.AnnotationTarget.FIELD})
public abstract @interface FieldAnnotation /* FieldAnnotation*/ {
}
public final class MyClass /* MyClass*/ {
@AnotherUniversalAnnotation()
private final int x5;
@FieldAnnotation()
private final int x1;
@UniversalAnnotation()
private final int x6;
private final int x2;
private final int x3;
private final int x4;
private final int x7;
public MyClass(@AnotherUniversalAnnotation() @FieldAnnotation() @ParameterAnnotation() @PropertyAnnotation() @UniversalAnnotation() int, @PropertyOrFieldAnnotation() int, @PropertyOrParameterAnnotation() int, @ParameterOrFieldAnnotation() int, int, @AnotherUniversalAnnotation() int, @UniversalAnnotation() int);// .ctor(int, int, int, int, int, int, int)
public final int getX1();// getX1()
public final int getX2();// getX2()
public final int getX3();// getX3()
public final int getX4();// getX4()
public final int getX5();// getX5()
public final int getX6();// getX6()
public final int getX7();// getX7()
}
@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
@java.lang.annotation.Target(value = {java.lang.annotation.ElementType.PARAMETER})
@kotlin.annotation.Target(allowedTargets = {kotlin.annotation.AnnotationTarget.VALUE_PARAMETER})
public abstract @interface ParameterAnnotation /* ParameterAnnotation*/ {
}
@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
@java.lang.annotation.Target(value = {java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.PARAMETER})
@kotlin.annotation.Target(allowedTargets = {kotlin.annotation.AnnotationTarget.FIELD, kotlin.annotation.AnnotationTarget.VALUE_PARAMETER})
public abstract @interface ParameterOrFieldAnnotation /* ParameterOrFieldAnnotation*/ {
}
@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
@java.lang.annotation.Target(value = {})
@kotlin.annotation.Target(allowedTargets = {kotlin.annotation.AnnotationTarget.PROPERTY})
public abstract @interface PropertyAnnotation /* PropertyAnnotation*/ {
}
@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
@java.lang.annotation.Target(value = {java.lang.annotation.ElementType.FIELD})
@kotlin.annotation.Target(allowedTargets = {kotlin.annotation.AnnotationTarget.PROPERTY, kotlin.annotation.AnnotationTarget.FIELD})
public abstract @interface PropertyOrFieldAnnotation /* PropertyOrFieldAnnotation*/ {
}
@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
@java.lang.annotation.Target(value = {java.lang.annotation.ElementType.PARAMETER})
@kotlin.annotation.Target(allowedTargets = {kotlin.annotation.AnnotationTarget.PROPERTY, kotlin.annotation.AnnotationTarget.VALUE_PARAMETER})
public abstract @interface PropertyOrParameterAnnotation /* PropertyOrParameterAnnotation*/ {
}
@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
@java.lang.annotation.Target(value = {java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.PARAMETER})
@kotlin.annotation.Target(allowedTargets = {kotlin.annotation.AnnotationTarget.PROPERTY, kotlin.annotation.AnnotationTarget.FIELD, kotlin.annotation.AnnotationTarget.VALUE_PARAMETER})
public abstract @interface UniversalAnnotation /* UniversalAnnotation*/ {
}
@@ -0,0 +1,33 @@
@Target(AnnotationTarget.PROPERTY)
annotation class PropertyAnnotation
@Target(AnnotationTarget.FIELD)
annotation class FieldAnnotation
@Target(AnnotationTarget.VALUE_PARAMETER)
annotation class ParameterAnnotation
@Target(AnnotationTarget.PROPERTY, AnnotationTarget.FIELD)
annotation class PropertyOrFieldAnnotation
@Target(AnnotationTarget.PROPERTY, AnnotationTarget.VALUE_PARAMETER)
annotation class PropertyOrParameterAnnotation
@Target(AnnotationTarget.FIELD, AnnotationTarget.VALUE_PARAMETER)
annotation class ParameterOrFieldAnnotation
@Target(AnnotationTarget.PROPERTY, AnnotationTarget.FIELD, AnnotationTarget.VALUE_PARAMETER)
annotation class UniversalAnnotation
annotation class AnotherUniversalAnnotation
class MyClass(
@PropertyAnnotation @FieldAnnotation @ParameterAnnotation @UniversalAnnotation @AnotherUniversalAnnotation val x1: Int,
@PropertyOrFieldAnnotation val x2: Int,
@PropertyOrParameterAnnotation val x3: Int,
@ParameterOrFieldAnnotation val x4: Int,
@property:UniversalAnnotation @field:AnotherUniversalAnnotation val x5: Int,
@field:UniversalAnnotation @param:AnotherUniversalAnnotation val x6: Int,
@param:UniversalAnnotation @property:AnotherUniversalAnnotation val x7: Int
)
@@ -0,0 +1,80 @@
@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
public abstract @interface AnotherUniversalAnnotation /* AnotherUniversalAnnotation*/ {
}
@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
@java.lang.annotation.Target(value = {java.lang.annotation.ElementType.FIELD})
@kotlin.annotation.Target(allowedTargets = {kotlin.annotation.AnnotationTarget.FIELD})
public abstract @interface FieldAnnotation /* FieldAnnotation*/ {
}
public final class MyClass /* MyClass*/ {
@AnotherUniversalAnnotation()
private final int x5;
@FieldAnnotation()
private final int x1;
@UniversalAnnotation()
private final int x6;
private final int x2;
private final int x3;
private final int x4;
private final int x7;
public MyClass(@AnotherUniversalAnnotation() @ParameterAnnotation() @UniversalAnnotation() int, int, @PropertyOrParameterAnnotation() int, @ParameterOrFieldAnnotation() int, int, @AnotherUniversalAnnotation() int, @UniversalAnnotation() int);// .ctor(int, int, int, int, int, int, int)
public final int getX1();// getX1()
public final int getX2();// getX2()
public final int getX3();// getX3()
public final int getX4();// getX4()
public final int getX5();// getX5()
public final int getX6();// getX6()
public final int getX7();// getX7()
}
@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
@java.lang.annotation.Target(value = {java.lang.annotation.ElementType.PARAMETER})
@kotlin.annotation.Target(allowedTargets = {kotlin.annotation.AnnotationTarget.VALUE_PARAMETER})
public abstract @interface ParameterAnnotation /* ParameterAnnotation*/ {
}
@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
@java.lang.annotation.Target(value = {java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.PARAMETER})
@kotlin.annotation.Target(allowedTargets = {kotlin.annotation.AnnotationTarget.FIELD, kotlin.annotation.AnnotationTarget.VALUE_PARAMETER})
public abstract @interface ParameterOrFieldAnnotation /* ParameterOrFieldAnnotation*/ {
}
@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
@java.lang.annotation.Target(value = {})
@kotlin.annotation.Target(allowedTargets = {kotlin.annotation.AnnotationTarget.PROPERTY})
public abstract @interface PropertyAnnotation /* PropertyAnnotation*/ {
}
@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
@java.lang.annotation.Target(value = {java.lang.annotation.ElementType.FIELD})
@kotlin.annotation.Target(allowedTargets = {kotlin.annotation.AnnotationTarget.PROPERTY, kotlin.annotation.AnnotationTarget.FIELD})
public abstract @interface PropertyOrFieldAnnotation /* PropertyOrFieldAnnotation*/ {
}
@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
@java.lang.annotation.Target(value = {java.lang.annotation.ElementType.PARAMETER})
@kotlin.annotation.Target(allowedTargets = {kotlin.annotation.AnnotationTarget.PROPERTY, kotlin.annotation.AnnotationTarget.VALUE_PARAMETER})
public abstract @interface PropertyOrParameterAnnotation /* PropertyOrParameterAnnotation*/ {
}
@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
@java.lang.annotation.Target(value = {java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.PARAMETER})
@kotlin.annotation.Target(allowedTargets = {kotlin.annotation.AnnotationTarget.PROPERTY, kotlin.annotation.AnnotationTarget.FIELD, kotlin.annotation.AnnotationTarget.VALUE_PARAMETER})
public abstract @interface UniversalAnnotation /* UniversalAnnotation*/ {
}
@@ -0,0 +1,73 @@
// WITH_STDLIB
// WITH_REFLECT
// TARGET_BACKEND: JVM_IR
import kotlin.test.assertEquals
import kotlin.reflect.*
import kotlin.reflect.jvm.javaField
@Target(AnnotationTarget.PROPERTY)
annotation class PropertyAnnotation
@Target(AnnotationTarget.FIELD)
annotation class FieldAnnotation
@Target(AnnotationTarget.VALUE_PARAMETER)
annotation class ParameterAnnotation
@Target(AnnotationTarget.PROPERTY, AnnotationTarget.FIELD)
annotation class PropertyOrFieldAnnotation
@Target(AnnotationTarget.PROPERTY, AnnotationTarget.VALUE_PARAMETER)
annotation class PropertyOrParameterAnnotation
@Target(AnnotationTarget.FIELD, AnnotationTarget.VALUE_PARAMETER)
annotation class ParameterOrFieldAnnotation
@Target(AnnotationTarget.PROPERTY, AnnotationTarget.FIELD, AnnotationTarget.VALUE_PARAMETER)
annotation class UniversalAnnotation
annotation class AnotherUniversalAnnotation
class C(
@PropertyAnnotation @FieldAnnotation @ParameterAnnotation @UniversalAnnotation @AnotherUniversalAnnotation val x1: Int,
@PropertyOrFieldAnnotation val x2: Int,
@PropertyOrParameterAnnotation val x3: Int,
@ParameterOrFieldAnnotation val x4: Int,
@property:UniversalAnnotation @field:AnotherUniversalAnnotation val x5: Int,
@field:UniversalAnnotation @param:AnotherUniversalAnnotation val x6: Int,
@param:UniversalAnnotation @property:AnotherUniversalAnnotation val x7: Int
)
fun box(): String {
val parameterAnnotations = C::class.constructors.single().parameters.map { it.name to it.annotations.map { it.annotationClass.simpleName ?: "" }.toSet() }.toMap()
assertEquals(setOf("ParameterAnnotation", "UniversalAnnotation", "AnotherUniversalAnnotation"), parameterAnnotations["x1"])
assertEquals(setOf(), parameterAnnotations["x2"])
assertEquals(setOf("PropertyOrParameterAnnotation"), parameterAnnotations["x3"])
assertEquals(setOf("ParameterOrFieldAnnotation"), parameterAnnotations["x4"])
assertEquals(setOf(), parameterAnnotations["x5"])
assertEquals(setOf("AnotherUniversalAnnotation"), parameterAnnotations["x6"])
assertEquals(setOf("UniversalAnnotation"), parameterAnnotations["x7"])
val properties = C::class.members.filterIsInstance<KProperty<*>>()
val propertyAnnotations = properties.map { it.name to it.annotations.map { it.annotationClass.simpleName ?: "" }.toSet() }.toMap()
assertEquals(setOf("PropertyAnnotation"), propertyAnnotations["x1"])
assertEquals(setOf("PropertyOrFieldAnnotation"), propertyAnnotations["x2"])
assertEquals(setOf(), propertyAnnotations["x3"])
assertEquals(setOf(), propertyAnnotations["x4"])
assertEquals(setOf("UniversalAnnotation"), propertyAnnotations["x5"])
assertEquals(setOf(), propertyAnnotations["x6"])
assertEquals(setOf("AnotherUniversalAnnotation"), propertyAnnotations["x7"])
val fieldAnnotations = properties.map { it.javaField!! }.map { it.name to it.declaredAnnotations.map { it.annotationClass.simpleName ?: "" }.toSet() }.toMap()
assertEquals(setOf("FieldAnnotation"), fieldAnnotations["x1"])
assertEquals(setOf(), fieldAnnotations["x2"])
assertEquals(setOf(), fieldAnnotations["x3"])
assertEquals(setOf(), fieldAnnotations["x4"])
assertEquals(setOf("AnotherUniversalAnnotation"), fieldAnnotations["x5"])
assertEquals(setOf("UniversalAnnotation"), fieldAnnotations["x6"])
assertEquals(setOf(), fieldAnnotations["x7"])
return "OK"
}