Generate static backing fields for properties in object
#KT-4973 Fixed
This commit is contained in:
@@ -705,6 +705,11 @@ public class AsmUtil {
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isInstancePropertyWithStaticBackingField(@NotNull PropertyDescriptor propertyDescriptor) {
|
||||
DeclarationDescriptor containingDeclaration = propertyDescriptor.getContainingDeclaration();
|
||||
return isObject(containingDeclaration) || isPropertyWithBackingFieldInOuterClass(propertyDescriptor);
|
||||
}
|
||||
|
||||
public static boolean isPropertyWithBackingFieldInOuterClass(@NotNull PropertyDescriptor propertyDescriptor) {
|
||||
return isClassObjectWithBackingFieldsInOuter(propertyDescriptor.getContainingDeclaration());
|
||||
}
|
||||
|
||||
@@ -1953,7 +1953,8 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
DeclarationDescriptor containingDeclaration = propertyDescriptor.getContainingDeclaration();
|
||||
|
||||
boolean isBackingFieldInAnotherClass = AsmUtil.isPropertyWithBackingFieldInOuterClass(propertyDescriptor);
|
||||
boolean isStaticBackingField = DescriptorUtils.isStaticDeclaration(propertyDescriptor) || isBackingFieldInAnotherClass;
|
||||
boolean isStaticBackingField = DescriptorUtils.isStaticDeclaration(propertyDescriptor) ||
|
||||
AsmUtil.isInstancePropertyWithStaticBackingField(propertyDescriptor);
|
||||
boolean isSuper = superExpression != null;
|
||||
boolean isExtensionProperty = propertyDescriptor.getExtensionReceiverParameter() != null;
|
||||
|
||||
|
||||
@@ -249,17 +249,18 @@ public class PropertyCodegen {
|
||||
ClassBuilder builder = v;
|
||||
|
||||
FieldOwnerContext backingFieldContext = context;
|
||||
if (AsmUtil.isPropertyWithBackingFieldInOuterClass(propertyDescriptor)) {
|
||||
if (AsmUtil.isInstancePropertyWithStaticBackingField(propertyDescriptor) ) {
|
||||
modifiers |= ACC_STATIC | getVisibilityForSpecialPropertyBackingField(propertyDescriptor, isDelegate);
|
||||
ImplementationBodyCodegen codegen = getParentBodyCodegen(classBodyCodegen);
|
||||
builder = codegen.v;
|
||||
backingFieldContext = codegen.context;
|
||||
v.getSerializationBindings().put(STATIC_FIELD_IN_OUTER_CLASS, propertyDescriptor);
|
||||
} else {
|
||||
if (kind != OwnerKind.PACKAGE || isDelegate) {
|
||||
modifiers |= ACC_PRIVATE;
|
||||
if (AsmUtil.isPropertyWithBackingFieldInOuterClass(propertyDescriptor)) {
|
||||
ImplementationBodyCodegen codegen = getParentBodyCodegen(classBodyCodegen);
|
||||
builder = codegen.v;
|
||||
backingFieldContext = codegen.context;
|
||||
v.getSerializationBindings().put(STATIC_FIELD_IN_OUTER_CLASS, propertyDescriptor);
|
||||
}
|
||||
}
|
||||
else if (kind != OwnerKind.PACKAGE || isDelegate) {
|
||||
modifiers |= ACC_PRIVATE;
|
||||
}
|
||||
|
||||
if (AsmUtil.isPropertyWithBackingFieldCopyInOuterClass(propertyDescriptor)) {
|
||||
ImplementationBodyCodegen parentBodyCodegen = getParentBodyCodegen(classBodyCodegen);
|
||||
|
||||
@@ -1482,11 +1482,11 @@ public abstract class StackValue {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dup(@NotNull InstructionAdapter v, boolean withReceiver) {
|
||||
if (!withReceiver) {
|
||||
super.dup(v, withReceiver);
|
||||
public void dup(@NotNull InstructionAdapter v, boolean withWriteReceiver) {
|
||||
if (!withWriteReceiver) {
|
||||
super.dup(v, withWriteReceiver);
|
||||
} else {
|
||||
int receiverSize = hasReceiver(false) && hasReceiver(true) ? receiverSize() : 0;
|
||||
int receiverSize = hasReceiver(false) ? receiverSize() : 0;
|
||||
switch (receiverSize) {
|
||||
case 0:
|
||||
AsmUtil.dup(v, type);
|
||||
@@ -1577,19 +1577,23 @@ public abstract class StackValue {
|
||||
}
|
||||
}
|
||||
|
||||
public static class Delegated extends StackValueWithSimpleReceiver {
|
||||
public static class DelegatedForComplexReceiver extends StackValueWithSimpleReceiver {
|
||||
|
||||
public final StackValueWithSimpleReceiver originalValue;
|
||||
|
||||
public Delegated(
|
||||
public DelegatedForComplexReceiver(
|
||||
@NotNull Type type,
|
||||
@NotNull StackValueWithSimpleReceiver originalValue,
|
||||
@NotNull StackValue receiver
|
||||
) {
|
||||
super(type, !originalValue.hasReceiver(true), !originalValue.hasReceiver(false), receiver);
|
||||
super(type, bothReceiverStatic(originalValue), bothReceiverStatic(originalValue), receiver);
|
||||
this.originalValue = originalValue;
|
||||
}
|
||||
|
||||
private static boolean bothReceiverStatic(StackValueWithSimpleReceiver originalValue) {
|
||||
return !(originalValue.hasReceiver(true) || originalValue.hasReceiver(false));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putSelector(
|
||||
@NotNull Type type, @NotNull InstructionAdapter v
|
||||
@@ -1605,8 +1609,8 @@ public abstract class StackValue {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dup(@NotNull InstructionAdapter v, boolean withReceiver) {
|
||||
originalValue.dup(v, withReceiver);
|
||||
public void dup(@NotNull InstructionAdapter v, boolean withWriteReceiver) {
|
||||
originalValue.dup(v, withWriteReceiver);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1616,7 +1620,7 @@ public abstract class StackValue {
|
||||
|
||||
private static StackValue complexReceiver(StackValue stackValue, boolean ... isReadOperations) {
|
||||
if (stackValue instanceof StackValueWithSimpleReceiver) {
|
||||
return new Delegated(stackValue.type, (StackValueWithSimpleReceiver) stackValue,
|
||||
return new DelegatedForComplexReceiver(stackValue.type, (StackValueWithSimpleReceiver) stackValue,
|
||||
new ComplexReceiver((StackValueWithSimpleReceiver) stackValue, isReadOperations));
|
||||
} else {
|
||||
return stackValue;
|
||||
|
||||
Reference in New Issue
Block a user