Пример #1
0
            public override void VisitIfElseStatement(IfElseStatement ifElseStatement)
            {
                base.VisitIfElseStatement(ifElseStatement);
                var match = ifPattern.Match(ifElseStatement);

                if (match.Success)
                {
                    var cond1 = match.Get <Expression>("condition").Single();
                    var cond2 = match.Get <Expression>("condition2").Single();
                    if (!AlUtil.AreConditionsEqual(cond1, cond2))
                    {
                        return;
                    }
                    AddIssue(new CodeIssue(
                                 ifElseStatement.IfToken,
                                 ctx.TranslateString("Statement can be simplified to 'while' statement"),
                                 ctx.TranslateString("Replace with 'while'"),
                                 script => {
                        script.Replace(
                            ifElseStatement,
                            new WhileStatement(
                                cond1.Clone(),
                                match.Get <Statement>("EmbeddedStatement").Single().Clone()
                                )
                            );
                    }
                                 )
                    {
                        IssueMarker = IssueMarker.DottedLine
                    });
                }
            }
            public override void VisitUnaryOperatorExpression(UnaryOperatorExpression unaryOperatorExpression)
            {
                base.VisitUnaryOperatorExpression(unaryOperatorExpression);
                if (unaryOperatorExpression.Operator != UnaryOperatorType.Not)
                {
                    return;
                }
                var invocation = AlUtil.GetInnerMostExpression(unaryOperatorExpression.Expression) as InvocationExpression;

                if (invocation == null)
                {
                    return;
                }
                var rr = ctx.Resolve(invocation) as AlInvocationResolveResult;

                if (rr == null || rr.IsError)
                {
                    return;
                }

                if (rr.Member.DeclaringType.Name != "Enumerable" || rr.Member.DeclaringType.Namespace != "System.Linq")
                {
                    return;
                }
                if (!new[] { "All", "Any" }.Contains(rr.Member.Name))
                {
                    return;
                }
                if (invocation.Arguments.Count != 1)
                {
                    return;
                }
                var arg   = invocation.Arguments.First();
                var match = argumentPattern.Match(arg);

                if (!match.Success)
                {
                    return;
                }
                AddIssue(new CodeIssue(
                             unaryOperatorExpression,
                             ctx.TranslateString("Simplify LINQ expression"),
                             ctx.TranslateString("Simplify LINQ expression"),
                             s => {
                    var target        = invocation.Target.Clone() as MemberReferenceExpression;
                    target.MemberName = target.MemberName == "All" ? "Any" : "All";

                    var expr   = arg.Clone();
                    var nmatch = argumentPattern.Match(expr);
                    var cond   = nmatch.Get <Expression>("expr").Single();
                    cond.ReplaceWith(AlUtil.InvertCondition(cond));
                    var simplifiedInvocation = new InvocationExpression(
                        target,
                        expr
                        );
                    s.Replace(unaryOperatorExpression, simplifiedInvocation);
                }
                             ));
            }
		void GenerateNewScript(Script script, IfElseStatement ifStatement)
		{
			var mergedIfStatement = new IfElseStatement {
				Condition = AlUtil.InvertCondition(ifStatement.Condition),
				TrueStatement = new ContinueStatement()
			};
			mergedIfStatement.Condition.AcceptVisitor(_insertParenthesesVisitor);
			
			script.Replace(ifStatement, mergedIfStatement);
			
			SimplifyIfFlowAction.InsertBody(script, ifStatement);
		}
            public override void VisitInvocationExpression(InvocationExpression invocationExpression)
            {
                base.VisitInvocationExpression(invocationExpression);
                var rr = ctx.Resolve(invocationExpression) as InvocationResolveResult;

                if (rr == null || rr.Member.Name != "Equals" || !rr.Member.ReturnType.IsKnownType(KnownTypeCode.Boolean))
                {
                    return;
                }

                if (rr.Member.IsStatic)
                {
                    if (rr.Member.Parameters.Count != 2)
                    {
                        return;
                    }
                    if (AlUtil.AreConditionsEqual(invocationExpression.Arguments.FirstOrDefault(), invocationExpression.Arguments.Last()))
                    {
                        if ((invocationExpression.Parent is UnaryOperatorExpression) && ((UnaryOperatorExpression)invocationExpression.Parent).Operator == UnaryOperatorType.Not)
                        {
                            AddIssue(invocationExpression.Parent, invocationExpression.Parent, false);
                        }
                        else
                        {
                            AddIssue(invocationExpression, invocationExpression, true);
                        }
                    }
                }
                else
                {
                    if (rr.Member.Parameters.Count != 1)
                    {
                        return;
                    }
                    var target = invocationExpression.Target as MemberReferenceExpression;
                    if (target == null)
                    {
                        return;
                    }
                    if (AlUtil.AreConditionsEqual(invocationExpression.Arguments.FirstOrDefault(), target.Target))
                    {
                        if ((invocationExpression.Parent is UnaryOperatorExpression) && ((UnaryOperatorExpression)invocationExpression.Parent).Operator == UnaryOperatorType.Not)
                        {
                            AddIssue(invocationExpression.Parent, invocationExpression.Parent, false);
                        }
                        else
                        {
                            AddIssue(invocationExpression, invocationExpression, true);
                        }
                    }
                }
            }
        Expression Subtract(Expression expr, Expression step)
        {
            if (step != null && AlUtil.GetInnerMostExpression(expr).IsMatch(AlUtil.GetInnerMostExpression(step)))
            {
                return(new PrimitiveExpression(0));
            }

            var pe = expr as PrimitiveExpression;

            if (pe != null)
            {
                if (step == null)
                {
                    return(new PrimitiveExpression((int)pe.Value - 1));
                }
                var stepExpr = step as PrimitiveExpression;
                if (stepExpr != null)
                {
                    return(new PrimitiveExpression((int)pe.Value - (int)stepExpr.Value));
                }
            }

            var bOp = expr as BinaryOperatorExpression;

            if (bOp != null)
            {
                if (bOp.Operator == BinaryOperatorType.Subtract)
                {
                    var right = Add(bOp.Right, step);
                    if (zeroExpr.IsMatch(right))
                    {
                        return(bOp.Left.Clone());
                    }
                    return(new BinaryOperatorExpression(bOp.Left.Clone(), BinaryOperatorType.Subtract, right));
                }
                if (bOp.Operator == BinaryOperatorType.Add)
                {
                    var right = Subtract(bOp.Right, step);
                    if (zeroExpr.IsMatch(right))
                    {
                        return(bOp.Left.Clone());
                    }
                    return(new BinaryOperatorExpression(bOp.Left.Clone(), BinaryOperatorType.Add, Subtract(bOp.Right, step)));
                }
            }
            if (step == null)
            {
                return(new BinaryOperatorExpression(expr.Clone(), BinaryOperatorType.Subtract, new PrimitiveExpression(1)));
            }

            return(new BinaryOperatorExpression(expr.Clone(), BinaryOperatorType.Subtract, AlUtil.AddParensForUnaryExpressionIfRequired(step.Clone())));
        }
