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
This commit is contained in:
@@ -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<KtFile> {
|
||||
@@ -104,6 +107,12 @@ public class PackagePartCodegen extends MemberCodegen<KtFile> {
|
||||
|
||||
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;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
+6
@@ -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");
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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";
|
||||
|
||||
|
||||
@@ -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:
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user