Write java signature of serialized descriptors efficiently

Instead of storing a string with the signature, write the name, return type and
parameter types separately, reusing the name table. Refactor the name table to
allow it to store not only names of Kotlin entities, but also arbitrary names
and fq-names
This commit is contained in:
Alexander Udalov
2013-07-11 17:12:01 +04:00
parent eee9bb5a12
commit 453b0e8f10
13 changed files with 1841 additions and 76 deletions
@@ -37,6 +37,7 @@ import java.util.List;
import static org.jetbrains.jet.descriptors.serialization.ProtoBuf.Callable;
import static org.jetbrains.jet.descriptors.serialization.ProtoBuf.TypeParameter;
import static org.jetbrains.jet.descriptors.serialization.TypeDeserializer.TypeParameterResolver.NONE;
import static org.jetbrains.jet.descriptors.serialization.descriptors.AnnotationDeserializer.AnnotatedCallableKind;
public class DescriptorDeserializer {
@@ -153,7 +154,7 @@ public class DescriptorDeserializer {
boolean isNotDefault = proto.hasGetterFlags() && Flags.IS_NOT_DEFAULT.get(getterFlags);
if (isNotDefault) {
getter = new PropertyGetterDescriptorImpl(
property, Collections.<AnnotationDescriptor>emptyList(),
property, getAnnotations(proto, getterFlags, AnnotatedCallableKind.PROPERTY_GETTER),
modality(Flags.MODALITY.get(getterFlags)), visibility(Flags.VISIBILITY.get(getterFlags)),
isNotDefault, !isNotDefault, property.getKind()
);
@@ -169,7 +170,7 @@ public class DescriptorDeserializer {
boolean isNotDefault = proto.hasSetterFlags() && Flags.IS_NOT_DEFAULT.get(setterFlags);
if (isNotDefault) {
setter = new PropertySetterDescriptorImpl(
property, getAnnotations(proto, setterFlags),
property, getAnnotations(proto, setterFlags, AnnotatedCallableKind.PROPERTY_SETTER),
modality(Flags.MODALITY.get(setterFlags)), visibility(Flags.VISIBILITY.get(setterFlags)),
isNotDefault, !isNotDefault, property.getKind()
);
@@ -192,7 +193,7 @@ public class DescriptorDeserializer {
private PropertyDescriptorImpl createPropertyDescriptor(@NotNull Callable proto) {
int flags = proto.getFlags();
Name name = nameResolver.getName(proto.getName());
List<AnnotationDescriptor> annotations = getAnnotations(proto, proto.getFlags());
List<AnnotationDescriptor> annotations = Collections.emptyList(); // TODO: getAnnotations(proto, flags, PROPERTY);
Visibility visibility = visibility(Flags.VISIBILITY.get(flags));
Callable.CallableKind callableKind = Flags.CALLABLE_KIND.get(flags);
@@ -221,7 +222,7 @@ public class DescriptorDeserializer {
int flags = proto.getFlags();
SimpleFunctionDescriptorImpl function = new SimpleFunctionDescriptorImpl(
containingDeclaration,
getAnnotations(proto, proto.getFlags()),
getAnnotations(proto, proto.getFlags(), AnnotatedCallableKind.FUNCTION),
nameResolver.getName(proto.getName()),
memberKind(Flags.MEMBER_KIND.get(flags))
);
@@ -252,7 +253,7 @@ public class DescriptorDeserializer {
ClassDescriptor classDescriptor = (ClassDescriptor) containingDeclaration;
ConstructorDescriptorImpl descriptor = new ConstructorDescriptorImpl(
classDescriptor,
getAnnotations(proto, proto.getFlags()),
getAnnotations(proto, proto.getFlags(), AnnotatedCallableKind.FUNCTION),
// TODO: primary
true);
List<TypeParameterDescriptor> typeParameters = new ArrayList<TypeParameterDescriptor>(proto.getTypeParameterCount());
@@ -268,11 +269,12 @@ public class DescriptorDeserializer {
}
@NotNull
private List<AnnotationDescriptor> getAnnotations(@NotNull Callable proto, int flags) {
private List<AnnotationDescriptor> getAnnotations(@NotNull Callable proto, int flags, @NotNull AnnotatedCallableKind kind) {
assert containingDeclaration instanceof ClassOrNamespaceDescriptor
: "Only members in classes or namespaces should be serialized: " + containingDeclaration;
return Flags.HAS_ANNOTATIONS.get(flags)
? annotationDeserializer.loadCallableAnnotations((ClassOrNamespaceDescriptor) containingDeclaration, proto)
? annotationDeserializer
.loadCallableAnnotations((ClassOrNamespaceDescriptor) containingDeclaration, proto, nameResolver, kind)
: Collections.<AnnotationDescriptor>emptyList();
}
@@ -212,7 +212,7 @@ public class DescriptorSerializer {
builder.setReturnType(local.type(getSerializableReturnType(descriptor.getReturnType())));
extension.serializeCallable(descriptor, builder);
extension.serializeCallable(descriptor, builder, nameTable);
return builder;
}
@@ -76,11 +76,7 @@ public class NameResolver {
}
@Nullable
private QualifiedName renderFqName(
StringBuilder sb,
QualifiedName fqNameProto,
QualifiedName.Kind kind
) {
private QualifiedName renderFqName(StringBuilder sb, QualifiedName fqNameProto, QualifiedName.Kind kind) {
QualifiedName result = null;
if (fqNameProto.hasParentQualifiedName()) {
QualifiedName parentProto = qualifiedNames.getQualifiedName(fqNameProto.getParentQualifiedName());
@@ -95,4 +91,14 @@ public class NameResolver {
sb.append(simpleNames.getName(fqNameProto.getShortName()));
return result;
}
@NotNull
public FqName getFqName(int index) {
QualifiedName qualifiedName = qualifiedNames.getQualifiedName(index);
Name shortName = getName(qualifiedName.getShortName());
if (!qualifiedName.hasParentQualifiedName()) {
return FqName.topLevel(shortName);
}
return getFqName(qualifiedName.getParentQualifiedName()).child(shortName);
}
}
@@ -19,10 +19,11 @@ package org.jetbrains.jet.descriptors.serialization;
import gnu.trove.TObjectHashingStrategy;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.ClassOrNamespaceDescriptor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
import org.jetbrains.jet.lang.descriptors.impl.NamespaceDescriptorParent;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.name.Name;
import java.util.List;
@@ -42,9 +43,7 @@ public class NameTable {
}
@Override
public boolean equals(
QualifiedName.Builder o1, QualifiedName.Builder o2
) {
public boolean equals(QualifiedName.Builder o1, QualifiedName.Builder o2) {
return o1.getParentQualifiedName() == o2.getParentQualifiedName()
&& o1.getShortName() == o2.getShortName()
&& o1.getKind() == o2.getKind();
@@ -71,18 +70,17 @@ public class NameTable {
return simpleNames.intern(name.asString());
}
public int getFqNameIndex(@NotNull ClassDescriptor classDescriptor) {
public int getFqNameIndex(@NotNull ClassOrNamespaceDescriptor descriptor) {
QualifiedName.Builder builder = QualifiedName.newBuilder();
builder.setKind(QualifiedName.Kind.CLASS);
builder.setShortName(getSimpleNameIndex(classDescriptor.getName()));
if (descriptor instanceof ClassDescriptor) {
builder.setKind(QualifiedName.Kind.CLASS);
}
builder.setShortName(getSimpleNameIndex(descriptor.getName()));
DeclarationDescriptor containingDeclaration = classDescriptor.getContainingDeclaration();
DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration();
if (containingDeclaration instanceof NamespaceDescriptor) {
NamespaceDescriptor namespaceDescriptor = (NamespaceDescriptor) containingDeclaration;
if (DescriptorUtils.isRootNamespace(namespaceDescriptor)) {
builder.clearParentQualifiedName();
}
else {
if (!DescriptorUtils.isRootNamespace(namespaceDescriptor)) {
builder.setParentQualifiedName(getFqNameIndex(namespaceDescriptor));
}
}
@@ -91,28 +89,22 @@ public class NameTable {
builder.setParentQualifiedName(getFqNameIndex(outerClass));
}
else {
throw new IllegalStateException("FQ names are only stored for top-level or inner classes: " + classDescriptor);
throw new IllegalStateException("FQ names are only stored for top-level or inner classes: " + descriptor);
}
return qualifiedNames.intern(builder);
}
public int getFqNameIndex(@NotNull NamespaceDescriptor namespaceDescriptor) {
QualifiedName.Builder builder = QualifiedName.newBuilder();
//default: builder.setKind(QualifiedNameTable.QualifiedName.Kind.PACKAGE);
builder.setShortName(getSimpleNameIndex(namespaceDescriptor.getName()));
NamespaceDescriptorParent containingDeclaration = namespaceDescriptor.getContainingDeclaration();
if (containingDeclaration instanceof NamespaceDescriptor) {
NamespaceDescriptor parentNamespace = (NamespaceDescriptor) containingDeclaration;
if (!DescriptorUtils.isRootNamespace(parentNamespace)) {
builder.setParentQualifiedName(getFqNameIndex(parentNamespace));
public int getFqNameIndex(@NotNull FqName fqName) {
int result = -1;
for (Name segment : fqName.pathSegments()) {
QualifiedName.Builder builder = QualifiedName.newBuilder();
builder.setShortName(getSimpleNameIndex(segment));
if (result != -1) {
builder.setParentQualifiedName(result);
}
result = qualifiedNames.intern(builder);
}
else {
builder.clearParentQualifiedName();
}
return qualifiedNames.intern(builder);
return result;
}
}
@@ -27,6 +27,10 @@ public abstract class SerializerExtension {
return true;
}
public void serializeCallable(@NotNull CallableMemberDescriptor callable, @NotNull ProtoBuf.Callable.Builder proto) {
public void serializeCallable(
@NotNull CallableMemberDescriptor callable,
@NotNull ProtoBuf.Callable.Builder proto,
@NotNull NameTable nameTable
) {
}
}
@@ -1,6 +1,7 @@
package org.jetbrains.jet.descriptors.serialization.descriptors;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.descriptors.serialization.NameResolver;
import org.jetbrains.jet.descriptors.serialization.ProtoBuf;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.ClassOrNamespaceDescriptor;
@@ -19,7 +20,10 @@ public interface AnnotationDeserializer {
@NotNull
@Override
public List<AnnotationDescriptor> loadCallableAnnotations(
@NotNull ClassOrNamespaceDescriptor container, @NotNull ProtoBuf.Callable callableProto
@NotNull ClassOrNamespaceDescriptor container,
@NotNull ProtoBuf.Callable proto,
@NotNull NameResolver nameResolver,
@NotNull AnnotatedCallableKind kind
) {
return notSupported();
}
@@ -30,18 +34,27 @@ public interface AnnotationDeserializer {
return notSupported();
}
@NotNull
private List<AnnotationDescriptor> notSupported() {
throw new UnsupportedOperationException("Annotations are not supported");
}
};
enum AnnotatedCallableKind {
FUNCTION,
PROPERTY_GETTER,
PROPERTY_SETTER
}
@NotNull
List<AnnotationDescriptor> loadClassAnnotations(@NotNull ClassDescriptor descriptor, @NotNull ProtoBuf.Class classProto);
@NotNull
List<AnnotationDescriptor> loadCallableAnnotations(
@NotNull ClassOrNamespaceDescriptor container,
@NotNull ProtoBuf.Callable callableProto
@NotNull ProtoBuf.Callable proto,
@NotNull NameResolver nameResolver,
@NotNull AnnotatedCallableKind kind
);
@NotNull