IR: IrSimpleTypeBuilder

This commit is contained in:
Dmitry Petrov
2019-04-11 17:16:20 +03:00
parent 2844d48f9f
commit bf2ab99b61
4 changed files with 97 additions and 105 deletions
@@ -12,8 +12,9 @@ import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.IrCall
import org.jetbrains.kotlin.ir.symbols.*
import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
import org.jetbrains.kotlin.ir.types.impl.buildSimpleType
import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection
import org.jetbrains.kotlin.ir.types.impl.toBuilder
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
@@ -153,27 +154,22 @@ internal class DeepCopyIrTreeWithSymbolsForInliner(val context: Context,
val substitutedType = typeArguments?.get(type.classifier)
if (substitutedType != null) {
substitutedType as IrSimpleType
return IrSimpleTypeImpl(
kotlinType = null,
classifier = substitutedType.classifier,
hasQuestionMark = type.hasQuestionMark or substitutedType.isMarkedNullable(),
arguments = substitutedType.arguments,
annotations = substitutedType.annotations
)
return substitutedType.buildSimpleType {
kotlinType = null
hasQuestionMark = type.hasQuestionMark or substitutedType.isMarkedNullable()
}
}
return IrSimpleTypeImpl(
kotlinType = null,
classifier = symbolRemapper.getReferencedClassifier(type.classifier),
hasQuestionMark = type.hasQuestionMark,
arguments = remapTypeArguments(type.arguments),
annotations = type.annotations.map { it.transform(copier, null) as IrCall }
)
return type.buildSimpleType {
kotlinType = null
classifier = symbolRemapper.getReferencedClassifier(type.classifier)
arguments = remapTypeArguments(type.arguments)
annotations = type.annotations.map { it.transform(copier, null) as IrCall }
}
}
}
private class SymbolRemapperImpl(descriptorsRemapper: DescriptorsRemapper)
: DeepCopySymbolRemapper(descriptorsRemapper) {
private class SymbolRemapperImpl(descriptorsRemapper: DescriptorsRemapper) : DeepCopySymbolRemapper(descriptorsRemapper) {
var typeArguments: Map<IrTypeParameterSymbol, IrType?>? = null
set(value) {
@@ -192,9 +188,6 @@ internal class DeepCopyIrTreeWithSymbolsForInliner(val context: Context,
}
private val symbolRemapper = SymbolRemapperImpl(DescriptorsToIrRemapper())
private val copier = DeepCopyIrTreeWithSymbols(
symbolRemapper,
InlinerTypeRemapper(symbolRemapper, typeArguments),
InlinerSymbolRenamer()
)
private val copier =
DeepCopyIrTreeWithSymbols(symbolRemapper, InlinerTypeRemapper(symbolRemapper, typeArguments), InlinerSymbolRenamer())
}
@@ -11,53 +11,73 @@ import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
class IrSimpleTypeImpl(
kotlinType: KotlinType?,
override val classifier: IrClassifierSymbol,
override val hasQuestionMark: Boolean,
override val arguments: List<IrTypeArgument>,
annotations: List<IrCall>,
variance: Variance
) : IrTypeBase(kotlinType, annotations, variance), IrSimpleType, IrTypeProjection {
annotations: List<IrCall>
) : IrTypeBase(kotlinType, annotations, Variance.INVARIANT), IrSimpleType, IrTypeProjection {
constructor(
classifier: IrClassifierSymbol,
hasQuestionMark: Boolean,
arguments: List<IrTypeArgument>,
annotations: List<IrCall>
) : this(null, classifier, hasQuestionMark, arguments, annotations, Variance.INVARIANT)
constructor(
kotlinType: KotlinType?,
classifier: IrClassifierSymbol,
hasQuestionMark: Boolean,
arguments: List<IrTypeArgument>,
annotations: List<IrCall>
) : this(kotlinType, classifier, hasQuestionMark, arguments, annotations, Variance.INVARIANT)
constructor(
other: IrSimpleType,
variance: Variance
) :
this(
other.safeAs<IrSimpleTypeImpl>()?.kotlinType,
other.classifier, other.hasQuestionMark, other.arguments, other.annotations, variance
)
) : this(null, classifier, hasQuestionMark, arguments, annotations)
override fun equals(other: Any?): Boolean =
other is IrSimpleTypeImpl &&
FqNameEqualityChecker.areEqual(classifier, other.classifier) &&
hasQuestionMark == other.hasQuestionMark &&
arguments == other.arguments &&
variance == other.variance
arguments == other.arguments
override fun hashCode(): Int =
((FqNameEqualityChecker.getHashCode(classifier) * 31 + hasQuestionMark.hashCode()) * 31 +
arguments.hashCode()) * 31 + variance.hashCode()
(FqNameEqualityChecker.getHashCode(classifier) * 31 +
hasQuestionMark.hashCode()) * 31 +
arguments.hashCode()
}
class IrSimpleTypeBuilder {
var kotlinType: KotlinType? = null
var classifier: IrClassifierSymbol? = null
var hasQuestionMark = false
var arguments: List<IrTypeArgument> = emptyList()
var annotations: List<IrCall> = emptyList()
var variance = Variance.INVARIANT
}
fun IrSimpleType.toBuilder() =
IrSimpleTypeBuilder().also { b ->
b.kotlinType = originalKotlinType
b.classifier = classifier
b.hasQuestionMark = hasQuestionMark
b.arguments = arguments
b.annotations = annotations
}
fun IrSimpleTypeBuilder.buildSimpleType() =
IrSimpleTypeImpl(
kotlinType,
classifier ?: throw AssertionError("Classifier not provided"),
hasQuestionMark,
arguments,
annotations
)
fun IrSimpleTypeBuilder.buildTypeProjection() =
if (variance == Variance.INVARIANT)
buildSimpleType()
else
IrTypeProjectionImpl(buildSimpleType(), variance)
inline fun IrSimpleType.buildSimpleType(b: IrSimpleTypeBuilder.() -> Unit): IrSimpleType =
toBuilder().apply(b).buildSimpleType()
inline fun IrSimpleType.buildTypeProjection(b: IrSimpleTypeBuilder.() -> Unit): IrTypeProjection =
toBuilder().apply(b).buildTypeProjection()
class IrTypeProjectionImpl internal constructor(
override val type: IrType,
override val variance: Variance
@@ -72,7 +92,7 @@ class IrTypeProjectionImpl internal constructor(
fun makeTypeProjection(type: IrType, variance: Variance): IrTypeProjection =
when {
type is IrTypeProjection && type.variance == variance -> type
type is IrSimpleType -> IrSimpleTypeImpl(type, variance)
type is IrSimpleType -> type.toBuilder().apply { this.variance = variance }.buildTypeProjection()
type is IrDynamicType -> IrDynamicTypeImpl(null, type.annotations, variance)
type is IrErrorType -> IrErrorTypeImpl(null, type.annotations, variance)
else -> IrTypeProjectionImpl(type, variance)
@@ -6,35 +6,29 @@
package org.jetbrains.kotlin.ir.types
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrTypeParameter
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
import org.jetbrains.kotlin.ir.symbols.impl.IrClassSymbolImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrTypeParameterSymbolImpl
import org.jetbrains.kotlin.ir.types.impl.*
import org.jetbrains.kotlin.ir.util.SymbolTable
import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.typeUtil.makeNotNullable
import org.jetbrains.kotlin.types.typeUtil.makeNullable
import org.jetbrains.kotlin.utils.addToStdlib.cast
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
fun IrType.withHasQuestionMark(hasQuestionMark: Boolean): IrType =
fun IrType.withHasQuestionMark(newHasQuestionMark: Boolean): IrType =
when (this) {
is IrSimpleType ->
if (this.hasQuestionMark == hasQuestionMark)
if (this.hasQuestionMark == newHasQuestionMark)
this
else
IrSimpleTypeImpl(
originalKotlinType?.run { if (hasQuestionMark) makeNullable() else makeNotNullable() },
classifier,
hasQuestionMark,
arguments,
annotations
)
buildSimpleType {
hasQuestionMark = newHasQuestionMark
kotlinType = originalKotlinType?.run {
if (newHasQuestionMark) makeNullable() else makeNotNullable()
}
}
else -> this
}
@@ -49,27 +43,19 @@ val IrType.classOrNull: IrClassSymbol?
fun IrType.makeNotNull() =
if (this is IrSimpleType && this.hasQuestionMark) {
IrSimpleTypeImpl(
originalKotlinType?.makeNotNullable(),
classifier,
false,
arguments,
annotations,
Variance.INVARIANT
)
buildSimpleType {
kotlinType = originalKotlinType?.makeNotNullable()
hasQuestionMark = false
}
} else
this
fun IrType.makeNullable() =
if (this is IrSimpleType && !this.hasQuestionMark)
IrSimpleTypeImpl(
originalKotlinType?.makeNullable(),
classifier,
true,
arguments,
annotations,
Variance.INVARIANT
)
buildSimpleType {
kotlinType = originalKotlinType?.makeNullable()
hasQuestionMark = true
}
else
this
@@ -15,10 +15,7 @@ import org.jetbrains.kotlin.ir.declarations.IrTypeParametersContainer
import org.jetbrains.kotlin.ir.expressions.IrCall
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.types.IrTypeProjection
import org.jetbrains.kotlin.ir.types.impl.IrDynamicTypeImpl
import org.jetbrains.kotlin.ir.types.impl.IrErrorTypeImpl
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
import org.jetbrains.kotlin.ir.types.impl.IrStarProjectionImpl
import org.jetbrains.kotlin.ir.types.impl.*
import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.typeUtil.replaceArgumentsWithStarProjections
import org.jetbrains.kotlin.types.typesApproximation.approximateCapturedTypes
@@ -78,30 +75,26 @@ class TypeTranslator(
val ktTypeDescriptor = ktTypeConstructor.declarationDescriptor
?: throw AssertionError("No descriptor for type $approximatedType")
return when (ktTypeDescriptor) {
is TypeParameterDescriptor ->
IrSimpleTypeImpl(
approximatedType,
resolveTypeParameter(ktTypeDescriptor),
approximatedType.isMarkedNullable,
emptyList(),
translateTypeAnnotations(approximatedType.annotations),
variance
)
return IrSimpleTypeBuilder().apply {
kotlinType = approximatedType
hasQuestionMark = approximatedType.isMarkedNullable
this.variance = variance
when (ktTypeDescriptor) {
is TypeParameterDescriptor -> {
classifier = resolveTypeParameter(ktTypeDescriptor)
annotations = translateTypeAnnotations(approximatedType.annotations)
}
is ClassDescriptor ->
IrSimpleTypeImpl(
approximatedType,
symbolTable.referenceClass(ktTypeDescriptor),
approximatedType.isMarkedNullable,
translateTypeArguments(approximatedType.arguments),
translateTypeAnnotations(approximatedType.annotations),
variance
)
is ClassDescriptor -> {
classifier = symbolTable.referenceClass(ktTypeDescriptor)
arguments = translateTypeArguments(approximatedType.arguments)
annotations = translateTypeAnnotations(approximatedType.annotations)
}
else ->
throw AssertionError("Unexpected type descriptor $ktTypeDescriptor :: ${ktTypeDescriptor::class}")
}
else ->
throw AssertionError("Unexpected type descriptor $ktTypeDescriptor :: ${ktTypeDescriptor::class}")
}
}.buildTypeProjection()
}
private inner class LegacyTypeApproximation {