IR: minor refactorings around IrType/IrCapturedType
- use identity in equals/hashCode. It was already effectively working like this because of `constructor === other.constructor` - implement variance and declare it in IrSimpleType - remove obsolete TODO - simplify code in captureFromArguments - use data objects
This commit is contained in:
committed by
Space Team
parent
dec41e8c46
commit
898d3aeea9
@@ -91,6 +91,9 @@ abstract class IrSimpleType(kotlinType: KotlinType?) : IrTypeBase(kotlinType), S
|
||||
)
|
||||
val hasQuestionMark: Boolean
|
||||
get() = nullability == SimpleTypeNullability.MARKED_NULLABLE
|
||||
|
||||
override val variance: Variance
|
||||
get() = Variance.INVARIANT
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -90,7 +90,7 @@ class IrTypeSubstitutor(
|
||||
override fun isEmptySubstitution(): Boolean = substitution.isEmpty()
|
||||
}
|
||||
|
||||
class IrCapturedTypeSubstitutor(
|
||||
internal class IrCapturedTypeSubstitutor(
|
||||
typeParameters: List<IrTypeParameterSymbol>,
|
||||
typeArguments: List<IrTypeArgument>,
|
||||
capturedTypes: List<IrCapturedType?>,
|
||||
|
||||
@@ -239,9 +239,7 @@ interface IrTypeSystemContext : TypeSystemContext, TypeSystemCommonSuperTypesCon
|
||||
*
|
||||
* See https://kotlinlang.org/spec/type-system.html#type-capturing
|
||||
*/
|
||||
|
||||
override fun captureFromArguments(type: SimpleTypeMarker, status: CaptureStatus): SimpleTypeMarker? {
|
||||
// TODO: is that correct?
|
||||
require(type is IrSimpleType)
|
||||
|
||||
if (type is IrCapturedType) return null
|
||||
@@ -252,43 +250,33 @@ interface IrTypeSystemContext : TypeSystemContext, TypeSystemCommonSuperTypesCon
|
||||
if (!classifier.isBound) return null
|
||||
|
||||
val typeParameters = extractTypeParameters(classifier.owner)
|
||||
|
||||
require(typeArguments.size == typeParameters.size)
|
||||
|
||||
if (typeArguments.all { it is IrTypeProjection && it.variance == Variance.INVARIANT }) return type
|
||||
|
||||
val capturedTypes = ArrayList<IrCapturedType?>(typeArguments.size)
|
||||
|
||||
for (index in typeArguments.indices) {
|
||||
val parameter = typeParameters[index]
|
||||
val argument = typeArguments[index]
|
||||
|
||||
val capturedTypes = typeArguments.mapIndexed { index, argument ->
|
||||
if (argument is IrTypeProjection && argument.variance == Variance.INVARIANT) {
|
||||
capturedTypes.add(null)
|
||||
null
|
||||
} else {
|
||||
val lowerType = if (argument is IrTypeProjection && argument.variance == Variance.IN_VARIANCE) {
|
||||
argument.type
|
||||
} else null
|
||||
|
||||
capturedTypes.add(IrCapturedType(status, lowerType, argument, parameter))
|
||||
IrCapturedType(status, lowerType, argument, typeParameters[index])
|
||||
}
|
||||
}
|
||||
|
||||
val newArguments = ArrayList<IrTypeArgument>(typeArguments.size)
|
||||
|
||||
val typeSubstitutor = IrCapturedTypeSubstitutor(typeParameters.memoryOptimizedMap { it.symbol }, typeArguments, capturedTypes)
|
||||
|
||||
for (index in typeArguments.indices) {
|
||||
val oldArgument = typeArguments[index]
|
||||
val parameter = typeParameters[index]
|
||||
val newArguments = typeArguments.mapIndexed { index, oldArgument ->
|
||||
val capturedType = capturedTypes[index]
|
||||
|
||||
if (capturedType == null) {
|
||||
assert(oldArgument is IrTypeProjection && oldArgument.variance == Variance.INVARIANT)
|
||||
newArguments.add(oldArgument)
|
||||
oldArgument
|
||||
} else {
|
||||
val capturedSuperTypes = mutableListOf<IrType>()
|
||||
parameter.superTypes.mapTo(capturedSuperTypes) {
|
||||
typeParameters[index].superTypes.mapTo(capturedSuperTypes) {
|
||||
typeSubstitutor.substitute(it)
|
||||
}
|
||||
|
||||
@@ -298,7 +286,7 @@ interface IrTypeSystemContext : TypeSystemContext, TypeSystemCommonSuperTypesCon
|
||||
|
||||
capturedType.constructor.initSuperTypes(capturedSuperTypes)
|
||||
|
||||
newArguments.add(makeTypeProjection(capturedType, Variance.INVARIANT))
|
||||
makeTypeProjection(capturedType, Variance.INVARIANT)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,15 +10,11 @@ import org.jetbrains.kotlin.ir.symbols.FqNameEqualityChecker
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.utils.compactIfPossible
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
import org.jetbrains.kotlin.utils.compactIfPossible
|
||||
|
||||
abstract class IrAbstractSimpleType(kotlinType: KotlinType?) : IrSimpleType(kotlinType) {
|
||||
|
||||
override val variance: Variance
|
||||
get() = Variance.INVARIANT
|
||||
|
||||
abstract override val classifier: IrClassifierSymbol
|
||||
abstract override val nullability: SimpleTypeNullability
|
||||
abstract override val arguments: List<IrTypeArgument>
|
||||
|
||||
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.ir.declarations.IrTypeParameter
|
||||
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.util.render
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
import org.jetbrains.kotlin.types.model.CaptureStatus
|
||||
@@ -44,11 +45,7 @@ class IrDynamicTypeImpl(
|
||||
val IrType.originalKotlinType: KotlinType?
|
||||
get() = (this as? IrTypeBase)?.kotlinType
|
||||
|
||||
object IrStarProjectionImpl : IrStarProjection {
|
||||
override fun equals(other: Any?): Boolean = this === other
|
||||
|
||||
override fun hashCode(): Int = System.identityHashCode(this)
|
||||
}
|
||||
data object IrStarProjectionImpl : IrStarProjection
|
||||
|
||||
/**
|
||||
* An instance which should be used when creating an IR element whose type cannot be determined at the moment of creation.
|
||||
@@ -60,15 +57,11 @@ object IrStarProjectionImpl : IrStarProjection {
|
||||
* however this could lead to a situation where we forget to set return type sometimes. This would result in crashes at unexpected moments,
|
||||
* especially in Kotlin/JS where function return types are not present in the resulting binary files.
|
||||
*/
|
||||
object IrUninitializedType : IrType() {
|
||||
data object IrUninitializedType : IrType() {
|
||||
override val annotations: List<IrConstructorCall> = emptyList()
|
||||
|
||||
override fun equals(other: Any?): Boolean = this === other
|
||||
|
||||
override fun hashCode(): Int = System.identityHashCode(this)
|
||||
}
|
||||
|
||||
class ReturnTypeIsNotInitializedException(function: IrFunction) : IllegalStateException(
|
||||
internal class ReturnTypeIsNotInitializedException(function: IrFunction) : IllegalStateException(
|
||||
"Return type is not initialized for function '${function.name}'"
|
||||
)
|
||||
|
||||
@@ -80,19 +73,12 @@ class IrCapturedType(
|
||||
projection: IrTypeArgument,
|
||||
typeParameter: IrTypeParameter
|
||||
) : IrSimpleType(null), CapturedTypeMarker {
|
||||
|
||||
override val variance: Variance
|
||||
get() = TODO("Not yet implemented")
|
||||
|
||||
class Constructor(val argument: IrTypeArgument, val typeParameter: IrTypeParameter) :
|
||||
CapturedTypeConstructorMarker {
|
||||
|
||||
private var _superTypes: List<IrType> = emptyList()
|
||||
|
||||
val superTypes: List<IrType> get() = _superTypes
|
||||
class Constructor(val argument: IrTypeArgument, val typeParameter: IrTypeParameter) : CapturedTypeConstructorMarker {
|
||||
var superTypes: List<IrType> = emptyList()
|
||||
private set
|
||||
|
||||
fun initSuperTypes(superTypes: List<IrType>) {
|
||||
_superTypes = superTypes
|
||||
this.superTypes = superTypes
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,18 +86,13 @@ class IrCapturedType(
|
||||
|
||||
override val classifier: IrClassifierSymbol get() = error("Captured Type does not have a classifier")
|
||||
override val arguments: List<IrTypeArgument> get() = emptyList()
|
||||
override val abbreviation: IrTypeAbbreviation? get () = null
|
||||
override val abbreviation: IrTypeAbbreviation? get() = null
|
||||
override val nullability: SimpleTypeNullability get() = SimpleTypeNullability.DEFINITELY_NOT_NULL
|
||||
override val annotations: List<IrConstructorCall> get() = emptyList()
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
return other is IrCapturedType
|
||||
&& captureStatus == other.captureStatus
|
||||
&& lowerType == other.lowerType
|
||||
&& constructor === other.constructor
|
||||
}
|
||||
override fun equals(other: Any?): Boolean = this === other
|
||||
|
||||
override fun hashCode(): Int {
|
||||
return (captureStatus.hashCode() * 31 + (lowerType?.hashCode() ?: 0)) * 31 + constructor.hashCode()
|
||||
}
|
||||
override fun hashCode(): Int = System.identityHashCode(this)
|
||||
|
||||
override fun toString(): String = "IrCapturedType(${constructor.argument.render()}"
|
||||
}
|
||||
|
||||
+12
-10
@@ -8,8 +8,11 @@ package org.jetbrains.kotlin.backend.common.linkage.partial
|
||||
import org.jetbrains.kotlin.ir.IrBuiltIns
|
||||
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
|
||||
import org.jetbrains.kotlin.ir.linkage.partial.ExploredClassifier
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||
import org.jetbrains.kotlin.ir.types.IrSimpleType
|
||||
import org.jetbrains.kotlin.ir.types.IrTypeAbbreviation
|
||||
import org.jetbrains.kotlin.ir.types.IrTypeArgument
|
||||
import org.jetbrains.kotlin.ir.types.SimpleTypeNullability
|
||||
|
||||
/**
|
||||
* Replacement for IR types that reference unusable classifier symbols.
|
||||
@@ -17,15 +20,14 @@ import org.jetbrains.kotlin.types.Variance
|
||||
*/
|
||||
internal class PartiallyLinkedMarkerType(
|
||||
builtIns: IrBuiltIns,
|
||||
val unusableClassifier: ExploredClassifier.Unusable
|
||||
val unusableClassifier: ExploredClassifier.Unusable,
|
||||
) : IrSimpleType(null) {
|
||||
override val annotations get() = emptyList<IrConstructorCall>()
|
||||
override val classifier = builtIns.anyClass
|
||||
override val nullability get() = SimpleTypeNullability.MARKED_NULLABLE
|
||||
override val arguments get() = emptyList<IrTypeArgument>()
|
||||
override val annotations: List<IrConstructorCall> get() = emptyList()
|
||||
override val classifier: IrClassSymbol = builtIns.anyClass
|
||||
override val nullability: SimpleTypeNullability get() = SimpleTypeNullability.MARKED_NULLABLE
|
||||
override val arguments: List<IrTypeArgument> get() = emptyList()
|
||||
override val abbreviation: IrTypeAbbreviation? get() = null
|
||||
override val variance get() = Variance.INVARIANT
|
||||
|
||||
override fun equals(other: Any?) = (other as? PartiallyLinkedMarkerType)?.unusableClassifier == unusableClassifier
|
||||
override fun hashCode() = unusableClassifier.hashCode()
|
||||
override fun equals(other: Any?): Boolean = (other as? PartiallyLinkedMarkerType)?.unusableClassifier == unusableClassifier
|
||||
override fun hashCode(): Int = unusableClassifier.hashCode()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user