Load annotations on properties declared in traits
This commit is contained in:
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user