예제 #1
0
 private static Task <Document> RefactorAsync(
     Document document,
     ExpressionSyntax expression,
     CancellationToken cancellationToken)
 {
     return(document.ReplaceNodeAsync(expression, Negator.LogicallyNegate(expression), cancellationToken));
 }
 private static async Task <Document> RefactorAsync(
     Document document,
     ExpressionSyntax expression,
     CancellationToken cancellationToken)
 {
     return(await document.ReplaceNodeAsync(expression, Negator.LogicallyNegate(expression), cancellationToken).ConfigureAwait(false));
 }
예제 #3
0
        public static async Task <Document> RefactorAsync(
            Document document,
            ConditionalExpressionSyntax conditionalExpression,
            CancellationToken cancellationToken)
        {
            SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            ExpressionSyntax condition = conditionalExpression.Condition;

            ExpressionSyntax newNode = (conditionalExpression.WhenTrue.WalkDownParentheses().IsKind(SyntaxKind.TrueLiteralExpression))
                ? condition
                : Negator.LogicallyNegate(condition, semanticModel, cancellationToken);

            SyntaxTriviaList trailingTrivia = conditionalExpression
                                              .DescendantTrivia(TextSpan.FromBounds(condition.Span.End, conditionalExpression.Span.End))
                                              .ToSyntaxTriviaList()
                                              .EmptyIfWhitespace()
                                              .AddRange(conditionalExpression.GetTrailingTrivia());

            newNode = newNode
                      .WithLeadingTrivia(conditionalExpression.GetLeadingTrivia())
                      .WithTrailingTrivia(trailingTrivia);

            return(await document.ReplaceNodeAsync(conditionalExpression, newNode, cancellationToken).ConfigureAwait(false));
        }
예제 #4
0
        public static async Task <Document> RefactorAsync(
            Document document,
            IfStatementSyntax ifStatement,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            ElseClauseSyntax elseClause = ifStatement.Else;
            StatementSyntax  whenTrue   = ifStatement.Statement;
            StatementSyntax  whenFalse  = elseClause.Statement;

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

            ElseClauseSyntax newElseClause = null;

            if ((whenFalse as BlockSyntax)?.Statements.Any() != false)
            {
                newElseClause = elseClause.WithStatement(whenTrue.WithTriviaFrom(whenFalse));
            }

            IfStatementSyntax newIfStatement = ifStatement
                                               .WithCondition(Negator.LogicallyNegate(ifStatement.Condition, semanticModel, cancellationToken))
                                               .WithStatement(whenFalse.WithTriviaFrom(whenTrue))
                                               .WithElse(newElseClause)
                                               .WithFormatterAnnotation();

            return(await document.ReplaceNodeAsync(ifStatement, newIfStatement, cancellationToken).ConfigureAwait(false));
        }
예제 #5
0
        public static async Task <Document> RefactorAsync(
            Document document,
            ConditionalExpressionSyntax conditionalExpression,
            CancellationToken cancellationToken)
        {
            ExpressionSyntax condition = conditionalExpression.Condition;

            ExpressionSyntax newNode = (conditionalExpression.WhenTrue.IsKind(SyntaxKind.TrueLiteralExpression))
                ? condition
                : Negator.LogicallyNegate(condition);

            TextSpan span = TextSpan.FromBounds(
                conditionalExpression.Condition.Span.End,
                conditionalExpression.FullSpan.End);

            IEnumerable <SyntaxTrivia> trivia = conditionalExpression.DescendantTrivia(span);

            if (trivia.Any(f => !f.IsWhitespaceOrEndOfLineTrivia()))
            {
                newNode = newNode.WithTrailingTrivia(trivia);
            }
            else
            {
                newNode = newNode.WithoutTrailingTrivia();
            }

            return(await document.ReplaceNodeAsync(conditionalExpression, newNode, cancellationToken).ConfigureAwait(false));
        }
            public override SyntaxNode VisitBlock(BlockSyntax node)
            {
                _block = node;

                if (node.LastStatementOrDefault(skipLocalFunction: true) is IfStatementSyntax ifStatement &&
                    IsFixable(ifStatement))
                {
                    SyntaxList <StatementSyntax> statements = node.Statements;

                    int index = statements.IndexOf(ifStatement);

                    ifStatement = (IfStatementSyntax)VisitIfStatement(ifStatement);

                    var block = (BlockSyntax)ifStatement.Statement;

                    ExpressionSyntax newCondition = Negator.LogicallyNegate(ifStatement.Condition);

                    IfStatementSyntax newIfStatement = ifStatement
                                                       .WithCondition(newCondition)
                                                       .WithStatement(block.WithStatements(SingletonList(_jumpStatement)))
                                                       .WithFormatterAnnotation();

                    SyntaxList <StatementSyntax> newStatements = statements
                                                                 .ReplaceAt(index, newIfStatement)
                                                                 .InsertRange(index + 1, block.Statements.Select(f => f.WithFormatterAnnotation()));

                    node = node.WithStatements(newStatements);
                }

                return(node);
            }
