[IR] Implement captureFromArguments for IrType

This commit is contained in:
Roman Artemev
2019-03-12 19:22:18 +03:00
committed by Dmitry Petrov
parent d4e561baf6
commit b7d098af56
3 changed files with 55 additions and 6 deletions
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.ir.types
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.types.AbstractTypeCheckerContext
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 {
TODO("not implemented")
}
@Suppress("UNCHECKED_CAST")
override fun intersectTypes(types: List<KotlinTypeMarker>) = makeTypeIntersection(types as List<IrType>)
override val isErrorTypeEqualsToAnything = false
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.IrTypeParameterSymbol
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.model.*
@@ -116,8 +119,49 @@ interface IrTypeSystemContext : TypeSystemContext {
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
@@ -97,3 +97,8 @@ fun makeTypeProjection(type: IrType, variance: Variance): IrTypeProjection =
type is IrErrorType -> IrErrorTypeImpl(null, type.annotations, variance)
else -> IrTypeProjectionImpl(type, variance)
}
fun makeTypeIntersection(types: List<IrType>) =
if (types.size == 1) types[1]
else TODO("Not implemented")