[IR] Implement captureFromArguments for IrType
This commit is contained in:
committed by
Dmitry Petrov
parent
d4e561baf6
commit
b7d098af56
@@ -6,6 +6,7 @@
|
|||||||
package org.jetbrains.kotlin.ir.types
|
package org.jetbrains.kotlin.ir.types
|
||||||
|
|
||||||
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
||||||
|
import org.jetbrains.kotlin.ir.types.impl.makeTypeIntersection
|
||||||
import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection
|
import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection
|
||||||
import org.jetbrains.kotlin.types.AbstractTypeCheckerContext
|
import org.jetbrains.kotlin.types.AbstractTypeCheckerContext
|
||||||
import org.jetbrains.kotlin.types.Variance
|
import org.jetbrains.kotlin.types.Variance
|
||||||
@@ -23,11 +24,10 @@ class IrTypeCheckerContext(override val irBuiltIns: IrBuiltIns) : IrTypeSystemCo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun areEqualTypeConstructors(a: TypeConstructorMarker, b: TypeConstructorMarker) = a === b
|
override fun areEqualTypeConstructors(a: TypeConstructorMarker, b: TypeConstructorMarker) = super.isEqualTypeConstructors(a, b)
|
||||||
|
|
||||||
override fun intersectTypes(types: List<KotlinTypeMarker>): KotlinTypeMarker {
|
@Suppress("UNCHECKED_CAST")
|
||||||
TODO("not implemented")
|
override fun intersectTypes(types: List<KotlinTypeMarker>) = makeTypeIntersection(types as List<IrType>)
|
||||||
}
|
|
||||||
|
|
||||||
override val isErrorTypeEqualsToAnything = false
|
override val isErrorTypeEqualsToAnything = false
|
||||||
override val KotlinTypeMarker.isAllowedTypeVariable: Boolean
|
override val KotlinTypeMarker.isAllowedTypeVariable: Boolean
|
||||||
|
|||||||
@@ -13,6 +13,9 @@ import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
|||||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
|
||||||
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
|
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
|
||||||
|
import org.jetbrains.kotlin.ir.types.impl.makeTypeIntersection
|
||||||
|
import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection
|
||||||
|
import org.jetbrains.kotlin.types.Variance
|
||||||
import org.jetbrains.kotlin.types.checker.convertVariance
|
import org.jetbrains.kotlin.types.checker.convertVariance
|
||||||
import org.jetbrains.kotlin.types.model.*
|
import org.jetbrains.kotlin.types.model.*
|
||||||
|
|
||||||
@@ -116,8 +119,49 @@ interface IrTypeSystemContext : TypeSystemContext {
|
|||||||
return classSymbol.owner.run { modality == Modality.FINAL && kind != ClassKind.ENUM_CLASS && kind != ClassKind.ANNOTATION_CLASS }
|
return classSymbol.owner.run { modality == Modality.FINAL && kind != ClassKind.ENUM_CLASS && kind != ClassKind.ANNOTATION_CLASS }
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: is that correct?
|
/*
|
||||||
override fun captureFromArguments(type: SimpleTypeMarker, status: CaptureStatus): SimpleTypeMarker? = type
|
* fun <T> foo(x: Array<T>) {}
|
||||||
|
* fun bar(y: Array<out CharSequence>) {
|
||||||
|
* foo(y)
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* In this case Captured Type of `y` would be `Array<CharSequence>`
|
||||||
|
*
|
||||||
|
* See https://jetbrains.github.io/kotlin-spec/#type-capturing
|
||||||
|
*/
|
||||||
|
override fun captureFromArguments(type: SimpleTypeMarker, status: CaptureStatus): SimpleTypeMarker? {
|
||||||
|
// TODO: is that correct?
|
||||||
|
require(type is IrSimpleType)
|
||||||
|
|
||||||
|
val classifier = type.classifier as IrClassSymbol
|
||||||
|
val typeArguments = type.arguments
|
||||||
|
|
||||||
|
if (!classifier.isBound) return null
|
||||||
|
|
||||||
|
val typeParameters = classifier.owner.typeParameters
|
||||||
|
|
||||||
|
require(typeArguments.size == typeParameters.size)
|
||||||
|
|
||||||
|
if (typeArguments.all { it is IrTypeProjection && it.variance == Variance.INVARIANT }) return type
|
||||||
|
|
||||||
|
val newArguments = mutableListOf<IrTypeArgument>()
|
||||||
|
for (index in typeArguments.indices) {
|
||||||
|
val argument = typeArguments[index]
|
||||||
|
val parameter = typeParameters[index]
|
||||||
|
|
||||||
|
if (argument is IrTypeProjection && argument.variance == Variance.INVARIANT) {
|
||||||
|
newArguments += argument
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
val additionalBounds =
|
||||||
|
if (argument is IrTypeProjection && argument.variance == Variance.OUT_VARIANCE) listOf(argument.type) else emptyList()
|
||||||
|
|
||||||
|
newArguments += makeTypeProjection(makeTypeIntersection(parameter.superTypes + additionalBounds), Variance.INVARIANT)
|
||||||
|
}
|
||||||
|
|
||||||
|
return IrSimpleTypeImpl(type.classifier, type.hasQuestionMark, newArguments, type.annotations)
|
||||||
|
}
|
||||||
|
|
||||||
override fun SimpleTypeMarker.asArgumentList() = this as IrSimpleType
|
override fun SimpleTypeMarker.asArgumentList() = this as IrSimpleType
|
||||||
|
|
||||||
|
|||||||
@@ -97,3 +97,8 @@ fun makeTypeProjection(type: IrType, variance: Variance): IrTypeProjection =
|
|||||||
type is IrErrorType -> IrErrorTypeImpl(null, type.annotations, variance)
|
type is IrErrorType -> IrErrorTypeImpl(null, type.annotations, variance)
|
||||||
else -> IrTypeProjectionImpl(type, variance)
|
else -> IrTypeProjectionImpl(type, variance)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun makeTypeIntersection(types: List<IrType>) =
|
||||||
|
if (types.size == 1) types[1]
|
||||||
|
else TODO("Not implemented")
|
||||||
Reference in New Issue
Block a user