コード例 #1
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 = CSharpUtil.GetInnerMostExpression(outerIs) as IsExpression;
            var obj        = CSharpUtil.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));
        }
コード例 #2
0
        protected override CodeAction GetAction(RefactoringContext ctx, IfElseStatement ifElseStatement)
        {
            var isExpr = ctx.GetNode <IsExpression>();

            if (isExpr == null || !isExpr.IsToken.Contains(ctx.Location))
            {
                return(null);
            }

            int foundCasts;
            var action = ScanIfElse(ctx, ifElseStatement, out isExpr, out foundCasts);

            if (action != null)
            {
                return(action);
            }

            isExpr = ctx.GetNode <IsExpression>();
            var node = isExpr.Parent;

            while (node is ParenthesizedExpression)
            {
                node = node.Parent;
            }
            var uOp = node as UnaryOperatorExpression;

            if (uOp != null && uOp.Operator == UnaryOperatorType.Not)
            {
                var rr = ctx.Resolve(isExpr.Type);
                if (rr == null || rr.IsError || rr.Type.IsReferenceType == false)
                {
                    return(null);
                }

                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(isExpr.Expression.Clone(), isExpr.Type.Clone()));
                    var binaryOperatorIdentifier = new IdentifierExpression(varName);
                    var binaryOperatorExpression = new BinaryOperatorExpression(binaryOperatorIdentifier, BinaryOperatorType.Equality, new NullReferenceExpression());
                    if (IsEmbeddedStatement(ifElseStatement))
                    {
                        var block = new BlockStatement();
                        block.Add(varDec);
                        var newIf = (IfElseStatement)ifElseStatement.Clone();
                        newIf.Condition = binaryOperatorExpression;
                        block.Add(newIf);
                        script.Replace(ifElseStatement, block);
                    }
                    else
                    {
                        script.InsertBefore(ifElseStatement, varDec);
                        script.Replace(uOp, binaryOperatorExpression);
                    }
                }, isExpr.IsToken));
            }

            var obj        = isExpr.Expression;
            var castToType = isExpr.Type;

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

            var rr2 = ctx.Resolve(castToType);

            if (rr2 == null || rr2.IsError || rr2.Type.IsReferenceType == false)
            {
                return(null);
            }
            var foundCasts2 = isExpr.GetParent <Statement>().DescendantNodesAndSelf(n => !cast.IsMatch(n)).Where(n => isExpr.StartLocation < n.StartLocation && cast.IsMatch(n)).ToList();

            return(new CodeAction(ctx.TranslateString("Use 'as' and check for null"), script => {
                var varName = ctx.GetNameProposal(CreateMethodDeclarationAction.GuessNameFromType(rr2.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.InEquality, 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 node2 in newIf.DescendantNodesAndSelf(n => !cast.IsMatch(n)).Where(n => cast.IsMatch(n)))
                    {
                        var id = new IdentifierExpression(varName);
                        linkedNodes.Add(id);
                        node2.ReplaceWith(id);
                    }
                    block.Add(newIf);
                    script.Replace(ifElseStatement, block);
                }
                else
                {
                    script.InsertBefore(ifElseStatement, varDec);
                    script.Replace(isExpr, binaryOperatorExpression);
                    foreach (var c in foundCasts2)
                    {
                        var id = new IdentifierExpression(varName);
                        linkedNodes.Add(id);
                        script.Replace(c, id);
                    }
                }
                script.Link(linkedNodes);
            }, isExpr.IsToken));
        }