Use EnumClassObjectDescriptor in TypeHierarchyResolver
This commit is contained in:
@@ -344,9 +344,10 @@ public class DeclarationResolver {
|
|||||||
|
|
||||||
Collection<DeclarationDescriptor> allDescriptors = classDescriptor.getScopeForMemberLookup().getOwnDeclaredDescriptors();
|
Collection<DeclarationDescriptor> allDescriptors = classDescriptor.getScopeForMemberLookup().getOwnDeclaredDescriptors();
|
||||||
|
|
||||||
ClassDescriptorWithResolutionScopes classObj = classDescriptor.getClassObjectDescriptor();
|
ClassDescriptor classObj = classDescriptor.getClassObjectDescriptor();
|
||||||
if (classObj != null) {
|
if (classObj instanceof ClassDescriptorWithResolutionScopes) {
|
||||||
Collection<DeclarationDescriptor> classObjDescriptors = classObj.getScopeForMemberLookup().getOwnDeclaredDescriptors();
|
Collection<DeclarationDescriptor> classObjDescriptors =
|
||||||
|
((ClassDescriptorWithResolutionScopes) classObj).getScopeForMemberLookup().getOwnDeclaredDescriptors();
|
||||||
if (!classObjDescriptors.isEmpty()) {
|
if (!classObjDescriptors.isEmpty()) {
|
||||||
allDescriptors = Lists.newArrayList(allDescriptors);
|
allDescriptors = Lists.newArrayList(allDescriptors);
|
||||||
allDescriptors.addAll(classObjDescriptors);
|
allDescriptors.addAll(classObjDescriptors);
|
||||||
|
|||||||
@@ -85,9 +85,9 @@ public class OverrideResolver {
|
|||||||
if (ourClasses.contains(klass)) {
|
if (ourClasses.contains(klass)) {
|
||||||
generateOverridesAndDelegationInAClass(klass, processed, ourClasses);
|
generateOverridesAndDelegationInAClass(klass, processed, ourClasses);
|
||||||
|
|
||||||
MutableClassDescriptor classObject = klass.getClassObjectDescriptor();
|
ClassDescriptor classObject = klass.getClassObjectDescriptor();
|
||||||
if (classObject != null) {
|
if (classObject instanceof MutableClassDescriptor) {
|
||||||
generateOverridesAndDelegationInAClass(classObject, processed, ourClasses);
|
generateOverridesAndDelegationInAClass((MutableClassDescriptor) classObject, processed, ourClasses);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -245,7 +245,7 @@ public class TopDownAnalyzer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ClassObjectStatus setClassObjectDescriptor(@NotNull MutableClassDescriptor classObjectDescriptor) {
|
public ClassObjectStatus setClassObjectDescriptor(@NotNull ClassDescriptor classObjectDescriptor) {
|
||||||
return ClassObjectStatus.NOT_ALLOWED;
|
return ClassObjectStatus.NOT_ALLOWED;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -21,10 +21,7 @@ import com.intellij.psi.PsiNameIdentifierOwner;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.lang.descriptors.*;
|
import org.jetbrains.jet.lang.descriptors.*;
|
||||||
import org.jetbrains.jet.lang.descriptors.impl.ConstructorDescriptorImpl;
|
import org.jetbrains.jet.lang.descriptors.impl.*;
|
||||||
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.psi.*;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||||
import org.jetbrains.jet.lang.resolve.name.SpecialNames;
|
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.WritableScope;
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.WriteThroughScope;
|
import org.jetbrains.jet.lang.resolve.scopes.WriteThroughScope;
|
||||||
import org.jetbrains.jet.lang.types.JetType;
|
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 org.jetbrains.jet.utils.DFS;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
@@ -203,22 +200,16 @@ public class TypeHierarchyResolver {
|
|||||||
descriptor.createTypeConstructor();
|
descriptor.createTypeConstructor();
|
||||||
|
|
||||||
ClassKind kind = descriptor.getKind();
|
ClassKind kind = descriptor.getKind();
|
||||||
if (kind == ClassKind.ENUM_ENTRY || kind == ClassKind.OBJECT || kind == ClassKind.ENUM_CLASS) {
|
if (kind == ClassKind.ENUM_ENTRY || kind == ClassKind.OBJECT) {
|
||||||
MutableClassDescriptor classObject = descriptor.getClassObjectDescriptor();
|
MutableClassDescriptor classObject = (MutableClassDescriptor) descriptor.getClassObjectDescriptor();
|
||||||
assert classObject != null : "Enum entries and named objects should have class objects: " + classOrObject.getText();
|
assert classObject != null : "Enum entries and named objects should have class objects: " + classOrObject.getText();
|
||||||
|
|
||||||
JetType supertype;
|
// This is a clever hack: each enum entry and object declaration (i.e. singleton) has a synthetic class object.
|
||||||
if (kind == ClassKind.ENUM_CLASS) {
|
// We make this class object inherit from the singleton here, thus allowing to use the singleton's class object where
|
||||||
supertype = KotlinBuiltIns.getInstance().getAnyType();
|
// 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()
|
||||||
else {
|
classObject.setSupertypes(Collections.singleton(descriptor.getDefaultType()));
|
||||||
// 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));
|
|
||||||
classObject.createTypeConstructor();
|
classObject.createTypeConstructor();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -377,7 +368,7 @@ public class TypeHierarchyResolver {
|
|||||||
owner.addClassifierDescriptor(descriptor);
|
owner.addClassifierDescriptor(descriptor);
|
||||||
trace.record(FQNAME_TO_CLASS_DESCRIPTOR, JetNamedDeclarationUtil.getUnsafeFQName(declaration), descriptor);
|
trace.record(FQNAME_TO_CLASS_DESCRIPTOR, JetNamedDeclarationUtil.getUnsafeFQName(declaration), descriptor);
|
||||||
|
|
||||||
descriptor.getBuilder().setClassObjectDescriptor(createSyntheticClassObject(descriptor));
|
descriptor.getBuilder().setClassObjectDescriptor(createSyntheticClassObjectForSingleton(descriptor));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -387,7 +378,7 @@ public class TypeHierarchyResolver {
|
|||||||
|
|
||||||
owner.addClassifierDescriptor(descriptor);
|
owner.addClassifierDescriptor(descriptor);
|
||||||
|
|
||||||
descriptor.getBuilder().setClassObjectDescriptor(createSyntheticClassObject(descriptor));
|
descriptor.getBuilder().setClassObjectDescriptor(createSyntheticClassObjectForSingleton(descriptor));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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
|
@NotNull
|
||||||
private MutableClassDescriptor createSyntheticClassObject(@NotNull ClassDescriptor classDescriptor) {
|
private MutableClassDescriptor createSyntheticClassObjectForSingleton(@NotNull ClassDescriptor classDescriptor) {
|
||||||
MutableClassDescriptor classObject = new MutableClassDescriptor(classDescriptor, outerScope, ClassKind.CLASS_OBJECT, false,
|
MutableClassDescriptor classObject = new MutableClassDescriptor(classDescriptor, outerScope, ClassKind.CLASS_OBJECT, false,
|
||||||
getClassObjectName(classDescriptor.getName()));
|
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
|
// 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)
|
// (otherwise it would be impossible to create a class object in the enum)
|
||||||
boolean isInner = kind == ClassKind.CLASS && klass.isInner();
|
boolean isInner = kind == ClassKind.CLASS && klass.isInner();
|
||||||
MutableClassDescriptor mutableClassDescriptor = new MutableClassDescriptor(
|
MutableClassDescriptor descriptor = new MutableClassDescriptor(containingDeclaration, outerScope, kind, isInner,
|
||||||
containingDeclaration, outerScope, kind, isInner, JetPsiUtil.safeName(klass.getName()));
|
JetPsiUtil.safeName(klass.getName()));
|
||||||
c.getDeclaredClasses().put(klass, mutableClassDescriptor);
|
c.getDeclaredClasses().put(klass, descriptor);
|
||||||
trace.record(FQNAME_TO_CLASS_DESCRIPTOR, JetNamedDeclarationUtil.getUnsafeFQName(klass), mutableClassDescriptor);
|
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 descriptor;
|
||||||
|
|
||||||
return mutableClassDescriptor;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
|
|||||||
-5
@@ -17,7 +17,6 @@
|
|||||||
package org.jetbrains.jet.lang.descriptors;
|
package org.jetbrains.jet.lang.descriptors;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
import org.jetbrains.annotations.ReadOnly;
|
import org.jetbrains.annotations.ReadOnly;
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||||
|
|
||||||
@@ -36,10 +35,6 @@ public interface ClassDescriptorWithResolutionScopes extends ClassDescriptor {
|
|||||||
@NotNull
|
@NotNull
|
||||||
JetScope getScopeForMemberLookup();
|
JetScope getScopeForMemberLookup();
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
ClassDescriptorWithResolutionScopes getClassObjectDescriptor();
|
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@ReadOnly
|
@ReadOnly
|
||||||
Collection<CallableMemberDescriptor> getDeclaredCallableMembers();
|
Collection<CallableMemberDescriptor> getDeclaredCallableMembers();
|
||||||
|
|||||||
+3
-1
@@ -50,7 +50,9 @@ public class EnumClassObjectDescriptor(
|
|||||||
private val scope = WritableScopeImpl(JetScope.EMPTY, this, RedeclarationHandler.DO_NOTHING, "MemberLookup")
|
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)
|
val enumArrayType = KotlinBuiltIns.getInstance().getArrayType(enumType)
|
||||||
scope.addFunctionDescriptor(DescriptorFactory.createEnumClassObjectValuesMethod(this, enumArrayType))
|
scope.addFunctionDescriptor(DescriptorFactory.createEnumClassObjectValuesMethod(this, enumArrayType))
|
||||||
scope.addFunctionDescriptor(DescriptorFactory.createEnumClassObjectValueOfMethod(this, enumType))
|
scope.addFunctionDescriptor(DescriptorFactory.createEnumClassObjectValueOfMethod(this, enumType))
|
||||||
|
|||||||
+5
-5
@@ -44,7 +44,7 @@ public class MutableClassDescriptor extends ClassDescriptorBase implements Class
|
|||||||
private List<TypeParameterDescriptor> typeParameters;
|
private List<TypeParameterDescriptor> typeParameters;
|
||||||
private Collection<JetType> supertypes = new ArrayList<JetType>();
|
private Collection<JetType> supertypes = new ArrayList<JetType>();
|
||||||
|
|
||||||
private MutableClassDescriptor classObjectDescriptor;
|
private ClassDescriptor classObjectDescriptor;
|
||||||
|
|
||||||
private final Set<ConstructorDescriptor> constructors = Sets.newLinkedHashSet();
|
private final Set<ConstructorDescriptor> constructors = Sets.newLinkedHashSet();
|
||||||
private ConstructorDescriptor primaryConstructor;
|
private ConstructorDescriptor primaryConstructor;
|
||||||
@@ -88,7 +88,7 @@ public class MutableClassDescriptor extends ClassDescriptorBase implements Class
|
|||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public MutableClassDescriptor getClassObjectDescriptor() {
|
public ClassDescriptor getClassObjectDescriptor() {
|
||||||
return classObjectDescriptor;
|
return classObjectDescriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -296,8 +296,8 @@ public class MutableClassDescriptor extends ClassDescriptorBase implements Class
|
|||||||
|
|
||||||
public void lockScopes() {
|
public void lockScopes() {
|
||||||
getScopeForMemberLookupAsWritableScope().changeLockLevel(WritableScope.LockLevel.READING);
|
getScopeForMemberLookupAsWritableScope().changeLockLevel(WritableScope.LockLevel.READING);
|
||||||
if (classObjectDescriptor != null) {
|
if (classObjectDescriptor instanceof MutableClassDescriptor) {
|
||||||
classObjectDescriptor.lockScopes();
|
((MutableClassDescriptor) classObjectDescriptor).lockScopes();
|
||||||
}
|
}
|
||||||
scopeForSupertypeResolution.changeLockLevel(WritableScope.LockLevel.READING);
|
scopeForSupertypeResolution.changeLockLevel(WritableScope.LockLevel.READING);
|
||||||
scopeForMemberResolution.changeLockLevel(WritableScope.LockLevel.READING);
|
scopeForMemberResolution.changeLockLevel(WritableScope.LockLevel.READING);
|
||||||
@@ -334,7 +334,7 @@ public class MutableClassDescriptor extends ClassDescriptorBase implements Class
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ClassObjectStatus setClassObjectDescriptor(@NotNull MutableClassDescriptor classObjectDescriptor) {
|
public ClassObjectStatus setClassObjectDescriptor(@NotNull ClassDescriptor classObjectDescriptor) {
|
||||||
if (getKind() == ClassKind.CLASS_OBJECT || isInner()) {
|
if (getKind() == ClassKind.CLASS_OBJECT || isInner()) {
|
||||||
return ClassObjectStatus.NOT_ALLOWED;
|
return ClassObjectStatus.NOT_ALLOWED;
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -17,6 +17,7 @@
|
|||||||
package org.jetbrains.jet.lang.descriptors.impl;
|
package org.jetbrains.jet.lang.descriptors.impl;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
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.DeclarationDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
|
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.SimpleFunctionDescriptor;
|
import org.jetbrains.jet.lang.descriptors.SimpleFunctionDescriptor;
|
||||||
@@ -37,5 +38,5 @@ public interface PackageLikeBuilder {
|
|||||||
NOT_ALLOWED
|
NOT_ALLOWED
|
||||||
}
|
}
|
||||||
|
|
||||||
ClassObjectStatus setClassObjectDescriptor(@NotNull MutableClassDescriptor classObjectDescriptor);
|
ClassObjectStatus setClassObjectDescriptor(@NotNull ClassDescriptor classObjectDescriptor);
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -17,6 +17,7 @@
|
|||||||
package org.jetbrains.jet.lang.descriptors.impl;
|
package org.jetbrains.jet.lang.descriptors.impl;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
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.DeclarationDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
|
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.SimpleFunctionDescriptor;
|
import org.jetbrains.jet.lang.descriptors.SimpleFunctionDescriptor;
|
||||||
@@ -44,7 +45,7 @@ public class PackageLikeBuilderDummy implements PackageLikeBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ClassObjectStatus setClassObjectDescriptor(@NotNull MutableClassDescriptor classObjectDescriptor) {
|
public ClassObjectStatus setClassObjectDescriptor(@NotNull ClassDescriptor classObjectDescriptor) {
|
||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -17,6 +17,7 @@
|
|||||||
package org.jetbrains.jet.lang.descriptors.impl;
|
package org.jetbrains.jet.lang.descriptors.impl;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
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.DeclarationDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
|
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.SimpleFunctionDescriptor;
|
import org.jetbrains.jet.lang.descriptors.SimpleFunctionDescriptor;
|
||||||
@@ -56,7 +57,7 @@ public class ScopeBasedPackageLikeBuilder implements PackageLikeBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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");
|
throw new IllegalStateException("Must be guaranteed not to happen by the parser");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user