Don't serialize non-serializable types

If there's a private property in a class which has a type of some local
class/object, write its type as jet.Any (otherwise there's no obvious way to
construct a FQ name of such type)
This commit is contained in:
Alexander Udalov
2013-06-27 18:33:28 +04:00
parent 1acc1564d9
commit 2841238567
3 changed files with 49 additions and 8 deletions
@@ -22,10 +22,13 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.annotations.Annotated;
import org.jetbrains.jet.lang.types.*;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import org.jetbrains.jet.renderer.DescriptorRenderer;
import java.util.*;
import static org.jetbrains.jet.lang.resolve.DescriptorUtils.isTopLevelOrInnerClass;
public class DescriptorSerializer {
private static final DescriptorRenderer RENDERER = DescriptorRenderer.STARTS_FROM_NAME;
@@ -193,11 +196,40 @@ public class DescriptorSerializer {
builder.addValueParameters(local.valueParameter(valueParameterDescriptor));
}
builder.setReturnType(local.type(descriptor.getReturnType()));
builder.setReturnType(local.type(getSerializableReturnType(descriptor.getReturnType())));
return builder;
}
@NotNull
private static JetType getSerializableReturnType(@NotNull JetType type) {
return isSerializableType(type) ? type : KotlinBuiltIns.getInstance().getAnyType();
}
/**
* @return true iff this type can be serialized. Types which correspond to type parameters, top-level classes, inner classes, and
* generic classes with serializable arguments are serializable. For other types (local classes, inner of local, etc.) it may be
* problematical to construct a FQ name for serialization
*/
private static boolean isSerializableType(@NotNull JetType type) {
ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor();
if (descriptor instanceof TypeParameterDescriptor) {
return true;
}
else if (descriptor instanceof ClassDescriptor) {
for (TypeProjection projection : type.getArguments()) {
if (!isSerializableType(projection.getType())) {
return false;
}
}
return isTopLevelOrInnerClass((ClassDescriptor) descriptor);
}
else {
throw new IllegalStateException("Unknown type constructor: " + type);
}
}
private static int getAccessorFlags(@NotNull PropertyAccessorDescriptor accessor) {
return Flags.getAccessorFlags(
hasAnnotations(accessor),