private static async Task <Document> UseExceptionFilterAsync(
            Document document,
            IfStatementSyntax ifStatement,
            CancellationToken cancellationToken)
        {
            ElseClauseSyntax elseClause = ifStatement.Else;

            var catchClause = (CatchClauseSyntax)ifStatement.Parent.Parent;

            SyntaxList <StatementSyntax> statements = catchClause.Block.Statements;

            ExpressionSyntax filterExpression = ifStatement.Condition;

            SyntaxList <StatementSyntax> newStatements;

            if (ifStatement.Statement.SingleNonBlockStatementOrDefault() is ThrowStatementSyntax throwStatement &&
                throwStatement.Expression == null)
            {
                if (elseClause != null)
                {
                    newStatements = ReplaceStatement(elseClause.Statement);
                }
                else
                {
                    newStatements = statements.RemoveAt(0);
                }

                SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

                filterExpression = SyntaxInverter.LogicallyInvert(filterExpression, semanticModel, cancellationToken);
            }
        private static async Task <ExpressionSyntax> CreateNewNodeAsync(
            Document document,
            BinaryExpressionSyntax binaryExpression,
            CancellationToken cancellationToken)
        {
            ExpressionSyntax left  = binaryExpression.Left;
            ExpressionSyntax right = binaryExpression.Right;

            SyntaxTriviaList trivia = binaryExpression
                                      .DescendantTrivia(TextSpan.FromBounds(left.Span.End, right.SpanStart))
                                      .ToSyntaxTriviaList()
                                      .EmptyIfWhitespace();

            SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            if (CSharpFacts.IsBooleanLiteralExpression(left.Kind()))
            {
                SyntaxTriviaList leadingTrivia = binaryExpression.GetLeadingTrivia().AddRange(trivia);

                if (right.IsKind(SyntaxKind.LogicalNotExpression))
                {
                    var logicalNot = (PrefixUnaryExpressionSyntax)right;

                    ExpressionSyntax operand = logicalNot.Operand;

                    if (semanticModel.GetTypeInfo(operand, cancellationToken).ConvertedType.IsNullableOf(SpecialType.System_Boolean))
                    {
                        return(binaryExpression
                               .WithLeft(SyntaxInverter.LogicallyInvert(left, semanticModel, cancellationToken))
                               .WithRight(operand.WithTriviaFrom(right)));
                    }
                }

                return(SyntaxInverter.LogicallyInvert(right, semanticModel, cancellationToken)
                       .WithLeadingTrivia(leadingTrivia));
            }
            else if (CSharpFacts.IsBooleanLiteralExpression(right.Kind()))
            {
                SyntaxTriviaList trailingTrivia = trivia.AddRange(binaryExpression.GetTrailingTrivia());

                if (left.IsKind(SyntaxKind.LogicalNotExpression))
                {
                    var logicalNot = (PrefixUnaryExpressionSyntax)left;

                    ExpressionSyntax operand = logicalNot.Operand;

                    if (semanticModel.GetTypeInfo(operand, cancellationToken).ConvertedType.IsNullableOf(SpecialType.System_Boolean))
                    {
                        return(binaryExpression
                               .WithLeft(operand.WithTriviaFrom(left))
                               .WithRight(SyntaxInverter.LogicallyInvert(right, semanticModel, cancellationToken)));
                    }
                }

                return(SyntaxInverter.LogicallyInvert(left, semanticModel, cancellationToken)
                       .WithTrailingTrivia(trailingTrivia));
            }

            throw new InvalidOperationException();
        }
예제 #3
0
        private static async Task <Document> InvertIfElseAsync(
            Document document,
            IfStatementSyntax ifStatement,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            cancellationToken.ThrowIfCancellationRequested();

            ElseClauseSyntax elseClause = ifStatement.Else;
            StatementSyntax  whenTrue   = ifStatement.Statement;
            StatementSyntax  whenFalse  = elseClause.Statement;

            SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            IfStatementSyntax newIfStatement = ifStatement.Update(
                ifKeyword: ifStatement.IfKeyword,
                openParenToken: ifStatement.OpenParenToken,
                condition: SyntaxInverter.LogicallyInvert(ifStatement.Condition, semanticModel, cancellationToken),
                closeParenToken: ifStatement.CloseParenToken,
                statement: whenFalse.WithTriviaFrom(whenTrue),
                @else: elseClause.WithStatement(whenTrue.WithTriviaFrom(whenFalse)));

            newIfStatement = newIfStatement.WithFormatterAnnotation();

            return(await document.ReplaceNodeAsync(ifStatement, newIfStatement, cancellationToken).ConfigureAwait(false));
        }
예제 #4
0
        private static async Task <Document> RefactorAsync(
            Document document,
            ExpressionSyntax expression,
            CancellationToken cancellationToken)
        {
            SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            ExpressionSyntax newNode = SyntaxInverter.LogicallyInvert(expression, semanticModel, cancellationToken);

            return(await document.ReplaceNodeAsync(expression, newNode, cancellationToken).ConfigureAwait(false));
        }
예제 #5
0
        private static ExpressionSyntax GetBooleanExpression(
            ExpressionSyntax condition,
            ExpressionSyntax expression1,
            ExpressionSyntax expression2,
            SemanticModel semanticModel,
            CancellationToken cancellationToken = default)
        {
            switch (expression1.Kind())
            {
            case SyntaxKind.TrueLiteralExpression:
            {
                switch (expression2.Kind())
                {
                case SyntaxKind.TrueLiteralExpression:
                    return(expression2);

                case SyntaxKind.FalseLiteralExpression:
                    return(condition);

                default:
                    return(LogicalOrExpression(condition, expression2));
                }
            }

            case SyntaxKind.FalseLiteralExpression:
            {
                switch (expression2.Kind())
                {
                case SyntaxKind.TrueLiteralExpression:
                    return(SyntaxInverter.LogicallyInvert(condition, semanticModel, cancellationToken));

                case SyntaxKind.FalseLiteralExpression:
                    return(expression2);

                default:
                    return(LogicalAndExpression(SyntaxInverter.LogicallyInvert(condition, semanticModel, cancellationToken), expression2));
                }
            }

            default:
            {
                switch (expression2.Kind())
                {
                case SyntaxKind.TrueLiteralExpression:
                    return(LogicalOrExpression(SyntaxInverter.LogicallyInvert(condition, semanticModel, cancellationToken), expression1));

                case SyntaxKind.FalseLiteralExpression:
                    return(LogicalAndExpression(condition, expression1));

                default:
                    throw new InvalidOperationException();
                }
            }
            }
예제 #6
0
        private static ExpressionSyntax GetNewNode(PrefixUnaryExpressionSyntax logicalNot)
        {
            ExpressionSyntax operand    = logicalNot.Operand;
            ExpressionSyntax expression = operand.WalkDownParentheses();

            switch (expression.Kind())
            {
            case SyntaxKind.TrueLiteralExpression:
            case SyntaxKind.FalseLiteralExpression:
            {
                LiteralExpressionSyntax newNode = BooleanLiteralExpression(expression.Kind() == SyntaxKind.FalseLiteralExpression);

                newNode = newNode.WithTriviaFrom(expression);

                return(operand.ReplaceNode(expression, newNode));
            }

            case SyntaxKind.LogicalNotExpression:
            {
                return(((PrefixUnaryExpressionSyntax)expression).Operand);
            }

            case SyntaxKind.EqualsExpression:
            case SyntaxKind.NotEqualsExpression:
            case SyntaxKind.LessThanExpression:
            case SyntaxKind.LessThanOrEqualExpression:
            case SyntaxKind.GreaterThanExpression:
            case SyntaxKind.GreaterThanOrEqualExpression:
            {
                BinaryExpressionSyntax newExpression = SyntaxInverter.InvertBinaryExpression((BinaryExpressionSyntax)expression);

                return(operand.ReplaceNode(expression, newExpression));
            }

            case SyntaxKind.InvocationExpression:
            {
                var invocationExpression = (InvocationExpressionSyntax)expression;

                var memberAccessExpression = (MemberAccessExpressionSyntax)invocationExpression.Expression;

                ExpressionSyntax lambdaExpression = invocationExpression.ArgumentList.Arguments[0].Expression.WalkDownParentheses();

                SingleParameterLambdaExpressionInfo lambdaInfo = SyntaxInfo.SingleParameterLambdaExpressionInfo(lambdaExpression);

                var logicalNot2 = (PrefixUnaryExpressionSyntax)SimplifyLogicalNegationAnalyzer.GetReturnExpression(lambdaInfo.Body).WalkDownParentheses();

                InvocationExpressionSyntax newNode = invocationExpression.ReplaceNode(logicalNot2, logicalNot2.Operand.WithTriviaFrom(logicalNot2));

                return(SyntaxRefactorings.ChangeInvokedMethodName(newNode, (memberAccessExpression.Name.Identifier.ValueText == "All") ? "Any" : "All"));
            }
            }

            return(null);
        }
예제 #7
0
        private static Task <Document> IfToReturnWithExpressionAsync(
            Document document,
            IfToReturnWithExpressionAnalysis analysis,
            CancellationToken cancellationToken = default)
        {
            ExpressionSyntax expression = analysis.Expression;

            if (analysis.Invert)
            {
                expression = SyntaxInverter.LogicallyInvert(expression, analysis.SemanticModel, cancellationToken);
            }

            StatementSyntax statement;

            if (analysis.IsYield)
            {
                statement = YieldReturnStatement(expression);
            }
            else
            {
                statement = ReturnStatement(expression);
            }

            IfStatementSyntax ifStatement = analysis.IfStatement;

            if (ifStatement.IsSimpleIf())
            {
                StatementListInfo statementsInfo = SyntaxInfo.StatementListInfo(ifStatement);

                SyntaxList <StatementSyntax> statements = statementsInfo.Statements;

                int index = statements.IndexOf(ifStatement);

                StatementSyntax newNode = statement
                                          .WithLeadingTrivia(ifStatement.GetLeadingTrivia())
                                          .WithTrailingTrivia(statements[index + 1].GetTrailingTrivia())
                                          .WithFormatterAnnotation();

                SyntaxList <StatementSyntax> newStatements = statements
                                                             .RemoveAt(index)
                                                             .ReplaceAt(index, newNode);

                return(document.ReplaceStatementsAsync(statementsInfo, newStatements, cancellationToken));
            }
            else
            {
                StatementSyntax newNode = statement
                                          .WithTriviaFrom(ifStatement)
                                          .WithFormatterAnnotation();

                return(document.ReplaceNodeAsync(ifStatement, newNode, cancellationToken));
            }
        }
예제 #8
0
        public static async Task <Document> RefactorAsync(
            Document document,
            BinaryExpressionSyntax binaryExpression,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            ExpressionSyntax newNode = SyntaxInverter.LogicallyInvert(binaryExpression, semanticModel, cancellationToken);

            newNode = newNode.WithFormatterAnnotation();

            return(await document.ReplaceNodeAsync(binaryExpression, newNode, cancellationToken).ConfigureAwait(false));
        }
예제 #9
0
        private static Task <Document> IfElseToAssignmentWithConditionAsync(
            Document document,
            IfElseToAssignmentWithConditionAnalysis analysis,
            CancellationToken cancellationToken = default)
        {
            ExpressionSyntax right = analysis.Right;

            if (analysis.Invert)
            {
                right = SyntaxInverter.LogicallyInvert(right, analysis.SemanticModel, cancellationToken);
            }

            ExpressionStatementSyntax newNode = SimpleAssignmentStatement(analysis.Left.WithoutTrivia(), right.WithoutTrivia())
                                                .WithTriviaFrom(analysis.IfStatement)
                                                .WithFormatterAnnotation();

            return(document.ReplaceNodeAsync(analysis.IfStatement, newNode, cancellationToken));
        }
        public static async Task <Document> RefactorAsync(
            Document document,
            ConditionalExpressionSyntax conditionalExpression,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            ConditionalExpressionSyntax newNode = conditionalExpression.Update(
                condition: SyntaxInverter.LogicallyInvert(conditionalExpression.Condition, semanticModel, cancellationToken),
                questionToken: conditionalExpression.QuestionToken,
                whenTrue: conditionalExpression.WhenFalse.WithTriviaFrom(conditionalExpression.WhenTrue),
                colonToken: conditionalExpression.ColonToken,
                whenFalse: conditionalExpression.WhenTrue.WithTriviaFrom(conditionalExpression.WhenFalse));

            newNode = newNode.WithFormatterAnnotation();

            return(await document.ReplaceNodeAsync(conditionalExpression, newNode, cancellationToken).ConfigureAwait(false));
        }
예제 #11
0
        public static async Task <Document> RefactorAsync(
            Document document,
            InvocationExpressionSyntax invocationExpression,
            string memberName,
            ExpressionSyntax expression,
            CancellationToken cancellationToken = default)
        {
            var memberAccessExpression = (MemberAccessExpressionSyntax)invocationExpression.Expression;

            MemberAccessExpressionSyntax newMemberAccessExpression = memberAccessExpression
                                                                     .WithName(SyntaxFactory.IdentifierName(memberName).WithTriviaFrom(memberAccessExpression.Name));

            SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            InvocationExpressionSyntax newNode = invocationExpression
                                                 .ReplaceNode(expression, SyntaxInverter.LogicallyInvert(expression, semanticModel, cancellationToken))
                                                 .WithExpression(newMemberAccessExpression);

            return(await document.ReplaceNodeAsync(invocationExpression, newNode, cancellationToken).ConfigureAwait(false));
        }
예제 #12
0
        public static async Task <Document> InvertIfAsync(
            Document document,
            IfStatementSyntax ifStatement,
            bool recursive = false,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            cancellationToken.ThrowIfCancellationRequested();

            StatementSyntax statement = ifStatement.Statement;

            StatementListInfo statementsInfo = SyntaxInfo.StatementListInfo(ifStatement);

            SyntaxList <StatementSyntax> statements = statementsInfo.Statements;

            InvertIfAnalysis analysis = InvertIfAnalysis.Create(ifStatement, statement);

            int ifStatementIndex = statements.IndexOf(ifStatement);

            StatementSyntax lastStatement = analysis.LastStatement;

            int lastStatementIndex = statements.IndexOf(lastStatement);

            bool isLastStatementRedundant = IsLastStatementRedundant();

            bool shouldUseElseClause = !CSharpFacts.IsJumpStatement(lastStatement.Kind());

            SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            SyntaxList <StatementSyntax> newStatements = statements;

            if (!recursive)
            {
                Refactor();
            }
            else
            {
                IfStatementSyntax lastIfStatement;

                InvertIfAnalysis a = analysis.AnalyzeNextStatement();

                do
                {
                    lastIfStatement = a.IfStatement;

                    a = a.AnalyzeNextStatement();
                } while (a.Success);

                int firstLastStatementIndex = lastStatementIndex;

                int index = statements.IndexOf(lastIfStatement);

                int firstIndex = ifStatementIndex;

                while (index >= firstIndex)
                {
                    ifStatementIndex = index;
                    ifStatement      = (IfStatementSyntax)statements[ifStatementIndex];
                    statement        = ifStatement.Statement;
                    Refactor();
                    lastStatementIndex = firstLastStatementIndex + newStatements.Count - statements.Count;
                    lastStatement      = (statement is BlockSyntax block) ? block.Statements.Last() : statement;
                    index--;
                }
            }

            return(await document.ReplaceStatementsAsync(statementsInfo, newStatements, cancellationToken).ConfigureAwait(false));

            void Refactor()
            {
                cancellationToken.ThrowIfCancellationRequested();

                SyntaxList <StatementSyntax> nextStatements = newStatements
                                                              .Skip(ifStatementIndex + 1)
                                                              .Take(lastStatementIndex - ifStatementIndex)
                                                              .ToSyntaxList()
                                                              .TrimTrivia();

                BlockSyntax newStatement;
                SyntaxList <StatementSyntax> newNextStatements;

                if (statement is BlockSyntax block)
                {
                    newStatement      = block.WithStatements(nextStatements);
                    newNextStatements = block.Statements;
                }
                else
                {
                    newStatement      = Block(nextStatements);
                    newNextStatements = SingletonList(statement);
                }

                if (isLastStatementRedundant)
                {
                    newNextStatements = newNextStatements.RemoveAt(newNextStatements.Count - 1);
                }

                ElseClauseSyntax elseClause = null;

                if (newNextStatements.Any() &&
                    shouldUseElseClause)
                {
                    elseClause        = ElseClause(Block(newNextStatements));
                    newNextStatements = default;
                }

                IfStatementSyntax newIfStatement = ifStatement.Update(
                    ifKeyword: ifStatement.IfKeyword,
                    openParenToken: ifStatement.OpenParenToken,
                    condition: SyntaxInverter.LogicallyInvert(ifStatement.Condition, semanticModel, cancellationToken),
                    closeParenToken: ifStatement.CloseParenToken,
                    statement: newStatement,
                    @else: elseClause);

                newIfStatement = newIfStatement.WithFormatterAnnotation();

                SyntaxList <StatementSyntax> newNodes = newNextStatements.Insert(0, newIfStatement);

                newStatements = newStatements.ReplaceRange(ifStatementIndex, lastStatementIndex - ifStatementIndex + 1, newNodes);
            }

            bool IsLastStatementRedundant()
            {
                StatementSyntax jumpStatement = analysis.JumpStatement;

                switch (jumpStatement.Kind())
                {
                case SyntaxKind.ReturnStatement:
                {
                    if (((ReturnStatementSyntax)jumpStatement).Expression == null &&
                        RemoveRedundantStatementAnalysis.IsFixable(lastStatement, SyntaxKind.ReturnStatement))
                    {
                        return(true);
                    }

                    break;
                }

                case SyntaxKind.ContinueStatement:
                {
                    if (RemoveRedundantStatementAnalysis.IsFixable(lastStatement, SyntaxKind.ContinueStatement))
                    {
                        return(true);
                    }

                    break;
                }
                }

                return(false);
            }
        }
예제 #13
0
        private static async Task <Document> RefactorAsync(
            Document document,
            IfStatementSyntax ifStatement,
            CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();

            ExpressionSyntax condition = ifStatement.Condition;

            ElseClauseSyntax elseClause = ifStatement.Else;

            SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            SimplifyCodeBranchingKind kind = SimplifyCodeBranchingAnalyzer.GetKind(ifStatement, semanticModel, cancellationToken).Value;

            if (kind == SimplifyCodeBranchingKind.IfElseWithEmptyIf)
            {
                ExpressionSyntax newCondition = SyntaxInverter.LogicallyInvert(condition, semanticModel, cancellationToken);

                StatementSyntax statement = elseClause.Statement;

                if (statement is IfStatementSyntax nestedIf)
                {
                    newCondition = LogicalAndExpression(newCondition.Parenthesize(), nestedIf.Condition.Parenthesize());

                    statement = nestedIf.Statement;
                }

                IfStatementSyntax newIfStatement = ifStatement.Update(
                    ifStatement.IfKeyword,
                    ifStatement.OpenParenToken,
                    newCondition,
                    ifStatement.CloseParenToken,
                    statement,
                    default(ElseClauseSyntax));

                newIfStatement = newIfStatement.WithFormatterAnnotation();

                return(await document.ReplaceNodeAsync(ifStatement, newIfStatement, cancellationToken).ConfigureAwait(false));
            }
            else if (kind == SimplifyCodeBranchingKind.IfElseInsideWhile)
            {
                bool elseContainsBreak = elseClause.SingleNonBlockStatementOrDefault()?.Kind() == SyntaxKind.BreakStatement;

                SyntaxList <StatementSyntax> statements;

                if (elseContainsBreak)
                {
                    statements = (ifStatement.Statement is BlockSyntax block2)
                        ? block2.Statements
                        : SingletonList(ifStatement.Statement);
                }
                else
                {
                    statements = (elseClause.Statement is BlockSyntax block2)
                        ? block2.Statements
                        : SingletonList(elseClause.Statement);
                }

                WhileStatementSyntax whileStatement;

                if (ifStatement.Parent is BlockSyntax block)
                {
                    whileStatement = (WhileStatementSyntax)block.Parent;

                    block = block.WithStatements(block.Statements.ReplaceRange(ifStatement, statements));
                }
                else
                {
                    whileStatement = (WhileStatementSyntax)ifStatement.Parent;

                    block = Block(statements);
                }

                if (!elseContainsBreak)
                {
                    condition = SyntaxInverter.LogicallyInvert(condition, semanticModel, cancellationToken);
                }

                WhileStatementSyntax newWhileStatement = whileStatement.Update(
                    whileStatement.WhileKeyword,
                    whileStatement.OpenParenToken,
                    condition,
                    whileStatement.CloseParenToken,
                    block);

                newWhileStatement = newWhileStatement.WithFormatterAnnotation();

                return(await document.ReplaceNodeAsync(whileStatement, newWhileStatement, cancellationToken).ConfigureAwait(false));
            }
            else if (kind == SimplifyCodeBranchingKind.SimplifIfInsideWhileOrDo)
            {
                var block = (BlockSyntax)ifStatement.Parent;

                SyntaxList <StatementSyntax> statements = block.Statements;

                BlockSyntax newBlock = block.WithStatements(statements.Remove(ifStatement));

                ExpressionSyntax newCondition = SyntaxInverter.LogicallyInvert(condition, semanticModel, cancellationToken);

                SyntaxNode newNode;

                switch (block.Parent)
                {
                case WhileStatementSyntax whileStatement:
                {
                    if (statements.IsFirst(ifStatement))
                    {
                        newNode = whileStatement.Update(
                            whileStatement.WhileKeyword,
                            whileStatement.OpenParenToken,
                            newCondition,
                            whileStatement.CloseParenToken,
                            newBlock);
                    }
                    else
                    {
                        newNode = DoStatement(
                            Token(whileStatement.WhileKeyword.LeadingTrivia, SyntaxKind.DoKeyword, whileStatement.CloseParenToken.TrailingTrivia),
                            newBlock.WithoutTrailingTrivia(),
                            Token(SyntaxKind.WhileKeyword),
                            OpenParenToken(),
                            newCondition,
                            CloseParenToken(),
                            SemicolonToken().WithTrailingTrivia(newBlock.GetTrailingTrivia()));
                    }

                    break;
                }

                case DoStatementSyntax doStatement:
                {
                    if (statements.IsLast(ifStatement))
                    {
                        newNode = doStatement.Update(
                            doStatement.DoKeyword,
                            newBlock,
                            doStatement.WhileKeyword,
                            doStatement.OpenParenToken,
                            newCondition,
                            doStatement.CloseParenToken,
                            doStatement.SemicolonToken);
                    }
                    else
                    {
                        newNode = WhileStatement(
                            Token(doStatement.DoKeyword.LeadingTrivia, SyntaxKind.WhileKeyword, SyntaxTriviaList.Empty),
                            OpenParenToken(),
                            newCondition,
                            Token(SyntaxTriviaList.Empty, SyntaxKind.CloseParenToken, doStatement.DoKeyword.TrailingTrivia),
                            newBlock.WithTrailingTrivia(doStatement.GetTrailingTrivia()));
                    }

                    break;
                }

                default:
                {
                    throw new InvalidOperationException();
                }
                }

                newNode = newNode.WithFormatterAnnotation();

                return(await document.ReplaceNodeAsync(block.Parent, newNode, cancellationToken).ConfigureAwait(false));
            }
            else if (kind == SimplifyCodeBranchingKind.SimpleIfContainingOnlyDo)
            {
                StatementSyntax statement = ifStatement.SingleNonBlockStatementOrDefault();

                var doStatement = (DoStatementSyntax)statement;

                WhileStatementSyntax whileStatement = WhileStatement(
                    Token(ifStatement.GetLeadingTrivia(), SyntaxKind.WhileKeyword, SyntaxTriviaList.Empty),
                    OpenParenToken(),
                    doStatement.Condition,
                    Token(SyntaxTriviaList.Empty, SyntaxKind.CloseParenToken, doStatement.DoKeyword.TrailingTrivia),
                    doStatement.Statement.WithTrailingTrivia(ifStatement.GetTrailingTrivia()));

                whileStatement = whileStatement.WithFormatterAnnotation();

                return(await document.ReplaceNodeAsync(ifStatement, whileStatement, cancellationToken).ConfigureAwait(false));
            }
            else
            {
                throw new InvalidOperationException();
            }
        }
예제 #14
0
        private static async Task <Document> RefactorAsync(
            Document document,
            IfStatementSyntax ifStatement,
            CancellationToken cancellationToken)
        {
            ExpressionSyntax condition = ifStatement.Condition;

            ElseClauseSyntax elseClause = ifStatement.Else;

            if ((ifStatement.Statement as BlockSyntax)?.Statements.Any() == false)
            {
                SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

                ExpressionSyntax newCondition = SyntaxInverter.LogicallyInvert(condition, semanticModel, cancellationToken);

                StatementSyntax statement = elseClause.Statement;

                if (statement is IfStatementSyntax nestedIf)
                {
                    newCondition = LogicalAndExpression(newCondition.Parenthesize(), nestedIf.Condition.Parenthesize());

                    statement = nestedIf.Statement;
                }

                cancellationToken.ThrowIfCancellationRequested();

                IfStatementSyntax newNode = ifStatement.Update(
                    ifStatement.IfKeyword,
                    ifStatement.OpenParenToken,
                    newCondition,
                    ifStatement.CloseParenToken,
                    statement,
                    default(ElseClauseSyntax));

                newNode = newNode.WithFormatterAnnotation();

                return(await document.ReplaceNodeAsync(ifStatement, newNode, cancellationToken).ConfigureAwait(false));
            }
            else if (elseClause != null)
            {
                WhileStatementSyntax whileStatement;

                if (ifStatement.Parent is BlockSyntax block)
                {
                    whileStatement = (WhileStatementSyntax)block.Parent;
                }
                else
                {
                    block          = Block();
                    whileStatement = (WhileStatementSyntax)ifStatement.Parent;
                }

                cancellationToken.ThrowIfCancellationRequested();

                BlockSyntax newBlock = (ifStatement.Statement is BlockSyntax ifBlock)
                    ? block.WithStatements(ifBlock.Statements)
                    : block.WithStatements(SingletonList(ifStatement.Statement));

                SyntaxNode newNode = whileStatement.Update(
                    whileStatement.WhileKeyword,
                    whileStatement.OpenParenToken,
                    ifStatement.Condition,
                    whileStatement.CloseParenToken,
                    newBlock);

                newNode = newNode.WithFormatterAnnotation();

                return(await document.ReplaceNodeAsync(whileStatement, newNode, cancellationToken).ConfigureAwait(false));
            }
            else
            {
                StatementSyntax statement = ifStatement.SingleNonBlockStatementOrDefault();

                if (statement.Kind() == SyntaxKind.BreakStatement)
                {
                    var block = (BlockSyntax)ifStatement.Parent;

                    SyntaxList <StatementSyntax> statements = block.Statements;

                    BlockSyntax newBlock = block.WithStatements(statements.Remove(ifStatement));

                    SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

                    ExpressionSyntax newCondition = SyntaxInverter.LogicallyInvert(condition, semanticModel, cancellationToken);

                    SyntaxNode newNode = block.Parent;

                    switch (block.Parent)
                    {
                    case WhileStatementSyntax whileStatement:
                    {
                        cancellationToken.ThrowIfCancellationRequested();

                        if (statements.IsFirst(ifStatement))
                        {
                            newNode = whileStatement.Update(
                                whileStatement.WhileKeyword,
                                whileStatement.OpenParenToken,
                                newCondition,
                                whileStatement.CloseParenToken,
                                newBlock);
                        }
                        else
                        {
                            newNode = DoStatement(
                                Token(whileStatement.WhileKeyword.LeadingTrivia, SyntaxKind.DoKeyword, whileStatement.CloseParenToken.TrailingTrivia),
                                newBlock.WithoutTrailingTrivia(),
                                Token(SyntaxKind.WhileKeyword),
                                OpenParenToken(),
                                newCondition,
                                CloseParenToken(),
                                SemicolonToken().WithTrailingTrivia(newBlock.GetTrailingTrivia()));
                        }

                        break;
                    }

                    case DoStatementSyntax doStatement:
                    {
                        cancellationToken.ThrowIfCancellationRequested();

                        if (statements.IsLast(ifStatement))
                        {
                            newNode = doStatement.Update(
                                doStatement.DoKeyword,
                                newBlock,
                                doStatement.WhileKeyword,
                                doStatement.OpenParenToken,
                                newCondition,
                                doStatement.CloseParenToken,
                                doStatement.SemicolonToken);
                        }
                        else
                        {
                            newNode = WhileStatement(
                                Token(doStatement.DoKeyword.LeadingTrivia, SyntaxKind.WhileKeyword, SyntaxTriviaList.Empty),
                                OpenParenToken(),
                                newCondition,
                                Token(SyntaxTriviaList.Empty, SyntaxKind.CloseParenToken, doStatement.DoKeyword.TrailingTrivia),
                                newBlock.WithTrailingTrivia(doStatement.GetTrailingTrivia()));
                        }

                        break;
                    }

                    default:
                    {
                        Debug.Fail(block.Parent.Kind().ToString());
                        break;
                    }
                    }

                    newNode = newNode.WithFormatterAnnotation();

                    return(await document.ReplaceNodeAsync(block.Parent, newNode, cancellationToken).ConfigureAwait(false));
                }
                else if (statement.Kind() == SyntaxKind.DoStatement)
                {
                    var doStatement = (DoStatementSyntax)statement;

                    WhileStatementSyntax whileStatement = WhileStatement(
                        Token(ifStatement.GetLeadingTrivia(), SyntaxKind.WhileKeyword, SyntaxTriviaList.Empty),
                        OpenParenToken(),
                        doStatement.Condition,
                        Token(SyntaxTriviaList.Empty, SyntaxKind.CloseParenToken, doStatement.DoKeyword.TrailingTrivia),
                        doStatement.Statement.WithTrailingTrivia(ifStatement.GetTrailingTrivia()));

                    whileStatement = whileStatement.WithFormatterAnnotation();

                    return(await document.ReplaceNodeAsync(ifStatement, whileStatement, cancellationToken).ConfigureAwait(false));
                }
            }

            throw new InvalidOperationException();
        }
예제 #15
0
        private static ExpressionSyntax GetBooleanExpression(
            ExpressionSyntax condition,
            ExpressionSyntax expression1,
            ExpressionSyntax expression2,
            SemanticModel semanticModel,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            switch (expression1.Kind())
            {
            case SyntaxKind.TrueLiteralExpression:
            {
                switch (expression2.Kind())
                {
                case SyntaxKind.TrueLiteralExpression:
                    return(expression2);

                case SyntaxKind.FalseLiteralExpression:
                    return(condition);

                default:
                    return(LogicalOrExpression(condition, expression2));
                }
            }

            case SyntaxKind.FalseLiteralExpression:
            {
                switch (expression2.Kind())
                {
                case SyntaxKind.TrueLiteralExpression:
                    return(SyntaxInverter.LogicallyInvert(condition, semanticModel, cancellationToken));

                case SyntaxKind.FalseLiteralExpression:
                    return(expression2);

                default:
                    return(LogicalAndExpression(SyntaxInverter.LogicallyInvert(condition, semanticModel, cancellationToken), expression2));
                }
            }

            default:
            {
                switch (expression2.Kind())
                {
                case SyntaxKind.TrueLiteralExpression:
                    return(LogicalOrExpression(SyntaxInverter.LogicallyInvert(condition, semanticModel, cancellationToken), expression1));

                case SyntaxKind.FalseLiteralExpression:
                    return(LogicalAndExpression(condition, expression1));

                default:
                    throw new InvalidOperationException();
                }
            }
            }

            BinaryExpressionSyntax LogicalAndExpression(ExpressionSyntax left, ExpressionSyntax right)
            {
                return(CSharpFactory.LogicalAndExpression(
                           left.Parenthesize(),
                           right.Parenthesize()));
            }

            BinaryExpressionSyntax LogicalOrExpression(ExpressionSyntax left, ExpressionSyntax right)
            {
                return(CSharpFactory.LogicalOrExpression(
                           left.Parenthesize(),
                           right.Parenthesize()));
            }
        }
        public static async Task <Document> RefactorAsync(
            Document document,
            ConditionalExpressionSyntax conditionalExpression,
            CancellationToken cancellationToken)
        {
            ConditionalExpressionInfo info = SyntaxInfo.ConditionalExpressionInfo(conditionalExpression);

            ExpressionSyntax whenTrue  = info.WhenTrue;
            ExpressionSyntax whenFalse = info.WhenFalse;

            SyntaxKind trueKind  = whenTrue.Kind();
            SyntaxKind falseKind = whenFalse.Kind();

            ExpressionSyntax newNode = null;

            if (trueKind == SyntaxKind.TrueLiteralExpression)
            {
                if (falseKind == SyntaxKind.FalseLiteralExpression)
                {
                    newNode = CreateNewNode(conditionalExpression, info.Condition);
                }
                else
                {
                    SyntaxTriviaList trailingTrivia = info
                                                      .QuestionToken
                                                      .LeadingTrivia
                                                      .AddRange(info.QuestionToken.TrailingTrivia)
                                                      .AddRange(whenTrue.GetLeadingTrivia())
                                                      .EmptyIfWhitespace();

                    newNode = LogicalOrExpression(
                        conditionalExpression.Condition.Parenthesize().AppendToTrailingTrivia(trailingTrivia),
                        Token(info.ColonToken.LeadingTrivia, SyntaxKind.BarBarToken, info.ColonToken.TrailingTrivia),
                        whenFalse.Parenthesize());
                }
            }
            else if (falseKind == SyntaxKind.FalseLiteralExpression)
            {
                SyntaxTriviaList trailingTrivia = whenTrue
                                                  .GetTrailingTrivia()
                                                  .AddRange(info.ColonToken.LeadingTrivia)
                                                  .AddRange(info.ColonToken.TrailingTrivia)
                                                  .AddRange(whenFalse.GetLeadingTrivia())
                                                  .EmptyIfWhitespace()
                                                  .AddRange(whenFalse.GetTrailingTrivia());

                newNode = LogicalAndExpression(
                    conditionalExpression.Condition.Parenthesize(),
                    Token(info.QuestionToken.LeadingTrivia, SyntaxKind.AmpersandAmpersandToken, info.QuestionToken.TrailingTrivia),
                    whenTrue.WithTrailingTrivia(trailingTrivia).Parenthesize());
            }
            else if (trueKind == SyntaxKind.FalseLiteralExpression &&
                     falseKind == SyntaxKind.TrueLiteralExpression)
            {
                SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

                newNode = CreateNewNode(conditionalExpression, SyntaxInverter.LogicallyInvert(info.Condition, semanticModel, cancellationToken));
            }

            newNode = newNode.Parenthesize();

            return(await document.ReplaceNodeAsync(conditionalExpression, newNode, cancellationToken).ConfigureAwait(false));
        }