Пример #6
0
            public override void VisitUnaryOperatorExpression(UnaryOperatorExpression unaryOperatorExpression)
            {
                base.VisitUnaryOperatorExpression(unaryOperatorExpression);

                if (unaryOperatorExpression.Operator != UnaryOperatorType.Not)
                {
                    return;
                }

                var expr = unaryOperatorExpression.Expression;

                while (expr != null && expr is ParenthesizedExpression)
                {
                    expr = ((ParenthesizedExpression)expr).Expression;
                }

                var binaryOperatorExpr = expr as BinaryOperatorExpression;

                if (binaryOperatorExpr == null)
                {
                    return;
                }
                switch (binaryOperatorExpr.Operator)
                {
                case BinaryOperatorType.BitwiseAnd:
                case BinaryOperatorType.BitwiseOr:
                case BinaryOperatorType.ConditionalAnd:
                case BinaryOperatorType.ConditionalOr:
                case BinaryOperatorType.ExclusiveOr:
                    return;
                }

                var negatedOp = AlUtil.NegateRelationalOperator(binaryOperatorExpr.Operator);

                if (negatedOp == BinaryOperatorType.Any)
                {
                    return;
                }

                if (IsFloatingPoint(binaryOperatorExpr.Left) || IsFloatingPoint(binaryOperatorExpr.Right))
                {
                    if (negatedOp != BinaryOperatorType.Equality && negatedOp != BinaryOperatorType.InEquality)
                    {
                        return;
                    }
                }

                AddIssue(new CodeIssue(unaryOperatorExpression, ctx.TranslateString("Simplify negative relational expression"), ctx.TranslateString("Simplify negative relational expression"),
                                       script => script.Replace(unaryOperatorExpression,
                                                                new BinaryOperatorExpression(binaryOperatorExpr.Left.Clone(), negatedOp,
                                                                                             binaryOperatorExpr.Right.Clone()))));
            }