예제 #7
0
            public override SyntaxNode VisitBlock(BlockSyntax node)
            {
                node = (BlockSyntax)base.VisitBlock(node);

                SyntaxList <StatementSyntax> statements = node.Statements;

                var ifStatement = statements.LastOrDefault(f => !f.IsKind(SyntaxKind.LocalFunctionStatement)) as IfStatementSyntax;

                if (ifStatement != null &&
                    IsFixable(ifStatement) &&
                    ((BlockSyntax)ifStatement.Parent).Statements.IsLastStatement(ifStatement, skipLocalFunction: true))
                {
                    var block = (BlockSyntax)ifStatement.Statement;

                    ExpressionSyntax newCondition = Negator.LogicallyNegate(ifStatement.Condition);

                    IfStatementSyntax newIfStatement = ifStatement
                                                       .WithCondition(newCondition)
                                                       .WithStatement(block.WithStatements(SingletonList(_jumpStatement)))
                                                       .WithFormatterAnnotation();

                    int index = statements.IndexOf(ifStatement);

                    SyntaxList <StatementSyntax> newStatements = statements
                                                                 .ReplaceAt(index, newIfStatement)
                                                                 .InsertRange(index + 1, block.Statements.Select(f => f.WithFormatterAnnotation()));

                    node = node.WithStatements(newStatements);
                }

                return(node);
            }
        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: Negator.LogicallyNegate(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));
        }
예제 #9
0
        public static Task <Document> RefactorAsync(
            Document document,
            BinaryExpressionSyntax binaryExpression,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            ExpressionSyntax newNode = Negator.LogicallyNegate(binaryExpression)
                                       .WithFormatterAnnotation();

            return(document.ReplaceNodeAsync(binaryExpression, newNode, cancellationToken));
        }
        private static async Task <Document> RefactorAsync(
            Document document,
            ExpressionSyntax expression,
            CancellationToken cancellationToken)
        {
            SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            ExpressionSyntax newNode = Negator.LogicallyNegate(expression, semanticModel, cancellationToken);

            return(await document.ReplaceNodeAsync(expression, newNode, cancellationToken).ConfigureAwait(false));
        }
예제 #11
0
        private static Task <Document> IfToReturnWithExpressionAsync(
            Document document,
            IfToReturnWithExpressionAnalysis analysis,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            ExpressionSyntax expression = analysis.Expression;

            if (analysis.Negate)
            {
                expression = Negator.LogicallyNegate(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));
            }
        }
        public static Task <Document> RefactorAsync(
            Document document,
            ConditionalExpressionSyntax conditionalExpression,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            ConditionalExpressionSyntax newConditionalExpression = conditionalExpression
                                                                   .WithCondition(Negator.LogicallyNegate(conditionalExpression.Condition))
                                                                   .WithWhenTrue(conditionalExpression.WhenFalse.WithTriviaFrom(conditionalExpression.WhenTrue))
                                                                   .WithWhenFalse(conditionalExpression.WhenTrue.WithTriviaFrom(conditionalExpression.WhenFalse))
                                                                   .WithFormatterAnnotation();

            return(document.ReplaceNodeAsync(conditionalExpression, newConditionalExpression, cancellationToken));
        }
