@Nullable public static TypeParameterDescriptor getTypeParameterDescriptorOrNull(@NotNull KotlinType type) { if (type.getConstructor().getDeclarationDescriptor() instanceof TypeParameterDescriptor) { return (TypeParameterDescriptor) type.getConstructor().getDeclarationDescriptor(); } return null; }
public static boolean dependsOnTypeConstructors( @NotNull KotlinType type, @NotNull Collection<TypeConstructor> typeParameterConstructors) { if (typeParameterConstructors.contains(type.getConstructor())) return true; for (TypeProjection typeProjection : type.getArguments()) { if (!typeProjection.isStarProjection() && dependsOnTypeConstructors(typeProjection.getType(), typeParameterConstructors)) { return true; } } return false; }
public static boolean hasNullableSuperType(@NotNull KotlinType type) { if (type.getConstructor().getDeclarationDescriptor() instanceof ClassDescriptor) { // A class/trait cannot have a nullable supertype return false; } for (KotlinType supertype : getImmediateSupertypes(type)) { if (supertype.isMarkedNullable()) return true; if (hasNullableSuperType(supertype)) return true; } return false; }
private static boolean lowerThanBound( KotlinTypeChecker typeChecker, KotlinType argument, TypeParameterDescriptor parameterDescriptor) { for (KotlinType bound : parameterDescriptor.getUpperBounds()) { if (typeChecker.isSubtypeOf(argument, bound)) { if (!argument.getConstructor().equals(bound.getConstructor())) { return true; } } } return false; }
@NotNull public KotlinType getArrayElementType(@NotNull KotlinType arrayType) { if (isArray(arrayType)) { if (arrayType.getArguments().size() != 1) { throw new IllegalStateException(); } return arrayType.getArguments().get(0).getType(); } KotlinType primitiveType = kotlinArrayTypeToPrimitiveKotlinType.get(TypeUtils.makeNotNullable(arrayType)); if (primitiveType == null) { throw new IllegalStateException("not array: " + arrayType); } return primitiveType; }
public static boolean contains( @Nullable KotlinType type, @NotNull Function1<KotlinType, Boolean> isSpecialType) { if (type == null) return false; if (isSpecialType.invoke(type)) return true; Flexibility flexibility = type.getCapability(Flexibility.class); if (flexibility != null && (contains(flexibility.getLowerBound(), isSpecialType) || contains(flexibility.getUpperBound(), isSpecialType))) { return true; } for (TypeProjection projection : type.getArguments()) { if (!projection.isStarProjection() && contains(projection.getType(), isSpecialType)) return true; } return false; }
@Nullable public static ClassDescriptor getClassDescriptor(@NotNull KotlinType type) { DeclarationDescriptor declarationDescriptor = type.getConstructor().getDeclarationDescriptor(); if (declarationDescriptor instanceof ClassDescriptor) { return (ClassDescriptor) declarationDescriptor; } return null; }
public static boolean isExtensionFunctionType(@NotNull KotlinType type) { if (isExactExtensionFunctionType(type)) return true; for (KotlinType superType : type.getConstructor().getSupertypes()) { if (isExtensionFunctionType(superType)) return true; } return false; }
public static boolean isSubtypeOfClass( @NotNull KotlinType type, @NotNull DeclarationDescriptor superClass) { if (isSameClass(type, superClass)) return true; for (KotlinType superType : type.getConstructor().getSupertypes()) { if (isSubtypeOfClass(superType, superClass)) { return true; } } return false; }
@Nullable public static KotlinType getReceiverType(@NotNull KotlinType type) { assert isFunctionOrExtensionFunctionType(type) : type; if (isExtensionFunctionType(type)) { // TODO: this is incorrect when a class extends from an extension function and swaps type // arguments return type.getArguments().get(0).getType(); } return null; }
private static boolean isConstructedFromGivenClass( @NotNull KotlinType type, @NotNull FqNameUnsafe fqName) { ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor(); return descriptor != null && /* quick check to avoid creation of full FqName instance */ descriptor .getName() .equals(fqName.shortName()) && fqName.equals(getFqName(descriptor)); }
/** * Differs from `isNullableType` only by treating type parameters: acceptsNullable(T) <=> T has * nullable lower bound Semantics should be the same as `isSubtype(Nothing?, T)` * * @return true if `null` can be assigned to storage of this type */ public static boolean acceptsNullable(@NotNull KotlinType type) { if (type.isMarkedNullable()) { return true; } if (FlexibleTypesKt.isFlexible(type) && acceptsNullable(FlexibleTypesKt.flexibility(type).getUpperBound())) { return true; } return false; }
@Nullable public static KotlinType createSubstitutedSupertype( @NotNull KotlinType subType, @NotNull KotlinType superType, @NotNull TypeSubstitutor substitutor) { KotlinType substitutedType = substitutor.substitute(superType, Variance.INVARIANT); if (substitutedType != null) { return makeNullableIfNeeded(substitutedType, subType.isMarkedNullable()); } return null; }
public static boolean shouldRecordInitializerForProperty( @NotNull VariableDescriptor variable, @NotNull KotlinType type) { if (variable.isVar() || type.isError()) return false; if (TypeUtils.acceptsNullable(type)) return true; KotlinBuiltIns builtIns = getBuiltIns(variable); return KotlinBuiltIns.isPrimitiveType(type) || KotlinTypeChecker.DEFAULT.equalTypes(builtIns.getStringType(), type) || KotlinTypeChecker.DEFAULT.equalTypes(builtIns.getNumber().getDefaultType(), type) || KotlinTypeChecker.DEFAULT.equalTypes(builtIns.getAnyType(), type); }
@NotNull public static List<KotlinType> getImmediateSupertypes(@NotNull KotlinType type) { TypeSubstitutor substitutor = TypeSubstitutor.create(type); Collection<KotlinType> originalSupertypes = type.getConstructor().getSupertypes(); List<KotlinType> result = new ArrayList<KotlinType>(originalSupertypes.size()); for (KotlinType supertype : originalSupertypes) { KotlinType substitutedType = createSubstitutedSupertype(type, supertype, substitutor); if (substitutedType != null) { result.add(substitutedType); } } return result; }
/** * A work-around of the generic nullability problem in the type checker Semantics should be the * same as `!isSubtype(T, Any)` * * @return true if a value of this type can be null */ public static boolean isNullableType(@NotNull KotlinType type) { if (type.isMarkedNullable()) { return true; } if (FlexibleTypesKt.isFlexible(type) && isNullableType(FlexibleTypesKt.flexibility(type).getUpperBound())) { return true; } if (isTypeParameter(type)) { return hasNullableSuperType(type); } return false; }
@NotNull public static KotlinType getPrimitiveNumberType( @NotNull IntegerValueTypeConstructor numberValueTypeConstructor, @NotNull KotlinType expectedType) { if (noExpectedType(expectedType) || expectedType.isError()) { return getDefaultPrimitiveNumberType(numberValueTypeConstructor); } for (KotlinType primitiveNumberType : numberValueTypeConstructor.getSupertypes()) { if (KotlinTypeChecker.DEFAULT.isSubtypeOf(primitiveNumberType, expectedType)) { return primitiveNumberType; } } return getDefaultPrimitiveNumberType(numberValueTypeConstructor); }
private static boolean isSameClass( @NotNull KotlinType type, @NotNull DeclarationDescriptor other) { DeclarationDescriptor descriptor = type.getConstructor().getDeclarationDescriptor(); if (descriptor != null) { DeclarationDescriptor originalDescriptor = descriptor.getOriginal(); if (originalDescriptor instanceof ClassifierDescriptor && other instanceof ClassifierDescriptor && ((ClassifierDescriptor) other) .getTypeConstructor() .equals(((ClassifierDescriptor) originalDescriptor).getTypeConstructor())) { return true; } } return false; }
@NotNull public static List<TypeProjection> getParameterTypeProjectionsFromFunctionType( @NotNull KotlinType type) { assert isFunctionOrExtensionFunctionType(type); List<TypeProjection> arguments = type.getArguments(); int first = isExtensionFunctionType(type) ? 1 : 0; int last = arguments.size() - 2; // TODO: fix bugs associated with this here and in neighboring methods, see KT-9820 assert first <= last + 1 : "Not an exact function type: " + type; List<TypeProjection> parameterTypes = new ArrayList<TypeProjection>(last - first + 1); for (int i = first; i <= last; i++) { parameterTypes.add(arguments.get(i)); } return parameterTypes; }
@NotNull public static KotlinType makeNullableAsSpecified(@NotNull KotlinType type, boolean nullable) { Flexibility flexibility = type.getCapability(Flexibility.class); if (flexibility != null) { return flexibility.makeNullableAsSpecified(nullable); } // Wrapping serves two purposes here // 1. It's requires less memory than copying with a changed nullability flag: a copy has many // fields, while a wrapper has only one // 2. It preserves laziness of types // Unwrap to avoid long delegation call chains if (type instanceof AbstractTypeWithKnownNullability) { return makeNullableAsSpecified(((AbstractTypeWithKnownNullability) type).delegate, nullable); } // checking to preserve laziness if (!(type instanceof LazyType) && type.isMarkedNullable() == nullable) { return type; } return nullable ? new NullableType(type) : new NotNullType(type); }
@NotNull public static KotlinType getReturnTypeFromFunctionType(@NotNull KotlinType type) { assert isFunctionOrExtensionFunctionType(type); List<TypeProjection> arguments = type.getArguments(); return arguments.get(arguments.size() - 1).getType(); }
public static boolean isExactFunctionOrExtensionFunctionType(@NotNull KotlinType type) { ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor(); return descriptor != null && isNumberedFunctionClassFqName(getFqName(descriptor)); }
@NotNull @Override public TypeCapabilities getCapabilities() { return delegate.getCapabilities(); }
public static boolean isNullableNothing(@NotNull KotlinType type) { return isNothingOrNullableNothing(type) && type.isMarkedNullable(); }
public static boolean isPrimitiveType(@NotNull KotlinType type) { ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor(); return !type.isMarkedNullable() && descriptor instanceof ClassDescriptor && isPrimitiveClass((ClassDescriptor) descriptor); }
public static boolean isPrimitiveArray(@NotNull KotlinType type) { ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor(); return descriptor != null && getPrimitiveTypeByArrayClassFqName(getFqName(descriptor)) != null; }
private static boolean isTypeAnnotatedWithExtension(@NotNull KotlinType type) { return type.getAnnotations().findAnnotation(FQ_NAMES.extensionFunctionType) != null || type.getAnnotations().findAnnotation(FQ_NAMES.deprecatedExtensionAnnotation) != null; }
public static boolean isNullableAny(@NotNull KotlinType type) { return isAnyOrNullableAny(type) && type.isMarkedNullable(); }
private static boolean isNotNullConstructedFromGivenClass( @NotNull KotlinType type, @NotNull FqNameUnsafe fqName) { return !type.isMarkedNullable() && isConstructedFromGivenClass(type, fqName); }
@NotNull public static ClassDescriptor getClassDescriptorForType(@NotNull KotlinType type) { return getClassDescriptorForTypeConstructor(type.getConstructor()); }