Object descriptors for enum entries created properly

This commit is contained in:
Andrey Breslav
2012-08-09 15:44:18 +04:00
parent 56414e90b3
commit 8dd9225411
4 changed files with 36 additions and 49 deletions
@@ -69,10 +69,11 @@ public abstract class AbstractLazyMemberScope<D extends DeclarationDescriptor, D
JetClassOrObject classOrObjectDeclaration = declarationProvider.getClassOrObjectDeclaration(name);
if (classOrObjectDeclaration == null) return null;
if (object != classOrObjectDeclaration instanceof JetObjectDeclaration) return null;
// TODO: when enum entries with constructors are dropped, replace with declaresObjectOrEnumConstant()
if (object != mayDeclareObject(classOrObjectDeclaration)) return null;
ClassDescriptor classDescriptor = new LazyClassDescriptor(resolveSession, thisDescriptor, name,
JetClassInfoUtil.createClassLikeInfo(classOrObjectDeclaration));
JetClassInfoUtil.createClassLikeInfo(classOrObjectDeclaration));
cache.put(name, classDescriptor);
if (!object) {
@@ -82,6 +83,17 @@ public abstract class AbstractLazyMemberScope<D extends DeclarationDescriptor, D
return classDescriptor;
}
private static boolean mayDeclareObject(JetClassOrObject declaration) {
return declaration instanceof JetObjectDeclaration || declaration instanceof JetEnumEntry;
}
protected static boolean declaresObjectOrEnumConstant(JetClassOrObject declaration) {
if (declaration instanceof JetObjectDeclaration) {
return true;
}
return declaration instanceof JetEnumEntry && !declaration.hasPrimaryConstructor();
}
@Override
public ClassifierDescriptor getClassifier(@NotNull Name name) {
return getClassOrObjectDescriptor(classDescriptors, name, false);
@@ -89,7 +101,6 @@ public abstract class AbstractLazyMemberScope<D extends DeclarationDescriptor, D
@Override
public ClassDescriptor getObjectDescriptor(@NotNull Name name) {
// TODO: We shouldn't really allow objects in classes...
return getClassOrObjectDescriptor(objectDescriptors, name, true);
}
@@ -147,14 +158,13 @@ public abstract class AbstractLazyMemberScope<D extends DeclarationDescriptor, D
// Objects are also properties
JetClassOrObject classOrObjectDeclaration = declarationProvider.getClassOrObjectDeclaration(name);
if (classOrObjectDeclaration instanceof JetObjectDeclaration) {
JetObjectDeclaration objectDeclaration = (JetObjectDeclaration) classOrObjectDeclaration;
if (declaresObjectOrEnumConstant(classOrObjectDeclaration)) {
ClassDescriptor classifier = getObjectDescriptor(name);
if (classifier == null) {
throw new IllegalStateException("Object declaration " + name + " found in the DeclarationProvider " + declarationProvider + " but not in the scope " + this);
}
VariableDescriptor propertyDescriptor = resolveSession.getInjector().getDescriptorResolver()
.resolveObjectDeclaration(thisDescriptor, objectDeclaration, classifier, resolveSession.getTrace());
.resolveObjectDeclaration(thisDescriptor, classOrObjectDeclaration, classifier, resolveSession.getTrace());
result.add(propertyDescriptor);
}
@@ -209,6 +219,7 @@ public abstract class AbstractLazyMemberScope<D extends DeclarationDescriptor, D
Name name = jetEnumEntry.getNameAsName();
if (name != null) {
getProperties(name);
getObjectDescriptor(name);
}
}
else if (declaration instanceof JetObjectDeclaration) {
@@ -182,22 +182,6 @@ public class LazyClassMemberScope extends AbstractLazyMemberScope<LazyClassDescr
}
}
// 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()) {
@@ -264,9 +248,14 @@ public class LazyClassMemberScope extends AbstractLazyMemberScope<LazyClassDescr
@Nullable
public ConstructorDescriptor getPrimaryConstructor() {
if (!primaryConstructorResolved) {
if (EnumSet.of(ClassKind.CLASS, ClassKind.ANNOTATION_CLASS, ClassKind.OBJECT, ClassKind.ENUM_CLASS).contains(thisDescriptor.getKind())) {
Set<ClassKind> generateConstructorsFor =
EnumSet.of(ClassKind.CLASS, ClassKind.ANNOTATION_CLASS, ClassKind.OBJECT, ClassKind.ENUM_CLASS, ClassKind.ENUM_ENTRY);
if (generateConstructorsFor.contains(thisDescriptor.getKind())) {
JetClassOrObject classOrObject = declarationProvider.getOwnerInfo().getCorrespondingClassOrObject();
if (thisDescriptor.getKind() != ClassKind.OBJECT) {
if (
thisDescriptor.getKind() != ClassKind.OBJECT // a fake class object of an enum class
&& !declaresObjectOrEnumConstant(classOrObject) // normal objects and enum entries with no constructors
) {
JetClass jetClass = (JetClass) classOrObject;
ConstructorDescriptorImpl constructor = resolveSession.getInjector().getDescriptorResolver()
.resolvePrimaryConstructorDescriptor(thisDescriptor.getScopeForClassHeaderResolution(),
@@ -18,7 +18,6 @@ package org.jetbrains.jet.lang.resolve.lazy;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.Maps;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import com.intellij.psi.util.PsiTreeUtil;
@@ -32,7 +31,6 @@ 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;
@@ -40,7 +38,6 @@ 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
@@ -66,7 +63,6 @@ public class ResolveSession {
private final InjectorForLazyResolve injector;
private final ModuleConfiguration moduleConfiguration;
private final Map<JetEnumEntry, ClassDescriptor> enumEntryClassDescriptorCache = Maps.newHashMap();
private final Function<FqName, Name> classifierAliases;
public ResolveSession(
@@ -136,10 +132,6 @@ 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());
}
@@ -147,29 +139,15 @@ public class ResolveSession {
Name name = classOrObject.getNameAsName();
assert name != null : "Name is null for " + classOrObject + " " + classOrObject.getText();
ClassifierDescriptor classifier = resolutionScope.getClassifier(name);
if (classifier == null) {
classifier = resolutionScope.getObjectDescriptor(name);
}
if (classifier == null) {
throw new IllegalArgumentException("Could not find a classifier for " + classOrObject + " " + classOrObject.getText());
}
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();
@@ -6,5 +6,14 @@ internal final enum class test.Test : jet.Any {
internal final /*constructor*/ fun <init>(): test.Test.<class-object-for-Test>
internal final val A: test.Test.<class-object-for-Test>.A
internal final val C: test.Test.<class-object-for-Test>.C
internal final enum entry test.Test.<class-object-for-Test>.A : test.Test {
internal final /*constructor*/ fun <init>(): test.Test.<class-object-for-Test>.A
}
internal final enum entry test.Test.<class-object-for-Test>.B : test.Test {
public final /*constructor*/ fun <init>(/*0*/ x: jet.Int): test.Test.<class-object-for-Test>.B
}
internal final enum entry test.Test.<class-object-for-Test>.C : test.Test {
internal final /*constructor*/ fun <init>(): test.Test.<class-object-for-Test>.C
}
}
}