Пример #7
0
        public override System.Collections.Generic.IEnumerable <CodeAction> GetActions(RefactoringContext context)
        {
            Expression expr = null;
            AstNode    token;

            if (!NegateRelationalExpressionAction.GetLogicalExpression(context, out expr, out token))
            {
                yield break;
            }

            var uOp = expr as UnaryOperatorExpression;

            if (uOp != null)
            {
                yield return(new CodeAction(
                                 string.Format(context.TranslateString("Invert '{0}'"), expr),
                                 script => {
                    script.Replace(uOp, AlUtil.InvertCondition(AlUtil.GetInnerMostExpression(uOp.Expression)));
                }, token
                                 ));

                yield break;
            }

            var negativeExpression = AlUtil.InvertCondition(expr);

            if (expr.Parent is ParenthesizedExpression && expr.Parent.Parent is UnaryOperatorExpression)
            {
                var unaryOperatorExpression = expr.Parent.Parent as UnaryOperatorExpression;
                if (unaryOperatorExpression.Operator == UnaryOperatorType.Not)
                {
                    yield return(new CodeAction(
                                     string.Format(context.TranslateString("Invert '{0}'"), unaryOperatorExpression),
                                     script => {
                        script.Replace(unaryOperatorExpression, negativeExpression);
                    }, token
                                     ));

                    yield break;
                }
            }
            var newExpression = new UnaryOperatorExpression(UnaryOperatorType.Not, new ParenthesizedExpression(negativeExpression));

            yield return(new CodeAction(
                             string.Format(context.TranslateString("Invert '{0}'"), expr),
                             script => {
                script.Replace(expr, newExpression);
            }, token
                             ));
        }
 void AddIssue(AstNode invocationExpression, Match match, bool negate = false)
 {
     AddIssue(new CodeIssue(
                  invocationExpression,
                  ctx.TranslateString("Use 'is' operator"),
                  ctx.TranslateString("Replace with 'is' operator"),
                  s => {
         Expression expression = new IsExpression(AlUtil.AddParensForUnaryExpressionIfRequired(match.Get <Expression>("object").Single().Clone()), match.Get <AstType>("Type").Single().Clone());
         if (negate)
         {
             expression = new UnaryOperatorExpression(UnaryOperatorType.Not, new ParenthesizedExpression(expression));
         }
         s.Replace(invocationExpression, expression);
     }
                  ));
 }
            bool CheckNullComparison(BinaryOperatorExpression binaryOperatorExpression, Expression right, Expression nullNode)
            {
                if (binaryOperatorExpression.Operator != BinaryOperatorType.Equality && binaryOperatorExpression.Operator != BinaryOperatorType.InEquality)
                {
                    return(false);
                }
                // note null == null is checked by similiar expression comparison.
                var expr = AlUtil.GetInnerMostExpression(right);

                var rr = ctx.Resolve(expr);

                if (rr.Type.IsReferenceType == false)
                {
                    // nullable check
                    if (NullableType.IsNullable(rr.Type))
                    {
                        return(false);
                    }

                    var conversion = ctx.GetConversion(nullNode);
                    if (conversion.ConversionAfterUserDefinedOperator == Conversion.IdentityConversion)
                    {
                        return(false);
                    }

                    // check for user operators
                    foreach (var op in rr.Type.GetMethods(m => m.SymbolKind == SymbolKind.Operator && m.Parameters.Count == 2))
                    {
                        if (op.Parameters[0].Type.IsReferenceType == false && op.Parameters[1].Type.IsReferenceType == false)
                        {
                            continue;
                        }
                        if (binaryOperatorExpression.Operator == BinaryOperatorType.Equality && op.Name == "op_Equality")
                        {
                            return(false);
                        }
                        if (binaryOperatorExpression.Operator == BinaryOperatorType.InEquality && op.Name == "op_Inequality")
                        {
                            return(false);
                        }
                    }

                    AddIssue(binaryOperatorExpression, binaryOperatorExpression.Operator != BinaryOperatorType.Equality);
                    return(true);
                }
                return(false);
            }
