Serialize properties for objects

A new special CallableKind for properties created for objects --
OBJECT_PROPERTY.
Also fix PropertyPsiData.isFinal() in case of properties backed by fields
This commit is contained in:
Alexander Udalov
2013-07-03 20:34:09 +04:00
parent a57f74c278
commit 011f733aad
46 changed files with 85 additions and 39 deletions
@@ -199,10 +199,10 @@ public final class PropertyPsiData {
if (getter != null) {
return getter.getMember().isFinal();
}
if (setter != null) {
return setter.getMember().isFinal();
}
return false;
assert field != null : "Property with no getter and no setter should at least have a backing field";
return field.getMember().isFinal();
}
}
Binary file not shown.
@@ -1,4 +1,4 @@
 H2
R Â0B
Z Ć0IB
Z Ć 0IB

@@ -1,4 +1,4 @@
 N2
R Â0B
"Z Ć0IB
"Z Ć 0IB

@@ -1,4 +1,4 @@
 a2
R Â0B
*Z Æ0IB
*Z Æ 0IB

@@ -1,4 +1,4 @@
 ®2
R В0B
/Z Ж0IB
/Z Ж 0IB

Binary file not shown.
Binary file not shown.
@@ -1,4 +1,4 @@
 Î2
R Â0B
3Z Ć0IB
3Z Ć 0IB

@@ -1,4 +1,4 @@
 Ґ2
R В0B
fZ Ж0IB
fZ Ж 0IB

@@ -1,3 +1,3 @@
f É2
Z ć0cB
Z ć 0cB
#
Binary file not shown.
@@ -1,4 +1,4 @@
 Ο2
R Β0B
xZ Ζ0IB
xZ Ζ 0IB

Binary file not shown.
@@ -1,4 +1,4 @@
 ×2
