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; }
@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); }
@Nullable @Override public <T extends TypeCapability> T getCapability(@NotNull Class<T> capabilityClass) { return delegate.getCapability(capabilityClass); }