Fir2Ir: handle type parameter signatures

Type parameter references should be deserialized.
This commit is contained in:
Georgy Bronnikov
2022-02-11 17:43:59 +03:00
committed by Alexander Udalov
parent a6d4cd0fe4
commit bbec6f0d85
11 changed files with 78 additions and 34 deletions
@@ -26,10 +26,7 @@ import org.jetbrains.kotlin.ir.builders.declarations.UNDEFINED_PARAMETER_INDEX
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.IrExternalPackageFragmentImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrEnumConstructorCallImpl
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.symbols.IrEnumEntrySymbol
import org.jetbrains.kotlin.ir.symbols.IrTypeAliasSymbol
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
import org.jetbrains.kotlin.ir.symbols.*
import org.jetbrains.kotlin.ir.symbols.impl.*
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
@@ -96,15 +93,15 @@ class Fir2IrClassifierStorage(
symbolTable.leaveScope(this)
}
internal fun preCacheTypeParameters(owner: FirTypeParameterRefsOwner) {
internal fun preCacheTypeParameters(owner: FirTypeParameterRefsOwner, irOwnerSymbol: IrSymbol) {
for ((index, typeParameter) in owner.typeParameters.withIndex()) {
val original = typeParameter.symbol.fir
getCachedIrTypeParameter(original, index)
?: createIrTypeParameterWithoutBounds(original, index)
?: createIrTypeParameterWithoutBounds(original, index, irOwnerSymbol)
if (owner is FirProperty && owner.isVar) {
val context = ConversionTypeContext.DEFAULT.inSetter()
getCachedIrTypeParameter(original, index, context)
?: createIrTypeParameterWithoutBounds(original, index, context)
?: createIrTypeParameterWithoutBounds(original, index, irOwnerSymbol, context)
}
}
}
@@ -115,7 +112,7 @@ class Fir2IrClassifierStorage(
) {
typeParameters = owner.typeParameters.mapIndexedNotNull { index, typeParameter ->
if (typeParameter !is FirTypeParameter) return@mapIndexedNotNull null
getIrTypeParameter(typeParameter, index, typeContext).apply {
getIrTypeParameter(typeParameter, index, symbol, typeContext).apply {
parent = this@setTypeParameters
if (superTypes.isEmpty()) {
superTypes = typeParameter.bounds.map { it.toIrType() }
@@ -126,7 +123,7 @@ class Fir2IrClassifierStorage(
private fun IrClass.declareTypeParameters(klass: FirClass) {
if (klass is FirRegularClass) {
preCacheTypeParameters(klass)
preCacheTypeParameters(klass, symbol)
setTypeParameters(klass)
val fieldsForContextReceiversOfCurrentClass = createContextReceiverFields(klass)
if (fieldsForContextReceiversOfCurrentClass.isNotEmpty()) {
@@ -263,9 +260,9 @@ class Fir2IrClassifierStorage(
parent: IrFile
): IrTypeAlias {
val signature = signatureComposer.composeSignature(typeAlias)
preCacheTypeParameters(typeAlias)
return typeAlias.convertWithOffsets { startOffset, endOffset ->
declareIrTypeAlias(signature) { symbol ->
preCacheTypeParameters(typeAlias, symbol)
val irTypeAlias = irFactory.createTypeAlias(
startOffset, endOffset, symbol,
typeAlias.name, components.visibilityConverter.convertToDescriptorVisibility(typeAlias.visibility),
@@ -375,13 +372,43 @@ class Fir2IrClassifierStorage(
private fun createIrTypeParameterWithoutBounds(
typeParameter: FirTypeParameter,
index: Int,
typeContext: ConversionTypeContext = ConversionTypeContext.DEFAULT
ownerSymbol: IrSymbol,
typeContext: ConversionTypeContext = ConversionTypeContext.DEFAULT,
): IrTypeParameter {
require(index >= 0)
val origin = typeParameter.computeIrOrigin()
val irTypeParameter = with(typeParameter) {
convertWithOffsets { startOffset, endOffset ->
irFactory.createTypeParameter(
signatureComposer.composeTypeParameterSignature(
typeParameter, index, ownerSymbol.signature
)?.let { signature ->
if (ownerSymbol is IrClassifierSymbol) {
symbolTable.declareGlobalTypeParameter(
signature,
symbolFactory = { IrTypeParameterPublicSymbolImpl(signature) }
) { symbol ->
irFactory.createTypeParameter(
startOffset, endOffset, origin, symbol,
name, if (index < 0) 0 else index,
isReified,
variance
)
}
} else {
symbolTable.declareScopedTypeParameter(
signature,
symbolFactory = { IrTypeParameterPublicSymbolImpl(signature) }
) { symbol ->
irFactory.createTypeParameter(
startOffset, endOffset, origin, symbol,
name, if (index < 0) 0 else index,
isReified,
variance
)
}
}
} ?: irFactory.createTypeParameter(
startOffset, endOffset, origin, IrTypeParameterSymbolImpl(),
name, if (index < 0) 0 else index,
isReified,
@@ -428,11 +455,12 @@ class Fir2IrClassifierStorage(
internal fun getIrTypeParameter(
typeParameter: FirTypeParameter,
index: Int,
ownerSymbol: IrSymbol,
typeContext: ConversionTypeContext = ConversionTypeContext.DEFAULT
): IrTypeParameter {
getCachedIrTypeParameter(typeParameter, index, typeContext)?.let { return it }
return typeParameter.run {
val irTypeParameter = createIrTypeParameterWithoutBounds(typeParameter, index, typeContext)
val irTypeParameter = createIrTypeParameterWithoutBounds(typeParameter, index, ownerSymbol, typeContext)
irTypeParameter.superTypes = bounds.map { it.toIrType() }
irTypeParameter
}
@@ -509,7 +509,6 @@ class Fir2IrDeclarationStorage(
// For private functions signature is null, fallback to non-lazy function
return createIrLazyFunction(function as FirSimpleFunction, signature, irParent, updatedOrigin)
}
classifierStorage.preCacheTypeParameters(function)
val name = simpleFunction?.name
?: if (isLambda) SpecialNames.ANONYMOUS else Name.special("<no name provided>")
val visibility = simpleFunction?.visibility ?: Visibilities.Local
@@ -518,6 +517,7 @@ class Fir2IrDeclarationStorage(
else simpleFunction?.isSuspend == true
val created = function.convertWithOffsets { startOffset, endOffset ->
val result = declareIrSimpleFunction(signature, simpleFunction?.containerSource) { symbol ->
classifierStorage.preCacheTypeParameters(function, symbol)
irFactory.createFunction(
startOffset, endOffset, updatedOrigin, symbol,
name, components.visibilityConverter.convertToDescriptorVisibility(visibility),
@@ -602,10 +602,10 @@ class Fir2IrDeclarationStorage(
): IrConstructor = convertCatching(constructor) {
val origin = constructor.computeIrOrigin(predefinedOrigin)
val isPrimary = constructor.isPrimary
classifierStorage.preCacheTypeParameters(constructor)
val signature = if (isLocal) null else signatureComposer.composeSignature(constructor)
val created = constructor.convertWithOffsets { startOffset, endOffset ->
declareIrConstructor(signature) { symbol ->
classifierStorage.preCacheTypeParameters(constructor, symbol)
irFactory.createConstructor(
startOffset, endOffset, origin, symbol,
SpecialNames.INIT, components.visibilityConverter.convertToDescriptorVisibility(constructor.visibility),
@@ -829,14 +829,9 @@ class Fir2IrDeclarationStorage(
// For private functions signature is null, fallback to non-lazy property
return createIrLazyProperty(property, signature, irParent, origin)
}
classifierStorage.preCacheTypeParameters(property)
if (property.delegate != null) {
((property.delegate as? FirQualifiedAccess)?.calleeReference?.resolvedSymbol?.fir as? FirTypeParameterRefsOwner)?.let {
classifierStorage.preCacheTypeParameters(it)
}
}
return property.convertWithOffsets { startOffset, endOffset ->
val result = declareIrProperty(signature, property.containerSource) { symbol ->
classifierStorage.preCacheTypeParameters(property, symbol)
irFactory.createProperty(
startOffset, endOffset, origin, symbol,
property.name, components.visibilityConverter.convertToDescriptorVisibility(property.visibility), property.modality!!,
@@ -861,6 +856,9 @@ class Fir2IrDeclarationStorage(
val setter = property.setter
if (delegate != null || property.hasBackingField) {
backingField = if (delegate != null) {
((delegate as? FirQualifiedAccess)?.calleeReference?.resolvedSymbol?.fir as? FirTypeParameterRefsOwner)?.let {
classifierStorage.preCacheTypeParameters(it, symbol)
}
createBackingField(
property, IrDeclarationOrigin.PROPERTY_DELEGATE,
components.visibilityConverter.convertToDescriptorVisibility(property.fieldVisibility),
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.fir.backend
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.declarations.FirProperty
import org.jetbrains.kotlin.fir.declarations.FirTypeParameter
import org.jetbrains.kotlin.fir.signaturer.FirMangler
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
import org.jetbrains.kotlin.ir.util.IdSignature
@@ -15,5 +16,6 @@ interface Fir2IrSignatureComposer {
val mangler: FirMangler
fun composeSignature(declaration: FirDeclaration, containingClass: ConeClassLikeLookupTag? = null): IdSignature?
fun composeAccessorSignature(property: FirProperty, isSetter: Boolean, containingClass: ConeClassLikeLookupTag? = null): IdSignature?
fun composeTypeParameterSignature(typeParameter: FirTypeParameter, index: Int, containerSignature: IdSignature?): IdSignature?
fun withFileSignature(sig: IdSignature.FileSignature, body: () -> Unit)
}
@@ -15,10 +15,7 @@ import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
import org.jetbrains.kotlin.ir.declarations.IrDeclarationParent
import org.jetbrains.kotlin.ir.declarations.IrProperty
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.linkage.IrProvider
import org.jetbrains.kotlin.ir.symbols.*
import org.jetbrains.kotlin.ir.util.IdSignature
@@ -56,7 +53,12 @@ class FirIrProvider(val fir2IrComponents: Fir2IrComponents) : IrProvider {
private fun getDeclarationForCompositeSignature(signature: IdSignature.CompositeSignature, kind: SymbolKind): IrDeclaration? {
if (kind == SymbolKind.TYPE_PARAMETER_SYMBOL) {
TODO()
val container = (getDeclarationForSignature(signature.container, SymbolKind.CLASS_SYMBOL)
?: getDeclarationForSignature(signature.container, SymbolKind.FUNCTION_SYMBOL)
?: getDeclarationForSignature(signature.container, SymbolKind.PROPERTY_SYMBOL)
) as IrTypeParametersContainer
val localSignature = signature.inner as IdSignature.LocalSignature
return container.typeParameters[localSignature.index()]
}
return getDeclarationForSignature(signature.nearestPublicSig(), kind)
}
@@ -35,6 +35,7 @@ import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.util.IdSignature
import org.jetbrains.kotlin.ir.util.parentAsClass
import org.jetbrains.kotlin.ir.util.withScope
import org.jetbrains.kotlin.load.java.JavaDescriptorVisibilities
import org.jetbrains.kotlin.name.Name
@@ -220,7 +221,6 @@ class FakeOverrideGenerator(
// We've got no relevant declaration in FIR world for such a fake override in current class, thus we're creating it here
val fakeOverrideSymbol = createFakeOverrideSymbol(originalDeclaration, baseSymbol)
declarationStorage.saveFakeOverrideInClass(irClass, originalDeclaration, fakeOverrideSymbol.fir)
classifierStorage.preCacheTypeParameters(originalDeclaration)
fakeOverrideSymbol.fir to listOf(originalSymbol)
}
else -> {
@@ -274,7 +274,7 @@ class FakeOverrideGenerator(
// We've got no relevant declaration in FIR world for such a fake override in current class, thus we're creating it here
val fakeOverrideSymbol = createFakeOverrideSymbol(originalDeclaration, baseSymbol)
declarationStorage.saveFakeOverrideInClass(irClass, originalDeclaration, fakeOverrideSymbol.fir)
classifierStorage.preCacheTypeParameters(originalDeclaration)
classifierStorage.preCacheTypeParameters(originalDeclaration, irClass.symbol)
fakeOverrideSymbol.fir to listOf(originalSymbol)
}
else -> {
@@ -44,7 +44,7 @@ class Fir2IrLazyClass(
IrMaybeDeserializedClass, DeserializableClass, Fir2IrComponents by components {
init {
symbol.bind(this)
classifierStorage.preCacheTypeParameters(fir)
classifierStorage.preCacheTypeParameters(fir, symbol)
}
override var annotations: List<IrConstructorCall> by createLazyAnnotations()
@@ -39,7 +39,7 @@ class Fir2IrLazyConstructor(
Fir2IrComponents by components {
init {
symbol.bind(this)
classifierStorage.preCacheTypeParameters(fir)
classifierStorage.preCacheTypeParameters(fir, symbol)
}
override var annotations: List<IrConstructorCall> by createLazyAnnotations()
@@ -45,7 +45,7 @@ class Fir2IrLazyProperty(
) : IrProperty(), AbstractFir2IrLazyDeclaration<FirProperty>, Fir2IrComponents by components {
init {
symbol.bind(this)
classifierStorage.preCacheTypeParameters(fir)
classifierStorage.preCacheTypeParameters(fir, symbol)
}
override var annotations: List<IrConstructorCall> by createLazyAnnotations()
@@ -33,7 +33,7 @@ class Fir2IrLazySimpleFunction(
) : AbstractFir2IrLazyFunction<FirSimpleFunction>(components, startOffset, endOffset, origin, symbol, isFakeOverride) {
init {
symbol.bind(this)
classifierStorage.preCacheTypeParameters(fir)
classifierStorage.preCacheTypeParameters(fir, symbol)
}
override var annotations: List<IrConstructorCall> by createLazyAnnotations()
@@ -17,7 +17,7 @@ interface Fir2IrTypeParametersContainer : IrTypeParametersContainer, Fir2IrCompo
fun prepareTypeParameters() {
typeParameters = fir.typeParameters.mapIndexedNotNull { index, typeParameter ->
if (typeParameter !is FirTypeParameter) return@mapIndexedNotNull null
classifierStorage.getIrTypeParameter(typeParameter, index).apply {
classifierStorage.getIrTypeParameter(typeParameter, index, symbol).apply {
parent = this@Fir2IrTypeParametersContainer
if (superTypes.isEmpty()) {
superTypes = typeParameter.bounds.map { it.toIrType(typeConverter) }
@@ -25,4 +25,4 @@ interface Fir2IrTypeParametersContainer : IrTypeParametersContainer, Fir2IrCompo
}
}
}
}
}
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.fir.signaturer
import org.jetbrains.kotlin.backend.common.serialization.mangle.MangleConstant
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.backend.Fir2IrSignatureComposer
@@ -17,6 +18,7 @@ import org.jetbrains.kotlin.fir.declarations.utils.visibility
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
import org.jetbrains.kotlin.fir.visitors.FirVisitor
import org.jetbrains.kotlin.ir.util.IdSignature
import org.jetbrains.kotlin.name.ClassId
// @NoMutableState -- we'll restore this annotation once we get rid of withFileSignature().
class FirBasedSignatureComposer(override val mangler: FirMangler) : Fir2IrSignatureComposer {
@@ -118,6 +120,18 @@ class FirBasedSignatureComposer(override val mangler: FirMangler) : Fir2IrSignat
publicSignature
}
override fun composeTypeParameterSignature(
typeParameter: FirTypeParameter,
index: Int,
containerSignature: IdSignature?
): IdSignature? {
if (containerSignature == null) return null
return IdSignature.CompositeSignature(
containerSignature,
IdSignature.LocalSignature(MangleConstant.TYPE_PARAMETER_MARKER_NAME, index.toLong(), null)
)
}
override fun composeAccessorSignature(
property: FirProperty,
isSetter: Boolean,