internal static void TransformDynamicSetMemberInstruction(DynamicSetMemberInstruction inst, StatementTransformContext context) { if (!inst.BinderFlags.HasFlag(CSharpBinderFlags.ValueFromCompoundAssignment)) { return; } if (!(inst.Value is DynamicBinaryOperatorInstruction binaryOp)) { return; } if (!(binaryOp.Left is DynamicGetMemberInstruction dynamicGetMember)) { return; } if (!dynamicGetMember.Target.Match(inst.Target).Success) { return; } if (!SemanticHelper.IsPure(dynamicGetMember.Target.Flags)) { return; } if (inst.Name != dynamicGetMember.Name || !DynamicCompoundAssign.IsExpressionTypeSupported(binaryOp.Operation)) { return; } context.Step("dynamic.setmember.compound -> dynamic.compound.op", inst); inst.ReplaceWith(new DynamicCompoundAssign(binaryOp.Operation, binaryOp.BinderFlags, binaryOp.Left, binaryOp.LeftArgumentInfo, binaryOp.Right, binaryOp.RightArgumentInfo)); }
/// <summary> /// dynamic.setindex.compound(target, index, dynamic.binary.operator op(dynamic.getindex(target, index), value)) /// => /// dynamic.compound.op (dynamic.getindex(target, index), value) /// </summary> protected internal override void VisitDynamicSetIndexInstruction(DynamicSetIndexInstruction inst) { base.VisitDynamicSetIndexInstruction(inst); if (!inst.BinderFlags.HasFlag(CSharpBinderFlags.ValueFromCompoundAssignment)) { return; } if (!(inst.Arguments.LastOrDefault() is DynamicBinaryOperatorInstruction binaryOp)) { return; } if (!(binaryOp.Left is DynamicGetIndexInstruction dynamicGetIndex)) { return; } if (inst.Arguments.Count != dynamicGetIndex.Arguments.Count + 1) { return; } // Ensure that same arguments are passed to dynamicGetIndex and inst: for (int j = 0; j < dynamicGetIndex.Arguments.Count; j++) { if (!SemanticHelper.IsPure(dynamicGetIndex.Arguments[j].Flags)) { return; } if (!dynamicGetIndex.Arguments[j].Match(inst.Arguments[j]).Success) { return; } } if (!DynamicCompoundAssign.IsExpressionTypeSupported(binaryOp.Operation)) { return; } context.Step("dynamic.setindex.compound -> dynamic.compound.op", inst); inst.ReplaceWith(new DynamicCompoundAssign(binaryOp.Operation, binaryOp.BinderFlags, binaryOp.Left, binaryOp.LeftArgumentInfo, binaryOp.Right, binaryOp.RightArgumentInfo)); }