Generate type annotations on class type parameters bounds
#KT-13228 #KT-46539 Fixed
This commit is contained in:
committed by
TeamCityServer
parent
f574f89f78
commit
cd7841ceed
+12
@@ -429,6 +429,18 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
|||||||
runTest("compiler/testData/codegen/box/annotations/typeAnnotations/checkingNotincorporatedInputTypes.kt");
|
runTest("compiler/testData/codegen/box/annotations/typeAnnotations/checkingNotincorporatedInputTypes.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("classTypeParameterBound.kt")
|
||||||
|
public void testClassTypeParameterBound() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/annotations/typeAnnotations/classTypeParameterBound.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("classTypeParameterBoundsJava.kt")
|
||||||
|
public void testClassTypeParameterBoundsJava() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/annotations/typeAnnotations/classTypeParameterBoundsJava.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("functionTypeParameterBound.kt")
|
@TestMetadata("functionTypeParameterBound.kt")
|
||||||
public void testFunctionTypeParameterBound() throws Exception {
|
public void testFunctionTypeParameterBound() throws Exception {
|
||||||
|
|||||||
+14
-3
@@ -153,10 +153,21 @@ class ClassCodegen private constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
object : AnnotationCodegen(this@ClassCodegen, context) {
|
object : AnnotationCodegen(this@ClassCodegen, context) {
|
||||||
override fun visitAnnotation(descr: String?, visible: Boolean): AnnotationVisitor {
|
override fun visitAnnotation(descr: String, visible: Boolean): AnnotationVisitor {
|
||||||
return visitor.visitor.visitAnnotation(descr, visible)
|
return visitor.visitor.visitAnnotation(descr, visible)
|
||||||
}
|
}
|
||||||
}.genAnnotations(irClass, null, null)
|
}.genAnnotations(irClass, null, null)
|
||||||
|
|
||||||
|
AnnotationCodegen.genAnnotationsOnTypeParametersAndBounds(
|
||||||
|
context,
|
||||||
|
irClass,
|
||||||
|
this,
|
||||||
|
TypeReference.CLASS_TYPE_PARAMETER,
|
||||||
|
TypeReference.CLASS_TYPE_PARAMETER_BOUND
|
||||||
|
) { typeRef: Int, typePath: TypePath?, descriptor: String, visible: Boolean ->
|
||||||
|
visitor.visitor.visitTypeAnnotation(typeRef, typePath, descriptor, visible)
|
||||||
|
}
|
||||||
|
|
||||||
generateKotlinMetadataAnnotation()
|
generateKotlinMetadataAnnotation()
|
||||||
|
|
||||||
generateInnerAndOuterClasses()
|
generateInnerAndOuterClasses()
|
||||||
@@ -306,11 +317,11 @@ class ClassCodegen private constructor(
|
|||||||
flags and (Opcodes.ACC_SYNTHETIC or Opcodes.ACC_ENUM) != 0 ||
|
flags and (Opcodes.ACC_SYNTHETIC or Opcodes.ACC_ENUM) != 0 ||
|
||||||
field.origin == JvmLoweredDeclarationOrigin.FIELD_FOR_STATIC_CALLABLE_REFERENCE_INSTANCE
|
field.origin == JvmLoweredDeclarationOrigin.FIELD_FOR_STATIC_CALLABLE_REFERENCE_INSTANCE
|
||||||
object : AnnotationCodegen(this@ClassCodegen, context, skipNullabilityAnnotations) {
|
object : AnnotationCodegen(this@ClassCodegen, context, skipNullabilityAnnotations) {
|
||||||
override fun visitAnnotation(descr: String?, visible: Boolean): AnnotationVisitor {
|
override fun visitAnnotation(descr: String, visible: Boolean): AnnotationVisitor {
|
||||||
return fv.visitAnnotation(descr, visible)
|
return fv.visitAnnotation(descr, visible)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitTypeAnnotation(descr: String?, path: TypePath?, visible: Boolean): AnnotationVisitor {
|
override fun visitTypeAnnotation(descr: String, path: TypePath?, visible: Boolean): AnnotationVisitor {
|
||||||
return fv.visitTypeAnnotation(TypeReference.newTypeReference(TypeReference.FIELD).value, path, descr, visible)
|
return fv.visitTypeAnnotation(TypeReference.newTypeReference(TypeReference.FIELD).value, path, descr, visible)
|
||||||
}
|
}
|
||||||
}.genAnnotations(field, fieldType, field.type)
|
}.genAnnotations(field, fieldType, field.type)
|
||||||
|
|||||||
@@ -0,0 +1,79 @@
|
|||||||
|
// IGNORE_BACKEND: JVM
|
||||||
|
// KOTLIN_CONFIGURATION_FLAGS: +JVM.EMIT_JVM_TYPE_ANNOTATIONS
|
||||||
|
// RENDER_ANNOTATIONS
|
||||||
|
// TARGET_BACKEND: JVM
|
||||||
|
// JVM_TARGET: 1.8
|
||||||
|
package foo
|
||||||
|
|
||||||
|
@Target(AnnotationTarget.TYPE)
|
||||||
|
annotation class TypeAnn(val name: String)
|
||||||
|
|
||||||
|
@Target( AnnotationTarget.TYPE_PARAMETER)
|
||||||
|
annotation class TypeParameterAnn(val name: String)
|
||||||
|
|
||||||
|
@Target(AnnotationTarget.TYPE_PARAMETER)
|
||||||
|
@Retention(AnnotationRetention.BINARY)
|
||||||
|
annotation class TypeParameterAnnBinary
|
||||||
|
|
||||||
|
@Target(AnnotationTarget.TYPE_PARAMETER)
|
||||||
|
@Retention(AnnotationRetention.SOURCE)
|
||||||
|
annotation class TypeParameterAnnSource
|
||||||
|
|
||||||
|
interface SimpleInterface
|
||||||
|
interface SimpleInterface2
|
||||||
|
open class SimpleClass
|
||||||
|
|
||||||
|
interface GenericInterface<Z>
|
||||||
|
open class GenericClass<Z>
|
||||||
|
|
||||||
|
@Suppress("UNSUPPORTED")
|
||||||
|
class Simple<@TypeParameterAnn("T") @TypeParameterAnnBinary @TypeParameterAnnSource T> {
|
||||||
|
fun test(p: T) : T {
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class TypeBound<Y, T: @foo.TypeAnn("Y") Y> {
|
||||||
|
fun test(p: T) : T {
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class InterfaceBound<T: @foo.TypeAnn("Interface") SimpleInterface> {
|
||||||
|
fun test(p: T) : T {
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ClassBound<T: @foo.TypeAnn("Class") SimpleClass> {
|
||||||
|
fun test(p: T) : T {
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ClassBoundGeneric<T: @foo.TypeAnn("Class") GenericClass<@foo.TypeAnn("SimpleClass") SimpleClass>> {
|
||||||
|
fun test(p: T) : T {
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class InterfaceBoundGeneric<T: @foo.TypeAnn("Interface") GenericInterface<@foo.TypeAnn("SimpleInterface") SimpleInterface>> {
|
||||||
|
fun test(p: T) : T {
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class ClassInterfaceBound<T: @foo.TypeAnn("Class") SimpleClass> where T : @foo.TypeAnn("Interface") SimpleInterface, T : @foo.TypeAnn("Interface2") SimpleInterface2 {
|
||||||
|
fun test(p: T) : T {
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class InterfaceClassBound<T: @foo.TypeAnn("Interface") SimpleInterface > where T : @foo.TypeAnn("Class") SimpleClass, T : @foo.TypeAnn("Interface2") SimpleInterface2 {
|
||||||
|
fun test(p: T) : T {
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,133 @@
|
|||||||
|
<T:Lfoo/SimpleClass;>Ljava/lang/Object;
|
||||||
|
public final class foo/ClassBound : java/lang/Object {
|
||||||
|
@Lfoo/TypeAnn;([name="Class"]) : CLASS_TYPE_PARAMETER_BOUND 0, 0, null
|
||||||
|
|
||||||
|
public void <init>()
|
||||||
|
|
||||||
|
(TT;)TT;
|
||||||
|
public final foo.SimpleClass test(foo.SimpleClass p)
|
||||||
|
@Lorg/jetbrains/annotations/NotNull;([]) // invisible
|
||||||
|
@Lorg/jetbrains/annotations/NotNull;([]) // invisible, parameter 0
|
||||||
|
}
|
||||||
|
|
||||||
|
<T:Lfoo/GenericClass<Lfoo/SimpleClass;>;>Ljava/lang/Object;
|
||||||
|
public final class foo/ClassBoundGeneric : java/lang/Object {
|
||||||
|
@Lfoo/TypeAnn;([name="Class"]) : CLASS_TYPE_PARAMETER_BOUND 0, 0, null
|
||||||
|
@Lfoo/TypeAnn;([name="SimpleClass"]) : CLASS_TYPE_PARAMETER_BOUND 0, 0, 0;
|
||||||
|
|
||||||
|
public void <init>()
|
||||||
|
|
||||||
|
(TT;)TT;
|
||||||
|
public final foo.GenericClass test(foo.GenericClass p)
|
||||||
|
@Lorg/jetbrains/annotations/NotNull;([]) // invisible
|
||||||
|
@Lorg/jetbrains/annotations/NotNull;([]) // invisible, parameter 0
|
||||||
|
}
|
||||||
|
|
||||||
|
<T:Lfoo/SimpleClass;:Lfoo/SimpleInterface;:Lfoo/SimpleInterface2;>Ljava/lang/Object;
|
||||||
|
public final class foo/ClassInterfaceBound : java/lang/Object {
|
||||||
|
@Lfoo/TypeAnn;([name="Class"]) : CLASS_TYPE_PARAMETER_BOUND 0, 0, null
|
||||||
|
@Lfoo/TypeAnn;([name="Interface"]) : CLASS_TYPE_PARAMETER_BOUND 0, 1, null
|
||||||
|
@Lfoo/TypeAnn;([name="Interface2"]) : CLASS_TYPE_PARAMETER_BOUND 0, 2, null
|
||||||
|
|
||||||
|
public void <init>()
|
||||||
|
|
||||||
|
(TT;)TT;
|
||||||
|
public final foo.SimpleClass test(foo.SimpleClass p)
|
||||||
|
@Lorg/jetbrains/annotations/NotNull;([]) // invisible
|
||||||
|
@Lorg/jetbrains/annotations/NotNull;([]) // invisible, parameter 0
|
||||||
|
}
|
||||||
|
|
||||||
|
<Z:Ljava/lang/Object;>Ljava/lang/Object;
|
||||||
|
public class foo/GenericClass : java/lang/Object {
|
||||||
|
public void <init>()
|
||||||
|
}
|
||||||
|
|
||||||
|
<Z:Ljava/lang/Object;>Ljava/lang/Object;
|
||||||
|
public abstract interface foo/GenericInterface : java/lang/Object {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
<T::Lfoo/SimpleInterface;>Ljava/lang/Object;
|
||||||
|
public final class foo/InterfaceBound : java/lang/Object {
|
||||||
|
@Lfoo/TypeAnn;([name="Interface"]) : CLASS_TYPE_PARAMETER_BOUND 0, 1, null
|
||||||
|
|
||||||
|
public void <init>()
|
||||||
|
|
||||||
|
(TT;)TT;
|
||||||
|
public final foo.SimpleInterface test(foo.SimpleInterface p)
|
||||||
|
@Lorg/jetbrains/annotations/NotNull;([]) // invisible
|
||||||
|
@Lorg/jetbrains/annotations/NotNull;([]) // invisible, parameter 0
|
||||||
|
}
|
||||||
|
|
||||||
|
<T::Lfoo/GenericInterface<Lfoo/SimpleInterface;>;>Ljava/lang/Object;
|
||||||
|
public final class foo/InterfaceBoundGeneric : java/lang/Object {
|
||||||
|
@Lfoo/TypeAnn;([name="Interface"]) : CLASS_TYPE_PARAMETER_BOUND 0, 1, null
|
||||||
|
@Lfoo/TypeAnn;([name="SimpleInterface"]) : CLASS_TYPE_PARAMETER_BOUND 0, 1, 0;
|
||||||
|
|
||||||
|
public void <init>()
|
||||||
|
|
||||||
|
(TT;)TT;
|
||||||
|
public final foo.GenericInterface test(foo.GenericInterface p)
|
||||||
|
@Lorg/jetbrains/annotations/NotNull;([]) // invisible
|
||||||
|
@Lorg/jetbrains/annotations/NotNull;([]) // invisible, parameter 0
|
||||||
|
}
|
||||||
|
|
||||||
|
<T:Lfoo/SimpleClass;:Lfoo/SimpleInterface;:Lfoo/SimpleInterface2;>Ljava/lang/Object;
|
||||||
|
public final class foo/InterfaceClassBound : java/lang/Object {
|
||||||
|
@Lfoo/TypeAnn;([name="Interface"]) : CLASS_TYPE_PARAMETER_BOUND 0, 1, null
|
||||||
|
@Lfoo/TypeAnn;([name="Class"]) : CLASS_TYPE_PARAMETER_BOUND 0, 0, null
|
||||||
|
@Lfoo/TypeAnn;([name="Interface2"]) : CLASS_TYPE_PARAMETER_BOUND 0, 2, null
|
||||||
|
|
||||||
|
public void <init>()
|
||||||
|
|
||||||
|
(TT;)TT;
|
||||||
|
public final foo.SimpleClass test(foo.SimpleClass p)
|
||||||
|
@Lorg/jetbrains/annotations/NotNull;([]) // invisible
|
||||||
|
@Lorg/jetbrains/annotations/NotNull;([]) // invisible, parameter 0
|
||||||
|
}
|
||||||
|
|
||||||
|
<T:Ljava/lang/Object;>Ljava/lang/Object;
|
||||||
|
public final class foo/Simple : java/lang/Object {
|
||||||
|
public void <init>()
|
||||||
|
|
||||||
|
(TT;)TT;
|
||||||
|
public final java.lang.Object test(java.lang.Object p)
|
||||||
|
}
|
||||||
|
|
||||||
|
public class foo/SimpleClass : java/lang/Object {
|
||||||
|
public void <init>()
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract interface foo/SimpleInterface : java/lang/Object {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract interface foo/SimpleInterface2 : java/lang/Object {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract interface foo/TypeAnn : java/lang/Object, java/lang/annotation/Annotation {
|
||||||
|
public abstract java.lang.String name()
|
||||||
|
}
|
||||||
|
|
||||||
|
<Y:Ljava/lang/Object;T::TY;>Ljava/lang/Object;
|
||||||
|
public final class foo/TypeBound : java/lang/Object {
|
||||||
|
@Lfoo/TypeAnn;([name="Y"]) : CLASS_TYPE_PARAMETER_BOUND 1, 0, null
|
||||||
|
|
||||||
|
public void <init>()
|
||||||
|
|
||||||
|
(TT;)TT;
|
||||||
|
public final java.lang.Object test(java.lang.Object p)
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract interface foo/TypeParameterAnn : java/lang/Object, java/lang/annotation/Annotation {
|
||||||
|
public abstract java.lang.String name()
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract interface foo/TypeParameterAnnBinary : java/lang/Object, java/lang/annotation/Annotation {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract interface foo/TypeParameterAnnSource : java/lang/Object, java/lang/annotation/Annotation {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -56,3 +56,5 @@ class Kotlin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class WithBound<T: Bar<Outer.Inner<@Ann Outer>>>()
|
||||||
@@ -74,3 +74,8 @@ public final class foo/Outer$Inner : java/lang/Object {
|
|||||||
public final class foo/Outer : java/lang/Object {
|
public final class foo/Outer : java/lang/Object {
|
||||||
public void <init>()
|
public void <init>()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
<T:Lfoo/Bar<Lfoo/Outer$Inner<Lfoo/Outer;>;>;>Ljava/lang/Object;
|
||||||
|
public final class foo/WithBound : java/lang/Object {
|
||||||
|
public void <init>()
|
||||||
|
}
|
||||||
+43
@@ -0,0 +1,43 @@
|
|||||||
|
// IGNORE_BACKEND_FIR: JVM_IR
|
||||||
|
// TARGET_BACKEND: JVM
|
||||||
|
// EMIT_JVM_TYPE_ANNOTATIONS
|
||||||
|
// JVM_TARGET: 1.8
|
||||||
|
// WITH_REFLECT
|
||||||
|
// FULL_JDK
|
||||||
|
package foo
|
||||||
|
|
||||||
|
import kotlin.reflect.KClass
|
||||||
|
import kotlin.reflect.full.functions
|
||||||
|
|
||||||
|
@Target(AnnotationTarget.TYPE)
|
||||||
|
annotation class TypeAnn(val name: String)
|
||||||
|
|
||||||
|
interface SimpleInterface
|
||||||
|
open class SimpleClass
|
||||||
|
|
||||||
|
class InterfaceClassBound<T>() where T : @TypeAnn("Interface") SimpleInterface, T : @TypeAnn("Class") SimpleClass {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class ClassInterfaceBound<T>() where T : @TypeAnn("Class") SimpleClass, T : @TypeAnn("Interface") SimpleInterface {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box() : String {
|
||||||
|
val interfaceBounds = InterfaceClassBound::class.typeParameters.single()
|
||||||
|
if (interfaceBounds.upperBounds[0].annotations.joinToString() != "@foo.TypeAnn(name=Interface)") return "fail 1: ${interfaceBounds.upperBounds[0].annotations.joinToString()}"
|
||||||
|
if ((interfaceBounds.upperBounds[0].classifier as KClass<*>).simpleName != "SimpleInterface") return "fail 1.1: ${interfaceBounds.upperBounds[0].classifier}"
|
||||||
|
|
||||||
|
if (interfaceBounds.upperBounds[1].annotations.joinToString() != "@foo.TypeAnn(name=Class)") return "fail 2: ${interfaceBounds.upperBounds[1].annotations.joinToString()}"
|
||||||
|
if ((interfaceBounds.upperBounds[1].classifier as KClass<*>).simpleName != "SimpleClass") return "fail 2.1: ${interfaceBounds.upperBounds[1].classifier}"
|
||||||
|
|
||||||
|
val classBounds = ClassInterfaceBound::class.typeParameters.single()
|
||||||
|
if (classBounds.upperBounds[0].annotations.joinToString() != "@foo.TypeAnn(name=Class)") return "fail 3: ${classBounds.upperBounds[0].annotations.joinToString()}"
|
||||||
|
if ((classBounds.upperBounds[0].classifier as KClass<*>).simpleName != "SimpleClass") return "fail 3.1: ${classBounds.upperBounds[0].classifier}"
|
||||||
|
|
||||||
|
if (classBounds.upperBounds[1].annotations.joinToString() != "@foo.TypeAnn(name=Interface)") return "fail 4: ${classBounds.upperBounds[1].annotations.joinToString()}"
|
||||||
|
if ((classBounds.upperBounds[1].classifier as KClass<*>).simpleName != "SimpleInterface") return "fail 4.1: ${classBounds.upperBounds[1].classifier}"
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
|
|
||||||
+173
@@ -0,0 +1,173 @@
|
|||||||
|
// IGNORE_BACKEND: JVM
|
||||||
|
// IGNORE_LIGHT_ANALYSIS
|
||||||
|
// IGNORE_BACKEND_FIR: JVM_IR
|
||||||
|
// TARGET_BACKEND: JVM
|
||||||
|
// EMIT_JVM_TYPE_ANNOTATIONS
|
||||||
|
// JVM_TARGET: 1.8
|
||||||
|
// WITH_REFLECT
|
||||||
|
// FULL_JDK
|
||||||
|
package foo
|
||||||
|
|
||||||
|
import java.lang.reflect.AnnotatedType
|
||||||
|
import java.lang.reflect.TypeVariable
|
||||||
|
import java.lang.reflect.AnnotatedParameterizedType
|
||||||
|
import kotlin.reflect.jvm.javaMethod
|
||||||
|
import kotlin.test.fail
|
||||||
|
|
||||||
|
@Target(AnnotationTarget.TYPE)
|
||||||
|
annotation class TypeAnn(val name: String)
|
||||||
|
|
||||||
|
@Target(AnnotationTarget.TYPE_PARAMETER)
|
||||||
|
annotation class TypeParameterAnn
|
||||||
|
|
||||||
|
@Target(AnnotationTarget.TYPE_PARAMETER)
|
||||||
|
@Retention(AnnotationRetention.BINARY)
|
||||||
|
annotation class TypeParameterAnnBinary
|
||||||
|
|
||||||
|
interface Simple
|
||||||
|
class SimpleClass
|
||||||
|
interface Generic<G>
|
||||||
|
class GenericClass<G>
|
||||||
|
|
||||||
|
@Suppress("UNSUPPORTED")
|
||||||
|
class SimpleParameter<@TypeParameterAnn @TypeParameterAnnBinary T> {}
|
||||||
|
|
||||||
|
@Suppress("UNSUPPORTED")
|
||||||
|
class InterfaceBound<@TypeParameterAnn T : @TypeAnn("Simple") Simple> {}
|
||||||
|
|
||||||
|
@Suppress("UNSUPPORTED")
|
||||||
|
class ClassBound<@TypeParameterAnn T : @TypeAnn("Simple") SimpleClass>
|
||||||
|
|
||||||
|
class InterfaceBoundGeneric<T : @TypeAnn("Generic") Generic<@TypeAnn("Simple") Simple>> {}
|
||||||
|
|
||||||
|
class ClassBoundGeneric<T : @TypeAnn("GenericClass") GenericClass<@TypeAnn("SimpleClass") SimpleClass>>
|
||||||
|
|
||||||
|
@Suppress("UNSUPPORTED")
|
||||||
|
class TypeParameterAsBound<Y, @TypeParameterAnn T : @TypeAnn("Y as Bound") Y>
|
||||||
|
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
|
||||||
|
//foo
|
||||||
|
// checkTypeParameterAnnotation(
|
||||||
|
// SimpleParameter::class.java.typeParameters.single(),
|
||||||
|
// "T",
|
||||||
|
// "@foo.TypeParameterAnn()",
|
||||||
|
// "foo"
|
||||||
|
// )
|
||||||
|
|
||||||
|
//interfaceBound
|
||||||
|
val interfaceBound = InterfaceBound::class.java
|
||||||
|
// checkTypeParameterAnnotation(
|
||||||
|
// InterfaceBound.typeParameters.single(),
|
||||||
|
// "T",
|
||||||
|
// "@foo.TypeParameterAnn()",
|
||||||
|
// "interfaceBound type parameter"
|
||||||
|
// )
|
||||||
|
|
||||||
|
checkTypeAnnotation(
|
||||||
|
interfaceBound.typeParameters.single().annotatedBounds.single(),
|
||||||
|
"interface foo.Simple",
|
||||||
|
"@foo.TypeAnn(name=Simple)",
|
||||||
|
"interfaceBound bound"
|
||||||
|
)
|
||||||
|
|
||||||
|
//classBound
|
||||||
|
val classBound = ClassBound::class.java
|
||||||
|
// checkTypeParameterAnnotation(
|
||||||
|
// classBound.typeParameters.single(),
|
||||||
|
// "T",
|
||||||
|
// "@foo.TypeParameterAnn()",
|
||||||
|
// "classBound type parameter"
|
||||||
|
// )
|
||||||
|
|
||||||
|
checkTypeAnnotation(
|
||||||
|
classBound.typeParameters.single().annotatedBounds.single(),
|
||||||
|
"class foo.SimpleClass",
|
||||||
|
"@foo.TypeAnn(name=Simple)",
|
||||||
|
"classBound bound"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
//interfaceBoundGeneric
|
||||||
|
val interfaceBoundGeneric = InterfaceBoundGeneric::class.java
|
||||||
|
// checkTypeAnnotation(
|
||||||
|
// interfaceBoundGeneric.typeParameters.single().annotatedBounds.single(),
|
||||||
|
// "foo.Generic<foo.Simple>",
|
||||||
|
// "@foo.TypeAnn(name=Generic)",
|
||||||
|
// "interfaceBoundGeneric bound"
|
||||||
|
// )
|
||||||
|
|
||||||
|
checkTypeAnnotation(
|
||||||
|
(interfaceBoundGeneric.typeParameters.single().annotatedBounds.single() as AnnotatedParameterizedType).getAnnotatedActualTypeArguments().single(),
|
||||||
|
"interface foo.Simple",
|
||||||
|
"@foo.TypeAnn(name=Simple)",
|
||||||
|
"interfaceBoundGeneric bound parameter"
|
||||||
|
)
|
||||||
|
|
||||||
|
//classBoundGeneric
|
||||||
|
val classBoundGeneric = ClassBoundGeneric::class.java
|
||||||
|
// Works on JDK 15
|
||||||
|
// checkTypeAnnotation(
|
||||||
|
// classBoundGeneric.typeParameters.single().annotatedBounds.single(),
|
||||||
|
// "foo.GenericClass<foo.SimpleClass>",
|
||||||
|
// "@foo.TypeAnn(name=GenericClass)",
|
||||||
|
// "classBoundGeneric bound"
|
||||||
|
// )
|
||||||
|
|
||||||
|
checkTypeAnnotation(
|
||||||
|
(classBoundGeneric.typeParameters.single().annotatedBounds.single() as AnnotatedParameterizedType).getAnnotatedActualTypeArguments().single(),
|
||||||
|
"class foo.SimpleClass",
|
||||||
|
"@foo.TypeAnn(name=SimpleClass)",
|
||||||
|
"classBoundGeneric bound parameter"
|
||||||
|
)
|
||||||
|
|
||||||
|
//typeParameterTypeParameterBound
|
||||||
|
val typeParameterTypeParameterBound = TypeParameterAsBound::class.java
|
||||||
|
// checkTypeParameterAnnotation(
|
||||||
|
// typeParameterTypeParameterBound.typeParameters[1]!!,
|
||||||
|
// "T",
|
||||||
|
// "@foo.TypeParameterAnn()",
|
||||||
|
// "typeParameterTypeParameterBound type parameter"
|
||||||
|
// )
|
||||||
|
// Works on JDK 15
|
||||||
|
// checkTypeAnnotation(
|
||||||
|
// typeParameterTypeParameterBound.typeParameters[1]!!.annotatedBounds.single(),
|
||||||
|
// "Y",
|
||||||
|
// "@foo.TypeAnn(name=Y as Bound)",
|
||||||
|
// "typeParameterTypeParameterBound bound"
|
||||||
|
// )
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
|
|
||||||
|
fun checkTypeParameterAnnotation(
|
||||||
|
typeParameter: TypeVariable<*>,
|
||||||
|
type: String,
|
||||||
|
annotations: String,
|
||||||
|
message: String
|
||||||
|
) {
|
||||||
|
if (typeParameter.annotation() != annotations) fail("check $message (1): ${typeParameter.annotation()} != $annotations")
|
||||||
|
|
||||||
|
if (typeParameter.toString() != type) fail("check $message (2): ${typeParameter.toString()} != $type")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun checkTypeAnnotation(
|
||||||
|
annotatedType: AnnotatedType,
|
||||||
|
type: String,
|
||||||
|
annotations: String,
|
||||||
|
message: String
|
||||||
|
) {
|
||||||
|
if (annotatedType.annotation() != annotations &&
|
||||||
|
//JDK11+
|
||||||
|
annotatedType . annotation () != annotations.replace("=", "=\"").replace(")", "\")")
|
||||||
|
) fail("check $message (1): ${annotatedType.annotation()} != $annotations")
|
||||||
|
|
||||||
|
if (annotatedType.type.toString() != type) fail("check $message (2): ${annotatedType.type} != $type")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun AnnotatedType.annotation() = annotations.joinToString()
|
||||||
|
|
||||||
|
fun TypeVariable<*>.annotation() = annotations.joinToString()
|
||||||
+12
@@ -429,6 +429,18 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
runTest("compiler/testData/codegen/box/annotations/typeAnnotations/checkingNotincorporatedInputTypes.kt");
|
runTest("compiler/testData/codegen/box/annotations/typeAnnotations/checkingNotincorporatedInputTypes.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("classTypeParameterBound.kt")
|
||||||
|
public void testClassTypeParameterBound() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/annotations/typeAnnotations/classTypeParameterBound.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("classTypeParameterBoundsJava.kt")
|
||||||
|
public void testClassTypeParameterBoundsJava() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/annotations/typeAnnotations/classTypeParameterBoundsJava.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("functionTypeParameterBound.kt")
|
@TestMetadata("functionTypeParameterBound.kt")
|
||||||
public void testFunctionTypeParameterBound() throws Exception {
|
public void testFunctionTypeParameterBound() throws Exception {
|
||||||
|
|||||||
+12
@@ -429,6 +429,18 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
runTest("compiler/testData/codegen/box/annotations/typeAnnotations/checkingNotincorporatedInputTypes.kt");
|
runTest("compiler/testData/codegen/box/annotations/typeAnnotations/checkingNotincorporatedInputTypes.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("classTypeParameterBound.kt")
|
||||||
|
public void testClassTypeParameterBound() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/annotations/typeAnnotations/classTypeParameterBound.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("classTypeParameterBoundsJava.kt")
|
||||||
|
public void testClassTypeParameterBoundsJava() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/annotations/typeAnnotations/classTypeParameterBoundsJava.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("functionTypeParameterBound.kt")
|
@TestMetadata("functionTypeParameterBound.kt")
|
||||||
public void testFunctionTypeParameterBound() throws Exception {
|
public void testFunctionTypeParameterBound() throws Exception {
|
||||||
|
|||||||
Generated
+5
@@ -115,6 +115,11 @@ public class AsmLikeInstructionListingTestGenerated extends AbstractAsmLikeInstr
|
|||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/asmLike/typeAnnotations"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true);
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/asmLike/typeAnnotations"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("classTypeParameter.kt")
|
||||||
|
public void testClassTypeParameter() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/asmLike/typeAnnotations/classTypeParameter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("complex.kt")
|
@TestMetadata("complex.kt")
|
||||||
public void testComplex() throws Exception {
|
public void testComplex() throws Exception {
|
||||||
runTest("compiler/testData/codegen/asmLike/typeAnnotations/complex.kt");
|
runTest("compiler/testData/codegen/asmLike/typeAnnotations/complex.kt");
|
||||||
|
|||||||
+10
@@ -372,6 +372,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
|||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
public static class TypeAnnotations extends AbstractLightAnalysisModeTest {
|
public static class TypeAnnotations extends AbstractLightAnalysisModeTest {
|
||||||
|
@TestMetadata("classTypeParameterBoundsJava.kt")
|
||||||
|
public void ignoreClassTypeParameterBoundsJava() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/annotations/typeAnnotations/classTypeParameterBoundsJava.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("methodTypeParameters.kt")
|
@TestMetadata("methodTypeParameters.kt")
|
||||||
public void ignoreMethodTypeParameters() throws Exception {
|
public void ignoreMethodTypeParameters() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/annotations/typeAnnotations/methodTypeParameters.kt");
|
runTest("compiler/testData/codegen/box/annotations/typeAnnotations/methodTypeParameters.kt");
|
||||||
@@ -390,6 +395,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
|||||||
runTest("compiler/testData/codegen/box/annotations/typeAnnotations/checkingNotincorporatedInputTypes.kt");
|
runTest("compiler/testData/codegen/box/annotations/typeAnnotations/checkingNotincorporatedInputTypes.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("classTypeParameterBound.kt")
|
||||||
|
public void testClassTypeParameterBound() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/annotations/typeAnnotations/classTypeParameterBound.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("functionTypeParameterBound.kt")
|
@TestMetadata("functionTypeParameterBound.kt")
|
||||||
public void testFunctionTypeParameterBound() throws Exception {
|
public void testFunctionTypeParameterBound() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/annotations/typeAnnotations/functionTypeParameterBound.kt");
|
runTest("compiler/testData/codegen/box/annotations/typeAnnotations/functionTypeParameterBound.kt");
|
||||||
|
|||||||
Generated
+5
@@ -115,6 +115,11 @@ public class IrAsmLikeInstructionListingTestGenerated extends AbstractIrAsmLikeI
|
|||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/asmLike/typeAnnotations"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/asmLike/typeAnnotations"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("classTypeParameter.kt")
|
||||||
|
public void testClassTypeParameter() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/asmLike/typeAnnotations/classTypeParameter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("complex.kt")
|
@TestMetadata("complex.kt")
|
||||||
public void testComplex() throws Exception {
|
public void testComplex() throws Exception {
|
||||||
runTest("compiler/testData/codegen/asmLike/typeAnnotations/complex.kt");
|
runTest("compiler/testData/codegen/asmLike/typeAnnotations/complex.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user