Remove 'inner enum' hack & fix Java inner class resolve

Inner enum was placed into the class object of the outer class. Remove the
hack from frontend, frontend.java & backend. Fix tests

 #KT-1174 In Progress
This commit is contained in:
Alexander Udalov
2012-12-04 20:07:13 +04:00
parent cc6bd6239a
commit b612989eb0
19 changed files with 70 additions and 236 deletions
@@ -160,8 +160,6 @@ public interface Errors {
// Enum-specific
SimpleDiagnosticFactory<PsiElement> ENUM_NOT_ALLOWED = SimpleDiagnosticFactory.create(ERROR);
SimpleDiagnosticFactory<JetModifierListOwner> ILLEGAL_ENUM_ANNOTATION = SimpleDiagnosticFactory
.create(ERROR, modifierSetPosition(JetTokens.ENUM_KEYWORD));
@@ -162,7 +162,6 @@ public class DefaultErrorMessages {
MAP.put(ENUM_ENTRY_SHOULD_BE_INITIALIZED, "Missing delegation specifier ''{0}''", NAME);
MAP.put(ENUM_ENTRY_ILLEGAL_TYPE, "The type constructor of enum entry should be ''{0}''", NAME);
MAP.put(ENUM_NOT_ALLOWED, "Enum class is not allowed here");
MAP.put(UNINITIALIZED_VARIABLE, "Variable ''{0}'' must be initialized", NAME);
MAP.put(UNINITIALIZED_PARAMETER, "Parameter ''{0}'' is uninitialized here", NAME);
@@ -228,8 +228,6 @@ public interface BindingContext {
ReadOnlySlice<PsiElement, DeclarationDescriptor> DECLARATION_TO_DESCRIPTOR = Slices.<PsiElement, DeclarationDescriptor>sliceBuilder()
.setFurtherLookupSlices(DECLARATIONS_TO_DESCRIPTORS).build();
WritableSlice<ClassDescriptor, Boolean> IS_ENUM_MOVED_TO_CLASS_OBJECT = Slices.createSimpleSlice();
WritableSlice<JetReferenceExpression, PsiElement> LABEL_TARGET = Slices.<JetReferenceExpression, PsiElement>sliceBuilder().build();
WritableSlice<JetReferenceExpression, Collection<? extends PsiElement>> AMBIGUOUS_LABEL_TARGET =
Slices.<JetReferenceExpression, Collection<? extends PsiElement>>sliceBuilder().build();
@@ -196,8 +196,6 @@ public class TypeHierarchyResolver {
declaration.accept(collector);
}
collector.finishProcessing();
return forDeferredResolve;
}
@@ -470,8 +468,6 @@ public class TypeHierarchyResolver {
private final NamespaceLikeBuilder owner;
private final Collection<JetDeclarationContainer> forDeferredResolve;
private final List<JetClass> enumsToAddLater = new ArrayList<JetClass>(0);
public ClassifierCollector(@NotNull JetScope outerScope,
@NotNull NamespaceLikeBuilder owner,
@NotNull Collection<JetDeclarationContainer> forDeferredResolve
@@ -501,25 +497,11 @@ public class TypeHierarchyResolver {
@Override
public void visitClass(JetClass klass) {
if (getClassKind(klass) == ClassKind.ENUM_CLASS && inClass()) {
// Enums inside non-static context are put not to owner, but rather into its class object.
// This is handled after visiting all declarations in this class, because we may or may not
// encounter class object to put this enum into.
enumsToAddLater.add(klass);
return;
}
MutableClassDescriptor mutableClassDescriptor = createClassDescriptorForClass(klass, owner.getOwnerForChildren());
owner.addClassifierDescriptor(mutableClassDescriptor);
}
private boolean inClass() {
if (!(owner.getOwnerForChildren() instanceof ClassDescriptor)) return false;
ClassKind kind = ((ClassDescriptor) owner.getOwnerForChildren()).getKind();
return kind == ClassKind.CLASS || kind == ClassKind.ENUM_CLASS || kind == ClassKind.TRAIT;
}
@Override
public void visitObjectDeclaration(JetObjectDeclaration declaration) {
MutableClassDescriptor objectDescriptor =
@@ -673,50 +655,5 @@ public class TypeHierarchyResolver {
context.normalScope.put(container, outerScope);
context.forDeferredResolver.put(container, descriptorForDeferredResolve);
}
@Nullable
private MutableClassDescriptor getOrCreateClassObjectDescriptor() {
ClassDescriptor ownerForChildren = (ClassDescriptor) owner.getOwnerForChildren();
MutableClassDescriptor classObjectDescriptor = (MutableClassDescriptor) ownerForChildren.getClassObjectDescriptor();
if (classObjectDescriptor == null) {
classObjectDescriptor = createClassObjectDescriptor(ownerForChildren, Visibilities.PUBLIC);
NamespaceLikeBuilder.ClassObjectStatus status = owner.setClassObjectDescriptor(classObjectDescriptor);
assert status != NamespaceLikeBuilder.ClassObjectStatus.DUPLICATE :
"Attempting to create an artificial class object where the real one exists: " + ownerForChildren;
if (status == NamespaceLikeBuilder.ClassObjectStatus.NOT_ALLOWED) {
return null;
}
}
return classObjectDescriptor;
}
private void putEnumsIntoOuterClassObject() {
if (enumsToAddLater.isEmpty()) return;
MutableClassDescriptor classObjectDescriptor = getOrCreateClassObjectDescriptor();
if (classObjectDescriptor == null) {
// A class object is not allowed in outer class, so report an error on every declared enum
for (JetClass klass : enumsToAddLater) {
JetModifierList modifierList = klass.getModifierList();
assert modifierList != null : "Enum class without modifier list: " + klass.getText();
ASTNode node = modifierList.getModifierNode(JetTokens.ENUM_KEYWORD);
assert node != null : "Enum class without enum modifier: " + klass.getText();
trace.report(ENUM_NOT_ALLOWED.on(node.getPsi()));
}
return;
}
for (JetClass klass : enumsToAddLater) {
MutableClassDescriptor mutableClassDescriptor = createClassDescriptorForClass(klass, classObjectDescriptor);
trace.record(BindingContext.IS_ENUM_MOVED_TO_CLASS_OBJECT, mutableClassDescriptor);
classObjectDescriptor.getBuilder().addClassifierDescriptor(mutableClassDescriptor);
}
}
private void finishProcessing() {
putEnumsIntoOuterClassObject();
}
}
}