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
|
||||
}
|
||||
|
||||
@interface Anno {
|
||||
public @interface Anno {
|
||||
E value();
|
||||
}
|
||||
|
||||
|
||||
@@ -4,8 +4,8 @@ public open class NestedEnumArgument {
|
||||
public constructor NestedEnumArgument()
|
||||
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/*package*/ constructor Anno(/*0*/ value: test.NestedEnumArgument.E)
|
||||
public final annotation class Anno : kotlin.Annotation {
|
||||
public constructor Anno(/*0*/ 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
|
||||
|
||||
import org.jetbrains.kotlin.load.java.structure.*
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.load.java.structure.JavaClass
|
||||
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.utils.emptyOrSingletonList
|
||||
import java.lang.reflect.AnnotatedElement
|
||||
import java.lang.reflect.Method
|
||||
import java.lang.reflect.Modifier
|
||||
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()
|
||||
.stream()
|
||||
.filterNot {
|
||||
@@ -86,17 +91,6 @@ public class ReflectJavaClass(private val klass: Class<*>) : ReflectJavaElement(
|
||||
|
||||
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 isInterface() = klass.isInterface()
|
||||
|
||||
+5
-20
@@ -16,40 +16,25 @@
|
||||
|
||||
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.JavaTypeParameter
|
||||
import org.jetbrains.kotlin.load.java.structure.JavaValueParameter
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import java.lang.reflect.Constructor
|
||||
import java.lang.reflect.Modifier
|
||||
import java.util.Arrays
|
||||
|
||||
public class ReflectJavaConstructor(constructor: Constructor<*>) : ReflectJavaMember(constructor), 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
|
||||
}
|
||||
|
||||
public class ReflectJavaConstructor(override val member: Constructor<*>) : ReflectJavaMember(), JavaConstructor {
|
||||
override fun getValueParameters(): List<JavaValueParameter> =
|
||||
getValueParameters(
|
||||
dropSynthetic(constructor.getGenericParameterTypes()),
|
||||
dropSynthetic(constructor.getParameterAnnotations()),
|
||||
constructor.isVarArgs()
|
||||
dropSynthetic(member.getGenericParameterTypes()),
|
||||
dropSynthetic(member.getParameterAnnotations()),
|
||||
member.isVarArgs()
|
||||
)
|
||||
|
||||
// Constructors of inner classes have one additional synthetic parameter
|
||||
// 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> {
|
||||
val klass = constructor.getDeclaringClass()
|
||||
val klass = member.getDeclaringClass()
|
||||
return if (klass.getDeclaringClass() != null && !Modifier.isStatic(klass.getModifiers())) {
|
||||
Arrays.copyOfRange(array, 1, array.size())
|
||||
}
|
||||
|
||||
+4
-19
@@ -16,26 +16,11 @@
|
||||
|
||||
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.JavaAnnotation
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import java.lang.reflect.Field
|
||||
|
||||
public class ReflectJavaField(field: Field) : ReflectJavaMember(field), JavaField {
|
||||
val field: Field
|
||||
get() = member as Field
|
||||
public class ReflectJavaField(override val member: Field) : ReflectJavaMember(), JavaField {
|
||||
override fun isEnumEntry() = member.isEnumConstant()
|
||||
|
||||
override fun getAnnotations(): Collection<JavaAnnotation> {
|
||||
// TODO
|
||||
return listOf()
|
||||
}
|
||||
|
||||
override fun findAnnotation(fqName: FqName): JavaAnnotation? {
|
||||
// TODO
|
||||
return null
|
||||
}
|
||||
|
||||
override fun isEnumEntry() = field.isEnumConstant()
|
||||
|
||||
override fun getType() = ReflectJavaType.create(field.getGenericType()!!)
|
||||
override fun getType() = ReflectJavaType.create(member.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.name.Name
|
||||
import org.jetbrains.kotlin.name.SpecialNames
|
||||
import java.lang.reflect.AnnotatedElement
|
||||
import java.lang.reflect.Member
|
||||
import java.lang.reflect.Modifier
|
||||
import java.lang.reflect.Type
|
||||
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 getContainingClass() = ReflectJavaClass(member.getDeclaringClass())
|
||||
|
||||
+5
-24
@@ -16,36 +16,17 @@
|
||||
|
||||
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.JavaType
|
||||
import org.jetbrains.kotlin.load.java.structure.JavaValueParameter
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import java.lang.reflect.Method
|
||||
|
||||
public class ReflectJavaMethod(method: Method) : ReflectJavaMember(method), 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
|
||||
}
|
||||
|
||||
public class ReflectJavaMethod(override val member: Method) : ReflectJavaMember(), JavaMethod {
|
||||
override fun getValueParameters(): List<JavaValueParameter> =
|
||||
getValueParameters(method.getGenericParameterTypes(), method.getParameterAnnotations(), method.isVarArgs())
|
||||
getValueParameters(member.getGenericParameterTypes(), member.getParameterAnnotations(), member.isVarArgs())
|
||||
|
||||
override fun getReturnType(): JavaType? {
|
||||
// TODO
|
||||
return ReflectJavaType.create(method.getGenericReturnType()!!)
|
||||
}
|
||||
override fun getReturnType() = ReflectJavaType.create(member.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) }
|
||||
}
|
||||
|
||||
+3
-10
@@ -17,7 +17,6 @@
|
||||
package org.jetbrains.kotlin.load.java.structure.reflect
|
||||
|
||||
import org.jetbrains.kotlin.load.java.structure.JavaValueParameter
|
||||
import org.jetbrains.kotlin.load.java.structure.JavaAnnotation
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
|
||||
public class ReflectJavaValueParameter(
|
||||
@@ -25,17 +24,11 @@ public class ReflectJavaValueParameter(
|
||||
private val annotations: Array<Annotation>,
|
||||
private val isVararg: Boolean
|
||||
) : ReflectJavaElement(), JavaValueParameter {
|
||||
override fun getAnnotations(): Collection<JavaAnnotation> {
|
||||
// TODO
|
||||
return listOf()
|
||||
}
|
||||
override fun getAnnotations() = getAnnotations(annotations)
|
||||
|
||||
override fun findAnnotation(fqName: FqName): JavaAnnotation? {
|
||||
// TODO
|
||||
return null
|
||||
}
|
||||
override fun findAnnotation(fqName: FqName) = findAnnotation(annotations, fqName)
|
||||
|
||||
override fun getName() = null // TODO: use ParameterNames on JDK 8
|
||||
override fun getType() = returnType
|
||||
override fun isVararg() = isVararg
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user