Пример #10
0
        public override System.Collections.Generic.IEnumerable <CodeAction> GetActions(RefactoringContext context)
        {
            Expression expr = null;
            AstNode    token;

            if (!GetLogicalExpression(context, out expr, out token))
            {
                yield break;
            }
            yield return(new CodeAction(
                             string.Format(context.TranslateString("Negate '{0}'"), expr),
                             script => {
                script.Replace(expr, AlUtil.InvertCondition(expr));
            },
                             token
                             ));
        }
        protected override CodeAction GetAction(RefactoringContext context, UnaryOperatorExpression node)
        {
            if (node.Operator != UnaryOperatorType.PostIncrement && node.Operator != UnaryOperatorType.PostDecrement)
            {
                return(null);
            }
            string desc = node.Operator == UnaryOperatorType.PostIncrement ? context.TranslateString("Replace with '{0} += 1'") : context.TranslateString("Replace with '{0} -= 1'");

            return(new CodeAction(
                       string.Format(desc, AlUtil.GetInnerMostExpression(node.Expression)),
                       s => s.Replace(node, new AssignmentExpression(
                                          AlUtil.GetInnerMostExpression(node.Expression).Clone(),
                                          node.Operator == UnaryOperatorType.PostIncrement ? AssignmentOperatorType.Add : AssignmentOperatorType.Subtract,
                                          new PrimitiveExpression(1)
                                          )),
                       node.OperatorToken
                       ));
        }
Пример #12
0
        public override IEnumerable <CodeAction> GetActions(RefactoringContext context)
        {
            // TODO: Invert if without else
            // ex. if (cond) DoSomething () == if (!cond) return; DoSomething ()
            // beware of loop contexts return should be continue then.

            var ifStatement = GetIfElseStatement(context);

            if (!(ifStatement != null && !ifStatement.TrueStatement.IsNull && !ifStatement.FalseStatement.IsNull))
            {
                yield break;
            }
            yield return(new CodeAction(context.TranslateString("Invert if"), script => {
                script.Replace(ifStatement.Condition, AlUtil.InvertCondition(ifStatement.Condition.Clone()));
                script.Replace(ifStatement.TrueStatement, ifStatement.FalseStatement.Clone());
                script.Replace(ifStatement.FalseStatement, ifStatement.TrueStatement.Clone());
                script.FormatText(ifStatement);
            }, ifStatement));
        }
Пример #13
0
        public static bool GetLogicalExpression(RefactoringContext context, out Expression expr, out AstNode token)
        {
            expr  = null;
            token = null;
            var bOp = context.GetNode <BinaryOperatorExpression>();

            if (bOp != null && bOp.OperatorToken.Contains(context.Location) && AlUtil.IsRelationalOperator(bOp.Operator))
            {
                expr  = bOp;
                token = bOp.OperatorToken;
                return(true);
            }

            var uOp = context.GetNode <UnaryOperatorExpression>();

            if (uOp != null && uOp.OperatorToken.Contains(context.Location) && uOp.Operator == UnaryOperatorType.Not)
            {
                expr  = uOp;
                token = uOp.OperatorToken;
                return(true);
            }
            return(false);
        }
        protected override CodeAction GetAction(RefactoringContext context, ConditionalExpression conditionalExpr)
        {
            if (context.Location != conditionalExpr.Condition.StartLocation && context.Location < conditionalExpr.Condition.EndLocation ||
                context.Location != conditionalExpr.TrueExpression.StartLocation && conditionalExpr.TrueExpression.Contains(context.Location) ||
                context.Location != conditionalExpr.FalseExpression.StartLocation && conditionalExpr.FalseExpression.Contains(context.Location))
            {
                return(null);
            }

            var node = conditionalExpr.GetNodeAt(context.Location);

            if (node == null)
            {
                return(null);
            }

            return(new CodeAction(context.TranslateString("Invert '?:'"), script => {
                script.Replace(conditionalExpr.Condition, AlUtil.InvertCondition(conditionalExpr.Condition.Clone()));
                script.Replace(conditionalExpr.TrueExpression, conditionalExpr.FalseExpression.Clone());
                script.Replace(conditionalExpr.FalseExpression, conditionalExpr.TrueExpression.Clone());
                script.FormatText(conditionalExpr);
            }, node));
        }
