From 2c688a5e3c41f96d40b1fde6c0550c51b75190d5 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Mon, 25 Jun 2012 17:59:30 +0200 Subject: [PATCH] Lazy resolve of enum entries --- .../resolve/lazy/AbstractLazyMemberScope.java | 13 +-- .../resolve/lazy/LazyClassDescriptor.java | 11 +++ .../resolve/lazy/LazyClassMemberScope.java | 84 ++++++++++++------- .../jet/lang/resolve/lazy/ResolveSession.java | 26 ++++++ .../jet/lang/resolve/lazy/ScopeProvider.java | 3 + .../resolve/lazy/data/JetClassInfoUtil.java | 7 -- 6 files changed, 101 insertions(+), 43 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/AbstractLazyMemberScope.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/AbstractLazyMemberScope.java index 5daadd96668..b83bbe2ef13 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/AbstractLazyMemberScope.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/AbstractLazyMemberScope.java @@ -150,10 +150,6 @@ public abstract class AbstractLazyMemberScope getAllDescriptors() { for (JetDeclaration declaration : declarationProvider.getAllDeclarations()) { - if (declaration instanceof JetClassOrObject) { + if (declaration instanceof JetEnumEntry) { + JetEnumEntry jetEnumEntry = (JetEnumEntry) declaration; + Name name = jetEnumEntry.getNameAsName(); + if (name != null) { + getProperties(name); + } + } + else if (declaration instanceof JetClassOrObject) { JetClassOrObject classOrObject = (JetClassOrObject) declaration; Name name = classOrObject.getNameAsName(); if (name != null) { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyClassDescriptor.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyClassDescriptor.java index dddd075a302..c452f039d21 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyClassDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyClassDescriptor.java @@ -316,11 +316,22 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes private static JetClassLikeInfo onlyEnumEntries(JetClassLikeInfo classLikeInfo) { return new FilteringClassLikeInfo(classLikeInfo, ONLY_ENUM_ENTIRES) { + @Override + public JetClassOrObject getCorrespondingClassOrObject() { + return null; + } + @NotNull @Override public ClassKind getClassKind() { return ClassKind.OBJECT; } + + @NotNull + @Override + public List getPrimaryConstructorParameters() { + return Collections.emptyList(); + } }; } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyClassMemberScope.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyClassMemberScope.java index 673ce10e83a..5a29b9ef577 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyClassMemberScope.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyClassMemberScope.java @@ -22,11 +22,12 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.diagnostics.Errors; -import org.jetbrains.jet.lang.psi.JetClass; -import org.jetbrains.jet.lang.psi.JetClassOrObject; -import org.jetbrains.jet.lang.psi.JetDeclaration; -import org.jetbrains.jet.lang.psi.JetParameter; -import org.jetbrains.jet.lang.resolve.*; +import org.jetbrains.jet.lang.psi.*; +import org.jetbrains.jet.lang.resolve.BindingContextUtils; +import org.jetbrains.jet.lang.resolve.BindingTrace; +import org.jetbrains.jet.lang.resolve.DescriptorResolver; +import org.jetbrains.jet.lang.resolve.OverrideResolver; +import org.jetbrains.jet.lang.resolve.lazy.data.JetClassLikeInfo; import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; @@ -72,7 +73,10 @@ public class LazyClassMemberScope extends AbstractLazyMemberScope result) { - JetClassOrObject classOrObject = declarationProvider.getOwnerClassOrObject(); - if (classOrObject instanceof JetClass) { - JetClass jetClass = (JetClass) classOrObject; + JetClassLikeInfo classInfo = declarationProvider.getOwnerInfo(); - ConstructorDescriptor primaryConstructor = getPrimaryConstructor(); - if (primaryConstructor != null) { - List valueParameterDescriptors = primaryConstructor.getValueParameters(); - List primaryConstructorParameters = jetClass.getPrimaryConstructorParameters(); - assert valueParameterDescriptors.size() == primaryConstructorParameters.size(); - for (ValueParameterDescriptor valueParameterDescriptor : valueParameterDescriptors) { - JetParameter parameter = primaryConstructorParameters.get(valueParameterDescriptor.getIndex()); - if (parameter.getValOrVarNode() != null && name.equals(parameter.getNameAsName())) { - PropertyDescriptor propertyDescriptor = - resolveSession.getInjector().getDescriptorResolver().resolvePrimaryConstructorParameterToAProperty( - thisDescriptor, - valueParameterDescriptor, - thisDescriptor.getScopeForClassHeaderResolution(), - parameter, resolveSession.getTrace() - ); - result.add(propertyDescriptor); - } + // From primary constructor parameters + ConstructorDescriptor primaryConstructor = getPrimaryConstructor(); + if (primaryConstructor != null) { + List valueParameterDescriptors = primaryConstructor.getValueParameters(); + List primaryConstructorParameters = classInfo.getPrimaryConstructorParameters(); + assert valueParameterDescriptors.size() == primaryConstructorParameters.size() : "From descriptor: " + valueParameterDescriptors.size() + " but from PSI: " + primaryConstructorParameters.size(); + for (ValueParameterDescriptor valueParameterDescriptor : valueParameterDescriptors) { + JetParameter parameter = primaryConstructorParameters.get(valueParameterDescriptor.getIndex()); + if (parameter.getValOrVarNode() != null && name.equals(parameter.getNameAsName())) { + PropertyDescriptor propertyDescriptor = + resolveSession.getInjector().getDescriptorResolver().resolvePrimaryConstructorParameterToAProperty( + thisDescriptor, + valueParameterDescriptor, + thisDescriptor.getScopeForClassHeaderResolution(), + parameter, resolveSession.getTrace() + ); + result.add(propertyDescriptor); } } } + // Enum entries + JetClassOrObject classOrObjectDeclaration = declarationProvider.getClassOrObjectDeclaration(name); + if (classOrObjectDeclaration instanceof JetEnumEntry) { + // TODO: This code seems to be wrong, but it mimics the present behavior of eager resolve + JetEnumEntry jetEnumEntry = (JetEnumEntry) classOrObjectDeclaration; + if (!jetEnumEntry.hasPrimaryConstructor()) { + VariableDescriptor propertyDescriptor = resolveSession.getInjector().getDescriptorResolver() + .resolveObjectDeclarationAsPropertyDescriptor(thisDescriptor, + jetEnumEntry, + resolveSession.getClassDescriptor(jetEnumEntry), + resolveSession.getTrace()); + result.add(propertyDescriptor); + } + + } + + + // Members from supertypes Collection fromSupertypes = Lists.newArrayList(); for (JetType supertype : thisDescriptor.getTypeConstructor().getSupertypes()) { fromSupertypes.addAll((Set) supertype.getMemberScope().getProperties(name)); @@ -198,12 +219,13 @@ public class LazyClassMemberScope extends AbstractLazyMemberScope enumEntryClassDescriptorCache = Maps.newHashMap(); + public ResolveSession( @NotNull Project project, @NotNull ModuleDescriptor rootDescriptor, @@ -98,6 +103,10 @@ public class ResolveSession { @NotNull public ClassDescriptor getClassDescriptor(@NotNull JetClassOrObject classOrObject) { + if (classOrObject instanceof JetEnumEntry) { + JetEnumEntry enumEntry = (JetEnumEntry) classOrObject; + return getEnumEntryClassDescriptor(enumEntry); + } if (classOrObject.getParent() instanceof JetClassObject) { return getClassObjectDescriptor((JetClassObject) classOrObject.getParent()); } @@ -108,6 +117,23 @@ public class ResolveSession { return (ClassDescriptor) classifier; } + @NotNull + private ClassDescriptor getEnumEntryClassDescriptor(@NotNull JetEnumEntry jetEnumEntry) { + ClassDescriptor classDescriptor = enumEntryClassDescriptorCache.get(jetEnumEntry); + if (classDescriptor != null) { + return classDescriptor; + } + + DeclarationDescriptor containingDeclaration = getInjector().getScopeProvider().getResolutionScopeForDeclaration(jetEnumEntry) + .getContainingDeclaration(); + LazyClassDescriptor newClassDescriptor = new LazyClassDescriptor(this, + containingDeclaration, + jetEnumEntry.getNameAsName(), + JetClassInfoUtil.createClassLikeInfo(jetEnumEntry)); + enumEntryClassDescriptorCache.put(jetEnumEntry, newClassDescriptor); + return newClassDescriptor; + } + /*package*/ LazyClassDescriptor getClassObjectDescriptor(JetClassObject classObject) { LazyClassDescriptor classDescriptor = (LazyClassDescriptor) getClassDescriptor(PsiTreeUtil.getParentOfType(classObject, JetClass.class)); LazyClassDescriptor classObjectDescriptor = (LazyClassDescriptor) classDescriptor.getClassObjectDescriptor(); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ScopeProvider.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ScopeProvider.java index f7a1d3594da..38ddbe25f13 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ScopeProvider.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ScopeProvider.java @@ -86,6 +86,9 @@ public class ScopeProvider { if (parentDeclaration instanceof JetClassOrObject) { JetClassOrObject classOrObject = (JetClassOrObject) parentDeclaration; LazyClassDescriptor classDescriptor = (LazyClassDescriptor) resolveSession.getClassDescriptor(classOrObject); + if (jetDeclaration instanceof JetEnumEntry) { + return ((LazyClassDescriptor) classDescriptor.getClassObjectDescriptor()).getScopeForMemberDeclarationResolution(); + } return classDescriptor.getScopeForMemberDeclarationResolution(); } else if (parentDeclaration instanceof JetClassObject) { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/data/JetClassInfoUtil.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/data/JetClassInfoUtil.java index 095799389b3..57b4ef3fb87 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/data/JetClassInfoUtil.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/data/JetClassInfoUtil.java @@ -19,7 +19,6 @@ package org.jetbrains.jet.lang.resolve.lazy.data; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.psi.JetClass; import org.jetbrains.jet.lang.psi.JetClassOrObject; -import org.jetbrains.jet.lang.psi.JetEnumEntry; import org.jetbrains.jet.lang.psi.JetObjectDeclaration; /** @@ -28,12 +27,6 @@ import org.jetbrains.jet.lang.psi.JetObjectDeclaration; public class JetClassInfoUtil { public static JetClassLikeInfo createClassLikeInfo(@NotNull JetClassOrObject classOrObject) { - if (classOrObject instanceof JetEnumEntry) { - JetEnumEntry jetEnumEntry = (JetEnumEntry) classOrObject; - if (!jetEnumEntry.hasPrimaryConstructor()) { - return new JetObjectInfo(jetEnumEntry); - } - } if (classOrObject instanceof JetClass) { JetClass jetClass = (JetClass) classOrObject; return new JetClassInfo(jetClass);