Delegation and nullability turned into capabilities
Otherwise they did not sustain substitutions
This commit is contained in:
@@ -11,8 +11,8 @@ fun test(d: dynamic) {
|
||||
val v3 = d.foo(1, "")
|
||||
v3.isDynamic() // to check that anything is resolvable
|
||||
|
||||
// val v4 = d.foo<String>()
|
||||
// v4.isDynamic() // to check that anything is resolvable
|
||||
val v4 = d.foo<String>()
|
||||
v4.isDynamic() // to check that anything is resolvable
|
||||
|
||||
val v5 = d.foo
|
||||
v5.isDynamic() // to check that anything is resolvable
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
// MODULE[js]: m1
|
||||
// FILE: k.kt
|
||||
|
||||
fun test(d: dynamic) {
|
||||
val v1 = d?.foo()
|
||||
v1.isDynamic() // to check that anything is resolvable
|
||||
|
||||
val v2 = d!!.foo(1)
|
||||
v2.isDynamic() // to check that anything is resolvable
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
package
|
||||
|
||||
internal fun test(/*0*/ d: dynamic): kotlin.Unit
|
||||
@@ -11,8 +11,8 @@ fun (dynamic).test() {
|
||||
val v3 = foo(1, "")
|
||||
v3.isDynamic() // to check that anything is resolvable
|
||||
|
||||
// val v4 = foo<String>()
|
||||
// v4.isDynamic() // to check that anything is resolvable
|
||||
val v4 = foo<String>()
|
||||
v4.isDynamic() // to check that anything is resolvable
|
||||
|
||||
val v5 = foo
|
||||
v5.isDynamic() // to check that anything is resolvable
|
||||
|
||||
@@ -3728,6 +3728,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("dynamicSafeCalls.kt")
|
||||
public void testDynamicSafeCalls() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/dynamicTypes/dynamicSafeCalls.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("implicitDynamicReceiver.kt")
|
||||
public void testImplicitDynamicReceiver() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/dynamicTypes/implicitDynamicReceiver.kt");
|
||||
|
||||
@@ -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