Binary or runtime repeatable annotations are not allowed for JVM. Some tests fixed accordingly.
This commit is contained in:
@@ -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) {
|
||||
|
||||
+1
@@ -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);
|
||||
|
||||
|
||||
+23
-1
@@ -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
-1
@@ -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()
|
||||
|
||||
|
||||
+1
-1
@@ -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
-1
@@ -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) {}
|
||||
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
|
||||
+2
-1
@@ -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
|
||||
|
||||
|
||||
|
||||
compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameterMustBeConstant/array.kt
Vendored
+2
-2
@@ -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
|
||||
|
||||
+2
-2
@@ -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
-1
@@ -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>)
|
||||
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
+2
-2
@@ -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
|
||||
|
||||
+2
-2
@@ -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
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user