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:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user