[FIR2IR] Introduce lazy constructors
This commit is contained in:
+27
-2
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.fir.expressions.FirConstExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.impl.FirExpressionStub
|
||||
import org.jetbrains.kotlin.fir.lazy.Fir2IrLazyClass
|
||||
import org.jetbrains.kotlin.fir.lazy.Fir2IrLazyConstructor
|
||||
import org.jetbrains.kotlin.fir.lazy.Fir2IrLazySimpleFunction
|
||||
import org.jetbrains.kotlin.fir.render
|
||||
import org.jetbrains.kotlin.fir.resolve.*
|
||||
@@ -820,9 +821,33 @@ class Fir2IrDeclarationStorage(
|
||||
fun getIrConstructorSymbol(firConstructorSymbol: FirConstructorSymbol): IrConstructorSymbol {
|
||||
val firConstructor = firConstructorSymbol.fir
|
||||
getCachedIrConstructor(firConstructor)?.let { return it.symbol }
|
||||
|
||||
val signature = signatureComposer.composeSignature(firConstructor)
|
||||
val irParent = findIrParent(firConstructor) as IrClass
|
||||
val parentOrigin = (irParent as? IrDeclaration)?.origin ?: IrDeclarationOrigin.DEFINED
|
||||
val parentOrigin = irParent.origin
|
||||
if (signature != null) {
|
||||
symbolTable.referenceConstructorIfAny(signature)?.let { irConstructorSymbol ->
|
||||
val irFunction = irConstructorSymbol.owner
|
||||
constructorCache[firConstructor] = irFunction
|
||||
return irConstructorSymbol
|
||||
}
|
||||
if (parentOrigin == IrDeclarationOrigin.DEFINED) {
|
||||
throw AssertionError()
|
||||
}
|
||||
val symbol = Fir2IrConstructorSymbol(signature)
|
||||
val irConstructor = firConstructor.convertWithOffsets { startOffset, endOffset ->
|
||||
symbolTable.declareConstructor(signature, { symbol }) {
|
||||
Fir2IrLazyConstructor(
|
||||
components, startOffset, endOffset, parentOrigin, firConstructor, symbol
|
||||
).apply {
|
||||
parent = irParent
|
||||
}
|
||||
}
|
||||
}
|
||||
constructorCache[firConstructor] = irConstructor
|
||||
// NB: this is needed to prevent recursions in case of self bounds
|
||||
(irConstructor as Fir2IrLazyConstructor).prepareTypeParameters()
|
||||
return symbol
|
||||
}
|
||||
val irDeclaration = createIrConstructor(firConstructor, irParent, origin = parentOrigin).apply {
|
||||
setAndModifyParent(irParent)
|
||||
}
|
||||
|
||||
@@ -123,7 +123,7 @@ class Fir2IrLazyClass(
|
||||
// e.g. to avoid accessing un-enhanced Java declarations with FirJavaTypeRef etc. inside
|
||||
val scope = fir.buildUseSiteMemberScope(session, scopeSession)!!
|
||||
scope.processDeclaredConstructors {
|
||||
result += declarationStorage.createIrConstructor(it.fir, this)
|
||||
result += declarationStorage.getIrConstructorSymbol(it).owner
|
||||
}
|
||||
for (declaration in fir.declarations) {
|
||||
when (declaration) {
|
||||
|
||||
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* Copyright 2010-2020 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.ClassConstructorDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.Visibility
|
||||
import org.jetbrains.kotlin.fir.backend.Fir2IrComponents
|
||||
import org.jetbrains.kotlin.fir.backend.declareThisReceiverParameter
|
||||
import org.jetbrains.kotlin.fir.backend.toIrType
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.symbols.Fir2IrConstructorSymbol
|
||||
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrConstructor
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
|
||||
import org.jetbrains.kotlin.ir.declarations.IrValueParameter
|
||||
import org.jetbrains.kotlin.ir.declarations.lazy.lazyVar
|
||||
import org.jetbrains.kotlin.ir.expressions.IrBody
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.util.mapOptimized
|
||||
import org.jetbrains.kotlin.ir.util.parentClassOrNull
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
class Fir2IrLazyConstructor(
|
||||
components: Fir2IrComponents,
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
origin: IrDeclarationOrigin,
|
||||
fir: FirConstructor,
|
||||
symbol: Fir2IrConstructorSymbol
|
||||
) : AbstractFir2IrLazyDeclaration<FirConstructor, IrConstructor>(
|
||||
components, startOffset, endOffset, origin, fir, symbol
|
||||
), IrConstructor {
|
||||
init {
|
||||
symbol.bind(this)
|
||||
classifierStorage.preCacheTypeParameters(fir)
|
||||
}
|
||||
|
||||
override val isPrimary: Boolean
|
||||
get() = fir.isPrimary
|
||||
|
||||
@ObsoleteDescriptorBasedAPI
|
||||
override val descriptor: ClassConstructorDescriptor
|
||||
get() = super.descriptor as ClassConstructorDescriptor
|
||||
|
||||
override val symbol: Fir2IrConstructorSymbol
|
||||
get() = super.symbol as Fir2IrConstructorSymbol
|
||||
|
||||
override val isInline: Boolean
|
||||
get() = fir.isInline
|
||||
|
||||
override val isExternal: Boolean
|
||||
get() = fir.isExternal
|
||||
|
||||
override val isExpect: Boolean
|
||||
get() = fir.isExpect
|
||||
|
||||
override var body: IrBody? = null
|
||||
|
||||
override val name: Name
|
||||
get() = Name.special("<init>")
|
||||
|
||||
override var visibility: Visibility
|
||||
get() = fir.visibility
|
||||
set(_) {
|
||||
throw AssertionError("Mutating Fir2Ir lazy elements is not possible")
|
||||
}
|
||||
|
||||
override var returnType: IrType by lazyVar {
|
||||
fir.returnTypeRef.toIrType(typeConverter)
|
||||
}
|
||||
|
||||
override var dispatchReceiverParameter: IrValueParameter? by lazyVar {
|
||||
val containingClass = parent as? IrClass
|
||||
val outerClass = containingClass?.parentClassOrNull
|
||||
if (containingClass?.isInner == true && outerClass != null) {
|
||||
declarationStorage.enterScope(this)
|
||||
declareThisReceiverParameter(
|
||||
symbolTable,
|
||||
thisType = outerClass.thisReceiver!!.type,
|
||||
thisOrigin = origin
|
||||
).apply {
|
||||
declarationStorage.leaveScope(this@Fir2IrLazyConstructor)
|
||||
}
|
||||
} else null
|
||||
}
|
||||
|
||||
override var extensionReceiverParameter: IrValueParameter?
|
||||
get() = null
|
||||
set(_) {
|
||||
throw AssertionError("Mutating Fir2Ir lazy elements is not possible")
|
||||
}
|
||||
|
||||
override var valueParameters: List<IrValueParameter> by lazyVar {
|
||||
declarationStorage.enterScope(this)
|
||||
fir.valueParameters.mapIndexed { index, valueParameter ->
|
||||
declarationStorage.createIrParameter(
|
||||
valueParameter, index,
|
||||
useStubForDefaultValueStub = (parent as? IrClass)?.name != Name.identifier("Enum")
|
||||
).apply {
|
||||
this.parent = this@Fir2IrLazyConstructor
|
||||
}
|
||||
}.apply {
|
||||
declarationStorage.leaveScope(this@Fir2IrLazyConstructor)
|
||||
}
|
||||
}
|
||||
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
|
||||
return visitor.visitConstructor(this, data)
|
||||
}
|
||||
|
||||
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||
typeParameters.forEach { it.accept(visitor, data) }
|
||||
|
||||
dispatchReceiverParameter?.accept(visitor, data)
|
||||
extensionReceiverParameter?.accept(visitor, data)
|
||||
valueParameters.forEach { it.accept(visitor, data) }
|
||||
|
||||
body?.accept(visitor, data)
|
||||
}
|
||||
|
||||
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
|
||||
typeParameters = typeParameters.mapOptimized { it.transform(transformer, data) }
|
||||
|
||||
dispatchReceiverParameter = dispatchReceiverParameter?.transform(transformer, data)
|
||||
extensionReceiverParameter = extensionReceiverParameter?.transform(transformer, data)
|
||||
valueParameters = valueParameters.mapOptimized { it.transform(transformer, data) }
|
||||
|
||||
body = body?.transform(transformer, data)
|
||||
}
|
||||
}
|
||||
@@ -487,6 +487,9 @@ open class SymbolTable(
|
||||
override fun referenceConstructor(descriptor: ClassConstructorDescriptor) =
|
||||
constructorSymbolTable.referenced(descriptor) { createConstructorSymbol(descriptor) }
|
||||
|
||||
fun referenceConstructorIfAny(sig: IdSignature): IrConstructorSymbol? =
|
||||
constructorSymbolTable.get(sig)
|
||||
|
||||
fun declareConstructorFromLinker(
|
||||
descriptor: ClassConstructorDescriptor,
|
||||
sig: IdSignature,
|
||||
|
||||
Reference in New Issue
Block a user