diff --git a/compiler/testData/codegen/boxWithJava/reflection/annotationsOnJavaMembers/J.java b/compiler/testData/codegen/boxWithJava/reflection/annotationsOnJavaMembers/J.java new file mode 100644 index 00000000000..6bf42851cf0 --- /dev/null +++ b/compiler/testData/codegen/boxWithJava/reflection/annotationsOnJavaMembers/J.java @@ -0,0 +1,11 @@ +@Anno("J") +public class J { + @Anno("foo") + public static int foo = 42; + + @Anno("bar") + public static void bar() {} + + @Anno("constructor") + public J() {} +} diff --git a/compiler/testData/codegen/boxWithJava/reflection/annotationsOnJavaMembers/K.kt b/compiler/testData/codegen/boxWithJava/reflection/annotationsOnJavaMembers/K.kt new file mode 100644 index 00000000000..adfaa64d385 --- /dev/null +++ b/compiler/testData/codegen/boxWithJava/reflection/annotationsOnJavaMembers/K.kt @@ -0,0 +1,12 @@ +import kotlin.test.assertEquals + +annotation class Anno(val value: String) + +fun box(): String { + assertEquals("[@Anno(value=J)]", J::class.annotations.toString()) + assertEquals("[@Anno(value=foo)]", J::foo.annotations.toString()) + assertEquals("[@Anno(value=bar)]", J::bar.annotations.toString()) + assertEquals("[@Anno(value=constructor)]", ::J.annotations.toString()) + + return "OK" +} diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithJavaCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithJavaCodegenTestGenerated.java index e7294c5d240..8d582b48383 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithJavaCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithJavaCodegenTestGenerated.java @@ -581,6 +581,12 @@ public class BlackBoxWithJavaCodegenTestGenerated extends AbstractBlackBoxCodege KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxWithJava/reflection"), Pattern.compile("^([^\\.]+)$"), true); } + @TestMetadata("annotationsOnJavaMembers") + public void testAnnotationsOnJavaMembers() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxWithJava/reflection/annotationsOnJavaMembers/"); + doTestWithJava(fileName); + } + @TestMetadata("callInstanceJavaMethod") public void testCallInstanceJavaMethod() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxWithJava/reflection/callInstanceJavaMethod/"); diff --git a/core/descriptors.runtime/src/org/jetbrains/kotlin/load/java/components/RuntimeSourceElementFactory.kt b/core/descriptors.runtime/src/org/jetbrains/kotlin/load/java/components/RuntimeSourceElementFactory.kt index 4cd53b907db..422691f57dd 100644 --- a/core/descriptors.runtime/src/org/jetbrains/kotlin/load/java/components/RuntimeSourceElementFactory.kt +++ b/core/descriptors.runtime/src/org/jetbrains/kotlin/load/java/components/RuntimeSourceElementFactory.kt @@ -23,7 +23,7 @@ import org.jetbrains.kotlin.load.java.structure.JavaElement import org.jetbrains.kotlin.load.java.structure.reflect.ReflectJavaElement object RuntimeSourceElementFactory : JavaSourceElementFactory { - private class RuntimeSourceElement(override val javaElement: ReflectJavaElement) : JavaSourceElement { + class RuntimeSourceElement(override val javaElement: ReflectJavaElement) : JavaSourceElement { override fun toString() = javaClass.name + ": " + javaElement.toString() override fun getContainingFile(): SourceFile = SourceFile.NO_SOURCE_FILE } diff --git a/core/descriptors.runtime/src/org/jetbrains/kotlin/load/java/structure/reflect/ReflectJavaAnnotation.kt b/core/descriptors.runtime/src/org/jetbrains/kotlin/load/java/structure/reflect/ReflectJavaAnnotation.kt index 1da90612ada..0fe1e61380d 100644 --- a/core/descriptors.runtime/src/org/jetbrains/kotlin/load/java/structure/reflect/ReflectJavaAnnotation.kt +++ b/core/descriptors.runtime/src/org/jetbrains/kotlin/load/java/structure/reflect/ReflectJavaAnnotation.kt @@ -21,7 +21,7 @@ import org.jetbrains.kotlin.load.java.structure.JavaAnnotationArgument import org.jetbrains.kotlin.name.Name import java.lang.reflect.Method -class ReflectJavaAnnotation(private val annotation: Annotation) : ReflectJavaElement(), JavaAnnotation { +class ReflectJavaAnnotation(val annotation: Annotation) : ReflectJavaElement(), JavaAnnotation { override fun findArgument(name: Name): JavaAnnotationArgument? { return getArgumentValue(annotation.annotationClass.java.getDeclaredMethod(name.asString())) } diff --git a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KAnnotatedElementImpl.kt b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KAnnotatedElementImpl.kt index 9bc0b850407..e40e3521b9e 100644 --- a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KAnnotatedElementImpl.kt +++ b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KAnnotatedElementImpl.kt @@ -17,6 +17,8 @@ package kotlin.reflect.jvm.internal import org.jetbrains.kotlin.descriptors.annotations.Annotated +import org.jetbrains.kotlin.load.java.components.RuntimeSourceElementFactory +import org.jetbrains.kotlin.load.java.structure.reflect.ReflectJavaAnnotation import org.jetbrains.kotlin.load.kotlin.reflect.ReflectAnnotationSource import kotlin.reflect.KAnnotatedElement @@ -24,7 +26,16 @@ internal interface KAnnotatedElementImpl : KAnnotatedElement { val annotated: Annotated override val annotations: List - get() = annotated.annotations.map { - (it.source as? ReflectAnnotationSource)?.annotation - }.filterNotNull() + get() = annotated.annotations.mapNotNull { + val source = it.source + when (source) { + is ReflectAnnotationSource -> { + source.annotation + } + is RuntimeSourceElementFactory.RuntimeSourceElement -> { + (source.javaElement as? ReflectJavaAnnotation)?.annotation + } + else -> null + } + } }