Binary or runtime repeatable annotations are not allowed for JVM. Some tests fixed accordingly.

This commit is contained in:
Mikhail Glukhikh
2015-07-30 14:31:10 +03:00
parent f51107b502
commit dfaed3fef3
26 changed files with 104 additions and 75 deletions
@@ -18,7 +18,6 @@ package org.jetbrains.kotlin.codegen;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
import org.jetbrains.kotlin.codegen.state.JetTypeMapper;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.descriptors.annotations.*;
@@ -27,6 +26,7 @@ import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.resolve.AnnotationChecker;
import org.jetbrains.kotlin.resolve.constants.*;
import org.jetbrains.kotlin.resolve.constants.StringValue;
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilPackage;
import org.jetbrains.kotlin.types.Flexibility;
import org.jetbrains.kotlin.types.JetType;
import org.jetbrains.kotlin.types.TypeUtils;
@@ -407,20 +407,9 @@ public abstract class AnnotationCodegen {
@NotNull
private RetentionPolicy getRetentionPolicy(@NotNull Annotated descriptor) {
AnnotationDescriptor kotlinAnnotation = descriptor.getAnnotations().findAnnotation(KotlinBuiltIns.FQ_NAMES.annotation);
if (kotlinAnnotation != null) {
for (Map.Entry<ValueParameterDescriptor, ConstantValue<?>> argument : kotlinAnnotation.getAllValueArguments().entrySet()) {
if ("retention".equals(argument.getKey().getName().asString()) && argument.getValue() instanceof EnumValue) {
ClassDescriptor enumEntry = ((EnumValue) argument.getValue()).getValue();
JetType classObjectType = getClassObjectType(enumEntry);
if (classObjectType != null) {
if ("kotlin/annotation/AnnotationRetention".equals(typeMapper.mapType(classObjectType).getInternalName())) {
KotlinRetention retention = KotlinRetention.valueOf(enumEntry.getName().asString());
return annotationRetentionMap.get(retention);
}
}
}
}
KotlinRetention retention = DescriptorUtilPackage.getAnnotationRetention(descriptor);
if (retention != null) {
return annotationRetentionMap.get(retention);
}
AnnotationDescriptor retentionAnnotation = descriptor.getAnnotations().findAnnotation(new FqName(Retention.class.getName()));
if (retentionAnnotation != null) {
@@ -58,6 +58,7 @@ public class DefaultErrorMessagesJvm implements DefaultErrorMessages.Extension {
MAP.put(ErrorsJvm.POSITIONED_VALUE_ARGUMENT_FOR_JAVA_ANNOTATION, "Only named arguments are available for Java annotations");
MAP.put(ErrorsJvm.DEPRECATED_ANNOTATION_METHOD_CALL, "Annotation methods are deprecated. Use property instead");
MAP.put(ErrorsJvm.DEPRECATED_JAVA_ANNOTATION, "This annotation is deprecated in Kotlin. Use ''{0}'' instead", Renderers.TO_STRING);
MAP.put(ErrorsJvm.NON_SOURCE_REPEATED_ANNOTATION, "Only annotations with SOURCE retention can be repeated on JVM platform");
MAP.put(ErrorsJvm.NO_REFLECTION_IN_CLASS_PATH, "Call uses reflection API which is not found in compilation classpath. " +
"Make sure you have kotlin-reflect.jar in the classpath");
@@ -56,6 +56,7 @@ public interface ErrorsJvm {
DiagnosticFactory0<JetExpression> POSITIONED_VALUE_ARGUMENT_FOR_JAVA_ANNOTATION = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<JetElement> DEPRECATED_ANNOTATION_METHOD_CALL = DiagnosticFactory0.create(WARNING);
DiagnosticFactory1<JetAnnotationEntry, FqName> DEPRECATED_JAVA_ANNOTATION = DiagnosticFactory1.create(WARNING);
DiagnosticFactory0<JetAnnotationEntry> NON_SOURCE_REPEATED_ANNOTATION = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<JetElement> TRAIT_CANT_CALL_DEFAULT_METHOD_VIA_SUPER = DiagnosticFactory0.create(ERROR);
@@ -20,6 +20,8 @@ import org.jetbrains.kotlin.cfg.WhenChecker
import org.jetbrains.kotlin.container.StorageComponentContainer
import org.jetbrains.kotlin.container.useImpl
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.KotlinRetention
import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget
import org.jetbrains.kotlin.diagnostics.DiagnosticSink
import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.jvm.RuntimeAssertionsTypeChecker
@@ -43,6 +45,8 @@ import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValue
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory
import org.jetbrains.kotlin.resolve.calls.smartcasts.Nullability
import org.jetbrains.kotlin.resolve.descriptorUtil.getAnnotationRetention
import org.jetbrains.kotlin.resolve.descriptorUtil.isRepeatableAnnotation
import org.jetbrains.kotlin.resolve.jvm.calls.checkers.NeedSyntheticChecker
import org.jetbrains.kotlin.resolve.jvm.calls.checkers.ReflectionAPICallChecker
import org.jetbrains.kotlin.resolve.jvm.calls.checkers.TraitDefaultMethodCallChecker
@@ -75,7 +79,10 @@ public object JvmPlatformConfigurator : PlatformConfigurator(
JavaNullabilityWarningsChecker(),
RuntimeAssertionsTypeChecker
),
additionalSymbolUsageValidators = listOf()
additionalSymbolUsageValidators = listOf(),
additionalAnnotationChecker = RepeatableAnnotationChecker
) {
override fun configure(container: StorageComponentContainer) {
@@ -85,6 +92,21 @@ public object JvmPlatformConfigurator : PlatformConfigurator(
}
}
public object RepeatableAnnotationChecker: AdditionalAnnotationChecker {
override fun checkEntries(entries: List<JetAnnotationEntry>, actualTargets: List<KotlinTarget>, trace: BindingTrace) {
val entryTypes: MutableSet<JetType> = hashSetOf()
for (entry in entries) {
val descriptor = trace.get(BindingContext.ANNOTATION, entry) ?: continue
val classDescriptor = TypeUtils.getClassDescriptor(descriptor.type) ?: continue
if (!entryTypes.add(descriptor.type)
&& classDescriptor.isRepeatableAnnotation()
&& classDescriptor.getAnnotationRetention() != KotlinRetention.SOURCE) {
trace.report(ErrorsJvm.NON_SOURCE_REPEATED_ANNOTATION.on(entry));
}
}
}
}
public class LocalFunInlineChecker : DeclarationChecker {
override fun check(
@@ -27,10 +27,12 @@ import org.jetbrains.kotlin.resolve.constants.EnumValue
import org.jetbrains.kotlin.types.JetType
import org.jetbrains.kotlin.types.TypeUtils
import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget
import org.jetbrains.kotlin.resolve.constants.BooleanValue
import org.jetbrains.kotlin.resolve.descriptorUtil.isRepeatableAnnotation
public object AnnotationChecker {
public var additionalChecker: AdditionalAnnotationChecker? = null
public fun check(annotated: JetAnnotated, trace: BindingTrace, descriptor: ClassDescriptor? = null) {
if (annotated is JetTypeParameter) return // TODO: support type parameter annotations
val actualTargets = getActualTargetList(annotated, descriptor)
@@ -64,24 +66,17 @@ public object AnnotationChecker {
}
}
private fun isRepeatable(classDescriptor: ClassDescriptor): Boolean {
val annotationEntryDescriptor = classDescriptor.annotations.findAnnotation(KotlinBuiltIns.FQ_NAMES.annotation) ?: return false
val repeatableArgumentValue = annotationEntryDescriptor.allValueArguments.entrySet().firstOrNull {
"repeatable" == it.key.name.asString()
}?.getValue() as? BooleanValue ?: return false
return repeatableArgumentValue.value
}
private fun checkEntries(entries: List<JetAnnotationEntry>, actualTargets: List<KotlinTarget>, trace: BindingTrace) {
val entryTypes: MutableSet<JetType> = hashSetOf()
for (entry in entries) {
checkAnnotationEntry(entry, actualTargets, trace)
val descriptor = trace.get(BindingContext.ANNOTATION, entry) ?: continue
val classDescriptor = TypeUtils.getClassDescriptor(descriptor.type) ?: continue
if (!entryTypes.add(descriptor.type) && !isRepeatable(classDescriptor)) {
if (!entryTypes.add(descriptor.type) && !classDescriptor.isRepeatableAnnotation()) {
trace.report(Errors.REPEATED_ANNOTATION.on(entry));
}
}
additionalChecker?.checkEntries(entries, actualTargets, trace)
}
public fun possibleTargetSet(classDescriptor: ClassDescriptor): Set<KotlinTarget>? {
@@ -135,4 +130,8 @@ public object AnnotationChecker {
if (annotated is JetTypeParameter) return listOf(KotlinTarget.TYPE_PARAMETER)
return listOf()
}
}
public interface AdditionalAnnotationChecker {
public fun checkEntries(entries: List<JetAnnotationEntry>, actualTargets: List<KotlinTarget>, trace: BindingTrace)
}
@@ -48,7 +48,8 @@ public open class PlatformConfigurator(
additionalDeclarationCheckers: List<DeclarationChecker>,
additionalCallCheckers: List<CallChecker>,
additionalTypeCheckers: List<AdditionalTypeChecker>,
additionalSymbolUsageValidators: List<SymbolUsageValidator>
additionalSymbolUsageValidators: List<SymbolUsageValidator>,
private val additionalAnnotationChecker: AdditionalAnnotationChecker? = null
) {
private val declarationCheckers: List<DeclarationChecker> = DEFAULT_DECLARATION_CHECKERS + additionalDeclarationCheckers
@@ -64,5 +65,6 @@ public open class PlatformConfigurator(
typeCheckers.forEach { useInstance(it) }
useInstance(symbolUsageValidator)
}
AnnotationChecker.additionalChecker = additionalAnnotationChecker
}
}
@@ -1,5 +1,5 @@
target(AnnotationTarget.EXPRESSION)
annotation(repeatable = true) class Ann(val x: Int = 1)
annotation(repeatable = true, retention = AnnotationRetention.SOURCE) class Ann(val x: Int = 1)
inline fun bar(block: () -> Int): Int = block()
@@ -3,7 +3,7 @@ package
kotlin.inline() internal fun bar(/*0*/ block: () -> kotlin.Int): kotlin.Int
internal fun foo(): kotlin.Unit
kotlin.annotation.target(allowedTargets = {AnnotationTarget.EXPRESSION}) kotlin.annotation.annotation(repeatable = true) internal final class Ann : kotlin.Annotation {
kotlin.annotation.target(allowedTargets = {AnnotationTarget.EXPRESSION}) kotlin.annotation.annotation(repeatable = true, retention = AnnotationRetention.SOURCE) internal final class Ann : kotlin.Annotation {
public constructor Ann(/*0*/ x: kotlin.Int = ...)
internal final val x: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
@@ -2,7 +2,7 @@
target(AnnotationTarget.TYPE, AnnotationTarget.CLASSIFIER,
AnnotationTarget.CONSTRUCTOR, AnnotationTarget.FUNCTION,
AnnotationTarget.EXPRESSION, AnnotationTarget.PROPERTY)
annotation(repeatable = true) class Ann(val x: Int = 6)
annotation(repeatable = true, retention = AnnotationRetention.SOURCE) class Ann(val x: Int = 6)
@Ann(1) @Ann(2) @Ann(3) @private class A @Ann constructor() {
@Ann(x = 5) fun foo() {
@@ -10,7 +10,7 @@ Ann(x = 1) Ann(x = 2) Ann(x = 3) private final class A {
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
kotlin.annotation.target(allowedTargets = {AnnotationTarget.TYPE, AnnotationTarget.CLASSIFIER, AnnotationTarget.CONSTRUCTOR, AnnotationTarget.FUNCTION, AnnotationTarget.EXPRESSION, AnnotationTarget.PROPERTY}) kotlin.annotation.annotation(repeatable = true) internal final class Ann : kotlin.Annotation {
kotlin.annotation.target(allowedTargets = {AnnotationTarget.TYPE, AnnotationTarget.CLASSIFIER, AnnotationTarget.CONSTRUCTOR, AnnotationTarget.FUNCTION, AnnotationTarget.EXPRESSION, AnnotationTarget.PROPERTY}) kotlin.annotation.annotation(repeatable = true, retention = AnnotationRetention.SOURCE) internal final class Ann : kotlin.Annotation {
public constructor Ann(/*0*/ x: kotlin.Int = ...)
internal final val x: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
@@ -4,14 +4,18 @@ annotation(retention = AnnotationRetention.SOURCE, repeatable = true) class repa
annotation(repeatable = true, retention = AnnotationRetention.SOURCE) class repann2(val f: Boolean)
annotation(repeatable = true, retention = AnnotationRetention.BINARY) class binrepann
target(AnnotationTarget.EXPRESSION) annotation(repeatable = true) class repexpr
repann repann class DoubleAnnotated
repann <!NON_SOURCE_REPEATED_ANNOTATION!>repann<!> class DoubleAnnotated
repann1(1) repann1(2) repann1(3) class TripleAnnotated
repann2(true) repann2(false) repann2(false) repann2(true) class FourTimesAnnotated
@repann @repann fun foo(@repann @repann x: Int): Int {
@repexpr @repexpr return x
binrepann <!NON_SOURCE_REPEATED_ANNOTATION!>binrepann<!> class BinaryAnnotated
@repann <!NON_SOURCE_REPEATED_ANNOTATION!>@repann<!> fun foo(@repann <!NON_SOURCE_REPEATED_ANNOTATION!>@repann<!> x: Int): Int {
@repexpr <!NON_SOURCE_REPEATED_ANNOTATION!>@repexpr<!> return x
}
@@ -2,6 +2,13 @@ package
repann() repann() internal fun foo(/*0*/ repann() repann() x: kotlin.Int): kotlin.Int
binrepann() binrepann() internal final class BinaryAnnotated {
public constructor BinaryAnnotated()
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 toString(): kotlin.String
}
repann() repann() internal final class DoubleAnnotated {
public constructor DoubleAnnotated()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
@@ -23,6 +30,13 @@ repann1(x = 1) repann1(x = 2) repann1(x = 3) internal final class TripleAnnotate
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
kotlin.annotation.annotation(repeatable = true, retention = AnnotationRetention.BINARY) internal final class binrepann : kotlin.Annotation {
public constructor binrepann()
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 toString(): kotlin.String
}
kotlin.annotation.annotation(repeatable = true) internal final class repann : kotlin.Annotation {
public constructor repann()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
@@ -1,6 +1,6 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER
target(AnnotationTarget.EXPRESSION)
annotation(repeatable = true) class Ann
annotation(repeatable = true, retention = AnnotationRetention.SOURCE) class Ann
fun <T> bar(block: (T) -> Int) {}
@@ -3,7 +3,7 @@ package
internal fun </*0*/ T> bar(/*0*/ block: (T) -> kotlin.Int): kotlin.Unit
internal fun foo(): kotlin.Unit
kotlin.annotation.target(allowedTargets = {AnnotationTarget.EXPRESSION}) kotlin.annotation.annotation(repeatable = true) internal final class Ann : kotlin.Annotation {
kotlin.annotation.target(allowedTargets = {AnnotationTarget.EXPRESSION}) kotlin.annotation.annotation(repeatable = true, retention = AnnotationRetention.SOURCE) internal final class Ann : kotlin.Annotation {
public constructor Ann()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
@@ -15,5 +15,6 @@ public @interface RepeatableAnnotations {
// FILE: RepeatableUse.kt
RepeatableAnnotation RepeatableAnnotation class My
// Error should be gone when Java 8 Target will be available
RepeatableAnnotation <!NON_SOURCE_REPEATED_ANNOTATION!>RepeatableAnnotation<!> class My
@@ -16,6 +16,7 @@ public @interface RepeatableAnnotations {
// FILE: RepeatableUse.kt
RepeatableAnnotation RepeatableAnnotation class My
// Error should be gone when Java 8 Target will be available
RepeatableAnnotation <!NON_SOURCE_REPEATED_ANNOTATION!>RepeatableAnnotation<!> class My
@@ -1,4 +1,4 @@
annotation(repeatable = true) class Ann(val i: IntArray)
annotation(repeatable = true, retention = AnnotationRetention.SOURCE) class Ann(val i: IntArray)
Ann(intArrayOf(<!ANNOTATION_PARAMETER_MUST_BE_CONST!>i<!>))
Ann(intArrayOf(i2))
@@ -13,7 +13,7 @@ val i3 = foo()
fun foo(): Int = 1
annotation(repeatable = true) class AnnAnn(val i: Array<Ann>)
annotation(repeatable = true, retention = AnnotationRetention.SOURCE) class AnnAnn(val i: Array<Ann>)
AnnAnn(arrayOf(Ann(intArrayOf(1))))
AnnAnn(arrayOf(<!ANNOTATION_PARAMETER_MUST_BE_CONST!>iAnn<!>))
class TestAnn
@@ -6,7 +6,7 @@ internal val i3: kotlin.Int
internal val iAnn: Ann
internal fun foo(): kotlin.Int
kotlin.annotation.annotation(repeatable = true) internal final class Ann : kotlin.Annotation {
kotlin.annotation.annotation(repeatable = true, retention = AnnotationRetention.SOURCE) internal final class Ann : kotlin.Annotation {
public constructor Ann(/*0*/ i: kotlin.IntArray)
internal final val i: kotlin.IntArray
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
@@ -14,7 +14,7 @@ kotlin.annotation.annotation(repeatable = true) internal final class Ann : kotli
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
kotlin.annotation.annotation(repeatable = true) internal final class AnnAnn : kotlin.Annotation {
kotlin.annotation.annotation(repeatable = true, retention = AnnotationRetention.SOURCE) internal final class AnnAnn : kotlin.Annotation {
public constructor AnnAnn(/*0*/ i: kotlin.Array<Ann>)
internal final val i: kotlin.Array<Ann>
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
@@ -1,4 +1,4 @@
annotation(repeatable = true) class Ann(val i: Int)
annotation(repeatable = true, retention = AnnotationRetention.SOURCE) class Ann(val i: Int)
annotation class AnnIA(val ia: IntArray)
annotation class AnnSA(val sa: Array<String>)
@@ -6,7 +6,7 @@ internal val ia: kotlin.IntArray
internal val sa: kotlin.Array<kotlin.String>
internal fun foo(): kotlin.Int
kotlin.annotation.annotation(repeatable = true) internal final class Ann : kotlin.Annotation {
kotlin.annotation.annotation(repeatable = true, retention = AnnotationRetention.SOURCE) internal final class Ann : kotlin.Annotation {
public constructor Ann(/*0*/ i: kotlin.Int)
internal final val i: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
@@ -1,4 +1,4 @@
annotation(repeatable = true) class Ann(vararg val i: Int)
annotation(repeatable = true, retention = AnnotationRetention.SOURCE) class Ann(vararg val i: Int)
Ann(<!ANNOTATION_PARAMETER_MUST_BE_CONST!>i<!>)
Ann(i2)
@@ -16,7 +16,7 @@ val i3 = foo()
fun foo(): Int = 1
annotation(repeatable = true) class AnnAnn(vararg val i: Ann)
annotation(repeatable = true, retention = AnnotationRetention.SOURCE) class AnnAnn(vararg val i: Ann)
AnnAnn(*arrayOf(Ann(1)))
AnnAnn(*arrayOf(<!ANNOTATION_PARAMETER_MUST_BE_CONST!>iAnn<!>))
class TestAnn
@@ -6,7 +6,7 @@ internal val i3: kotlin.Int
internal val iAnn: Ann
internal fun foo(): kotlin.Int
kotlin.annotation.annotation(repeatable = true) internal final class Ann : kotlin.Annotation {
kotlin.annotation.annotation(repeatable = true, retention = AnnotationRetention.SOURCE) internal final class Ann : kotlin.Annotation {
public constructor Ann(/*0*/ vararg i: kotlin.Int /*kotlin.IntArray*/)
internal final val i: kotlin.IntArray
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
@@ -14,7 +14,7 @@ kotlin.annotation.annotation(repeatable = true) internal final class Ann : kotli
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
kotlin.annotation.annotation(repeatable = true) internal final class AnnAnn : kotlin.Annotation {
kotlin.annotation.annotation(repeatable = true, retention = AnnotationRetention.SOURCE) internal final class AnnAnn : kotlin.Annotation {
public constructor AnnAnn(/*0*/ vararg i: Ann /*kotlin.Array<out Ann>*/)
internal final val i: kotlin.Array<out Ann>
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
@@ -21,10 +21,14 @@ import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.ClassKind.ENUM_CLASS
import org.jetbrains.kotlin.descriptors.ClassKind.ENUM_ENTRY
import org.jetbrains.kotlin.descriptors.ClassKind.OBJECT
import org.jetbrains.kotlin.descriptors.annotations.Annotated
import org.jetbrains.kotlin.descriptors.annotations.KotlinRetention
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.FqNameUnsafe
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.constants.BooleanValue
import org.jetbrains.kotlin.resolve.constants.EnumValue
import org.jetbrains.kotlin.types.JetType
public fun ClassDescriptor.getClassObjectReferenceTarget(): ClassDescriptor = getCompanionObjectDescriptor() ?: this
@@ -140,3 +144,19 @@ public fun CallableDescriptor.getOwnerForEffectiveDispatchReceiverParameter(): D
}
return getDispatchReceiverParameter()?.getContainingDeclaration()
}
public fun Annotated.isRepeatableAnnotation(): Boolean {
val annotationEntryDescriptor = annotations.findAnnotation(KotlinBuiltIns.FQ_NAMES.annotation) ?: return false
val repeatableArgumentValue = annotationEntryDescriptor.allValueArguments.entrySet().firstOrNull {
"repeatable" == it.key.name.asString()
}?.getValue() as? BooleanValue ?: return false // not repeatable by default
return repeatableArgumentValue.value
}
public fun Annotated.getAnnotationRetention(): KotlinRetention? {
val annotationEntryDescriptor = annotations.findAnnotation(KotlinBuiltIns.FQ_NAMES.annotation) ?: return null
val retentionArgumentValue = annotationEntryDescriptor.allValueArguments.entrySet().firstOrNull {
"retention" == it.key.name.asString()
}?.getValue() as? EnumValue ?: return null
return KotlinRetention.valueOf(retentionArgumentValue.value.name.asString())
}
+1 -1
View File
@@ -20,4 +20,4 @@ val BAZ = "baz"
val N = 0
target(AnnotationTarget.FILE)
annotation(repeatable = true) class myAnnotation(val i: Int, val s: String)
annotation(repeatable = true, retention = AnnotationRetention.SOURCE) class myAnnotation(val i: Int, val s: String)
@@ -32,6 +32,6 @@ annotation class a
target(AnnotationTarget.PROPERTY, AnnotationTarget.FUNCTION, AnnotationTarget.CLASSIFIER,
AnnotationTarget.CONSTRUCTOR, AnnotationTarget.TYPE)
annotation(repeatable = true) class b(val e: E)
annotation(repeatable = true, retention = AnnotationRetention.SOURCE) class b(val e: E)
enum class E { E1 E2 }
@@ -44,19 +44,9 @@ PsiJetFileStubImpl[package=]
CLASS_BODY:
OBJECT_DECLARATION:[fqName=Annotations.Companion, isCompanion=true, isLocal=false, isObjectLiteral=false, isTopLevel=false, name=Companion, superNames=[]]
MODIFIER_LIST:[private companion]
ANNOTATION_ENTRY:[hasValueArguments=false, shortName=b]
CONSTRUCTOR_CALLEE:
TYPE_REFERENCE:
USER_TYPE:[isAbsoluteInRootPackage=false]
REFERENCE_EXPRESSION:[referencedName=b]
CLASS_BODY:
PROPERTY:[fqName=Annotations.c, hasDelegate=false, hasDelegateExpression=false, hasInitializer=false, hasReturnTypeRef=true, isExtension=false, isTopLevel=false, isVar=false, name=c]
MODIFIER_LIST:[private final]
ANNOTATION_ENTRY:[hasValueArguments=false, shortName=b]
CONSTRUCTOR_CALLEE:
TYPE_REFERENCE:
USER_TYPE:[isAbsoluteInRootPackage=false]
REFERENCE_EXPRESSION:[referencedName=b]
TYPE_REFERENCE:
USER_TYPE:[isAbsoluteInRootPackage=false]
USER_TYPE:[isAbsoluteInRootPackage=false]
@@ -133,11 +123,6 @@ PsiJetFileStubImpl[package=]
TYPE_REFERENCE:
USER_TYPE:[isAbsoluteInRootPackage=false]
REFERENCE_EXPRESSION:[referencedName=a]
ANNOTATION_ENTRY:[hasValueArguments=false, shortName=b]
CONSTRUCTOR_CALLEE:
TYPE_REFERENCE:
USER_TYPE:[isAbsoluteInRootPackage=false]
REFERENCE_EXPRESSION:[referencedName=b]
VALUE_PARAMETER_LIST:
VALUE_PARAMETER:[fqName=null, hasDefaultValue=false, hasValOrVar=false, isMutable=false, name=p1]
MODIFIER_LIST:[]
@@ -200,15 +185,5 @@ PsiJetFileStubImpl[package=]
TYPE_REFERENCE:
USER_TYPE:[isAbsoluteInRootPackage=false]
REFERENCE_EXPRESSION:[referencedName=a]
ANNOTATION_ENTRY:[hasValueArguments=false, shortName=b]
CONSTRUCTOR_CALLEE:
TYPE_REFERENCE:
USER_TYPE:[isAbsoluteInRootPackage=false]
REFERENCE_EXPRESSION:[referencedName=b]
ANNOTATION_ENTRY:[hasValueArguments=false, shortName=b]
CONSTRUCTOR_CALLEE:
TYPE_REFERENCE:
USER_TYPE:[isAbsoluteInRootPackage=false]
REFERENCE_EXPRESSION:[referencedName=b]
VALUE_PARAMETER_LIST:
CLASS_BODY: