annotation --> Retention / Repeatable / MustBeDocumented: converting from Java to Kotlin and back.
At this very short moment Kotlin supports both annotation(retention, repeatable, mustBeDocumented) and Retention / Repeatable / MustBeDocumented separately.
This commit is contained in:
@@ -6,7 +6,7 @@ public open class DocumentedAnnotations {
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
|
||||
java.lang.annotation.Documented() kotlin.annotation.annotation(mustBeDocumented = true) public final class DocAnn : kotlin.Annotation {
|
||||
kotlin.annotation.MustBeDocumented() public final class DocAnn : kotlin.Annotation {
|
||||
public constructor DocAnn()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
@@ -20,7 +20,7 @@ public open class DocumentedAnnotations {
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
java.lang.annotation.Documented() kotlin.annotation.annotation(mustBeDocumented = true, retention = AnnotationRetention.RUNTIME) public final class RunDocAnn : kotlin.Annotation {
|
||||
kotlin.annotation.MustBeDocumented() kotlin.annotation.Retention(value = AnnotationRetention.RUNTIME) public final class RunDocAnn : kotlin.Annotation {
|
||||
public constructor RunDocAnn()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
|
||||
@@ -13,21 +13,21 @@ public open class AnnotationRetentions {
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
kotlin.annotation.annotation(retention = AnnotationRetention.BINARY) public final class BinaryAnnotation : kotlin.Annotation {
|
||||
kotlin.annotation.Retention(value = AnnotationRetention.BINARY) public final class BinaryAnnotation : kotlin.Annotation {
|
||||
public constructor BinaryAnnotation()
|
||||
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(retention = AnnotationRetention.RUNTIME) public final class RuntimeAnnotation : kotlin.Annotation {
|
||||
kotlin.annotation.Retention(value = AnnotationRetention.RUNTIME) public final class RuntimeAnnotation : kotlin.Annotation {
|
||||
public constructor RuntimeAnnotation()
|
||||
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(retention = AnnotationRetention.SOURCE) public final class SourceAnnotation : kotlin.Annotation {
|
||||
kotlin.annotation.Retention(value = AnnotationRetention.SOURCE) public final class SourceAnnotation : kotlin.Annotation {
|
||||
public constructor SourceAnnotation()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@ RepeatableAnnotation() RepeatableAnnotation() internal final class My {
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
java.lang.annotation.Repeatable(value = RepeatableAnnotations::class) kotlin.annotation.annotation(repeatable = true) public final class RepeatableAnnotation : kotlin.Annotation {
|
||||
kotlin.annotation.Repeatable() public final class RepeatableAnnotation : kotlin.Annotation {
|
||||
public constructor RepeatableAnnotation()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@ RepeatableAnnotation() RepeatableAnnotation() internal final class My {
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
java.lang.annotation.Repeatable(value = RepeatableAnnotations::class) kotlin.annotation.annotation(repeatable = true, retention = AnnotationRetention.RUNTIME) public final class RepeatableAnnotation : kotlin.Annotation {
|
||||
kotlin.annotation.Repeatable() kotlin.annotation.Retention(value = AnnotationRetention.RUNTIME) public final class RepeatableAnnotation : kotlin.Annotation {
|
||||
public constructor RepeatableAnnotation()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
|
||||
+3
-3
@@ -11,7 +11,7 @@ public open class AnnotationRetentions {
|
||||
public/*package*/ constructor BaseClass()
|
||||
}
|
||||
|
||||
kotlin.annotation.annotation(retention = AnnotationRetention.BINARY) public final class BinaryAnnotation : kotlin.Annotation {
|
||||
kotlin.annotation.Retention(value = AnnotationRetention.BINARY) public final class BinaryAnnotation : kotlin.Annotation {
|
||||
public constructor BinaryAnnotation()
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ public open class AnnotationRetentions {
|
||||
public/*package*/ constructor BinaryClass()
|
||||
}
|
||||
|
||||
kotlin.annotation.annotation(retention = AnnotationRetention.RUNTIME) public final class RuntimeAnnotation : kotlin.Annotation {
|
||||
kotlin.annotation.Retention(value = AnnotationRetention.RUNTIME) public final class RuntimeAnnotation : kotlin.Annotation {
|
||||
public constructor RuntimeAnnotation()
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ public open class AnnotationRetentions {
|
||||
public/*package*/ constructor RuntimeClass()
|
||||
}
|
||||
|
||||
kotlin.annotation.annotation(retention = AnnotationRetention.SOURCE) public final class SourceAnnotation : kotlin.Annotation {
|
||||
kotlin.annotation.Retention(value = AnnotationRetention.SOURCE) public final class SourceAnnotation : kotlin.Annotation {
|
||||
public constructor SourceAnnotation()
|
||||
}
|
||||
|
||||
|
||||
+36
-56
@@ -38,17 +38,20 @@ import java.util.EnumSet
|
||||
|
||||
public object JavaAnnotationMapper {
|
||||
|
||||
private val JAVA_TARGET_FQ_NAME = FqName(javaClass<Target>().canonicalName)
|
||||
private val JAVA_RETENTION_FQ_NAME = FqName(javaClass<Retention>().canonicalName)
|
||||
private val JAVA_DEPRECATED_FQ_NAME = FqName(javaClass<Deprecated>().canonicalName)
|
||||
private val JAVA_DOCUMENTED_FQ_NAME = FqName(javaClass<Documented>().canonicalName)
|
||||
private val JAVA_TARGET_FQ_NAME = FqName(Target::class.java.canonicalName)
|
||||
private val JAVA_RETENTION_FQ_NAME = FqName(Retention::class.java.canonicalName)
|
||||
private val JAVA_DEPRECATED_FQ_NAME = FqName(Deprecated::class.java.canonicalName)
|
||||
private val JAVA_DOCUMENTED_FQ_NAME = FqName(Documented::class.java.canonicalName)
|
||||
// Java8-specific thing
|
||||
private val JAVA_REPEATABLE_FQ_NAME = FqName("java.lang.annotation.Repeatable")
|
||||
|
||||
public fun mapOrResolveJavaAnnotation(annotation: JavaAnnotation, c: LazyJavaResolverContext): AnnotationDescriptor? =
|
||||
when (annotation.classId) {
|
||||
ClassId.topLevel(JAVA_TARGET_FQ_NAME) -> JavaTargetAnnotationDescriptor(annotation, c)
|
||||
ClassId.topLevel(JAVA_RETENTION_FQ_NAME), ClassId.topLevel(JAVA_DEPRECATED_FQ_NAME) -> null
|
||||
ClassId.topLevel(JAVA_RETENTION_FQ_NAME) -> JavaRetentionAnnotationDescriptor(annotation, c)
|
||||
ClassId.topLevel(JAVA_REPEATABLE_FQ_NAME) -> JavaAnnotationDescriptor(c, annotation, c.module.builtIns.repeatableAnnotation)
|
||||
ClassId.topLevel(JAVA_DOCUMENTED_FQ_NAME) -> JavaAnnotationDescriptor(c, annotation, c.module.builtIns.mustBeDocumentedAnnotation)
|
||||
ClassId.topLevel(JAVA_DEPRECATED_FQ_NAME) -> null
|
||||
else -> c.resolveAnnotation(annotation)
|
||||
}
|
||||
|
||||
@@ -56,19 +59,6 @@ public object JavaAnnotationMapper {
|
||||
annotationOwner: JavaAnnotationOwner,
|
||||
c: LazyJavaResolverContext
|
||||
): AnnotationDescriptor? {
|
||||
if (kotlinName == KotlinBuiltIns.FQ_NAMES.annotation) {
|
||||
// Construct kotlin.annotation.annotation from Retention & Repeatable
|
||||
val retentionAnnotation = annotationOwner.findAnnotation(JAVA_RETENTION_FQ_NAME)
|
||||
val repeatableAnnotation = annotationOwner.findAnnotation(JAVA_REPEATABLE_FQ_NAME)
|
||||
val documentedAnnotation = annotationOwner.findAnnotation(JAVA_DOCUMENTED_FQ_NAME)
|
||||
return if (retentionAnnotation != null || repeatableAnnotation != null || documentedAnnotation != null) {
|
||||
JavaRetentionRepeatableAnnotationDescriptor(retentionAnnotation, repeatableAnnotation != null,
|
||||
documentedAnnotation != null, c)
|
||||
}
|
||||
else {
|
||||
null
|
||||
}
|
||||
}
|
||||
if (kotlinName == KotlinBuiltIns.FQ_NAMES.deprecated) {
|
||||
val javaAnnotation = annotationOwner.findAnnotation(JAVA_DEPRECATED_FQ_NAME)
|
||||
if (javaAnnotation != null || annotationOwner.isDeprecatedInJavaDoc) {
|
||||
@@ -84,17 +74,20 @@ public object JavaAnnotationMapper {
|
||||
|
||||
// kotlin.annotation.annotation is treated separately
|
||||
private val kotlinToJavaNameMap: Map<FqName, FqName> =
|
||||
mapOf(KotlinBuiltIns.FQ_NAMES.target to JAVA_TARGET_FQ_NAME)
|
||||
mapOf(KotlinBuiltIns.FQ_NAMES.target to JAVA_TARGET_FQ_NAME,
|
||||
KotlinBuiltIns.FQ_NAMES.retention to JAVA_RETENTION_FQ_NAME,
|
||||
KotlinBuiltIns.FQ_NAMES.repeatable to JAVA_REPEATABLE_FQ_NAME,
|
||||
KotlinBuiltIns.FQ_NAMES.mustBeDocumented to JAVA_DOCUMENTED_FQ_NAME)
|
||||
|
||||
public val javaToKotlinNameMap: Map<FqName, FqName> =
|
||||
mapOf(JAVA_TARGET_FQ_NAME to KotlinBuiltIns.FQ_NAMES.target,
|
||||
JAVA_RETENTION_FQ_NAME to KotlinBuiltIns.FQ_NAMES.annotation,
|
||||
JAVA_RETENTION_FQ_NAME to KotlinBuiltIns.FQ_NAMES.retention,
|
||||
JAVA_DEPRECATED_FQ_NAME to KotlinBuiltIns.FQ_NAMES.deprecated,
|
||||
JAVA_REPEATABLE_FQ_NAME to KotlinBuiltIns.FQ_NAMES.annotation,
|
||||
JAVA_DOCUMENTED_FQ_NAME to KotlinBuiltIns.FQ_NAMES.annotation)
|
||||
JAVA_REPEATABLE_FQ_NAME to KotlinBuiltIns.FQ_NAMES.repeatable,
|
||||
JAVA_DOCUMENTED_FQ_NAME to KotlinBuiltIns.FQ_NAMES.mustBeDocumented)
|
||||
}
|
||||
|
||||
abstract class AbstractJavaAnnotationDescriptor(
|
||||
open class JavaAnnotationDescriptor(
|
||||
c: LazyJavaResolverContext,
|
||||
annotation: JavaAnnotation?,
|
||||
private val kotlinAnnotationClassDescriptor: ClassDescriptor
|
||||
@@ -109,12 +102,14 @@ abstract class AbstractJavaAnnotationDescriptor(
|
||||
get() = kotlinAnnotationClassDescriptor.constructors.single().valueParameters
|
||||
|
||||
protected val firstArgument: JavaAnnotationArgument? = annotation?.arguments?.firstOrNull()
|
||||
|
||||
override fun getAllValueArguments() = emptyMap<ValueParameterDescriptor, ConstantValue<*>?>()
|
||||
}
|
||||
|
||||
class JavaDeprecatedAnnotationDescriptor(
|
||||
annotation: JavaAnnotation?,
|
||||
c: LazyJavaResolverContext
|
||||
): AbstractJavaAnnotationDescriptor(c, annotation, c.module.builtIns.deprecatedAnnotation) {
|
||||
): JavaAnnotationDescriptor(c, annotation, c.module.builtIns.deprecatedAnnotation) {
|
||||
|
||||
private val valueArguments = c.storageManager.createLazyValue {
|
||||
val parameterDescriptor = valueParameters.firstOrNull {
|
||||
@@ -126,41 +121,10 @@ class JavaDeprecatedAnnotationDescriptor(
|
||||
override fun getAllValueArguments() = valueArguments()
|
||||
}
|
||||
|
||||
class JavaRetentionRepeatableAnnotationDescriptor(
|
||||
retentionAnnotation: JavaAnnotation?,
|
||||
repeatable: Boolean,
|
||||
documented: Boolean,
|
||||
c: LazyJavaResolverContext
|
||||
): AbstractJavaAnnotationDescriptor(c, retentionAnnotation, c.module.builtIns.annotationAnnotation) {
|
||||
|
||||
private val valueArguments = c.storageManager.createLazyValue {
|
||||
val retentionArgument = when (firstArgument) {
|
||||
is JavaEnumValueAnnotationArgument -> JavaAnnotationTargetMapper.mapJavaRetentionArgument(firstArgument, c.module.builtIns)
|
||||
else -> null
|
||||
}
|
||||
val retentionParameterDescriptor = valueParameters.first {
|
||||
it.name == JvmAnnotationNames.RETENTION_ANNOTATION_PARAMETER_NAME
|
||||
}
|
||||
val repeatableArgument = if (repeatable) BooleanValue(true, c.module.builtIns) else null
|
||||
val repeatableParameterDescriptor = valueParameters.first {
|
||||
it.name == JvmAnnotationNames.REPEATABLE_ANNOTATION_PARAMETER_NAME
|
||||
}
|
||||
val documentedArgument = if (documented) BooleanValue(true, c.module.builtIns) else null
|
||||
val documentedParameterDescriptor = valueParameters.first {
|
||||
it.name == JvmAnnotationNames.DOCUMENTED_ANNOTATION_PARAMETER_NAME
|
||||
}
|
||||
(retentionArgument?.let { mapOf(retentionParameterDescriptor to it) } ?: emptyMap()) +
|
||||
(repeatableArgument?.let { mapOf(repeatableParameterDescriptor to it) } ?: emptyMap()) +
|
||||
(documentedArgument?.let { mapOf(documentedParameterDescriptor to it) } ?: emptyMap())
|
||||
}
|
||||
|
||||
override fun getAllValueArguments() = valueArguments()
|
||||
}
|
||||
|
||||
class JavaTargetAnnotationDescriptor(
|
||||
annotation: JavaAnnotation,
|
||||
c: LazyJavaResolverContext
|
||||
): AbstractJavaAnnotationDescriptor(c, annotation, c.module.builtIns.targetAnnotation) {
|
||||
): JavaAnnotationDescriptor(c, annotation, c.module.builtIns.targetAnnotation) {
|
||||
|
||||
private val valueArguments = c.storageManager.createLazyValue {
|
||||
val targetArgument = when (firstArgument) {
|
||||
@@ -174,6 +138,22 @@ class JavaTargetAnnotationDescriptor(
|
||||
override fun getAllValueArguments() = valueArguments()
|
||||
}
|
||||
|
||||
class JavaRetentionAnnotationDescriptor(
|
||||
annotation: JavaAnnotation,
|
||||
c: LazyJavaResolverContext
|
||||
): JavaAnnotationDescriptor(c, annotation, c.module.builtIns.retentionAnnotation) {
|
||||
|
||||
private val valueArguments = c.storageManager.createLazyValue {
|
||||
val retentionArgument = when (firstArgument) {
|
||||
is JavaEnumValueAnnotationArgument -> JavaAnnotationTargetMapper.mapJavaRetentionArgument(firstArgument, c.module.builtIns)
|
||||
else -> return@createLazyValue emptyMap<ValueParameterDescriptor, ConstantValue<*>>()
|
||||
}
|
||||
mapOf(valueParameters.single() to retentionArgument)
|
||||
}
|
||||
|
||||
override fun getAllValueArguments() = valueArguments()
|
||||
}
|
||||
|
||||
public object JavaAnnotationTargetMapper {
|
||||
private val targetNameLists = mapOf("PACKAGE" to EnumSet.noneOf(KotlinTarget::class.java),
|
||||
"TYPE" to EnumSet.of(KotlinTarget.CLASSIFIER, KotlinTarget.FILE),
|
||||
|
||||
@@ -181,14 +181,22 @@ private fun Annotated.isAnnotationPropertyTrue(name: String, defaultValue: Boole
|
||||
return repeatableArgumentValue.value
|
||||
}
|
||||
|
||||
public fun Annotated.isRepeatableAnnotation(): Boolean = isAnnotationPropertyTrue("repeatable")
|
||||
public fun Annotated.isRepeatableAnnotation(): Boolean =
|
||||
annotations.findAnnotation(KotlinBuiltIns.FQ_NAMES.repeatable) != null
|
||||
// deprecated
|
||||
|| isAnnotationPropertyTrue("repeatable")
|
||||
|
||||
public fun Annotated.isDocumentedAnnotation(): Boolean = isAnnotationPropertyTrue("mustBeDocumented")
|
||||
public fun Annotated.isDocumentedAnnotation(): Boolean =
|
||||
annotations.findAnnotation(KotlinBuiltIns.FQ_NAMES.mustBeDocumented) != null
|
||||
// deprecated
|
||||
|| isAnnotationPropertyTrue("mustBeDocumented")
|
||||
|
||||
public fun Annotated.getAnnotationRetention(): KotlinRetention? {
|
||||
val annotationEntryDescriptor = annotations.findAnnotation(KotlinBuiltIns.FQ_NAMES.annotation) ?: return null
|
||||
val annotationEntryDescriptor = annotations.findAnnotation(KotlinBuiltIns.FQ_NAMES.retention) ?:
|
||||
// deprecated
|
||||
annotations.findAnnotation(KotlinBuiltIns.FQ_NAMES.annotation) ?: return null
|
||||
val retentionArgumentValue = annotationEntryDescriptor.allValueArguments.entrySet().firstOrNull {
|
||||
"retention" == it.key.name.asString()
|
||||
it.key.name.asString() in setOf("value", "retention")
|
||||
}?.getValue() as? EnumValue ?: return null
|
||||
return KotlinRetention.valueOf(retentionArgumentValue.value.name.asString())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user