From 6c74b10f6c3bcc940370554ab48026329ae97794 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Tue, 12 Nov 2013 18:14:50 +0400 Subject: [PATCH] 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 --- .../jet/lang/resolve/DeclarationResolver.java | 8 ---- .../jet/lang/resolve/OverrideResolver.java | 12 ++++- .../lang/resolve/TypeHierarchyResolver.java | 45 +++++++++++-------- .../impl/AbstractClassDescriptor.java | 4 ++ .../impl/MutableClassDescriptorLite.java | 2 +- .../scopes/InnerClassesScopeWrapper.java | 9 ++-- .../resolve/scopes/WritableScopeImpl.java | 5 --- 7 files changed, 44 insertions(+), 41 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DeclarationResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DeclarationResolver.java index 2b923ac1a3e..6ab20d92c85 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DeclarationResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DeclarationResolver.java @@ -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 diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/OverrideResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/OverrideResolver.java index d77f3d94995..2ffa95e551c 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/OverrideResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/OverrideResolver.java @@ -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 membersFromSupertypes = getCallableMembersFromSupertypes(classDescriptor); MultiMap membersFromSupertypesByName = groupDescriptorsByName(membersFromSupertypes); 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 30d99a61ccd..250ce6cd369 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java @@ -198,6 +198,10 @@ public class TypeHierarchyResolver { descriptor.setVisibility(resolveVisibilityFromModifiers(declaration, getDefaultClassVisibility(descriptor))); descriptor.setTypeParameterDescriptors(Collections.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; } } diff --git a/core/descriptors/src/org/jetbrains/jet/lang/descriptors/impl/AbstractClassDescriptor.java b/core/descriptors/src/org/jetbrains/jet/lang/descriptors/impl/AbstractClassDescriptor.java index f7c9ea2f35a..df9e4ee37d3 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/descriptors/impl/AbstractClassDescriptor.java +++ b/core/descriptors/src/org/jetbrains/jet/lang/descriptors/impl/AbstractClassDescriptor.java @@ -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(); } diff --git a/core/descriptors/src/org/jetbrains/jet/lang/descriptors/impl/MutableClassDescriptorLite.java b/core/descriptors/src/org/jetbrains/jet/lang/descriptors/impl/MutableClassDescriptorLite.java index ce14c5549ba..f16389af1a3 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/descriptors/impl/MutableClassDescriptorLite.java +++ b/core/descriptors/src/org/jetbrains/jet/lang/descriptors/impl/MutableClassDescriptorLite.java @@ -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; } 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 34e76937d33..d0432bb1711 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 @@ -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; } } diff --git a/core/descriptors/src/org/jetbrains/jet/lang/resolve/scopes/WritableScopeImpl.java b/core/descriptors/src/org/jetbrains/jet/lang/resolve/scopes/WritableScopeImpl.java index f3baed3ab58..9b04c0ce17f 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/resolve/scopes/WritableScopeImpl.java +++ b/core/descriptors/src/org/jetbrains/jet/lang/resolve/scopes/WritableScopeImpl.java @@ -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); }