Пример #15
0
        protected override CodeAction GetAction(RefactoringContext context, WhileStatement node)
        {
            if (!node.WhileToken.Contains(context.Location))
            {
                return(null);
            }

            return(new CodeAction(
                       context.TranslateString("Extract condition to internal 'if' statement"),
                       script => {
                script.Replace(node.Condition, new PrimitiveExpression(true));
                var ifStmt = new IfElseStatement(
                    AlUtil.InvertCondition(node.Condition),
                    new BreakStatement()
                    );

                var block = node.EmbeddedStatement as BlockStatement;
                if (block != null)
                {
                    script.InsertAfter(block.LBraceToken, ifStmt);
                }
                else
                {
                    var blockStatement = new BlockStatement {
                        ifStmt
                    };
                    if (!(node.EmbeddedStatement is EmptyStatement))
                    {
                        blockStatement.Statements.Add(node.EmbeddedStatement.Clone());
                    }
                    script.Replace(node.EmbeddedStatement, blockStatement);
                }
            },
                       node
                       ));
        }
            public override void VisitBinaryOperatorExpression(BinaryOperatorExpression binaryOperatorExpression)
            {
                if (CheckConstant(binaryOperatorExpression))
                {
                    return;
                }
                if (AlUtil.GetInnerMostExpression(binaryOperatorExpression.Left) is NullReferenceExpression)
                {
                    if (CheckNullComparison(binaryOperatorExpression, binaryOperatorExpression.Right, binaryOperatorExpression.Left))
                    {
                        return;
                    }
                }

                if (AlUtil.GetInnerMostExpression(binaryOperatorExpression.Right) is NullReferenceExpression)
                {
                    if (CheckNullComparison(binaryOperatorExpression, binaryOperatorExpression.Left, binaryOperatorExpression.Right))
                    {
                        return;
                    }
                }

                base.VisitBinaryOperatorExpression(binaryOperatorExpression);
            }
