FieldNode field = expression.getField();
boolean setReferenceFromReference = field.isHolder() && expression.isUseReferenceDirectly();
String ownerName = (field.getOwner().equals(controller.getClassNode())) ?
controller.getInternalClassName() : BytecodeHelper.getClassInternalName(field.getOwner());
OperandStack operandStack = controller.getOperandStack();
if (setReferenceFromReference) {
// rhs is ready to use reference, just put it in the field
mv.visitVarInsn(ALOAD, 0);
operandStack.push(controller.getClassNode());
operandStack.swap();
mv.visitFieldInsn(PUTFIELD, ownerName, field.getName(), BytecodeHelper.getTypeDescription(field.getType()));
} else if (field.isHolder()){
// rhs is normal value, set the value in the Reference
operandStack.doGroovyCast(field.getOriginType());
operandStack.box();
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, ownerName, expression.getFieldName(), BytecodeHelper.getTypeDescription(field.getType()));
mv.visitInsn(SWAP);
mv.visitMethodInsn(INVOKEVIRTUAL, "groovy/lang/Reference", "set", "(Ljava/lang/Object;)V", false);
} else {
// rhs is normal value, set normal value
operandStack.doGroovyCast(field.getOriginType());
mv.visitVarInsn(ALOAD, 0);
operandStack.push(controller.getClassNode());
operandStack.swap();
mv.visitFieldInsn(PUTFIELD, ownerName, field.getName(), BytecodeHelper.getTypeDescription(field.getType()));
}
}