diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/calls/inference/CapturedTypeConstructor.kt b/core/descriptors/src/org/jetbrains/kotlin/resolve/calls/inference/CapturedTypeConstructor.kt index f4a1d00b1f0..0b3b86b9f50 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/calls/inference/CapturedTypeConstructor.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/calls/inference/CapturedTypeConstructor.kt @@ -19,6 +19,7 @@ package org.jetbrains.kotlin.resolve.calls.inference import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor import org.jetbrains.kotlin.descriptors.annotations.Annotations +import org.jetbrains.kotlin.resolve.scopes.MemberScope import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.Variance.IN_VARIANCE import org.jetbrains.kotlin.types.Variance.OUT_VARIANCE @@ -57,27 +58,19 @@ class CapturedTypeConstructor( } class CapturedType( - private val typeProjection: TypeProjection -): DelegatingType(), SubtypingRepresentatives { + private val typeProjection: TypeProjection, + override val constructor: TypeConstructor = CapturedTypeConstructor(typeProjection), + override val isMarkedNullable: Boolean = false, + override val annotations: Annotations = Annotations.EMPTY +): AbstractKotlinType(), SubtypingRepresentatives, TypeWithCustomReplacement { - private val delegateType = run { - val scope = ErrorUtils.createErrorScope( + override val arguments: List + get() = listOf() + override val memberScope: MemberScope + get() = ErrorUtils.createErrorScope( "No member resolution should be done on captured type, it used only during constraint system resolution", true) - KotlinTypeFactory.simpleType(Annotations.EMPTY, CapturedTypeConstructor(typeProjection), listOf(), false, scope) - } - - override fun getDelegate(): KotlinType = delegateType - - override val capabilities: TypeCapabilities get() = object : TypeCapabilities { - override fun getCapability(capabilityClass: Class) = - this@CapturedType.getCapability(capabilityClass) - } - - override fun getCapability(capabilityClass: Class): T? { - @Suppress("UNCHECKED_CAST") - return if (capabilityClass == SubtypingRepresentatives::class.java) this as T - else super.getCapability(capabilityClass) - } + override val isError: Boolean + get() = false override val subTypeRepresentative: KotlinType get() = representative(OUT_VARIANCE, builtIns.nullableAnyType) @@ -88,9 +81,16 @@ class CapturedType( private fun representative(variance: Variance, default: KotlinType) = if (typeProjection.projectionKind == variance) typeProjection.type else default - override fun sameTypeConstructor(type: KotlinType) = delegateType.constructor === type.constructor + override fun sameTypeConstructor(type: KotlinType) = constructor === type.constructor - override fun toString() = "Captured($typeProjection)" + override fun toString() = "Captured($typeProjection)${if (isMarkedNullable) '?' else ""}" + + override fun makeNullableAsSpecified(nullable: Boolean): KotlinType { + if (nullable == isMarkedNullable) return this + return CapturedType(typeProjection, constructor, nullable, annotations) + } + + override fun replaceAnnotations(newAnnotations: Annotations): KotlinType = CapturedType(typeProjection, constructor, isMarkedNullable, newAnnotations) } fun createCapturedType(typeProjection: TypeProjection): KotlinType diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/KotlinType.kt b/core/descriptors/src/org/jetbrains/kotlin/types/KotlinType.kt index 535eda1b3be..885f3966941 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/KotlinType.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/KotlinType.kt @@ -56,6 +56,12 @@ fun KotlinType.unwrap(): KotlinType { interface SimpleType : KotlinType +interface TypeWithCustomReplacement : KotlinType { + fun makeNullableAsSpecified(nullable: Boolean): KotlinType + + fun replaceAnnotations(newAnnotations: Annotations): KotlinType +} + abstract class WrappedType() : KotlinType, LazyType { override val annotations: Annotations get() = delegate.annotations override val constructor: TypeConstructor get() = delegate.constructor diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/TypeCapabilities.kt b/core/descriptors/src/org/jetbrains/kotlin/types/TypeCapabilities.kt index 0a406ff45ac..90a2b80f9ac 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/TypeCapabilities.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/TypeCapabilities.kt @@ -74,7 +74,7 @@ fun KotlinType.getCustomTypeVariable(): CustomTypeVariable? = if (it.isTypeVariable) it else null } -interface SubtypingRepresentatives : TypeCapability { +interface SubtypingRepresentatives { val subTypeRepresentative: KotlinType val superTypeRepresentative: KotlinType @@ -82,15 +82,14 @@ interface SubtypingRepresentatives : TypeCapability { } fun KotlinType.getSubtypeRepresentative(): KotlinType = - this.getCapability(SubtypingRepresentatives::class.java)?.subTypeRepresentative ?: this + (unwrap() as? SubtypingRepresentatives)?.subTypeRepresentative ?: this fun KotlinType.getSupertypeRepresentative(): KotlinType = - this.getCapability(SubtypingRepresentatives::class.java)?.superTypeRepresentative ?: this + (unwrap() as? SubtypingRepresentatives)?.superTypeRepresentative ?: this fun sameTypeConstructors(first: KotlinType, second: KotlinType): Boolean { - val typeRangeCapability = SubtypingRepresentatives::class.java - return first.getCapability(typeRangeCapability)?.sameTypeConstructor(second) ?: false - || second.getCapability(typeRangeCapability)?.sameTypeConstructor(first) ?: false + return (first.unwrap() as? SubtypingRepresentatives)?.sameTypeConstructor(second) ?: false + || (second.unwrap() as? SubtypingRepresentatives)?.sameTypeConstructor(first) ?: false } interface AbbreviatedType : TypeCapability { diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/TypeUtils.java b/core/descriptors/src/org/jetbrains/kotlin/types/TypeUtils.java index 359c622cffe..9172434902c 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/TypeUtils.java +++ b/core/descriptors/src/org/jetbrains/kotlin/types/TypeUtils.java @@ -136,8 +136,8 @@ public class TypeUtils { @NotNull public static KotlinType makeNullableAsSpecified(@NotNull KotlinType type, boolean nullable) { KotlinType unwrappedType = KotlinTypeKt.unwrap(type); - if (unwrappedType instanceof FlexibleType) { - return ((FlexibleType) unwrappedType).makeNullableAsSpecified(nullable); + if (unwrappedType instanceof TypeWithCustomReplacement) { + return ((TypeWithCustomReplacement) unwrappedType).makeNullableAsSpecified(nullable); } else { SimpleType simpleType = (SimpleType) unwrappedType; diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/TypeUtils.kt b/core/descriptors/src/org/jetbrains/kotlin/types/TypeUtils.kt index b3a61db0122..ef7cb64ee06 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/TypeUtils.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/TypeUtils.kt @@ -85,7 +85,8 @@ fun TypeProjection.substitute(doSubstitute: (KotlinType) -> KotlinType): TypePro fun KotlinType.replaceAnnotations(newAnnotations: Annotations): KotlinType { if (annotations.isEmpty() && newAnnotations.isEmpty()) return this - if (isFlexible()) return asFlexibleType().replaceAnnotations(newAnnotations) + val unwrappedType = unwrap() + if (unwrappedType is TypeWithCustomReplacement) return unwrappedType.replaceAnnotations(newAnnotations) return asSimpleType().lazyReplaceAnnotations(newAnnotations) } diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/flexibleTypes.kt b/core/descriptors/src/org/jetbrains/kotlin/types/flexibleTypes.kt index fa45558748b..a2d822014e6 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/flexibleTypes.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/flexibleTypes.kt @@ -21,7 +21,7 @@ import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.types.checker.KotlinTypeChecker import org.jetbrains.kotlin.types.typeUtil.replaceAnnotations -interface FlexibleType : SubtypingRepresentatives { +interface FlexibleType : SubtypingRepresentatives, TypeWithCustomReplacement { // lowerBound is a subtype of upperBound val lowerBound: SimpleType val upperBound: SimpleType @@ -33,10 +33,6 @@ interface FlexibleType : SubtypingRepresentatives { get() = upperBound override fun sameTypeConstructor(type: KotlinType) = false - - fun makeNullableAsSpecified(nullable: Boolean): KotlinType - - fun replaceAnnotations(newAnnotations: Annotations): KotlinType } fun KotlinType.isFlexible(): Boolean = unwrap() is FlexibleType @@ -115,14 +111,6 @@ abstract class DelegatingFlexibleType protected constructor( protected abstract val delegateType: KotlinType - override fun getCapability(capabilityClass: Class): T? { - @Suppress("UNCHECKED_CAST") - return when(capabilityClass) { - SubtypingRepresentatives::class.java -> this as T - else -> super.getCapability(capabilityClass) - } - } - override fun makeNullableAsSpecified(nullable: Boolean): KotlinType { return KotlinTypeFactory.flexibleType(TypeUtils.makeNullableAsSpecified(lowerBound, nullable), TypeUtils.makeNullableAsSpecified(upperBound, nullable)) }