From 5f775497e228b674e0a69d9fc0312455ee66deba Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Thu, 12 Oct 2017 15:44:04 +0200 Subject: [PATCH] Add Kotlin package FQ name to kotlin.Metadata It might differ from the JVM package FQ name if the JvmPackageName annotation is used. This will be useful for faster indexing in the IDE and for reflection --- .../kotlin/codegen/PackagePartCodegen.java | 9 ++++++ .../box/jvmPackageName/metadataField.kt | 28 +++++++++++++++++++ .../ir/IrBlackBoxCodegenTestGenerated.java | 6 ++++ .../codegen/BlackBoxCodegenTestGenerated.java | 6 ++++ .../LightAnalysisModeTestGenerated.java | 6 ++++ .../kotlin/load/java/JvmAnnotationNames.java | 1 + core/runtime.jvm/src/kotlin/Metadata.kt | 6 ++++ 7 files changed, 62 insertions(+) create mode 100644 compiler/testData/codegen/box/jvmPackageName/metadataField.kt 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: *