From c811c1bea53aacb96d015cd0c13ba40d8d9aed4b Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Tue, 12 Jul 2016 19:54:30 +0300 Subject: [PATCH] Reflection: add KAnnotatedElement.findAnnotation #KT-12250 Fixed --- .../reflection/annotations/findAnnotation.kt | 15 +++++++++++ .../reflection/annotations/findAnnotation.txt | 19 ++++++++++++++ .../ir/IrBlackBoxCodegenTestGenerated.java | 6 +++++ .../codegen/BlackBoxCodegenTestGenerated.java | 6 +++++ ...LightAnalysisModeCodegenTestGenerated.java | 6 +++++ .../src/kotlin/reflect/KAnnotatedElements.kt | 25 +++++++++++++++++++ .../semantics/JsCodegenBoxTestGenerated.java | 12 +++++++++ 7 files changed, 89 insertions(+) create mode 100644 compiler/testData/codegen/box/reflection/annotations/findAnnotation.kt create mode 100644 compiler/testData/codegen/light-analysis/reflection/annotations/findAnnotation.txt create mode 100644 core/reflection.jvm/src/kotlin/reflect/KAnnotatedElements.kt diff --git a/compiler/testData/codegen/box/reflection/annotations/findAnnotation.kt b/compiler/testData/codegen/box/reflection/annotations/findAnnotation.kt new file mode 100644 index 00000000000..3e3824e2f42 --- /dev/null +++ b/compiler/testData/codegen/box/reflection/annotations/findAnnotation.kt @@ -0,0 +1,15 @@ +// IGNORE_BACKEND: JS +// WITH_REFLECT + +import kotlin.reflect.findAnnotation + +annotation class Yes(val value: String) +annotation class No(val value: String) + +@Yes("OK") +@No("Fail") +class Foo + +fun box(): String { + return Foo::class.findAnnotation()?.value ?: "Fail: no annotation" +} diff --git a/compiler/testData/codegen/light-analysis/reflection/annotations/findAnnotation.txt b/compiler/testData/codegen/light-analysis/reflection/annotations/findAnnotation.txt new file mode 100644 index 00000000000..c6a11310ec9 --- /dev/null +++ b/compiler/testData/codegen/light-analysis/reflection/annotations/findAnnotation.txt @@ -0,0 +1,19 @@ +public final class FindAnnotationKt { + public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String +} + +@Yes +@No +public final class Foo { + public method (): void +} + +@java.lang.annotation.Retention +public annotation class No { + public abstract method value(): java.lang.String +} + +@java.lang.annotation.Retention +public annotation class Yes { + public abstract method value(): java.lang.String +} diff --git a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index 5ab59dae010..f7de3f8137d 100644 --- a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -12199,6 +12199,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes doTest(fileName); } + @TestMetadata("findAnnotation.kt") + public void testFindAnnotation() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/annotations/findAnnotation.kt"); + doTest(fileName); + } + @TestMetadata("propertyAccessors.kt") public void testPropertyAccessors() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/annotations/propertyAccessors.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index 825f9fbd1e7..7841ca3ee44 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -12199,6 +12199,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest(fileName); } + @TestMetadata("findAnnotation.kt") + public void testFindAnnotation() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/annotations/findAnnotation.kt"); + doTest(fileName); + } + @TestMetadata("propertyAccessors.kt") public void testPropertyAccessors() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/annotations/propertyAccessors.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeCodegenTestGenerated.java index d0956cb56d4..55aa7677260 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeCodegenTestGenerated.java @@ -12199,6 +12199,12 @@ public class LightAnalysisModeCodegenTestGenerated extends AbstractLightAnalysis doTest(fileName); } + @TestMetadata("findAnnotation.kt") + public void testFindAnnotation() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/annotations/findAnnotation.kt"); + doTest(fileName); + } + @TestMetadata("propertyAccessors.kt") public void testPropertyAccessors() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/annotations/propertyAccessors.kt"); diff --git a/core/reflection.jvm/src/kotlin/reflect/KAnnotatedElements.kt b/core/reflection.jvm/src/kotlin/reflect/KAnnotatedElements.kt new file mode 100644 index 00000000000..3c486def3e8 --- /dev/null +++ b/core/reflection.jvm/src/kotlin/reflect/KAnnotatedElements.kt @@ -0,0 +1,25 @@ +/* + * Copyright 2010-2016 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@file:JvmName("KAnnotatedElements") +package kotlin.reflect + +/** + * Returns an annotation of the given type on this element. + */ +@Suppress("UNCHECKED_CAST") +inline fun KAnnotatedElement.findAnnotation(): T? = + annotations.first { it is T } as T diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index c0a95d9470d..316380cc34d 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -14894,6 +14894,18 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that."); } + @TestMetadata("findAnnotation.kt") + public void testFindAnnotation() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/annotations/findAnnotation.kt"); + try { + doTest(fileName); + } + catch (Throwable ignore) { + return; + } + throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that."); + } + @TestMetadata("propertyAccessors.kt") public void testPropertyAccessors() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/annotations/propertyAccessors.kt");