FIR: load parents of Java inner classes first, as before

This commit is contained in:
pyos
2021-09-09 17:24:51 +02:00
committed by TeamCityServer
parent cac0cf6a50
commit 8ff79e002e
8 changed files with 63 additions and 23 deletions
@@ -185,13 +185,27 @@ abstract class AbstractFirDeserializedSymbolsProvider(
return packagePartsCache.getValue(packageFqName) return packagePartsCache.getValue(packageFqName)
} }
protected open fun shouldLoadParentsFirst(classId: ClassId): Boolean = false
protected open fun getClass( protected open fun getClass(
classId: ClassId, classId: ClassId,
parentContext: FirDeserializationContext? = null parentContext: FirDeserializationContext? = null
): FirRegularClassSymbol? { ): FirRegularClassSymbol? {
if (parentContext == null && shouldLoadParentsFirst(classId)) {
return getClassAfterLoadingParents(classId)
}
return classCache.getValue(classId, parentContext) return classCache.getValue(classId, parentContext)
} }
private fun getClassAfterLoadingParents(classId: ClassId): FirRegularClassSymbol? {
classId.outerClassId?.let { parentClassId ->
val alreadyLoaded = classCache.getValueIfComputed(classId)
if (alreadyLoaded != null) return alreadyLoaded
getClassAfterLoadingParents(parentClassId)
}
return classCache.getValue(classId, null)
}
private fun getTypeAlias( private fun getTypeAlias(
classId: ClassId, classId: ClassId,
): FirTypeAliasSymbol? { ): FirTypeAliasSymbol? {
@@ -22946,6 +22946,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
runTest("compiler/testData/codegen/box/javaInterop/genericSamSmartcast.kt"); runTest("compiler/testData/codegen/box/javaInterop/genericSamSmartcast.kt");
} }
@Test
@TestMetadata("javaOuterClassDependsOnInner.kt")
public void testJavaOuterClassDependsOnInner() throws Exception {
runTest("compiler/testData/codegen/box/javaInterop/javaOuterClassDependsOnInner.kt");
}
@Test @Test
@TestMetadata("kt43217.kt") @TestMetadata("kt43217.kt")
public void testKt43217() throws Exception { public void testKt43217() throws Exception {
@@ -93,6 +93,9 @@ open class KotlinDeserializedJvmSymbolsProvider(
private val KotlinJvmBinaryClass.isPreReleaseInvisible: Boolean private val KotlinJvmBinaryClass.isPreReleaseInvisible: Boolean
get() = classHeader.isPreRelease get() = classHeader.isPreRelease
override fun shouldLoadParentsFirst(classId: ClassId): Boolean =
javaSymbolProvider.hasTopLevelClassOf(classId)
override fun extractClassMetadata(classId: ClassId, parentContext: FirDeserializationContext?): ClassMetadataFindResult? { override fun extractClassMetadata(classId: ClassId, parentContext: FirDeserializationContext?): ClassMetadataFindResult? {
if (knownNameInPackageCache.hasNoTopLevelClassOf(classId)) return null if (knownNameInPackageCache.hasNoTopLevelClassOf(classId)) return null
val result = try { val result = try {
@@ -0,0 +1,21 @@
// TARGET_BACKEND: JVM
// This is really a frontend test that checks loading of compiled Java classes.
// MODULE: lib
// FILE: I.java
public interface I<T> {}
// FILE: J.java
public class J implements I<J.X> {
public static class X {}
}
// FILE: Z.java
public class Z<T> {
public T foo(J.X x) { return null; }
}
// MODULE: main(lib)
// FILE: main.kt
class C : Z<Int>()
fun box() = C().foo(null) ?: "OK"
@@ -22814,6 +22814,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
runTest("compiler/testData/codegen/box/javaInterop/genericSamSmartcast.kt"); runTest("compiler/testData/codegen/box/javaInterop/genericSamSmartcast.kt");
} }
@Test
@TestMetadata("javaOuterClassDependsOnInner.kt")
public void testJavaOuterClassDependsOnInner() throws Exception {
runTest("compiler/testData/codegen/box/javaInterop/javaOuterClassDependsOnInner.kt");
}
@Test @Test
@TestMetadata("kt43217.kt") @TestMetadata("kt43217.kt")
public void testKt43217() throws Exception { public void testKt43217() throws Exception {
@@ -22946,6 +22946,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/javaInterop/genericSamSmartcast.kt"); runTest("compiler/testData/codegen/box/javaInterop/genericSamSmartcast.kt");
} }
@Test
@TestMetadata("javaOuterClassDependsOnInner.kt")
public void testJavaOuterClassDependsOnInner() throws Exception {
runTest("compiler/testData/codegen/box/javaInterop/javaOuterClassDependsOnInner.kt");
}
@Test @Test
@TestMetadata("kt43217.kt") @TestMetadata("kt43217.kt")
public void testKt43217() throws Exception { public void testKt43217() throws Exception {
@@ -19136,6 +19136,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
runTest("compiler/testData/codegen/box/javaInterop/genericSamSmartcast.kt"); runTest("compiler/testData/codegen/box/javaInterop/genericSamSmartcast.kt");
} }
@TestMetadata("javaOuterClassDependsOnInner.kt")
public void testJavaOuterClassDependsOnInner() throws Exception {
runTest("compiler/testData/codegen/box/javaInterop/javaOuterClassDependsOnInner.kt");
}
@TestMetadata("kt43217.kt") @TestMetadata("kt43217.kt")
public void testKt43217() throws Exception { public void testKt43217() throws Exception {
runTest("compiler/testData/codegen/box/javaInterop/kt43217.kt"); runTest("compiler/testData/codegen/box/javaInterop/kt43217.kt");
@@ -16,7 +16,6 @@ import org.jetbrains.kotlin.fir.backend.jvm.FirJvmTypeMapper
import org.jetbrains.kotlin.fir.caches.FirCachesFactory import org.jetbrains.kotlin.fir.caches.FirCachesFactory
import org.jetbrains.kotlin.fir.checkers.registerExtendedCommonCheckers import org.jetbrains.kotlin.fir.checkers.registerExtendedCommonCheckers
import org.jetbrains.kotlin.fir.declarations.SealedClassInheritorsProvider import org.jetbrains.kotlin.fir.declarations.SealedClassInheritorsProvider
import org.jetbrains.kotlin.fir.deserialization.FirDeserializationContext
import org.jetbrains.kotlin.fir.deserialization.ModuleDataProvider import org.jetbrains.kotlin.fir.deserialization.ModuleDataProvider
import org.jetbrains.kotlin.fir.java.JavaSymbolProvider import org.jetbrains.kotlin.fir.java.JavaSymbolProvider
import org.jetbrains.kotlin.fir.java.JavaSymbolProviderWrapper import org.jetbrains.kotlin.fir.java.JavaSymbolProviderWrapper
@@ -32,7 +31,6 @@ import org.jetbrains.kotlin.fir.resolve.transformers.FirPhaseCheckingPhaseManage
import org.jetbrains.kotlin.fir.symbols.FirPhaseManager import org.jetbrains.kotlin.fir.symbols.FirPhaseManager
import org.jetbrains.kotlin.fir.scopes.FirKotlinScopeProvider import org.jetbrains.kotlin.fir.scopes.FirKotlinScopeProvider
import org.jetbrains.kotlin.fir.session.* import org.jetbrains.kotlin.fir.session.*
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
import org.jetbrains.kotlin.idea.fir.low.level.api.* import org.jetbrains.kotlin.idea.fir.low.level.api.*
import org.jetbrains.kotlin.idea.fir.low.level.api.FirPhaseRunner import org.jetbrains.kotlin.idea.fir.low.level.api.FirPhaseRunner
import org.jetbrains.kotlin.idea.fir.low.level.api.IdeFirPhaseManager import org.jetbrains.kotlin.idea.fir.low.level.api.IdeFirPhaseManager
@@ -232,7 +230,7 @@ internal object FirIdeSessionFactory {
/** /**
* Workaround of SOE for loading classes that loads via parent. * Workaround of SOE for loading classes that loads via parent.
* It is not observable in compiler but it is in IDE * It is not observable in compiler but it is in IDE
* Remove this when cyclic cache request will be fixed in the compiler provider * TODO: this is probably already unnecessary
*/ */
private class KotlinDeserializedJvmSymbolsProviderForIde( private class KotlinDeserializedJvmSymbolsProviderForIde(
session: FirSession, session: FirSession,
@@ -246,26 +244,7 @@ internal object FirIdeSessionFactory {
session, moduleDataProvider, kotlinScopeProvider, packagePartProvider, kotlinClassFinder, session, moduleDataProvider, kotlinScopeProvider, packagePartProvider, kotlinClassFinder,
javaClassFinder, javaSymbolProvider javaClassFinder, javaSymbolProvider
) { ) {
override fun getClass( override fun shouldLoadParentsFirst(classId: ClassId): Boolean = true
classId: ClassId,
parentContext: FirDeserializationContext?
): FirRegularClassSymbol? {
if (parentContext !== null) {
return super.getClass(classId, parentContext)
}
val computedClass = classCache.getValueIfComputed(classId)
if (computedClass != null) {
return computedClass
}
var parentClassId = classId
while (true) {
parentClassId = parentClassId.outerClassId ?: break
}
classCache.getValue(parentClassId, parentContext)
return classCache.getValue(classId, parentContext)
}
} }
fun createBuiltinsAndCloneableSession( fun createBuiltinsAndCloneableSession(