Resolve annotations on all reflected elements
Annotation in NestedEnumArgument test is made public, because we try to load annotation argument values eagerly and fail, since you can't invoke methods reflectively on an object of a non-effectively-public class
This commit is contained in:
@@ -5,7 +5,7 @@ public class NestedEnumArgument {
|
|||||||
FIRST
|
FIRST
|
||||||
}
|
}
|
||||||
|
|
||||||
@interface Anno {
|
public @interface Anno {
|
||||||
E value();
|
E value();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ public open class NestedEnumArgument {
|
|||||||
public constructor NestedEnumArgument()
|
public constructor NestedEnumArgument()
|
||||||
test.NestedEnumArgument.Anno(value = E.FIRST: test.NestedEnumArgument.E) public/*package*/ open fun foo(): kotlin.Unit
|
test.NestedEnumArgument.Anno(value = E.FIRST: test.NestedEnumArgument.E) public/*package*/ open fun foo(): kotlin.Unit
|
||||||
|
|
||||||
public/*package*/ final annotation class Anno : kotlin.Annotation {
|
public final annotation class Anno : kotlin.Annotation {
|
||||||
public/*package*/ constructor Anno(/*0*/ value: test.NestedEnumArgument.E)
|
public constructor Anno(/*0*/ value: test.NestedEnumArgument.E)
|
||||||
public abstract fun value(): test.NestedEnumArgument.E
|
public abstract fun value(): test.NestedEnumArgument.E
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+37
@@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* 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 org.jetbrains.kotlin.load.java.structure.reflect
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.load.java.structure.JavaAnnotationOwner
|
||||||
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
import java.lang.reflect.AnnotatedElement
|
||||||
|
|
||||||
|
public trait ReflectJavaAnnotationOwner : JavaAnnotationOwner {
|
||||||
|
val element: AnnotatedElement
|
||||||
|
|
||||||
|
override fun getAnnotations() = getAnnotations(element.getDeclaredAnnotations())
|
||||||
|
|
||||||
|
override fun findAnnotation(fqName: FqName) = findAnnotation(element.getDeclaredAnnotations(), fqName)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getAnnotations(annotations: Array<Annotation>): List<ReflectJavaAnnotation> {
|
||||||
|
return annotations.map { ReflectJavaAnnotation(it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun findAnnotation(annotations: Array<Annotation>, fqName: FqName): ReflectJavaAnnotation? {
|
||||||
|
return annotations.firstOrNull { it.annotationType().fqName == fqName }?.let { ReflectJavaAnnotation(it) }
|
||||||
|
}
|
||||||
+8
-14
@@ -16,15 +16,20 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.load.java.structure.reflect
|
package org.jetbrains.kotlin.load.java.structure.reflect
|
||||||
|
|
||||||
import org.jetbrains.kotlin.load.java.structure.*
|
import org.jetbrains.kotlin.load.java.structure.JavaClass
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.load.java.structure.JavaClassifierType
|
||||||
|
import org.jetbrains.kotlin.load.java.structure.JavaType
|
||||||
|
import org.jetbrains.kotlin.load.java.structure.JavaTypeSubstitutor
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.utils.emptyOrSingletonList
|
import org.jetbrains.kotlin.utils.emptyOrSingletonList
|
||||||
|
import java.lang.reflect.AnnotatedElement
|
||||||
import java.lang.reflect.Method
|
import java.lang.reflect.Method
|
||||||
import java.lang.reflect.Modifier
|
import java.lang.reflect.Modifier
|
||||||
import java.util.Arrays
|
import java.util.Arrays
|
||||||
|
|
||||||
public class ReflectJavaClass(private val klass: Class<*>) : ReflectJavaElement(), JavaClass {
|
public class ReflectJavaClass(private val klass: Class<*>) : ReflectJavaElement(), ReflectJavaAnnotationOwner, JavaClass {
|
||||||
|
override val element: AnnotatedElement get() = klass
|
||||||
|
|
||||||
override fun getInnerClasses() = klass.getDeclaredClasses()
|
override fun getInnerClasses() = klass.getDeclaredClasses()
|
||||||
.stream()
|
.stream()
|
||||||
.filterNot {
|
.filterNot {
|
||||||
@@ -86,17 +91,6 @@ public class ReflectJavaClass(private val klass: Class<*>) : ReflectJavaElement(
|
|||||||
|
|
||||||
override fun getName(): Name = Name.identifier(klass.getSimpleName())
|
override fun getName(): Name = Name.identifier(klass.getSimpleName())
|
||||||
|
|
||||||
override fun getAnnotations() = klass.getDeclaredAnnotations().map { ReflectJavaAnnotation(it) }
|
|
||||||
|
|
||||||
override fun findAnnotation(fqName: FqName): JavaAnnotation? {
|
|
||||||
for (annotation in klass.getDeclaredAnnotations()) {
|
|
||||||
if (annotation.annotationType().fqName == fqName) {
|
|
||||||
return ReflectJavaAnnotation(annotation)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getTypeParameters() = klass.getTypeParameters().map { ReflectJavaTypeParameter(it) }
|
override fun getTypeParameters() = klass.getTypeParameters().map { ReflectJavaTypeParameter(it) }
|
||||||
|
|
||||||
override fun isInterface() = klass.isInterface()
|
override fun isInterface() = klass.isInterface()
|
||||||
|
|||||||
+5
-20
@@ -16,40 +16,25 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.load.java.structure.reflect
|
package org.jetbrains.kotlin.load.java.structure.reflect
|
||||||
|
|
||||||
import org.jetbrains.kotlin.load.java.structure.JavaAnnotation
|
|
||||||
import org.jetbrains.kotlin.load.java.structure.JavaConstructor
|
import org.jetbrains.kotlin.load.java.structure.JavaConstructor
|
||||||
import org.jetbrains.kotlin.load.java.structure.JavaTypeParameter
|
import org.jetbrains.kotlin.load.java.structure.JavaTypeParameter
|
||||||
import org.jetbrains.kotlin.load.java.structure.JavaValueParameter
|
import org.jetbrains.kotlin.load.java.structure.JavaValueParameter
|
||||||
import org.jetbrains.kotlin.name.FqName
|
|
||||||
import java.lang.reflect.Constructor
|
import java.lang.reflect.Constructor
|
||||||
import java.lang.reflect.Modifier
|
import java.lang.reflect.Modifier
|
||||||
import java.util.Arrays
|
import java.util.Arrays
|
||||||
|
|
||||||
public class ReflectJavaConstructor(constructor: Constructor<*>) : ReflectJavaMember(constructor), JavaConstructor {
|
public class ReflectJavaConstructor(override val member: Constructor<*>) : ReflectJavaMember(), JavaConstructor {
|
||||||
private val constructor: Constructor<*>
|
|
||||||
get() = member as Constructor<*>
|
|
||||||
|
|
||||||
override fun getAnnotations(): Collection<JavaAnnotation> {
|
|
||||||
// TODO
|
|
||||||
return listOf()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun findAnnotation(fqName: FqName): JavaAnnotation? {
|
|
||||||
// TODO
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getValueParameters(): List<JavaValueParameter> =
|
override fun getValueParameters(): List<JavaValueParameter> =
|
||||||
getValueParameters(
|
getValueParameters(
|
||||||
dropSynthetic(constructor.getGenericParameterTypes()),
|
dropSynthetic(member.getGenericParameterTypes()),
|
||||||
dropSynthetic(constructor.getParameterAnnotations()),
|
dropSynthetic(member.getParameterAnnotations()),
|
||||||
constructor.isVarArgs()
|
member.isVarArgs()
|
||||||
)
|
)
|
||||||
|
|
||||||
// Constructors of inner classes have one additional synthetic parameter
|
// Constructors of inner classes have one additional synthetic parameter
|
||||||
// TODO: test this code with annotations on constructor parameters of enums and inner classes
|
// TODO: test this code with annotations on constructor parameters of enums and inner classes
|
||||||
private inline fun <reified T> dropSynthetic(array: Array<T>): Array<T> {
|
private inline fun <reified T> dropSynthetic(array: Array<T>): Array<T> {
|
||||||
val klass = constructor.getDeclaringClass()
|
val klass = member.getDeclaringClass()
|
||||||
return if (klass.getDeclaringClass() != null && !Modifier.isStatic(klass.getModifiers())) {
|
return if (klass.getDeclaringClass() != null && !Modifier.isStatic(klass.getModifiers())) {
|
||||||
Arrays.copyOfRange(array, 1, array.size())
|
Arrays.copyOfRange(array, 1, array.size())
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-19
@@ -16,26 +16,11 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.load.java.structure.reflect
|
package org.jetbrains.kotlin.load.java.structure.reflect
|
||||||
|
|
||||||
import java.lang.reflect.Field
|
|
||||||
import org.jetbrains.kotlin.load.java.structure.JavaField
|
import org.jetbrains.kotlin.load.java.structure.JavaField
|
||||||
import org.jetbrains.kotlin.load.java.structure.JavaAnnotation
|
import java.lang.reflect.Field
|
||||||
import org.jetbrains.kotlin.name.FqName
|
|
||||||
|
|
||||||
public class ReflectJavaField(field: Field) : ReflectJavaMember(field), JavaField {
|
public class ReflectJavaField(override val member: Field) : ReflectJavaMember(), JavaField {
|
||||||
val field: Field
|
override fun isEnumEntry() = member.isEnumConstant()
|
||||||
get() = member as Field
|
|
||||||
|
|
||||||
override fun getAnnotations(): Collection<JavaAnnotation> {
|
override fun getType() = ReflectJavaType.create(member.getGenericType())
|
||||||
// TODO
|
|
||||||
return listOf()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun findAnnotation(fqName: FqName): JavaAnnotation? {
|
|
||||||
// TODO
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun isEnumEntry() = field.isEnumConstant()
|
|
||||||
|
|
||||||
override fun getType() = ReflectJavaType.create(field.getGenericType()!!)
|
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-1
@@ -20,12 +20,17 @@ import org.jetbrains.kotlin.load.java.structure.JavaMember
|
|||||||
import org.jetbrains.kotlin.load.java.structure.JavaValueParameter
|
import org.jetbrains.kotlin.load.java.structure.JavaValueParameter
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.name.SpecialNames
|
import org.jetbrains.kotlin.name.SpecialNames
|
||||||
|
import java.lang.reflect.AnnotatedElement
|
||||||
import java.lang.reflect.Member
|
import java.lang.reflect.Member
|
||||||
import java.lang.reflect.Modifier
|
import java.lang.reflect.Modifier
|
||||||
import java.lang.reflect.Type
|
import java.lang.reflect.Type
|
||||||
import java.util.ArrayList
|
import java.util.ArrayList
|
||||||
|
|
||||||
public abstract class ReflectJavaMember(protected val member: Member) : ReflectJavaElement(), JavaMember {
|
public abstract class ReflectJavaMember : ReflectJavaElement(), ReflectJavaAnnotationOwner, JavaMember {
|
||||||
|
protected abstract val member: Member
|
||||||
|
|
||||||
|
override val element: AnnotatedElement get() = member as AnnotatedElement
|
||||||
|
|
||||||
override fun getName() = member.getName()?.let { Name.identifier(it) } ?: SpecialNames.NO_NAME_PROVIDED
|
override fun getName() = member.getName()?.let { Name.identifier(it) } ?: SpecialNames.NO_NAME_PROVIDED
|
||||||
|
|
||||||
override fun getContainingClass() = ReflectJavaClass(member.getDeclaringClass())
|
override fun getContainingClass() = ReflectJavaClass(member.getDeclaringClass())
|
||||||
|
|||||||
+5
-24
@@ -16,36 +16,17 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.load.java.structure.reflect
|
package org.jetbrains.kotlin.load.java.structure.reflect
|
||||||
|
|
||||||
import org.jetbrains.kotlin.load.java.structure.JavaAnnotation
|
|
||||||
import org.jetbrains.kotlin.load.java.structure.JavaMethod
|
import org.jetbrains.kotlin.load.java.structure.JavaMethod
|
||||||
import org.jetbrains.kotlin.load.java.structure.JavaType
|
|
||||||
import org.jetbrains.kotlin.load.java.structure.JavaValueParameter
|
import org.jetbrains.kotlin.load.java.structure.JavaValueParameter
|
||||||
import org.jetbrains.kotlin.name.FqName
|
|
||||||
import java.lang.reflect.Method
|
import java.lang.reflect.Method
|
||||||
|
|
||||||
public class ReflectJavaMethod(method: Method) : ReflectJavaMember(method), JavaMethod {
|
public class ReflectJavaMethod(override val member: Method) : ReflectJavaMember(), JavaMethod {
|
||||||
private val method: Method
|
|
||||||
get() = member as Method
|
|
||||||
|
|
||||||
override fun getAnnotations(): Collection<JavaAnnotation> {
|
|
||||||
// TODO
|
|
||||||
return listOf()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun findAnnotation(fqName: FqName): JavaAnnotation? {
|
|
||||||
// TODO
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getValueParameters(): List<JavaValueParameter> =
|
override fun getValueParameters(): List<JavaValueParameter> =
|
||||||
getValueParameters(method.getGenericParameterTypes(), method.getParameterAnnotations(), method.isVarArgs())
|
getValueParameters(member.getGenericParameterTypes(), member.getParameterAnnotations(), member.isVarArgs())
|
||||||
|
|
||||||
override fun getReturnType(): JavaType? {
|
override fun getReturnType() = ReflectJavaType.create(member.getGenericReturnType())
|
||||||
// TODO
|
|
||||||
return ReflectJavaType.create(method.getGenericReturnType()!!)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun hasAnnotationParameterDefaultValue() = method.getDefaultValue() != null
|
override fun hasAnnotationParameterDefaultValue() = member.getDefaultValue() != null
|
||||||
|
|
||||||
override fun getTypeParameters() = method.getTypeParameters().map { ReflectJavaTypeParameter(it) }
|
override fun getTypeParameters() = member.getTypeParameters().map { ReflectJavaTypeParameter(it) }
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-9
@@ -17,7 +17,6 @@
|
|||||||
package org.jetbrains.kotlin.load.java.structure.reflect
|
package org.jetbrains.kotlin.load.java.structure.reflect
|
||||||
|
|
||||||
import org.jetbrains.kotlin.load.java.structure.JavaValueParameter
|
import org.jetbrains.kotlin.load.java.structure.JavaValueParameter
|
||||||
import org.jetbrains.kotlin.load.java.structure.JavaAnnotation
|
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
|
||||||
public class ReflectJavaValueParameter(
|
public class ReflectJavaValueParameter(
|
||||||
@@ -25,15 +24,9 @@ public class ReflectJavaValueParameter(
|
|||||||
private val annotations: Array<Annotation>,
|
private val annotations: Array<Annotation>,
|
||||||
private val isVararg: Boolean
|
private val isVararg: Boolean
|
||||||
) : ReflectJavaElement(), JavaValueParameter {
|
) : ReflectJavaElement(), JavaValueParameter {
|
||||||
override fun getAnnotations(): Collection<JavaAnnotation> {
|
override fun getAnnotations() = getAnnotations(annotations)
|
||||||
// TODO
|
|
||||||
return listOf()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun findAnnotation(fqName: FqName): JavaAnnotation? {
|
override fun findAnnotation(fqName: FqName) = findAnnotation(annotations, fqName)
|
||||||
// TODO
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getName() = null // TODO: use ParameterNames on JDK 8
|
override fun getName() = null // TODO: use ParameterNames on JDK 8
|
||||||
override fun getType() = returnType
|
override fun getType() = returnType
|
||||||
|
|||||||
Reference in New Issue
Block a user