diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/PackagePartCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/PackagePartCodegen.java index 7df705e0c07..20eca990630 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/PackagePartCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/PackagePartCodegen.java @@ -31,8 +31,10 @@ import org.jetbrains.kotlin.descriptors.annotations.Annotated; import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.kotlin.descriptors.annotations.AnnotationsImpl; import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader; +import org.jetbrains.kotlin.name.FqName; import org.jetbrains.kotlin.psi.*; import org.jetbrains.kotlin.resolve.BindingContext; +import org.jetbrains.kotlin.resolve.jvm.JvmClassName; import org.jetbrains.kotlin.serialization.DescriptorSerializer; import org.jetbrains.kotlin.serialization.ProtoBuf; import org.jetbrains.org.objectweb.asm.Type; @@ -41,6 +43,7 @@ import java.util.ArrayList; import java.util.List; import static org.jetbrains.kotlin.codegen.AsmUtil.writeAnnotationData; +import static org.jetbrains.kotlin.load.java.JvmAnnotationNames.METADATA_PACKAGE_NAME_FIELD_NAME; import static org.jetbrains.org.objectweb.asm.Opcodes.*; public class PackagePartCodegen extends MemberCodegen { @@ -104,6 +107,12 @@ public class PackagePartCodegen extends MemberCodegen { WriteAnnotationUtilKt.writeKotlinMetadata(v, state, KotlinClassHeader.Kind.FILE_FACADE, 0, av -> { writeAnnotationData(av, serializedPart.getFirst(), serializedPart.getSecond()); + + FqName kotlinPackageFqName = element.getPackageFqName(); + if (!kotlinPackageFqName.equals(JvmClassName.byInternalName(packagePartType.getInternalName()).getPackageFqName())) { + av.visit(METADATA_PACKAGE_NAME_FIELD_NAME, kotlinPackageFqName.asString()); + } + return Unit.INSTANCE; }); } diff --git a/compiler/testData/codegen/box/jvmPackageName/metadataField.kt b/compiler/testData/codegen/box/jvmPackageName/metadataField.kt new file mode 100644 index 00000000000..3636bc85fc0 --- /dev/null +++ b/compiler/testData/codegen/box/jvmPackageName/metadataField.kt @@ -0,0 +1,28 @@ +// TARGET_BACKEND: JVM +// WITH_RUNTIME +// LANGUAGE_VERSION: 1.2 + +// FILE: foo.kt + +@file:Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER") +@file:JvmPackageName("baz.foo.quux.bar") +package foo.bar + +fun f() {} + +// FILE: bar.kt + +@file:Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER") + +fun getPackageName(classFqName: String): String = + Class.forName(classFqName).getAnnotation(Metadata::class.java).pn + +fun box(): String { + val bar = getPackageName("BarKt") + if (bar != "") return "Fail 1: $bar" + + val foo = getPackageName("baz.foo.quux.bar.FooKt") + if (foo != "foo.bar") return "Fail 2: $foo" + + return "OK" +} diff --git a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index 90cacd91b28..22653ea8db8 100644 --- a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -10568,6 +10568,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/jvmPackageName"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true); } + @TestMetadata("metadataField.kt") + public void testMetadataField() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/jvmPackageName/metadataField.kt"); + doTest(fileName); + } + @TestMetadata("rootPackage.kt") public void testRootPackage() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/jvmPackageName/rootPackage.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index ce2ea371e85..315ee959cfc 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -10568,6 +10568,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/jvmPackageName"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true); } + @TestMetadata("metadataField.kt") + public void testMetadataField() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/jvmPackageName/metadataField.kt"); + doTest(fileName); + } + @TestMetadata("rootPackage.kt") public void testRootPackage() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/jvmPackageName/rootPackage.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 8b03ccc6a32..da1836b3379 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -10568,6 +10568,12 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/jvmPackageName"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true); } + @TestMetadata("metadataField.kt") + public void testMetadataField() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/jvmPackageName/metadataField.kt"); + doTest(fileName); + } + @TestMetadata("rootPackage.kt") public void testRootPackage() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/jvmPackageName/rootPackage.kt"); diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/JvmAnnotationNames.java b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/JvmAnnotationNames.java index 884b943dcd9..fca767bb29b 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/JvmAnnotationNames.java +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/JvmAnnotationNames.java @@ -31,6 +31,7 @@ public final class JvmAnnotationNames { public static final String METADATA_DATA_FIELD_NAME = "d1"; public static final String METADATA_STRINGS_FIELD_NAME = "d2"; public static final String METADATA_EXTRA_STRING_FIELD_NAME = "xs"; + public static final String METADATA_PACKAGE_NAME_FIELD_NAME = "pn"; public static final String METADATA_MULTIFILE_CLASS_NAME_FIELD_NAME = METADATA_EXTRA_STRING_FIELD_NAME; public static final String METADATA_EXTRA_INT_FIELD_NAME = "xi"; diff --git a/core/runtime.jvm/src/kotlin/Metadata.kt b/core/runtime.jvm/src/kotlin/Metadata.kt index 51b715a25f8..acc9fb8670b 100644 --- a/core/runtime.jvm/src/kotlin/Metadata.kt +++ b/core/runtime.jvm/src/kotlin/Metadata.kt @@ -56,6 +56,12 @@ internal annotation class Metadata( * An extra string. For a multi-file part class, internal name of the facade class. */ val xs: String = "", + /** + * Fully qualified name of the package this class is located in, from Kotlin's point of view, or empty string if this name + * does not differ from the JVM's package FQ name. These names can be different in case the [JvmPackageName] annotation is used. + * Note that this information is also stored in the corresponding module's `.kotlin_module` file. + */ + val pn: String = "", /** * An extra int. Bits of this number represent the following flags: *