Annotations on lazy classes are resolved lazily

This commit is contained in:
Andrey Breslav
2014-03-30 09:07:43 +04:00
parent b43958f4b3
commit f0bab0c6d1
3 changed files with 53 additions and 36 deletions
@@ -116,7 +116,7 @@ public class AnnotationResolver {
}
private Annotations resolveAnnotationEntries(
@NotNull JetScope scope,
@NotNull final JetScope scope,
@NotNull List<JetAnnotationEntry> annotationEntryElements,
@NotNull BindingTrace trace,
boolean shouldResolveArguments
@@ -128,15 +128,22 @@ public class AnnotationResolver {
if (descriptor == null) {
if (TopDownAnalyzer.LAZY) {
descriptor = new LazyAnnotationDescriptor(
new LazyAnnotationsContext(this, storageManager, scope, trace),
new LazyAnnotationsContext(this, storageManager, trace) {
@NotNull
@Override
public JetScope getScope() {
return scope;
}
},
entryElement
);
}
else {
descriptor = new AnnotationDescriptorImpl();
((AnnotationDescriptorImpl) descriptor).setAnnotationType(resolveAnnotationType(scope, entryElement));
trace.record(BindingContext.ANNOTATION, entryElement, descriptor);
}
trace.record(BindingContext.ANNOTATION, entryElement, descriptor);
}
if (shouldResolveArguments) {
resolveAnnotationArguments(entryElement, scope, trace);
@@ -218,7 +225,8 @@ public class AnnotationResolver {
) {
AnnotationDescriptor annotationDescriptor = trace.getBindingContext().get(BindingContext.ANNOTATION, annotationEntry);
assert annotationDescriptor != null : "Annotation descriptor should be created before resolving arguments for " + annotationEntry.getText();
if (TopDownAnalyzer.LAZY && annotationDescriptor instanceof LazyAnnotationDescriptor) {
if (annotationDescriptor instanceof LazyAnnotationDescriptor) {
// TopDownAnalyzer.LAZY
((LazyAnnotationDescriptor) annotationDescriptor).forceResolveAllContents();
return;
}
@@ -20,30 +20,31 @@ import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.jet.lang.resolve.name.FqName
import org.jetbrains.jet.lang.descriptors.annotations.Annotations
import org.jetbrains.jet.lang.resolve.lazy.LazyEntity
import org.jetbrains.jet.lang.psi.JetAnnotated
import org.jetbrains.jet.lang.psi.JetAnnotationEntry
import org.jetbrains.jet.lang.resolve.DescriptorUtils
import org.jetbrains.jet.lang.resolve.AnnotationResolver
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant
import org.jetbrains.jet.lang.resolve.lazy.ForceResolveUtil
import org.jetbrains.jet.storage.StorageManager
import org.jetbrains.jet.lang.resolve.scopes.JetScope
import org.jetbrains.jet.lang.resolve.AnnotationResolver
import org.jetbrains.jet.lang.resolve.BindingTrace
import org.jetbrains.jet.lang.resolve.scopes.JetScope
import org.jetbrains.jet.utils.keysToMapExceptNulls
import org.jetbrains.jet.lang.resolve.BindingContext
class LazyAnnotationsContext(
abstract class LazyAnnotationsContext(
val annotationResolver: AnnotationResolver,
val storageManager: StorageManager,
val scope: JetScope,
val trace: BindingTrace
)
) {
abstract val scope: JetScope
}
public class LazyAnnotations(
val c: LazyAnnotationsContext,
val annotatedElement: JetAnnotated
val annotationEntries: List<JetAnnotationEntry>
) : Annotations, LazyEntity {
override fun isEmpty() = annotatedElement.getAnnotationEntries().isEmpty()
override fun isEmpty() = annotationEntries.isEmpty()
val _annotation = c.storageManager.createMemoizedFunction {
(entry: JetAnnotationEntry) ->
@@ -69,7 +70,7 @@ public class LazyAnnotations(
}
override fun iterator(): Iterator<AnnotationDescriptor> {
return annotatedElement.getAnnotationEntries().stream().map(_annotation).iterator()
return annotationEntries.stream().map(_annotation).iterator()
}
override fun forceResolveAllContents() {
@@ -83,6 +84,10 @@ public class LazyAnnotationDescriptor(
val annotationEntry: JetAnnotationEntry
) : AnnotationDescriptor, LazyEntity {
{
c.trace.record(BindingContext.ANNOTATION, annotationEntry, this)
}
private val _resolutionResults = c.storageManager.createLazyValue {
val results = c.annotationResolver.resolveAnnotationCall(
annotationEntry,
@@ -76,7 +76,7 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes
private final ClassKind kind;
private final boolean isInner;
private final NotNullLazyValue<Annotations> annotations;
private final Annotations annotations;
private final NullableLazyValue<ClassDescriptorWithResolutionScopes> classObjectDescriptor;
private final LazyClassMemberScope unsubstitutedMemberScope;
@@ -88,7 +88,7 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes
private final NullableLazyValue<Void> forceResolveAllContents;
public LazyClassDescriptor(
@NotNull ResolveSession resolveSession,
@NotNull final ResolveSession resolveSession,
@NotNull DeclarationDescriptor containingDeclaration,
@NotNull Name name,
@NotNull JetClassLikeInfo classLikeInfo
@@ -124,12 +124,30 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes
this.isInner = isInnerClass(modifierList);
StorageManager storageManager = resolveSession.getStorageManager();
this.annotations = storageManager.createLazyValue(new Function0<Annotations>() {
@Override
public Annotations invoke() {
return resolveAnnotations();
}
});
if (modifierList != null) {
this.annotations = new LazyAnnotations(
new LazyAnnotationsContext(
resolveSession.getAnnotationResolver(),
resolveSession.getStorageManager(),
resolveSession.getTrace()
) {
@NotNull
@Override
public JetScope getScope() {
JetClassLikeInfo ownerInfo = declarationProvider.getOwnerInfo();
return resolveSession.getScopeProvider().getResolutionScopeForDeclaration(ownerInfo.getScopeAnchor());
}
},
modifierList.getAnnotationEntries()
);
}
else {
this.annotations = Annotations.EMPTY;
}
this.classObjectDescriptor = storageManager.createNullableLazyValue(new Function0<ClassDescriptorWithResolutionScopes>() {
@Override
public ClassDescriptorWithResolutionScopes invoke() {
@@ -341,21 +359,7 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes
@NotNull
@Override
public Annotations getAnnotations() {
return annotations.invoke();
}
@NotNull
private Annotations resolveAnnotations() {
JetClassLikeInfo classInfo = declarationProvider.getOwnerInfo();
JetModifierList modifierList = classInfo.getModifierList();
if (modifierList != null) {
AnnotationResolver annotationResolver = resolveSession.getAnnotationResolver();
JetScope scopeForDeclaration = getScopeProvider().getResolutionScopeForDeclaration(classInfo.getScopeAnchor());
return annotationResolver.resolveAnnotationsWithArguments(scopeForDeclaration, modifierList, resolveSession.getTrace());
}
else {
return Annotations.EMPTY;
}
return annotations;
}
@Override