Enum entries are put into enum class, not its class object

This commit is contained in:
Alexander Udalov
2013-11-13 21:17:31 +04:00
parent a5d6d6719c
commit 60e7722a82
11 changed files with 90 additions and 136 deletions
@@ -1677,9 +1677,8 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
return StackValue.singleton(classDescriptor, typeMapper);
}
if (classDescriptor.getKind() == ClassKind.ENUM_ENTRY) {
DeclarationDescriptor enumClass = classDescriptor.getContainingDeclaration().getContainingDeclaration();
assert enumClass != null && DescriptorUtils.isEnumClass(enumClass)
: "Enum entry should be declared in enum class object: " + descriptor;
DeclarationDescriptor enumClass = classDescriptor.getContainingDeclaration();
assert DescriptorUtils.isEnumClass(enumClass) : "Enum entry should be declared in enum class: " + descriptor;
Type type = typeMapper.mapType((ClassDescriptor) enumClass);
return StackValue.field(type, type, descriptor.getName().asString(), true);
}
@@ -279,11 +279,10 @@ public class BodyResolver {
delegationSpecifier.accept(visitor);
}
Set<TypeConstructor> parentEnum = Collections.emptySet();
if (jetClass instanceof JetEnumEntry) {
parentEnum = Collections.singleton(((ClassDescriptor) descriptor.getContainingDeclaration().getContainingDeclaration()).getTypeConstructor());
}
Set<TypeConstructor> parentEnum =
jetClass instanceof JetEnumEntry
? Collections.singleton(((ClassDescriptor) descriptor.getContainingDeclaration()).getTypeConstructor())
: Collections.<TypeConstructor>emptySet();
checkSupertypeList(descriptor, supertypes, parentEnum);
}
@@ -104,11 +104,11 @@ public class DeclarationsChecker {
if (aClass.isTrait()) {
checkTraitModifiers(aClass);
}
else if (classDescriptor.getKind() == ClassKind.ENUM_CLASS) {
else if (aClass.isEnum()) {
checkEnumModifiers(aClass);
}
else if (classDescriptor.getKind() == ClassKind.ENUM_ENTRY) {
checkEnumEntry(aClass, classDescriptor);
else if (aClass instanceof JetEnumEntry) {
checkEnumEntry((JetEnumEntry) aClass, classDescriptor);
}
}
@@ -332,17 +332,16 @@ public class DeclarationsChecker {
}
}
private void checkEnumEntry(JetClass aClass, ClassDescriptor classDescriptor) {
DeclarationDescriptor declaration = classDescriptor.getContainingDeclaration().getContainingDeclaration();
assert declaration instanceof ClassDescriptor;
private void checkEnumEntry(@NotNull JetEnumEntry enumEntry, @NotNull ClassDescriptor classDescriptor) {
DeclarationDescriptor declaration = classDescriptor.getContainingDeclaration();
assert DescriptorUtils.isEnumClass(declaration) : "Enum entry should be declared in enum class: " + classDescriptor;
ClassDescriptor enumClass = (ClassDescriptor) declaration;
assert enumClass.getKind() == ClassKind.ENUM_CLASS;
List<JetDelegationSpecifier> delegationSpecifiers = aClass.getDelegationSpecifiers();
List<JetDelegationSpecifier> delegationSpecifiers = enumEntry.getDelegationSpecifiers();
ConstructorDescriptor constructor = enumClass.getUnsubstitutedPrimaryConstructor();
assert constructor != null;
if (!constructor.getValueParameters().isEmpty() && delegationSpecifiers.isEmpty()) {
trace.report(ENUM_ENTRY_SHOULD_BE_INITIALIZED.on(aClass, enumClass));
trace.report(ENUM_ENTRY_SHOULD_BE_INITIALIZED.on(enumEntry, enumClass));
}
for (JetDelegationSpecifier delegationSpecifier : delegationSpecifiers) {
@@ -27,6 +27,7 @@ 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.JetEnumEntry;
import org.jetbrains.jet.lang.psi.JetModifierList;
import org.jetbrains.jet.lang.psi.JetModifierListOwner;
import org.jetbrains.jet.lexer.JetKeywordToken;
@@ -106,7 +107,7 @@ public class ModifiersChecker {
}
}
else {
if (modifierListOwner instanceof JetClass && isIllegalNestedClass(descriptor)) {
if (modifierListOwner instanceof JetClass && !(modifierListOwner instanceof JetEnumEntry) && isIllegalNestedClass(descriptor)) {
PsiElement name = ((JetClass) modifierListOwner).getNameIdentifier();
if (name != null) {
trace.report(Errors.NESTED_CLASS_NOT_ALLOWED.on(name));
@@ -475,16 +475,13 @@ public class TypeHierarchyResolver {
@Override
public void visitObjectDeclaration(@NotNull JetObjectDeclaration declaration) {
if (declaration.isObjectLiteral()) {
MutableClassDescriptor descriptor =
createClassDescriptorForObject(declaration, SpecialNames.NO_NAME_PROVIDED, ClassKind.CLASS);
context.getClasses().put(declaration, descriptor);
createClassDescriptorForSingleton(declaration, SpecialNames.NO_NAME_PROVIDED, ClassKind.CLASS);
return;
}
MutableClassDescriptor descriptor =
createClassDescriptorForObject(declaration, JetPsiUtil.safeName(declaration.getName()), ClassKind.OBJECT);
createClassDescriptorForSingleton(declaration, JetPsiUtil.safeName(declaration.getName()), ClassKind.OBJECT);
context.getClasses().put(declaration, descriptor);
owner.addClassifierDescriptor(descriptor);
trace.record(FQNAME_TO_CLASS_DESCRIPTOR, JetPsiUtil.getFQName(declaration), descriptor);
@@ -492,12 +489,13 @@ public class TypeHierarchyResolver {
}
@Override
public void visitEnumEntry(@NotNull JetEnumEntry enumEntry) {
// TODO: Bad casting
MutableClassDescriptorLite enumClass = (MutableClassDescriptorLite) owner.getOwnerForChildren();
MutableClassDescriptorLite enumClassObject = enumClass.getClassObjectDescriptor();
assert enumClassObject != null : enumEntry.getParent().getText();
createClassDescriptorForEnumEntry(enumEntry, enumClassObject);
public void visitEnumEntry(@NotNull JetEnumEntry declaration) {
MutableClassDescriptor descriptor =
createClassDescriptorForSingleton(declaration, JetPsiUtil.safeName(declaration.getName()), ClassKind.ENUM_ENTRY);
owner.addClassifierDescriptor(descriptor);
descriptor.getBuilder().setClassObjectDescriptor(createSyntheticClassObject(descriptor));
}
@Override
@@ -511,9 +509,8 @@ public class TypeHierarchyResolver {
if (objectDeclaration == null) return;
MutableClassDescriptor classObjectDescriptor =
createClassDescriptorForObject(objectDeclaration, getClassObjectName(owner.getOwnerForChildren().getName()),
ClassKind.CLASS_OBJECT);
context.getClasses().put(objectDeclaration, classObjectDescriptor);
createClassDescriptorForSingleton(objectDeclaration, getClassObjectName(owner.getOwnerForChildren().getName()),
ClassKind.CLASS_OBJECT);
NamespaceLikeBuilder.ClassObjectStatus status = owner.setClassObjectDescriptor(classObjectDescriptor);
switch (status) {
@@ -573,47 +570,20 @@ public class TypeHierarchyResolver {
return mutableClassDescriptor;
}
@NotNull
private MutableClassDescriptor createClassDescriptorForObject(
@NotNull JetClassOrObject declaration,
@NotNull Name name,
@NotNull ClassKind kind
) {
return createClassDescriptorForSingleton(owner.getOwnerForChildren(), outerScope, declaration, name, kind);
}
@NotNull
private MutableClassDescriptor createClassDescriptorForSingleton(
@NotNull DeclarationDescriptor containingDeclaration,
@NotNull JetScope scope,
@NotNull JetClassOrObject declaration,
@NotNull Name name,
@NotNull ClassKind kind
) {
MutableClassDescriptor descriptor = new MutableClassDescriptor(containingDeclaration, scope, kind, false, name);
MutableClassDescriptor descriptor = new MutableClassDescriptor(owner.getOwnerForChildren(), outerScope, kind, false, name);
prepareForDeferredCall(descriptor.getScopeForMemberResolution(), descriptor, declaration);
createPrimaryConstructorForObject(declaration, descriptor);
trace.record(BindingContext.CLASS, declaration, descriptor);
return descriptor;
}
@NotNull
private MutableClassDescriptor createClassDescriptorForEnumEntry(
@NotNull JetEnumEntry declaration,
@NotNull MutableClassDescriptorLite enumClassObject
) {
JetScope scope = ((MutableClassDescriptor) enumClassObject).getScopeForMemberResolution();
MutableClassDescriptor descriptor =
createClassDescriptorForSingleton(enumClassObject, scope, declaration, JetPsiUtil.safeName(declaration.getName()),
ClassKind.ENUM_ENTRY);
context.getClasses().put(declaration, descriptor);
enumClassObject.getBuilder().addClassifierDescriptor(descriptor);
descriptor.getBuilder().setClassObjectDescriptor(createSyntheticClassObject(descriptor));
return descriptor;
}
@@ -9,17 +9,17 @@ internal final enum class In : jet.Enum<test.In> {
/*primary*/ private constructor <class-object-for-In>()
public final /*synthesized*/ fun valueOf(/*0*/ value: jet.String): test.In
public final /*synthesized*/ fun values(): jet.Array<test.In>
}
public enum entry A : test.In {
/*primary*/ private constructor A()
public final override /*1*/ /*fake_override*/ fun name(): jet.String
public final override /*1*/ /*fake_override*/ fun ordinal(): jet.Int
public enum entry A : test.In {
/*primary*/ private constructor A()
public class object <class-object-for-A> : test.In.A {
/*primary*/ private constructor <class-object-for-A>()
public final override /*1*/ /*fake_override*/ fun name(): jet.String
public final override /*1*/ /*fake_override*/ fun ordinal(): jet.Int
public class object <class-object-for-A> : test.In.A {
/*primary*/ private constructor <class-object-for-A>()
public final override /*1*/ /*fake_override*/ fun name(): jet.String
public final override /*1*/ /*fake_override*/ fun ordinal(): jet.Int
}
}
}
}
@@ -33,17 +33,17 @@ private final enum class Pr : jet.Enum<test.Pr> {
/*primary*/ private constructor <class-object-for-Pr>()
public final /*synthesized*/ fun valueOf(/*0*/ value: jet.String): test.Pr
public final /*synthesized*/ fun values(): jet.Array<test.Pr>
}
public enum entry A : test.Pr {
/*primary*/ private constructor A()
public final override /*1*/ /*fake_override*/ fun name(): jet.String
public final override /*1*/ /*fake_override*/ fun ordinal(): jet.Int
public enum entry A : test.Pr {
/*primary*/ private constructor A()
public class object <class-object-for-A> : test.Pr.A {
/*primary*/ private constructor <class-object-for-A>()
public final override /*1*/ /*fake_override*/ fun name(): jet.String
public final override /*1*/ /*fake_override*/ fun ordinal(): jet.Int
public class object <class-object-for-A> : test.Pr.A {
/*primary*/ private constructor <class-object-for-A>()
public final override /*1*/ /*fake_override*/ fun name(): jet.String
public final override /*1*/ /*fake_override*/ fun ordinal(): jet.Int
}
}
}
}
@@ -57,17 +57,17 @@ public final enum class Pu : jet.Enum<test.Pu> {
/*primary*/ private constructor <class-object-for-Pu>()
public final /*synthesized*/ fun valueOf(/*0*/ value: jet.String): test.Pu
public final /*synthesized*/ fun values(): jet.Array<test.Pu>
}
public enum entry A : test.Pu {
/*primary*/ private constructor A()
public final override /*1*/ /*fake_override*/ fun name(): jet.String
public final override /*1*/ /*fake_override*/ fun ordinal(): jet.Int
public enum entry A : test.Pu {
/*primary*/ private constructor A()
public class object <class-object-for-A> : test.Pu.A {
/*primary*/ private constructor <class-object-for-A>()
public final override /*1*/ /*fake_override*/ fun name(): jet.String
public final override /*1*/ /*fake_override*/ fun ordinal(): jet.Int
public class object <class-object-for-A> : test.Pu.A {
/*primary*/ private constructor <class-object-for-A>()
public final override /*1*/ /*fake_override*/ fun name(): jet.String
public final override /*1*/ /*fake_override*/ fun ordinal(): jet.Int
}
}
}
}
@@ -16,17 +16,17 @@ internal final class A {
/*primary*/ private constructor <class-object-for-E>()
public final /*synthesized*/ fun valueOf(/*0*/ value: jet.String): test.A.E
public final /*synthesized*/ fun values(): jet.Array<test.A.E>
}
public enum entry ENTRY : test.A.E {
/*primary*/ private constructor ENTRY()
public final override /*1*/ /*fake_override*/ fun name(): jet.String
public final override /*1*/ /*fake_override*/ fun ordinal(): jet.Int
public enum entry ENTRY : test.A.E {
/*primary*/ private constructor ENTRY()
public class object <class-object-for-ENTRY> : test.A.E.ENTRY {
/*primary*/ private constructor <class-object-for-ENTRY>()
public final override /*1*/ /*fake_override*/ fun name(): jet.String
public final override /*1*/ /*fake_override*/ fun ordinal(): jet.Int
public class object <class-object-for-ENTRY> : test.A.E.ENTRY {
/*primary*/ private constructor <class-object-for-ENTRY>()
public final override /*1*/ /*fake_override*/ fun name(): jet.String
public final override /*1*/ /*fake_override*/ fun ordinal(): jet.Int
}
}
}
}
@@ -12,17 +12,17 @@ internal final class A {
/*primary*/ private constructor <class-object-for-E>()
public final /*synthesized*/ fun valueOf(/*0*/ value: jet.String): test.A.E
public final /*synthesized*/ fun values(): jet.Array<test.A.E>
}
public enum entry ENTRY : test.A.E {
/*primary*/ private constructor ENTRY()
public final override /*1*/ /*fake_override*/ fun name(): jet.String
public final override /*1*/ /*fake_override*/ fun ordinal(): jet.Int
public enum entry ENTRY : test.A.E {
/*primary*/ private constructor ENTRY()
public class object <class-object-for-ENTRY> : test.A.E.ENTRY {
/*primary*/ private constructor <class-object-for-ENTRY>()
public final override /*1*/ /*fake_override*/ fun name(): jet.String
public final override /*1*/ /*fake_override*/ fun ordinal(): jet.Int
public class object <class-object-for-ENTRY> : test.A.E.ENTRY {
/*primary*/ private constructor <class-object-for-ENTRY>()
public final override /*1*/ /*fake_override*/ fun name(): jet.String
public final override /*1*/ /*fake_override*/ fun ordinal(): jet.Int
}
}
}
}
@@ -9,17 +9,17 @@ internal final enum class MyEnum : jet.Enum<test.MyEnum> {
/*primary*/ private constructor <class-object-for-MyEnum>()
public final /*synthesized*/ fun valueOf(/*0*/ value: jet.String): test.MyEnum
public final /*synthesized*/ fun values(): jet.Array<test.MyEnum>
}
public enum entry ENTRY : test.MyEnum {
/*primary*/ private constructor ENTRY()
public final override /*1*/ /*fake_override*/ fun name(): jet.String
public final override /*1*/ /*fake_override*/ fun ordinal(): jet.Int
public enum entry ENTRY : test.MyEnum {
/*primary*/ private constructor ENTRY()
public class object <class-object-for-ENTRY> : test.MyEnum.ENTRY {
/*primary*/ private constructor <class-object-for-ENTRY>()
public final override /*1*/ /*fake_override*/ fun name(): jet.String
public final override /*1*/ /*fake_override*/ fun ordinal(): jet.Int
public class object <class-object-for-ENTRY> : test.MyEnum.ENTRY {
/*primary*/ private constructor <class-object-for-ENTRY>()
public final override /*1*/ /*fake_override*/ fun name(): jet.String
public final override /*1*/ /*fake_override*/ fun ordinal(): jet.Int
}
}
}
}
@@ -490,9 +490,7 @@ public class DescriptorUtils {
@NotNull
public static JetScope getEnumEntriesScope(@NotNull ClassDescriptor enumClass) {
assert enumClass.getKind() == ClassKind.ENUM_CLASS : "Only enum classes have enum entries: " + enumClass;
ClassDescriptor classObject = enumClass.getClassObjectDescriptor();
assert classObject != null : "Enum class should have a class object: " + enumClass;
return classObject.getDefaultType().getMemberScope();
assert isEnumClass(enumClass) : "Only enum classes have enum entries: " + enumClass;
return enumClass.getUnsubstitutedInnerClassesScope();
}
}
}
@@ -17,10 +17,13 @@
package org.jetbrains.jet.lang.resolve.scopes;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.Collections2;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.ReceiverParameterDescriptor;
import org.jetbrains.jet.lang.resolve.name.LabelName;
import org.jetbrains.jet.lang.resolve.name.Name;
@@ -29,9 +32,11 @@ import java.util.Collections;
import java.util.List;
public class InnerClassesScopeWrapper extends AbstractScopeAdapter {
private static final Predicate<Object> IS_CLASS = Predicates.instanceOf(ClassDescriptor.class);
private final JetScope actualScope;
public InnerClassesScopeWrapper(JetScope actualScope) {
public InnerClassesScopeWrapper(@NotNull JetScope actualScope) {
this.actualScope = actualScope;
}
@@ -44,32 +49,19 @@ public class InnerClassesScopeWrapper extends AbstractScopeAdapter {
@Override
public ClassifierDescriptor getClassifier(@NotNull Name name) {
ClassifierDescriptor classifier = actualScope.getClassifier(name);
if (isClass(classifier)) return classifier;
return null;
return IS_CLASS.apply(classifier) ? classifier : null;
}
@NotNull
@Override
public Collection<DeclarationDescriptor> getDeclarationsByLabel(LabelName labelName) {
Collection<DeclarationDescriptor> declarationsByLabel = actualScope.getDeclarationsByLabel(labelName);
return Collections2.filter(declarationsByLabel, new Predicate<DeclarationDescriptor>() {
@Override
public boolean apply(@Nullable DeclarationDescriptor descriptor) {
return isClass(descriptor);
}
});
return Collections2.filter(actualScope.getDeclarationsByLabel(labelName), IS_CLASS);
}
@NotNull
@Override
public Collection<DeclarationDescriptor> getAllDescriptors() {
Collection<DeclarationDescriptor> allDescriptors = actualScope.getAllDescriptors();
return Collections2.filter(allDescriptors, new Predicate<DeclarationDescriptor>() {
@Override
public boolean apply(@Nullable DeclarationDescriptor descriptor) {
return isClass(descriptor);
}
});
return Collections2.filter(actualScope.getAllDescriptors(), IS_CLASS);
}
@NotNull
@@ -82,8 +74,4 @@ public class InnerClassesScopeWrapper extends AbstractScopeAdapter {
public String toString() {
return "Classes from " + actualScope;
}
private static boolean isClass(@Nullable DeclarationDescriptor descriptor) {
return descriptor instanceof ClassDescriptor && ((ClassDescriptor) descriptor).getKind() != ClassKind.ENUM_ENTRY;
}
}