Esempio n. 1
0
 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>
 /// if (logic.not(ldloc V_1)) Block IL_0149 {
 ///     dynamic.setmember.compound B(target, dynamic.binary.operator AddAssign(ldloc V_2,  value))
 /// } else Block IL_0151 {
 ///     dynamic.invokemember.invokespecial.discard add_B(target, value)
 /// }
 /// </summary>
 static bool MatchIsEventAssignmentIfInstruction(ILInstruction ifInst, DynamicIsEventInstruction isEvent, ILVariable flagVar, ILVariable getMemberVar,
                                                 out DynamicSetMemberInstruction setMemberInst, out ILInstruction getMemberVarUse, out ILInstruction isEventConditionUse)
 {
     setMemberInst       = null;
     getMemberVarUse     = null;
     isEventConditionUse = null;
     if (!ifInst.MatchIfInstruction(out var condition, out var trueInst, out var falseInst))
     {
         return(false);
     }
     if (MatchFlagEqualsZero(condition, flagVar))
     {
         if (!condition.MatchCompEquals(out var left, out _))
         {
             return(false);
         }
         isEventConditionUse = left;
     }
     else if (condition.MatchLdLoc(flagVar))
     {
         var tmp = trueInst;
         trueInst            = falseInst;
         falseInst           = tmp;
         isEventConditionUse = condition;
     }
     else
     {
         return(false);
     }
     setMemberInst = Block.Unwrap(trueInst) as DynamicSetMemberInstruction;
     if (!(setMemberInst != null))
     {
         return(false);
     }
     if (!isEvent.Argument.Match(setMemberInst.Target).Success)
     {
         return(false);
     }
     if (!(Block.Unwrap(falseInst) is DynamicInvokeMemberInstruction invokeMemberInst && invokeMemberInst.Arguments.Count == 2))
     {
         return(false);
     }
     if (!isEvent.Argument.Match(invokeMemberInst.Arguments[0]).Success)
     {
         return(false);
     }
     if (!(setMemberInst.Value is DynamicBinaryOperatorInstruction binOp && binOp.Left.MatchLdLoc(getMemberVar)))
     {
         return(false);
     }
     getMemberVarUse = binOp.Left;
     return(true);
 }
Esempio n. 3
0
 /// <summary>
 /// dynamic.setmember.compound Name(target, dynamic.binary.operator op(dynamic.getmember Name(target), value))
 /// =>
 /// dynamic.compound.op (dynamic.getmember Name(target), value)
 /// </summary>
 protected internal override void VisitDynamicSetMemberInstruction(DynamicSetMemberInstruction inst)
 {
     base.VisitDynamicSetMemberInstruction(inst);
     TransformDynamicSetMemberInstruction(inst, context);
 }