FIR2IR (refactoring): introduce ConversionTypeContext
This commit is contained in:
@@ -50,53 +50,72 @@ internal fun <T : IrElement> FirElement.convertWithOffsets(
|
|||||||
|
|
||||||
internal fun createErrorType(): IrErrorType = IrErrorTypeImpl(null, emptyList(), Variance.INVARIANT)
|
internal fun createErrorType(): IrErrorType = IrErrorTypeImpl(null, emptyList(), Variance.INVARIANT)
|
||||||
|
|
||||||
|
internal enum class ConversionTypeOrigin {
|
||||||
|
DEFAULT,
|
||||||
|
SETTER
|
||||||
|
}
|
||||||
|
|
||||||
|
class ConversionTypeContext internal constructor(
|
||||||
|
internal val definitelyNotNull: Boolean,
|
||||||
|
internal val origin: ConversionTypeOrigin
|
||||||
|
) {
|
||||||
|
fun definitelyNotNull() = ConversionTypeContext(true, origin)
|
||||||
|
|
||||||
|
fun inSetter() = ConversionTypeContext(definitelyNotNull, ConversionTypeOrigin.SETTER)
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
internal val DEFAULT = ConversionTypeContext(
|
||||||
|
definitelyNotNull = false, origin = ConversionTypeOrigin.DEFAULT
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun FirTypeRef.toIrType(
|
fun FirTypeRef.toIrType(
|
||||||
session: FirSession,
|
session: FirSession,
|
||||||
declarationStorage: Fir2IrDeclarationStorage,
|
declarationStorage: Fir2IrDeclarationStorage,
|
||||||
irBuiltIns: IrBuiltIns,
|
irBuiltIns: IrBuiltIns,
|
||||||
forSetter: Boolean = false
|
typeContext: ConversionTypeContext = ConversionTypeContext.DEFAULT
|
||||||
): IrType {
|
): IrType {
|
||||||
if (this !is FirResolvedTypeRef) {
|
if (this !is FirResolvedTypeRef) {
|
||||||
return createErrorType()
|
return createErrorType()
|
||||||
}
|
}
|
||||||
return type.toIrType(session, declarationStorage, irBuiltIns, forSetter = forSetter)
|
return type.toIrType(session, declarationStorage, irBuiltIns, typeContext)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun ConeKotlinType.toIrType(
|
fun ConeKotlinType.toIrType(
|
||||||
session: FirSession,
|
session: FirSession,
|
||||||
declarationStorage: Fir2IrDeclarationStorage,
|
declarationStorage: Fir2IrDeclarationStorage,
|
||||||
irBuiltIns: IrBuiltIns,
|
irBuiltIns: IrBuiltIns,
|
||||||
definitelyNotNull: Boolean = false,
|
typeContext: ConversionTypeContext = ConversionTypeContext.DEFAULT
|
||||||
forSetter: Boolean = false
|
|
||||||
): IrType {
|
): IrType {
|
||||||
return when (this) {
|
return when (this) {
|
||||||
is ConeKotlinErrorType -> createErrorType()
|
is ConeKotlinErrorType -> createErrorType()
|
||||||
is ConeLookupTagBasedType -> {
|
is ConeLookupTagBasedType -> {
|
||||||
val irSymbol = getArrayType(this.classId, irBuiltIns) ?: run {
|
val irSymbol = getArrayType(this.classId, irBuiltIns) ?: run {
|
||||||
val firSymbol = this.lookupTag.toSymbol(session) ?: return createErrorType()
|
val firSymbol = this.lookupTag.toSymbol(session) ?: return createErrorType()
|
||||||
firSymbol.toIrSymbol(session, declarationStorage, forSetter)
|
firSymbol.toIrSymbol(session, declarationStorage, typeContext)
|
||||||
}
|
}
|
||||||
// TODO: annotations
|
// TODO: annotations
|
||||||
IrSimpleTypeImpl(
|
IrSimpleTypeImpl(
|
||||||
irSymbol, !definitelyNotNull && this.isMarkedNullable,
|
irSymbol, !typeContext.definitelyNotNull && this.isMarkedNullable,
|
||||||
typeArguments.map { it.toIrTypeArgument(session, declarationStorage, irBuiltIns) },
|
typeArguments.map { it.toIrTypeArgument(session, declarationStorage, irBuiltIns) },
|
||||||
emptyList()
|
emptyList()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
is ConeFlexibleType -> {
|
is ConeFlexibleType -> {
|
||||||
// TODO: yet we take more general type. Not quite sure it's Ok
|
// TODO: yet we take more general type. Not quite sure it's Ok
|
||||||
upperBound.toIrType(session, declarationStorage, irBuiltIns, definitelyNotNull)
|
upperBound.toIrType(session, declarationStorage, irBuiltIns, typeContext)
|
||||||
}
|
}
|
||||||
is ConeCapturedType -> TODO()
|
is ConeCapturedType -> TODO()
|
||||||
is ConeDefinitelyNotNullType -> {
|
is ConeDefinitelyNotNullType -> {
|
||||||
original.toIrType(session, declarationStorage, irBuiltIns, definitelyNotNull = true)
|
original.toIrType(session, declarationStorage, irBuiltIns, typeContext.definitelyNotNull())
|
||||||
}
|
}
|
||||||
is ConeIntersectionType -> {
|
is ConeIntersectionType -> {
|
||||||
// TODO: add intersectionTypeApproximation
|
// TODO: add intersectionTypeApproximation
|
||||||
intersectedTypes.first().toIrType(session, declarationStorage, irBuiltIns, definitelyNotNull)
|
intersectedTypes.first().toIrType(session, declarationStorage, irBuiltIns, typeContext)
|
||||||
}
|
}
|
||||||
is ConeStubType -> createErrorType()
|
is ConeStubType -> createErrorType()
|
||||||
is ConeIntegerLiteralType -> getApproximatedType().toIrType(session, declarationStorage, irBuiltIns, definitelyNotNull)
|
is ConeIntegerLiteralType -> getApproximatedType().toIrType(session, declarationStorage, irBuiltIns, typeContext)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,11 +160,11 @@ fun ConeTypeProjection.toIrTypeArgument(
|
|||||||
fun FirClassifierSymbol<*>.toIrSymbol(
|
fun FirClassifierSymbol<*>.toIrSymbol(
|
||||||
session: FirSession,
|
session: FirSession,
|
||||||
declarationStorage: Fir2IrDeclarationStorage,
|
declarationStorage: Fir2IrDeclarationStorage,
|
||||||
forSetter: Boolean = false
|
typeContext: ConversionTypeContext = ConversionTypeContext.DEFAULT
|
||||||
): IrClassifierSymbol {
|
): IrClassifierSymbol {
|
||||||
return when (this) {
|
return when (this) {
|
||||||
is FirTypeParameterSymbol -> {
|
is FirTypeParameterSymbol -> {
|
||||||
toTypeParameterSymbol(declarationStorage, forSetter)
|
toTypeParameterSymbol(declarationStorage, typeContext)
|
||||||
}
|
}
|
||||||
is FirTypeAliasSymbol -> {
|
is FirTypeAliasSymbol -> {
|
||||||
val typeAlias = fir
|
val typeAlias = fir
|
||||||
@@ -201,9 +220,9 @@ fun FirClassSymbol<*>.toClassSymbol(declarationStorage: Fir2IrDeclarationStorage
|
|||||||
|
|
||||||
fun FirTypeParameterSymbol.toTypeParameterSymbol(
|
fun FirTypeParameterSymbol.toTypeParameterSymbol(
|
||||||
declarationStorage: Fir2IrDeclarationStorage,
|
declarationStorage: Fir2IrDeclarationStorage,
|
||||||
forSetter: Boolean = false
|
typeContext: ConversionTypeContext = ConversionTypeContext.DEFAULT
|
||||||
): IrTypeParameterSymbol {
|
): IrTypeParameterSymbol {
|
||||||
return declarationStorage.getIrTypeParameterSymbol(this, forSetter)
|
return declarationStorage.getIrTypeParameterSymbol(this, typeContext)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun FirFunctionSymbol<*>.toFunctionSymbol(declarationStorage: Fir2IrDeclarationStorage): IrFunctionSymbol {
|
fun FirFunctionSymbol<*>.toFunctionSymbol(declarationStorage: Fir2IrDeclarationStorage): IrFunctionSymbol {
|
||||||
|
|||||||
+38
-18
@@ -102,8 +102,11 @@ class Fir2IrDeclarationStorage(
|
|||||||
irSymbolTable.leaveScope(descriptor)
|
irSymbolTable.leaveScope(descriptor)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun FirTypeRef.toIrType(session: FirSession, declarationStorage: Fir2IrDeclarationStorage, forSetter: Boolean = false) =
|
private fun FirTypeRef.toIrType(
|
||||||
toIrType(session, declarationStorage, irBuiltIns, forSetter)
|
session: FirSession,
|
||||||
|
declarationStorage: Fir2IrDeclarationStorage,
|
||||||
|
typeContext: ConversionTypeContext = ConversionTypeContext.DEFAULT
|
||||||
|
) = toIrType(session, declarationStorage, irBuiltIns, typeContext)
|
||||||
|
|
||||||
private fun getIrExternalPackageFragment(fqName: FqName): IrExternalPackageFragment {
|
private fun getIrExternalPackageFragment(fqName: FqName): IrExternalPackageFragment {
|
||||||
return fragmentCache.getOrPut(fqName) {
|
return fragmentCache.getOrPut(fqName) {
|
||||||
@@ -151,14 +154,17 @@ class Fir2IrDeclarationStorage(
|
|||||||
owner.typeParameters.mapIndexed { index, typeParameter ->
|
owner.typeParameters.mapIndexed { index, typeParameter ->
|
||||||
getIrTypeParameter(typeParameter, index)
|
getIrTypeParameter(typeParameter, index)
|
||||||
if (owner is FirProperty && owner.isVar) {
|
if (owner is FirProperty && owner.isVar) {
|
||||||
getIrTypeParameter(typeParameter, index, forSetter = true)
|
getIrTypeParameter(typeParameter, index, ConversionTypeContext.DEFAULT.inSetter())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun IrTypeParametersContainer.setTypeParameters(owner: FirTypeParametersOwner, forSetter: Boolean = false) {
|
private fun IrTypeParametersContainer.setTypeParameters(
|
||||||
|
owner: FirTypeParametersOwner,
|
||||||
|
typeContext: ConversionTypeContext = ConversionTypeContext.DEFAULT
|
||||||
|
) {
|
||||||
typeParameters = owner.typeParameters.mapIndexed { index, typeParameter ->
|
typeParameters = owner.typeParameters.mapIndexed { index, typeParameter ->
|
||||||
getIrTypeParameter(typeParameter, index, forSetter).apply { parent = this@setTypeParameters }
|
getIrTypeParameter(typeParameter, index, typeContext).apply { parent = this@setTypeParameters }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -328,12 +334,16 @@ class Fir2IrDeclarationStorage(
|
|||||||
}.declareSupertypesAndTypeParameters(anonymousObject)
|
}.declareSupertypesAndTypeParameters(anonymousObject)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getIrTypeParameter(typeParameter: FirTypeParameter, index: Int = -1, forSetter: Boolean = false): IrTypeParameter {
|
private fun getIrTypeParameter(
|
||||||
|
typeParameter: FirTypeParameter,
|
||||||
|
index: Int = -1,
|
||||||
|
typeContext: ConversionTypeContext = ConversionTypeContext.DEFAULT
|
||||||
|
): IrTypeParameter {
|
||||||
// Here transformation is a bit difficult because one FIR property type parameter
|
// Here transformation is a bit difficult because one FIR property type parameter
|
||||||
// can be transformed to two different type parameters: one for getter and another one for setter
|
// can be transformed to two different type parameters: one for getter and another one for setter
|
||||||
val simpleCachedParameter = typeParameterCache[typeParameter]
|
val simpleCachedParameter = typeParameterCache[typeParameter]
|
||||||
if (simpleCachedParameter != null) {
|
if (simpleCachedParameter != null) {
|
||||||
if (!forSetter) {
|
if (typeContext.origin != ConversionTypeOrigin.SETTER) {
|
||||||
return simpleCachedParameter
|
return simpleCachedParameter
|
||||||
}
|
}
|
||||||
if (index < 0) {
|
if (index < 0) {
|
||||||
@@ -343,7 +353,7 @@ class Fir2IrDeclarationStorage(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (forSetter) {
|
if (typeContext.origin == ConversionTypeOrigin.SETTER) {
|
||||||
typeParameterCacheForSetter[typeParameter]?.let { return it }
|
typeParameterCacheForSetter[typeParameter]?.let { return it }
|
||||||
}
|
}
|
||||||
return typeParameter.run {
|
return typeParameter.run {
|
||||||
@@ -368,7 +378,7 @@ class Fir2IrDeclarationStorage(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Cache the type parameter BEFORE processing its bounds/supertypes, to properly handle recursive type bounds.
|
// Cache the type parameter BEFORE processing its bounds/supertypes, to properly handle recursive type bounds.
|
||||||
if (forSetter) {
|
if (typeContext.origin == ConversionTypeOrigin.SETTER) {
|
||||||
typeParameterCacheForSetter[typeParameter] = irTypeParameter
|
typeParameterCacheForSetter[typeParameter] = irTypeParameter
|
||||||
} else {
|
} else {
|
||||||
typeParameterCache[typeParameter] = irTypeParameter
|
typeParameterCache[typeParameter] = irTypeParameter
|
||||||
@@ -445,9 +455,13 @@ class Fir2IrDeclarationStorage(
|
|||||||
setTypeParameters(function)
|
setTypeParameters(function)
|
||||||
}
|
}
|
||||||
val forSetter = function is FirPropertyAccessor && function.isSetter
|
val forSetter = function is FirPropertyAccessor && function.isSetter
|
||||||
|
val typeContext = ConversionTypeContext(
|
||||||
|
definitelyNotNull = false,
|
||||||
|
origin = if (forSetter) ConversionTypeOrigin.SETTER else ConversionTypeOrigin.DEFAULT
|
||||||
|
)
|
||||||
if (function is FirDefaultPropertySetter) {
|
if (function is FirDefaultPropertySetter) {
|
||||||
val type = function.valueParameters.first().returnTypeRef.toIrType(
|
val type = function.valueParameters.first().returnTypeRef.toIrType(
|
||||||
session, this@Fir2IrDeclarationStorage, forSetter = true
|
session, this@Fir2IrDeclarationStorage, ConversionTypeContext.DEFAULT.inSetter()
|
||||||
)
|
)
|
||||||
declareDefaultSetterParameter(type)
|
declareDefaultSetterParameter(type)
|
||||||
} else if (function != null) {
|
} else if (function != null) {
|
||||||
@@ -455,7 +469,7 @@ class Fir2IrDeclarationStorage(
|
|||||||
createAndSaveIrParameter(
|
createAndSaveIrParameter(
|
||||||
valueParameter, index,
|
valueParameter, index,
|
||||||
useStubForDefaultValueStub = function !is FirConstructor || containingClass?.name != Name.identifier("Enum"),
|
useStubForDefaultValueStub = function !is FirConstructor || containingClass?.name != Name.identifier("Enum"),
|
||||||
forSetter = forSetter
|
typeContext
|
||||||
).apply {
|
).apply {
|
||||||
this.parent = parent
|
this.parent = parent
|
||||||
}
|
}
|
||||||
@@ -468,7 +482,7 @@ class Fir2IrDeclarationStorage(
|
|||||||
extensionReceiverParameter = receiverTypeRef.convertWithOffsets { startOffset, endOffset ->
|
extensionReceiverParameter = receiverTypeRef.convertWithOffsets { startOffset, endOffset ->
|
||||||
declareThisReceiverParameter(
|
declareThisReceiverParameter(
|
||||||
parent,
|
parent,
|
||||||
thisType = receiverTypeRef.toIrType(session, this@Fir2IrDeclarationStorage, forSetter),
|
thisType = receiverTypeRef.toIrType(session, this@Fir2IrDeclarationStorage, typeContext),
|
||||||
thisOrigin = thisOrigin,
|
thisOrigin = thisOrigin,
|
||||||
startOffset = startOffset,
|
startOffset = startOffset,
|
||||||
endOffset = endOffset
|
endOffset = endOffset
|
||||||
@@ -657,10 +671,13 @@ class Fir2IrDeclarationStorage(
|
|||||||
isFakeOverride = origin == IrDeclarationOrigin.FAKE_OVERRIDE,
|
isFakeOverride = origin == IrDeclarationOrigin.FAKE_OVERRIDE,
|
||||||
isOperator = false
|
isOperator = false
|
||||||
).apply {
|
).apply {
|
||||||
setTypeParameters(property, forSetter = isSetter)
|
setTypeParameters(property, ConversionTypeContext(
|
||||||
|
definitelyNotNull = false,
|
||||||
|
origin = if (isSetter) ConversionTypeOrigin.SETTER else ConversionTypeOrigin.DEFAULT
|
||||||
|
))
|
||||||
if (propertyAccessor == null && isSetter) {
|
if (propertyAccessor == null && isSetter) {
|
||||||
declareDefaultSetterParameter(
|
declareDefaultSetterParameter(
|
||||||
property.returnTypeRef.toIrType(session, this@Fir2IrDeclarationStorage, forSetter = true)
|
property.returnTypeRef.toIrType(session, this@Fir2IrDeclarationStorage, ConversionTypeContext.DEFAULT.inSetter())
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}.bindAndDeclareParameters(
|
}.bindAndDeclareParameters(
|
||||||
@@ -799,7 +816,7 @@ class Fir2IrDeclarationStorage(
|
|||||||
valueParameter: FirValueParameter,
|
valueParameter: FirValueParameter,
|
||||||
index: Int = -1,
|
index: Int = -1,
|
||||||
useStubForDefaultValueStub: Boolean = true,
|
useStubForDefaultValueStub: Boolean = true,
|
||||||
forSetter: Boolean = false
|
typeContext: ConversionTypeContext = ConversionTypeContext.DEFAULT
|
||||||
): IrValueParameter {
|
): IrValueParameter {
|
||||||
val descriptor = WrappedValueParameterDescriptor()
|
val descriptor = WrappedValueParameterDescriptor()
|
||||||
val origin = IrDeclarationOrigin.DEFINED
|
val origin = IrDeclarationOrigin.DEFINED
|
||||||
@@ -813,7 +830,7 @@ class Fir2IrDeclarationStorage(
|
|||||||
valueParameter.name, index, type,
|
valueParameter.name, index, type,
|
||||||
if (!valueParameter.isVararg) null
|
if (!valueParameter.isVararg) null
|
||||||
else valueParameter.returnTypeRef.coneTypeSafe<ConeKotlinType>()?.arrayElementType(session)?.toIrType(
|
else valueParameter.returnTypeRef.coneTypeSafe<ConeKotlinType>()?.arrayElementType(session)?.toIrType(
|
||||||
session, this, irBuiltIns, forSetter
|
session, this, irBuiltIns, typeContext
|
||||||
),
|
),
|
||||||
valueParameter.isCrossinline, valueParameter.isNoinline
|
valueParameter.isCrossinline, valueParameter.isNoinline
|
||||||
).apply {
|
).apply {
|
||||||
@@ -894,8 +911,11 @@ class Fir2IrDeclarationStorage(
|
|||||||
return irSymbolTable.referenceClass(irClass.descriptor)
|
return irSymbolTable.referenceClass(irClass.descriptor)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getIrTypeParameterSymbol(firTypeParameterSymbol: FirTypeParameterSymbol, forSetter: Boolean): IrTypeParameterSymbol {
|
fun getIrTypeParameterSymbol(
|
||||||
val irTypeParameter = getIrTypeParameter(firTypeParameterSymbol.fir, forSetter = forSetter)
|
firTypeParameterSymbol: FirTypeParameterSymbol,
|
||||||
|
typeContext: ConversionTypeContext
|
||||||
|
): IrTypeParameterSymbol {
|
||||||
|
val irTypeParameter = getIrTypeParameter(firTypeParameterSymbol.fir, typeContext = typeContext)
|
||||||
return irSymbolTable.referenceTypeParameter(irTypeParameter.descriptor)
|
return irSymbolTable.referenceTypeParameter(irTypeParameter.descriptor)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user