Generate static backing fields for properties in object

#KT-4973 Fixed
This commit is contained in:
Michael Bogdanov
2014-09-24 18:35:51 +04:00
parent 37bb4ae984
commit 5412a67d29
29 changed files with 639 additions and 463 deletions
@@ -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;