diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index 3423035c536..93a32896ddd 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -1677,9 +1677,8 @@ public class ExpressionCodegen extends JetVisitor 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); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java index b7974402cb7..fb011a7d072 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java @@ -279,11 +279,10 @@ public class BodyResolver { delegationSpecifier.accept(visitor); } - - Set parentEnum = Collections.emptySet(); - if (jetClass instanceof JetEnumEntry) { - parentEnum = Collections.singleton(((ClassDescriptor) descriptor.getContainingDeclaration().getContainingDeclaration()).getTypeConstructor()); - } + Set parentEnum = + jetClass instanceof JetEnumEntry + ? Collections.singleton(((ClassDescriptor) descriptor.getContainingDeclaration()).getTypeConstructor()) + : Collections.emptySet(); checkSupertypeList(descriptor, supertypes, parentEnum); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DeclarationsChecker.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DeclarationsChecker.java index 98fbab4e1ae..341c318aa58 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DeclarationsChecker.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DeclarationsChecker.java @@ -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 delegationSpecifiers = aClass.getDelegationSpecifiers(); + List 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) { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ModifiersChecker.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ModifiersChecker.java index ff60d63381d..24da8528e74 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ModifiersChecker.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ModifiersChecker.java @@ -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)); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java index 8a6044d156d..227a9a43836 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java @@ -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; } diff --git a/compiler/testData/loadKotlinCustom/enum/enumVisibilitySource.txt b/compiler/testData/loadKotlinCustom/enum/enumVisibilitySource.txt index af416fbc911..566e718acb8 100644 --- a/compiler/testData/loadKotlinCustom/enum/enumVisibilitySource.txt +++ b/compiler/testData/loadKotlinCustom/enum/enumVisibilitySource.txt @@ -9,17 +9,17 @@ internal final enum class In : jet.Enum { /*primary*/ private constructor () public final /*synthesized*/ fun valueOf(/*0*/ value: jet.String): test.In public final /*synthesized*/ fun values(): jet.Array + } + + 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 : test.In.A { + /*primary*/ private constructor () public final override /*1*/ /*fake_override*/ fun name(): jet.String public final override /*1*/ /*fake_override*/ fun ordinal(): jet.Int - - public class object : test.In.A { - /*primary*/ private constructor () - 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 { /*primary*/ private constructor () public final /*synthesized*/ fun valueOf(/*0*/ value: jet.String): test.Pr public final /*synthesized*/ fun values(): jet.Array + } + + 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 : test.Pr.A { + /*primary*/ private constructor () public final override /*1*/ /*fake_override*/ fun name(): jet.String public final override /*1*/ /*fake_override*/ fun ordinal(): jet.Int - - public class object : test.Pr.A { - /*primary*/ private constructor () - 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 { /*primary*/ private constructor () public final /*synthesized*/ fun valueOf(/*0*/ value: jet.String): test.Pu public final /*synthesized*/ fun values(): jet.Array + } + + 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 : test.Pu.A { + /*primary*/ private constructor () public final override /*1*/ /*fake_override*/ fun name(): jet.String public final override /*1*/ /*fake_override*/ fun ordinal(): jet.Int - - public class object : test.Pu.A { - /*primary*/ private constructor () - public final override /*1*/ /*fake_override*/ fun name(): jet.String - public final override /*1*/ /*fake_override*/ fun ordinal(): jet.Int - } } } } diff --git a/compiler/testData/loadKotlinCustom/enum/innerEnumExistingClassObjectSource.txt b/compiler/testData/loadKotlinCustom/enum/innerEnumExistingClassObjectSource.txt index 456bbe938f8..39180940703 100644 --- a/compiler/testData/loadKotlinCustom/enum/innerEnumExistingClassObjectSource.txt +++ b/compiler/testData/loadKotlinCustom/enum/innerEnumExistingClassObjectSource.txt @@ -16,17 +16,17 @@ internal final class A { /*primary*/ private constructor () public final /*synthesized*/ fun valueOf(/*0*/ value: jet.String): test.A.E public final /*synthesized*/ fun values(): jet.Array + } + + 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 : test.A.E.ENTRY { + /*primary*/ private constructor () public final override /*1*/ /*fake_override*/ fun name(): jet.String public final override /*1*/ /*fake_override*/ fun ordinal(): jet.Int - - public class object : test.A.E.ENTRY { - /*primary*/ private constructor () - public final override /*1*/ /*fake_override*/ fun name(): jet.String - public final override /*1*/ /*fake_override*/ fun ordinal(): jet.Int - } } } } diff --git a/compiler/testData/loadKotlinCustom/enum/innerEnumSource.txt b/compiler/testData/loadKotlinCustom/enum/innerEnumSource.txt index d0c3916866f..19fd6e11d6b 100644 --- a/compiler/testData/loadKotlinCustom/enum/innerEnumSource.txt +++ b/compiler/testData/loadKotlinCustom/enum/innerEnumSource.txt @@ -12,17 +12,17 @@ internal final class A { /*primary*/ private constructor () public final /*synthesized*/ fun valueOf(/*0*/ value: jet.String): test.A.E public final /*synthesized*/ fun values(): jet.Array + } + + 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 : test.A.E.ENTRY { + /*primary*/ private constructor () public final override /*1*/ /*fake_override*/ fun name(): jet.String public final override /*1*/ /*fake_override*/ fun ordinal(): jet.Int - - public class object : test.A.E.ENTRY { - /*primary*/ private constructor () - public final override /*1*/ /*fake_override*/ fun name(): jet.String - public final override /*1*/ /*fake_override*/ fun ordinal(): jet.Int - } } } } diff --git a/compiler/testData/loadKotlinCustom/enum/simpleEnumSource.txt b/compiler/testData/loadKotlinCustom/enum/simpleEnumSource.txt index e85d2240e14..ae20e2aff41 100644 --- a/compiler/testData/loadKotlinCustom/enum/simpleEnumSource.txt +++ b/compiler/testData/loadKotlinCustom/enum/simpleEnumSource.txt @@ -9,17 +9,17 @@ internal final enum class MyEnum : jet.Enum { /*primary*/ private constructor () public final /*synthesized*/ fun valueOf(/*0*/ value: jet.String): test.MyEnum public final /*synthesized*/ fun values(): jet.Array + } + + 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 : test.MyEnum.ENTRY { + /*primary*/ private constructor () public final override /*1*/ /*fake_override*/ fun name(): jet.String public final override /*1*/ /*fake_override*/ fun ordinal(): jet.Int - - public class object : test.MyEnum.ENTRY { - /*primary*/ private constructor () - public final override /*1*/ /*fake_override*/ fun name(): jet.String - public final override /*1*/ /*fake_override*/ fun ordinal(): jet.Int - } } } } diff --git a/core/descriptors/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java b/core/descriptors/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java index 589c476ad96..267c4c6f3f6 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java +++ b/core/descriptors/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java @@ -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(); } -} \ No newline at end of file +} diff --git a/core/descriptors/src/org/jetbrains/jet/lang/resolve/scopes/InnerClassesScopeWrapper.java b/core/descriptors/src/org/jetbrains/jet/lang/resolve/scopes/InnerClassesScopeWrapper.java index d0432bb1711..90ac6d9c532 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/resolve/scopes/InnerClassesScopeWrapper.java +++ b/core/descriptors/src/org/jetbrains/jet/lang/resolve/scopes/InnerClassesScopeWrapper.java @@ -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 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 getDeclarationsByLabel(LabelName labelName) { - Collection declarationsByLabel = actualScope.getDeclarationsByLabel(labelName); - return Collections2.filter(declarationsByLabel, new Predicate() { - @Override - public boolean apply(@Nullable DeclarationDescriptor descriptor) { - return isClass(descriptor); - } - }); + return Collections2.filter(actualScope.getDeclarationsByLabel(labelName), IS_CLASS); } @NotNull @Override public Collection getAllDescriptors() { - Collection allDescriptors = actualScope.getAllDescriptors(); - return Collections2.filter(allDescriptors, new Predicate() { - @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; - } }