Annotations supported
This commit is contained in:
@@ -21,6 +21,9 @@ import org.jetbrains.jet.lang.resolve.java.lazy.types.LazyJavaTypeResolver
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.jet.lang.resolve.java.structure.JavaTypeParameter
|
||||
import org.jetbrains.jet.lang.resolve.java.JavaClassFinder
|
||||
import org.jetbrains.jet.lang.resolve.java.structure.JavaAnnotation
|
||||
import org.jetbrains.jet.lang.resolve.java.lazy.descriptors.LazyJavaAnnotationDescriptor
|
||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor
|
||||
|
||||
open class LazyJavaResolverContext(
|
||||
val storageManager: StorageManager,
|
||||
@@ -48,4 +51,7 @@ class LazyJavaResolverContextWithTypes(
|
||||
fun LazyJavaResolverContextWithTypes.child(
|
||||
containingDeclaration: DeclarationDescriptor,
|
||||
typeParameters: Set<JavaTypeParameter>
|
||||
): LazyJavaResolverContextWithTypes = this.withTypes(LazyJavaTypeParameterResolver(this, containingDeclaration, typeParameters))
|
||||
): LazyJavaResolverContextWithTypes = this.withTypes(LazyJavaTypeParameterResolver(this, containingDeclaration, typeParameters))
|
||||
|
||||
fun LazyJavaResolverContextWithTypes.resolveAnnotations(javaAnnotations: Collection<JavaAnnotation>): List<AnnotationDescriptor>
|
||||
= javaAnnotations.map {jAnnotation -> LazyJavaAnnotationDescriptor(this, jAnnotation)}
|
||||
+150
@@ -0,0 +1,150 @@
|
||||
package org.jetbrains.jet.lang.resolve.java.lazy.descriptors
|
||||
|
||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor
|
||||
import org.jetbrains.jet.lang.types.JetType
|
||||
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor
|
||||
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant
|
||||
import org.jetbrains.jet.lang.resolve.java.lazy.LazyJavaResolverContextWithTypes
|
||||
import org.jetbrains.jet.lang.resolve.java.structure.*
|
||||
import org.jetbrains.jet.lang.types.ErrorUtils
|
||||
import org.jetbrains.jet.lang.resolve.constants.*
|
||||
import org.jetbrains.jet.lang.resolve.name.Name
|
||||
import org.jetbrains.jet.lang.resolve.name.FqName
|
||||
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns
|
||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor
|
||||
import org.jetbrains.jet.lang.descriptors.VariableDescriptor
|
||||
import org.jetbrains.jet.lang.resolve.java.resolver.JavaAnnotationArgumentResolver
|
||||
import org.jetbrains.jet.lang.resolve.java.resolver.JavaAnnotationResolver.*
|
||||
import org.jetbrains.jet.lang.resolve.java.JvmAnnotationNames
|
||||
import org.jetbrains.jet.lang.resolve.java.resolver.DescriptorResolverUtils
|
||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils
|
||||
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.jet.lang.resolve.java.resolver.TypeUsage
|
||||
import org.jetbrains.jet.lang.types.TypeProjectionImpl
|
||||
import org.jetbrains.jet.lang.types.JetTypeImpl
|
||||
import org.jetbrains.jet.lang.types.TypeConstructor
|
||||
import org.jetbrains.jet.lang.types.TypeProjection
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope
|
||||
import org.jetbrains.jet.lang.resolve.java.lazy.types.LazyType
|
||||
import org.jetbrains.jet.utils.valuesToMap
|
||||
import org.jetbrains.jet.utils.keysToMap
|
||||
import org.jetbrains.jet.utils.keysToMapExceptNulls
|
||||
import org.jetbrains.jet.lang.resolve.java.resolver.JavaAnnotationResolver
|
||||
import org.jetbrains.jet.renderer.DescriptorRenderer
|
||||
|
||||
class LazyJavaAnnotationDescriptor(
|
||||
private val c: LazyJavaResolverContextWithTypes,
|
||||
val javaAnnotation : JavaAnnotation
|
||||
) : AnnotationDescriptor {
|
||||
|
||||
private val _type = c.storageManager.createLazyValue {() : JetType ->
|
||||
val fqName = javaAnnotation.getFqName()
|
||||
if (fqName == null) return@createLazyValue ErrorUtils.createErrorType("No fqName: $javaAnnotation")
|
||||
val annotationClass = c.javaClassResolver.resolveClassByFqName(fqName)
|
||||
annotationClass?.getDefaultType() ?: ErrorUtils.createErrorType(fqName.asString())
|
||||
}
|
||||
|
||||
override fun getType(): JetType = _type()
|
||||
|
||||
private val _nameToArgument = c.storageManager.createLazyValue {
|
||||
javaAnnotation.getArguments().valuesToMap { a -> a.getName() }
|
||||
}
|
||||
|
||||
private val _valueArguments = c.storageManager.createMemoizedFunctionWithNullableValues<ValueParameterDescriptor, CompileTimeConstant<out Any?>> {
|
||||
valueParameter ->
|
||||
val nameToArg = _nameToArgument()
|
||||
|
||||
var javaAnnotationArgument = nameToArg[valueParameter.getName()]
|
||||
if (javaAnnotationArgument == null && valueParameter.getName() == JavaAnnotationResolver.DEFAULT_ANNOTATION_MEMBER_NAME) {
|
||||
javaAnnotationArgument = nameToArg[null]
|
||||
}
|
||||
|
||||
resolveAnnotationArgument(javaAnnotationArgument)
|
||||
}
|
||||
|
||||
override fun getValueArgument(valueParameterDescriptor: ValueParameterDescriptor) = _valueArguments(valueParameterDescriptor)
|
||||
|
||||
private val _allValueArguments = c.storageManager.createLazyValue {
|
||||
val constructors = getAnnotationClass().getConstructors()
|
||||
if (constructors.isEmpty()) mapOf<ValueParameterDescriptor, CompileTimeConstant<out Any?>>()
|
||||
constructors.first().getValueParameters().keysToMapExceptNulls {
|
||||
vp -> getValueArgument(vp)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getAllValueArguments() = _allValueArguments()
|
||||
|
||||
private fun getAnnotationClass() = getType().getConstructor().getDeclarationDescriptor() as ClassDescriptor
|
||||
|
||||
private fun resolveAnnotationArgument(argument: JavaAnnotationArgument?): CompileTimeConstant<*>? {
|
||||
return when (argument) {
|
||||
is JavaLiteralAnnotationArgument -> JavaAnnotationArgumentResolver.resolveCompileTimeConstantValue(argument.getValue(), null)
|
||||
is JavaReferenceAnnotationArgument -> resolveFromReference(argument.resolve())
|
||||
is JavaArrayAnnotationArgument -> resolveFromArray(argument.getName() ?: DEFAULT_ANNOTATION_MEMBER_NAME, argument.getElements())
|
||||
is JavaAnnotationAsAnnotationArgument -> resolveFromAnnotation(argument.getAnnotation())
|
||||
is JavaClassObjectAnnotationArgument -> resolveFromJavaClassObjectType(argument.getReferencedType())
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
private fun resolveFromAnnotation(javaAnnotation: JavaAnnotation): CompileTimeConstant<*>? {
|
||||
val fqName = javaAnnotation.getFqName()
|
||||
if (fqName == null) return null
|
||||
|
||||
if (JavaAnnotationResolver.isSpecialAnnotation(fqName)) {
|
||||
return null
|
||||
}
|
||||
|
||||
return AnnotationValue(LazyJavaAnnotationDescriptor(c, javaAnnotation))
|
||||
}
|
||||
|
||||
private fun resolveFromArray(argumentName: Name, elements: List<JavaAnnotationArgument>): CompileTimeConstant<*>? {
|
||||
if (getType().isError()) return null
|
||||
|
||||
val valueParameter = DescriptorResolverUtils.getAnnotationParameterByName(argumentName, getAnnotationClass())
|
||||
if (valueParameter == null) return null
|
||||
|
||||
val values = elements.map {
|
||||
argument -> resolveAnnotationArgument(argument) ?: NullValue.NULL
|
||||
}
|
||||
return ArrayValue(values, valueParameter.getType())
|
||||
}
|
||||
|
||||
private fun resolveFromReference(element: JavaElement?): CompileTimeConstant<*>? {
|
||||
if (element !is JavaField) return null
|
||||
|
||||
if (!element.isEnumEntry()) return null
|
||||
|
||||
val fqName = element.getContainingClass().getFqName()
|
||||
if (fqName == null) return null
|
||||
|
||||
val enumClass = c.javaClassResolver.resolveClassByFqName(fqName)
|
||||
if (enumClass == null) return null
|
||||
|
||||
val classifier = enumClass.getUnsubstitutedInnerClassesScope().getClassifier(element.getName())
|
||||
if (classifier !is ClassDescriptor) return null
|
||||
|
||||
return EnumValue(classifier)
|
||||
}
|
||||
|
||||
private fun resolveFromJavaClassObjectType(javaType: JavaType): CompileTimeConstant<*>? {
|
||||
val `type` = c.typeResolver.transformJavaType(javaType, TypeUsage.MEMBER_SIGNATURE_INVARIANT)
|
||||
val jlClass = c.javaClassResolver.resolveClassByFqName(JavaAnnotationArgumentResolver.JL_CLASS_FQ_NAME)
|
||||
if (jlClass == null) return null
|
||||
|
||||
val arguments = listOf(TypeProjectionImpl(`type`))
|
||||
|
||||
val javaClassObjectType = object : LazyType(c.storageManager) {
|
||||
override fun computeTypeConstructor() = jlClass.getTypeConstructor()
|
||||
override fun computeArguments() = arguments
|
||||
override fun computeMemberScope() = jlClass.getMemberScope(arguments)
|
||||
}
|
||||
|
||||
return JavaClassValue(javaClassObjectType)
|
||||
}
|
||||
|
||||
|
||||
override fun toString(): String {
|
||||
return DescriptorRenderer.TEXT.renderAnnotation(this)
|
||||
}
|
||||
}
|
||||
+3
-2
@@ -18,6 +18,7 @@ import org.jetbrains.jet.lang.resolve.java.lazy.LazyJavaResolverContextWithTypes
|
||||
import org.jetbrains.jet.lang.resolve.DescriptorFactory
|
||||
import org.jetbrains.jet.lang.resolve.java.lazy.child
|
||||
import org.jetbrains.jet.lang.resolve.java.resolver.TypeUsage
|
||||
import org.jetbrains.jet.lang.resolve.java.lazy.resolveAnnotations
|
||||
|
||||
class LazyJavaClassDescriptor(
|
||||
private val c: LazyJavaResolverContextWithTypes,
|
||||
@@ -63,8 +64,8 @@ class LazyJavaClassDescriptor(
|
||||
|
||||
override fun getClassObjectDescriptor(): ClassDescriptor? = null
|
||||
|
||||
// TODO
|
||||
override fun getAnnotations(): List<AnnotationDescriptor> = Collections.emptyList()
|
||||
private val _annotations = c.resolveAnnotations(jClass.getAnnotations())
|
||||
override fun getAnnotations(): List<AnnotationDescriptor> = _annotations
|
||||
|
||||
private inner class LazyJavaClassTypeConstructor : TypeConstructor {
|
||||
|
||||
|
||||
+4
-3
@@ -20,13 +20,14 @@ import org.jetbrains.jet.lang.resolve.java.structure.JavaClass
|
||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor
|
||||
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor
|
||||
import org.jetbrains.jet.lang.resolve.java.structure.JavaTypeParameter
|
||||
import org.jetbrains.jet.utils.toMap
|
||||
import org.jetbrains.jet.utils.valuesToMap
|
||||
import org.jetbrains.jet.lang.resolve.java.lazy.descriptors.LazyJavaTypeParameterDescriptor
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.jet.lang.resolve.java.lazy.types.LazyJavaTypeResolver
|
||||
import org.jetbrains.jet.lang.resolve.name.FqName
|
||||
|
||||
trait LazyJavaClassResolver {
|
||||
fun resolveClass(javaClass: JavaClass): ClassDescriptor?
|
||||
fun resolveClassByFqName(fqName: FqName): ClassDescriptor?
|
||||
}
|
||||
|
||||
trait TypeParameterResolver {
|
||||
@@ -44,7 +45,7 @@ class TypeParameterResolverImpl(
|
||||
private val parent: TypeParameterResolver = TypeParameterResolver.EMPTY
|
||||
) : TypeParameterResolver {
|
||||
|
||||
private val parameters = _typeParameters.toMap { p -> p.javaTypeParameter }
|
||||
private val parameters = _typeParameters.valuesToMap { p -> p.javaTypeParameter }
|
||||
|
||||
override fun resolveTypeParameter(javaTypeParameter: JavaTypeParameter): TypeParameterDescriptor? {
|
||||
return parameters[javaTypeParameter] ?: parent.resolveTypeParameter(javaTypeParameter)
|
||||
|
||||
Reference in New Issue
Block a user