JVM IR: generate kotlin.Metadata.packageName value for JvmPackageName files
Support this for single file facades as well as for multi-file classes, similar to code in MultifileClassCodegen.writeKotlinMultifileFacadeAnnotationIfNeeded. Extend the test on this attribute to also cover multi-file classes.
This commit is contained in:
+7
-1
@@ -214,6 +214,10 @@ open class ClassCodegen protected constructor(
|
||||
writeKotlinMetadata(visitor, state, KotlinClassHeader.Kind.CLASS, 0) {
|
||||
AsmUtil.writeAnnotationData(it, serializer, classProto)
|
||||
}
|
||||
|
||||
assert(irClass !in context.classNameOverride) {
|
||||
"JvmPackageName is not supported for classes: ${irClass.render()}"
|
||||
}
|
||||
}
|
||||
is MetadataSource.File -> {
|
||||
val packageFqName = irClass.getPackageFragment()!!.fqName
|
||||
@@ -230,7 +234,9 @@ open class ClassCodegen protected constructor(
|
||||
av.visit(JvmAnnotationNames.METADATA_MULTIFILE_CLASS_NAME_FIELD_NAME, facadeClassName.internalName)
|
||||
}
|
||||
|
||||
// TODO: JvmPackageName
|
||||
if (irClass in context.classNameOverride) {
|
||||
av.visit(JvmAnnotationNames.METADATA_PACKAGE_NAME_FIELD_NAME, irClass.fqNameWhenAvailable!!.parent().asString())
|
||||
}
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
|
||||
+5
-1
@@ -29,6 +29,7 @@ import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrClassImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrClassSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
|
||||
import org.jetbrains.kotlin.psi2ir.PsiSourceManager
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
||||
import org.jetbrains.kotlin.resolve.source.KotlinSourceElement
|
||||
@@ -112,7 +113,10 @@ private class FileClassLowering(val context: JvmBackendContext) : FileLoweringPa
|
||||
if (fileClassInfo.withJvmMultifileClass) AsmUtil.asmTypeByFqNameWithoutInnerClasses(fileClassInfo.facadeClassFqName)
|
||||
else null
|
||||
context.state.factory.packagePartRegistry.addPart(irFile.fqName, partClassType.internalName, facadeClassType?.internalName)
|
||||
context.classNameOverride[this] = JvmClassName.byInternalName(partClassType.internalName)
|
||||
|
||||
if (fileClassInfo.fileClassFqName != fqNameWhenAvailable) {
|
||||
context.classNameOverride[this] = JvmClassName.byInternalName(partClassType.internalName)
|
||||
}
|
||||
|
||||
if (facadeClassType != null) {
|
||||
val jvmClassName = JvmClassName.byInternalName(facadeClassType.internalName)
|
||||
|
||||
+15
-1
@@ -39,6 +39,7 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrGetFieldImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.util.deepCopyWithSymbols
|
||||
import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
|
||||
import org.jetbrains.kotlin.ir.util.transformFlat
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
@@ -100,14 +101,27 @@ private fun generateMultifileFacades(
|
||||
functionDelegates: MutableMap<IrFunctionSymbol, IrFunctionSymbol>
|
||||
): List<IrFile> =
|
||||
context.multifileFacadesToAdd.map { (jvmClassName, partClasses) ->
|
||||
val kotlinPackageFqName = partClasses.first().fqNameWhenAvailable!!.parent()
|
||||
if (!partClasses.all { it.fqNameWhenAvailable!!.parent() == kotlinPackageFqName }) {
|
||||
throw UnsupportedOperationException(
|
||||
"Multi-file parts of a facade with JvmPackageName should all lie in the same Kotlin package:\n " +
|
||||
partClasses.joinToString("\n ") { klass ->
|
||||
"Class ${klass.fqNameWhenAvailable}, JVM name ${context.classNameOverride[klass]}"
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
val fileEntry = MultifileFacadeFileEntry(jvmClassName, partClasses.map(IrClass::fileParent))
|
||||
val file = IrFileImpl(fileEntry, EmptyPackageFragmentDescriptor(module, jvmClassName.packageFqName))
|
||||
val file = IrFileImpl(fileEntry, EmptyPackageFragmentDescriptor(module, kotlinPackageFqName))
|
||||
|
||||
val facadeClass = buildClass {
|
||||
name = jvmClassName.fqNameForTopLevelClassMaybeWithDollars.shortName()
|
||||
}.apply {
|
||||
parent = file
|
||||
createImplicitParameterDeclarationWithWrappedDescriptor()
|
||||
if (jvmClassName.packageFqName != kotlinPackageFqName) {
|
||||
context.classNameOverride[this] = jvmClassName
|
||||
}
|
||||
}
|
||||
file.declarations.add(facadeClass)
|
||||
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// TARGET_BACKEND: JVM
|
||||
// WITH_RUNTIME
|
||||
|
||||
// FILE: foo.kt
|
||||
// FILE: singleFileFacade.kt
|
||||
|
||||
@file:Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
|
||||
@file:JvmPackageName("baz.foo.quux.bar")
|
||||
@@ -10,17 +9,35 @@ package foo.bar
|
||||
|
||||
fun f() {}
|
||||
|
||||
// FILE: multiFile.kt
|
||||
|
||||
@file:Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
|
||||
@file:JvmPackageName("bar.baz.quux.foo")
|
||||
@file:JvmMultifileClass
|
||||
@file:JvmName("Facade")
|
||||
package foo.bar
|
||||
|
||||
fun g() {}
|
||||
|
||||
// FILE: bar.kt
|
||||
|
||||
package test
|
||||
|
||||
fun getPackageName(classFqName: String): String =
|
||||
Class.forName(classFqName).getAnnotation(Metadata::class.java).packageName
|
||||
|
||||
fun box(): String {
|
||||
val bar = getPackageName("BarKt")
|
||||
val bar = getPackageName("test.BarKt")
|
||||
if (bar != "") return "Fail 1: $bar"
|
||||
|
||||
val foo = getPackageName("baz.foo.quux.bar.FooKt")
|
||||
if (foo != "foo.bar") return "Fail 2: $foo"
|
||||
val singleFileFacade = getPackageName("baz.foo.quux.bar.SingleFileFacadeKt")
|
||||
if (singleFileFacade != "foo.bar") return "Fail 2: $singleFileFacade"
|
||||
|
||||
val multiFileFacade = getPackageName("bar.baz.quux.foo.Facade")
|
||||
if (multiFileFacade != "foo.bar") return "Fail 3: $multiFileFacade"
|
||||
|
||||
val multiFilePart = getPackageName("bar.baz.quux.foo.Facade__MultiFileKt")
|
||||
if (multiFilePart != "foo.bar") return "Fail 4: $multiFilePart"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user