[FIR2IR] Part 6. Delete FirIrProvider

`IrProvider`s are used to bind unbound symbols which are left after IR
  construction. fir2ir doesn't leave any unbound symbols in the tree,
  so there is actually no need in FirIrProvider at all
This commit is contained in:
Dmitriy Novozhilov
2024-02-21 11:19:30 +02:00
committed by Space Team
parent aba1e587c4
commit 7aa99a97d9
2 changed files with 1 additions and 214 deletions
@@ -58,7 +58,7 @@ class Fir2IrComponentsStorage(
override val builtIns: Fir2IrBuiltIns = Fir2IrBuiltIns(this, specialSymbolProvider)
override val fakeOverrideBuilder: IrFakeOverrideBuilder = irFakeOverrideBuilderProvider(irBuiltIns)
override val irProviders: List<IrProvider> = listOf(FirIrProvider(this))
override val irProviders: List<IrProvider> = emptyList()
override val typeConverter: Fir2IrTypeConverter = Fir2IrTypeConverter(this, conversionScope)
@@ -1,213 +0,0 @@
/*
* Copyright 2010-2023 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.backend
import org.jetbrains.kotlin.backend.common.serialization.encodings.BinarySymbolData.SymbolKind
import org.jetbrains.kotlin.backend.common.serialization.kind
import org.jetbrains.kotlin.fir.backend.generators.FakeOverrideGenerator
import org.jetbrains.kotlin.fir.backend.generators.FirBasedFakeOverrideGenerator
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.utils.classId
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
import org.jetbrains.kotlin.fir.scopes.FirScope
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.IrProperty
import org.jetbrains.kotlin.ir.declarations.IrTypeParametersContainer
import org.jetbrains.kotlin.ir.linkage.IrProvider
import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.util.IdSignature
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.utils.addToStdlib.shouldNotBeCalled
@OptIn(FirBasedFakeOverrideGenerator::class) // only for lazy
class FirIrProvider(val components: Fir2IrComponents) : IrProvider {
private val symbolProvider = components.session.symbolProvider
private val declarationStorage = components.declarationStorage
private val classifierStorage = components.classifierStorage
private val fakeOverrideGenerator = FakeOverrideGenerator(components, Fir2IrConversionScope(components.configuration))
override fun getDeclaration(symbol: IrSymbol): IrDeclaration? {
val signature = symbol.signature ?: return null
return getDeclarationForSignature(signature, symbol.kind())
}
private fun getDeclarationForSignature(signature: IdSignature, kind: SymbolKind): IrDeclaration? = when (signature) {
is IdSignature.AccessorSignature -> getDeclarationForAccessorSignature(signature)
is IdSignature.CompositeSignature -> getDeclarationForCompositeSignature(signature, kind)
is IdSignature.CommonSignature -> getDeclarationForCommonSignature(signature, kind)
else -> error("Unexpected signature kind: $signature")
}
private fun getDeclarationForAccessorSignature(signature: IdSignature.AccessorSignature): IrDeclaration? {
val property = getDeclarationForSignature(signature.propertySignature, SymbolKind.PROPERTY_SYMBOL) as? IrProperty ?: return null
return when (signature.accessorSignature.shortName) {
property.getter?.name?.asString() -> property.getter
property.setter?.name?.asString() -> property.setter
else -> null
}
}
private fun getDeclarationForCompositeSignature(signature: IdSignature.CompositeSignature, kind: SymbolKind): IrDeclaration? {
if (kind == SymbolKind.TYPE_PARAMETER_SYMBOL) {
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)
}
private fun getDeclarationForCommonSignature(signature: IdSignature.CommonSignature, kind: SymbolKind): IrDeclaration? {
val packageFqName = FqName(signature.packageFqName)
val nameSegments = signature.nameSegments
val topName = Name.identifier(nameSegments[0])
val firCandidates: List<FirDeclaration>
val parentClass: IrClass?
if (nameSegments.size == 1 && kind != SymbolKind.CLASS_SYMBOL) {
firCandidates = symbolProvider.getTopLevelCallableSymbols(packageFqName, topName).map { it.fir }
parentClass = null // TODO: need to insert file facade class on JVM
} else {
val topLevelClass = symbolProvider.getClassLikeSymbolByClassId(ClassId(packageFqName, topName))?.fir as? FirRegularClass
?: return null
var firParentClass: FirRegularClass? = null
var firClass = topLevelClass
val midSegments = if (kind == SymbolKind.CLASS_SYMBOL) nameSegments.drop(1) else nameSegments.drop(1).dropLast(1)
for (midName in midSegments) {
firParentClass = firClass
firClass = firClass.declarations.singleOrNull { (it as? FirRegularClass)?.name?.asString() == midName } as? FirRegularClass
?: return null
}
val classId = firClass.classId
val scope = with(components) { firClass.unsubstitutedScope() }
fun findIrClass(firClass: FirRegularClass): IrClass {
val irClassSymbol = classifierStorage.getIrClassSymbol(firClass.symbol)
return getDeclaration(irClassSymbol) as IrClass
}
when (kind) {
SymbolKind.CLASS_SYMBOL -> {
firCandidates = listOf(firClass)
parentClass = firParentClass?.let { findIrClass(it) }
}
SymbolKind.ENUM_ENTRY_SYMBOL -> {
val lastName = Name.guessByFirstCharacter(nameSegments.last())
val firCandidate = firClass.declarations.singleOrNull { (it as? FirEnumEntry)?.name == lastName }
firCandidates = firCandidate?.let { listOf(it) } ?: return null
parentClass = findIrClass(firClass)
}
SymbolKind.CONSTRUCTOR_SYMBOL -> {
val constructors = mutableListOf<FirConstructor>()
scope.processDeclaredConstructors { constructors.add(it.fir) }
firCandidates = constructors
parentClass = findIrClass(firClass)
}
SymbolKind.FUNCTION_SYMBOL -> {
parentClass = findIrClass(firClass)
val lastName = Name.guessByFirstCharacter(nameSegments.last())
val functions = mutableListOf<FirSimpleFunction>()
scope.processFunctionsByName(lastName) { functionSymbol ->
val dispatchReceiverClassId = (functionSymbol.fir.dispatchReceiverType as? ConeClassLikeType)?.lookupTag?.classId
val function = if (dispatchReceiverClassId != null && dispatchReceiverClassId != classId) {
fakeOverrideGenerator.createFirFunctionFakeOverrideIfNeeded(
functionSymbol.fir,
firClass.symbol.toLookupTag(),
parentClass
)!!
} else functionSymbol.fir
functions.add(function)
}
firClass.staticScopeForCallables?.processFunctionsByName(lastName) { functionSymbol ->
functions.add(functionSymbol.fir)
}
firCandidates = functions
}
SymbolKind.PROPERTY_SYMBOL -> {
parentClass = findIrClass(firClass)
val lastName = Name.guessByFirstCharacter(nameSegments.last())
val properties = mutableListOf<FirVariable>()
scope.processPropertiesByName(lastName) { propertySymbol ->
propertySymbol as FirPropertySymbol
val dispatchReceiverClassId = (propertySymbol.fir.dispatchReceiverType as? ConeClassLikeType)?.lookupTag?.classId
val property = if (dispatchReceiverClassId != null && dispatchReceiverClassId != classId) {
fakeOverrideGenerator.createFirPropertyFakeOverrideIfNeeded(
propertySymbol.fir,
firClass.symbol.toLookupTag(),
parentClass
)!!
} else propertySymbol.fir
properties.add(property)
}
firCandidates = properties
}
SymbolKind.FIELD_SYMBOL -> {
parentClass = findIrClass(firClass)
val lastName = Name.guessByFirstCharacter(nameSegments.last())
val fields = mutableListOf<FirVariable>()
scope.processPropertiesByName(lastName) { propertySymbol ->
fields.add(propertySymbol.fir)
}
firClass.staticScopeForCallables?.processPropertiesByName(lastName) { propertySymbol ->
fields.add(propertySymbol.fir)
}
firCandidates = fields
}
else -> {
val lastName = nameSegments.last()
firCandidates = firClass.declarations.filter { it is FirCallableDeclaration && it.symbol.name.asString() == lastName }
parentClass = findIrClass(firClass)
}
}
}
val firDeclaration = findDeclarationByHash(firCandidates, signature.id) ?: return null
return when (kind) {
SymbolKind.CLASS_SYMBOL -> {
shouldNotBeCalled()
}
SymbolKind.ENUM_ENTRY_SYMBOL -> {
shouldNotBeCalled()
}
SymbolKind.CONSTRUCTOR_SYMBOL -> {
shouldNotBeCalled()
}
SymbolKind.FUNCTION_SYMBOL -> {
shouldNotBeCalled()
}
SymbolKind.PROPERTY_SYMBOL -> {
shouldNotBeCalled()
}
SymbolKind.FIELD_SYMBOL -> {
val firField = firDeclaration as FirField
declarationStorage.getOrCreateIrField(firField.symbol)
}
else -> error("Don't know how to deal with this symbol kind: $kind")
}
}
private fun findDeclarationByHash(candidates: Collection<FirDeclaration>, hash: Long?): FirDeclaration? =
candidates.firstOrNull { candidate ->
if (hash == null) {
// We don't compute id for type aliases and classes.
candidate is FirClass || candidate is FirEnumEntry || candidate is FirTypeAlias
} else {
// The next line should have singleOrNull, but in some cases we get multiple references to the same FIR declaration.
with(components.signatureComposer.mangler) { candidate.signatureMangle(compatibleMode = false) == hash }
}
}
private val FirClass.staticScopeForCallables: FirScope?
get() = scopeProvider.getStaticMemberScopeForCallables(this, components.session, components.scopeSession)
}