Object descriptors for enum entries created properly
This commit is contained in:
+17
-6
@@ -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) {
|
||||
|
||||
+7
-18
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user