FIR: fix hasTopLevelClassOf optimization in deserialized provider

Before this commit, we answered 'no top level class' if Java class finder
could not calculate known class names. However, it's incorrect,
because this situation means 'don't actually know'.

To precise semantics, function name was also inverted
This commit is contained in:
Mikhail Glukhikh
2019-12-10 12:11:33 +03:00
parent fa89aa0b49
commit 7d62e3ce56
4 changed files with 15 additions and 4 deletions
@@ -88,18 +88,20 @@ class KotlinDeserializedJvmSymbolsProvider(
private val knownClassNamesInPackage = mutableMapOf<FqName, Set<String>?>() private val knownClassNamesInPackage = mutableMapOf<FqName, Set<String>?>()
private fun hasTopLevelClassOf(classId: ClassId): Boolean { // This function returns true if we are sure that no top-level class with this id is available
// If it returns false, it means we can say nothing about this id
private fun hasNoTopLevelClassOf(classId: ClassId): Boolean {
val knownNames = knownClassNamesInPackage.getOrPut(classId.packageFqName) { val knownNames = knownClassNamesInPackage.getOrPut(classId.packageFqName) {
javaClassFinder.knownClassNamesInPackage(classId.packageFqName) javaClassFinder.knownClassNamesInPackage(classId.packageFqName)
} ?: return false } ?: return false
return classId.relativeClassName.topLevelName() in knownNames return classId.relativeClassName.topLevelName() !in knownNames
} }
private fun computePackagePartsInfos(packageFqName: FqName): List<PackagePartsCacheData> { private fun computePackagePartsInfos(packageFqName: FqName): List<PackagePartsCacheData> {
return packagePartProvider.findPackageParts(packageFqName.asString()).mapNotNull { partName -> return packagePartProvider.findPackageParts(packageFqName.asString()).mapNotNull { partName ->
val classId = ClassId.topLevel(JvmClassName.byInternalName(partName).fqNameForTopLevelClassMaybeWithDollars) val classId = ClassId.topLevel(JvmClassName.byInternalName(partName).fqNameForTopLevelClassMaybeWithDollars)
if (!hasTopLevelClassOf(classId)) return@mapNotNull null if (hasNoTopLevelClassOf(classId)) return@mapNotNull null
val kotlinJvmBinaryClass = kotlinClassFinder.findKotlinClass(classId) ?: return@mapNotNull null val kotlinJvmBinaryClass = kotlinClassFinder.findKotlinClass(classId) ?: return@mapNotNull null
val header = kotlinJvmBinaryClass.classHeader val header = kotlinJvmBinaryClass.classHeader
@@ -308,7 +310,7 @@ class KotlinDeserializedJvmSymbolsProvider(
classId: ClassId, classId: ClassId,
parentContext: FirDeserializationContext? = null parentContext: FirDeserializationContext? = null
): FirRegularClassSymbol? { ): FirRegularClassSymbol? {
if (!hasTopLevelClassOf(classId)) return null if (hasNoTopLevelClassOf(classId)) return null
if (classesCache.containsKey(classId)) return classesCache[classId] if (classesCache.containsKey(classId)) return classesCache[classId]
if (classId in handledByJava) return null if (classId in handledByJava) return null
@@ -0,0 +1 @@
val someList = listOf(1, 2, 3)
@@ -0,0 +1,3 @@
FILE: Some.kt
public final val someList: R|kotlin/collections/List<kotlin/Int>| = R|kotlin/collections/listOf|<R|kotlin/Int|>(Int(1), Int(2), Int(3))
public get(): R|kotlin/collections/List<kotlin/Int>|
@@ -122,4 +122,9 @@ public class FirMultiModuleResolveTestGenerated extends AbstractFirMultiModuleRe
public void testOverrideWithJava() throws Exception { public void testOverrideWithJava() throws Exception {
runTest("idea/testData/fir/multiModule/overrideWithJava/"); runTest("idea/testData/fir/multiModule/overrideWithJava/");
} }
@TestMetadata("withStdlib")
public void testWithStdlib() throws Exception {
runTest("idea/testData/fir/multiModule/withStdlib/");
}
} }