Пример #17
0
        AssignmentExpression GetTransformedAssignmentExpression(RefactoringContext context, ForeachStatement foreachStatement)
        {
            var enumerableToIterate = foreachStatement.InExpression.Clone();

            Statement statement = foreachStatement.EmbeddedStatement;

            Expression leftExpression, rightExpression;

            if (!ExtractExpression(statement, out leftExpression, out rightExpression))
            {
                return(null);
            }
            if (leftExpression == null || rightExpression == null)
            {
                return(null);
            }

            var type = context.Resolve(leftExpression).Type;

            if (!IsLinqSummableType(type))
            {
                return(null);
            }

            if (rightExpression.DescendantsAndSelf.OfType <AssignmentExpression>().Any())
            {
                // Reject loops such as
                // int k = 0;
                // foreach (var x in y) { k += (z = 2); }

                return(null);
            }

            if (rightExpression.DescendantsAndSelf.OfType <UnaryOperatorExpression>().Any(IsUnaryModifierExpression))
            {
                // int k = 0;
                // foreach (var x in y) { k += (z++); }

                return(null);
            }

            var zeroLiteral = new PrimitiveExpression(0);

            Expression baseExpression = enumerableToIterate;

            for (;;)
            {
                ConditionalExpression condition = rightExpression as ConditionalExpression;
                if (condition == null)
                {
                    break;
                }

                if (SameNode(zeroLiteral, condition.TrueExpression))
                {
                    baseExpression = new InvocationExpression(new MemberReferenceExpression(baseExpression.Clone(), "Where"),
                                                              BuildLambda(foreachStatement.VariableName, AlUtil.InvertCondition(condition.Condition)));
                    rightExpression = condition.FalseExpression.Clone();

                    continue;
                }

                if (SameNode(zeroLiteral, condition.FalseExpression))
                {
                    baseExpression = new InvocationExpression(new MemberReferenceExpression(baseExpression.Clone(), "Where"),
                                                              BuildLambda(foreachStatement.VariableName, condition.Condition.Clone()));
                    rightExpression = condition.TrueExpression.Clone();

                    continue;
                }

                break;
            }

            var  primitiveOne   = new PrimitiveExpression(1);
            bool isPrimitiveOne = SameNode(primitiveOne, rightExpression);

            var arguments = new List <Expression>();

            string method = isPrimitiveOne ? "Count" : "Sum";

            if (!isPrimitiveOne && !IsIdentifier(rightExpression, foreachStatement.VariableName))
            {
                var lambda = BuildLambda(foreachStatement.VariableName, rightExpression);

                arguments.Add(lambda);
            }

            var rightSide = new InvocationExpression(new MemberReferenceExpression(baseExpression, method), arguments);

            return(new AssignmentExpression(leftExpression.Clone(), AssignmentOperatorType.Add, rightSide));
        }
            public override void VisitIfElseStatement(IfElseStatement ifElseStatement)
            {
                base.VisitIfElseStatement(ifElseStatement);

                var match = ifPattern.Match(ifElseStatement);

                if (match.Success)
                {
                    var varDeclaration = ifElseStatement.GetPrevSibling(s => s.Role == BlockStatement.StatementRole) as VariableDeclarationStatement;
                    var target         = match.Get <Expression>("target").Single();
                    var match2         = varDelarationPattern.Match(varDeclaration);
                    if (match2.Success)
                    {
                        var initializer = varDeclaration.Variables.FirstOrDefault();
                        if (initializer != null && target is IdentifierExpression && ((IdentifierExpression)target).Identifier != initializer.Name)
                        {
                            return;
                        }
                        var expr = match.Get <Expression>("condition").Single();
                        if (!ConvertIfToOrExpressionIssue.CheckTarget(target, expr))
                        {
                            return;
                        }
                        AddIssue(new CodeIssue(
                                     ifElseStatement.IfToken,
                                     ctx.TranslateString("Convert to '&&' expresssion"),
                                     ctx.TranslateString("Replace with '&&'"),
                                     script => {
                            var variable             = initializer;
                            var initalizerExpression = variable.Initializer.Clone();
                            var bOp = initalizerExpression as BinaryOperatorExpression;
                            if (bOp != null && bOp.Operator == BinaryOperatorType.ConditionalOr)
                            {
                                initalizerExpression = new ParenthesizedExpression(initalizerExpression);
                            }
                            script.Replace(
                                varDeclaration,
                                new VariableDeclarationStatement(
                                    varDeclaration.Type.Clone(),
                                    variable.Name,
                                    new BinaryOperatorExpression(initalizerExpression, BinaryOperatorType.ConditionalAnd, AlUtil.InvertCondition(expr))
                                    )
                                );
                            script.Remove(ifElseStatement);
                        }
                                     )
                        {
                            IssueMarker = IssueMarker.DottedLine
                        });
                        return;
                    }
                    else
                    {
                        var expr = match.Get <Expression>("condition").Single();
                        if (!ConvertIfToOrExpressionIssue.CheckTarget(target, expr))
                        {
                            return;
                        }
                        AddIssue(new CodeIssue(
                                     ifElseStatement.IfToken,
                                     ctx.TranslateString("Convert to '&=' expresssion"),
                                     ctx.TranslateString("Replace with '&='"),
                                     script =>
                                     script.Replace(
                                         ifElseStatement,
                                         new ExpressionStatement(
                                             new AssignmentExpression(
                                                 target.Clone(),
                                                 AssignmentOperatorType.BitwiseAnd,
                                                 AlUtil.InvertCondition(expr)
                                                 )
                                             )
                                         )
                                     )
                        {
                            IssueMarker = IssueMarker.DottedLine
                        });
                    }
                }
            }
Пример #19
0
            public override void VisitConditionalExpression(ConditionalExpression conditionalExpression)
            {
                base.VisitConditionalExpression(conditionalExpression);

                bool?trueBranch  = GetBool(AlUtil.GetInnerMostExpression(conditionalExpression.TrueExpression));
                bool?falseBranch = GetBool(AlUtil.GetInnerMostExpression(conditionalExpression.FalseExpression));

                if (trueBranch == falseBranch ||
                    trueBranch == true && falseBranch == false)                 // Handled by RedundantTernaryExpressionIssue
                {
                    return;
                }

                AddIssue(new CodeIssue(
                             conditionalExpression.QuestionMarkToken.StartLocation,
                             conditionalExpression.FalseExpression.EndLocation,
                             ctx.TranslateString("Simplify conditional expression"),
                             ctx.TranslateString("Simplify conditional expression"),
                             script => {
                    if (trueBranch == false && falseBranch == true)
                    {
                        script.Replace(conditionalExpression, AlUtil.InvertCondition(conditionalExpression.Condition));
                        return;
                    }
                    if (trueBranch == true)
                    {
                        script.Replace(
                            conditionalExpression,
                            new BinaryOperatorExpression(
                                conditionalExpression.Condition.Clone(),
                                BinaryOperatorType.ConditionalOr,
                                conditionalExpression.FalseExpression.Clone()
                                )
                            );
                        return;
                    }

                    if (trueBranch == false)
                    {
                        script.Replace(
                            conditionalExpression,
                            new BinaryOperatorExpression(
                                AlUtil.InvertCondition(conditionalExpression.Condition),
                                BinaryOperatorType.ConditionalAnd,
                                conditionalExpression.FalseExpression.Clone()
                                )
                            );
                        return;
                    }

                    if (falseBranch == true)
                    {
                        script.Replace(
                            conditionalExpression,
                            new BinaryOperatorExpression(
                                AlUtil.InvertCondition(conditionalExpression.Condition),
                                BinaryOperatorType.ConditionalOr,
                                conditionalExpression.TrueExpression.Clone()
                                )
                            );
                        return;
                    }

                    if (falseBranch == false)
                    {
                        script.Replace(
                            conditionalExpression,
                            new BinaryOperatorExpression(
                                conditionalExpression.Condition.Clone(),
                                BinaryOperatorType.ConditionalAnd,
                                conditionalExpression.TrueExpression.Clone()
                                )
                            );
                        return;
                    }

                    // Should never happen
                }
                             ));
            }
