コード例 #1
0
        public override object VisitAssign(BoundAssignEx x)
        {
            // A = A <binOp> <right>
            if (x.Target is BoundVariableRef trg &&
                MatchExprSkipCopy(x.Value, out BoundBinaryEx binOp, isCopied: out _) &&
                binOp.Left is BoundVariableRef valLeft &&
                trg.Variable == valLeft.Variable)
            {
                var newTrg =
                    new BoundVariableRef(trg.Name)
                    .WithAccess(trg.Access.WithRead())
                    .WithSyntax(trg.PhpSyntax);

                // A = A +/- 1; => ++A; / --A;
                if ((binOp.Operation == Ast.Operations.Add || binOp.Operation == Ast.Operations.Sub) &&
                    binOp.Right.ConstantValue.IsInteger(out long rightVal) && rightVal == 1)
                {
                    TransformationCount++;
                    return(new BoundIncDecEx(newTrg, binOp.Operation == Ast.Operations.Add, false).WithAccess(x));
                }

                // A = A & B => A &= B; // &, |, ^, <<, >>, +, -, *, /, %, **, .
                switch (binOp.Operation)
                {
                case Ast.Operations.BitAnd:
                case Ast.Operations.BitOr:
                case Ast.Operations.BitXor:
                case Ast.Operations.ShiftLeft:
                case Ast.Operations.ShiftRight:
                case Ast.Operations.Add:
                case Ast.Operations.Sub:
                case Ast.Operations.Mul:
                case Ast.Operations.Div:
                case Ast.Operations.Mod:
                case Ast.Operations.Pow:
                case Ast.Operations.Concat:
                    TransformationCount++;
                    var compoundOp = AstUtils.BinaryToCompoundOp(binOp.Operation);
                    return(new BoundCompoundAssignEx(newTrg, binOp.Right, compoundOp).WithAccess(x));
                }
            }

            return(base.VisitAssign(x));
        }