FIR2IR: don't create non-lazy fake overrides inside lazy class

This commit allows to calculate member with initial signature properly.
Only lazy IR members are suitable to calculate initial signature.
Before this commit we sometimes built non-lazy children for lazy class.
Now we build lazy children (with an exception of private declarations).
This commit is contained in:
Mikhail Glukhikh
2022-02-14 16:29:14 +03:00
committed by Space
parent 80a68ec433
commit 76ff717091
5 changed files with 72 additions and 54 deletions
@@ -476,6 +476,11 @@ class Fir2IrDeclarationStorage(
function.origin == FirDeclarationOrigin.Enhancement -> IrDeclarationOrigin.IR_EXTERNAL_JAVA_DECLARATION_STUB
else -> function.computeIrOrigin(predefinedOrigin)
}
val signature = if (isLocal) null else signatureComposer.composeSignature(function, containingClass)
if (irParent is Fir2IrLazyClass && signature != null) {
// 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("<no name provided>")
@@ -483,7 +488,6 @@ class Fir2IrDeclarationStorage(
val isSuspend =
if (isLambda) ((function as FirAnonymousFunction).typeRef as? FirResolvedTypeRef)?.type?.isSuspendFunctionType(session) == true
else simpleFunction?.isSuspend == true
val signature = if (isLocal) null else signatureComposer.composeSignature(function, containingClass)
val created = function.convertWithOffsets { startOffset, endOffset ->
val result = declareIrSimpleFunction(signature, simpleFunction?.containerSource) { symbol ->
irFactory.createFunction(
@@ -792,13 +796,17 @@ class Fir2IrDeclarationStorage(
containingClass: ConeClassLikeLookupTag? = null,
): IrProperty = convertCatching(property) {
val origin = property.computeIrOrigin(predefinedOrigin)
val signature = if (isLocal) null else signatureComposer.composeSignature(property, containingClass)
if (irParent is Fir2IrLazyClass && signature != null) {
// 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)
}
}
val signature = if (isLocal) null else signatureComposer.composeSignature(property, containingClass)
return property.convertWithOffsets { startOffset, endOffset ->
val result = declareIrProperty(signature, property.containerSource) { symbol ->
irFactory.createProperty(
@@ -1181,27 +1189,11 @@ class Fir2IrDeclarationStorage(
firFunctionSymbol,
dispatchReceiverLookupTag,
getCachedIrDeclaration = ::getCachedIrFunction,
createIrDeclaration = { parent, origin -> createIrFunction(fir, parent, predefinedOrigin = origin) },
createIrDeclaration = { parent, origin ->
createIrFunction(fir, parent, predefinedOrigin = origin)
},
createIrLazyDeclaration = { signature, lazyParent, declarationOrigin ->
val symbol = Fir2IrSimpleFunctionSymbol(signature, fir.containerSource)
val irFunction = fir.convertWithOffsets { startOffset, endOffset ->
symbolTable.declareSimpleFunction(signature, { symbol }) {
val isFakeOverride =
firFunctionSymbol is FirNamedFunctionSymbol && fir.isSubstitutionOrIntersectionOverride &&
firFunctionSymbol.dispatchReceiverClassOrNull() !=
firFunctionSymbol.originalForSubstitutionOverride?.dispatchReceiverClassOrNull()
Fir2IrLazySimpleFunction(
components, startOffset, endOffset, declarationOrigin,
fir, lazyParent.fir, symbol, isFakeOverride
).apply {
this.parent = lazyParent
}
}
}
functionCache[fir] = irFunction
// NB: this is needed to prevent recursions in case of self bounds
(irFunction as Fir2IrLazySimpleFunction).prepareTypeParameters()
irFunction
createIrLazyFunction(fir, signature, lazyParent, declarationOrigin)
}
) as IrFunctionSymbol
if (unmatchedReceiver && dispatchReceiverLookupTag is ConeClassLookupTagWithFixedSymbol) {
@@ -1218,6 +1210,33 @@ class Fir2IrDeclarationStorage(
}
}
private fun createIrLazyFunction(
fir: FirSimpleFunction,
signature: IdSignature,
lazyParent: Fir2IrLazyClass,
declarationOrigin: IrDeclarationOrigin
): IrSimpleFunction {
val symbol = Fir2IrSimpleFunctionSymbol(signature, fir.containerSource)
val firFunctionSymbol = fir.symbol
val irFunction = fir.convertWithOffsets { startOffset, endOffset ->
symbolTable.declareSimpleFunction(signature, { symbol }) {
val isFakeOverride = fir.isSubstitutionOrIntersectionOverride &&
firFunctionSymbol.dispatchReceiverClassOrNull() !=
firFunctionSymbol.originalForSubstitutionOverride?.dispatchReceiverClassOrNull()
Fir2IrLazySimpleFunction(
components, startOffset, endOffset, declarationOrigin,
fir, lazyParent.fir, symbol, isFakeOverride
).apply {
this.parent = lazyParent
}
}
}
functionCache[fir] = irFunction
// NB: this is needed to prevent recursions in case of self bounds
(irFunction as Fir2IrLazySimpleFunction).prepareTypeParameters()
return irFunction
}
fun getIrPropertySymbol(
firPropertySymbol: FirPropertySymbol,
dispatchReceiverLookupTag: ConeClassLikeLookupTag? = null
@@ -1238,22 +1257,7 @@ class Fir2IrDeclarationStorage(
getCachedIrDeclaration = ::getCachedIrProperty,
createIrDeclaration = { parent, origin -> createIrProperty(fir, parent, predefinedOrigin = origin) },
createIrLazyDeclaration = { signature, lazyParent, declarationOrigin ->
val symbol = Fir2IrPropertySymbol(signature, fir.containerSource)
val irProperty = fir.convertWithOffsets { startOffset, endOffset ->
symbolTable.declareProperty(signature, { symbol }) {
val isFakeOverride =
fir.isSubstitutionOrIntersectionOverride &&
firPropertySymbol.dispatchReceiverClassOrNull() !=
firPropertySymbol.originalForSubstitutionOverride?.dispatchReceiverClassOrNull()
Fir2IrLazyProperty(
components, startOffset, endOffset, declarationOrigin, fir, lazyParent.fir, symbol, isFakeOverride
).apply {
this.parent = lazyParent
}
}
}
propertyCache[fir] = irProperty
return symbol
createIrLazyProperty(fir, signature, lazyParent, declarationOrigin)
}
)
@@ -1284,6 +1288,33 @@ class Fir2IrDeclarationStorage(
}
}
private fun createIrLazyProperty(
fir: FirProperty,
signature: IdSignature,
lazyParent: Fir2IrLazyClass,
declarationOrigin: IrDeclarationOrigin
): IrProperty {
val symbol = Fir2IrPropertySymbol(signature, fir.containerSource)
val firPropertySymbol = fir.symbol
val irProperty = fir.convertWithOffsets { startOffset, endOffset ->
symbolTable.declareProperty(signature, { symbol }) {
val isFakeOverride =
fir.isSubstitutionOrIntersectionOverride &&
firPropertySymbol.dispatchReceiverClassOrNull() !=
firPropertySymbol.originalForSubstitutionOverride?.dispatchReceiverClassOrNull()
Fir2IrLazyProperty(
components, startOffset, endOffset, declarationOrigin, fir, lazyParent.fir, symbol, isFakeOverride
).apply {
this.parent = lazyParent
}
}
}
propertyCache[fir] = irProperty
// NB: this is needed to prevent recursions in case of self bounds
(irProperty as Fir2IrLazyProperty).prepareTypeParameters()
return irProperty
}
private inline fun <reified S : IrSymbol, reified D : IrOverridableDeclaration<S>> ConeClassLookupTagWithFixedSymbol.findIrFakeOverride(
name: Name, originalDeclaration: IrOverridableDeclaration<S>
): IrSymbol? {
@@ -16,6 +16,8 @@ import org.jetbrains.kotlin.fir.declarations.utils.allowsToHaveFakeOverride
import org.jetbrains.kotlin.fir.declarations.utils.isExpect
import org.jetbrains.kotlin.fir.declarations.utils.isLocal
import org.jetbrains.kotlin.fir.declarations.utils.visibility
import org.jetbrains.kotlin.fir.declarations.utils.*
import org.jetbrains.kotlin.fir.lazy.Fir2IrLazyClass
import org.jetbrains.kotlin.fir.resolve.defaultType
import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.scopes.FirTypeScope
@@ -75,7 +77,7 @@ class FakeOverrideGenerator(
)
}
fun IrClass.getFakeOverrides(klass: FirClass, realDeclarations: Collection<FirDeclaration>): List<IrDeclaration> {
private fun IrClass.getFakeOverrides(klass: FirClass, realDeclarations: Collection<FirDeclaration>): List<IrDeclaration> {
val result = mutableListOf<IrDeclaration>()
val useSiteMemberScope = klass.unsubstitutedScope(session, scopeSession, withForcedTypeCalculator = true)
val superTypesCallableNames = useSiteMemberScope.getCallableNames()
@@ -3,12 +3,6 @@
// SKIP_JDK6
// FULL_JDK
// IGNORE_BACKEND_FIR: JVM_IR
// FIR_STATUS: java.lang.StackOverflowError
// at Test.remove(removeAtBridgeToJavaDefault.kt:7)
// at Test.remove(removeAtBridgeToJavaDefault.kt:7)
// at Test.remove(removeAtBridgeToJavaDefault.kt:7)
// FILE: removeAtBridgeToJavaDefault.kt
class Test : IntArrayList()
@@ -3,12 +3,6 @@
// SKIP_JDK6
// FULL_JDK
// IGNORE_BACKEND_FIR: JVM_IR
// FIR_STATUS: java.lang.StackOverflowError
// at Test.remove(removeAtBridgeToJavaSuperClass.kt:7)
// at Test.remove(removeAtBridgeToJavaSuperClass.kt:7)
// at Test.remove(removeAtBridgeToJavaSuperClass.kt:7)
// FILE: removeAtBridgeToJavaSuperClass.kt
class Test : IntArrayList()
@@ -3,9 +3,6 @@
// SKIP_JDK6
// FULL_JDK
// IGNORE_BACKEND_FIR: JVM_IR
// FIR_STATUS: java.lang.NoSuchMethodError: IntArrayList.removeAt(I)Ljava/lang/Integer;
// FILE: superCallToRemoveAtInJavaDefault.kt
class Test : IntArrayList() {
override fun removeAt(index: Int): Int {