Implementation of Kotlin's 'target' annotation mapping to Java's 'Target' annotation + tests
This commit is contained in:
@@ -24,8 +24,10 @@ import org.jetbrains.kotlin.descriptors.*;
|
|||||||
import org.jetbrains.kotlin.descriptors.annotations.Annotated;
|
import org.jetbrains.kotlin.descriptors.annotations.Annotated;
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationArgumentVisitor;
|
import org.jetbrains.kotlin.descriptors.annotations.AnnotationArgumentVisitor;
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor;
|
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor;
|
||||||
|
import org.jetbrains.kotlin.descriptors.annotations.AnnotationTarget;
|
||||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames;
|
import org.jetbrains.kotlin.load.java.JvmAnnotationNames;
|
||||||
import org.jetbrains.kotlin.name.FqName;
|
import org.jetbrains.kotlin.name.FqName;
|
||||||
|
import org.jetbrains.kotlin.resolve.AnnotationTargetChecker;
|
||||||
import org.jetbrains.kotlin.resolve.constants.*;
|
import org.jetbrains.kotlin.resolve.constants.*;
|
||||||
import org.jetbrains.kotlin.resolve.constants.StringValue;
|
import org.jetbrains.kotlin.resolve.constants.StringValue;
|
||||||
import org.jetbrains.kotlin.types.Flexibility;
|
import org.jetbrains.kotlin.types.Flexibility;
|
||||||
@@ -34,8 +36,10 @@ import org.jetbrains.kotlin.types.TypeUtils;
|
|||||||
import org.jetbrains.kotlin.types.TypesPackage;
|
import org.jetbrains.kotlin.types.TypesPackage;
|
||||||
import org.jetbrains.org.objectweb.asm.*;
|
import org.jetbrains.org.objectweb.asm.*;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import static org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilPackage.getClassObjectType;
|
import static org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilPackage.getClassObjectType;
|
||||||
@@ -123,6 +127,7 @@ public abstract class AnnotationCodegen {
|
|||||||
ClassDescriptor classDescriptor = (ClassDescriptor) annotated;
|
ClassDescriptor classDescriptor = (ClassDescriptor) annotated;
|
||||||
if (classDescriptor.getKind() == ClassKind.ANNOTATION_CLASS) {
|
if (classDescriptor.getKind() == ClassKind.ANNOTATION_CLASS) {
|
||||||
generateRetentionAnnotation(classDescriptor, annotationDescriptorsAlreadyPresent);
|
generateRetentionAnnotation(classDescriptor, annotationDescriptorsAlreadyPresent);
|
||||||
|
generateTargetAnnotation(classDescriptor, annotationDescriptorsAlreadyPresent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -166,6 +171,47 @@ public abstract class AnnotationCodegen {
|
|||||||
generateAnnotationIfNotPresent(annotationDescriptorsAlreadyPresent, annotationClass);
|
generateAnnotationIfNotPresent(annotationDescriptorsAlreadyPresent, annotationClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final Map<AnnotationTarget, ElementType> annotationTargetMap =
|
||||||
|
new EnumMap<AnnotationTarget, ElementType>(AnnotationTarget.class);
|
||||||
|
|
||||||
|
static {
|
||||||
|
annotationTargetMap.put(AnnotationTarget.PACKAGE, ElementType.PACKAGE);
|
||||||
|
annotationTargetMap.put(AnnotationTarget.CLASSIFIER, ElementType.TYPE);
|
||||||
|
annotationTargetMap.put(AnnotationTarget.ANNOTATION_CLASS, ElementType.ANNOTATION_TYPE);
|
||||||
|
annotationTargetMap.put(AnnotationTarget.CONSTRUCTOR, ElementType.CONSTRUCTOR);
|
||||||
|
annotationTargetMap.put(AnnotationTarget.LOCAL_VARIABLE, ElementType.LOCAL_VARIABLE);
|
||||||
|
annotationTargetMap.put(AnnotationTarget.FUNCTION, ElementType.METHOD);
|
||||||
|
annotationTargetMap.put(AnnotationTarget.PROPERTY_GETTER, ElementType.METHOD);
|
||||||
|
annotationTargetMap.put(AnnotationTarget.PROPERTY_SETTER, ElementType.METHOD);
|
||||||
|
annotationTargetMap.put(AnnotationTarget.FIELD, ElementType.FIELD);
|
||||||
|
annotationTargetMap.put(AnnotationTarget.VALUE_PARAMETER, ElementType.PARAMETER);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void generateTargetAnnotation(@NotNull ClassDescriptor classDescriptor, @NotNull Set<String> annotationDescriptorsAlreadyPresent) {
|
||||||
|
String descriptor = Type.getType(Target.class).getDescriptor();
|
||||||
|
if (!annotationDescriptorsAlreadyPresent.add(descriptor)) return;
|
||||||
|
Set<AnnotationTarget> targets = AnnotationTargetChecker.INSTANCE$.possibleTargetSet(classDescriptor);
|
||||||
|
Set<ElementType> javaTargets;
|
||||||
|
if (targets == null) {
|
||||||
|
javaTargets = getJavaTargetList(classDescriptor);
|
||||||
|
if (javaTargets == null) return;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
javaTargets = EnumSet.noneOf(ElementType.class);
|
||||||
|
for (AnnotationTarget target : targets) {
|
||||||
|
if (annotationTargetMap.get(target) == null) continue;
|
||||||
|
javaTargets.add(annotationTargetMap.get(target));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AnnotationVisitor visitor = visitAnnotation(descriptor, true);
|
||||||
|
AnnotationVisitor arrayVisitor = visitor.visitArray("value");
|
||||||
|
for (ElementType javaTarget : javaTargets) {
|
||||||
|
arrayVisitor.visitEnum(null, Type.getType(ElementType.class).getDescriptor(), javaTarget.name());
|
||||||
|
}
|
||||||
|
arrayVisitor.visitEnd();
|
||||||
|
visitor.visitEnd();
|
||||||
|
}
|
||||||
|
|
||||||
private void generateRetentionAnnotation(@NotNull ClassDescriptor classDescriptor, @NotNull Set<String> annotationDescriptorsAlreadyPresent) {
|
private void generateRetentionAnnotation(@NotNull ClassDescriptor classDescriptor, @NotNull Set<String> annotationDescriptorsAlreadyPresent) {
|
||||||
RetentionPolicy policy = getRetentionPolicy(classDescriptor);
|
RetentionPolicy policy = getRetentionPolicy(classDescriptor);
|
||||||
String descriptor = Type.getType(Retention.class).getDescriptor();
|
String descriptor = Type.getType(Retention.class).getDescriptor();
|
||||||
@@ -337,18 +383,46 @@ public abstract class AnnotationCodegen {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private Set<ElementType> getJavaTargetList(ClassDescriptor descriptor) {
|
||||||
|
AnnotationDescriptor targetAnnotation = descriptor.getAnnotations().findAnnotation(new FqName(Target.class.getName()));
|
||||||
|
if (targetAnnotation != null) {
|
||||||
|
Collection<ConstantValue<?>> valueArguments = targetAnnotation.getAllValueArguments().values();
|
||||||
|
if (!valueArguments.isEmpty()) {
|
||||||
|
ConstantValue<?> compileTimeConstant = valueArguments.iterator().next();
|
||||||
|
if (compileTimeConstant instanceof ArrayValue) {
|
||||||
|
List<? extends ConstantValue<?>> values = ((ArrayValue) compileTimeConstant).getValue();
|
||||||
|
Set<ElementType> result = EnumSet.noneOf(ElementType.class);
|
||||||
|
for (ConstantValue<?> value : values) {
|
||||||
|
if (value instanceof EnumValue) {
|
||||||
|
ClassDescriptor enumEntry = ((EnumValue) value).getValue();
|
||||||
|
JetType classObjectType = getClassObjectType(enumEntry);
|
||||||
|
if (classObjectType != null) {
|
||||||
|
if ("java/lang/annotation/ElementType".equals(typeMapper.mapType(classObjectType).getInternalName())) {
|
||||||
|
result.add(ElementType.valueOf(enumEntry.getName().asString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private RetentionPolicy getRetentionPolicy(@NotNull Annotated descriptor) {
|
private RetentionPolicy getRetentionPolicy(@NotNull Annotated descriptor) {
|
||||||
AnnotationDescriptor kotlinAnnotation = descriptor.getAnnotations().findAnnotation(KotlinBuiltIns.FQ_NAMES.annotation);
|
AnnotationDescriptor kotlinAnnotation = descriptor.getAnnotations().findAnnotation(KotlinBuiltIns.FQ_NAMES.annotation);
|
||||||
if (kotlinAnnotation != null) {
|
if (kotlinAnnotation != null) {
|
||||||
for (Map.Entry<ValueParameterDescriptor, ConstantValue<?>> argument: kotlinAnnotation.getAllValueArguments().entrySet()) {
|
for (Map.Entry<ValueParameterDescriptor, ConstantValue<?>> argument : kotlinAnnotation.getAllValueArguments().entrySet()) {
|
||||||
if ("retention".equals(argument.getKey().getName().asString()) && argument.getValue() instanceof EnumValue) {
|
if ("retention".equals(argument.getKey().getName().asString()) && argument.getValue() instanceof EnumValue) {
|
||||||
ClassDescriptor enumEntry = ((EnumValue) argument.getValue()).getValue();
|
ClassDescriptor enumEntry = ((EnumValue) argument.getValue()).getValue();
|
||||||
JetType classObjectType = getClassObjectType(enumEntry);
|
JetType classObjectType = getClassObjectType(enumEntry);
|
||||||
if (classObjectType != null) {
|
if (classObjectType != null) {
|
||||||
if ("kotlin/annotation/AnnotationRetention".equals(typeMapper.mapType(classObjectType).getInternalName())) {
|
if ("kotlin/annotation/AnnotationRetention".equals(typeMapper.mapType(classObjectType).getInternalName())) {
|
||||||
String entryName = enumEntry.getName().asString();
|
String entryName = enumEntry.getName().asString();
|
||||||
for (KotlinRetention retention: KotlinRetention.values()) {
|
for (KotlinRetention retention : KotlinRetention.values()) {
|
||||||
if (retention.name().equals(entryName)) return retention.mapped;
|
if (retention.name().equals(entryName)) return retention.mapped;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,33 +27,13 @@ import org.jetbrains.kotlin.resolve.constants.ArrayValue
|
|||||||
import org.jetbrains.kotlin.resolve.constants.EnumValue
|
import org.jetbrains.kotlin.resolve.constants.EnumValue
|
||||||
import org.jetbrains.kotlin.types.JetType
|
import org.jetbrains.kotlin.types.JetType
|
||||||
import org.jetbrains.kotlin.types.TypeUtils
|
import org.jetbrains.kotlin.types.TypeUtils
|
||||||
|
import java.lang.annotation.ElementType
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
import org.jetbrains.kotlin.descriptors.annotations.AnnotationTarget
|
||||||
|
import kotlin.annotation
|
||||||
|
|
||||||
public object AnnotationTargetChecker {
|
public object AnnotationTargetChecker {
|
||||||
|
|
||||||
// NOTE: this enum must have the same entries with kotlin.annotation.AnnotationTarget
|
|
||||||
public enum class Target(val description: String, val isDefault: Boolean = true) {
|
|
||||||
PACKAGE("package"),
|
|
||||||
CLASSIFIER("classifier"),
|
|
||||||
ANNOTATION_CLASS("annotation class"),
|
|
||||||
TYPE_PARAMETER("type parameter", false),
|
|
||||||
PROPERTY("property"),
|
|
||||||
FIELD("field"),
|
|
||||||
LOCAL_VARIABLE("local variable"),
|
|
||||||
VALUE_PARAMETER("value parameter"),
|
|
||||||
CONSTRUCTOR("constructor"),
|
|
||||||
FUNCTION("function"),
|
|
||||||
PROPERTY_GETTER("getter"),
|
|
||||||
PROPERTY_SETTER("setter"),
|
|
||||||
TYPE("type usage", false),
|
|
||||||
EXPRESSION("expression", false),
|
|
||||||
FILE("file", false)
|
|
||||||
}
|
|
||||||
|
|
||||||
private val DEFAULT_TARGET_LIST = Target.values().filter { it.isDefault }.map { it.name() }
|
|
||||||
|
|
||||||
private val ALL_TARGET_LIST = Target.values().map { it.name() }
|
|
||||||
|
|
||||||
public fun check(annotated: JetAnnotated, trace: BindingTrace, descriptor: ClassDescriptor? = null) {
|
public fun check(annotated: JetAnnotated, trace: BindingTrace, descriptor: ClassDescriptor? = null) {
|
||||||
if (annotated is JetTypeParameter) return // TODO: support type parameter annotations
|
if (annotated is JetTypeParameter) return // TODO: support type parameter annotations
|
||||||
val actualTargets = getActualTargetList(annotated, descriptor)
|
val actualTargets = getActualTargetList(annotated, descriptor)
|
||||||
@@ -82,7 +62,7 @@ public object AnnotationTargetChecker {
|
|||||||
|
|
||||||
public fun checkExpression(expression: JetExpression, trace: BindingTrace) {
|
public fun checkExpression(expression: JetExpression, trace: BindingTrace) {
|
||||||
for (entry in expression.getAnnotationEntries()) {
|
for (entry in expression.getAnnotationEntries()) {
|
||||||
checkAnnotationEntry(entry, listOf(Target.EXPRESSION), trace)
|
checkAnnotationEntry(entry, listOf(AnnotationTarget.EXPRESSION), trace)
|
||||||
}
|
}
|
||||||
if (expression is JetFunctionLiteralExpression) {
|
if (expression is JetFunctionLiteralExpression) {
|
||||||
for (parameter in expression.getValueParameters()) {
|
for (parameter in expression.getValueParameters()) {
|
||||||
@@ -91,51 +71,55 @@ public object AnnotationTargetChecker {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun possibleTargetList(entry: JetAnnotationEntry, trace: BindingTrace): List<String> {
|
public fun possibleTargetSet(classDescriptor: ClassDescriptor): Set<AnnotationTarget>? {
|
||||||
val descriptor = trace.get(BindingContext.ANNOTATION, entry) ?: return DEFAULT_TARGET_LIST
|
|
||||||
// For descriptor with error type, all targets are considered as possible
|
|
||||||
if (descriptor.getType().isError()) return ALL_TARGET_LIST
|
|
||||||
val classDescriptor = TypeUtils.getClassDescriptor(descriptor.getType()) ?: return DEFAULT_TARGET_LIST
|
|
||||||
val targetEntryDescriptor = classDescriptor.getAnnotations().findAnnotation(KotlinBuiltIns.FQ_NAMES.target)
|
val targetEntryDescriptor = classDescriptor.getAnnotations().findAnnotation(KotlinBuiltIns.FQ_NAMES.target)
|
||||||
?: return DEFAULT_TARGET_LIST
|
?: return null
|
||||||
val valueArguments = targetEntryDescriptor.getAllValueArguments()
|
val valueArguments = targetEntryDescriptor.getAllValueArguments()
|
||||||
val valueArgument = valueArguments.entrySet().firstOrNull()?.getValue() as? ArrayValue ?: return DEFAULT_TARGET_LIST
|
val valueArgument = valueArguments.entrySet().firstOrNull()?.getValue() as? ArrayValue ?: return null
|
||||||
return valueArgument.value.filterIsInstance<EnumValue>().map { it.value.getName().asString() }
|
return valueArgument.value.filterIsInstance<EnumValue>().map {
|
||||||
|
AnnotationTarget.valueOrNull(it.value.getName().asString())
|
||||||
|
}.filterNotNull().toSet()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun checkAnnotationEntry(entry: JetAnnotationEntry, actualTargets: List<Target>, trace: BindingTrace) {
|
private fun possibleTargetSet(entry: JetAnnotationEntry, trace: BindingTrace): Set<AnnotationTarget> {
|
||||||
val possibleTargets = possibleTargetList(entry, trace)
|
val descriptor = trace.get(BindingContext.ANNOTATION, entry) ?: return AnnotationTarget.DEFAULT_TARGET_SET
|
||||||
for (actualTarget in actualTargets) {
|
// For descriptor with error type, all targets are considered as possible
|
||||||
if (actualTarget.name() in possibleTargets) return
|
if (descriptor.getType().isError()) return AnnotationTarget.ALL_TARGET_SET
|
||||||
}
|
val classDescriptor = TypeUtils.getClassDescriptor(descriptor.getType()) ?: return AnnotationTarget.DEFAULT_TARGET_SET
|
||||||
|
return possibleTargetSet(classDescriptor) ?: AnnotationTarget.DEFAULT_TARGET_SET
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun checkAnnotationEntry(entry: JetAnnotationEntry, actualTargets: List<AnnotationTarget>, trace: BindingTrace) {
|
||||||
|
val possibleTargets = possibleTargetSet(entry, trace)
|
||||||
|
if (actualTargets.any { it in possibleTargets }) return
|
||||||
trace.report(Errors.WRONG_ANNOTATION_TARGET.on(entry, actualTargets.firstOrNull()?.description ?: "unidentified target"))
|
trace.report(Errors.WRONG_ANNOTATION_TARGET.on(entry, actualTargets.firstOrNull()?.description ?: "unidentified target"))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getActualTargetList(annotated: JetAnnotated, descriptor: ClassDescriptor?): List<Target> {
|
private fun getActualTargetList(annotated: JetAnnotated, descriptor: ClassDescriptor?): List<AnnotationTarget> {
|
||||||
if (annotated is JetClassOrObject) {
|
if (annotated is JetClassOrObject) {
|
||||||
if (annotated is JetEnumEntry) return listOf(Target.PROPERTY, Target.FIELD)
|
if (annotated is JetEnumEntry) return listOf(AnnotationTarget.PROPERTY, AnnotationTarget.FIELD)
|
||||||
return if (descriptor?.getKind() == ClassKind.ANNOTATION_CLASS) {
|
return if (descriptor?.getKind() == ClassKind.ANNOTATION_CLASS) {
|
||||||
listOf(Target.ANNOTATION_CLASS, Target.CLASSIFIER)
|
listOf(AnnotationTarget.ANNOTATION_CLASS, AnnotationTarget.CLASSIFIER)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
listOf(Target.CLASSIFIER)
|
listOf(AnnotationTarget.CLASSIFIER)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (annotated is JetProperty) {
|
if (annotated is JetProperty) {
|
||||||
return if (annotated.isLocal()) listOf(Target.LOCAL_VARIABLE) else listOf(Target.PROPERTY, Target.FIELD)
|
return if (annotated.isLocal()) listOf(AnnotationTarget.LOCAL_VARIABLE) else listOf(AnnotationTarget.PROPERTY, AnnotationTarget.FIELD)
|
||||||
}
|
}
|
||||||
if (annotated is JetParameter) {
|
if (annotated is JetParameter) {
|
||||||
return if (annotated.hasValOrVar()) listOf(Target.PROPERTY, Target.FIELD) else listOf(Target.VALUE_PARAMETER)
|
return if (annotated.hasValOrVar()) listOf(AnnotationTarget.PROPERTY, AnnotationTarget.FIELD) else listOf(AnnotationTarget.VALUE_PARAMETER)
|
||||||
}
|
}
|
||||||
if (annotated is JetConstructor<*>) return listOf(Target.CONSTRUCTOR)
|
if (annotated is JetConstructor<*>) return listOf(AnnotationTarget.CONSTRUCTOR)
|
||||||
if (annotated is JetFunction) return listOf(Target.FUNCTION)
|
if (annotated is JetFunction) return listOf(AnnotationTarget.FUNCTION)
|
||||||
if (annotated is JetPropertyAccessor) {
|
if (annotated is JetPropertyAccessor) {
|
||||||
return if (annotated.isGetter()) listOf(Target.PROPERTY_GETTER) else listOf(Target.PROPERTY_SETTER)
|
return if (annotated.isGetter()) listOf(AnnotationTarget.PROPERTY_GETTER) else listOf(AnnotationTarget.PROPERTY_SETTER)
|
||||||
}
|
}
|
||||||
if (annotated is JetPackageDirective) return listOf(Target.PACKAGE)
|
if (annotated is JetPackageDirective) return listOf(AnnotationTarget.PACKAGE)
|
||||||
if (annotated is JetTypeReference) return listOf(Target.TYPE)
|
if (annotated is JetTypeReference) return listOf(AnnotationTarget.TYPE)
|
||||||
if (annotated is JetFile) return listOf(Target.FILE)
|
if (annotated is JetFile) return listOf(AnnotationTarget.FILE)
|
||||||
if (annotated is JetTypeParameter) return listOf(Target.TYPE_PARAMETER)
|
if (annotated is JetTypeParameter) return listOf(AnnotationTarget.TYPE_PARAMETER)
|
||||||
return listOf()
|
return listOf()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package test;
|
||||||
|
|
||||||
|
@meta @interface MyAnn {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@meta class My {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
annotation.java:7:1:compiler.err.annotation.type.not.applicable
|
||||||
|
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
target(AnnotationTarget.ANNOTATION_CLASS)
|
||||||
|
annotation class meta
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
test.meta() public/*package*/ final class MyAnn : kotlin.Annotation {
|
||||||
|
public/*package*/ constructor MyAnn()
|
||||||
|
}
|
||||||
|
|
||||||
|
kotlin.annotation.target(allowedTargets = {AnnotationTarget.ANNOTATION_CLASS}) kotlin.annotation.annotation() java.lang.annotation.Target(value = {ElementType.ANNOTATION_TYPE}) internal final class meta : kotlin.Annotation {
|
||||||
|
public constructor meta()
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package test;
|
||||||
|
|
||||||
|
@base class My {
|
||||||
|
|
||||||
|
@base int foo(@base int i) {
|
||||||
|
return i + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
annotation class base
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
test.base() public/*package*/ open class My {
|
||||||
|
public/*package*/ constructor My()
|
||||||
|
test.base() public/*package*/ open fun foo(/*0*/ test.base() kotlin.Int): kotlin.Int
|
||||||
|
}
|
||||||
|
|
||||||
|
kotlin.annotation.annotation() internal final class base : kotlin.Annotation {
|
||||||
|
public constructor base()
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package test;
|
||||||
|
|
||||||
|
@classifier class My {
|
||||||
|
|
||||||
|
@classifier int foo() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
classifier.java:5:5:compiler.err.annotation.type.not.applicable
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
target(AnnotationTarget.CLASSIFIER)
|
||||||
|
annotation class classifier
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
kotlin.annotation.target(allowedTargets = {AnnotationTarget.CLASSIFIER}) kotlin.annotation.annotation() java.lang.annotation.Target(value = {ElementType.TYPE}) internal final class classifier : kotlin.Annotation {
|
||||||
|
public constructor classifier()
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package test;
|
||||||
|
|
||||||
|
class My {
|
||||||
|
|
||||||
|
@constructor My() {}
|
||||||
|
|
||||||
|
@constructor int foo() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
constructor.java:7:5:compiler.err.annotation.type.not.applicable
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
target(AnnotationTarget.CONSTRUCTOR)
|
||||||
|
annotation class constructor
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
kotlin.annotation.target(allowedTargets = {AnnotationTarget.CONSTRUCTOR}) kotlin.annotation.annotation() java.lang.annotation.Target(value = {ElementType.CONSTRUCTOR}) internal final class constructor : kotlin.Annotation {
|
||||||
|
public constructor constructor()
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package test;
|
||||||
|
|
||||||
|
@empty class My {
|
||||||
|
|
||||||
|
@empty int foo(@empty int i) {
|
||||||
|
return i + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
empty.java:3:1:compiler.err.annotation.type.not.applicable
|
||||||
|
empty.java:5:20:compiler.err.annotation.type.not.applicable
|
||||||
|
empty.java:5:5:compiler.err.annotation.type.not.applicable
|
||||||
|
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
target()
|
||||||
|
annotation class empty
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
kotlin.annotation.target(allowedTargets = {}) kotlin.annotation.annotation() java.lang.annotation.Target(value = {}) internal final class empty : kotlin.Annotation {
|
||||||
|
public constructor empty()
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package test;
|
||||||
|
|
||||||
|
class My {
|
||||||
|
@field int prop;
|
||||||
|
|
||||||
|
@field int get() { return prop; }
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
field.java:6:5:compiler.err.annotation.type.not.applicable
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
target(AnnotationTarget.FIELD)
|
||||||
|
annotation class field
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
kotlin.annotation.target(allowedTargets = {AnnotationTarget.FIELD}) kotlin.annotation.annotation() java.lang.annotation.Target(value = {ElementType.FIELD}) internal final class field : kotlin.Annotation {
|
||||||
|
public constructor field()
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package test;
|
||||||
|
|
||||||
|
@function class My {
|
||||||
|
|
||||||
|
@function int foo() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
function.java:3:1:compiler.err.annotation.type.not.applicable
|
||||||
|
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
target(AnnotationTarget.FUNCTION)
|
||||||
|
annotation class function
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
kotlin.annotation.target(allowedTargets = {AnnotationTarget.FUNCTION}) kotlin.annotation.annotation() java.lang.annotation.Target(value = {ElementType.METHOD}) internal final class function : kotlin.Annotation {
|
||||||
|
public constructor function()
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package test;
|
||||||
|
|
||||||
|
@getter class My {
|
||||||
|
|
||||||
|
@getter int foo() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
getter.java:3:1:compiler.err.annotation.type.not.applicable
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
target(AnnotationTarget.PROPERTY_GETTER)
|
||||||
|
annotation class getter
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
kotlin.annotation.target(allowedTargets = {AnnotationTarget.PROPERTY_GETTER}) kotlin.annotation.annotation() java.lang.annotation.Target(value = {ElementType.METHOD}) internal final class getter : kotlin.Annotation {
|
||||||
|
public constructor getter()
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package test;
|
||||||
|
|
||||||
|
class My {
|
||||||
|
|
||||||
|
int foo(@local int i) {
|
||||||
|
@local int j = i + 1;
|
||||||
|
return j;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
local.java:5:13:compiler.err.annotation.type.not.applicable
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
target(AnnotationTarget.LOCAL_VARIABLE)
|
||||||
|
annotation class local
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
kotlin.annotation.target(allowedTargets = {AnnotationTarget.LOCAL_VARIABLE}) kotlin.annotation.annotation() java.lang.annotation.Target(value = {ElementType.LOCAL_VARIABLE}) internal final class local : kotlin.Annotation {
|
||||||
|
public constructor local()
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package test;
|
||||||
|
|
||||||
|
@multiple class My {
|
||||||
|
|
||||||
|
@multiple int foo(@multiple int i) {
|
||||||
|
return i + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
multiple.java:5:23:compiler.err.annotation.type.not.applicable
|
||||||
|
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
target(AnnotationTarget.CLASSIFIER, AnnotationTarget.FUNCTION)
|
||||||
|
annotation class multiple
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
kotlin.annotation.target(allowedTargets = {AnnotationTarget.CLASSIFIER, AnnotationTarget.FUNCTION}) kotlin.annotation.annotation() java.lang.annotation.Target(value = {ElementType.TYPE, ElementType.METHOD}) internal final class multiple : kotlin.Annotation {
|
||||||
|
public constructor multiple()
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
@pck package test;
|
||||||
|
|
||||||
|
@pck class My {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
package-info.java:3:1:compiler.err.annotation.type.not.applicable
|
||||||
|
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
target(AnnotationTarget.PACKAGE)
|
||||||
|
annotation class pck
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
test.pck() public/*package*/ interface `package-info` {
|
||||||
|
}
|
||||||
|
|
||||||
|
kotlin.annotation.target(allowedTargets = {AnnotationTarget.PACKAGE}) kotlin.annotation.annotation() java.lang.annotation.Target(value = {ElementType.PACKAGE}) internal final class pck : kotlin.Annotation {
|
||||||
|
public constructor pck()
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package test;
|
||||||
|
|
||||||
|
@parameter class My {
|
||||||
|
|
||||||
|
@parameter int foo(@parameter int i) {
|
||||||
|
return i + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
parameter.java:3:1:compiler.err.annotation.type.not.applicable
|
||||||
|
parameter.java:5:5:compiler.err.annotation.type.not.applicable
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
target(AnnotationTarget.VALUE_PARAMETER)
|
||||||
|
annotation class parameter
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
kotlin.annotation.target(allowedTargets = {AnnotationTarget.VALUE_PARAMETER}) kotlin.annotation.annotation() java.lang.annotation.Target(value = {ElementType.PARAMETER}) internal final class parameter : kotlin.Annotation {
|
||||||
|
public constructor parameter()
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package test;
|
||||||
|
|
||||||
|
class My {
|
||||||
|
@property int prop;
|
||||||
|
|
||||||
|
@property int get() { return prop; }
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
property.java:4:5:compiler.err.annotation.type.not.applicable
|
||||||
|
property.java:6:5:compiler.err.annotation.type.not.applicable
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
target(AnnotationTarget.PROPERTY)
|
||||||
|
annotation class property
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
kotlin.annotation.target(allowedTargets = {AnnotationTarget.PROPERTY}) kotlin.annotation.annotation() java.lang.annotation.Target(value = {}) internal final class property : kotlin.Annotation {
|
||||||
|
public constructor property()
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package test;
|
||||||
|
|
||||||
|
@setter class My {
|
||||||
|
|
||||||
|
@setter int foo() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
setter.java:3:1:compiler.err.annotation.type.not.applicable
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
target(AnnotationTarget.PROPERTY_SETTER)
|
||||||
|
annotation class setter
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
kotlin.annotation.target(allowedTargets = {AnnotationTarget.PROPERTY_SETTER}) kotlin.annotation.annotation() java.lang.annotation.Target(value = {ElementType.METHOD}) internal final class setter : kotlin.Annotation {
|
||||||
|
public constructor setter()
|
||||||
|
}
|
||||||
+1
-1
@@ -7,7 +7,7 @@ kotlin.annotation.annotation() internal final class my : kotlin.Annotation {
|
|||||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
}
|
}
|
||||||
|
|
||||||
kotlin.annotation.annotation() java.lang.annotation.Target(value = {ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR}) internal final class my1 : kotlin.Annotation {
|
kotlin.annotation.annotation() internal final class my1 : kotlin.Annotation {
|
||||||
public constructor my1()
|
public constructor my1()
|
||||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package test
|
|||||||
|
|
||||||
public interface ArrayOfEnumInParam {
|
public interface ArrayOfEnumInParam {
|
||||||
|
|
||||||
java.lang.annotation.Target(value = {ElementType.FIELD, ElementType.CONSTRUCTOR}) public final class targetAnnotation : kotlin.Annotation {
|
public final class targetAnnotation : kotlin.Annotation {
|
||||||
public constructor targetAnnotation(/*0*/ value: kotlin.String)
|
public constructor targetAnnotation(/*0*/ value: kotlin.String)
|
||||||
public final val value: kotlin.String
|
public final val value: kotlin.String
|
||||||
public abstract fun value(): kotlin.String
|
public abstract fun value(): kotlin.String
|
||||||
|
|||||||
+93
@@ -553,4 +553,97 @@ public class CompileJavaAgainstKotlinTestGenerated extends AbstractCompileJavaAg
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/compileJavaAgainstKotlin/targets")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class Targets extends AbstractCompileJavaAgainstKotlinTest {
|
||||||
|
public void testAllFilesPresentInTargets() throws Exception {
|
||||||
|
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/compileJavaAgainstKotlin/targets"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("annotation.kt")
|
||||||
|
public void testAnnotation() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/compileJavaAgainstKotlin/targets/annotation.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("base.kt")
|
||||||
|
public void testBase() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/compileJavaAgainstKotlin/targets/base.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("classifier.kt")
|
||||||
|
public void testClassifier() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/compileJavaAgainstKotlin/targets/classifier.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("constructor.kt")
|
||||||
|
public void testConstructor() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/compileJavaAgainstKotlin/targets/constructor.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("empty.kt")
|
||||||
|
public void testEmpty() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/compileJavaAgainstKotlin/targets/empty.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("field.kt")
|
||||||
|
public void testField() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/compileJavaAgainstKotlin/targets/field.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("function.kt")
|
||||||
|
public void testFunction() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/compileJavaAgainstKotlin/targets/function.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("getter.kt")
|
||||||
|
public void testGetter() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/compileJavaAgainstKotlin/targets/getter.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("local.kt")
|
||||||
|
public void testLocal() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/compileJavaAgainstKotlin/targets/local.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("multiple.kt")
|
||||||
|
public void testMultiple() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/compileJavaAgainstKotlin/targets/multiple.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("package-info.kt")
|
||||||
|
public void testPackage_info() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/compileJavaAgainstKotlin/targets/package-info.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("parameter.kt")
|
||||||
|
public void testParameter() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/compileJavaAgainstKotlin/targets/parameter.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("property.kt")
|
||||||
|
public void testProperty() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/compileJavaAgainstKotlin/targets/property.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("setter.kt")
|
||||||
|
public void testSetter() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/compileJavaAgainstKotlin/targets/setter.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ import org.junit.Assert;
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isEnumEntry;
|
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isEnumEntry;
|
||||||
@@ -52,6 +53,7 @@ public class RecursiveDescriptorComparator {
|
|||||||
static {
|
static {
|
||||||
excludedAnnotations.add(new FqName(ExpectedLoadErrorsUtil.ANNOTATION_CLASS_NAME));
|
excludedAnnotations.add(new FqName(ExpectedLoadErrorsUtil.ANNOTATION_CLASS_NAME));
|
||||||
excludedAnnotations.add(new FqName(Retention.class.getName()));
|
excludedAnnotations.add(new FqName(Retention.class.getName()));
|
||||||
|
excludedAnnotations.add(new FqName(Target.class.getName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final DescriptorRenderer DEFAULT_RENDERER = DescriptorRenderer.Companion.withOptions(
|
private static final DescriptorRenderer DEFAULT_RENDERER = DescriptorRenderer.Companion.withOptions(
|
||||||
|
|||||||
@@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2015 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.descriptors.annotations
|
||||||
|
|
||||||
|
import java.util.*
|
||||||
|
import kotlin.annotation
|
||||||
|
|
||||||
|
// NOTE: this enum must have the same entries with kotlin.annotation.AnnotationTarget
|
||||||
|
public enum class AnnotationTarget(val description: String, val isDefault: Boolean = true) {
|
||||||
|
PACKAGE("package"),
|
||||||
|
CLASSIFIER("classifier"),
|
||||||
|
ANNOTATION_CLASS("annotation class"),
|
||||||
|
TYPE_PARAMETER("type parameter", false),
|
||||||
|
PROPERTY("property"),
|
||||||
|
FIELD("field"),
|
||||||
|
LOCAL_VARIABLE("local variable"),
|
||||||
|
VALUE_PARAMETER("value parameter"),
|
||||||
|
CONSTRUCTOR("constructor"),
|
||||||
|
FUNCTION("function"),
|
||||||
|
PROPERTY_GETTER("getter"),
|
||||||
|
PROPERTY_SETTER("setter"),
|
||||||
|
TYPE("type usage", false),
|
||||||
|
EXPRESSION("expression", false),
|
||||||
|
FILE("file", false);
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
|
||||||
|
private val map = HashMap<String, AnnotationTarget>()
|
||||||
|
|
||||||
|
init {
|
||||||
|
for (target in AnnotationTarget.values()) {
|
||||||
|
map[target.name()] = target
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public fun valueOrNull(name: String): AnnotationTarget? = map[name]
|
||||||
|
|
||||||
|
public val DEFAULT_TARGET_SET: Set<AnnotationTarget> = values().filter { it.isDefault }.toSet()
|
||||||
|
|
||||||
|
public val ALL_TARGET_SET: Set<AnnotationTarget> = values().toSet()
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user