diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/annotationUtils.kt b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/annotationUtils.kt index 846f4263fcb..a207ae64678 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/annotationUtils.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/annotationUtils.kt @@ -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): 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() - } - 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 + = 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 diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaClassDescriptor.kt b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaClassDescriptor.kt index d93f5f7d8bf..49e17004d7c 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaClassDescriptor.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaClassDescriptor.kt @@ -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 { diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaMemberScope.kt b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaMemberScope.kt index e059bd555e0..e26532d6577 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaMemberScope.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaMemberScope.kt @@ -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)