[FIR2IR] Implement support for Fir2IrLazyTypeAlias

Fir-based lazy type alias is required in IR text tests to check that
lazily loaded IR is equivalent to deserialized IR (module bodies)
and does not cause ABI compatibility issues in KLIB-based backends.

^KT-65033
This commit is contained in:
Dmitriy Dolovov
2024-01-16 16:44:55 +01:00
committed by Space Team
parent 96db6eb94f
commit 8f046d36e0
4 changed files with 98 additions and 19 deletions
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeAliasSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
@@ -399,6 +400,28 @@ class Fir2IrClassifierStorage(
internal fun getCachedTypeAlias(firTypeAlias: FirTypeAlias): IrTypeAlias? = typeAliasCache[firTypeAlias]
fun referenceTypeAlias(firTypeAliasSymbol: FirTypeAliasSymbol): IrTypeAlias {
val firTypeAlias = firTypeAliasSymbol.fir
classifierStorage.getCachedTypeAlias(firTypeAlias)?.let { return it }
val typeAliasId = firTypeAliasSymbol.classId
val parentId = typeAliasId.outerClassId
val parentClass = parentId?.let { session.symbolProvider.getClassLikeSymbolByClassId(it) }
val irParent = declarationStorage.findIrParent(
typeAliasId.packageFqName,
parentClass?.toLookupTag(),
firTypeAliasSymbol,
firTypeAlias.origin
)!!
val symbol = createTypeAliasSymbol(firTypeAlias)
val irTypeAlias = lazyDeclarationsGenerator.createIrLazyTypeAlias(firTypeAlias, irParent, symbol)
typeAliasCache[firTypeAlias] = irTypeAlias
irTypeAlias.prepareTypeParameters()
return irTypeAlias
}
// ------------------------------------ code fragments ------------------------------------
fun getCachedIrCodeFragment(codeFragment: FirCodeFragment): IrClass? {
@@ -16,10 +16,7 @@ import org.jetbrains.kotlin.fir.moduleData
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
import org.jetbrains.kotlin.fir.scopes.*
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.ir.IrBuiltIns
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
import org.jetbrains.kotlin.ir.linkage.IrDeserializer
@@ -81,17 +78,8 @@ class Fir2IrPluginContext(
}
override fun referenceTypeAlias(classId: ClassId): IrTypeAliasSymbol? {
return referenceClassLikeSymbol(classId, symbolProvider::getClassLikeSymbolByClassId, symbolTable::referenceTypeAlias)
}
private inline fun <R> referenceClassLikeSymbol(
id: ClassId,
firSymbolExtractor: (ClassId) -> FirClassLikeSymbol<*>?,
irSymbolExtractor: (IdSignature) -> R
): R? {
val firSymbol = firSymbolExtractor(id) ?: return null
val signature = components.signatureComposer.composeSignature(firSymbol.fir) ?: return null
return irSymbolExtractor(signature)
val firSymbol = symbolProvider.getClassLikeSymbolByClassId(classId) as? FirTypeAliasSymbol ?: return null
return components.classifierStorage.referenceTypeAlias(firSymbol).symbol
}
override fun referenceConstructors(classId: ClassId): Collection<IrConstructorSymbol> {
@@ -12,10 +12,7 @@ import org.jetbrains.kotlin.fir.isSubstitutionOrIntersectionOverride
import org.jetbrains.kotlin.fir.lazy.*
import org.jetbrains.kotlin.fir.unwrapUseSiteSubstitutionOverrides
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.*
class Fir2IrLazyDeclarationsGenerator(val components: Fir2IrComponents) : Fir2IrComponents by components {
internal fun createIrLazyFunction(
@@ -75,6 +72,16 @@ class Fir2IrLazyDeclarationsGenerator(val components: Fir2IrComponents) : Fir2Ir
Fir2IrLazyClass(components, startOffset, endOffset, firClassOrigin, firClass, symbol, irParent)
}
fun createIrLazyTypeAlias(
firTypeAlias: FirTypeAlias,
irParent: IrDeclarationParent,
symbol: IrTypeAliasSymbol
): Fir2IrLazyTypeAlias = firTypeAlias.convertWithOffsets { startOffset, endOffset ->
Fir2IrLazyTypeAlias(
components, startOffset, endOffset, IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB, firTypeAlias, symbol, irParent
)
}
fun createIrLazyField(
fir: FirField,
symbol: IrFieldSymbol,
@@ -0,0 +1,61 @@
/*
* Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.fir.lazy
import org.jetbrains.kotlin.descriptors.DescriptorVisibility
import org.jetbrains.kotlin.descriptors.TypeAliasDescriptor
import org.jetbrains.kotlin.fir.backend.Fir2IrComponents
import org.jetbrains.kotlin.fir.backend.toIrType
import org.jetbrains.kotlin.fir.declarations.FirTypeAlias
import org.jetbrains.kotlin.fir.declarations.utils.isActual
import org.jetbrains.kotlin.fir.declarations.utils.visibility
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
import org.jetbrains.kotlin.ir.declarations.IrDeclarationParent
import org.jetbrains.kotlin.ir.declarations.IrTypeAlias
import org.jetbrains.kotlin.ir.declarations.IrTypeParameter
import org.jetbrains.kotlin.ir.declarations.lazy.lazyVar
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
import org.jetbrains.kotlin.ir.symbols.IrTypeAliasSymbol
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.name.Name
class Fir2IrLazyTypeAlias(
components: Fir2IrComponents,
override val startOffset: Int,
override val endOffset: Int,
override var origin: IrDeclarationOrigin,
override val fir: FirTypeAlias,
override val symbol: IrTypeAliasSymbol,
override var parent: IrDeclarationParent
) : IrTypeAlias(), AbstractFir2IrLazyDeclaration<FirTypeAlias>, Fir2IrTypeParametersContainer, Fir2IrComponents by components {
init {
symbol.bind(this)
classifierStorage.preCacheTypeParameters(fir, symbol)
}
override var annotations: List<IrConstructorCall> by createLazyAnnotations()
override lateinit var typeParameters: List<IrTypeParameter>
@ObsoleteDescriptorBasedAPI
override val descriptor: TypeAliasDescriptor
get() = symbol.descriptor
override var name: Name
get() = fir.name
set(_) = mutationNotSupported()
override var visibility: DescriptorVisibility = components.visibilityConverter.convertToDescriptorVisibility(fir.visibility)
set(_) = mutationNotSupported()
override var isActual: Boolean
get() = fir.isActual
set(_) = mutationNotSupported()
override var expandedType: IrType by lazyVar(lock) {
fir.expandedTypeRef.toIrType(typeConverter)
}
}