From bbec6f0d85e97885e554804ee3355a15a9742c90 Mon Sep 17 00:00:00 2001 From: Georgy Bronnikov Date: Fri, 11 Feb 2022 17:43:59 +0300 Subject: [PATCH] Fir2Ir: handle type parameter signatures Type parameter references should be deserialized. --- .../fir/backend/Fir2IrClassifierStorage.kt | 54 ++++++++++++++----- .../fir/backend/Fir2IrDeclarationStorage.kt | 14 +++-- .../fir/backend/Fir2IrSignatureComposer.kt | 2 + .../kotlin/fir/backend/FirIrProvider.kt | 12 +++-- .../generators/FakeOverrideGenerator.kt | 4 +- .../kotlin/fir/lazy/Fir2IrLazyClass.kt | 2 +- .../kotlin/fir/lazy/Fir2IrLazyConstructor.kt | 2 +- .../kotlin/fir/lazy/Fir2IrLazyProperty.kt | 2 +- .../fir/lazy/Fir2IrLazySimpleFunction.kt | 2 +- .../fir/lazy/Fir2IrTypeParametersContainer.kt | 4 +- .../signaturer/FirBasedSignatureComposer.kt | 14 +++++ 11 files changed, 78 insertions(+), 34 deletions(-) diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrClassifierStorage.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrClassifierStorage.kt index 1cccde9959a..5ad491fc2a8 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrClassifierStorage.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrClassifierStorage.kt @@ -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 } diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt index 2b12d77f121..999441dca95 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt @@ -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("") 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), diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrSignatureComposer.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrSignatureComposer.kt index 4988d831329..4db932d22bc 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrSignatureComposer.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrSignatureComposer.kt @@ -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) } diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/FirIrProvider.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/FirIrProvider.kt index 1453515cf60..1870fb0278b 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/FirIrProvider.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/FirIrProvider.kt @@ -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) } diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/FakeOverrideGenerator.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/FakeOverrideGenerator.kt index f7493484a50..e6519c6d537 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/FakeOverrideGenerator.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/FakeOverrideGenerator.kt @@ -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 -> { diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyClass.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyClass.kt index 8ca6aa92ad7..97863bed85d 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyClass.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyClass.kt @@ -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 by createLazyAnnotations() diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyConstructor.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyConstructor.kt index e3a9a709ff1..0d1e76c25a2 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyConstructor.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyConstructor.kt @@ -39,7 +39,7 @@ class Fir2IrLazyConstructor( Fir2IrComponents by components { init { symbol.bind(this) - classifierStorage.preCacheTypeParameters(fir) + classifierStorage.preCacheTypeParameters(fir, symbol) } override var annotations: List by createLazyAnnotations() diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyProperty.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyProperty.kt index 6aa4eae2c73..06ff88dc626 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyProperty.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyProperty.kt @@ -45,7 +45,7 @@ class Fir2IrLazyProperty( ) : IrProperty(), AbstractFir2IrLazyDeclaration, Fir2IrComponents by components { init { symbol.bind(this) - classifierStorage.preCacheTypeParameters(fir) + classifierStorage.preCacheTypeParameters(fir, symbol) } override var annotations: List by createLazyAnnotations() diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazySimpleFunction.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazySimpleFunction.kt index a755b28969f..d1ace6d8357 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazySimpleFunction.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazySimpleFunction.kt @@ -33,7 +33,7 @@ class Fir2IrLazySimpleFunction( ) : AbstractFir2IrLazyFunction(components, startOffset, endOffset, origin, symbol, isFakeOverride) { init { symbol.bind(this) - classifierStorage.preCacheTypeParameters(fir) + classifierStorage.preCacheTypeParameters(fir, symbol) } override var annotations: List by createLazyAnnotations() diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrTypeParametersContainer.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrTypeParametersContainer.kt index 7ad3a5d5d09..821c4cfa0cd 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrTypeParametersContainer.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrTypeParametersContainer.kt @@ -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 } } } -} \ No newline at end of file +} diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/signaturer/FirBasedSignatureComposer.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/signaturer/FirBasedSignatureComposer.kt index cb50961ca4a..b34871ef528 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/signaturer/FirBasedSignatureComposer.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/signaturer/FirBasedSignatureComposer.kt @@ -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,