예제 #13
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 = Negator.LogicallyNegate(binaryExpression, semanticModel, cancellationToken);

            newNode = newNode.WithFormatterAnnotation();

            return(await document.ReplaceNodeAsync(binaryExpression, newNode, cancellationToken).ConfigureAwait(false));
        }
예제 #14
0
        public static ExpressionSyntax GetBooleanExpression(ExpressionSyntax condition, ExpressionSyntax expression1, ExpressionSyntax expression2)
        {
            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(Negator.LogicallyNegate(condition));

                case SyntaxKind.FalseLiteralExpression:
                    return(expression2);

                default:
                    return(LogicalAndExpression(Negator.LogicallyNegate(condition), expression2));
                }
            }

            default:
            {
                switch (expression2.Kind())
                {
                case SyntaxKind.TrueLiteralExpression:
                    return(LogicalOrExpression(Negator.LogicallyNegate(condition), expression1));

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

                default:
                    throw new InvalidOperationException();
                }
            }
            }
        }
        private static ReturnStatementSyntax CreateReturnStatement(IfStatementSyntax ifStatement)
        {
            ExpressionSyntax expression = ifStatement.Condition;

            if (GetBooleanLiteral(ifStatement.Statement).IsKind(SyntaxKind.FalseLiteralExpression))
            {
                expression = Negator.LogicallyNegate(expression);
            }

            return(ReturnStatement(
                       ReturnKeyword().WithTrailingTrivia(Space),
                       expression,
                       SemicolonToken()));
        }
예제 #16
0
        public static ExpressionSyntax GetBooleanExpression(ExpressionSyntax condition, ExpressionSyntax expression1, ExpressionSyntax expression2)
        {
            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(Negator.LogicallyNegate(condition));

                case SyntaxKind.FalseLiteralExpression:
                    return(expression2);

                default:
                    return(LogicalOrExpression(Negator.LogicallyNegate(condition), expression2));
                }
            }

            default:
            {
                switch (expression2.Kind())
                {
                case SyntaxKind.TrueLiteralExpression:
                    return(LogicalOrExpression(Negator.LogicallyNegate(condition), expression1));

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

                default:
                    return(LogicalOrExpression(ParenthesizedExpression(LogicalAndExpression(condition, expression1)), expression2));
                }
            }
            }
        }
        public static async Task <Document> RefactorAsync(
            Document document,
            BinaryExpressionSyntax binaryExpression,
            CancellationToken cancellationToken)
        {
            ExpressionSyntax left          = binaryExpression.Left;
            ExpressionSyntax right         = binaryExpression.Right;
            SyntaxToken      operatorToken = binaryExpression.OperatorToken;

            ExpressionSyntax newNode = binaryExpression;

            TextSpan span = TextSpan.FromBounds(left.Span.End, right.Span.Start);

            IEnumerable <SyntaxTrivia> trivia = binaryExpression.DescendantTrivia(span);

            bool isWhiteSpaceOrEndOfLine = trivia.All(f => f.IsWhitespaceOrEndOfLineTrivia());

            if (left.IsBooleanLiteralExpression())
            {
                SyntaxTriviaList leadingTrivia = binaryExpression.GetLeadingTrivia();

                if (!isWhiteSpaceOrEndOfLine)
                {
                    leadingTrivia = leadingTrivia.AddRange(trivia);
                }

                newNode = Negator.LogicallyNegate(right)
                          .WithLeadingTrivia(leadingTrivia);
            }
            else if (right.IsBooleanLiteralExpression())
            {
                SyntaxTriviaList trailingTrivia = binaryExpression.GetTrailingTrivia();

                if (!isWhiteSpaceOrEndOfLine)
                {
                    trailingTrivia = trailingTrivia.InsertRange(0, trivia);
                }

                newNode = Negator.LogicallyNegate(left)
                          .WithTrailingTrivia(trailingTrivia);
            }
#if DEBUG
            else
            {
                Debug.Assert(false, binaryExpression.ToString());
            }
#endif

            return(await document.ReplaceNodeAsync(binaryExpression, newNode.WithFormatterAnnotation(), cancellationToken).ConfigureAwait(false));
        }
        public static ExpressionSyntax GetExpression(ExpressionSyntax condition, ExpressionSyntax expression1, ExpressionSyntax expression2)
        {
            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(Negator.LogicallyNegate(condition));

                case SyntaxKind.FalseLiteralExpression:
                    return(expression2);

                default:
                    return(LogicalOrExpression(Negator.LogicallyNegate(condition), expression2));
                }
            }

            default:
            {
                switch (expression2.Kind())
                {
                case SyntaxKind.TrueLiteralExpression:
                    return(LogicalOrExpression(Negator.LogicallyNegate(condition), expression1));

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

                default:
                    return(LogicalOrExpression(ParenthesizedExpression(LogicalAndExpression(condition, expression1)), expression2));
                }
            }
            }
        }
