[JS] Support wrapped and dynamic types in typeOf
This commit is contained in:
@@ -35,6 +35,7 @@ fun box(): String {
|
|||||||
assertEquals("Short?", get1<Short>().toString())
|
assertEquals("Short?", get1<Short>().toString())
|
||||||
assertEquals("Map<in Short?, Array<Short>>?", get2<Short>().toString())
|
assertEquals("Map<in Short?, Array<Short>>?", get2<Short>().toString())
|
||||||
assertEquals("Map<in List<Short>?, Array<List<Short>>>?", get2<List<Short>>().toString())
|
assertEquals("Map<in List<Short>?, Array<List<Short>>>?", get2<List<Short>>().toString())
|
||||||
|
assertEquals("Map<in List<dynamic>?, Array<List<dynamic>>>?", get2<List<dynamic>>().toString())
|
||||||
|
|
||||||
return "OK"
|
return "OK"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,6 +76,7 @@ public final class Namer {
|
|||||||
public static final String GET_KCLASS_FROM_EXPRESSION = "getKClassFromExpression";
|
public static final String GET_KCLASS_FROM_EXPRESSION = "getKClassFromExpression";
|
||||||
|
|
||||||
public static final String CREATE_KTYPE = "createKType";
|
public static final String CREATE_KTYPE = "createKType";
|
||||||
|
public static final String CREATE_DYNAMIC_KTYPE = "createDynamicKType";
|
||||||
public static final String MARK_KTYPE_NULLABLE = "markKTypeNullable";
|
public static final String MARK_KTYPE_NULLABLE = "markKTypeNullable";
|
||||||
public static final String CREATE_KTYPE_PARAMETER = "createKTypeParameter";
|
public static final String CREATE_KTYPE_PARAMETER = "createKTypeParameter";
|
||||||
public static final String CREATE_REIFIED_KTYPE_PARAMETER = "getReifiedTypeParameterKType";
|
public static final String CREATE_REIFIED_KTYPE_PARAMETER = "getReifiedTypeParameterKType";
|
||||||
|
|||||||
+18
-7
@@ -18,9 +18,7 @@ import org.jetbrains.kotlin.js.translate.expression.ExpressionVisitor
|
|||||||
import org.jetbrains.kotlin.js.translate.intrinsic.functions.basic.FunctionIntrinsic
|
import org.jetbrains.kotlin.js.translate.intrinsic.functions.basic.FunctionIntrinsic
|
||||||
import org.jetbrains.kotlin.js.translate.utils.getReferenceToJsClass
|
import org.jetbrains.kotlin.js.translate.utils.getReferenceToJsClass
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
|
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
|
||||||
import org.jetbrains.kotlin.types.SimpleType
|
import org.jetbrains.kotlin.types.*
|
||||||
import org.jetbrains.kotlin.types.TypeProjection
|
|
||||||
import org.jetbrains.kotlin.types.Variance
|
|
||||||
|
|
||||||
object TypeOfFIF : FunctionIntrinsicFactory {
|
object TypeOfFIF : FunctionIntrinsicFactory {
|
||||||
override fun getIntrinsic(descriptor: FunctionDescriptor, context: TranslationContext): FunctionIntrinsic? =
|
override fun getIntrinsic(descriptor: FunctionDescriptor, context: TranslationContext): FunctionIntrinsic? =
|
||||||
@@ -28,7 +26,7 @@ object TypeOfFIF : FunctionIntrinsicFactory {
|
|||||||
|
|
||||||
object Intrinsic : FunctionIntrinsic() {
|
object Intrinsic : FunctionIntrinsic() {
|
||||||
override fun apply(callInfo: CallInfo, arguments: List<JsExpression>, context: TranslationContext): JsExpression {
|
override fun apply(callInfo: CallInfo, arguments: List<JsExpression>, context: TranslationContext): JsExpression {
|
||||||
val type = callInfo.resolvedCall.typeArguments.values.single() as SimpleType
|
val type = callInfo.resolvedCall.typeArguments.values.single()
|
||||||
return KTypeConstructor(context).createKType(type)
|
return KTypeConstructor(context).createKType(type)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -38,7 +36,20 @@ class KTypeConstructor(val context: TranslationContext) {
|
|||||||
fun callHelperFunction(name: String, vararg arguments: JsExpression) =
|
fun callHelperFunction(name: String, vararg arguments: JsExpression) =
|
||||||
JsInvocation(context.getReferenceToIntrinsic(name), *arguments)
|
JsInvocation(context.getReferenceToIntrinsic(name), *arguments)
|
||||||
|
|
||||||
fun createKType(type: SimpleType): JsExpression {
|
fun createKType(type: KotlinType): JsExpression {
|
||||||
|
val unwrappedType = type.unwrap()
|
||||||
|
if (unwrappedType is SimpleType)
|
||||||
|
return createSimpleKType(unwrappedType)
|
||||||
|
if (unwrappedType is DynamicType)
|
||||||
|
return createDynamicType()
|
||||||
|
error("Unexpected type $type")
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createDynamicType(): JsExpression {
|
||||||
|
return callHelperFunction(Namer.CREATE_DYNAMIC_KTYPE)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createSimpleKType(type: SimpleType): JsExpression {
|
||||||
val classifier: ClassifierDescriptor = type.constructor.declarationDescriptor!!
|
val classifier: ClassifierDescriptor = type.constructor.declarationDescriptor!!
|
||||||
|
|
||||||
if (classifier is TypeParameterDescriptor && classifier.isReified) {
|
if (classifier is TypeParameterDescriptor && classifier.isReified) {
|
||||||
@@ -75,7 +86,7 @@ class KTypeConstructor(val context: TranslationContext) {
|
|||||||
Variance.OUT_VARIANCE -> Namer.CREATE_COVARIANT_KTYPE_PROJECTION
|
Variance.OUT_VARIANCE -> Namer.CREATE_COVARIANT_KTYPE_PROJECTION
|
||||||
}
|
}
|
||||||
|
|
||||||
val kType = createKType(tp.type as SimpleType)
|
val kType = createKType(tp.type)
|
||||||
return callHelperFunction(factoryName, kType)
|
return callHelperFunction(factoryName, kType)
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -88,7 +99,7 @@ class KTypeConstructor(val context: TranslationContext) {
|
|||||||
|
|
||||||
fun createKTypeParameter(typeParameter: TypeParameterDescriptor): JsExpression {
|
fun createKTypeParameter(typeParameter: TypeParameterDescriptor): JsExpression {
|
||||||
val name = JsStringLiteral(typeParameter.name.asString())
|
val name = JsStringLiteral(typeParameter.name.asString())
|
||||||
val upperBounds = JsArrayLiteral(typeParameter.upperBounds.map { createKType(it as SimpleType) })
|
val upperBounds = JsArrayLiteral(typeParameter.upperBounds.map { createKType(it) })
|
||||||
val variance = when (typeParameter.variance) {
|
val variance = when (typeParameter.variance) {
|
||||||
Variance.INVARIANT -> JsStringLiteral("invariant")
|
Variance.INVARIANT -> JsStringLiteral("invariant")
|
||||||
Variance.IN_VARIANCE -> JsStringLiteral("in")
|
Variance.IN_VARIANCE -> JsStringLiteral("in")
|
||||||
|
|||||||
@@ -129,9 +129,7 @@ fun <T, S> List<T>.splitToRanges(classifier: (T) -> S): List<Pair<List<T>, S>> {
|
|||||||
|
|
||||||
fun getReferenceToJsClass(type: KotlinType, context: TranslationContext): JsExpression =
|
fun getReferenceToJsClass(type: KotlinType, context: TranslationContext): JsExpression =
|
||||||
getReferenceToJsClass(type.constructor.declarationDescriptor, context).also {
|
getReferenceToJsClass(type.constructor.declarationDescriptor, context).also {
|
||||||
if (type is SimpleType) {
|
it.kType = KTypeConstructor(context).createKType(type)
|
||||||
it.kType = KTypeConstructor(context).createKType(type)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getReferenceToJsClass(classifierDescriptor: ClassifierDescriptor?, context: TranslationContext): JsExpression {
|
fun getReferenceToJsClass(classifierDescriptor: ClassifierDescriptor?, context: TranslationContext): JsExpression {
|
||||||
|
|||||||
@@ -19,6 +19,9 @@ internal fun createKType(
|
|||||||
) =
|
) =
|
||||||
KTypeImpl(classifier, arguments.asList(), isMarkedNullable)
|
KTypeImpl(classifier, arguments.asList(), isMarkedNullable)
|
||||||
|
|
||||||
|
@JsName("createDynamicKType")
|
||||||
|
internal fun createDynamicKType(): KType = DynamicKType
|
||||||
|
|
||||||
@JsName("markKTypeNullable")
|
@JsName("markKTypeNullable")
|
||||||
internal fun markKTypeNullable(kType: KType) = KTypeImpl(kType.classifier!!, kType.arguments, true)
|
internal fun markKTypeNullable(kType: KType) = KTypeImpl(kType.classifier!!, kType.arguments, true)
|
||||||
|
|
||||||
|
|||||||
@@ -45,6 +45,14 @@ internal class KTypeImpl(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal object DynamicKType : KType {
|
||||||
|
override val classifier: KClassifier? = null
|
||||||
|
override val arguments: List<KTypeProjection> = emptyList()
|
||||||
|
override val isMarkedNullable: Boolean = false
|
||||||
|
override val annotations: List<Annotation> = emptyList()
|
||||||
|
override fun toString(): String = "dynamic"
|
||||||
|
}
|
||||||
|
|
||||||
internal fun KVariance.prefixString() =
|
internal fun KVariance.prefixString() =
|
||||||
when (this) {
|
when (this) {
|
||||||
KVariance.INVARIANT -> ""
|
KVariance.INVARIANT -> ""
|
||||||
|
|||||||
Reference in New Issue
Block a user