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.descriptors.DeclarationDescriptor
|
||||||
import org.jetbrains.jet.lang.resolve.java.structure.JavaTypeParameter
|
import org.jetbrains.jet.lang.resolve.java.structure.JavaTypeParameter
|
||||||
import org.jetbrains.jet.lang.resolve.java.JavaClassFinder
|
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(
|
open class LazyJavaResolverContext(
|
||||||
val storageManager: StorageManager,
|
val storageManager: StorageManager,
|
||||||
@@ -48,4 +51,7 @@ class LazyJavaResolverContextWithTypes(
|
|||||||
fun LazyJavaResolverContextWithTypes.child(
|
fun LazyJavaResolverContextWithTypes.child(
|
||||||
containingDeclaration: DeclarationDescriptor,
|
containingDeclaration: DeclarationDescriptor,
|
||||||
typeParameters: Set<JavaTypeParameter>
|
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.DescriptorFactory
|
||||||
import org.jetbrains.jet.lang.resolve.java.lazy.child
|
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.resolver.TypeUsage
|
||||||
|
import org.jetbrains.jet.lang.resolve.java.lazy.resolveAnnotations
|
||||||
|
|
||||||
class LazyJavaClassDescriptor(
|
class LazyJavaClassDescriptor(
|
||||||
private val c: LazyJavaResolverContextWithTypes,
|
private val c: LazyJavaResolverContextWithTypes,
|
||||||
@@ -63,8 +64,8 @@ class LazyJavaClassDescriptor(
|
|||||||
|
|
||||||
override fun getClassObjectDescriptor(): ClassDescriptor? = null
|
override fun getClassObjectDescriptor(): ClassDescriptor? = null
|
||||||
|
|
||||||
// TODO
|
private val _annotations = c.resolveAnnotations(jClass.getAnnotations())
|
||||||
override fun getAnnotations(): List<AnnotationDescriptor> = Collections.emptyList()
|
override fun getAnnotations(): List<AnnotationDescriptor> = _annotations
|
||||||
|
|
||||||
private inner class LazyJavaClassTypeConstructor : TypeConstructor {
|
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.ClassDescriptor
|
||||||
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor
|
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor
|
||||||
import org.jetbrains.jet.lang.resolve.java.structure.JavaTypeParameter
|
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.resolve.java.lazy.descriptors.LazyJavaTypeParameterDescriptor
|
||||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor
|
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 {
|
trait LazyJavaClassResolver {
|
||||||
fun resolveClass(javaClass: JavaClass): ClassDescriptor?
|
fun resolveClass(javaClass: JavaClass): ClassDescriptor?
|
||||||
|
fun resolveClassByFqName(fqName: FqName): ClassDescriptor?
|
||||||
}
|
}
|
||||||
|
|
||||||
trait TypeParameterResolver {
|
trait TypeParameterResolver {
|
||||||
@@ -44,7 +45,7 @@ class TypeParameterResolverImpl(
|
|||||||
private val parent: TypeParameterResolver = TypeParameterResolver.EMPTY
|
private val parent: TypeParameterResolver = TypeParameterResolver.EMPTY
|
||||||
) : TypeParameterResolver {
|
) : TypeParameterResolver {
|
||||||
|
|
||||||
private val parameters = _typeParameters.toMap { p -> p.javaTypeParameter }
|
private val parameters = _typeParameters.valuesToMap { p -> p.javaTypeParameter }
|
||||||
|
|
||||||
override fun resolveTypeParameter(javaTypeParameter: JavaTypeParameter): TypeParameterDescriptor? {
|
override fun resolveTypeParameter(javaTypeParameter: JavaTypeParameter): TypeParameterDescriptor? {
|
||||||
return parameters[javaTypeParameter] ?: parent.resolveTypeParameter(javaTypeParameter)
|
return parameters[javaTypeParameter] ?: parent.resolveTypeParameter(javaTypeParameter)
|
||||||
|
|||||||
+2
@@ -2,6 +2,7 @@ package org.jetbrains.jet.lang.descriptors.annotations;
|
|||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.jetbrains.annotations.ReadOnly;
|
||||||
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
|
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
|
||||||
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
|
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
|
||||||
import org.jetbrains.jet.lang.types.JetType;
|
import org.jetbrains.jet.lang.types.JetType;
|
||||||
@@ -16,5 +17,6 @@ public interface AnnotationDescriptor {
|
|||||||
CompileTimeConstant<?> getValueArgument(@NotNull ValueParameterDescriptor valueParameterDescriptor);
|
CompileTimeConstant<?> getValueArgument(@NotNull ValueParameterDescriptor valueParameterDescriptor);
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
|
@ReadOnly
|
||||||
Map<ValueParameterDescriptor, CompileTimeConstant<?>> getAllValueArguments();
|
Map<ValueParameterDescriptor, CompileTimeConstant<?>> getAllValueArguments();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,10 +18,29 @@ package org.jetbrains.jet.utils
|
|||||||
|
|
||||||
import java.util.LinkedHashMap
|
import java.util.LinkedHashMap
|
||||||
|
|
||||||
public fun <K, V> Iterable<V>.toMap(key: (V) -> K): Map<K, V> {
|
public fun <K, V> Iterable<V>.valuesToMap(key: (V) -> K): Map<K, V> {
|
||||||
val map = LinkedHashMap<K, V>()
|
val map = LinkedHashMap<K, V>()
|
||||||
for (v in this) {
|
for (v in this) {
|
||||||
map[key(v)] = v
|
map[key(v)] = v
|
||||||
}
|
}
|
||||||
return map
|
return map
|
||||||
|
}
|
||||||
|
|
||||||
|
public fun <K, V> Iterable<K>.keysToMap(value: (K) -> V): Map<K, V> {
|
||||||
|
val map = LinkedHashMap<K, V>()
|
||||||
|
for (k in this) {
|
||||||
|
map[k] = value(k)
|
||||||
|
}
|
||||||
|
return map
|
||||||
|
}
|
||||||
|
|
||||||
|
public fun <K, V: Any> Iterable<K>.keysToMapExceptNulls(value: (K) -> V?): Map<K, V> {
|
||||||
|
val map = LinkedHashMap<K, V>()
|
||||||
|
for (k in this) {
|
||||||
|
val v = value(k)
|
||||||
|
if (v != null) {
|
||||||
|
map[k] = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return map
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user