예제 #19
0
        public static Task <Document> RefactorAsync(
            Document document,
            ConditionalExpressionSyntax conditionalExpression,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            ConditionalExpressionSyntax newNode = conditionalExpression.Update(
                condition: Negator.LogicallyNegate(conditionalExpression.Condition),
                questionToken: conditionalExpression.QuestionToken,
                whenTrue: conditionalExpression.WhenFalse.WithTriviaFrom(conditionalExpression.WhenTrue),
                colonToken: conditionalExpression.ColonToken,
                whenFalse: conditionalExpression.WhenTrue.WithTriviaFrom(conditionalExpression.WhenFalse));

            newNode = newNode.WithFormatterAnnotation();

            return(document.ReplaceNodeAsync(conditionalExpression, newNode, cancellationToken));
        }
예제 #20
0
        public static Task <Document> RefactorAsync(
            Document document,
            IfStatementSyntax ifStatement,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            StatementSyntax trueStatement = ifStatement.Statement;

            StatementSyntax falseStatement = ifStatement.Else.Statement;

            IfStatementSyntax newIfStatement = ifStatement
                                               .WithCondition(Negator.LogicallyNegate(ifStatement.Condition))
                                               .WithStatement(falseStatement.WithTriviaFrom(trueStatement))
                                               .WithElse(ifStatement.Else.WithStatement(trueStatement.WithTriviaFrom(falseStatement)))
                                               .WithFormatterAnnotation();

            return(document.ReplaceNodeAsync(ifStatement, newIfStatement, cancellationToken));
        }
            public override SyntaxNode VisitBlock(BlockSyntax node)
            {
                _block = node;

                if (node.LastStatementOrDefault(skipLocalFunction: true) is IfStatementSyntax ifStatement &&
                    IsFixable(ifStatement))
                {
                    SyntaxList <StatementSyntax> statements = node.Statements;

                    int index = statements.IndexOf(ifStatement);

                    if (_recursive)
                    {
                        ifStatement = (IfStatementSyntax)VisitIfStatement(ifStatement);
                    }

                    var block = (BlockSyntax)ifStatement.Statement;

                    ExpressionSyntax newCondition = Negator.LogicallyNegate(ifStatement.Condition);

                    BlockSyntax newBlock = block.WithStatements(SingletonList(_jumpStatement));

                    if (!block
                        .Statements
                        .First()
                        .GetLeadingTrivia()
                        .Any(f => f.IsEndOfLineTrivia()))
                    {
                        newBlock = newBlock.WithCloseBraceToken(newBlock.CloseBraceToken.AppendToTrailingTrivia(NewLine()));
                    }

                    IfStatementSyntax newIfStatement = ifStatement
                                                       .WithCondition(newCondition)
                                                       .WithStatement(newBlock)
                                                       .WithFormatterAnnotation();

                    SyntaxList <StatementSyntax> newStatements = statements
                                                                 .ReplaceAt(index, newIfStatement)
                                                                 .InsertRange(index + 1, block.Statements.Select(f => f.WithFormatterAnnotation()));

                    node = node.WithStatements(newStatements);
                }

                return(node);
            }
        public static Task <Document> RefactorAsync(
            Document document,
            InvocationExpressionSyntax invocationExpression,
            string memberName,
            ExpressionSyntax expression,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            var memberAccessExpression = (MemberAccessExpressionSyntax)invocationExpression.Expression;

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

            InvocationExpressionSyntax newNode = invocationExpression
                                                 .ReplaceNode(expression, Negator.LogicallyNegate(expression))
                                                 .WithExpression(newMemberAccessExpression);

            return(document.ReplaceNodeAsync(invocationExpression, newNode, cancellationToken));
        }
