Delegation and nullability turned into capabilities
Otherwise they did not sustain substitutions
This commit is contained in:
@@ -31,15 +31,13 @@ class DynamicTypesAllowed: DynamicTypesSettings() {
|
||||
|
||||
trait Dynamicity : TypeCapability
|
||||
|
||||
// Object is created only for convenience here. Dynamic types may occur in the form of DelegatingFlexibleTypes,
|
||||
// which are produced by substitutions
|
||||
object DynamicType : DelegatingFlexibleType(
|
||||
KotlinBuiltIns.getInstance().getNothingType(),
|
||||
KotlinBuiltIns.getInstance().getNullableAnyType(),
|
||||
DynamicTypeCapabilities
|
||||
) {
|
||||
override fun getDelegate() = upperBound
|
||||
|
||||
override fun isNullable() = false
|
||||
}
|
||||
)
|
||||
|
||||
fun JetType.isDynamic(): Boolean = this.getCapability(javaClass<Dynamicity>()) != null
|
||||
|
||||
@@ -49,12 +47,13 @@ public object DynamicTypeCapabilities : FlexibleTypeCapabilities {
|
||||
override fun <T : TypeCapability> getCapability(capabilityClass: Class<T>, jetType: JetType, flexibility: Flexibility): T? {
|
||||
if (capabilityClass.isAssignableFrom(javaClass<Impl>()))
|
||||
[suppress("UNCHECKED_CAST")]
|
||||
return Impl as T
|
||||
return Impl(flexibility) as T
|
||||
else return null
|
||||
}
|
||||
|
||||
|
||||
private object Impl : Dynamicity, Specificity, NullAwareness {
|
||||
private class Impl(flexibility: Flexibility) : Dynamicity, Specificity, NullAwareness, FlexibleTypeDelegation {
|
||||
override val delegateType: JetType = flexibility.upperBound
|
||||
|
||||
override fun getSpecificityRelationTo(otherType: JetType): Specificity.Relation {
|
||||
return if (!otherType.isDynamic()) Specificity.Relation.LESS_SPECIFIC else Specificity.Relation.DONT_KNOW
|
||||
@@ -64,5 +63,7 @@ public object DynamicTypeCapabilities : FlexibleTypeCapabilities {
|
||||
// Nullability has no effect on dynamics
|
||||
return DynamicType
|
||||
}
|
||||
|
||||
override fun computeIsNullable() = false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,6 +90,7 @@ public fun JetType.upperIfFlexible(): JetType = if (this.isFlexible()) this.flex
|
||||
|
||||
public trait NullAwareness : TypeCapability {
|
||||
public fun makeNullableAsSpecified(nullable: Boolean): JetType
|
||||
public fun computeIsNullable(): Boolean
|
||||
}
|
||||
|
||||
public trait Approximation : TypeCapability {
|
||||
@@ -124,12 +125,15 @@ public fun JetType.getApproximationTo(
|
||||
extras: Approximation.DataFlowExtras = Approximation.DataFlowExtras.EMPTY
|
||||
): Approximation.Info? = this.getCapability(javaClass<Approximation>())?.approximateToExpectedType(expectedType, extras)
|
||||
|
||||
trait FlexibleTypeDelegation : TypeCapability {
|
||||
public val delegateType: JetType
|
||||
}
|
||||
|
||||
public open class DelegatingFlexibleType protected (
|
||||
override val lowerBound: JetType,
|
||||
override val upperBound: JetType,
|
||||
override val extraCapabilities: FlexibleTypeCapabilities
|
||||
) : DelegatingType(), NullAwareness, Flexibility, Approximation {
|
||||
) : DelegatingType(), NullAwareness, Flexibility, FlexibleTypeDelegation, Approximation {
|
||||
class object {
|
||||
platformStatic fun create(lowerBound: JetType, upperBound: JetType, extraCapabilities: FlexibleTypeCapabilities): JetType {
|
||||
if (lowerBound == upperBound) return lowerBound
|
||||
@@ -157,6 +161,10 @@ public open class DelegatingFlexibleType protected (
|
||||
extraCapabilities)
|
||||
}
|
||||
|
||||
override fun computeIsNullable() = delegateType.isNullable()
|
||||
|
||||
override fun isNullable(): Boolean = getCapability(javaClass<NullAwareness>())!!.computeIsNullable()
|
||||
|
||||
override fun approximateToExpectedType(expectedType: JetType, dataFlowExtras: Approximation.DataFlowExtras): Approximation.Info? {
|
||||
// val foo: Any? = foo() : Foo!
|
||||
if (JetTypeChecker.DEFAULT.isSubtypeOf(upperBound, expectedType)) return null
|
||||
@@ -171,7 +179,9 @@ public open class DelegatingFlexibleType protected (
|
||||
return Approximation.Info(this, expectedType, dataFlowExtras.presentableText)
|
||||
}
|
||||
|
||||
override fun getDelegate() = lowerBound
|
||||
override val delegateType: JetType = lowerBound
|
||||
|
||||
override fun getDelegate() = getCapability(javaClass<FlexibleTypeDelegation>())!!.delegateType
|
||||
|
||||
override fun toString() = "('$lowerBound'..'$upperBound')"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user