Deserialize annotations from package$src files if needed

For top-level members, we now write a FQ name of the package$src class which
has the member's annotations, and read the correct file in deserialization
This commit is contained in:
Alexander Udalov
2013-07-15 19:38:49 +04:00
parent e63a087ee5
commit cfe9d78015
16 changed files with 181 additions and 13 deletions
@@ -46,6 +46,7 @@ import org.jetbrains.jet.lang.resolve.java.JvmAbi;
import org.jetbrains.jet.lang.resolve.java.JvmClassName;
import org.jetbrains.jet.lang.resolve.java.JvmStdlibNames;
import org.jetbrains.jet.lang.resolve.java.kt.DescriptorKindUtils;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.name.Name;
import java.util.*;
@@ -112,7 +113,15 @@ public class FunctionCodegen extends GenerationStateAware {
asmMethod.getDescriptor(),
jvmSignature.getGenericsSignature(),
null);
v.getMemberMap().recordMethodOfDescriptor(functionDescriptor, asmMethod);
OwnerKind contextKind = owner.getContextKind();
if (contextKind instanceof OwnerKind.StaticDelegateKind) {
FqName fqName = ((OwnerKind.StaticDelegateKind) contextKind).getOwnerClass().getFqName();
v.getMemberMap().recordSrcClassNameForCallable(functionDescriptor, fqName.shortName());
}
else {
v.getMemberMap().recordMethodOfDescriptor(functionDescriptor, asmMethod);
}
AnnotationCodegen.forMethod(mv, typeMapper).genAnnotations(functionDescriptor);
if (state.getClassBuilderMode() == ClassBuilderMode.SIGNATURES) return;
@@ -25,6 +25,7 @@ import org.jetbrains.jet.descriptors.serialization.NameTable;
import org.jetbrains.jet.descriptors.serialization.ProtoBuf;
import org.jetbrains.jet.descriptors.serialization.SerializerExtension;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.resolve.name.Name;
public class JavaSerializerExtension extends SerializerExtension {
private final MemberMap memberMap;
@@ -38,9 +39,18 @@ public class JavaSerializerExtension extends SerializerExtension {
@NotNull CallableMemberDescriptor callable,
@NotNull ProtoBuf.Callable.Builder proto,
@NotNull NameTable nameTable
) {
saveSignature(callable, proto, nameTable);
saveSrcClassName(callable, proto, nameTable);
}
private void saveSignature(
@NotNull CallableMemberDescriptor callable,
@NotNull ProtoBuf.Callable.Builder proto,
@NotNull NameTable nameTable
) {
if (callable instanceof FunctionDescriptor) {
Method method = memberMap.getMethodOfDescriptor(callable);
Method method = memberMap.getMethodOfDescriptor((FunctionDescriptor) callable);
if (method != null) {
JavaProtoBufUtil.saveMethodSignature(proto, method, nameTable);
}
@@ -71,4 +81,15 @@ public class JavaSerializerExtension extends SerializerExtension {
JavaProtoBufUtil.savePropertySignature(proto, fieldType, fieldName, syntheticMethodName, getterMethod, setterMethod, nameTable);
}
}
private void saveSrcClassName(
@NotNull CallableMemberDescriptor callable,
@NotNull ProtoBuf.Callable.Builder proto,
@NotNull NameTable nameTable
) {
Name name = memberMap.getSrcClassNameOfCallable(callable);
if (name != null) {
JavaProtoBufUtil.saveSrcClassName(proto, name, nameTable);
}
}
}
@@ -22,22 +22,25 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.Method;
import org.jetbrains.jet.lang.descriptors.CallableMemberDescriptor;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
import org.jetbrains.jet.lang.resolve.name.Name;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
public final class MemberMap {
private final Map<CallableMemberDescriptor, Method> methodForFunction = new HashMap<CallableMemberDescriptor, Method>();
private final Map<FunctionDescriptor, Method> methodForFunction = new HashMap<FunctionDescriptor, Method>();
private final Map<PropertyDescriptor, Pair<Type, String>> fieldForProperty = new HashMap<PropertyDescriptor, Pair<Type, String>>();
private final Map<PropertyDescriptor, String> syntheticMethodNameForProperty = new HashMap<PropertyDescriptor, String>();
private final Map<CallableMemberDescriptor, Name> srcClassNameForCallable = new HashMap<CallableMemberDescriptor, Name>();
@NotNull
public static MemberMap union(@NotNull Collection<MemberMap> maps) {
MemberMap result = new MemberMap();
for (MemberMap map : maps) {
for (Map.Entry<CallableMemberDescriptor, Method> entry : map.methodForFunction.entrySet()) {
for (Map.Entry<FunctionDescriptor, Method> entry : map.methodForFunction.entrySet()) {
result.recordMethodOfDescriptor(entry.getKey(), entry.getValue());
}
@@ -48,12 +51,16 @@ public final class MemberMap {
for (Map.Entry<PropertyDescriptor, String> entry : map.syntheticMethodNameForProperty.entrySet()) {
result.recordSyntheticMethodNameOfProperty(entry.getKey(), entry.getValue());
}
for (Map.Entry<CallableMemberDescriptor, Name> entry : map.srcClassNameForCallable.entrySet()) {
result.recordSrcClassNameForCallable(entry.getKey(), entry.getValue());
}
}
return result;
}
public void recordMethodOfDescriptor(@NotNull CallableMemberDescriptor descriptor, @NotNull Method method) {
public void recordMethodOfDescriptor(@NotNull FunctionDescriptor descriptor, @NotNull Method method) {
Method old = methodForFunction.put(descriptor, method);
assert old == null : "Duplicate method for callable member: " + descriptor + "; " + old;
}
@@ -68,8 +75,13 @@ public final class MemberMap {
assert old == null : "Duplicate synthetic method for property: " + descriptor + "; " + old;
}
public void recordSrcClassNameForCallable(@NotNull CallableMemberDescriptor descriptor, @NotNull Name name) {
Name old = srcClassNameForCallable.put(descriptor, name);
assert old == null : "Duplicate src class name for callable: " + descriptor + "; " + old;
}
@Nullable
public Method getMethodOfDescriptor(@NotNull CallableMemberDescriptor descriptor) {
public Method getMethodOfDescriptor(@NotNull FunctionDescriptor descriptor) {
return methodForFunction.get(descriptor);
}
@@ -83,10 +95,16 @@ public final class MemberMap {
return syntheticMethodNameForProperty.get(descriptor);
}
@Nullable
public Name getSrcClassNameOfCallable(@NotNull CallableMemberDescriptor descriptor) {
return srcClassNameForCallable.get(descriptor);
}
@Override
public String toString() {
return "Functions: " + methodForFunction.size() +
", fields: " + fieldForProperty.size() +
", synthetic methods: " + syntheticMethodNameForProperty.size();
", synthetic methods: " + syntheticMethodNameForProperty.size() +
", src class names: " + srcClassNameForCallable.size();
}
}
@@ -99,14 +99,17 @@ public class NamespaceCodegen extends MemberCodegen {
}
public void generate(@NotNull CompilationErrorHandler errorHandler) {
List<MemberMap> namespaceMembers = new ArrayList<MemberMap>(files.size() + 1);
if (shouldGenerateNSClass(files)) {
AnnotationVisitor packageClassAnnotation =
v.getClassBuilder().newAnnotation(JvmStdlibNames.JET_PACKAGE_CLASS.getDescriptor(), true);
ClassBuilder cv = v.getClassBuilder();
AnnotationVisitor packageClassAnnotation = cv.newAnnotation(JvmStdlibNames.JET_PACKAGE_CLASS.getDescriptor(), true);
packageClassAnnotation.visit(JvmStdlibNames.ABI_VERSION_NAME, JvmAbi.VERSION);
packageClassAnnotation.visitEnd();
}
List<MemberMap> namespaceMembers = new ArrayList<MemberMap>();
namespaceMembers.add(cv.getMemberMap());
}
for (JetFile file : files) {
try {
@@ -42,6 +42,7 @@ import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
import org.jetbrains.jet.lang.resolve.java.JvmAbi;
import org.jetbrains.jet.lang.resolve.java.JvmStdlibNames;
import org.jetbrains.jet.lang.resolve.java.kt.DescriptorKindUtils;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.types.ErrorUtils;
import org.jetbrains.jet.lang.types.JetType;
@@ -88,9 +89,14 @@ public class PropertyCodegen extends GenerationStateAware {
assert kind instanceof OwnerKind.StaticDelegateKind || kind == OwnerKind.NAMESPACE || kind == OwnerKind.IMPLEMENTATION || kind == OwnerKind.TRAIT_IMPL
: "Generating property with a wrong kind (" + kind + "): " + propertyDescriptor;
if (kind != OwnerKind.TRAIT_IMPL && !(kind instanceof OwnerKind.StaticDelegateKind)) {
if (kind instanceof OwnerKind.StaticDelegateKind) {
FqName fqName = ((OwnerKind.StaticDelegateKind) kind).getOwnerClass().getFqName();
v.getMemberMap().recordSrcClassNameForCallable(propertyDescriptor, fqName.shortName());
}
else if (kind != OwnerKind.TRAIT_IMPL) {
generateBackingField(p, propertyDescriptor);
}
generateGetter(p, propertyDescriptor, p.getGetter());
generateSetter(p, propertyDescriptor, p.getSetter());