Write full synthetic method signature for annotated property

This will be needed to support annotated extension properties, since they have
the same name but different signatures
This commit is contained in:
Alexander Udalov
2013-10-09 22:46:51 +04:00
parent 6e45533065
commit 806d264771
9 changed files with 166 additions and 106 deletions
@@ -71,22 +71,22 @@ public class JavaSerializerExtension extends SerializerExtension {
Type fieldType;
String fieldName;
boolean isStaticInOuter;
String syntheticMethodName;
Method syntheticMethod;
if (field != null) {
fieldType = field.first;
fieldName = field.second;
isStaticInOuter = memberMap.isStaticFieldInOuterClass(property);
syntheticMethodName = null;
syntheticMethod = null;
}
else {
fieldType = null;
fieldName = null;
isStaticInOuter = false;
syntheticMethodName = memberMap.getSyntheticMethodNameOfProperty(property);
syntheticMethod = memberMap.getSyntheticMethodOfProperty(property);
}
JavaProtoBuf.JavaPropertySignature signature = new SignatureSerializer(nameTable)
.propertySignature(fieldType, fieldName, isStaticInOuter, syntheticMethodName, getterMethod, setterMethod);
.propertySignature(fieldType, fieldName, isStaticInOuter, syntheticMethod, getterMethod, setterMethod);
proto.setExtension(JavaProtoBuf.propertySignature, signature);
}
}
@@ -129,7 +129,7 @@ public class JavaSerializerExtension extends SerializerExtension {
@Nullable Type fieldType,
@Nullable String fieldName,
boolean isStaticInOuter,
@Nullable String syntheticMethodName,
@Nullable Method syntheticMethod,
@Nullable Method getter,
@Nullable Method setter
) {
@@ -140,8 +140,8 @@ public class JavaSerializerExtension extends SerializerExtension {
signature.setField(fieldSignature(fieldType, fieldName, isStaticInOuter));
}
if (syntheticMethodName != null) {
signature.setSyntheticMethodName(nameTable.getSimpleNameIndex(Name.guess(syntheticMethodName)));
if (syntheticMethod != null) {
signature.setSyntheticMethod(methodSignature(syntheticMethod));
}
if (getter != null) {
@@ -30,7 +30,7 @@ import java.util.*;
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, String> syntheticMethodNameForProperty = new HashMap<PropertyDescriptor, String>();
private final Map<PropertyDescriptor, Method> syntheticMethodForProperty = new HashMap<PropertyDescriptor, Method>();
private final Map<CallableMemberDescriptor, String> srcClassNameForCallable = new HashMap<CallableMemberDescriptor, String>();
private final Set<PropertyDescriptor> staticFieldInOuterClass = new HashSet<PropertyDescriptor>();
@@ -46,8 +46,8 @@ public final class MemberMap {
result.recordFieldOfProperty(entry.getKey(), entry.getValue().first, entry.getValue().second);
}
for (Map.Entry<PropertyDescriptor, String> entry : map.syntheticMethodNameForProperty.entrySet()) {
result.recordSyntheticMethodNameOfProperty(entry.getKey(), entry.getValue());
for (Map.Entry<PropertyDescriptor, Method> entry : map.syntheticMethodForProperty.entrySet()) {
result.recordSyntheticMethodOfProperty(entry.getKey(), entry.getValue());
}
for (Map.Entry<CallableMemberDescriptor, String> entry : map.srcClassNameForCallable.entrySet()) {
@@ -72,8 +72,8 @@ public final class MemberMap {
assert old == null : "Duplicate field for property: " + descriptor + "; " + old;
}
public void recordSyntheticMethodNameOfProperty(@NotNull PropertyDescriptor descriptor, @NotNull String name) {
String old = syntheticMethodNameForProperty.put(descriptor, name);
public void recordSyntheticMethodOfProperty(@NotNull PropertyDescriptor descriptor, @NotNull Method method) {
Method old = syntheticMethodForProperty.put(descriptor, method);
assert old == null : "Duplicate synthetic method for property: " + descriptor + "; " + old;
}
@@ -98,8 +98,8 @@ public final class MemberMap {
}
@Nullable
public String getSyntheticMethodNameOfProperty(@NotNull PropertyDescriptor descriptor) {
return syntheticMethodNameForProperty.get(descriptor);
public Method getSyntheticMethodOfProperty(@NotNull PropertyDescriptor descriptor) {
return syntheticMethodForProperty.get(descriptor);
}
@Nullable
@@ -115,7 +115,7 @@ public final class MemberMap {
public String toString() {
return "Functions: " + methodForFunction.size() +
", fields: " + fieldForProperty.size() +
", synthetic methods: " + syntheticMethodNameForProperty.size() +
", synthetic methods: " + syntheticMethodForProperty.size() +
", src class names: " + srcClassNameForCallable.size();
}
}
@@ -24,6 +24,7 @@ import org.jetbrains.asm4.MethodVisitor;
import org.jetbrains.asm4.Opcodes;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import org.jetbrains.asm4.commons.Method;
import org.jetbrains.jet.codegen.context.CodegenContext;
import org.jetbrains.jet.codegen.context.FieldOwnerContext;
import org.jetbrains.jet.codegen.context.NamespaceContext;
@@ -143,14 +144,15 @@ public class PropertyCodegen extends GenerationStateAware {
else if (!propertyDescriptor.getAnnotations().isEmpty()) {
// Annotations on properties without backing fields are stored in bytecode on an empty synthetic method. This way they're still
// accessible via reflection, and 'deprecated' and 'private' flags prevent this method from being called accidentally
String methodName = JvmAbi.getSyntheticMethodNameForAnnotatedProperty(propertyDescriptor.getName());
Method method = JvmAbi.getSyntheticMethodSignatureForAnnotatedProperty(propertyDescriptor.getName());
MethodVisitor mv = v.newMethod(null,
ACC_DEPRECATED | ACC_FINAL | ACC_PRIVATE | ACC_STATIC | ACC_SYNTHETIC,
methodName,
JvmAbi.ANNOTATED_PROPERTY_METHOD_SIGNATURE,
method.getName(),
method.getDescriptor(),
null,
null);
v.getMemberMap().recordSyntheticMethodNameOfProperty(propertyDescriptor, methodName);
v.getMemberMap().recordSyntheticMethodOfProperty(propertyDescriptor, method);
AnnotationCodegen.forMethod(mv, typeMapper).genAnnotations(propertyDescriptor);
mv.visitCode();
mv.visitInsn(Opcodes.RETURN);
+2 -2
View File
@@ -1,5 +1,5 @@
WARNING: $TESTDATA_DIR$/wrongAbiVersion.kt: (3, 9) Parameter 'x' is never used
ERROR: $TESTDATA_DIR$/wrongAbiVersion.kt: (4, 3) Unresolved reference: bar
ERROR: $TESTDATA_DIR$/wrongAbiVersionLib/wrong/WrongPackage.class: (0, 0) Class 'wrong/WrongPackage' was compiled with an incompatible version of Kotlin. Its ABI version is -1, expected ABI version is 9
ERROR: $TESTDATA_DIR$/wrongAbiVersionLib/ClassWithWrongAbiVersion.class: (0, 0) Class 'ClassWithWrongAbiVersion' was compiled with an incompatible version of Kotlin. Its ABI version is -1, expected ABI version is 9
ERROR: $TESTDATA_DIR$/wrongAbiVersionLib/wrong/WrongPackage.class: (0, 0) Class 'wrong/WrongPackage' was compiled with an incompatible version of Kotlin. Its ABI version is -1, expected ABI version is 10
ERROR: $TESTDATA_DIR$/wrongAbiVersionLib/ClassWithWrongAbiVersion.class: (0, 0) Class 'ClassWithWrongAbiVersion' was compiled with an incompatible version of Kotlin. Its ABI version is -1, expected ABI version is 10
COMPILATION_ERROR
@@ -265,7 +265,8 @@ public class PropertyGenTest extends CodegenTestCase {
}
}
private static final String TEST_SYNTHETIC_METHOD_NAME = JvmAbi.getSyntheticMethodNameForAnnotatedProperty(Name.identifier("property"));
private static final String TEST_SYNTHETIC_METHOD_NAME =
JvmAbi.getSyntheticMethodSignatureForAnnotatedProperty(Name.identifier("property")).getName();
public void testAnnotatedClassPropertyNoField() {
loadFile("properties/annotatedClassPropertyNoField.kt");