Load annotations on properties declared in traits

This commit is contained in:
Alexander Udalov
2013-10-16 21:49:27 +04:00
parent 5a1daaa4b6
commit b7789da3b9
21 changed files with 204 additions and 53 deletions
@@ -35,6 +35,7 @@ import java.util.List;
import static org.jetbrains.asm4.Opcodes.ACC_STATIC;
import static org.jetbrains.asm4.Opcodes.RETURN;
import static org.jetbrains.jet.codegen.binding.CodegenBinding.enumEntryNeedSubclass;
import static org.jetbrains.jet.lang.resolve.DescriptorUtils.isTopLevelOrInnerClass;
public abstract class ClassBodyCodegen extends MemberCodegen {
protected final JetClassOrObject myClass;
@@ -71,13 +72,14 @@ public abstract class ClassBodyCodegen extends MemberCodegen {
generateStaticInitializer();
generateKotlinAnnotation();
if (state.getClassBuilderMode() == ClassBuilderMode.FULL && isTopLevelOrInnerClass(descriptor)) {
generateKotlinAnnotation();
}
}
protected abstract void generateDeclaration();
protected void generateKotlinAnnotation() {
}
protected abstract void generateKotlinAnnotation();
protected abstract void generateSyntheticParts();
@@ -111,7 +111,7 @@ public class FunctionCodegen extends ParentCodegenAwareImpl {
if (owner instanceof NamespaceFacadeContext) {
Type ownerType = ((NamespaceFacadeContext) owner).getDelegateToClassType();
v.getMemberMap().recordSrcClassNameForCallable(functionDescriptor, shortNameByAsmType(ownerType));
v.getMemberMap().recordImplClassNameForCallable(functionDescriptor, shortNameByAsmType(ownerType));
}
else {
v.getMemberMap().recordMethodOfDescriptor(functionDescriptor, asmMethod);
@@ -213,12 +213,6 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
@Override
protected void generateKotlinAnnotation() {
if (state.getClassBuilderMode() != ClassBuilderMode.FULL) {
return;
}
if (!isTopLevelOrInnerClass(descriptor)) return;
DescriptorSerializer serializer = new DescriptorSerializer(new JavaSerializerExtension(v.getMemberMap()));
ProtoBuf.Class classProto = serializer.classProto(descriptor).build();
@@ -45,7 +45,7 @@ public class JavaSerializerExtension extends SerializerExtension {
@NotNull NameTable nameTable
) {
saveSignature(callable, proto, nameTable);
saveSrcClassName(callable, proto, nameTable);
saveImplClassName(callable, proto, nameTable);
}
private void saveSignature(
@@ -91,14 +91,14 @@ public class JavaSerializerExtension extends SerializerExtension {
}
}
private void saveSrcClassName(
private void saveImplClassName(
@NotNull CallableMemberDescriptor callable,
@NotNull ProtoBuf.Callable.Builder proto,
@NotNull NameTable nameTable
) {
String name = memberMap.getSrcClassNameOfCallable(callable);
String name = memberMap.getImplClassNameOfCallable(callable);
if (name != null) {
proto.setExtension(JavaProtoBuf.srcClassName, nameTable.getSimpleNameIndex(Name.identifier(name)));
proto.setExtension(JavaProtoBuf.implClassName, nameTable.getSimpleNameIndex(Name.identifier(name)));
}
}
@@ -31,7 +31,7 @@ public final class MemberMap {
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, Method> syntheticMethodForProperty = new HashMap<PropertyDescriptor, Method>();
private final Map<CallableMemberDescriptor, String> srcClassNameForCallable = new HashMap<CallableMemberDescriptor, String>();
private final Map<CallableMemberDescriptor, String> implClassNameForCallable = new HashMap<CallableMemberDescriptor, String>();
private final Set<PropertyDescriptor> staticFieldInOuterClass = new HashSet<PropertyDescriptor>();
@NotNull
@@ -50,8 +50,8 @@ public final class MemberMap {
result.recordSyntheticMethodOfProperty(entry.getKey(), entry.getValue());
}
for (Map.Entry<CallableMemberDescriptor, String> entry : map.srcClassNameForCallable.entrySet()) {
result.recordSrcClassNameForCallable(entry.getKey(), entry.getValue());
for (Map.Entry<CallableMemberDescriptor, String> entry : map.implClassNameForCallable.entrySet()) {
result.recordImplClassNameForCallable(entry.getKey(), entry.getValue());
}
for (PropertyDescriptor property : map.staticFieldInOuterClass) {
@@ -77,8 +77,8 @@ public final class MemberMap {
assert old == null : "Duplicate synthetic method for property: " + descriptor + "; " + old;
}
public void recordSrcClassNameForCallable(@NotNull CallableMemberDescriptor descriptor, @NotNull String name) {
String old = srcClassNameForCallable.put(descriptor, name);
public void recordImplClassNameForCallable(@NotNull CallableMemberDescriptor descriptor, @NotNull String name) {
String old = implClassNameForCallable.put(descriptor, name);
assert old == null : "Duplicate src class name for callable: " + descriptor + "; " + old;
}
@@ -103,8 +103,8 @@ public final class MemberMap {
}
@Nullable
public String getSrcClassNameOfCallable(@NotNull CallableMemberDescriptor descriptor) {
return srcClassNameForCallable.get(descriptor);
public String getImplClassNameOfCallable(@NotNull CallableMemberDescriptor descriptor) {
return implClassNameForCallable.get(descriptor);
}
public boolean isStaticFieldInOuterClass(@NotNull PropertyDescriptor property) {
@@ -116,6 +116,6 @@ public final class MemberMap {
return "Functions: " + methodForFunction.size() +
", fields: " + fieldForProperty.size() +
", synthetic methods: " + syntheticMethodForProperty.size() +
", src class names: " + srcClassNameForCallable.size();
", impl class names: " + implClassNameForCallable.size();
}
}
@@ -92,7 +92,7 @@ public class PropertyCodegen extends GenerationStateAware {
if (context instanceof NamespaceFacadeContext) {
Type ownerType = ((NamespaceFacadeContext) context).getDelegateToClassType();
v.getMemberMap().recordSrcClassNameForCallable(propertyDescriptor, shortNameByAsmType(ownerType));
v.getMemberMap().recordImplClassNameForCallable(propertyDescriptor, shortNameByAsmType(ownerType));
}
else if (kind != OwnerKind.TRAIT_IMPL) {
generateBackingField(p, propertyDescriptor);
@@ -142,11 +142,16 @@ public class PropertyCodegen extends GenerationStateAware {
AnnotationCodegen.forField(fieldVisitor, typeMapper).genAnnotations(propertyDescriptor);
}
else if (!propertyDescriptor.getAnnotations().isEmpty()) {
if (!isTrait(context.getContextDescriptor())) {
Method method = getSyntheticMethodSignature(typeMapper, propertyDescriptor);
generateSyntheticMethodForAnnotatedProperty(v, typeMapper, propertyDescriptor, method);
v.getMemberMap().recordSyntheticMethodOfProperty(propertyDescriptor, method);
Method method = getSyntheticMethodSignature(typeMapper, propertyDescriptor);
DeclarationDescriptor descriptor = context.getContextDescriptor();
if (isTrait(descriptor)) {
Type tImplType = typeMapper.mapTraitImpl((ClassDescriptor) descriptor);
v.getMemberMap().recordImplClassNameForCallable(propertyDescriptor, shortNameByAsmType(tImplType));
}
else {
generateSyntheticMethodForAnnotatedProperty(v, typeMapper, propertyDescriptor, method);
}
v.getMemberMap().recordSyntheticMethodOfProperty(propertyDescriptor, method);
}
}
@@ -18,6 +18,7 @@ package org.jetbrains.jet.codegen;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.asm4.AnnotationVisitor;
import org.jetbrains.asm4.commons.Method;
import org.jetbrains.jet.codegen.context.ClassContext;
import org.jetbrains.jet.codegen.state.GenerationState;
@@ -27,8 +28,11 @@ import org.jetbrains.jet.lang.psi.JetClassOrObject;
import org.jetbrains.jet.lang.psi.JetDeclaration;
import org.jetbrains.jet.lang.psi.JetProperty;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.java.JvmAbi;
import org.jetbrains.jet.lang.resolve.java.JvmAnnotationNames;
import static org.jetbrains.asm4.Opcodes.*;
import static org.jetbrains.jet.codegen.AsmUtil.asmDescByFqNameWithoutInnerClasses;
public class TraitImplBodyCodegen extends ClassBodyCodegen {
@@ -54,6 +58,14 @@ public class TraitImplBodyCodegen extends ClassBodyCodegen {
v.visitSource(myClass.getContainingFile().getName(), null);
}
@Override
protected void generateKotlinAnnotation() {
AnnotationVisitor av =
v.getVisitor().visitAnnotation(asmDescByFqNameWithoutInnerClasses(JvmAnnotationNames.KOTLIN_TRAIT_IMPL), true);
av.visit(JvmAnnotationNames.ABI_VERSION_FIELD_NAME, JvmAbi.VERSION);
av.visitEnd();
}
@Override
protected void generateSyntheticParts() {
generateSyntheticMethodsForAnnotatedProperties();