From e3743ace4f483ff68e234a97b2c767e0bb35d1f5 Mon Sep 17 00:00:00 2001 From: Evgeny Gerashchenko Date: Fri, 20 Dec 2013 21:37:35 +0400 Subject: [PATCH] Added validation that all non-trait classes have at least one supertype. Fixed it for some class objects. --- .../jet/InlineStrategy.object.kotlin_class | Bin 55 -> 61 bytes .../DeserializedClassDescriptor.java | 1 + .../lang/resolve/TypeHierarchyResolver.java | 30 +++++++++++------- .../lazy/descriptors/LazyClassDescriptor.java | 3 +- .../jet/test/util/DescriptorValidator.java | 10 +++++- .../java/resolver/JavaClassResolver.java | 1 + 6 files changed, 31 insertions(+), 14 deletions(-) diff --git a/compiler/frontend/builtins/jet/InlineStrategy.object.kotlin_class b/compiler/frontend/builtins/jet/InlineStrategy.object.kotlin_class index 097db3005a5ba902fea583d689eaffb1a6b367c0..76b789ca145b8c19ceff5c7f60164973909a0a81 100644 GIT binary patch delta 17 YcmXrF<>qK(mPj#T;bIbCn#gJd02ulLsQ>@~ delta 11 ScmcCDXXR*PmPnb%Z3F-e`~p<~ diff --git a/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/descriptors/DeserializedClassDescriptor.java b/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/descriptors/DeserializedClassDescriptor.java index 6e8b71ad27c..7dd74c8758a 100644 --- a/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/descriptors/DeserializedClassDescriptor.java +++ b/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/descriptors/DeserializedClassDescriptor.java @@ -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.emptyList()); 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 3f8720e4996..e1a59dd542b 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java @@ -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.emptyList()); createPrimaryConstructorForObject(null, classObject); - classObject.createTypeConstructor(); return classObject; } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/descriptors/LazyClassDescriptor.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/descriptors/LazyClassDescriptor.java index 89174791e7a..f7241cde1f2 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/descriptors/LazyClassDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/descriptors/LazyClassDescriptor.java @@ -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 allSupertypes = resolveSession.getInjector().getDescriptorResolver() diff --git a/compiler/tests/org/jetbrains/jet/test/util/DescriptorValidator.java b/compiler/tests/org/jetbrains/jet/test/util/DescriptorValidator.java index 324024da5b4..e61c20434e7 100644 --- a/compiler/tests/org/jetbrains/jet/test/util/DescriptorValidator.java +++ b/compiler/tests/org/jetbrains/jet/test/util/DescriptorValidator.java @@ -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 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); diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaClassResolver.java b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaClassResolver.java index 97a98f5037d..b9c0b128fb2 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaClassResolver.java +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaClassResolver.java @@ -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.emptyList());