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);
|
JetClassOrObject classOrObjectDeclaration = declarationProvider.getClassOrObjectDeclaration(name);
|
||||||
if (classOrObjectDeclaration == null) return null;
|
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,
|
ClassDescriptor classDescriptor = new LazyClassDescriptor(resolveSession, thisDescriptor, name,
|
||||||
JetClassInfoUtil.createClassLikeInfo(classOrObjectDeclaration));
|
JetClassInfoUtil.createClassLikeInfo(classOrObjectDeclaration));
|
||||||
|
|
||||||
cache.put(name, classDescriptor);
|
cache.put(name, classDescriptor);
|
||||||
if (!object) {
|
if (!object) {
|
||||||
@@ -82,6 +83,17 @@ public abstract class AbstractLazyMemberScope<D extends DeclarationDescriptor, D
|
|||||||
return classDescriptor;
|
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
|
@Override
|
||||||
public ClassifierDescriptor getClassifier(@NotNull Name name) {
|
public ClassifierDescriptor getClassifier(@NotNull Name name) {
|
||||||
return getClassOrObjectDescriptor(classDescriptors, name, false);
|
return getClassOrObjectDescriptor(classDescriptors, name, false);
|
||||||
@@ -89,7 +101,6 @@ public abstract class AbstractLazyMemberScope<D extends DeclarationDescriptor, D
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ClassDescriptor getObjectDescriptor(@NotNull Name name) {
|
public ClassDescriptor getObjectDescriptor(@NotNull Name name) {
|
||||||
// TODO: We shouldn't really allow objects in classes...
|
|
||||||
return getClassOrObjectDescriptor(objectDescriptors, name, true);
|
return getClassOrObjectDescriptor(objectDescriptors, name, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -147,14 +158,13 @@ public abstract class AbstractLazyMemberScope<D extends DeclarationDescriptor, D
|
|||||||
|
|
||||||
// Objects are also properties
|
// Objects are also properties
|
||||||
JetClassOrObject classOrObjectDeclaration = declarationProvider.getClassOrObjectDeclaration(name);
|
JetClassOrObject classOrObjectDeclaration = declarationProvider.getClassOrObjectDeclaration(name);
|
||||||
if (classOrObjectDeclaration instanceof JetObjectDeclaration) {
|
if (declaresObjectOrEnumConstant(classOrObjectDeclaration)) {
|
||||||
JetObjectDeclaration objectDeclaration = (JetObjectDeclaration) classOrObjectDeclaration;
|
|
||||||
ClassDescriptor classifier = getObjectDescriptor(name);
|
ClassDescriptor classifier = getObjectDescriptor(name);
|
||||||
if (classifier == null) {
|
if (classifier == null) {
|
||||||
throw new IllegalStateException("Object declaration " + name + " found in the DeclarationProvider " + declarationProvider + " but not in the scope " + this);
|
throw new IllegalStateException("Object declaration " + name + " found in the DeclarationProvider " + declarationProvider + " but not in the scope " + this);
|
||||||
}
|
}
|
||||||
VariableDescriptor propertyDescriptor = resolveSession.getInjector().getDescriptorResolver()
|
VariableDescriptor propertyDescriptor = resolveSession.getInjector().getDescriptorResolver()
|
||||||
.resolveObjectDeclaration(thisDescriptor, objectDeclaration, classifier, resolveSession.getTrace());
|
.resolveObjectDeclaration(thisDescriptor, classOrObjectDeclaration, classifier, resolveSession.getTrace());
|
||||||
result.add(propertyDescriptor);
|
result.add(propertyDescriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -209,6 +219,7 @@ public abstract class AbstractLazyMemberScope<D extends DeclarationDescriptor, D
|
|||||||
Name name = jetEnumEntry.getNameAsName();
|
Name name = jetEnumEntry.getNameAsName();
|
||||||
if (name != null) {
|
if (name != null) {
|
||||||
getProperties(name);
|
getProperties(name);
|
||||||
|
getObjectDescriptor(name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (declaration instanceof JetObjectDeclaration) {
|
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
|
// Members from supertypes
|
||||||
Collection<PropertyDescriptor> fromSupertypes = Lists.newArrayList();
|
Collection<PropertyDescriptor> fromSupertypes = Lists.newArrayList();
|
||||||
for (JetType supertype : thisDescriptor.getTypeConstructor().getSupertypes()) {
|
for (JetType supertype : thisDescriptor.getTypeConstructor().getSupertypes()) {
|
||||||
@@ -264,9 +248,14 @@ public class LazyClassMemberScope extends AbstractLazyMemberScope<LazyClassDescr
|
|||||||
@Nullable
|
@Nullable
|
||||||
public ConstructorDescriptor getPrimaryConstructor() {
|
public ConstructorDescriptor getPrimaryConstructor() {
|
||||||
if (!primaryConstructorResolved) {
|
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();
|
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;
|
JetClass jetClass = (JetClass) classOrObject;
|
||||||
ConstructorDescriptorImpl constructor = resolveSession.getInjector().getDescriptorResolver()
|
ConstructorDescriptorImpl constructor = resolveSession.getInjector().getDescriptorResolver()
|
||||||
.resolvePrimaryConstructorDescriptor(thisDescriptor.getScopeForClassHeaderResolution(),
|
.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.Predicate;
|
||||||
import com.google.common.base.Predicates;
|
import com.google.common.base.Predicates;
|
||||||
import com.google.common.collect.Maps;
|
|
||||||
import com.intellij.openapi.project.Project;
|
import com.intellij.openapi.project.Project;
|
||||||
import com.intellij.psi.PsiElement;
|
import com.intellij.psi.PsiElement;
|
||||||
import com.intellij.psi.util.PsiTreeUtil;
|
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.BindingContext;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingTrace;
|
import org.jetbrains.jet.lang.resolve.BindingTrace;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingTraceContext;
|
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.FqName;
|
||||||
import org.jetbrains.jet.lang.resolve.name.FqNameUnsafe;
|
import org.jetbrains.jet.lang.resolve.name.FqNameUnsafe;
|
||||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
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 org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author abreslav
|
* @author abreslav
|
||||||
@@ -66,7 +63,6 @@ public class ResolveSession {
|
|||||||
private final InjectorForLazyResolve injector;
|
private final InjectorForLazyResolve injector;
|
||||||
private final ModuleConfiguration moduleConfiguration;
|
private final ModuleConfiguration moduleConfiguration;
|
||||||
|
|
||||||
private final Map<JetEnumEntry, ClassDescriptor> enumEntryClassDescriptorCache = Maps.newHashMap();
|
|
||||||
private final Function<FqName, Name> classifierAliases;
|
private final Function<FqName, Name> classifierAliases;
|
||||||
|
|
||||||
public ResolveSession(
|
public ResolveSession(
|
||||||
@@ -136,10 +132,6 @@ public class ResolveSession {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public ClassDescriptor getClassDescriptor(@NotNull JetClassOrObject classOrObject) {
|
public ClassDescriptor getClassDescriptor(@NotNull JetClassOrObject classOrObject) {
|
||||||
if (classOrObject instanceof JetEnumEntry) {
|
|
||||||
JetEnumEntry enumEntry = (JetEnumEntry) classOrObject;
|
|
||||||
return getEnumEntryClassDescriptor(enumEntry);
|
|
||||||
}
|
|
||||||
if (classOrObject.getParent() instanceof JetClassObject) {
|
if (classOrObject.getParent() instanceof JetClassObject) {
|
||||||
return getClassObjectDescriptor((JetClassObject) classOrObject.getParent());
|
return getClassObjectDescriptor((JetClassObject) classOrObject.getParent());
|
||||||
}
|
}
|
||||||
@@ -147,29 +139,15 @@ public class ResolveSession {
|
|||||||
Name name = classOrObject.getNameAsName();
|
Name name = classOrObject.getNameAsName();
|
||||||
assert name != null : "Name is null for " + classOrObject + " " + classOrObject.getText();
|
assert name != null : "Name is null for " + classOrObject + " " + classOrObject.getText();
|
||||||
ClassifierDescriptor classifier = resolutionScope.getClassifier(name);
|
ClassifierDescriptor classifier = resolutionScope.getClassifier(name);
|
||||||
|
if (classifier == null) {
|
||||||
|
classifier = resolutionScope.getObjectDescriptor(name);
|
||||||
|
}
|
||||||
if (classifier == null) {
|
if (classifier == null) {
|
||||||
throw new IllegalArgumentException("Could not find a classifier for " + classOrObject + " " + classOrObject.getText());
|
throw new IllegalArgumentException("Could not find a classifier for " + classOrObject + " " + classOrObject.getText());
|
||||||
}
|
}
|
||||||
return (ClassDescriptor) classifier;
|
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) {
|
/*package*/ LazyClassDescriptor getClassObjectDescriptor(JetClassObject classObject) {
|
||||||
LazyClassDescriptor classDescriptor = (LazyClassDescriptor) getClassDescriptor(PsiTreeUtil.getParentOfType(classObject, JetClass.class));
|
LazyClassDescriptor classDescriptor = (LazyClassDescriptor) getClassDescriptor(PsiTreeUtil.getParentOfType(classObject, JetClass.class));
|
||||||
LazyClassDescriptor classObjectDescriptor = (LazyClassDescriptor) classDescriptor.getClassObjectDescriptor();
|
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 /*constructor*/ fun <init>(): test.Test.<class-object-for-Test>
|
||||||
internal final val A: test.Test.<class-object-for-Test>.A
|
internal final val A: test.Test.<class-object-for-Test>.A
|
||||||
internal final val C: test.Test.<class-object-for-Test>.C
|
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