From e63cef08482633586096bb139fcf25794e47ef21 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Fri, 5 Jul 2013 23:44:00 +0400 Subject: [PATCH] Deserialize annotations on package members --- .../jet/codegen/NamespaceCodegen.java | 2 +- .../serialization/JavaProtoBufUtil.java | 14 ++++++- .../AnnotationDescriptorDeserializer.java | 40 ++++++++++++++++--- .../DeserializedDescriptorResolver.java | 4 +- .../serialization/PackageData.java | 5 ++- .../annotations/packageMembers/Function.kt | 5 +++ .../annotations/packageMembers/Function.txt | 7 ++++ .../jet/codegen/KotlinInfoForPackageTest.java | 4 +- .../DescriptorSerializationTestGenerated.java | 16 +++++++- .../LoadCompiledKotlinTestGenerated.java | 16 +++++++- ...esolveNamespaceComparingTestGenerated.java | 16 +++++++- 11 files changed, 112 insertions(+), 17 deletions(-) create mode 100644 compiler/testData/loadKotlin/annotations/packageMembers/Function.kt create mode 100644 compiler/testData/loadKotlin/annotations/packageMembers/Function.txt diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java index c547a9e5ad5..3ad01c6706b 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java @@ -129,7 +129,7 @@ public class NamespaceCodegen extends MemberCodegen { } private void writeKotlinInfoIfNeeded() { - DescriptorSerializer serializer = new DescriptorSerializer(); + DescriptorSerializer serializer = new DescriptorSerializer(new JavaSerializerExtension(typeMapper)); ProtoBuf.Package.Builder packageProto = ProtoBuf.Package.newBuilder(); boolean writeAnnotation = false; diff --git a/compiler/frontend.java/serialization.java/src/org/jetbrains/jet/descriptors/serialization/JavaProtoBufUtil.java b/compiler/frontend.java/serialization.java/src/org/jetbrains/jet/descriptors/serialization/JavaProtoBufUtil.java index d5acb121547..4b47d32129e 100644 --- a/compiler/frontend.java/serialization.java/src/org/jetbrains/jet/descriptors/serialization/JavaProtoBufUtil.java +++ b/compiler/frontend.java/serialization.java/src/org/jetbrains/jet/descriptors/serialization/JavaProtoBufUtil.java @@ -36,9 +36,19 @@ public class JavaProtoBufUtil { } @NotNull - public static ClassData readJavaClassDataFrom(@NotNull byte[] data) { + private static ExtensionRegistryLite getExtensionRegistry() { ExtensionRegistryLite registry = ExtensionRegistryLite.newInstance(); JavaProtoBuf.registerAllExtensions(registry); - return ClassData.read(data, registry); + return registry; + } + + @NotNull + public static ClassData readClassDataFrom(@NotNull byte[] data) { + return ClassData.read(data, getExtensionRegistry()); + } + + @NotNull + public static PackageData readPackageDataFrom(@NotNull byte[] data) { + return PackageData.read(data, getExtensionRegistry()); } } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/AnnotationDescriptorDeserializer.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/AnnotationDescriptorDeserializer.java index 196fea06465..db772f71f79 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/AnnotationDescriptorDeserializer.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/AnnotationDescriptorDeserializer.java @@ -26,10 +26,13 @@ import org.jetbrains.jet.descriptors.serialization.ProtoBuf; import org.jetbrains.jet.descriptors.serialization.descriptors.AnnotationDeserializer; import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.descriptors.ClassOrNamespaceDescriptor; +import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; +import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant; import org.jetbrains.jet.lang.resolve.java.DescriptorResolverUtils; +import org.jetbrains.jet.lang.resolve.java.PackageClassUtils; import org.jetbrains.jet.lang.resolve.java.PsiClassFinder; import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.name.Name; @@ -61,7 +64,7 @@ public class AnnotationDescriptorDeserializer implements AnnotationDeserializer @NotNull @Override public List loadClassAnnotations(@NotNull ClassDescriptor descriptor, @NotNull ProtoBuf.Class classProto) { - VirtualFile virtualFile = findVirtualFileByDescriptor(descriptor); + VirtualFile virtualFile = findVirtualFileByClass(descriptor); try { return loadClassAnnotationsFromFile(virtualFile); } @@ -71,7 +74,20 @@ public class AnnotationDescriptorDeserializer implements AnnotationDeserializer } @NotNull - private VirtualFile findVirtualFileByDescriptor(@NotNull ClassDescriptor descriptor) { + private VirtualFile findVirtualFileByDescriptor(@NotNull ClassOrNamespaceDescriptor descriptor) { + if (descriptor instanceof ClassDescriptor) { + return findVirtualFileByClass((ClassDescriptor) descriptor); + } + else if (descriptor instanceof NamespaceDescriptor) { + return findVirtualFileByPackage((NamespaceDescriptor) descriptor); + } + else { + throw new IllegalStateException("Unrecognized descriptor: " + descriptor); + } + } + + @NotNull + private VirtualFile findVirtualFileByClass(@NotNull ClassDescriptor descriptor) { FqName fqName = kotlinFqNameToJavaFqName(naiveKotlinFqName(descriptor)); PsiClass psiClass = psiClassFinder.findPsiClass(fqName, PsiClassFinder.RuntimeClassesHandleMode.IGNORE /* TODO: ?! */); if (psiClass == null) { @@ -79,7 +95,21 @@ public class AnnotationDescriptorDeserializer implements AnnotationDeserializer } VirtualFile virtualFile = getVirtualFile(psiClass, fqName, (ClassOrNamespaceDescriptor) descriptor.getContainingDeclaration()); if (virtualFile == null) { - throw new IllegalStateException("Virtual file is not found for class: " + descriptor) ; + throw new IllegalStateException("Virtual file is not found for class: " + descriptor); + } + return virtualFile; + } + + @NotNull + private VirtualFile findVirtualFileByPackage(@NotNull NamespaceDescriptor descriptor) { + FqName fqName = PackageClassUtils.getPackageClassFqName(DescriptorUtils.getFQName(descriptor).toSafe()); + PsiClass psiClass = psiClassFinder.findPsiClass(fqName, PsiClassFinder.RuntimeClassesHandleMode.IGNORE /* TODO: ?! */); + if (psiClass == null) { + throw new IllegalStateException("Psi class is not found for package: " + descriptor); + } + VirtualFile virtualFile = psiClass.getContainingFile().getVirtualFile(); + if (virtualFile == null) { + throw new IllegalStateException("Virtual file is not found for package: " + descriptor); } return virtualFile; } @@ -147,9 +177,7 @@ public class AnnotationDescriptorDeserializer implements AnnotationDeserializer @NotNull ClassOrNamespaceDescriptor container, @NotNull ProtoBuf.Callable callableProto ) { - if (!(container instanceof ClassDescriptor)) return Collections.emptyList(); // TODO: NamespaceDescriptor - - VirtualFile file = findVirtualFileByDescriptor((ClassDescriptor) container); + VirtualFile file = findVirtualFileByDescriptor(container); try { // TODO: calculate this only once for each container diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/DeserializedDescriptorResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/DeserializedDescriptorResolver.java index 61835dee81b..e723a284255 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/DeserializedDescriptorResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/DeserializedDescriptorResolver.java @@ -138,14 +138,14 @@ public final class DeserializedDescriptorResolver { private static ClassData readClassDataFromClassFile(@NotNull VirtualFile virtualFile) { byte[] data = getKotlinInfoDataFromClassFile(virtualFile); if (data == null) return null; - return JavaProtoBufUtil.readJavaClassDataFrom(data); + return JavaProtoBufUtil.readClassDataFrom(data); } @Nullable private static PackageData readPackageDataFromClassFile(@NotNull VirtualFile virtualFile) { byte[] data = getKotlinInfoDataFromClassFile(virtualFile); if (data == null) return null; - return PackageData.read(data); + return JavaProtoBufUtil.readPackageDataFrom(data); } @Nullable diff --git a/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/PackageData.java b/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/PackageData.java index 138e0165469..496bd33d70b 100644 --- a/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/PackageData.java +++ b/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/PackageData.java @@ -16,6 +16,7 @@ package org.jetbrains.jet.descriptors.serialization; +import com.google.protobuf.ExtensionRegistryLite; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.utils.ExceptionUtils; @@ -24,11 +25,11 @@ import java.io.IOException; public final class PackageData { @NotNull - public static PackageData read(@NotNull byte[] bytes) { + public static PackageData read(@NotNull byte[] bytes, @NotNull ExtensionRegistryLite registry) { try { ByteArrayInputStream in = new ByteArrayInputStream(bytes); NameResolver nameResolver = NameSerializationUtil.deserializeNameResolver(in); - ProtoBuf.Package packageProto = ProtoBuf.Package.parseFrom(in); + ProtoBuf.Package packageProto = ProtoBuf.Package.parseFrom(in, registry); return new PackageData(nameResolver, packageProto); } catch (IOException e) { diff --git a/compiler/testData/loadKotlin/annotations/packageMembers/Function.kt b/compiler/testData/loadKotlin/annotations/packageMembers/Function.kt new file mode 100644 index 00000000000..3935c047e7a --- /dev/null +++ b/compiler/testData/loadKotlin/annotations/packageMembers/Function.kt @@ -0,0 +1,5 @@ +package test + +annotation class Anno + +Anno fun function() {} diff --git a/compiler/testData/loadKotlin/annotations/packageMembers/Function.txt b/compiler/testData/loadKotlin/annotations/packageMembers/Function.txt new file mode 100644 index 00000000000..c961286244b --- /dev/null +++ b/compiler/testData/loadKotlin/annotations/packageMembers/Function.txt @@ -0,0 +1,7 @@ +package test + +test.Anno() internal fun function(): jet.Unit + +internal final annotation class Anno : jet.Annotation { + /*primary*/ public constructor Anno() +} diff --git a/compiler/tests/org/jetbrains/jet/codegen/KotlinInfoForPackageTest.java b/compiler/tests/org/jetbrains/jet/codegen/KotlinInfoForPackageTest.java index a05bfe07027..4d517ceafc8 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/KotlinInfoForPackageTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/KotlinInfoForPackageTest.java @@ -29,6 +29,8 @@ import java.util.HashSet; import java.util.List; import java.util.Set; +import static com.google.protobuf.ExtensionRegistryLite.getEmptyRegistry; + public class KotlinInfoForPackageTest extends CodegenTestCase { public static final FqName NAMESPACE_NAME = new FqName("test"); @@ -52,7 +54,7 @@ public class KotlinInfoForPackageTest extends CodegenTestCase { assertTrue(aClass.isAnnotationPresent(KotlinInfo.class)); KotlinInfo kotlinInfo = (KotlinInfo) aClass.getAnnotation(KotlinInfo.class); - PackageData data = PackageData.read(kotlinInfo.data()); + PackageData data = PackageData.read(kotlinInfo.data(), getEmptyRegistry()); Set classNames = collectClassNames(data); assertSameElements(Arrays.asList("A", "B", "C"), classNames); diff --git a/compiler/tests/org/jetbrains/jet/descriptors/serialization/DescriptorSerializationTestGenerated.java b/compiler/tests/org/jetbrains/jet/descriptors/serialization/DescriptorSerializationTestGenerated.java index 3baa7af4c19..e9361750597 100644 --- a/compiler/tests/org/jetbrains/jet/descriptors/serialization/DescriptorSerializationTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/descriptors/serialization/DescriptorSerializationTestGenerated.java @@ -38,7 +38,7 @@ public class DescriptorSerializationTestGenerated extends AbstractDescriptorSeri } @TestMetadata("compiler/testData/loadKotlin/annotations") - @InnerTestClasses({Annotations.ClassMembers.class, Annotations.Classes.class}) + @InnerTestClasses({Annotations.ClassMembers.class, Annotations.Classes.class, Annotations.PackageMembers.class}) public static class Annotations extends AbstractDescriptorSerializationTest { public void testAllFilesPresentInAnnotations() throws Exception { JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/loadKotlin/annotations"), Pattern.compile("^(.+)\\.kt$"), true); @@ -105,11 +105,25 @@ public class DescriptorSerializationTestGenerated extends AbstractDescriptorSeri } + @TestMetadata("compiler/testData/loadKotlin/annotations/packageMembers") + public static class PackageMembers extends AbstractDescriptorSerializationTest { + public void testAllFilesPresentInPackageMembers() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/loadKotlin/annotations/packageMembers"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("Function.kt") + public void testFunction() throws Exception { + doTest("compiler/testData/loadKotlin/annotations/packageMembers/Function.kt"); + } + + } + public static Test innerSuite() { TestSuite suite = new TestSuite("Annotations"); suite.addTestSuite(Annotations.class); suite.addTestSuite(ClassMembers.class); suite.addTestSuite(Classes.class); + suite.addTestSuite(PackageMembers.class); return suite; } } diff --git a/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadCompiledKotlinTestGenerated.java b/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadCompiledKotlinTestGenerated.java index 14150f8a231..ee25dcaf12b 100644 --- a/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadCompiledKotlinTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadCompiledKotlinTestGenerated.java @@ -38,7 +38,7 @@ public class LoadCompiledKotlinTestGenerated extends AbstractLoadCompiledKotlinT } @TestMetadata("compiler/testData/loadKotlin/annotations") - @InnerTestClasses({Annotations.ClassMembers.class, Annotations.Classes.class}) + @InnerTestClasses({Annotations.ClassMembers.class, Annotations.Classes.class, Annotations.PackageMembers.class}) public static class Annotations extends AbstractLoadCompiledKotlinTest { public void testAllFilesPresentInAnnotations() throws Exception { JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/loadKotlin/annotations"), Pattern.compile("^(.+)\\.kt$"), true); @@ -105,11 +105,25 @@ public class LoadCompiledKotlinTestGenerated extends AbstractLoadCompiledKotlinT } + @TestMetadata("compiler/testData/loadKotlin/annotations/packageMembers") + public static class PackageMembers extends AbstractLoadCompiledKotlinTest { + public void testAllFilesPresentInPackageMembers() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/loadKotlin/annotations/packageMembers"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("Function.kt") + public void testFunction() throws Exception { + doTestWithAccessors("compiler/testData/loadKotlin/annotations/packageMembers/Function.kt"); + } + + } + public static Test innerSuite() { TestSuite suite = new TestSuite("Annotations"); suite.addTestSuite(Annotations.class); suite.addTestSuite(ClassMembers.class); suite.addTestSuite(Classes.class); + suite.addTestSuite(PackageMembers.class); return suite; } } diff --git a/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/LazyResolveNamespaceComparingTestGenerated.java b/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/LazyResolveNamespaceComparingTestGenerated.java index 667f1d70c4b..3eefb7385ba 100644 --- a/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/LazyResolveNamespaceComparingTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/LazyResolveNamespaceComparingTestGenerated.java @@ -40,7 +40,7 @@ public class LazyResolveNamespaceComparingTestGenerated extends AbstractLazyReso } @TestMetadata("compiler/testData/loadKotlin/annotations") - @InnerTestClasses({Annotations.ClassMembers.class, Annotations.Classes.class}) + @InnerTestClasses({Annotations.ClassMembers.class, Annotations.Classes.class, Annotations.PackageMembers.class}) public static class Annotations extends AbstractLazyResolveNamespaceComparingTest { public void testAllFilesPresentInAnnotations() throws Exception { JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/loadKotlin/annotations"), Pattern.compile("^(.+)\\.kt$"), true); @@ -107,11 +107,25 @@ public class LazyResolveNamespaceComparingTestGenerated extends AbstractLazyReso } + @TestMetadata("compiler/testData/loadKotlin/annotations/packageMembers") + public static class PackageMembers extends AbstractLazyResolveNamespaceComparingTest { + public void testAllFilesPresentInPackageMembers() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/loadKotlin/annotations/packageMembers"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("Function.kt") + public void testFunction() throws Exception { + doTestCheckingPrimaryConstructorsAndAccessors("compiler/testData/loadKotlin/annotations/packageMembers/Function.kt"); + } + + } + public static Test innerSuite() { TestSuite suite = new TestSuite("Annotations"); suite.addTestSuite(Annotations.class); suite.addTestSuite(ClassMembers.class); suite.addTestSuite(Classes.class); + suite.addTestSuite(PackageMembers.class); return suite; } }