Generate additional deprecated "OBJECT$" field for class object

To avoid breaking some code for now
It should be removed later
This commit is contained in:
Pavel V. Talanov
2015-01-30 18:57:19 +03:00
parent 7d5c0dc8bf
commit 766912c590
4 changed files with 41 additions and 12 deletions
@@ -20,6 +20,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.codegen.state.JetTypeMapper;
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
import org.jetbrains.kotlin.descriptors.ClassKind;
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor;
import org.jetbrains.kotlin.load.java.JvmAbi;
import org.jetbrains.kotlin.resolve.DescriptorUtils;
import org.jetbrains.org.objectweb.asm.Type;
@@ -44,6 +45,18 @@ public class FieldInfo {
}
}
@SuppressWarnings("deprecation")
@NotNull
public static FieldInfo deprecatedFieldForClassObject(@NotNull ClassDescriptor classObject, @NotNull JetTypeMapper typeMapper) {
assert DescriptorUtils.isClassObject(classObject) : "Not a class object: " + classObject;
return new FieldInfo(
typeMapper.mapType((ClassifierDescriptor) classObject.getContainingDeclaration()),
typeMapper.mapType(classObject),
JvmAbi.DEPRECATED_CLASS_OBJECT_FIELD,
true
);
}
@NotNull
public static FieldInfo createForHiddenField(@NotNull Type owner, @NotNull Type fieldType, @NotNull String fieldName) {
return new FieldInfo(owner, fieldType, fieldName, false);
@@ -37,6 +37,7 @@ import org.jetbrains.kotlin.lexer.JetTokens;
import org.jetbrains.kotlin.load.java.JvmAbi;
import org.jetbrains.kotlin.load.java.JvmAnnotationNames;
import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor;
import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.resolve.BindingContext;
@@ -961,7 +962,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
if (isEnumEntry(descriptor) || isClassObject(descriptor)) return;
if (isObject(descriptor)) {
createFieldForSingleton(descriptor, myClass);
StackValue.Field field = StackValue.singleton(descriptor, typeMapper);
v.newField(OtherOrigin(myClass), ACC_PUBLIC | ACC_STATIC | ACC_FINAL, field.name, field.type.getDescriptor(), null, null);
if (state.getClassBuilderMode() != ClassBuilderMode.FULL) return;
@@ -980,7 +982,14 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
JetObjectDeclaration classObject = ((JetClass) myClass).getClassObject();
assert classObject != null : "Class object not found: " + myClass.getText();
createFieldForSingleton(classObjectDescriptor, classObject);
StackValue.Field field = StackValue.singleton(classObjectDescriptor, typeMapper);
v.newField(OtherOrigin(classObject), ACC_PUBLIC | ACC_STATIC | ACC_FINAL, field.name, field.type.getDescriptor(), null, null);
StackValue.Field deprecatedField = StackValue.deprecatedClassObjectAccessor(classObjectDescriptor, typeMapper);
FieldVisitor fv = v.newField(OtherOrigin(classObject), ACC_PUBLIC | ACC_STATIC | ACC_FINAL | ACC_DEPRECATED,
deprecatedField.name, deprecatedField.type.getDescriptor(), null, null);
fv.visitAnnotation(asmDescByFqNameWithoutInnerClasses(new FqName("java.lang.Deprecated")), true).visitEnd();
if (state.getClassBuilderMode() != ClassBuilderMode.FULL) return;
@@ -989,12 +998,6 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
}
}
private void createFieldForSingleton(@NotNull ClassDescriptor fieldTypeDescriptor, @NotNull JetClassOrObject original) {
StackValue.Field field = StackValue.singleton(fieldTypeDescriptor, typeMapper);
v.newField(OtherOrigin(original), ACC_PUBLIC | ACC_STATIC | ACC_FINAL, field.name, field.type.getDescriptor(), null, null);
}
private void generateClassObjectBackingFieldCopies() {
if (classObjectPropertiesToCopy == null) return;
@@ -1044,7 +1047,10 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
ExpressionCodegen codegen = createOrGetClInitCodegen();
FunctionDescriptor constructor = codegen.accessibleFunctionDescriptor(KotlinPackage.single(classObject.getConstructors()));
generateMethodCallTo(constructor, codegen.v);
StackValue.singleton(classObject, typeMapper).store(StackValue.onStack(typeMapper.mapClass(classObject)), codegen.v, true);
codegen.v.dup();
StackValue instance = StackValue.onStack(typeMapper.mapClass(classObject));
StackValue.singleton(classObject, typeMapper).store(instance, codegen.v, true);
StackValue.deprecatedClassObjectAccessor(classObject, typeMapper).store(instance, codegen.v, true);
}
private void generatePrimaryConstructor(final DelegationFieldsInfo delegationFieldsInfo) {
@@ -1131,7 +1137,6 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
if (isClassObjectWithBackingFieldsInOuter(descriptor)) {
final ImplementationBodyCodegen parentCodegen = (ImplementationBodyCodegen) getParentCodegen();
//generate OBJECT$
parentCodegen.generateClassObjectInitializer(descriptor);
generateInitializers(new Function0<ExpressionCodegen>() {
@Override
@@ -206,6 +206,10 @@ public abstract class StackValue {
return new Field(field.type, field.owner, field.name, field.isStaticPut, newReceiver);
}
@NotNull
private static Field field(@NotNull FieldInfo info) {
return field(info.getFieldType(), Type.getObjectType(info.getOwnerInternalName()), info.getFieldName(), true, none());
}
@NotNull
public static StackValue changeReceiverForFieldAndSharedVar(@NotNull StackValueWithSimpleReceiver stackValue, @Nullable StackValue newReceiver) {
@@ -506,8 +510,11 @@ public abstract class StackValue {
}
public static Field singleton(ClassDescriptor classDescriptor, JetTypeMapper typeMapper) {
FieldInfo info = FieldInfo.createForSingleton(classDescriptor, typeMapper);
return field(info.getFieldType(), Type.getObjectType(info.getOwnerInternalName()), info.getFieldName(), true, none());
return field(FieldInfo.createForSingleton(classDescriptor, typeMapper));
}
public static Field deprecatedClassObjectAccessor(ClassDescriptor classDescriptor, JetTypeMapper typeMapper) {
return field(FieldInfo.deprecatedFieldForClassObject(classDescriptor, typeMapper));
}
public static StackValue operation(Type type, Function1<InstructionAdapter, Unit> lambda) {
@@ -45,6 +45,10 @@ public final class JvmAbi {
public static final String KOTLIN_CLASS_FIELD_NAME = "$kotlinClass";
public static final String KOTLIN_PACKAGE_FIELD_NAME = "$kotlinPackage";
//TODO: To be removed after kotlin M11
@Deprecated
public static final String DEPRECATED_CLASS_OBJECT_FIELD = "OBJECT$";
@NotNull
public static String getSyntheticMethodNameForAnnotatedProperty(@NotNull Name propertyName) {
return propertyName.asString() + ANNOTATED_PROPERTY_METHOD_NAME_SUFFIX;