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 ded579ce706..edbff9af384 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DeclarationResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DeclarationResolver.java @@ -344,9 +344,10 @@ public class DeclarationResolver { Collection allDescriptors = classDescriptor.getScopeForMemberLookup().getOwnDeclaredDescriptors(); - ClassDescriptorWithResolutionScopes classObj = classDescriptor.getClassObjectDescriptor(); - if (classObj != null) { - Collection classObjDescriptors = classObj.getScopeForMemberLookup().getOwnDeclaredDescriptors(); + ClassDescriptor classObj = classDescriptor.getClassObjectDescriptor(); + if (classObj instanceof ClassDescriptorWithResolutionScopes) { + Collection classObjDescriptors = + ((ClassDescriptorWithResolutionScopes) classObj).getScopeForMemberLookup().getOwnDeclaredDescriptors(); if (!classObjDescriptors.isEmpty()) { allDescriptors = Lists.newArrayList(allDescriptors); allDescriptors.addAll(classObjDescriptors); 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 e5b1be44da5..8843a35bd6b 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/OverrideResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/OverrideResolver.java @@ -85,9 +85,9 @@ public class OverrideResolver { if (ourClasses.contains(klass)) { generateOverridesAndDelegationInAClass(klass, processed, ourClasses); - MutableClassDescriptor classObject = klass.getClassObjectDescriptor(); - if (classObject != null) { - generateOverridesAndDelegationInAClass(classObject, processed, ourClasses); + ClassDescriptor classObject = klass.getClassObjectDescriptor(); + if (classObject instanceof MutableClassDescriptor) { + generateOverridesAndDelegationInAClass((MutableClassDescriptor) classObject, processed, ourClasses); } } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java index ee5dd70d4e6..716d37840c9 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java @@ -245,7 +245,7 @@ public class TopDownAnalyzer { } @Override - public ClassObjectStatus setClassObjectDescriptor(@NotNull MutableClassDescriptor classObjectDescriptor) { + public ClassObjectStatus setClassObjectDescriptor(@NotNull ClassDescriptor classObjectDescriptor) { return ClassObjectStatus.NOT_ALLOWED; } }, 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 9ff9a56f5c6..7085721fe60 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java @@ -21,10 +21,7 @@ import com.intellij.psi.PsiNameIdentifierOwner; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.*; -import org.jetbrains.jet.lang.descriptors.impl.ConstructorDescriptorImpl; -import org.jetbrains.jet.lang.descriptors.impl.MutableClassDescriptor; -import org.jetbrains.jet.lang.descriptors.impl.MutablePackageFragmentDescriptor; -import org.jetbrains.jet.lang.descriptors.impl.PackageLikeBuilder; +import org.jetbrains.jet.lang.descriptors.impl.*; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.resolve.name.SpecialNames; @@ -33,7 +30,7 @@ import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.resolve.scopes.WritableScope; import org.jetbrains.jet.lang.resolve.scopes.WriteThroughScope; import org.jetbrains.jet.lang.types.JetType; -import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; +import org.jetbrains.jet.storage.LockBasedStorageManager; import org.jetbrains.jet.utils.DFS; import javax.inject.Inject; @@ -203,22 +200,16 @@ public class TypeHierarchyResolver { descriptor.createTypeConstructor(); ClassKind kind = descriptor.getKind(); - if (kind == ClassKind.ENUM_ENTRY || kind == ClassKind.OBJECT || kind == ClassKind.ENUM_CLASS) { - MutableClassDescriptor classObject = descriptor.getClassObjectDescriptor(); + if (kind == ClassKind.ENUM_ENTRY || kind == ClassKind.OBJECT) { + MutableClassDescriptor classObject = (MutableClassDescriptor) descriptor.getClassObjectDescriptor(); assert classObject != null : "Enum entries and named objects should have class objects: " + classOrObject.getText(); - JetType supertype; - if (kind == ClassKind.ENUM_CLASS) { - supertype = KotlinBuiltIns.getInstance().getAnyType(); - } - else { - // This is a clever hack: each enum entry and object declaration (i.e. singleton) has a synthetic class object. - // We make this class object inherit from the singleton here, thus allowing to use the singleton's class object where - // the instance of the singleton is applicable. Effectively all members of the singleton would be present in its class - // object as fake overrides, so you can access them via standard class object notation: ObjectName.memberName() - supertype = descriptor.getDefaultType(); - } - classObject.setSupertypes(Collections.singleton(supertype)); + // This is a clever hack: each enum entry and object declaration (i.e. singleton) has a synthetic class object. + // We make this class object inherit from the singleton here, thus allowing to use the singleton's class object where + // the instance of the singleton is applicable. Effectively all members of the singleton would be present in its class + // object as fake overrides, so you can access them via standard class object notation: ObjectName.memberName() + classObject.setSupertypes(Collections.singleton(descriptor.getDefaultType())); + classObject.createTypeConstructor(); } } @@ -377,7 +368,7 @@ public class TypeHierarchyResolver { owner.addClassifierDescriptor(descriptor); trace.record(FQNAME_TO_CLASS_DESCRIPTOR, JetNamedDeclarationUtil.getUnsafeFQName(declaration), descriptor); - descriptor.getBuilder().setClassObjectDescriptor(createSyntheticClassObject(descriptor)); + descriptor.getBuilder().setClassObjectDescriptor(createSyntheticClassObjectForSingleton(descriptor)); } @Override @@ -387,7 +378,7 @@ public class TypeHierarchyResolver { owner.addClassifierDescriptor(descriptor); - descriptor.getBuilder().setClassObjectDescriptor(createSyntheticClassObject(descriptor)); + descriptor.getBuilder().setClassObjectDescriptor(createSyntheticClassObjectForSingleton(descriptor)); } @Override @@ -438,17 +429,8 @@ public class TypeHierarchyResolver { } - private void createClassObjectForEnumClass(@NotNull MutableClassDescriptor mutableClassDescriptor) { - if (mutableClassDescriptor.getKind() == ClassKind.ENUM_CLASS) { - MutableClassDescriptor classObject = createSyntheticClassObject(mutableClassDescriptor); - mutableClassDescriptor.getBuilder().setClassObjectDescriptor(classObject); - classObject.getBuilder().addFunctionDescriptor(DescriptorResolver.createEnumClassObjectValuesMethod(classObject, trace)); - classObject.getBuilder().addFunctionDescriptor(DescriptorResolver.createEnumClassObjectValueOfMethod(classObject, trace)); - } - } - @NotNull - private MutableClassDescriptor createSyntheticClassObject(@NotNull ClassDescriptor classDescriptor) { + private MutableClassDescriptor createSyntheticClassObjectForSingleton(@NotNull ClassDescriptor classDescriptor) { MutableClassDescriptor classObject = new MutableClassDescriptor(classDescriptor, outerScope, ClassKind.CLASS_OBJECT, false, getClassObjectName(classDescriptor.getName())); @@ -468,18 +450,19 @@ public class TypeHierarchyResolver { // Kind check is needed in order to not consider enums as inner in any case // (otherwise it would be impossible to create a class object in the enum) boolean isInner = kind == ClassKind.CLASS && klass.isInner(); - MutableClassDescriptor mutableClassDescriptor = new MutableClassDescriptor( - containingDeclaration, outerScope, kind, isInner, JetPsiUtil.safeName(klass.getName())); - c.getDeclaredClasses().put(klass, mutableClassDescriptor); - trace.record(FQNAME_TO_CLASS_DESCRIPTOR, JetNamedDeclarationUtil.getUnsafeFQName(klass), mutableClassDescriptor); + MutableClassDescriptor descriptor = new MutableClassDescriptor(containingDeclaration, outerScope, kind, isInner, + JetPsiUtil.safeName(klass.getName())); + c.getDeclaredClasses().put(klass, descriptor); + trace.record(FQNAME_TO_CLASS_DESCRIPTOR, JetNamedDeclarationUtil.getUnsafeFQName(klass), descriptor); - createClassObjectForEnumClass(mutableClassDescriptor); + if (descriptor.getKind() == ClassKind.ENUM_CLASS) { + ClassDescriptor classObject = new EnumClassObjectDescriptor(LockBasedStorageManager.NO_LOCKS, descriptor); + descriptor.getBuilder().setClassObjectDescriptor(classObject); + } - JetScope classScope = mutableClassDescriptor.getScopeForMemberDeclarationResolution(); + prepareForDeferredCall(descriptor.getScopeForMemberDeclarationResolution(), descriptor, klass); - prepareForDeferredCall(classScope, mutableClassDescriptor, klass); - - return mutableClassDescriptor; + return descriptor; } @NotNull diff --git a/core/descriptors/src/org/jetbrains/jet/lang/descriptors/ClassDescriptorWithResolutionScopes.java b/core/descriptors/src/org/jetbrains/jet/lang/descriptors/ClassDescriptorWithResolutionScopes.java index ad0efd0451e..e8325a222dc 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/descriptors/ClassDescriptorWithResolutionScopes.java +++ b/core/descriptors/src/org/jetbrains/jet/lang/descriptors/ClassDescriptorWithResolutionScopes.java @@ -17,7 +17,6 @@ package org.jetbrains.jet.lang.descriptors; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.ReadOnly; import org.jetbrains.jet.lang.resolve.scopes.JetScope; @@ -36,10 +35,6 @@ public interface ClassDescriptorWithResolutionScopes extends ClassDescriptor { @NotNull JetScope getScopeForMemberLookup(); - @Nullable - @Override - ClassDescriptorWithResolutionScopes getClassObjectDescriptor(); - @NotNull @ReadOnly Collection getDeclaredCallableMembers(); diff --git a/core/descriptors/src/org/jetbrains/jet/lang/descriptors/impl/EnumClassObjectDescriptor.kt b/core/descriptors/src/org/jetbrains/jet/lang/descriptors/impl/EnumClassObjectDescriptor.kt index 69647774c32..594325f8723 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/descriptors/impl/EnumClassObjectDescriptor.kt +++ b/core/descriptors/src/org/jetbrains/jet/lang/descriptors/impl/EnumClassObjectDescriptor.kt @@ -50,7 +50,9 @@ public class EnumClassObjectDescriptor( private val scope = WritableScopeImpl(JetScope.EMPTY, this, RedeclarationHandler.DO_NOTHING, "MemberLookup") ;{ - val enumType = (getContainingDeclaration() as ClassDescriptor).getDefaultType() + val enumType = object : DelegatingType() { + override fun getDelegate() = (getContainingDeclaration() as ClassDescriptor).getDefaultType() + } val enumArrayType = KotlinBuiltIns.getInstance().getArrayType(enumType) scope.addFunctionDescriptor(DescriptorFactory.createEnumClassObjectValuesMethod(this, enumArrayType)) scope.addFunctionDescriptor(DescriptorFactory.createEnumClassObjectValueOfMethod(this, enumType)) diff --git a/core/descriptors/src/org/jetbrains/jet/lang/descriptors/impl/MutableClassDescriptor.java b/core/descriptors/src/org/jetbrains/jet/lang/descriptors/impl/MutableClassDescriptor.java index caa0d911e75..ac7740b0eb1 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/descriptors/impl/MutableClassDescriptor.java +++ b/core/descriptors/src/org/jetbrains/jet/lang/descriptors/impl/MutableClassDescriptor.java @@ -44,7 +44,7 @@ public class MutableClassDescriptor extends ClassDescriptorBase implements Class private List typeParameters; private Collection supertypes = new ArrayList(); - private MutableClassDescriptor classObjectDescriptor; + private ClassDescriptor classObjectDescriptor; private final Set constructors = Sets.newLinkedHashSet(); private ConstructorDescriptor primaryConstructor; @@ -88,7 +88,7 @@ public class MutableClassDescriptor extends ClassDescriptorBase implements Class @Nullable @Override - public MutableClassDescriptor getClassObjectDescriptor() { + public ClassDescriptor getClassObjectDescriptor() { return classObjectDescriptor; } @@ -296,8 +296,8 @@ public class MutableClassDescriptor extends ClassDescriptorBase implements Class public void lockScopes() { getScopeForMemberLookupAsWritableScope().changeLockLevel(WritableScope.LockLevel.READING); - if (classObjectDescriptor != null) { - classObjectDescriptor.lockScopes(); + if (classObjectDescriptor instanceof MutableClassDescriptor) { + ((MutableClassDescriptor) classObjectDescriptor).lockScopes(); } scopeForSupertypeResolution.changeLockLevel(WritableScope.LockLevel.READING); scopeForMemberResolution.changeLockLevel(WritableScope.LockLevel.READING); @@ -334,7 +334,7 @@ public class MutableClassDescriptor extends ClassDescriptorBase implements Class } @Override - public ClassObjectStatus setClassObjectDescriptor(@NotNull MutableClassDescriptor classObjectDescriptor) { + public ClassObjectStatus setClassObjectDescriptor(@NotNull ClassDescriptor classObjectDescriptor) { if (getKind() == ClassKind.CLASS_OBJECT || isInner()) { return ClassObjectStatus.NOT_ALLOWED; } diff --git a/core/descriptors/src/org/jetbrains/jet/lang/descriptors/impl/PackageLikeBuilder.java b/core/descriptors/src/org/jetbrains/jet/lang/descriptors/impl/PackageLikeBuilder.java index 7478999acc8..a4cda695b60 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/descriptors/impl/PackageLikeBuilder.java +++ b/core/descriptors/src/org/jetbrains/jet/lang/descriptors/impl/PackageLikeBuilder.java @@ -17,6 +17,7 @@ package org.jetbrains.jet.lang.descriptors.impl; import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.descriptors.PropertyDescriptor; import org.jetbrains.jet.lang.descriptors.SimpleFunctionDescriptor; @@ -37,5 +38,5 @@ public interface PackageLikeBuilder { NOT_ALLOWED } - ClassObjectStatus setClassObjectDescriptor(@NotNull MutableClassDescriptor classObjectDescriptor); + ClassObjectStatus setClassObjectDescriptor(@NotNull ClassDescriptor classObjectDescriptor); } diff --git a/core/descriptors/src/org/jetbrains/jet/lang/descriptors/impl/PackageLikeBuilderDummy.java b/core/descriptors/src/org/jetbrains/jet/lang/descriptors/impl/PackageLikeBuilderDummy.java index f64f02f74c4..7c278df932e 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/descriptors/impl/PackageLikeBuilderDummy.java +++ b/core/descriptors/src/org/jetbrains/jet/lang/descriptors/impl/PackageLikeBuilderDummy.java @@ -17,6 +17,7 @@ package org.jetbrains.jet.lang.descriptors.impl; import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.descriptors.PropertyDescriptor; import org.jetbrains.jet.lang.descriptors.SimpleFunctionDescriptor; @@ -44,7 +45,7 @@ public class PackageLikeBuilderDummy implements PackageLikeBuilder { } @Override - public ClassObjectStatus setClassObjectDescriptor(@NotNull MutableClassDescriptor classObjectDescriptor) { + public ClassObjectStatus setClassObjectDescriptor(@NotNull ClassDescriptor classObjectDescriptor) { throw new IllegalStateException(); } } diff --git a/core/descriptors/src/org/jetbrains/jet/lang/descriptors/impl/ScopeBasedPackageLikeBuilder.java b/core/descriptors/src/org/jetbrains/jet/lang/descriptors/impl/ScopeBasedPackageLikeBuilder.java index 973ce2efa5a..3234fa4cfe4 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/descriptors/impl/ScopeBasedPackageLikeBuilder.java +++ b/core/descriptors/src/org/jetbrains/jet/lang/descriptors/impl/ScopeBasedPackageLikeBuilder.java @@ -17,6 +17,7 @@ package org.jetbrains.jet.lang.descriptors.impl; import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.descriptors.PropertyDescriptor; import org.jetbrains.jet.lang.descriptors.SimpleFunctionDescriptor; @@ -56,7 +57,7 @@ public class ScopeBasedPackageLikeBuilder implements PackageLikeBuilder { } @Override - public ClassObjectStatus setClassObjectDescriptor(@NotNull MutableClassDescriptor classObjectDescriptor) { + public ClassObjectStatus setClassObjectDescriptor(@NotNull ClassDescriptor classObjectDescriptor) { throw new IllegalStateException("Must be guaranteed not to happen by the parser"); } }