Specificity supported for dynamic types
This commit is contained in:
@@ -22,6 +22,7 @@ import org.jetbrains.jet.lang.descriptors.ConstructorDescriptor;
|
|||||||
import org.jetbrains.jet.lang.descriptors.SimpleFunctionDescriptor;
|
import org.jetbrains.jet.lang.descriptors.SimpleFunctionDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
|
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
|
||||||
import org.jetbrains.jet.lang.types.JetType;
|
import org.jetbrains.jet.lang.types.JetType;
|
||||||
|
import org.jetbrains.jet.lang.types.TypesPackage;
|
||||||
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
|
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -70,8 +71,8 @@ public class OverloadUtil {
|
|||||||
for (int i = 0; i < superValueParameters.size(); ++i) {
|
for (int i = 0; i < superValueParameters.size(); ++i) {
|
||||||
JetType superValueParameterType = OverridingUtil.getUpperBound(superValueParameters.get(i));
|
JetType superValueParameterType = OverridingUtil.getUpperBound(superValueParameters.get(i));
|
||||||
JetType subValueParameterType = OverridingUtil.getUpperBound(subValueParameters.get(i));
|
JetType subValueParameterType = OverridingUtil.getUpperBound(subValueParameters.get(i));
|
||||||
// TODO: compare erasure
|
if (!JetTypeChecker.DEFAULT.equalTypes(superValueParameterType, subValueParameterType)
|
||||||
if (!JetTypeChecker.DEFAULT.equalTypes(superValueParameterType, subValueParameterType)) {
|
|| TypesPackage.oneMoreSpecificThanAnother(subValueParameterType, superValueParameterType)) {
|
||||||
return OverridingUtil.OverrideCompatibilityInfo
|
return OverridingUtil.OverrideCompatibilityInfo
|
||||||
.valueParameterTypeMismatch(superValueParameterType, subValueParameterType, INCOMPATIBLE);
|
.valueParameterTypeMismatch(superValueParameterType, subValueParameterType, INCOMPATIBLE);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
// !CHECK_TYPE
|
||||||
|
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||||
|
|
||||||
|
// MODULE[js]: m1
|
||||||
|
// FILE: k.kt
|
||||||
|
|
||||||
|
fun dyn(d: dynamic) {}
|
||||||
|
|
||||||
|
fun foo(d: dynamic): String = ""
|
||||||
|
fun foo(d: Int): Int = 1
|
||||||
|
|
||||||
|
fun nothing(d: dynamic): Int = 1
|
||||||
|
fun nothing(d: Nothing): String = ""
|
||||||
|
|
||||||
|
fun test(d: dynamic) {
|
||||||
|
dyn(1)
|
||||||
|
dyn("")
|
||||||
|
|
||||||
|
foo(1).checkType { it : _<Int> }
|
||||||
|
foo("").checkType { it : _<String> }
|
||||||
|
|
||||||
|
// Checking specificity of `dynamic` vs `Nothing`
|
||||||
|
nothing(d).checkType { it : _<String> }
|
||||||
|
nothing("").checkType { it : _<Int> }
|
||||||
|
[suppress("UNREACHABLE_CODE")] nothing(null!!).checkType { it : _<String> }
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
internal fun dyn(/*0*/ d: (kotlin.Nothing..kotlin.Any?)): kotlin.Unit
|
||||||
|
internal fun foo(/*0*/ d: (kotlin.Nothing..kotlin.Any?)): kotlin.String
|
||||||
|
internal fun foo(/*0*/ d: kotlin.Int): kotlin.Int
|
||||||
|
internal fun nothing(/*0*/ d: dynamic): kotlin.Int
|
||||||
|
internal fun nothing(/*0*/ d: kotlin.Nothing): kotlin.String
|
||||||
|
internal fun test(/*0*/ d: dynamic): kotlin.Unit
|
||||||
@@ -3722,6 +3722,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("overloading.kt")
|
||||||
|
public void testOverloading() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/dynamicTypes/overloading.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("unsupported.kt")
|
@TestMetadata("unsupported.kt")
|
||||||
public void testUnsupported() throws Exception {
|
public void testUnsupported() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/dynamicTypes/unsupported.kt");
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/dynamicTypes/unsupported.kt");
|
||||||
|
|||||||
@@ -33,6 +33,8 @@ public trait Specificity : TypeCapability {
|
|||||||
|
|
||||||
fun JetType.getSpecificityRelationTo(otherType: JetType) = this.getCapability(javaClass<Specificity>())?.getSpecificityRelationTo(otherType) ?: Specificity.Relation.DONT_KNOW
|
fun JetType.getSpecificityRelationTo(otherType: JetType) = this.getCapability(javaClass<Specificity>())?.getSpecificityRelationTo(otherType) ?: Specificity.Relation.DONT_KNOW
|
||||||
|
|
||||||
|
fun oneMoreSpecificThanAnother(a: JetType, b: JetType) = a.getSpecificityRelationTo(b) != Specificity.Relation.DONT_KNOW || b.getSpecificityRelationTo(a) != Specificity.Relation.DONT_KNOW
|
||||||
|
|
||||||
// To facilitate laziness, any JetType implementation may inherit from this trait,
|
// To facilitate laziness, any JetType implementation may inherit from this trait,
|
||||||
// even if it turns out that the type an instance represents is not actually a type variable
|
// even if it turns out that the type an instance represents is not actually a type variable
|
||||||
// (i.e. it is not derived from a type parameter), see isTypeVariable
|
// (i.e. it is not derived from a type parameter), see isTypeVariable
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
package org.jetbrains.jet.lang.types
|
package org.jetbrains.jet.lang.types
|
||||||
|
|
||||||
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns
|
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns
|
||||||
|
import kotlin.platform.platformStatic
|
||||||
|
|
||||||
open class DynamicTypesSettings {
|
open class DynamicTypesSettings {
|
||||||
open val dynamicTypesAllowed: Boolean
|
open val dynamicTypesAllowed: Boolean
|
||||||
@@ -28,10 +29,36 @@ class DynamicTypesAllowed: DynamicTypesSettings() {
|
|||||||
get() = true
|
get() = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trait Dynamicity : TypeCapability
|
||||||
|
|
||||||
object DynamicType : DelegatingFlexibleType(
|
object DynamicType : DelegatingFlexibleType(
|
||||||
KotlinBuiltIns.getInstance().getNothingType(),
|
KotlinBuiltIns.getInstance().getNothingType(),
|
||||||
KotlinBuiltIns.getInstance().getNullableAnyType(),
|
KotlinBuiltIns.getInstance().getNullableAnyType(),
|
||||||
FlexibleTypeCapabilities.NONE
|
DynamicTypeCapabilities
|
||||||
) {
|
) {
|
||||||
override fun getDelegate() = upperBound
|
override fun getDelegate() = upperBound
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun JetType.isDynamic(): Boolean = this.getCapability(javaClass<Dynamicity>()) != null
|
||||||
|
|
||||||
|
public object DynamicTypeCapabilities : FlexibleTypeCapabilities {
|
||||||
|
override val id: String get() = "kotlin.DynamicType"
|
||||||
|
|
||||||
|
override fun <T : TypeCapability> getCapability(capabilityClass: Class<T>, jetType: JetType, flexibility: Flexibility): T? {
|
||||||
|
if (capabilityClass.isAssignableFrom(javaClass<Impl>()))
|
||||||
|
[suppress("UNCHECKED_CAST")]
|
||||||
|
return Impl(jetType, flexibility) as T
|
||||||
|
else return null
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private class Impl(val type: JetType, val flexibility: Flexibility) : Dynamicity, Specificity {
|
||||||
|
|
||||||
|
private val lowerBound: JetType get() = flexibility.lowerBound
|
||||||
|
private val upperBound: JetType get() = flexibility.upperBound
|
||||||
|
|
||||||
|
override fun getSpecificityRelationTo(otherType: JetType): Specificity.Relation {
|
||||||
|
return if (!otherType.isDynamic()) Specificity.Relation.LESS_SPECIFIC else Specificity.Relation.DONT_KNOW
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ fun jsFun(p: dynamic): dynamic
|
|||||||
- ??? `glb(T, dynamic) = T`
|
- ??? `glb(T, dynamic) = T`
|
||||||
- `dynamic` can't be substituted for reified parameters of function/constructor calls (this means that it's not possible to create an array of `dynamic`)
|
- `dynamic` can't be substituted for reified parameters of function/constructor calls (this means that it's not possible to create an array of `dynamic`)
|
||||||
- `dynamic` can't be used as a supertype or upper bound for a tpe parameter
|
- `dynamic` can't be used as a supertype or upper bound for a tpe parameter
|
||||||
|
- `dynamic` is less specific than any other type
|
||||||
|
|
||||||
## Syntax
|
## Syntax
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user