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);
		}
示例#3
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
                             ));
        }
示例#4
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
                             ));
        }
示例#5
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));
        }
        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));
        }
示例#7
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
                       ));
        }
示例#8
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));
        }
示例#9
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
                }
                             ));
            }
            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
                        });
                    }
                }
            }