FIR2IR: use lookupTag or class to getLocalClass, not classId

Before this commit, we sometimes tried to fetch anonymous object by id,
getting sometimes a wrong result because it's singleton.
Now we use lookupTag or FIR class itself instead.

#KT-44050 Fixed
This commit is contained in:
Jinseong Jeon
2020-12-22 22:02:50 -08:00
committed by Mikhail Glukhikh
parent 94315bc4dc
commit 34dbbdce07
12 changed files with 109 additions and 35 deletions
@@ -12,11 +12,9 @@ import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.lazy.Fir2IrLazyClass
import org.jetbrains.kotlin.fir.resolve.firProvider
import org.jetbrains.kotlin.fir.resolve.firSymbolProvider
import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.symbols.Fir2IrClassSymbol
import org.jetbrains.kotlin.fir.symbols.Fir2IrEnumEntrySymbol
import org.jetbrains.kotlin.fir.symbols.Fir2IrTypeAliasSymbol
import org.jetbrains.kotlin.fir.symbols.StandardClassIds
import org.jetbrains.kotlin.fir.symbols.*
import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLikeLookupTagImpl
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
@@ -36,7 +34,6 @@ import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
import org.jetbrains.kotlin.ir.util.IdSignature
import org.jetbrains.kotlin.ir.util.constructors
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name
class Fir2IrClassifierStorage(
@@ -143,11 +140,8 @@ class Fir2IrClassifierStorage(
}
}
internal fun getCachedLocalClass(classId: ClassId): IrClass? {
require(classId.isLocal) {
"As the function name implies, it ought to be used to look up _local_ classes."
}
return localStorage.getLocalClass(classId)
internal fun getCachedLocalClass(lookupTag: ConeClassLikeLookupTag): IrClass? {
return localStorage.getLocalClass(lookupTag.toSymbol(session)!!.fir as FirClass<*>)
}
private fun FirRegularClass.enumClassModality(): Modality {
@@ -452,7 +446,8 @@ class Fir2IrClassifierStorage(
firClass as FirRegularClass
val classId = firClassSymbol.classId
val parentId = classId.outerClassId
val irParent = declarationStorage.findIrParent(classId.packageFqName, parentId, firClassSymbol)!!
val parentClass = parentId?.let { session.firSymbolProvider.getClassLikeSymbolByFqName(it) }
val irParent = declarationStorage.findIrParent(classId.packageFqName, parentClass?.toLookupTag(), firClassSymbol)!!
val symbol = Fir2IrClassSymbol(signature)
val irClass = firClass.convertWithOffsets { startOffset, endOffset ->
symbolTable.declareClass(signature, { symbol }) {
@@ -27,9 +27,9 @@ import org.jetbrains.kotlin.fir.lazy.Fir2IrLazyProperty
import org.jetbrains.kotlin.fir.lazy.Fir2IrLazySimpleFunction
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
import org.jetbrains.kotlin.fir.resolve.firProvider
import org.jetbrains.kotlin.fir.resolve.firSymbolProvider
import org.jetbrains.kotlin.fir.resolve.inference.isSuspendFunctionType
import org.jetbrains.kotlin.fir.resolve.isKFunctionInvoke
import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.symbols.*
import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.fir.types.*
@@ -48,7 +48,6 @@ import org.jetbrains.kotlin.ir.types.IrErrorType
import org.jetbrains.kotlin.ir.types.IrSimpleType
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource
@@ -60,8 +59,6 @@ class Fir2IrDeclarationStorage(
private val moduleDescriptor: FirModuleDescriptor
) : Fir2IrComponents by components {
private val firSymbolProvider = session.firSymbolProvider
private val firProvider = session.firProvider
private val fragmentCache = mutableMapOf<FqName, IrExternalPackageFragment>()
@@ -200,11 +197,11 @@ class Fir2IrDeclarationStorage(
}
}
private fun findIrClass(classId: ClassId): IrClass? =
if (classId.isLocal) {
classifierStorage.getCachedLocalClass(classId)
private fun findIrClass(lookupTag: ConeClassLikeLookupTag): IrClass? =
if (lookupTag.classId.isLocal) {
classifierStorage.getCachedLocalClass(lookupTag)
} else {
val firSymbol = firSymbolProvider.getClassLikeSymbolByFqName(classId)
val firSymbol = lookupTag.toSymbol(session)
if (firSymbol is FirClassSymbol) {
classifierStorage.getIrClassSymbol(firSymbol).owner
} else {
@@ -212,9 +209,13 @@ class Fir2IrDeclarationStorage(
}
}
internal fun findIrParent(packageFqName: FqName, parentClassId: ClassId?, firBasedSymbol: FirBasedSymbol<*>): IrDeclarationParent? {
return if (parentClassId != null) {
findIrClass(parentClassId)
internal fun findIrParent(
packageFqName: FqName,
parentLookupTag: ConeClassLikeLookupTag?,
firBasedSymbol: FirBasedSymbol<*>
): IrDeclarationParent? {
return if (parentLookupTag != null) {
findIrClass(parentLookupTag)
} else {
val containerFile = when (firBasedSymbol) {
is FirCallableSymbol -> firProvider.getFirCallableContainerFile(firBasedSymbol)
@@ -235,7 +236,7 @@ class Fir2IrDeclarationStorage(
internal fun findIrParent(callableDeclaration: FirCallableDeclaration<*>): IrDeclarationParent? {
val firBasedSymbol = callableDeclaration.symbol
val callableId = firBasedSymbol.callableId
return findIrParent(callableId.packageName, callableDeclaration.containingClass()?.classId, firBasedSymbol)
return findIrParent(callableId.packageName, callableDeclaration.containingClass(), firBasedSymbol)
}
private fun IrDeclaration.setAndModifyParent(irParent: IrDeclarationParent?) {
@@ -359,9 +360,7 @@ class Fir2IrDeclarationStorage(
isStatic: Boolean,
parentPropertyReceiverType: FirTypeRef? = null
): T {
if (irParent != null) {
parent = irParent
}
setAndModifyParent(irParent)
declareParameters(function, thisReceiverOwner, isStatic, parentPropertyReceiverType)
return this
}
@@ -1049,9 +1048,7 @@ class Fir2IrDeclarationStorage(
val irParent = findIrParent(fir)
val parentOrigin = (irParent as? IrDeclaration)?.origin ?: IrDeclarationOrigin.DEFINED
val declarationOrigin = computeDeclarationOrigin(firFunctionSymbol, parentOrigin, irParent)
createIrFunction(fir, irParent, origin = declarationOrigin).apply {
setAndModifyParent(irParent)
}.symbol
createIrFunction(fir, irParent, origin = declarationOrigin).symbol
}
is FirSimpleFunction -> {
return getIrCallableSymbol(
@@ -1207,7 +1204,7 @@ class Fir2IrDeclarationStorage(
is FirEnumEntry -> {
classifierStorage.getCachedIrEnumEntry(firDeclaration)?.let { return it.symbol }
val containingFile = firProvider.getFirCallableContainerFile(firVariableSymbol)
val irParentClass = firDeclaration.containingClass()?.classId?.let { findIrClass(it) }
val irParentClass = firDeclaration.containingClass()?.let { findIrClass(it) }
classifierStorage.createIrEnumEntry(
firDeclaration,
irParent = irParentClass,
@@ -1228,7 +1225,7 @@ class Fir2IrDeclarationStorage(
private fun IrMutableAnnotationContainer.convertAnnotationsFromLibrary(firAnnotationContainer: FirAnnotationContainer) {
if ((firAnnotationContainer as? FirDeclaration)?.isFromLibrary == true) {
annotationGenerator?.generate(this, firAnnotationContainer)
annotationGenerator.generate(this, firAnnotationContainer)
}
}
@@ -39,10 +39,6 @@ class Fir2IrLocalStorage {
return localClassCache[localClass]
}
fun getLocalClass(classId: ClassId): IrClass? {
return localClassCache.entries.find { (firClass, _) -> firClass.classId == classId }?.value
}
fun getLocalFunction(localFunction: FirFunction<*>): IrSimpleFunction? =
last { getLocalFunction(localFunction) }
@@ -19884,6 +19884,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
runTest("compiler/testData/codegen/box/objects/useAnonymousObjectAsIterator.kt");
}
@TestMetadata("useAnonymousObjectFunction.kt")
public void testUseAnonymousObjectFunction() throws Exception {
runTest("compiler/testData/codegen/box/objects/useAnonymousObjectFunction.kt");
}
@TestMetadata("useImportedMember.kt")
public void testUseImportedMember() throws Exception {
runTest("compiler/testData/codegen/box/objects/useImportedMember.kt");
@@ -0,0 +1,46 @@
// KT-44050
enum class Enum {
Entry1() {
fun bogus() = 42
},
Entry2() {
fun bogus() = 42
}
}
class Outer {
fun barCaller(): Enum = obj1.bar()
fun bazCaller(): Enum = obj2.baz()
private abstract inner class Inner<T>(val default: T) {
abstract fun foo()
}
private val obj1 = object : Inner<Enum>(Enum.Entry1) {
override fun foo() {
TODO("not related")
}
fun bar(): Enum {
return default
}
}
private val obj2 = object : Inner<Enum>(Enum.Entry2) {
override fun foo() {
TODO("not related")
}
fun baz(): Enum {
return default
}
}
}
fun box(): String {
val o = Outer()
if (o.barCaller() != Enum.Entry1) return "Fail1"
if (o.bazCaller() != Enum.Entry2) return "Fail2"
return "OK"
}
@@ -19884,6 +19884,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
runTest("compiler/testData/codegen/box/objects/useAnonymousObjectAsIterator.kt");
}
@TestMetadata("useAnonymousObjectFunction.kt")
public void testUseAnonymousObjectFunction() throws Exception {
runTest("compiler/testData/codegen/box/objects/useAnonymousObjectFunction.kt");
}
@TestMetadata("useImportedMember.kt")
public void testUseImportedMember() throws Exception {
runTest("compiler/testData/codegen/box/objects/useImportedMember.kt");
@@ -19884,6 +19884,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
runTest("compiler/testData/codegen/box/objects/useAnonymousObjectAsIterator.kt");
}
@TestMetadata("useAnonymousObjectFunction.kt")
public void testUseAnonymousObjectFunction() throws Exception {
runTest("compiler/testData/codegen/box/objects/useAnonymousObjectFunction.kt");
}
@TestMetadata("useImportedMember.kt")
public void testUseImportedMember() throws Exception {
runTest("compiler/testData/codegen/box/objects/useImportedMember.kt");
@@ -19884,6 +19884,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/objects/useAnonymousObjectAsIterator.kt");
}
@TestMetadata("useAnonymousObjectFunction.kt")
public void testUseAnonymousObjectFunction() throws Exception {
runTest("compiler/testData/codegen/box/objects/useAnonymousObjectFunction.kt");
}
@TestMetadata("useImportedMember.kt")
public void testUseImportedMember() throws Exception {
runTest("compiler/testData/codegen/box/objects/useImportedMember.kt");
@@ -15939,6 +15939,11 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes
runTest("compiler/testData/codegen/box/objects/useAnonymousObjectAsIterator.kt");
}
@TestMetadata("useAnonymousObjectFunction.kt")
public void testUseAnonymousObjectFunction() throws Exception {
runTest("compiler/testData/codegen/box/objects/useAnonymousObjectFunction.kt");
}
@TestMetadata("useImportedMember.kt")
public void testUseImportedMember() throws Exception {
runTest("compiler/testData/codegen/box/objects/useImportedMember.kt");
@@ -15939,6 +15939,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
runTest("compiler/testData/codegen/box/objects/useAnonymousObjectAsIterator.kt");
}
@TestMetadata("useAnonymousObjectFunction.kt")
public void testUseAnonymousObjectFunction() throws Exception {
runTest("compiler/testData/codegen/box/objects/useAnonymousObjectFunction.kt");
}
@TestMetadata("useImportedMember.kt")
public void testUseImportedMember() throws Exception {
runTest("compiler/testData/codegen/box/objects/useImportedMember.kt");
@@ -16004,6 +16004,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
runTest("compiler/testData/codegen/box/objects/useAnonymousObjectAsIterator.kt");
}
@TestMetadata("useAnonymousObjectFunction.kt")
public void testUseAnonymousObjectFunction() throws Exception {
runTest("compiler/testData/codegen/box/objects/useAnonymousObjectFunction.kt");
}
@TestMetadata("useImportedMember.kt")
public void testUseImportedMember() throws Exception {
runTest("compiler/testData/codegen/box/objects/useImportedMember.kt");
@@ -9980,6 +9980,11 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest
runTest("compiler/testData/codegen/box/objects/useAnonymousObjectAsIterator.kt");
}
@TestMetadata("useAnonymousObjectFunction.kt")
public void testUseAnonymousObjectFunction() throws Exception {
runTest("compiler/testData/codegen/box/objects/useAnonymousObjectFunction.kt");
}
@TestMetadata("useImportedMember.kt")
public void testUseImportedMember() throws Exception {
runTest("compiler/testData/codegen/box/objects/useImportedMember.kt");