Fir2Ir: deserialize bodies of inline functions

This commit is contained in:
Georgy Bronnikov
2021-12-13 18:52:06 +03:00
committed by Alexander Udalov
parent e0c175bb50
commit af123d1daf
7 changed files with 55 additions and 20 deletions
@@ -41,4 +41,6 @@ interface Fir2IrComponents {
val callGenerator: CallAndReferenceGenerator
val fakeOverrideGenerator: FakeOverrideGenerator
val delegatedMemberGenerator: DelegatedMemberGenerator
val extensions: Fir2IrExtensions
}
@@ -23,7 +23,8 @@ class Fir2IrComponentsStorage(
override val scopeSession: ScopeSession,
override val symbolTable: SymbolTable,
override val irFactory: IrFactory,
override val signatureComposer: FirBasedSignatureComposer
override val signatureComposer: FirBasedSignatureComposer,
override val extensions: Fir2IrExtensions,
) : Fir2IrComponents {
override lateinit var converter: Fir2IrConverter
@@ -430,7 +430,7 @@ class Fir2IrConverter(
val moduleDescriptor = FirModuleDescriptor(session)
val symbolTable = SymbolTable(signaturer, irFactory)
val signatureComposer = FirBasedSignatureComposer(mangler)
val components = Fir2IrComponentsStorage(session, scopeSession, symbolTable, irFactory, signatureComposer)
val components = Fir2IrComponentsStorage(session, scopeSession, symbolTable, irFactory, signatureComposer, fir2IrExtensions)
val converter = Fir2IrConverter(moduleDescriptor, components)
components.converter = converter
@@ -57,13 +57,20 @@ class FirIrProvider(val fir2IrComponents: Fir2IrComponents) : IrProvider {
firClass = firClass.declarations.singleOrNull { (it as? FirRegularClass)?.name?.asString() == midName } as? FirRegularClass
?: return null
}
if (symbol is IrClassSymbol) {
firCandidates = listOf(firClass)
parent = classifierStorage.getIrClassSymbol(firParentClass!!.symbol).owner
} else {
val lastName = nameSegments.last()
firCandidates = firClass.declarations.filter { it is FirCallableDeclaration && it.symbol.name.asString() == lastName }
parent = firParentClass?.let { classifierStorage.getIrClassSymbol(it.symbol).owner } ?: packageFragment
when (symbol) {
is IrClassSymbol -> {
firCandidates = listOf(firClass)
parent = classifierStorage.getIrClassSymbol(firParentClass!!.symbol).owner
}
is IrConstructorSymbol -> {
firCandidates = firClass.declarations.filter { it is FirConstructor }
parent = classifierStorage.getIrClassSymbol(firClass.symbol).owner
}
else -> {
val lastName = nameSegments.last()
firCandidates = firClass.declarations.filter { it is FirCallableDeclaration && it.symbol.name.asString() == lastName }
parent = classifierStorage.getIrClassSymbol(firClass.symbol).owner
}
}
}
@@ -15,12 +15,15 @@ import org.jetbrains.kotlin.ir.declarations.IrDeclaration
import org.jetbrains.kotlin.ir.declarations.IrDeclarationParent
import org.jetbrains.kotlin.ir.declarations.IrFactory
import org.jetbrains.kotlin.ir.declarations.IrTypeParameter
import org.jetbrains.kotlin.ir.declarations.lazy.IrLazyDeclarationBase
import org.jetbrains.kotlin.ir.declarations.lazy.lazyVar
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
import org.jetbrains.kotlin.ir.util.DeclarationStubGenerator
import org.jetbrains.kotlin.ir.util.TypeTranslator
import kotlin.properties.ReadWriteProperty
interface AbstractFir2IrLazyDeclaration<F, D : IrDeclaration> :
IrDeclaration, IrDeclarationParent, Fir2IrComponents where F : FirMemberDeclaration, F : FirAnnotationContainer {
IrDeclaration, IrDeclarationParent, IrLazyDeclarationBase, Fir2IrComponents where F : FirMemberDeclaration, F : FirAnnotationContainer {
val fir: F
override val symbol: Fir2IrBindableSymbol<*, D>
@@ -42,9 +45,18 @@ interface AbstractFir2IrLazyDeclaration<F, D : IrDeclaration> :
}
}
fun createLazyAnnotations(): ReadWriteProperty<Any?, List<IrConstructorCall>> = lazyVar(lock) {
override fun createLazyAnnotations(): ReadWriteProperty<Any?, List<IrConstructorCall>> = lazyVar(lock) {
fir.annotations.mapNotNull {
callGenerator.convertToIrConstructorCall(it) as? IrConstructorCall
}
}
override fun lazyParent(): IrDeclarationParent {
return parent
}
override val stubGenerator: DeclarationStubGenerator
get() = error("Should not be called")
override val typeTranslator: TypeTranslator
get() = error("Should not be called")
}
@@ -101,11 +101,6 @@ abstract class AbstractFir2IrLazyFunction<F : FirCallableDeclaration>(
}
}
override val stubGenerator: DeclarationStubGenerator
get() = error("Should not be called")
override val typeTranslator: TypeTranslator
get() = error("Should not be called")
override val factory: IrFactory
get() = super<AbstractFir2IrLazyDeclaration>.factory
@@ -14,14 +14,13 @@ import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
import org.jetbrains.kotlin.fir.initialSignatureAttr
import org.jetbrains.kotlin.fir.symbols.Fir2IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.declarations.IrValueParameter
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.lazy.lazyVar
import org.jetbrains.kotlin.ir.expressions.IrBody
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.util.DeserializableClass
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource
@@ -52,6 +51,10 @@ class Fir2IrLazySimpleFunction(
fir.returnTypeRef.toIrType(typeConverter)
}
override var body: IrBody? by lazyVar(lock) {
if (tryLoadIr()) body else null
}
override var dispatchReceiverParameter: IrValueParameter? by lazyVar(lock) {
val containingClass = parent as? IrClass
if (containingClass != null && shouldHaveDispatchReceiver(containingClass, fir)) {
@@ -107,4 +110,19 @@ class Fir2IrLazySimpleFunction(
override val containerSource: DeserializedContainerSource?
get() = fir.containerSource
private fun tryLoadIr(): Boolean {
if (!isInline || isFakeOverride) return false
if (!extensions.irNeedsDeserialization) return false
val toplevel = getToplevel()
return (toplevel as? DeserializableClass)?.loadIr() ?: false
}
private fun getToplevel(): IrDeclaration {
var current: IrDeclaration = this
while (current.parent !is IrPackageFragment) {
current = current.parent as IrDeclaration
}
return current
}
}