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.codegen.state.JetTypeMapper;
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
|
||||||
import org.jetbrains.kotlin.descriptors.ClassKind;
|
import org.jetbrains.kotlin.descriptors.ClassKind;
|
||||||
|
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor;
|
||||||
import org.jetbrains.kotlin.load.java.JvmAbi;
|
import org.jetbrains.kotlin.load.java.JvmAbi;
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||||
import org.jetbrains.org.objectweb.asm.Type;
|
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
|
@NotNull
|
||||||
public static FieldInfo createForHiddenField(@NotNull Type owner, @NotNull Type fieldType, @NotNull String fieldName) {
|
public static FieldInfo createForHiddenField(@NotNull Type owner, @NotNull Type fieldType, @NotNull String fieldName) {
|
||||||
return new FieldInfo(owner, fieldType, fieldName, false);
|
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.JvmAbi;
|
||||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames;
|
import org.jetbrains.kotlin.load.java.JvmAnnotationNames;
|
||||||
import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor;
|
import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor;
|
||||||
|
import org.jetbrains.kotlin.name.FqName;
|
||||||
import org.jetbrains.kotlin.name.Name;
|
import org.jetbrains.kotlin.name.Name;
|
||||||
import org.jetbrains.kotlin.psi.*;
|
import org.jetbrains.kotlin.psi.*;
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||||
@@ -961,7 +962,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
if (isEnumEntry(descriptor) || isClassObject(descriptor)) return;
|
if (isEnumEntry(descriptor) || isClassObject(descriptor)) return;
|
||||||
|
|
||||||
if (isObject(descriptor)) {
|
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;
|
if (state.getClassBuilderMode() != ClassBuilderMode.FULL) return;
|
||||||
|
|
||||||
@@ -980,7 +982,14 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
JetObjectDeclaration classObject = ((JetClass) myClass).getClassObject();
|
JetObjectDeclaration classObject = ((JetClass) myClass).getClassObject();
|
||||||
assert classObject != null : "Class object not found: " + myClass.getText();
|
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;
|
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() {
|
private void generateClassObjectBackingFieldCopies() {
|
||||||
if (classObjectPropertiesToCopy == null) return;
|
if (classObjectPropertiesToCopy == null) return;
|
||||||
|
|
||||||
@@ -1044,7 +1047,10 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
ExpressionCodegen codegen = createOrGetClInitCodegen();
|
ExpressionCodegen codegen = createOrGetClInitCodegen();
|
||||||
FunctionDescriptor constructor = codegen.accessibleFunctionDescriptor(KotlinPackage.single(classObject.getConstructors()));
|
FunctionDescriptor constructor = codegen.accessibleFunctionDescriptor(KotlinPackage.single(classObject.getConstructors()));
|
||||||
generateMethodCallTo(constructor, codegen.v);
|
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) {
|
private void generatePrimaryConstructor(final DelegationFieldsInfo delegationFieldsInfo) {
|
||||||
@@ -1131,7 +1137,6 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
|
|
||||||
if (isClassObjectWithBackingFieldsInOuter(descriptor)) {
|
if (isClassObjectWithBackingFieldsInOuter(descriptor)) {
|
||||||
final ImplementationBodyCodegen parentCodegen = (ImplementationBodyCodegen) getParentCodegen();
|
final ImplementationBodyCodegen parentCodegen = (ImplementationBodyCodegen) getParentCodegen();
|
||||||
//generate OBJECT$
|
|
||||||
parentCodegen.generateClassObjectInitializer(descriptor);
|
parentCodegen.generateClassObjectInitializer(descriptor);
|
||||||
generateInitializers(new Function0<ExpressionCodegen>() {
|
generateInitializers(new Function0<ExpressionCodegen>() {
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -206,6 +206,10 @@ public abstract class StackValue {
|
|||||||
return new Field(field.type, field.owner, field.name, field.isStaticPut, newReceiver);
|
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
|
@NotNull
|
||||||
public static StackValue changeReceiverForFieldAndSharedVar(@NotNull StackValueWithSimpleReceiver stackValue, @Nullable StackValue newReceiver) {
|
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) {
|
public static Field singleton(ClassDescriptor classDescriptor, JetTypeMapper typeMapper) {
|
||||||
FieldInfo info = FieldInfo.createForSingleton(classDescriptor, typeMapper);
|
return field(FieldInfo.createForSingleton(classDescriptor, typeMapper));
|
||||||
return field(info.getFieldType(), Type.getObjectType(info.getOwnerInternalName()), info.getFieldName(), true, none());
|
}
|
||||||
|
|
||||||
|
public static Field deprecatedClassObjectAccessor(ClassDescriptor classDescriptor, JetTypeMapper typeMapper) {
|
||||||
|
return field(FieldInfo.deprecatedFieldForClassObject(classDescriptor, typeMapper));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static StackValue operation(Type type, Function1<InstructionAdapter, Unit> lambda) {
|
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_CLASS_FIELD_NAME = "$kotlinClass";
|
||||||
public static final String KOTLIN_PACKAGE_FIELD_NAME = "$kotlinPackage";
|
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
|
@NotNull
|
||||||
public static String getSyntheticMethodNameForAnnotatedProperty(@NotNull Name propertyName) {
|
public static String getSyntheticMethodNameForAnnotatedProperty(@NotNull Name propertyName) {
|
||||||
return propertyName.asString() + ANNOTATED_PROPERTY_METHOD_NAME_SUFFIX;
|
return propertyName.asString() + ANNOTATED_PROPERTY_METHOD_NAME_SUFFIX;
|
||||||
|
|||||||
Reference in New Issue
Block a user