[FIR] Import parents of companion objects first

Otherwise, information about members moved from companion objects to the
parent class (e.g. on JVM, companion object fields -> static fields in
parent class) will be incorrect.
This commit is contained in:
pyos
2020-11-25 11:49:35 +01:00
committed by Mikhail Glukhikh
parent 4d7b6c022b
commit 6cb573cb45
7 changed files with 78 additions and 36 deletions
@@ -148,6 +148,11 @@ public class FirCompileKotlinAgainstKotlinTestGenerated extends AbstractFirCompi
runTest("compiler/testData/compileKotlinAgainstKotlin/expectClassActualTypeAlias.kt");
}
@TestMetadata("importCompanion.kt")
public void testImportCompanion() throws Exception {
runTest("compiler/testData/compileKotlinAgainstKotlin/importCompanion.kt");
}
@TestMetadata("inlineClassFromBinaryDependencies.kt")
public void testInlineClassFromBinaryDependencies() throws Exception {
runTest("compiler/testData/compileKotlinAgainstKotlin/inlineClassFromBinaryDependencies.kt");
@@ -39,6 +39,7 @@ import org.jetbrains.kotlin.load.kotlin.*
import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinaryClass.AnnotationArrayArgumentVisitor
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
import org.jetbrains.kotlin.metadata.ProtoBuf
import org.jetbrains.kotlin.metadata.deserialization.Flags
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmMetadataVersion
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmNameResolver
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmProtoBufUtil
@@ -300,6 +301,12 @@ class KotlinDeserializedJvmSymbolsProvider(
return loadAnnotation(annotationClassId, result)
}
private fun findAndDeserializeClassViaParent(classId: ClassId): FirRegularClassSymbol? {
val outerClassId = classId.outerClassId ?: return null
findAndDeserializeClass(outerClassId) ?: return null
return classCache[classId]
}
private fun findAndDeserializeClass(
classId: ClassId,
parentContext: FirDeserializationContext? = null
@@ -314,7 +321,7 @@ class KotlinDeserializedJvmSymbolsProvider(
} catch (e: ProcessCanceledException) {
return null
}
val kotlinClassWithContent = when (result) {
val (kotlinJvmBinaryClass, byteContent) = when (result) {
is KotlinClassFinder.Result.KotlinClass -> result
is KotlinClassFinder.Result.ClassFileContent -> {
handledByJava.add(classId)
@@ -324,45 +331,39 @@ class KotlinDeserializedJvmSymbolsProvider(
null
}
}
null -> null
null -> return findAndDeserializeClassViaParent(classId)
}
if (kotlinClassWithContent == null) {
val outerClassId = classId.outerClassId ?: return null
findAndDeserializeClass(outerClassId) ?: return null
} else {
val (kotlinJvmBinaryClass, byteContent) = kotlinClassWithContent
if (kotlinJvmBinaryClass.classHeader.kind != KotlinClassHeader.Kind.CLASS) return null
val (nameResolver, classProto) = kotlinJvmBinaryClass.readClassDataFrom() ?: return null
if (kotlinJvmBinaryClass.classHeader.kind != KotlinClassHeader.Kind.CLASS) return null
val (nameResolver, classProto) = kotlinJvmBinaryClass.readClassDataFrom() ?: return null
val symbol = FirRegularClassSymbol(classId)
deserializeClassToSymbol(
classId, classProto, symbol, nameResolver, session,
JvmBinaryAnnotationDeserializer(session, kotlinJvmBinaryClass, byteContent),
kotlinScopeProvider,
parentContext, KotlinJvmBinarySourceElement(kotlinJvmBinaryClass),
this::findAndDeserializeClass
)
classCache[classId] = symbol
val annotations = mutableListOf<FirAnnotationCall>()
kotlinJvmBinaryClass.loadClassAnnotations(
object : KotlinJvmBinaryClass.AnnotationVisitor {
override fun visitAnnotation(classId: ClassId, source: SourceElement): KotlinJvmBinaryClass.AnnotationArgumentVisitor? {
return loadAnnotationIfNotSpecial(classId, annotations)
}
override fun visitEnd() {
}
},
byteContent,
)
(symbol.fir.annotations as MutableList<FirAnnotationCall>) += annotations
if (parentContext == null && Flags.CLASS_KIND.get(classProto.flags) == ProtoBuf.Class.Kind.COMPANION_OBJECT) {
return findAndDeserializeClassViaParent(classId)
}
return classCache[classId]
val symbol = FirRegularClassSymbol(classId)
deserializeClassToSymbol(
classId, classProto, symbol, nameResolver, session,
JvmBinaryAnnotationDeserializer(session, kotlinJvmBinaryClass, byteContent),
kotlinScopeProvider,
parentContext, KotlinJvmBinarySourceElement(kotlinJvmBinaryClass),
this::findAndDeserializeClass
)
classCache[classId] = symbol
val annotations = mutableListOf<FirAnnotationCall>()
kotlinJvmBinaryClass.loadClassAnnotations(
object : KotlinJvmBinaryClass.AnnotationVisitor {
override fun visitAnnotation(classId: ClassId, source: SourceElement): KotlinJvmBinaryClass.AnnotationArgumentVisitor? {
return loadAnnotationIfNotSpecial(classId, annotations)
}
override fun visitEnd() {
}
},
byteContent,
)
(symbol.fir.annotations as MutableList<FirAnnotationCall>) += annotations
return symbol
}
private fun loadFunctionsByName(part: PackagePartsCacheData, name: Name): List<FirCallableSymbol<*>> {
@@ -0,0 +1,16 @@
// WITH_RUNTIME
// TARGET_BACKEND: JVM
// FILE: 1.kt
package test
class C(val x: String) {
companion object {
@JvmField
val instance: C = C("OK")
}
}
// FILE: 2.kt
import test.C.Companion.instance
fun box() = instance.x
@@ -153,6 +153,11 @@ public class CompileKotlinAgainstKotlinTestGenerated extends AbstractCompileKotl
runTest("compiler/testData/compileKotlinAgainstKotlin/expectClassActualTypeAlias.kt");
}
@TestMetadata("importCompanion.kt")
public void testImportCompanion() throws Exception {
runTest("compiler/testData/compileKotlinAgainstKotlin/importCompanion.kt");
}
@TestMetadata("inlineClassFromBinaryDependencies.kt")
public void testInlineClassFromBinaryDependencies() throws Exception {
runTest("compiler/testData/compileKotlinAgainstKotlin/inlineClassFromBinaryDependencies.kt");
@@ -148,6 +148,11 @@ public class IrCompileKotlinAgainstKotlinTestGenerated extends AbstractIrCompile
runTest("compiler/testData/compileKotlinAgainstKotlin/expectClassActualTypeAlias.kt");
}
@TestMetadata("importCompanion.kt")
public void testImportCompanion() throws Exception {
runTest("compiler/testData/compileKotlinAgainstKotlin/importCompanion.kt");
}
@TestMetadata("inlineClassFromBinaryDependencies.kt")
public void testInlineClassFromBinaryDependencies() throws Exception {
runTest("compiler/testData/compileKotlinAgainstKotlin/inlineClassFromBinaryDependencies.kt");
@@ -148,6 +148,11 @@ public class JvmIrAgainstOldBoxTestGenerated extends AbstractJvmIrAgainstOldBoxT
runTest("compiler/testData/compileKotlinAgainstKotlin/expectClassActualTypeAlias.kt");
}
@TestMetadata("importCompanion.kt")
public void testImportCompanion() throws Exception {
runTest("compiler/testData/compileKotlinAgainstKotlin/importCompanion.kt");
}
@TestMetadata("inlineClassFromBinaryDependencies.kt")
public void testInlineClassFromBinaryDependencies() throws Exception {
runTest("compiler/testData/compileKotlinAgainstKotlin/inlineClassFromBinaryDependencies.kt");
@@ -148,6 +148,11 @@ public class JvmOldAgainstIrBoxTestGenerated extends AbstractJvmOldAgainstIrBoxT
runTest("compiler/testData/compileKotlinAgainstKotlin/expectClassActualTypeAlias.kt");
}
@TestMetadata("importCompanion.kt")
public void testImportCompanion() throws Exception {
runTest("compiler/testData/compileKotlinAgainstKotlin/importCompanion.kt");
}
@TestMetadata("inlineClassFromBinaryDependencies.kt")
public void testInlineClassFromBinaryDependencies() throws Exception {
runTest("compiler/testData/compileKotlinAgainstKotlin/inlineClassFromBinaryDependencies.kt");