Пример #20
0
        static CodeAction HandleNegatedCase(BaseRefactoringContext ctx, IfElseStatement ifElseStatement, Match match, out IsExpression isExpression, out int foundCastCount)
        {
            foundCastCount = 0;
            var outerIs = match.Get <Expression>("isExpression").Single();

            isExpression = AlUtil.GetInnerMostExpression(outerIs) as IsExpression;
            var obj        = AlUtil.GetInnerMostExpression(isExpression.Expression);
            var castToType = isExpression.Type;

            var cast = new Choice {
                PatternHelper.OptionalParentheses(PatternHelper.OptionalParentheses(obj.Clone()).CastTo(castToType.Clone())),
                PatternHelper.OptionalParentheses(PatternHelper.OptionalParentheses(obj.Clone()).CastAs(castToType.Clone()))
            };

            var rr = ctx.Resolve(castToType);

            if (rr == null || rr.IsError || rr.Type.IsReferenceType == false)
            {
                return(null);
            }
            var foundCasts = ifElseStatement.GetParent <BlockStatement>().DescendantNodes(n => n.StartLocation >= ifElseStatement.StartLocation && !cast.IsMatch(n)).Where(n => cast.IsMatch(n)).ToList();

            foundCastCount = foundCasts.Count;

            return(new CodeAction(ctx.TranslateString("Use 'as' and check for null"), script => {
                var varName = ctx.GetNameProposal(CreateMethodDeclarationAction.GuessNameFromType(rr.Type), ifElseStatement.StartLocation);
                var varDec = new VariableDeclarationStatement(new PrimitiveType("var"), varName, new AsExpression(obj.Clone(), castToType.Clone()));
                var binaryOperatorIdentifier = new IdentifierExpression(varName);
                var binaryOperatorExpression = new BinaryOperatorExpression(binaryOperatorIdentifier, BinaryOperatorType.Equality, new NullReferenceExpression());
                var linkedNodes = new List <AstNode>();
                linkedNodes.Add(varDec.Variables.First().NameToken);
                linkedNodes.Add(binaryOperatorIdentifier);
                if (IsEmbeddedStatement(ifElseStatement))
                {
                    var block = new BlockStatement();
                    block.Add(varDec);
                    var newIf = (IfElseStatement)ifElseStatement.Clone();
                    newIf.Condition = binaryOperatorExpression;
                    foreach (var node in newIf.DescendantNodesAndSelf(n => !cast.IsMatch(n)).Where(n => cast.IsMatch(n)))
                    {
                        var id = new IdentifierExpression(varName);
                        linkedNodes.Add(id);
                        node.ReplaceWith(id);
                    }
                    block.Add(newIf);
                    script.Replace(ifElseStatement, block);
                }
                else
                {
                    script.InsertBefore(ifElseStatement, varDec);
                    script.Replace(ifElseStatement.Condition, binaryOperatorExpression);
                    foreach (var c in foundCasts)
                    {
                        var id = new IdentifierExpression(varName);
                        linkedNodes.Add(id);
                        script.Replace(c, id);
                    }
                }
                script.Link(linkedNodes);
            }, isExpression.IsToken));
        }