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) {
|
writeKotlinMetadata(visitor, state, KotlinClassHeader.Kind.CLASS, 0) {
|
||||||
AsmUtil.writeAnnotationData(it, serializer, classProto)
|
AsmUtil.writeAnnotationData(it, serializer, classProto)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assert(irClass !in context.classNameOverride) {
|
||||||
|
"JvmPackageName is not supported for classes: ${irClass.render()}"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
is MetadataSource.File -> {
|
is MetadataSource.File -> {
|
||||||
val packageFqName = irClass.getPackageFragment()!!.fqName
|
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)
|
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 -> {
|
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.*
|
||||||
import org.jetbrains.kotlin.ir.declarations.impl.IrClassImpl
|
import org.jetbrains.kotlin.ir.declarations.impl.IrClassImpl
|
||||||
import org.jetbrains.kotlin.ir.symbols.impl.IrClassSymbolImpl
|
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.psi2ir.PsiSourceManager
|
||||||
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
||||||
import org.jetbrains.kotlin.resolve.source.KotlinSourceElement
|
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)
|
if (fileClassInfo.withJvmMultifileClass) AsmUtil.asmTypeByFqNameWithoutInnerClasses(fileClassInfo.facadeClassFqName)
|
||||||
else null
|
else null
|
||||||
context.state.factory.packagePartRegistry.addPart(irFile.fqName, partClassType.internalName, facadeClassType?.internalName)
|
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) {
|
if (facadeClassType != null) {
|
||||||
val jvmClassName = JvmClassName.byInternalName(facadeClassType.internalName)
|
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.IrFieldSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
||||||
import org.jetbrains.kotlin.ir.util.deepCopyWithSymbols
|
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.util.transformFlat
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
|
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||||
@@ -100,14 +101,27 @@ private fun generateMultifileFacades(
|
|||||||
functionDelegates: MutableMap<IrFunctionSymbol, IrFunctionSymbol>
|
functionDelegates: MutableMap<IrFunctionSymbol, IrFunctionSymbol>
|
||||||
): List<IrFile> =
|
): List<IrFile> =
|
||||||
context.multifileFacadesToAdd.map { (jvmClassName, partClasses) ->
|
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 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 {
|
val facadeClass = buildClass {
|
||||||
name = jvmClassName.fqNameForTopLevelClassMaybeWithDollars.shortName()
|
name = jvmClassName.fqNameForTopLevelClassMaybeWithDollars.shortName()
|
||||||
}.apply {
|
}.apply {
|
||||||
parent = file
|
parent = file
|
||||||
createImplicitParameterDeclarationWithWrappedDescriptor()
|
createImplicitParameterDeclarationWithWrappedDescriptor()
|
||||||
|
if (jvmClassName.packageFqName != kotlinPackageFqName) {
|
||||||
|
context.classNameOverride[this] = jvmClassName
|
||||||
|
}
|
||||||
}
|
}
|
||||||
file.declarations.add(facadeClass)
|
file.declarations.add(facadeClass)
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
// IGNORE_BACKEND: JVM_IR
|
|
||||||
// TARGET_BACKEND: JVM
|
// TARGET_BACKEND: JVM
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
|
|
||||||
// FILE: foo.kt
|
// FILE: singleFileFacade.kt
|
||||||
|
|
||||||
@file:Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
|
@file:Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
|
||||||
@file:JvmPackageName("baz.foo.quux.bar")
|
@file:JvmPackageName("baz.foo.quux.bar")
|
||||||
@@ -10,17 +9,35 @@ package foo.bar
|
|||||||
|
|
||||||
fun f() {}
|
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
|
// FILE: bar.kt
|
||||||
|
|
||||||
|
package test
|
||||||
|
|
||||||
fun getPackageName(classFqName: String): String =
|
fun getPackageName(classFqName: String): String =
|
||||||
Class.forName(classFqName).getAnnotation(Metadata::class.java).packageName
|
Class.forName(classFqName).getAnnotation(Metadata::class.java).packageName
|
||||||
|
|
||||||
fun box(): String {
|
fun box(): String {
|
||||||
val bar = getPackageName("BarKt")
|
val bar = getPackageName("test.BarKt")
|
||||||
if (bar != "") return "Fail 1: $bar"
|
if (bar != "") return "Fail 1: $bar"
|
||||||
|
|
||||||
val foo = getPackageName("baz.foo.quux.bar.FooKt")
|
val singleFileFacade = getPackageName("baz.foo.quux.bar.SingleFileFacadeKt")
|
||||||
if (foo != "foo.bar") return "Fail 2: $foo"
|
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"
|
return "OK"
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user