Lazy resolve of enum entries
This commit is contained in:
+8
-5
@@ -150,10 +150,6 @@ public abstract class AbstractLazyMemberScope<D extends DeclarationDescriptor, D
|
||||
.resolveObjectDeclaration(thisDescriptor, objectDeclaration, classifier, resolveSession.getTrace());
|
||||
result.add(propertyDescriptor);
|
||||
}
|
||||
else if (classOrObjectDeclaration instanceof JetEnumEntry) {
|
||||
JetEnumEntry jetEnumEntry = (JetEnumEntry) classOrObjectDeclaration;
|
||||
throw new UnsupportedOperationException("Enums are not supported yet: " + jetEnumEntry + " " + jetEnumEntry.getText());
|
||||
}
|
||||
|
||||
getNonDeclaredProperties(name, result);
|
||||
|
||||
@@ -198,7 +194,14 @@ public abstract class AbstractLazyMemberScope<D extends DeclarationDescriptor, D
|
||||
@Override
|
||||
public Collection<DeclarationDescriptor> 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) {
|
||||
|
||||
@@ -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<? extends JetParameter> getPrimaryConstructorParameters() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
+53
-31
@@ -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<LazyClassDescr
|
||||
new OverrideResolver.DescriptorSink() {
|
||||
@Override
|
||||
public void addToScope(@NotNull CallableMemberDescriptor fakeOverride) {
|
||||
assert exactDescriptorClass.isInstance(fakeOverride) : "Wrong descriptor type in an override: " + fakeOverride + " while expecting " + exactDescriptorClass.getSimpleName();
|
||||
assert exactDescriptorClass.isInstance(fakeOverride) : "Wrong descriptor type in an override: " +
|
||||
fakeOverride +
|
||||
" while expecting " +
|
||||
exactDescriptorClass.getSimpleName();
|
||||
//noinspection unchecked
|
||||
result.add((D) fakeOverride);
|
||||
}
|
||||
@@ -83,7 +87,8 @@ public class LazyClassMemberScope extends AbstractLazyMemberScope<LazyClassDescr
|
||||
JetDeclaration declaration = (JetDeclaration) BindingContextUtils.descriptorToDeclaration(trace.getBindingContext(),
|
||||
fromCurrent);
|
||||
assert declaration != null : "fromCurrent can not be a fake override";
|
||||
trace.report(Errors.CONFLICTING_OVERLOADS.on(declaration, fromCurrent, fromCurrent.getContainingDeclaration().getName().getName()));
|
||||
trace.report(Errors.CONFLICTING_OVERLOADS
|
||||
.on(declaration, fromCurrent, fromCurrent.getContainingDeclaration().getName().getName()));
|
||||
}
|
||||
}
|
||||
);
|
||||
@@ -131,31 +136,47 @@ public class LazyClassMemberScope extends AbstractLazyMemberScope<LazyClassDescr
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
protected void getNonDeclaredProperties(@NotNull Name name, @NotNull final Set<VariableDescriptor> result) {
|
||||
JetClassOrObject classOrObject = declarationProvider.getOwnerClassOrObject();
|
||||
if (classOrObject instanceof JetClass) {
|
||||
JetClass jetClass = (JetClass) classOrObject;
|
||||
JetClassLikeInfo classInfo = declarationProvider.getOwnerInfo();
|
||||
|
||||
ConstructorDescriptor primaryConstructor = getPrimaryConstructor();
|
||||
if (primaryConstructor != null) {
|
||||
List<ValueParameterDescriptor> valueParameterDescriptors = primaryConstructor.getValueParameters();
|
||||
List<JetParameter> 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<ValueParameterDescriptor> valueParameterDescriptors = primaryConstructor.getValueParameters();
|
||||
List<? extends JetParameter> 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<PropertyDescriptor> 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<LazyClassDescr
|
||||
@Nullable
|
||||
public ConstructorDescriptor getPrimaryConstructor() {
|
||||
if (!primaryConstructorResolved) {
|
||||
if (EnumSet.of(ClassKind.CLASS, ClassKind.ANNOTATION_CLASS, ClassKind.OBJECT).contains(thisDescriptor.getKind())) {
|
||||
JetClassOrObject classOrObject = declarationProvider.getOwnerClassOrObject();
|
||||
if (classOrObject instanceof JetClass) {
|
||||
if (EnumSet.of(ClassKind.CLASS, ClassKind.ANNOTATION_CLASS, ClassKind.OBJECT, ClassKind.ENUM_CLASS).contains(thisDescriptor.getKind())) {
|
||||
JetClassOrObject classOrObject = declarationProvider.getOwnerInfo().getCorrespondingClassOrObject();
|
||||
if (thisDescriptor.getKind() != ClassKind.OBJECT) {
|
||||
JetClass jetClass = (JetClass) classOrObject;
|
||||
ConstructorDescriptorImpl constructor = resolveSession.getInjector().getDescriptorResolver()
|
||||
.resolvePrimaryConstructorDescriptor(thisDescriptor.getScopeForClassHeaderResolution(), thisDescriptor,
|
||||
.resolvePrimaryConstructorDescriptor(thisDescriptor.getScopeForClassHeaderResolution(),
|
||||
thisDescriptor,
|
||||
jetClass,
|
||||
resolveSession.getTrace());
|
||||
primaryConstructor = constructor;
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.jetbrains.jet.lang.resolve.lazy;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
@@ -28,6 +29,7 @@ import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.BindingTrace;
|
||||
import org.jetbrains.jet.lang.resolve.BindingTraceContext;
|
||||
import org.jetbrains.jet.lang.resolve.lazy.data.JetClassInfoUtil;
|
||||
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||
import org.jetbrains.jet.lang.resolve.name.FqNameUnsafe;
|
||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
@@ -35,6 +37,7 @@ import org.jetbrains.jet.lang.resolve.scopes.InnerClassesScopeWrapper;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
@@ -49,6 +52,8 @@ public class ResolveSession {
|
||||
private final InjectorForLazyResolve injector;
|
||||
private final ModuleConfiguration moduleConfiguration;
|
||||
|
||||
private final Map<JetEnumEntry, ClassDescriptor> 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();
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user