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);
                }
                             ));
            }
        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())));
        }
Exemple #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
                             ));
        }
            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);
            }
        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
                       ));
        }
            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);
            }
Exemple #7
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
                }
                             ));
            }
Exemple #8
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));
        }