R Â0B
{Z ĆB
{Z Ć B

@@ -144,11 +144,12 @@ message Callable {
}
enum CallableKind {
// 2 bits
// 3 bits
FUN = 0;
VAL = 1;
VAR = 2;
CONSTRUCTOR = 3;
OBJECT_PROPERTY = 4;
}
/*
@@ -1,7 +1,5 @@
package org.jetbrains.jet.descriptors.serialization;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.ClassOrNamespaceDescriptor;
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
@@ -20,23 +18,23 @@ public final class ClassId {
public static ClassId fromFqNameAndContainingDeclaration(
@NotNull FqName fqName,
@NotNull ClassOrNamespaceDescriptor containingDeclaration
) {
return fromFqNameAndContainingDeclaration(fqName.toUnsafe(), containingDeclaration);
}
@NotNull
public static ClassId fromFqNameAndContainingDeclaration(
@NotNull FqNameUnsafe fqName,
@NotNull ClassOrNamespaceDescriptor containingDeclaration
) {
NamespaceDescriptor containingNamespace = DescriptorUtils.getParentOfType(containingDeclaration, NamespaceDescriptor.class, false);
assert containingNamespace != null;
List<Name> fullNameSegments = fqName.pathSegments();
FqName namespaceFqName = DescriptorUtils.getFQName(containingNamespace).toSafe();
List<Name> namespaceNameSegments = namespaceFqName.pathSegments();
for (int i = 0; i < namespaceNameSegments.size(); ++i) {
assert fullNameSegments.get(i).equals(namespaceNameSegments.get(i));
}
assert fullNameSegments.subList(0, namespaceNameSegments.size()).equals(namespaceNameSegments);
List<Name> relativeNameSegments = fullNameSegments.subList(namespaceNameSegments.size(), fullNameSegments.size());
FqName relativeFqName = FqName.fromSegments(ContainerUtil.map2List(relativeNameSegments, new Function<Name, String>() {
@Override
public String fun(Name name) {
return name.asString();
}
}));
return new ClassId(namespaceFqName, relativeFqName.toUnsafe());
return new ClassId(namespaceFqName, FqNameUnsafe.fromSegments(relativeNameSegments));
}
public ClassId(@NotNull FqName packageFqName, @NotNull FqNameUnsafe relativeClassName) {
@@ -24,7 +24,10 @@ import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.descriptors.impl.*;
import org.jetbrains.jet.lang.resolve.DescriptorResolver;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.lazy.storage.StorageManager;
import org.jetbrains.jet.lang.resolve.name.FqNameUnsafe;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.types.Variance;
import java.util.ArrayList;
@@ -121,6 +124,7 @@ public class DescriptorDeserializer {
return loadFunction(proto);
case VAL:
case VAR:
case OBJECT_PROPERTY:
return loadProperty(proto);
case CONSTRUCTOR:
return loadConstructor(proto);
@@ -130,16 +134,8 @@ public class DescriptorDeserializer {
@NotNull
private PropertyDescriptor loadProperty(@NotNull Callable proto) {
int flags = proto.getFlags();
PropertyDescriptorImpl property = new PropertyDescriptorImpl(
containingDeclaration,
getAnnotations(proto),
modality(Flags.MODALITY.get(flags)),
visibility(Flags.VISIBILITY.get(flags)),
Flags.CALLABLE_KIND.get(flags) == Callable.CallableKind.VAR,
nameResolver.getName(proto.getName()),
memberKind(Flags.MEMBER_KIND.get(flags))
);
PropertyDescriptorImpl property = createPropertyDescriptor(proto);
List<TypeParameterDescriptor> typeParameters = new ArrayList<TypeParameterDescriptor>(proto.getTypeParameterCount());
DescriptorDeserializer local = createChildDeserializer(property, proto.getTypeParameterList(), typeParameters);
property.setType(
@@ -152,7 +148,7 @@ public class DescriptorDeserializer {
PropertyGetterDescriptorImpl getter = null;
PropertySetterDescriptorImpl setter = null;
if (Flags.HAS_GETTER.get(flags)) {
if (Flags.HAS_GETTER.get(proto.getFlags())) {
int getterFlags = proto.getGetterFlags();
boolean isNotDefault = proto.hasGetterFlags() && Flags.IS_NOT_DEFAULT.get(getterFlags);
if (isNotDefault) {
@@ -168,7 +164,7 @@ public class DescriptorDeserializer {
getter.initialize(property.getReturnType());
}
if (Flags.HAS_SETTER.get(flags)) {
if (Flags.HAS_SETTER.get(proto.getFlags())) {
int setterFlags = proto.getSetterFlags();
boolean isNotDefault = proto.hasSetterFlags() && Flags.IS_NOT_DEFAULT.get(setterFlags);
if (isNotDefault) {
@@ -192,6 +188,36 @@ public class DescriptorDeserializer {
return property;
}
@NotNull
private PropertyDescriptorImpl createPropertyDescriptor(@NotNull Callable proto) {
int flags = proto.getFlags();
Name name = nameResolver.getName(proto.getName());
List<AnnotationDescriptor> annotations = getAnnotations(proto);
Visibility visibility = visibility(Flags.VISIBILITY.get(flags));
Callable.CallableKind callableKind = Flags.CALLABLE_KIND.get(flags);
if (callableKind == Callable.CallableKind.OBJECT_PROPERTY) {
assert containingDeclaration instanceof ClassOrNamespaceDescriptor
: "Properties for objects can only exist in class or namespace: " + name;
FqNameUnsafe fqName = DescriptorUtils.getFQName(containingDeclaration).child(name);
ClassId objectId = ClassId.fromFqNameAndContainingDeclaration(fqName, (ClassOrNamespaceDescriptor) containingDeclaration);
ClassDescriptor objectClass = typeDeserializer.getDescriptorFinder().findClass(objectId);
assert objectClass != null : "Object for property not found: " + name;
return new PropertyDescriptorForObjectImpl(containingDeclaration, annotations, visibility, name, objectClass);
}
return new PropertyDescriptorImpl(
containingDeclaration,
annotations,
modality(Flags.MODALITY.get(flags)),
visibility,
callableKind == Callable.CallableKind.VAR,
name,
memberKind(Flags.MEMBER_KIND.get(flags))
);
}
@NotNull
private CallableMemberDescriptor loadFunction(@NotNull Callable proto) {
int flags = proto.getFlags();
@@ -256,7 +256,10 @@ public class DescriptorSerializer {
}
private static ProtoBuf.Callable.CallableKind callableKind(CallableMemberDescriptor descriptor) {
if (descriptor instanceof PropertyDescriptor) {
if (descriptor instanceof VariableDescriptorForObject) {
return ProtoBuf.Callable.CallableKind.OBJECT_PROPERTY;
}
else if (descriptor instanceof PropertyDescriptor) {
PropertyDescriptor propertyDescriptor = (PropertyDescriptor) descriptor;
return propertyDescriptor.isVar() ? ProtoBuf.Callable.CallableKind.VAR : ProtoBuf.Callable.CallableKind.VAL;
}
@@ -5380,12 +5380,14 @@ public final class ProtoBuf {
VAL(1, 1),
VAR(2, 2),
CONSTRUCTOR(3, 3),
OBJECT_PROPERTY(4, 4),
;
public static final int FUN_VALUE = 0;
public static final int VAL_VALUE = 1;
public static final int VAR_VALUE = 2;
public static final int CONSTRUCTOR_VALUE = 3;
public static final int OBJECT_PROPERTY_VALUE = 4;
public final int getNumber() { return value; }
@@ -5396,6 +5398,7 @@ public final class ProtoBuf {
case 1: return VAL;
case 2: return VAR;
case 3: return CONSTRUCTOR;
case 4: return OBJECT_PROPERTY;
default: return null;
}
}
@@ -100,6 +100,10 @@ public class TypeDeserializer {
}, STRONG);
}
/* package */ DescriptorFinder getDescriptorFinder() {
return descriptorFinder;
}
@Nullable
public JetType typeOrNull(@Nullable ProtoBuf.Type proto) {
if (proto == null) {
@@ -24,7 +24,9 @@ import org.jetbrains.jet.descriptors.serialization.DescriptorDeserializer;
import org.jetbrains.jet.descriptors.serialization.Flags;
import org.jetbrains.jet.descriptors.serialization.ProtoBuf;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.resolve.lazy.storage.*;
import org.jetbrains.jet.lang.resolve.lazy.storage.MemoizedFunctionToNotNull;
import org.jetbrains.jet.lang.resolve.lazy.storage.NotNullLazyValue;
import org.jetbrains.jet.lang.resolve.lazy.storage.StorageManager;
import org.jetbrains.jet.lang.resolve.name.LabelName;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
@@ -44,7 +46,9 @@ public abstract class DeserializedMemberScope implements JetScope {
private static final Filter<ProtoBuf.Callable.CallableKind> PROPERTY = new Filter<ProtoBuf.Callable.CallableKind>() {
@Override
public boolean accept(ProtoBuf.Callable.CallableKind value) {
return value == ProtoBuf.Callable.CallableKind.VAL || value == ProtoBuf.Callable.CallableKind.VAR;
return value == ProtoBuf.Callable.CallableKind.VAL ||
value == ProtoBuf.Callable.CallableKind.VAR ||
value == ProtoBuf.Callable.CallableKind.OBJECT_PROPERTY;
}
};
@@ -17,6 +17,7 @@
package org.jetbrains.jet.lang.resolve.name;
import com.google.common.collect.Lists;
import com.intellij.openapi.util.text.StringUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -250,6 +251,12 @@ public final class FqNameUnsafe extends FqNameBase {
return shortName().equals(segment);
}
@NotNull
public static FqNameUnsafe fromSegments(@NotNull List<Name> names) {
String fqName = StringUtil.join(names, ".");
return new FqNameUnsafe(fqName);
}
@NotNull