Change object resolution strategy in TypeHierarchyResolver

Instead of creating a synthetic property descriptor for objects, create a
synthetic class object in it and make it inherit from the object. This way all
of object's members will be accessible via its class object
This commit is contained in:
Alexander Udalov
2013-11-12 18:14:50 +04:00
parent 18c59d5495
commit 6c74b10f6c
7 changed files with 44 additions and 41 deletions
@@ -245,14 +245,6 @@ public class DeclarationResolver {
}
}
@Override
public void visitObjectDeclaration(@NotNull JetObjectDeclaration declaration) {
PropertyDescriptor propertyDescriptor = descriptorResolver.resolveObjectDeclarationAsPropertyDescriptor(
scopeForFunctions, namespaceLike.getOwnerForChildren(), declaration, context.getObjects().get(declaration), trace);
namespaceLike.addPropertyDescriptor(propertyDescriptor);
}
@Override
public void visitEnumEntry(@NotNull JetEnumEntry enumEntry) {
// FIX: Bad cast
@@ -93,6 +93,11 @@ public class OverrideResolver {
for (MutableClassDescriptorLite klass : ContainerUtil.reverse(context.getClassesTopologicalOrder())) {
if (klass instanceof MutableClassDescriptor && ourClasses.contains(klass)) {
generateOverridesAndDelegationInAClass((MutableClassDescriptor) klass, processed, ourClasses);
MutableClassDescriptorLite classObject = klass.getClassObjectDescriptor();
if (classObject instanceof MutableClassDescriptor) {
generateOverridesAndDelegationInAClass((MutableClassDescriptor) classObject, processed, ourClasses);
}
}
}
}
@@ -116,11 +121,14 @@ public class OverrideResolver {
JetClassOrObject classOrObject = (JetClassOrObject) BindingContextUtils
.classDescriptorToDeclaration(trace.getBindingContext(), classDescriptor);
DelegationResolver.generateDelegatesInAClass(classDescriptor, trace, classOrObject);
if (classOrObject != null) {
DelegationResolver.generateDelegatesInAClass(classDescriptor, trace, classOrObject);
}
generateOverridesInAClass(classDescriptor);
}
private void generateOverridesInAClass(final MutableClassDescriptor classDescriptor) {
private void generateOverridesInAClass(@NotNull final MutableClassDescriptor classDescriptor) {
List<CallableMemberDescriptor> membersFromSupertypes = getCallableMembersFromSupertypes(classDescriptor);
MultiMap<Name, CallableMemberDescriptor> membersFromSupertypesByName = groupDescriptorsByName(membersFromSupertypes);
@@ -198,6 +198,10 @@ public class TypeHierarchyResolver {
descriptor.setVisibility(resolveVisibilityFromModifiers(declaration, getDefaultClassVisibility(descriptor)));
descriptor.setTypeParameterDescriptors(Collections.<TypeParameterDescriptor>emptyList());
descriptor.createTypeConstructor();
MutableClassDescriptorLite classObject = descriptor.getClassObjectDescriptor();
if (classObject != null) {
classObject.addSupertype(descriptor.getDefaultType());
}
}
private void resolveTypesInClassHeaders() {
@@ -488,9 +492,12 @@ public class TypeHierarchyResolver {
MutableClassDescriptor descriptor =
createClassDescriptorForObject(declaration, JetPsiUtil.safeName(declaration.getName()), ClassKind.OBJECT);
context.getObjects().put(declaration, descriptor);
owner.addObjectDescriptor(descriptor);
context.getClasses().put(declaration, descriptor);
owner.addClassifierDescriptor(descriptor);
trace.record(FQNAME_TO_CLASS_DESCRIPTOR, JetPsiUtil.getFQName(declaration), descriptor);
descriptor.getBuilder().setClassObjectDescriptor(createSyntheticClassObject(descriptor));
}
@Override
@@ -511,24 +518,24 @@ public class TypeHierarchyResolver {
@Override
public void visitClassObject(@NotNull JetClassObject classObject) {
JetObjectDeclaration objectDeclaration = classObject.getObjectDeclaration();
if (objectDeclaration != null) {
MutableClassDescriptor classObjectDescriptor =
createClassDescriptorForObject(objectDeclaration, getClassObjectName(owner.getOwnerForChildren().getName()),
ClassKind.CLASS_OBJECT);
context.getObjects().put(objectDeclaration, classObjectDescriptor);
if (objectDeclaration == null) return;
NamespaceLikeBuilder.ClassObjectStatus status = owner.setClassObjectDescriptor(classObjectDescriptor);
switch (status) {
case DUPLICATE:
trace.report(MANY_CLASS_OBJECTS.on(classObject));
break;
case NOT_ALLOWED:
trace.report(CLASS_OBJECT_NOT_ALLOWED.on(classObject));
break;
case OK:
// Everything is OK so no errors to trace.
break;
}
MutableClassDescriptor classObjectDescriptor =
createClassDescriptorForObject(objectDeclaration, getClassObjectName(owner.getOwnerForChildren().getName()),
ClassKind.CLASS_OBJECT);
context.getObjects().put(objectDeclaration, classObjectDescriptor);
NamespaceLikeBuilder.ClassObjectStatus status = owner.setClassObjectDescriptor(classObjectDescriptor);
switch (status) {
case DUPLICATE:
trace.report(MANY_CLASS_OBJECTS.on(classObject));
break;
case NOT_ALLOWED:
trace.report(CLASS_OBJECT_NOT_ALLOWED.on(classObject));
break;
case OK:
// Everything is OK so no errors to trace.
break;
}
}
@@ -77,6 +77,10 @@ public abstract class AbstractClassDescriptor implements ClassDescriptor {
@Nullable
@Override
public JetType getClassObjectType() {
if (getKind() == ClassKind.OBJECT) {
return getDefaultType();
}
ClassDescriptor classObject = getClassObjectDescriptor();
return classObject == null ? null : classObject.getDefaultType();
}
@@ -221,7 +221,7 @@ public abstract class MutableClassDescriptorLite extends ClassDescriptorBase {
@Override
public ClassObjectStatus setClassObjectDescriptor(@NotNull MutableClassDescriptorLite classObjectDescriptor) {
if (getKind().isSingleton() || isInner()) {
if (getKind() == ClassKind.CLASS_OBJECT || isInner()) {
return ClassObjectStatus.NOT_ALLOWED;
}
@@ -20,10 +20,7 @@ import com.google.common.base.Predicate;
import com.google.common.collect.Collections2;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
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.descriptors.*;
import org.jetbrains.jet.lang.resolve.name.LabelName;
import org.jetbrains.jet.lang.resolve.name.Name;
@@ -86,7 +83,7 @@ public class InnerClassesScopeWrapper extends AbstractScopeAdapter {
return "Classes from " + actualScope;
}
private static boolean isClass(DeclarationDescriptor descriptor) {
return descriptor instanceof ClassDescriptor && !((ClassDescriptor) descriptor).getKind().isSingleton();
private static boolean isClass(@Nullable DeclarationDescriptor descriptor) {
return descriptor instanceof ClassDescriptor && ((ClassDescriptor) descriptor).getKind() != ClassKind.ENUM_ENTRY;
}
}
@@ -21,7 +21,6 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.name.LabelName;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
@@ -310,10 +309,6 @@ public class WritableScopeImpl extends WritableScopeWithImports {
public void addClassifierDescriptor(@NotNull ClassifierDescriptor classDescriptor) {
checkMayWrite();
if (DescriptorUtils.isSingleton(classDescriptor)) {
throw new IllegalStateException("must not be object: " + classDescriptor);
}
addClassifierAlias(classDescriptor.getName(), classDescriptor);
}