Java annotation resolution made lazy

This commit is contained in:
Andrey Breslav
2014-01-22 18:05:40 +04:00
parent 7d10cfa4a5
commit ca7d5a2988
3 changed files with 30 additions and 15 deletions
@@ -21,20 +21,35 @@ import org.jetbrains.jet.lang.resolve.java.structure.JavaAnnotationOwner
import org.jetbrains.jet.lang.resolve.name.FqName
import org.jetbrains.jet.lang.resolve.java.resolver.JavaAnnotationResolver
import org.jetbrains.jet.lang.descriptors.annotations.Annotations
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationsImpl
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.jet.lang.resolve.java.lazy.descriptors.LazyJavaAnnotationDescriptor
fun LazyJavaResolverContextWithTypes.resolveAnnotations(javaAnnotations: Collection<JavaAnnotation>): Annotations
= AnnotationsImpl(javaAnnotations.flatMap {
jAnnotation ->
// TODO: we resolve all annotations, which slightly compromises our laziness
val fqName = jAnnotation.getFqName()
if (fqName == null || JavaAnnotationResolver.isSpecialAnnotation(fqName)) {
listOf<AnnotationDescriptor>()
}
else listOf(LazyJavaAnnotationDescriptor(this, jAnnotation))
})
class LazyJavaAnnotations(c: LazyJavaResolverContextWithTypes, val annotationOwner: JavaAnnotationOwner) : Annotations {
private val annotationDescriptors = c.storageManager.createMemoizedFunctionWithNullableValues {
(jAnnotation: JavaAnnotation) ->
val fqName = jAnnotation.getFqName()
if (fqName == null || JavaAnnotationResolver.isSpecialAnnotation(fqName)) {
null
}
else LazyJavaAnnotationDescriptor(c, jAnnotation)
}
override fun findAnnotation(fqName: FqName): AnnotationDescriptor? {
val jAnnotation = annotationOwner.findAnnotation(fqName)
if (jAnnotation == null) return null
return annotationDescriptors(jAnnotation)
}
[suppress("UNCHECKED_CAST")] // any iterator can be cast to MutableIterator
override fun iterator(): MutableIterator<AnnotationDescriptor>
= annotationOwner.getAnnotations().iterator().map { annotationDescriptors(it) }.filterNotNull() as MutableIterator
override fun isEmpty() = iterator().hasNext()
}
fun LazyJavaResolverContextWithTypes.resolveAnnotations(annotationsOwner: JavaAnnotationOwner): Annotations
= LazyJavaAnnotations(this, annotationsOwner)
private fun GlobalJavaResolverContext.hasAnnotation(owner: JavaAnnotationOwner, annotationFqName: FqName): Boolean
= owner.findAnnotation(annotationFqName) != null || externalAnnotationResolver.findExternalAnnotation(owner, annotationFqName) != null
@@ -93,7 +93,7 @@ class LazyJavaClassDescriptor(
override fun getConstructors() = _scopeForMemberLookup._constructors()
private val _annotations = c.storageManager.createLazyValue { c.resolveAnnotations(jClass.getAnnotations()) }
private val _annotations = c.storageManager.createLazyValue { c.resolveAnnotations(jClass) }
override fun getAnnotations() = _annotations()
private val _functionTypeForSamInterface = c.storageManager.createNullableLazyValue {
@@ -102,7 +102,7 @@ public abstract class LazyJavaMemberScope(
internal fun resolveMethodToFunctionDescriptor(method: JavaMethod, record: Boolean = true): SimpleFunctionDescriptor {
val functionDescriptorImpl = JavaMethodDescriptor(_containingDeclaration, c.resolveAnnotations(method.getAnnotations()), method.getName())
val functionDescriptorImpl = JavaMethodDescriptor(_containingDeclaration, c.resolveAnnotations(method), method.getName())
val c = c.child(functionDescriptorImpl, method.getTypeParameters().toSet())
@@ -194,7 +194,7 @@ public abstract class LazyJavaMemberScope(
ValueParameterDescriptorImpl(
function,
index,
c.resolveAnnotations(javaParameter.getAnnotations()),
c.resolveAnnotations(javaParameter),
// TODO: parameter names may be drawn from attached sources, which is slow; it's better to make them lazy
javaParameter.getName() ?: Name.identifier("p$index"),
outType,
@@ -251,7 +251,7 @@ public abstract class LazyJavaMemberScope(
private fun createPropertyDescriptor(field: JavaField): PropertyDescriptorImpl {
val isVar = !field.isFinal()
val visibility = field.getVisibility()
val annotations = c.resolveAnnotations(field.getAnnotations())
val annotations = c.resolveAnnotations(field)
val propertyName = field.getName()
return JavaPropertyDescriptor(_containingDeclaration, annotations, visibility, isVar, propertyName)