Refactor AbstractDescriptorSerializationTest
Use existing utility functions, replace ClassMetadata -> ClassData, add annotations, etc.
This commit is contained in:
+1
-1
@@ -36,7 +36,7 @@ public class JavaProtoBufUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private static ExtensionRegistryLite getExtensionRegistry() {
|
public static ExtensionRegistryLite getExtensionRegistry() {
|
||||||
ExtensionRegistryLite registry = ExtensionRegistryLite.newInstance();
|
ExtensionRegistryLite registry = ExtensionRegistryLite.newInstance();
|
||||||
JavaProtoBuf.registerAllExtensions(registry);
|
JavaProtoBuf.registerAllExtensions(registry);
|
||||||
return registry;
|
return registry;
|
||||||
|
|||||||
+57
-98
@@ -33,7 +33,6 @@ import org.jetbrains.jet.lang.descriptors.*;
|
|||||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.impl.NamespaceDescriptorImpl;
|
import org.jetbrains.jet.lang.descriptors.impl.NamespaceDescriptorImpl;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingTraceContext;
|
import org.jetbrains.jet.lang.resolve.BindingTraceContext;
|
||||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
|
||||||
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver;
|
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver;
|
||||||
import org.jetbrains.jet.lang.resolve.lazy.KotlinTestWithEnvironment;
|
import org.jetbrains.jet.lang.resolve.lazy.KotlinTestWithEnvironment;
|
||||||
import org.jetbrains.jet.lang.resolve.lazy.LazyResolveTestUtil;
|
import org.jetbrains.jet.lang.resolve.lazy.LazyResolveTestUtil;
|
||||||
@@ -48,9 +47,15 @@ import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
|
|||||||
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
||||||
import org.jetbrains.jet.test.util.NamespaceComparator;
|
import org.jetbrains.jet.test.util.NamespaceComparator;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
|
import static org.jetbrains.jet.descriptors.serialization.ClassSerializationUtil.constantSerializer;
|
||||||
|
import static org.jetbrains.jet.descriptors.serialization.ClassSerializationUtil.getClassId;
|
||||||
|
import static org.jetbrains.jet.descriptors.serialization.NameSerializationUtil.*;
|
||||||
import static org.jetbrains.jet.descriptors.serialization.descriptors.AnnotationDeserializer.UNSUPPORTED;
|
import static org.jetbrains.jet.descriptors.serialization.descriptors.AnnotationDeserializer.UNSUPPORTED;
|
||||||
import static org.jetbrains.jet.lang.resolve.java.resolver.DeserializedResolverUtils.naiveKotlinFqName;
|
import static org.jetbrains.jet.lang.resolve.java.resolver.DeserializedResolverUtils.naiveKotlinFqName;
|
||||||
|
|
||||||
@@ -62,7 +67,7 @@ public abstract class AbstractDescriptorSerializationTest extends KotlinTestWith
|
|||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public List<AnnotationDescriptor> loadClassAnnotations(@NotNull ClassDescriptor descriptor, @NotNull ProtoBuf.Class classProto) {
|
public List<AnnotationDescriptor> loadClassAnnotations(@NotNull ClassDescriptor descriptor, @NotNull ProtoBuf.Class classProto) {
|
||||||
// This is a hack for tests: only data annotations are present in test data so far
|
// TODO: not only data annotations are present in tests
|
||||||
AnnotationDescriptor annotationDescriptor = new AnnotationDescriptor();
|
AnnotationDescriptor annotationDescriptor = new AnnotationDescriptor();
|
||||||
annotationDescriptor.setAnnotationType(KotlinBuiltIns.getInstance().getDataClassAnnotation().getDefaultType());
|
annotationDescriptor.setAnnotationType(KotlinBuiltIns.getInstance().getDataClassAnnotation().getDefaultType());
|
||||||
return Collections.singletonList(annotationDescriptor);
|
return Collections.singletonList(annotationDescriptor);
|
||||||
@@ -88,7 +93,7 @@ public abstract class AbstractDescriptorSerializationTest extends KotlinTestWith
|
|||||||
return createEnvironmentWithMockJdk(ConfigurationKind.JDK_ONLY);
|
return createEnvironmentWithMockJdk(ConfigurationKind.JDK_ONLY);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void doTest(String path) throws IOException {
|
protected void doTest(@NotNull String path) throws IOException {
|
||||||
File ktFile = new File(path);
|
File ktFile = new File(path);
|
||||||
ModuleDescriptor moduleDescriptor = LazyResolveTestUtil.resolveEagerly(Collections.singletonList(
|
ModuleDescriptor moduleDescriptor = LazyResolveTestUtil.resolveEagerly(Collections.singletonList(
|
||||||
JetTestUtils.createFile(ktFile.getName(), FileUtil.loadFile(ktFile), getProject())
|
JetTestUtils.createFile(ktFile.getName(), FileUtil.loadFile(ktFile), getProject())
|
||||||
@@ -109,20 +114,19 @@ public abstract class AbstractDescriptorSerializationTest extends KotlinTestWith
|
|||||||
NamespaceComparator.validateAndCompareNamespaces(testNamespace, deserialized, NamespaceComparator.RECURSIVE, null);
|
NamespaceComparator.validateAndCompareNamespaces(testNamespace, deserialized, NamespaceComparator.RECURSIVE, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
private static NamespaceDescriptor serializeAndDeserialize(
|
private static NamespaceDescriptor serializeAndDeserialize(
|
||||||
JavaDescriptorResolver javaDescriptorResolver,
|
@NotNull JavaDescriptorResolver javaDescriptorResolver,
|
||||||
Collection<DeclarationDescriptor> initial
|
@NotNull Collection<DeclarationDescriptor> initial
|
||||||
) throws IOException {
|
) throws IOException {
|
||||||
List<ClassDescriptor> classes = Lists.newArrayList();
|
List<ClassDescriptor> classes = Lists.newArrayList();
|
||||||
List<CallableMemberDescriptor> callables = Lists.newArrayList();
|
List<CallableMemberDescriptor> callables = Lists.newArrayList();
|
||||||
for (DeclarationDescriptor descriptor : initial) {
|
for (DeclarationDescriptor descriptor : initial) {
|
||||||
if (descriptor instanceof ClassDescriptor) {
|
if (descriptor instanceof ClassDescriptor) {
|
||||||
ClassDescriptor classDescriptor = (ClassDescriptor) descriptor;
|
classes.add((ClassDescriptor) descriptor);
|
||||||
classes.add(classDescriptor);
|
|
||||||
}
|
}
|
||||||
else if (descriptor instanceof CallableMemberDescriptor) {
|
else if (descriptor instanceof CallableMemberDescriptor) {
|
||||||
CallableMemberDescriptor memberDescriptor = (CallableMemberDescriptor) descriptor;
|
callables.add((CallableMemberDescriptor) descriptor);
|
||||||
callables.add(memberDescriptor);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fail("Unsupported descriptor type: " + descriptor);
|
fail("Unsupported descriptor type: " + descriptor);
|
||||||
@@ -131,28 +135,21 @@ public abstract class AbstractDescriptorSerializationTest extends KotlinTestWith
|
|||||||
return getDeserializedDescriptors(javaDescriptorResolver, classes, callables);
|
return getDeserializedDescriptors(javaDescriptorResolver, classes, callables);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
private static NamespaceDescriptor getDeserializedDescriptors(
|
private static NamespaceDescriptor getDeserializedDescriptors(
|
||||||
JavaDescriptorResolver javaDescriptorResolver,
|
@NotNull JavaDescriptorResolver javaDescriptorResolver,
|
||||||
List<ClassDescriptor> classes,
|
@NotNull List<ClassDescriptor> classes,
|
||||||
List<CallableMemberDescriptor> callables
|
@NotNull List<CallableMemberDescriptor> callables
|
||||||
) throws IOException {
|
) throws IOException {
|
||||||
ByteArrayOutputStream serializedCallables = new ByteArrayOutputStream();
|
Map<ClassDescriptor, byte[]> serializedClasses = serializeClasses(classes);
|
||||||
Map<ClassDescriptor, byte[]> serializedClasses = Maps.newHashMap();
|
byte[] serializedCallables = serializeCallables(callables);
|
||||||
serialize(classes, callables, serializedClasses, serializedCallables);
|
|
||||||
|
|
||||||
final Map<String, ClassMetadata> classMetadata = Maps.newHashMap();
|
final Map<String, ClassData> classDataMap = Maps.newHashMap();
|
||||||
|
|
||||||
for (Map.Entry<ClassDescriptor, byte[]> entry : serializedClasses.entrySet()) {
|
for (Map.Entry<ClassDescriptor, byte[]> entry : serializedClasses.entrySet()) {
|
||||||
ClassDescriptor classDescriptor = entry.getKey();
|
String key = naiveKotlinFqName(entry.getKey()).asString();
|
||||||
byte[] bytes = entry.getValue();
|
ClassData value = ClassData.read(entry.getValue(), JavaProtoBufUtil.getExtensionRegistry());
|
||||||
|
classDataMap.put(key, value);
|
||||||
ByteArrayInputStream in = new ByteArrayInputStream(bytes);
|
|
||||||
|
|
||||||
ProtoBuf.SimpleNameTable simpleNames = ProtoBuf.SimpleNameTable.parseDelimitedFrom(in);
|
|
||||||
ProtoBuf.QualifiedNameTable qualifiedNames = ProtoBuf.QualifiedNameTable.parseDelimitedFrom(in);
|
|
||||||
ProtoBuf.Class proto = ProtoBuf.Class.parseFrom(in);
|
|
||||||
|
|
||||||
classMetadata.put(naiveKotlinFqName(classDescriptor).asString(), new ClassMetadata(simpleNames, qualifiedNames, proto));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NamespaceDescriptorImpl namespace = JetTestUtils.createTestNamespace(TEST_PACKAGE_NAME);
|
NamespaceDescriptorImpl namespace = JetTestUtils.createTestNamespace(TEST_PACKAGE_NAME);
|
||||||
@@ -160,18 +157,17 @@ public abstract class AbstractDescriptorSerializationTest extends KotlinTestWith
|
|||||||
|
|
||||||
DescriptorFinderImpl descriptorFinder = new DescriptorFinderImpl(
|
DescriptorFinderImpl descriptorFinder = new DescriptorFinderImpl(
|
||||||
javaDescriptorFinder, namespace,
|
javaDescriptorFinder, namespace,
|
||||||
new NullableFunction<String, ClassMetadata>() {
|
new NullableFunction<String, ClassData>() {
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public ClassMetadata fun(String fqName) {
|
public ClassData fun(String fqName) {
|
||||||
return classMetadata.get(fqName);
|
return classDataMap.get(fqName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
for (ClassDescriptor classDescriptor : classes) {
|
for (ClassDescriptor classDescriptor : classes) {
|
||||||
ClassId classId = new ClassId(DescriptorUtils.getFQName(classDescriptor.getContainingDeclaration()).toSafe(),
|
ClassId classId = getClassId(classDescriptor);
|
||||||
FqNameUnsafe.topLevel(classDescriptor.getName()));
|
|
||||||
ClassDescriptor descriptor = descriptorFinder.findClass(classId);
|
ClassDescriptor descriptor = descriptorFinder.findClass(classId);
|
||||||
assert descriptor != null : "Class not loaded: " + classId;
|
assert descriptor != null : "Class not loaded: " + classId;
|
||||||
if (descriptor.getKind().isObject()) {
|
if (descriptor.getKind().isObject()) {
|
||||||
@@ -182,9 +178,8 @@ public abstract class AbstractDescriptorSerializationTest extends KotlinTestWith
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ByteArrayInputStream in = new ByteArrayInputStream(serializedCallables.toByteArray());
|
ByteArrayInputStream in = new ByteArrayInputStream(serializedCallables);
|
||||||
ProtoBuf.SimpleNameTable simpleNames = ProtoBuf.SimpleNameTable.parseDelimitedFrom(in);
|
NameResolver nameResolver = deserializeNameResolver(in);
|
||||||
ProtoBuf.QualifiedNameTable qualifiedNames = ProtoBuf.QualifiedNameTable.parseDelimitedFrom(in);
|
|
||||||
|
|
||||||
List<ProtoBuf.Callable> callableProtos = Lists.newArrayList();
|
List<ProtoBuf.Callable> callableProtos = Lists.newArrayList();
|
||||||
for (int i = 0; i < callables.size(); i++) {
|
for (int i = 0; i < callables.size(); i++) {
|
||||||
@@ -193,8 +188,7 @@ public abstract class AbstractDescriptorSerializationTest extends KotlinTestWith
|
|||||||
}
|
}
|
||||||
|
|
||||||
DescriptorDeserializer deserializer =
|
DescriptorDeserializer deserializer =
|
||||||
DescriptorDeserializer.create(new LockBasedStorageManager(), namespace, new NameResolver(simpleNames, qualifiedNames),
|
DescriptorDeserializer.create(new LockBasedStorageManager(), namespace, nameResolver, descriptorFinder, UNSUPPORTED);
|
||||||
descriptorFinder, UNSUPPORTED);
|
|
||||||
for (ProtoBuf.Callable proto : callableProtos) {
|
for (ProtoBuf.Callable proto : callableProtos) {
|
||||||
CallableMemberDescriptor descriptor = deserializer.loadCallable(proto);
|
CallableMemberDescriptor descriptor = deserializer.loadCallable(proto);
|
||||||
if (descriptor instanceof FunctionDescriptor) {
|
if (descriptor instanceof FunctionDescriptor) {
|
||||||
@@ -212,85 +206,57 @@ public abstract class AbstractDescriptorSerializationTest extends KotlinTestWith
|
|||||||
return namespace;
|
return namespace;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void serialize(
|
@NotNull
|
||||||
List<ClassDescriptor> classes, List<CallableMemberDescriptor> callables,
|
private static byte[] serializeCallables(@NotNull List<CallableMemberDescriptor> callables) throws IOException {
|
||||||
Map<ClassDescriptor, byte[]> serializedClasses, OutputStream serializedCallables
|
DescriptorSerializer serializer = new DescriptorSerializer();
|
||||||
) throws IOException {
|
|
||||||
|
|
||||||
serializeClasses(classes, serializedClasses);
|
|
||||||
|
|
||||||
DescriptorSerializer descriptorSerializer = new DescriptorSerializer();
|
|
||||||
List<MessageLite> messages = Lists.newArrayList();
|
List<MessageLite> messages = Lists.newArrayList();
|
||||||
for (CallableMemberDescriptor callable : callables) {
|
for (CallableMemberDescriptor callable : callables) {
|
||||||
messages.add(descriptorSerializer.callableProto(callable).build());
|
messages.add(serializer.callableProto(callable).build());
|
||||||
}
|
}
|
||||||
|
|
||||||
NameSerializationUtil.serializeNameTable(serializedCallables, descriptorSerializer.getNameTable());
|
ByteArrayOutputStream serializedCallables = new ByteArrayOutputStream();
|
||||||
|
serializeNameTable(serializedCallables, serializer.getNameTable());
|
||||||
|
|
||||||
for (MessageLite message : messages) {
|
for (MessageLite message : messages) {
|
||||||
message.writeDelimitedTo(serializedCallables);
|
message.writeDelimitedTo(serializedCallables);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return serializedCallables.toByteArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void serializeClasses(Collection<ClassDescriptor> classes, Map<ClassDescriptor, byte[]> serializedClasses)
|
@NotNull
|
||||||
throws IOException {
|
private static Map<ClassDescriptor, byte[]> serializeClasses(@NotNull Collection<ClassDescriptor> classes) {
|
||||||
for (ClassDescriptor classDescriptor : classes) {
|
final Map<ClassDescriptor, byte[]> serializedClasses = Maps.newHashMap();
|
||||||
DescriptorSerializer descriptorSerializer = new DescriptorSerializer();
|
final DescriptorSerializer serializer = new DescriptorSerializer();
|
||||||
|
|
||||||
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
|
ClassSerializationUtil.serializeClasses(classes, constantSerializer(serializer), new ClassSerializationUtil.Sink() {
|
||||||
ProtoBuf.Class classProto = descriptorSerializer.classProto(classDescriptor).build();
|
@Override
|
||||||
|
public void writeClass(@NotNull ClassDescriptor classDescriptor, @NotNull ProtoBuf.Class classProto) {
|
||||||
NameSerializationUtil.serializeNameTable(bytes, descriptorSerializer.getNameTable());
|
serializedClasses.put(classDescriptor, new ClassData(createNameResolver(serializer.getNameTable()), classProto).toBytes());
|
||||||
classProto.writeTo(bytes);
|
|
||||||
|
|
||||||
serializedClasses.put(classDescriptor, bytes.toByteArray());
|
|
||||||
|
|
||||||
//noinspection unchecked
|
|
||||||
serializeClasses((Collection) classDescriptor.getUnsubstitutedInnerClassesScope().getAllDescriptors(), serializedClasses);
|
|
||||||
//noinspection unchecked
|
|
||||||
serializeClasses((Collection) classDescriptor.getUnsubstitutedInnerClassesScope().getObjectDescriptors(), serializedClasses);
|
|
||||||
|
|
||||||
ClassDescriptor classObjectDescriptor = classDescriptor.getClassObjectDescriptor();
|
|
||||||
if (classObjectDescriptor != null) {
|
|
||||||
serializeClasses(Collections.singletonList(classObjectDescriptor), serializedClasses);
|
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
}
|
|
||||||
|
|
||||||
private static class ClassMetadata {
|
return serializedClasses;
|
||||||
private final ProtoBuf.SimpleNameTable simpleNames;
|
|
||||||
private final ProtoBuf.QualifiedNameTable qualifiedNames;
|
|
||||||
private final ProtoBuf.Class classProto;
|
|
||||||
|
|
||||||
private ClassMetadata(
|
|
||||||
ProtoBuf.SimpleNameTable simpleNames,
|
|
||||||
ProtoBuf.QualifiedNameTable qualifiedNames,
|
|
||||||
ProtoBuf.Class classProto
|
|
||||||
) {
|
|
||||||
this.simpleNames = simpleNames;
|
|
||||||
this.qualifiedNames = qualifiedNames;
|
|
||||||
this.classProto = classProto;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class DescriptorFinderImpl implements DescriptorFinder {
|
private static class DescriptorFinderImpl implements DescriptorFinder {
|
||||||
private final DescriptorFinder parentResolver;
|
private final DescriptorFinder parentResolver;
|
||||||
|
|
||||||
private final DeclarationDescriptor parentForClasses;
|
private final DeclarationDescriptor parentForClasses;
|
||||||
private final NullableFunction<String, ClassMetadata> classMetadata;
|
private final NullableFunction<String, ClassData> classData;
|
||||||
|
|
||||||
private final MemoizedFunctionToNullable<ClassId, ClassDescriptor> classes;
|
private final MemoizedFunctionToNullable<ClassId, ClassDescriptor> classes;
|
||||||
|
|
||||||
public DescriptorFinderImpl(
|
public DescriptorFinderImpl(
|
||||||
@NotNull DescriptorFinder parentResolver,
|
@NotNull DescriptorFinder parentResolver,
|
||||||
@NotNull DeclarationDescriptor parentForClasses,
|
@NotNull DeclarationDescriptor parentForClasses,
|
||||||
@NotNull NullableFunction<String, ClassMetadata> classMetadata
|
@NotNull NullableFunction<String, ClassData> classData
|
||||||
) {
|
) {
|
||||||
this.parentResolver = parentResolver;
|
this.parentResolver = parentResolver;
|
||||||
|
|
||||||
this.parentForClasses = parentForClasses;
|
this.parentForClasses = parentForClasses;
|
||||||
|
|
||||||
this.classMetadata = classMetadata;
|
this.classData = classData;
|
||||||
|
|
||||||
this.classes = new MemoizedFunctionToNullableImpl<ClassId, ClassDescriptor>() {
|
this.classes = new MemoizedFunctionToNullableImpl<ClassId, ClassDescriptor>() {
|
||||||
@Nullable
|
@Nullable
|
||||||
@@ -305,21 +271,14 @@ public abstract class AbstractDescriptorSerializationTest extends KotlinTestWith
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private ClassDescriptor resolveClass(
|
private ClassDescriptor resolveClass(@NotNull DeclarationDescriptor containingDeclaration, @NotNull ClassId classId) {
|
||||||
@NotNull DeclarationDescriptor containingDeclaration,
|
ClassData classData = this.classData.fun(classId.asSingleFqName().asString());
|
||||||
@NotNull ClassId classId
|
if (classData == null) {
|
||||||
) {
|
|
||||||
FqNameUnsafe fqName = classId.asSingleFqName();
|
|
||||||
|
|
||||||
ClassMetadata classMetadata = this.classMetadata.fun(fqName.asString());
|
|
||||||
if (classMetadata == null) {
|
|
||||||
return parentResolver.findClass(classId);
|
return parentResolver.findClass(classId);
|
||||||
}
|
}
|
||||||
|
|
||||||
NameResolver nameResolver = new NameResolver(classMetadata.simpleNames, classMetadata.qualifiedNames);
|
return new DeserializedClassDescriptor(classId, new LockBasedStorageManager(), containingDeclaration,
|
||||||
return new DeserializedClassDescriptor(classId, new LockBasedStorageManager(), containingDeclaration, nameResolver,
|
classData.getNameResolver(), DUMMY_ANNOTATION_DESERIALIZER, this, classData.getClassProto(), null);
|
||||||
DUMMY_ANNOTATION_DESERIALIZER, this,
|
|
||||||
classMetadata.classProto, null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
|
|||||||
Reference in New Issue
Block a user