public static boolean isDirectSubclass( @NotNull ClassDescriptor subClass, @NotNull ClassDescriptor superClass) { for (KotlinType superType : subClass.getTypeConstructor().getSupertypes()) { if (isSameClass(superType, superClass.getOriginal())) { return true; } } return false; }
@Nullable public static ReceiverParameterDescriptor getDispatchReceiverParameterIfNeeded( @NotNull DeclarationDescriptor containingDeclaration) { if (containingDeclaration instanceof ClassDescriptor) { ClassDescriptor classDescriptor = (ClassDescriptor) containingDeclaration; return classDescriptor.getThisAsReceiverParameter(); } return null; }
@Nullable public static ClassDescriptor getSuperClassDescriptor(@NotNull ClassDescriptor classDescriptor) { Collection<KotlinType> superclassTypes = classDescriptor.getTypeConstructor().getSupertypes(); for (KotlinType type : superclassTypes) { ClassDescriptor superClassDescriptor = getClassDescriptorForType(type); if (superClassDescriptor.getKind() != ClassKind.INTERFACE) { return superClassDescriptor; } } return null; }
@NotNull public static KotlinType getSuperClassType(@NotNull ClassDescriptor classDescriptor) { Collection<KotlinType> superclassTypes = classDescriptor.getTypeConstructor().getSupertypes(); for (KotlinType type : superclassTypes) { ClassDescriptor superClassDescriptor = getClassDescriptorForType(type); if (superClassDescriptor.getKind() != ClassKind.INTERFACE) { return type; } } return getBuiltIns(classDescriptor).getAnyType(); }
@NotNull public JetType getFunctionType( @NotNull Annotations annotations, @Nullable JetType receiverType, @NotNull List<JetType> parameterTypes, @NotNull JetType returnType) { List<TypeProjection> arguments = getFunctionTypeArgumentProjections(receiverType, parameterTypes, returnType); int size = parameterTypes.size(); ClassDescriptor classDescriptor = receiverType == null ? getFunction(size) : getExtensionFunction(size); TypeConstructor constructor = classDescriptor.getTypeConstructor(); return new JetTypeImpl( annotations, constructor, false, arguments, classDescriptor.getMemberScope(arguments)); }
@Nullable private static ClassDescriptor getEnumEntry( @NotNull ClassDescriptor enumDescriptor, @NotNull String entryName) { ClassifierDescriptor result = enumDescriptor .getUnsubstitutedInnerClassesScope() .getContributedClassifier(Name.identifier(entryName), NoLookupLocation.FROM_BUILTINS); return result instanceof ClassDescriptor ? (ClassDescriptor) result : null; }
@NotNull public static List<ClassDescriptor> getSuperclassDescriptors( @NotNull ClassDescriptor classDescriptor) { Collection<KotlinType> superclassTypes = classDescriptor.getTypeConstructor().getSupertypes(); List<ClassDescriptor> superClassDescriptors = new ArrayList<ClassDescriptor>(); for (KotlinType type : superclassTypes) { ClassDescriptor result = getClassDescriptorForType(type); if (!isAny(result)) { superClassDescriptors.add(result); } } return superClassDescriptors; }
@NotNull public static Visibility getDefaultConstructorVisibility( @NotNull ClassDescriptor classDescriptor) { ClassKind classKind = classDescriptor.getKind(); if (classKind == ClassKind.ENUM_CLASS || classKind.isSingleton() || isSealedClass(classDescriptor)) { return Visibilities.PRIVATE; } if (isAnonymousObject(classDescriptor)) { return Visibilities.DEFAULT_VISIBILITY; } assert classKind == ClassKind.CLASS || classKind == ClassKind.INTERFACE || classKind == ClassKind.ANNOTATION_CLASS; return Visibilities.PUBLIC; }
// TODO: should be internal @Nullable public static ClassDescriptor getInnerClassByName( @NotNull ClassDescriptor classDescriptor, @NotNull String innerClassName, @NotNull LookupLocation location) { ClassifierDescriptor classifier = classDescriptor .getDefaultType() .getMemberScope() .getContributedClassifier(Name.identifier(innerClassName), location); assert classifier instanceof ClassDescriptor : "Inner class " + innerClassName + " in " + classDescriptor + " should be instance of ClassDescriptor, but was: " + (classifier == null ? "null" : classifier.getClass()); return (ClassDescriptor) classifier; }
// Returns a set of enum or sealed types of which supertypeOwner is an entry or a member @NotNull private static Set<TypeConstructor> getAllowedFinalSupertypes( @NotNull ClassDescriptor descriptor, @NotNull JetClassOrObject jetClass) { Set<TypeConstructor> parentEnumOrSealed; if (jetClass instanceof JetEnumEntry) { parentEnumOrSealed = Collections.singleton( ((ClassDescriptor) descriptor.getContainingDeclaration()).getTypeConstructor()); } else { parentEnumOrSealed = Collections.emptySet(); ClassDescriptor currentDescriptor = descriptor; while (currentDescriptor.getContainingDeclaration() instanceof ClassDescriptor) { currentDescriptor = (ClassDescriptor) currentDescriptor.getContainingDeclaration(); if (currentDescriptor.getModality() == Modality.SEALED) { if (parentEnumOrSealed.isEmpty()) { parentEnumOrSealed = new HashSet<TypeConstructor>(); } parentEnumOrSealed.add(currentDescriptor.getTypeConstructor()); } } } return parentEnumOrSealed; }
public static boolean isSingletonOrAnonymousObject(@NotNull ClassDescriptor classDescriptor) { return classDescriptor.getKind().isSingleton() || isAnonymousObject(classDescriptor); }
public static boolean classCanHaveOpenMembers(@NotNull ClassDescriptor classDescriptor) { return classDescriptor.getModality() != Modality.FINAL || classDescriptor.getKind() == ClassKind.ENUM_CLASS; }
public static boolean classCanHaveAbstractMembers(@NotNull ClassDescriptor classDescriptor) { return classDescriptor.getModality() == Modality.ABSTRACT || isSealedClass(classDescriptor) || classDescriptor.getKind() == ClassKind.ENUM_CLASS; }
/** @return true iff {@code descriptor}'s first non-class container is a package */ public static boolean isTopLevelOrInnerClass(@NotNull ClassDescriptor descriptor) { DeclarationDescriptor containing = descriptor.getContainingDeclaration(); return isTopLevelDeclaration(descriptor) || containing instanceof ClassDescriptor && isTopLevelOrInnerClass((ClassDescriptor) containing); }
public static boolean isSubclass( @NotNull ClassDescriptor subClass, @NotNull ClassDescriptor superClass) { return isSubtypeOfClass(subClass.getDefaultType(), superClass.getOriginal()); }
private void checkSupertypeList( @NotNull ClassDescriptor supertypeOwner, @NotNull Map<JetTypeReference, JetType> supertypes, @NotNull JetClassOrObject jetClass) { Set<TypeConstructor> allowedFinalSupertypes = getAllowedFinalSupertypes(supertypeOwner, jetClass); Set<TypeConstructor> typeConstructors = Sets.newHashSet(); boolean classAppeared = false; for (Map.Entry<JetTypeReference, JetType> entry : supertypes.entrySet()) { JetTypeReference typeReference = entry.getKey(); JetType supertype = entry.getValue(); boolean addSupertype = true; ClassDescriptor classDescriptor = TypeUtils.getClassDescriptor(supertype); if (classDescriptor != null) { if (ErrorUtils.isError(classDescriptor)) continue; if (classDescriptor.getKind() != ClassKind.INTERFACE) { if (supertypeOwner.getKind() == ClassKind.ENUM_CLASS) { trace.report(CLASS_IN_SUPERTYPE_FOR_ENUM.on(typeReference)); addSupertype = false; } else if (supertypeOwner.getKind() == ClassKind.INTERFACE && !classAppeared && !TypesPackage.isDynamic(supertype) /* avoid duplicate diagnostics */) { trace.report(TRAIT_WITH_SUPERCLASS.on(typeReference)); addSupertype = false; } if (classAppeared) { trace.report(MANY_CLASSES_IN_SUPERTYPE_LIST.on(typeReference)); } else { classAppeared = true; } } } else { trace.report(SUPERTYPE_NOT_A_CLASS_OR_TRAIT.on(typeReference)); } TypeConstructor constructor = supertype.getConstructor(); if (addSupertype && !typeConstructors.add(constructor)) { trace.report(SUPERTYPE_APPEARS_TWICE.on(typeReference)); } if (DescriptorUtils.isSingleton(classDescriptor)) { trace.report(SINGLETON_IN_SUPERTYPE.on(typeReference)); } else if (constructor.isFinal() && !allowedFinalSupertypes.contains(constructor)) { if (classDescriptor.getModality() == Modality.SEALED) { DeclarationDescriptor containingDescriptor = supertypeOwner.getContainingDeclaration(); while (containingDescriptor != null && containingDescriptor != classDescriptor) { containingDescriptor = containingDescriptor.getContainingDeclaration(); } if (containingDescriptor == null) { trace.report(SEALED_SUPERTYPE.on(typeReference)); } else { trace.report(SEALED_SUPERTYPE_IN_LOCAL_CLASS.on(typeReference)); } } else { trace.report(FINAL_SUPERTYPE.on(typeReference)); } } } }