예제 #23
0
        private static Task <Document> IfElseToAssignmentWithConditionAsync(
            Document document,
            IfElseToAssignmentWithConditionAnalysis analysis,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            ExpressionSyntax right = analysis.Right.WithoutTrivia();

            if (analysis.Negate)
            {
                right = Negator.LogicallyNegate(right, analysis.SemanticModel, cancellationToken);
            }

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

            return(document.ReplaceNodeAsync(analysis.IfStatement, newNode, cancellationToken));
        }
예제 #24
0
            private SyntaxNode Rewrite(StatementListInfo statementsInfo, IfStatementSyntax ifStatement)
            {
                SyntaxList <StatementSyntax> statements = statementsInfo.Statements;

                int index = statements.IndexOf(ifStatement);

                ExpressionSyntax newCondition = Negator.LogicallyNegate(ifStatement.Condition, _semanticModel, _cancellationToken);

                if (_recursive)
                {
                    ifStatement = (IfStatementSyntax)VisitIfStatement(ifStatement);
                }

                var block = (BlockSyntax)ifStatement.Statement;

                BlockSyntax newBlock = block.WithStatements(SingletonList(_jumpStatement));

                if (!block
                    .Statements
                    .First()
                    .GetLeadingTrivia()
                    .Any(f => f.IsEndOfLineTrivia()))
                {
                    newBlock = newBlock.WithCloseBraceToken(newBlock.CloseBraceToken.AppendToTrailingTrivia(NewLine()));
                }

                IfStatementSyntax newIfStatement = ifStatement
                                                   .WithCondition(newCondition)
                                                   .WithStatement(newBlock)
                                                   .WithFormatterAnnotation();

                if (CSharpFacts.IsJumpStatementOrYieldBreakStatement(statements.Last().Kind()) &&
                    CSharpFacts.IsJumpStatementOrYieldBreakStatement(block.Statements.Last().Kind()))
                {
                    statements = statements.RemoveAt(statements.Count - 1);
                }

                SyntaxList <StatementSyntax> newStatements = statements
                                                             .ReplaceAt(index, newIfStatement)
                                                             .InsertRange(index + 1, block.Statements.Select(f => f.WithFormatterAnnotation()));

                return(statementsInfo.WithStatements(newStatements).Parent);
            }
        public static Task <Document> RefactorAsync(
            Document document,
            IfStatementSyntax ifStatement,
            CancellationToken cancellationToken)
        {
            ExpressionSyntax condition = ifStatement.Condition;

            AssignmentExpressionSyntax assignment = GetSimpleAssignmentExpression(ifStatement.GetSingleStatementOrDefault());

            if (assignment.Right.IsKind(SyntaxKind.FalseLiteralExpression))
            {
                condition = Negator.LogicallyNegate(condition);
            }

            ExpressionStatementSyntax newNode = SimpleAssignmentStatement(assignment.Left, condition)
                                                .WithTriviaFrom(ifStatement)
                                                .WithFormatterAnnotation();

            return(document.ReplaceNodeAsync(ifStatement, newNode, cancellationToken));
        }
