Introduce KAnnotatedElement and val annotations: List<Annotation>
This commit is contained in:
Vendored
+15
@@ -0,0 +1,15 @@
|
|||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
annotation(retention = AnnotationRetention.RUNTIME) class Anno
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val a = Anno::class.annotations
|
||||||
|
/*
|
||||||
|
// TODO: support kotlin.annotation.annotation
|
||||||
|
if (a.size() != 1) return "Fail 1: $a"
|
||||||
|
val ann = a.single() as? annotation ?: return "Fail 2: ${a.single()}"
|
||||||
|
assertEquals(AnnotationRetention.RUNTIME, ann.retention)
|
||||||
|
*/
|
||||||
|
assert(a.isEmpty())
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+15
@@ -0,0 +1,15 @@
|
|||||||
|
annotation class Get
|
||||||
|
annotation class Set
|
||||||
|
annotation class SetParam
|
||||||
|
|
||||||
|
var foo: String
|
||||||
|
@Get get() = ""
|
||||||
|
@Set set(@SetParam value) {}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
assert(::foo.getter.annotations.single() is Get)
|
||||||
|
assert(::foo.setter.annotations.single() is Set)
|
||||||
|
assert(::foo.setter.parameters.single().annotations.single() is SetParam)
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
Vendored
+9
@@ -0,0 +1,9 @@
|
|||||||
|
annotation class Ann(val value: String)
|
||||||
|
|
||||||
|
@Ann("OK")
|
||||||
|
val property: String
|
||||||
|
get() = ""
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
return (::property.annotations.single() as Ann).value
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
annotation(retention = AnnotationRetention.SOURCE) class SourceAnno
|
||||||
|
annotation(retention = AnnotationRetention.BINARY) class BinaryAnno
|
||||||
|
annotation(retention = AnnotationRetention.RUNTIME) class RuntimeAnno
|
||||||
|
|
||||||
|
@SourceAnno
|
||||||
|
@BinaryAnno
|
||||||
|
@RuntimeAnno
|
||||||
|
fun box(): String {
|
||||||
|
assertEquals(listOf(javaClass<RuntimeAnno>()), ::box.annotations.map { it.annotationType() })
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
annotation(retention = AnnotationRetention.RUNTIME) class Simple(val value: String)
|
||||||
|
|
||||||
|
@Simple("OK")
|
||||||
|
class A
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
return (A::class.annotations.single() as Simple).value
|
||||||
|
}
|
||||||
Vendored
+13
@@ -0,0 +1,13 @@
|
|||||||
|
annotation class Primary
|
||||||
|
annotation class Secondary
|
||||||
|
|
||||||
|
class C @Primary constructor() {
|
||||||
|
@Secondary
|
||||||
|
constructor(s: String): this()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val ans = C::class.constructors.map { it.annotations.single().annotationType().simpleName }.toSortedList()
|
||||||
|
if (ans != listOf("Primary", "Secondary")) return "Fail: $ans"
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
annotation(retention = AnnotationRetention.RUNTIME) class Simple(val value: String)
|
||||||
|
|
||||||
|
@Simple("OK")
|
||||||
|
fun box(): String {
|
||||||
|
return (::box.annotations.single() as Simple).value
|
||||||
|
}
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
annotation(retention = AnnotationRetention.RUNTIME) class Simple(val value: String)
|
||||||
|
|
||||||
|
fun test(@Simple("OK") x: Int) {}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
return (::test.parameters.single().annotations.single() as Simple).value
|
||||||
|
}
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
annotation(retention = AnnotationRetention.RUNTIME) class Simple(val value: String)
|
||||||
|
|
||||||
|
@Simple("OK")
|
||||||
|
val foo: Int = 0
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
return (::foo.annotations.single() as Simple).value
|
||||||
|
}
|
||||||
+63
@@ -2767,6 +2767,69 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode
|
|||||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxWithStdlib/reflection"), Pattern.compile("^(.+)\\.kt$"), true);
|
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxWithStdlib/reflection"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/codegen/boxWithStdlib/reflection/annotations")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class Annotations extends AbstractBlackBoxCodegenTest {
|
||||||
|
public void testAllFilesPresentInAnnotations() throws Exception {
|
||||||
|
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxWithStdlib/reflection/annotations"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("annotationRetentionAnnotation.kt")
|
||||||
|
public void testAnnotationRetentionAnnotation() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reflection/annotations/annotationRetentionAnnotation.kt");
|
||||||
|
doTestWithStdlib(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("propertyAccessors.kt")
|
||||||
|
public void testPropertyAccessors() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reflection/annotations/propertyAccessors.kt");
|
||||||
|
doTestWithStdlib(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("propertyWithoutBackingField.kt")
|
||||||
|
public void testPropertyWithoutBackingField() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reflection/annotations/propertyWithoutBackingField.kt");
|
||||||
|
doTestWithStdlib(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("retentions.kt")
|
||||||
|
public void testRetentions() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reflection/annotations/retentions.kt");
|
||||||
|
doTestWithStdlib(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("simpleClassAnnotation.kt")
|
||||||
|
public void testSimpleClassAnnotation() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reflection/annotations/simpleClassAnnotation.kt");
|
||||||
|
doTestWithStdlib(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("simpleConstructorAnnotation.kt")
|
||||||
|
public void testSimpleConstructorAnnotation() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reflection/annotations/simpleConstructorAnnotation.kt");
|
||||||
|
doTestWithStdlib(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("simpleFunAnnotation.kt")
|
||||||
|
public void testSimpleFunAnnotation() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reflection/annotations/simpleFunAnnotation.kt");
|
||||||
|
doTestWithStdlib(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("simpleParamAnnotation.kt")
|
||||||
|
public void testSimpleParamAnnotation() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reflection/annotations/simpleParamAnnotation.kt");
|
||||||
|
doTestWithStdlib(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("simpleValAnnotation.kt")
|
||||||
|
public void testSimpleValAnnotation() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reflection/annotations/simpleValAnnotation.kt");
|
||||||
|
doTestWithStdlib(fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/codegen/boxWithStdlib/reflection/call")
|
@TestMetadata("compiler/testData/codegen/boxWithStdlib/reflection/call")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2015 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package kotlin.reflect
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents an annotated element and allows to obtain its annotations.
|
||||||
|
* See the [Kotlin language documentation](http://kotlinlang.org/docs/reference/annotations.html)
|
||||||
|
* for more information.
|
||||||
|
*/
|
||||||
|
public interface KAnnotatedElement {
|
||||||
|
/**
|
||||||
|
* Annotations which are present on this element.
|
||||||
|
*/
|
||||||
|
public val annotations: List<Annotation>
|
||||||
|
}
|
||||||
@@ -21,7 +21,7 @@ package kotlin.reflect
|
|||||||
*
|
*
|
||||||
* @param R return type of the callable.
|
* @param R return type of the callable.
|
||||||
*/
|
*/
|
||||||
public interface KCallable<out R> {
|
public interface KCallable<out R> : KAnnotatedElement {
|
||||||
/**
|
/**
|
||||||
* The name of this callable as it was declared in the source code.
|
* The name of this callable as it was declared in the source code.
|
||||||
* If the callable has no name, a special invented name is created.
|
* If the callable has no name, a special invented name is created.
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ package kotlin.reflect
|
|||||||
*
|
*
|
||||||
* @param T the type of the class.
|
* @param T the type of the class.
|
||||||
*/
|
*/
|
||||||
public interface KClass<T> : KDeclarationContainer {
|
public interface KClass<T> : KDeclarationContainer, KAnnotatedElement {
|
||||||
/**
|
/**
|
||||||
* The simple name of the class as it was declared in the source code,
|
* The simple name of the class as it was declared in the source code,
|
||||||
* or `null` if the class has no name (if, for example, it is an anonymous object literal).
|
* or `null` if the class has no name (if, for example, it is an anonymous object literal).
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ package kotlin.reflect
|
|||||||
* Represents a parameter passed to a function or a property getter/setter,
|
* Represents a parameter passed to a function or a property getter/setter,
|
||||||
* including `this` and extension receiver parameters.
|
* including `this` and extension receiver parameters.
|
||||||
*/
|
*/
|
||||||
public interface KParameter {
|
public interface KParameter : KAnnotatedElement {
|
||||||
/**
|
/**
|
||||||
* 0-based index of this parameter in the parameter list of its containing callable.
|
* 0-based index of this parameter in the parameter list of its containing callable.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2015 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package kotlin.reflect.jvm.internal
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.descriptors.annotations.Annotated
|
||||||
|
import org.jetbrains.kotlin.load.kotlin.reflect.ReflectAnnotationSource
|
||||||
|
import kotlin.reflect.KAnnotatedElement
|
||||||
|
|
||||||
|
interface KAnnotatedElementImpl : KAnnotatedElement {
|
||||||
|
val annotated: Annotated
|
||||||
|
|
||||||
|
override val annotations: List<Annotation>
|
||||||
|
get() = annotated.annotations.map {
|
||||||
|
(it.source as? ReflectAnnotationSource)?.annotation
|
||||||
|
}.filterNotNull()
|
||||||
|
}
|
||||||
@@ -17,14 +17,17 @@
|
|||||||
package kotlin.reflect.jvm.internal
|
package kotlin.reflect.jvm.internal
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.annotations.Annotated
|
||||||
import java.util.ArrayList
|
import java.util.ArrayList
|
||||||
import kotlin.reflect.KCallable
|
import kotlin.reflect.KCallable
|
||||||
import kotlin.reflect.KParameter
|
import kotlin.reflect.KParameter
|
||||||
import kotlin.reflect.KType
|
import kotlin.reflect.KType
|
||||||
|
|
||||||
interface KCallableImpl<out R> : KCallable<R> {
|
interface KCallableImpl<out R> : KCallable<R>, KAnnotatedElementImpl {
|
||||||
val descriptor: CallableMemberDescriptor
|
val descriptor: CallableMemberDescriptor
|
||||||
|
|
||||||
|
override val annotated: Annotated get() = descriptor
|
||||||
|
|
||||||
override val parameters: List<KParameter>
|
override val parameters: List<KParameter>
|
||||||
get() {
|
get() {
|
||||||
val result = ArrayList<KParameter>()
|
val result = ArrayList<KParameter>()
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ package kotlin.reflect.jvm.internal
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||||
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
|
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.annotations.Annotated
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.resolve.scopes.ChainedScope
|
import org.jetbrains.kotlin.resolve.scopes.ChainedScope
|
||||||
import org.jetbrains.kotlin.resolve.scopes.JetScope
|
import org.jetbrains.kotlin.resolve.scopes.JetScope
|
||||||
@@ -26,7 +27,7 @@ import kotlin.reflect.KClass
|
|||||||
import kotlin.reflect.KFunction
|
import kotlin.reflect.KFunction
|
||||||
import kotlin.reflect.KotlinReflectionInternalError
|
import kotlin.reflect.KotlinReflectionInternalError
|
||||||
|
|
||||||
class KClassImpl<T>(override val jClass: Class<T>) : KCallableContainerImpl(), KClass<T> {
|
class KClassImpl<T>(override val jClass: Class<T>) : KCallableContainerImpl(), KClass<T>, KAnnotatedElementImpl {
|
||||||
val descriptor by ReflectProperties.lazySoft {
|
val descriptor by ReflectProperties.lazySoft {
|
||||||
val classId = classId
|
val classId = classId
|
||||||
|
|
||||||
@@ -37,6 +38,8 @@ class KClassImpl<T>(override val jClass: Class<T>) : KCallableContainerImpl(), K
|
|||||||
descriptor ?: throw KotlinReflectionInternalError("Class not resolved: $jClass")
|
descriptor ?: throw KotlinReflectionInternalError("Class not resolved: $jClass")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override val annotated: Annotated get() = descriptor
|
||||||
|
|
||||||
private val classId: ClassId get() = RuntimeTypeMapper.mapJvmClassToKotlinClassId(jClass)
|
private val classId: ClassId get() = RuntimeTypeMapper.mapJvmClassToKotlinClassId(jClass)
|
||||||
|
|
||||||
override val scope: JetScope get() = ChainedScope(
|
override val scope: JetScope get() = ChainedScope(
|
||||||
|
|||||||
@@ -18,15 +18,18 @@ package kotlin.reflect.jvm.internal
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.ParameterDescriptor
|
import org.jetbrains.kotlin.descriptors.ParameterDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.annotations.Annotated
|
||||||
import kotlin.reflect.KParameter
|
import kotlin.reflect.KParameter
|
||||||
import kotlin.reflect.KType
|
import kotlin.reflect.KType
|
||||||
|
|
||||||
class KParameterImpl(
|
class KParameterImpl(
|
||||||
override val index: Int,
|
override val index: Int,
|
||||||
private val computeDescriptor: () -> ParameterDescriptor
|
private val computeDescriptor: () -> ParameterDescriptor
|
||||||
) : KParameter {
|
) : KParameter, KAnnotatedElementImpl {
|
||||||
private val descriptor: ParameterDescriptor by ReflectProperties.lazySoft(computeDescriptor)
|
private val descriptor: ParameterDescriptor by ReflectProperties.lazySoft(computeDescriptor)
|
||||||
|
|
||||||
|
override val annotated: Annotated get() = descriptor
|
||||||
|
|
||||||
override val name: String? get() {
|
override val name: String? get() {
|
||||||
val valueParameter = descriptor as? ValueParameterDescriptor ?: return null
|
val valueParameter = descriptor as? ValueParameterDescriptor ?: return null
|
||||||
if (valueParameter.containingDeclaration.hasSynthesizedParameterNames()) return null
|
if (valueParameter.containingDeclaration.hasSynthesizedParameterNames()) return null
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import kotlin.reflect.KParameter;
|
|||||||
import kotlin.reflect.KType;
|
import kotlin.reflect.KType;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.lang.annotation.Annotation;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -75,6 +76,11 @@ public abstract class CallableReference implements KCallable {
|
|||||||
throw error();
|
throw error();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Annotation> getAnnotations() {
|
||||||
|
throw error();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object call(@NotNull Object... args) {
|
public Object call(@NotNull Object... args) {
|
||||||
throw error();
|
throw error();
|
||||||
|
|||||||
@@ -33,5 +33,8 @@ public class ClassReference(override val jClass: Class<*>) : KClass<Any>, Declar
|
|||||||
override val constructors: Collection<KFunction<Any>>
|
override val constructors: Collection<KFunction<Any>>
|
||||||
get() = error()
|
get() = error()
|
||||||
|
|
||||||
|
override val annotations: List<Annotation>
|
||||||
|
get() = error()
|
||||||
|
|
||||||
private fun error(): Nothing = throw KotlinReflectionNotSupportedError()
|
private fun error(): Nothing = throw KotlinReflectionNotSupportedError()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import kotlin.jvm.KotlinReflectionNotSupportedError;
|
|||||||
import kotlin.reflect.*;
|
import kotlin.reflect.*;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.lang.annotation.Annotation;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
@@ -71,6 +72,11 @@ public class FunctionReference
|
|||||||
throw error();
|
throw error();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Annotation> getAnnotations() {
|
||||||
|
throw error();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object call(@NotNull Object... args) {
|
public Object call(@NotNull Object... args) {
|
||||||
throw error();
|
throw error();
|
||||||
|
|||||||
Reference in New Issue
Block a user