Support increment and '+=' on local delegated properties

This commit is contained in:
Mikhael Bogdanov
2016-05-05 14:13:26 +03:00
parent 6ae511b253
commit ec632c37ab
5 changed files with 69 additions and 3 deletions
@@ -2813,11 +2813,14 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
}
}
public int indexOfLocal(KtReferenceExpression lhs) {
public int indexOfLocalNotDelegated(KtReferenceExpression lhs) {
DeclarationDescriptor declarationDescriptor = bindingContext.get(REFERENCE_TARGET, lhs);
if (isVarCapturedInClosure(bindingContext, declarationDescriptor)) {
return -1;
}
if (declarationDescriptor instanceof LocalVariableDescriptor && ((LocalVariableDescriptor) declarationDescriptor).isDelegated()) {
return -1;
}
return lookupLocalIndex(declarationDescriptor);
}
@@ -3346,7 +3349,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
// Optimization for j = i++, when j and i are Int without any smart cast: we just work with primitive int
if (operand instanceof KtReferenceExpression && asmResultType == Type.INT_TYPE &&
bindingContext.get(BindingContext.SMARTCAST, operand) == null) {
int index = indexOfLocal((KtReferenceExpression) operand);
int index = indexOfLocalNotDelegated((KtReferenceExpression) operand);
if (index >= 0) {
return StackValue.postIncrement(index, increment);
}
@@ -672,7 +672,16 @@ public abstract class StackValue {
@NotNull CallableMethod getter,
@Nullable CallableMethod setter
) {
super(type, false, false, new Receiver(OBJECT_TYPE, delegateValue, constant(null, OBJECT_TYPE), metadataValue), false);
super(type, false, false, new Receiver(OBJECT_TYPE, delegateValue, constant(null, OBJECT_TYPE), metadataValue) {
@Override
public void dup(@NotNull InstructionAdapter v, boolean withReceiver) {
//UGLY HACK
//TODO rethink Receiver/StackValue concept
//We need to make duplication of delegated var, owner (null) and property metadata: dup 3.
//As HACK Type.LONG_TYPE and Type.INT_TYPE passed to dup util to simulate dup 3.
AsmUtil.dup(v, Type.LONG_TYPE, Type.INT_TYPE);
}
}, false);
this.delegateValue = delegateValue;
this.metadataValue = metadataValue;
this.getter = getter;