diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/AnnotationCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/AnnotationCodegen.java index 87e31991b7a..5a244099fbe 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/AnnotationCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/AnnotationCodegen.java @@ -228,6 +228,8 @@ public abstract class AnnotationCodegen { annotationTargetMap.put(KotlinTarget.PROPERTY_SETTER, ElementType.METHOD); annotationTargetMap.put(KotlinTarget.FIELD, ElementType.FIELD); annotationTargetMap.put(KotlinTarget.VALUE_PARAMETER, ElementType.PARAMETER); + annotationTargetMap.put(KotlinTarget.TYPE_PARAMETER, ElementType.TYPE_PARAMETER); + annotationTargetMap.put(KotlinTarget.TYPE, ElementType.TYPE_USE); } private void generateTargetAnnotation(@NotNull ClassDescriptor classDescriptor, @NotNull Set annotationDescriptorsAlreadyPresent) { diff --git a/compiler/testData/asJava/lightClasses/SpecialAnnotationsOnAnnotationClass.java b/compiler/testData/asJava/lightClasses/SpecialAnnotationsOnAnnotationClass.java index 1b1dfbc0541..f37c2845b95 100644 --- a/compiler/testData/asJava/lightClasses/SpecialAnnotationsOnAnnotationClass.java +++ b/compiler/testData/asJava/lightClasses/SpecialAnnotationsOnAnnotationClass.java @@ -4,7 +4,7 @@ @kotlin.annotation.Repeatable @java.lang.annotation.Documented @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) -@java.lang.annotation.Target({}) +@java.lang.annotation.Target({java.lang.annotation.ElementType.TYPE_PARAMETER}) public @interface Anno { int i(); } diff --git a/compiler/testData/codegen/java8/box/annotations/useTypeParameterAnnotationFromJava.kt b/compiler/testData/codegen/java8/box/annotations/useTypeParameterAnnotationFromJava.kt new file mode 100644 index 00000000000..7c08b4b7176 --- /dev/null +++ b/compiler/testData/codegen/java8/box/annotations/useTypeParameterAnnotationFromJava.kt @@ -0,0 +1,21 @@ +// TARGET_BACKEND: JVM +// WITH_RUNTIME +// FULL_JDK +// FILE: A.java +import java.util.List; + +public class A<@Anno(1) T> {} + +// FILE: Anno.kt + +import kotlin.test.assertEquals + +@Target(AnnotationTarget.TYPE_PARAMETER) +annotation class Anno(val value: Int = 0) + +fun box(): String { + val typeParameter = A::class.java.typeParameters.single() + assertEquals("[@Anno(value=1)]", typeParameter.annotations.toList().toString()) + + return "OK" +} diff --git a/compiler/testData/codegen/java8/box/annotations/useTypeUseAnnotationFromJava.kt b/compiler/testData/codegen/java8/box/annotations/useTypeUseAnnotationFromJava.kt new file mode 100644 index 00000000000..ba88f4e328e --- /dev/null +++ b/compiler/testData/codegen/java8/box/annotations/useTypeUseAnnotationFromJava.kt @@ -0,0 +1,29 @@ +// TARGET_BACKEND: JVM +// WITH_RUNTIME +// FULL_JDK +// FILE: A.java +import java.util.List; + +public class A { + public static @Anno(1) String test(List<@Anno(2) String> list) { + return list.get(0); + } +} + +// FILE: Anno.kt + +import java.lang.reflect.AnnotatedParameterizedType +import kotlin.test.assertEquals + +@Target(AnnotationTarget.TYPE) +annotation class Anno(val value: Int = 0) + +fun box(): String { + val method = A::class.java.declaredMethods.single() + assertEquals("[@Anno(value=1)]", method.annotatedReturnType.annotations.toList().toString()) + + val parameterType = method.parameters.single().annotatedType as AnnotatedParameterizedType + assertEquals("[@Anno(value=2)]", parameterType.annotatedActualTypeArguments.single().annotations.toList().toString()) + + return "OK" +} diff --git a/compiler/tests-java8/tests/org/jetbrains/kotlin/codegen/BlackBoxWithJava8CodegenTestGenerated.java b/compiler/tests-java8/tests/org/jetbrains/kotlin/codegen/BlackBoxWithJava8CodegenTestGenerated.java index b53066c4283..0b2c22f54b8 100644 --- a/compiler/tests-java8/tests/org/jetbrains/kotlin/codegen/BlackBoxWithJava8CodegenTestGenerated.java +++ b/compiler/tests-java8/tests/org/jetbrains/kotlin/codegen/BlackBoxWithJava8CodegenTestGenerated.java @@ -133,6 +133,29 @@ public class BlackBoxWithJava8CodegenTestGenerated extends AbstractBlackBoxCodeg runTest("compiler/testData/codegen/java8/box/useStream.kt"); } + @TestMetadata("compiler/testData/codegen/java8/box/annotations") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Annotations extends AbstractBlackBoxCodegenTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath); + } + + public void testAllFilesPresentInAnnotations() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/java8/box/annotations"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true); + } + + @TestMetadata("useTypeParameterAnnotationFromJava.kt") + public void testUseTypeParameterAnnotationFromJava() throws Exception { + runTest("compiler/testData/codegen/java8/box/annotations/useTypeParameterAnnotationFromJava.kt"); + } + + @TestMetadata("useTypeUseAnnotationFromJava.kt") + public void testUseTypeUseAnnotationFromJava() throws Exception { + runTest("compiler/testData/codegen/java8/box/annotations/useTypeUseAnnotationFromJava.kt"); + } + } + @TestMetadata("compiler/testData/codegen/java8/box/builtinStubMethods") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class)