Fir2IrDeclarationStorage: extract common getIrCallableSymbol

This commit is contained in:
Mikhail Glukhikh
2020-11-12 10:51:03 +03:00
parent b90391ced4
commit c515af4373
@@ -1004,96 +1004,73 @@ class Fir2IrDeclarationStorage(
} }
fun getIrConstructorSymbol(firConstructorSymbol: FirConstructorSymbol): IrConstructorSymbol { fun getIrConstructorSymbol(firConstructorSymbol: FirConstructorSymbol): IrConstructorSymbol {
val firConstructor = firConstructorSymbol.fir val fir = firConstructorSymbol.fir
val irParent by lazy { findIrParent(firConstructor) } return getIrCallableSymbol(
getCachedIrConstructor(firConstructor) { firConstructorSymbol,
irParent getCachedIrDeclaration = ::getCachedIrConstructor,
signatureComposer.composeSignature(firConstructor) createIrDeclaration = { parent, origin -> createIrConstructor(fir, parent as IrClass, origin = origin) },
}?.let { return it.symbol } createIrLazyDeclaration = { signature, lazyParent, declarationOrigin ->
val signature = signatureComposer.composeSignature(firConstructor) val symbol = Fir2IrConstructorSymbol(signature)
val parentOrigin = (irParent as? IrDeclaration)?.origin ?: IrDeclarationOrigin.DEFINED val irConstructor = fir.convertWithOffsets { startOffset, endOffset ->
if (signature != null) { symbolTable.declareConstructor(signature, { symbol }) {
assert(parentOrigin != IrDeclarationOrigin.DEFINED) { Fir2IrLazyConstructor(
"Should not have reference to public API uncached constructor from source code" components, startOffset, endOffset, declarationOrigin, fir, symbol
} ).apply {
val symbol = Fir2IrConstructorSymbol(signature) parent = lazyParent
val irConstructor = firConstructor.convertWithOffsets { startOffset, endOffset -> }
symbolTable.declareConstructor(signature, { symbol }) {
Fir2IrLazyConstructor(
components, startOffset, endOffset, parentOrigin, firConstructor, symbol
).apply {
parent = irParent!!
} }
} }
constructorCache[fir] = irConstructor
// NB: this is needed to prevent recursions in case of self bounds
(irConstructor as Fir2IrLazyConstructor).prepareTypeParameters()
irConstructor
} }
constructorCache[firConstructor] = irConstructor ) as IrConstructorSymbol
// NB: this is needed to prevent recursions in case of self bounds
(irConstructor as Fir2IrLazyConstructor).prepareTypeParameters()
return symbol
}
val irDeclaration = createIrConstructor(firConstructor, irParent as IrClass, origin = parentOrigin).apply {
setAndModifyParent(irParent)
}
return irDeclaration.symbol
} }
fun getIrFunctionSymbol(firFunctionSymbol: FirFunctionSymbol<*>): IrFunctionSymbol { fun getIrFunctionSymbol(firFunctionSymbol: FirFunctionSymbol<*>): IrFunctionSymbol {
return when (val firDeclaration = firFunctionSymbol.fir) { return when (val fir = firFunctionSymbol.fir) {
is FirAnonymousFunction -> { is FirAnonymousFunction -> {
getCachedIrFunction(firDeclaration)?.let { return it.symbol } getCachedIrFunction(fir)?.let { return it.symbol }
val irParent = findIrParent(firDeclaration) val irParent = findIrParent(fir)
val parentOrigin = (irParent as? IrDeclaration)?.origin ?: IrDeclarationOrigin.DEFINED val parentOrigin = (irParent as? IrDeclaration)?.origin ?: IrDeclarationOrigin.DEFINED
val declarationOrigin = computeDeclarationOrigin(firFunctionSymbol, parentOrigin, irParent) val declarationOrigin = computeDeclarationOrigin(firFunctionSymbol, parentOrigin, irParent)
createIrFunction(firDeclaration, irParent, origin = declarationOrigin).apply { createIrFunction(fir, irParent, origin = declarationOrigin).apply {
setAndModifyParent(irParent) setAndModifyParent(irParent)
}.symbol }.symbol
} }
is FirSimpleFunction -> { is FirSimpleFunction -> {
val irParent by lazy { findIrParent(firDeclaration) } return getIrCallableSymbol(
getCachedIrFunction(firDeclaration) { firFunctionSymbol,
// Parent calculation provokes function calculation for some members from IrBuiltIns getCachedIrDeclaration = ::getCachedIrFunction,
@Suppress("UNUSED_EXPRESSION") irParent createIrDeclaration = { parent, origin -> createIrFunction(fir, parent, origin = origin) },
signatureComposer.composeSignature(it) createIrLazyDeclaration = { signature, lazyParent, declarationOrigin ->
}?.let { return it.symbol } val symbol = Fir2IrSimpleFunctionSymbol(signature, fir.containerSource)
val parentOrigin = (irParent as? IrDeclaration)?.origin ?: IrDeclarationOrigin.DEFINED val irFunction = fir.convertWithOffsets { startOffset, endOffset ->
// TODO: package fragment members (?)
val parent = irParent
if (parent is Fir2IrLazyClass) {
assert(parentOrigin != IrDeclarationOrigin.DEFINED) {
"Should not have reference to public API uncached simple function from source code"
}
val signature = signatureComposer.composeSignature(firDeclaration)
if (signature != null) {
val symbol = Fir2IrSimpleFunctionSymbol(signature, firDeclaration.containerSource)
val irFunction = firDeclaration.convertWithOffsets { startOffset, endOffset ->
symbolTable.declareSimpleFunction(signature, { symbol }) { symbolTable.declareSimpleFunction(signature, { symbol }) {
val isFakeOverride = val isFakeOverride =
firFunctionSymbol is FirNamedFunctionSymbol && firFunctionSymbol.fir.isSubstitutionOverride && firFunctionSymbol is FirNamedFunctionSymbol && fir.isSubstitutionOverride &&
firFunctionSymbol.dispatchReceiverClassOrNull() != firFunctionSymbol.dispatchReceiverClassOrNull() !=
firFunctionSymbol.originalForSubstitutionOverride?.dispatchReceiverClassOrNull() firFunctionSymbol.originalForSubstitutionOverride?.dispatchReceiverClassOrNull()
Fir2IrLazySimpleFunction( Fir2IrLazySimpleFunction(
components, startOffset, endOffset, parentOrigin, firDeclaration, parent.fir, symbol, isFakeOverride components, startOffset, endOffset, declarationOrigin,
fir, lazyParent.fir, symbol, isFakeOverride
).apply { ).apply {
this.parent = parent this.parent = lazyParent
} }
} }
} }
functionCache[firDeclaration] = irFunction functionCache[fir] = irFunction
// NB: this is needed to prevent recursions in case of self bounds // NB: this is needed to prevent recursions in case of self bounds
(irFunction as Fir2IrLazySimpleFunction).prepareTypeParameters() (irFunction as Fir2IrLazySimpleFunction).prepareTypeParameters()
return symbol irFunction
} }
} ) as IrFunctionSymbol
val declarationOrigin = computeDeclarationOrigin(firFunctionSymbol, parentOrigin, irParent)
createIrFunction(firDeclaration, irParent, origin = declarationOrigin).apply {
setAndModifyParent(irParent)
}.symbol
} }
is FirConstructor -> { is FirConstructor -> {
getIrConstructorSymbol(firDeclaration.symbol) getIrConstructorSymbol(fir.symbol)
} }
else -> error("Unknown kind of function: ${firDeclaration::class.java}: ${firDeclaration.render()}") else -> error("Unknown kind of function: ${fir::class.java}: ${fir.render()}")
} }
} }
@@ -1102,41 +1079,63 @@ class Fir2IrDeclarationStorage(
if (fir.isLocal) { if (fir.isLocal) {
return localStorage.getDelegatedProperty(fir)?.symbol ?: getIrVariableSymbol(fir) return localStorage.getDelegatedProperty(fir)?.symbol ?: getIrVariableSymbol(fir)
} }
val irParent by lazy { findIrParent(fir) } return getIrCallableSymbol(
getCachedIrProperty(fir) { firPropertySymbol,
// Parent calculation provokes property calculation for some members from IrBuiltIns getCachedIrDeclaration = ::getCachedIrProperty,
@Suppress("UNUSED_EXPRESSION") irParent createIrDeclaration = { parent, origin -> createIrProperty(fir, parent, origin = origin) },
signatureComposer.composeSignature(it) createIrLazyDeclaration = { signature, lazyParent, declarationOrigin ->
}?.let { return it.symbol }
val parentOrigin = (irParent as? IrDeclaration)?.origin ?: IrDeclarationOrigin.DEFINED
val declarationOrigin = computeDeclarationOrigin(firPropertySymbol, parentOrigin, irParent)
// TODO: package fragment members (?)
val parent = irParent
if (parent is Fir2IrLazyClass) {
assert(parentOrigin != IrDeclarationOrigin.DEFINED) {
"Should not have reference to public API uncached property from source code"
}
val signature = signatureComposer.composeSignature(fir)
if (signature != null) {
val symbol = Fir2IrPropertySymbol(signature, fir.containerSource) val symbol = Fir2IrPropertySymbol(signature, fir.containerSource)
val irProperty = fir.convertWithOffsets { startOffset, endOffset -> val irProperty = fir.convertWithOffsets { startOffset, endOffset ->
symbolTable.declareProperty(signature, { symbol }) { symbolTable.declareProperty(signature, { symbol }) {
val isFakeOverride = val isFakeOverride =
firPropertySymbol.fir.isSubstitutionOverride && fir.isSubstitutionOverride &&
firPropertySymbol.dispatchReceiverClassOrNull() != firPropertySymbol.originalForSubstitutionOverride?.dispatchReceiverClassOrNull() firPropertySymbol.dispatchReceiverClassOrNull() !=
firPropertySymbol.originalForSubstitutionOverride?.dispatchReceiverClassOrNull()
Fir2IrLazyProperty( Fir2IrLazyProperty(
components, startOffset, endOffset, declarationOrigin, fir, parent.fir, symbol, isFakeOverride components, startOffset, endOffset, declarationOrigin, fir, lazyParent.fir, symbol, isFakeOverride
).apply { ).apply {
this.parent = parent this.parent = lazyParent
} }
} }
} }
propertyCache[fir] = irProperty propertyCache[fir] = irProperty
return symbol return symbol
} }
)
}
private inline fun <
reified FS : FirCallableSymbol<*>,
reified F : FirCallableDeclaration<*>,
I : IrSymbolOwner,
> getIrCallableSymbol(
firSymbol: FS,
getCachedIrDeclaration: (F, (F) -> IdSignature?) -> I?,
createIrDeclaration: (IrDeclarationParent?, IrDeclarationOrigin) -> I,
createIrLazyDeclaration: (IdSignature, Fir2IrLazyClass, IrDeclarationOrigin) -> I,
): IrSymbol {
val fir = firSymbol.fir as F
val irParent by lazy { findIrParent(fir) }
val signature by lazy { signatureComposer.composeSignature(fir) }
getCachedIrDeclaration(fir) {
// Parent calculation provokes declaration calculation for some members from IrBuiltIns
@Suppress("UNUSED_EXPRESSION") irParent
signature
}?.let { return it.symbol }
val parentOrigin = (irParent as? IrDeclaration)?.origin ?: IrDeclarationOrigin.DEFINED
val declarationOrigin = computeDeclarationOrigin(firSymbol, parentOrigin, irParent)
// TODO: package fragment members (?)
val parent = irParent
if (parent is Fir2IrLazyClass) {
assert(parentOrigin != IrDeclarationOrigin.DEFINED) {
"Should not have reference to public API uncached property from source code"
}
signature?.let {
return createIrLazyDeclaration(it, parent, declarationOrigin).symbol
}
} }
return createIrProperty(fir, irParent, origin = declarationOrigin).apply { return createIrDeclaration(irParent, declarationOrigin).apply {
setAndModifyParent(irParent) (this as IrDeclaration).setAndModifyParent(irParent)
}.symbol }.symbol
} }