Added validation that all non-trait classes have at least one supertype.

Fixed it for some class objects.
This commit is contained in:
Evgeny Gerashchenko
2013-12-20 21:37:35 +04:00
parent 4329c42e3f
commit e3743ace4f
6 changed files with 31 additions and 14 deletions
@@ -264,6 +264,7 @@ public class DeserializedClassDescriptor extends AbstractClassDescriptor impleme
private MutableClassDescriptor createEnumClassObject() {
MutableClassDescriptor classObject = new MutableClassDescriptor(this, getScopeForMemberLookup(), ClassKind.CLASS_OBJECT,
false, getClassObjectName(getName()));
classObject.setSupertypes(Collections.singleton(KotlinBuiltIns.getInstance().getAnyType()));
classObject.setModality(Modality.FINAL);
classObject.setVisibility(DescriptorUtils.getSyntheticClassObjectVisibility());
classObject.setTypeParameterDescriptors(Collections.<TypeParameterDescriptor>emptyList());
@@ -29,11 +29,9 @@ import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.resolve.name.SpecialNames;
import org.jetbrains.jet.lang.resolve.scopes.*;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.SubstitutionUtils;
import org.jetbrains.jet.lang.types.TypeConstructor;
import org.jetbrains.jet.lang.types.TypeProjection;
import org.jetbrains.jet.lang.types.*;
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import org.jetbrains.jet.utils.DFS;
import javax.inject.Inject;
@@ -188,16 +186,24 @@ public class TypeHierarchyResolver {
descriptor.createTypeConstructor();
if (classOrObject instanceof JetEnumEntry ||
classOrObject instanceof JetObjectDeclaration && classOrObject.getNameIdentifier() != null) {
ClassKind kind = descriptor.getKind();
if (kind == ClassKind.ENUM_ENTRY || kind == ClassKind.OBJECT || kind == ClassKind.ENUM_CLASS) {
MutableClassDescriptorLite classObject = descriptor.getClassObjectDescriptor();
assert classObject != null : "Enum entries and named objects should have class objects: " + classOrObject.getText();
// 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.addSupertype(descriptor.getDefaultType());
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));
classObject.createTypeConstructor();
}
}
}
@@ -546,11 +552,11 @@ public class TypeHierarchyResolver {
private MutableClassDescriptor createSyntheticClassObject(@NotNull ClassDescriptor classDescriptor) {
MutableClassDescriptor classObject = new MutableClassDescriptor(classDescriptor, outerScope, ClassKind.CLASS_OBJECT, false,
getClassObjectName(classDescriptor.getName()));
classObject.setModality(Modality.FINAL);
classObject.setVisibility(DescriptorUtils.getSyntheticClassObjectVisibility());
classObject.setTypeParameterDescriptors(Collections.<TypeParameterDescriptor>emptyList());
createPrimaryConstructorForObject(null, classObject);
classObject.createTypeConstructor();
return classObject;
}
@@ -45,6 +45,7 @@ import org.jetbrains.jet.lang.resolve.scopes.*;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.TypeConstructor;
import org.jetbrains.jet.lang.types.TypeUtils;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import org.jetbrains.jet.storage.NotNullLazyValue;
import org.jetbrains.jet.storage.NullableLazyValue;
import org.jetbrains.jet.storage.StorageManager;
@@ -361,7 +362,7 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements LazyDesc
JetClassOrObject classOrObject = info.getCorrespondingClassOrObject();
if (classOrObject == null) {
return Collections.emptyList();
return Collections.singleton(KotlinBuiltIns.getInstance().getAnyType());
}
List<JetType> allSupertypes = resolveSession.getInjector().getDescriptorResolver()
@@ -23,6 +23,7 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import java.io.PrintStream;
import java.util.Arrays;
@@ -222,7 +223,14 @@ public class DescriptorValidator {
ClassDescriptor descriptor, DiagnosticCollector collector
) {
validateTypeParameters(collector, descriptor.getTypeConstructor().getParameters());
validateTypes(descriptor, collector, descriptor.getTypeConstructor().getSupertypes());
Collection<JetType> supertypes = descriptor.getTypeConstructor().getSupertypes();
if (supertypes.isEmpty() && descriptor.getKind() != ClassKind.TRAIT
&& KotlinBuiltIns.getInstance().getAny() != descriptor
&& KotlinBuiltIns.getInstance().getNothing() != descriptor) {
report(collector, descriptor, "No supertypes for non-trait");
}
validateTypes(descriptor, collector, supertypes);
validateType(descriptor, descriptor.getDefaultType(), collector);
@@ -427,6 +427,7 @@ public final class JavaClassResolver {
private JavaEnumClassObjectDescriptor createEnumClassObject(@NotNull ClassDescriptor enumClass, @NotNull JavaClass javaClass) {
JavaEnumClassObjectDescriptor classObject = new JavaEnumClassObjectDescriptor(enumClass);
classObject.setSupertypes(Collections.singleton(KotlinBuiltIns.getInstance().getAnyType()));
classObject.setModality(Modality.FINAL);
classObject.setVisibility(DescriptorUtils.getSyntheticClassObjectVisibility());
classObject.setTypeParameterDescriptors(Collections.<TypeParameterDescriptor>emptyList());