예제 #26
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(Negator.LogicallyNegate(condition, semanticModel, cancellationToken));

                case SyntaxKind.FalseLiteralExpression:
                    return(expression2);

                default:
                    return(LogicalAndExpression(Negator.LogicallyNegate(condition, semanticModel, cancellationToken), expression2));
                }
            }

            default:
            {
                switch (expression2.Kind())
                {
                case SyntaxKind.TrueLiteralExpression:
                    return(LogicalOrExpression(Negator.LogicallyNegate(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 condition = info.Condition;
            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, condition);
                }
                else
                {
                    SyntaxTriviaList trailingTrivia = info
                                                      .QuestionToken
                                                      .LeadingTrivia
                                                      .AddRange(info.QuestionToken.TrailingTrivia)
                                                      .AddRange(whenTrue.GetLeadingTrivia())
                                                      .EmptyIfWhitespace();

                    newNode = LogicalOrExpression(
                        condition.Parenthesize().AppendToTrailingTrivia(trailingTrivia),
                        Token(info.ColonToken.LeadingTrivia, SyntaxKind.BarBarToken, info.ColonToken.TrailingTrivia),
                        whenFalse);
                }
            }
            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(
                    condition.Parenthesize(),
                    Token(info.QuestionToken.LeadingTrivia, SyntaxKind.AmpersandAmpersandToken, info.QuestionToken.TrailingTrivia),
                    whenTrue.WithTrailingTrivia(trailingTrivia));
            }
            else if (trueKind == SyntaxKind.FalseLiteralExpression &&
                     falseKind == SyntaxKind.TrueLiteralExpression)
            {
                SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

                newNode = CreateNewNode(conditionalExpression, Negator.LogicallyNegate(condition, semanticModel, cancellationToken));
            }

            return(await document.ReplaceNodeAsync(conditionalExpression, newNode, cancellationToken).ConfigureAwait(false));
        }
        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 = Negator.LogicallyNegate(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
            {
                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 = Negator.LogicallyNegate(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(),
                            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));
            }
        }
예제 #29
0
        private static async Task <ExpressionSyntax> CreateNewNode(
            Document document,
            BinaryExpressionSyntax binaryExpression,
            CancellationToken cancellationToken)
        {
            ExpressionSyntax left          = binaryExpression.Left;
            ExpressionSyntax right         = binaryExpression.Right;
            SyntaxToken      operatorToken = binaryExpression.OperatorToken;

            TextSpan span = TextSpan.FromBounds(left.Span.End, right.Span.Start);

            IEnumerable <SyntaxTrivia> trivia = binaryExpression.DescendantTrivia(span);

            bool isWhiteSpaceOrEndOfLine = trivia.All(f => f.IsWhitespaceOrEndOfLineTrivia());

            if (left.IsBooleanLiteralExpression())
            {
                SyntaxTriviaList leadingTrivia = binaryExpression.GetLeadingTrivia();

                if (!isWhiteSpaceOrEndOfLine)
                {
                    leadingTrivia = leadingTrivia.AddRange(trivia);
                }

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

                    ExpressionSyntax operand = logicalNot.Operand;

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

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

                return(Negator.LogicallyNegate(right)
                       .WithLeadingTrivia(leadingTrivia));
            }
            else if (right.IsBooleanLiteralExpression())
            {
                SyntaxTriviaList trailingTrivia = binaryExpression.GetTrailingTrivia();

                if (!isWhiteSpaceOrEndOfLine)
                {
                    trailingTrivia = trailingTrivia.InsertRange(0, trivia);
                }

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

                    ExpressionSyntax operand = logicalNot.Operand;

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

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

                return(Negator.LogicallyNegate(left)
                       .WithTrailingTrivia(trailingTrivia));
            }

            Debug.Fail(binaryExpression.ToString());

            return(binaryExpression);
        }
예제 #30
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 = ifStatement;

                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: Negator.LogicallyNegate(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);
            }
        }