Example #1
0
        public static Task <Document> RefactorAsync(
            Document document,
            BlockSyntax block,
            CancellationToken cancellationToken)
        {
            SyntaxList <StatementSyntax> statements = block.Statements;

            var ifStatement = (IfStatementSyntax)statements[0];

            var returnStatement = (ReturnStatementSyntax)statements[1];

            var expressionStatement = (ExpressionStatementSyntax)ifStatement.GetSingleStatementOrDefault();

            var assignment = (AssignmentExpressionSyntax)expressionStatement.Expression;

            ExpressionSyntax expression = returnStatement.Expression.WithoutTrivia();

            BinaryExpressionSyntax coalesceExpression = CSharpFactory.CoalesceExpression(
                expression,
                CSharpFactory.SimpleAssignmentExpression(expression, assignment.Right.WithoutTrivia()).Parenthesize());

            ReturnStatementSyntax newReturnStatement = returnStatement
                                                       .WithExpression(coalesceExpression)
                                                       .WithLeadingTrivia(ifStatement.GetLeadingTrivia());

            SyntaxList <StatementSyntax> newStatements = statements
                                                         .Replace(returnStatement, newReturnStatement)
                                                         .RemoveAt(0);

            BlockSyntax newBlock = block.WithStatements(newStatements);

            return(document.ReplaceNodeAsync(block, newBlock, cancellationToken));
        }
Example #2
0
        public static async Task <Document> RefactorAsync(
            Document document,
            ConditionalExpressionSyntax conditionalExpressionSyntax,
            CancellationToken cancellationToken)
        {
            ConditionalExpressionInfo conditionalExpression;

            if (ConditionalExpressionInfo.TryCreate(conditionalExpressionSyntax, out conditionalExpression))
            {
                SemanticModel semanticModel = await document.GetSemanticModelAsync().ConfigureAwait(false);

                NullCheckExpression nullCheck;
                if (NullCheckExpression.TryCreate(conditionalExpression.Condition, semanticModel, out nullCheck, cancellationToken))
                {
                    ExpressionSyntax whenNotNull = (nullCheck.IsCheckingNotNull)
                        ? conditionalExpression.WhenTrue
                        : conditionalExpression.WhenFalse;

                    ExpressionSyntax whenNull = (nullCheck.IsCheckingNull)
                        ? conditionalExpression.WhenTrue
                        : conditionalExpression.WhenFalse;

                    ExpressionSyntax expression = FindExpressionThatCanBeConditionallyAccessed(nullCheck.Expression, whenNotNull);

                    ExpressionSyntax newNode;

                    if (expression.Parent == whenNotNull &&
                        whenNotNull.IsKind(SyntaxKind.SimpleMemberAccessExpression) &&
                        SemanticUtilities.IsPropertyOfNullableOfT(whenNotNull, "Value", semanticModel, cancellationToken))
                    {
                        newNode = expression;
                    }
                    else
                    {
                        newNode = SyntaxFactory.ParseExpression(whenNotNull.ToString().Insert(expression.Span.End - whenNotNull.SpanStart, "?"));
                    }

                    if (!semanticModel.GetTypeSymbol(whenNotNull, cancellationToken).IsReferenceType)
                    {
                        newNode = CSharpFactory.CoalesceExpression(newNode.Parenthesize(), whenNull.Parenthesize());
                    }

                    newNode = newNode
                              .WithTriviaFrom(conditionalExpressionSyntax)
                              .Parenthesize();

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

            Debug.Fail(conditionalExpressionSyntax.ToString());

            return(document);
        }
        private static Task <Document> RefactorAsync(
            Document document,
            StatementSyntax statement,
            IfStatementSyntax ifStatement,
            int statementIndex,
            IStatementContainer container,
            ExpressionSyntax expression,
            CancellationToken cancellationToken)
        {
            var expressionStatement = (ExpressionStatementSyntax)ifStatement.GetSingleStatementOrDefault();

            var assignment = (AssignmentExpressionSyntax)expressionStatement.Expression;

            ExpressionSyntax left = expression
                                    .WithoutTrailingTrivia()
                                    .Parenthesize(moveTrivia: true)
                                    .WithSimplifierAnnotation();

            ExpressionSyntax right = assignment.Right
                                     .WithTrailingTrivia(expression.GetTrailingTrivia())
                                     .Parenthesize(moveTrivia: true)
                                     .WithSimplifierAnnotation();

            BinaryExpressionSyntax newNode = CSharpFactory.CoalesceExpression(left, right);

            StatementSyntax newStatement = statement.ReplaceNode(expression, newNode);

            IEnumerable <SyntaxTrivia> trivia = container.Node.DescendantTrivia(TextSpan.FromBounds(statement.Span.End, ifStatement.Span.End));

            if (!trivia.All(f => f.IsWhitespaceOrEndOfLineTrivia()))
            {
                newStatement = newStatement.WithTrailingTrivia(trivia);
                newStatement = newStatement.AppendToTrailingTrivia(ifStatement.GetTrailingTrivia());
            }
            else
            {
                newStatement = newStatement.WithTrailingTrivia(ifStatement.GetTrailingTrivia());
            }

            SyntaxList <StatementSyntax> newStatements = container.Statements
                                                         .Remove(ifStatement)
                                                         .ReplaceAt(statementIndex, newStatement);

            return(document.ReplaceNodeAsync(container.Node, container.NodeWithStatements(newStatements), cancellationToken));
        }
        private static BinaryExpressionSyntax CreateCoalesceExpression(
            ExpressionSyntax left,
            ExpressionSyntax right,
            ITypeSymbol targetType,
            int position,
            SemanticModel semanticModel)
        {
            if (targetType?.SupportsExplicitDeclaration() == true)
            {
                right = CastExpression(
                    targetType.ToMinimalTypeSyntax(semanticModel, position),
                    right.Parenthesize()).WithSimplifierAnnotation();
            }

            return(CSharpFactory.CoalesceExpression(
                       left.Parenthesize(),
                       right.Parenthesize()));
        }
Example #5
0
        public static Task <Document> RefactorAsync(
            Document document,
            IfStatementSyntax ifStatement,
            CancellationToken cancellationToken = default)
        {
            StatementListInfo statementsInfo = SyntaxInfo.StatementListInfo(ifStatement);

            SyntaxList <StatementSyntax> statements = statementsInfo.Statements;

            int index = statements.IndexOf(ifStatement);

            StatementSyntax expressionStatement = (ExpressionStatementSyntax)statements[index + 1];

            SimpleMemberInvocationStatementInfo invocationInfo = SyntaxInfo.SimpleMemberInvocationStatementInfo((ExpressionStatementSyntax)expressionStatement);

            ExpressionSyntax expression = invocationInfo.Expression;

            SimpleAssignmentStatementInfo assignmentInfo = SyntaxInfo.SimpleAssignmentStatementInfo((ExpressionStatementSyntax)ifStatement.SingleNonBlockStatementOrDefault());

            BinaryExpressionSyntax coalesceExpression = CSharpFactory.CoalesceExpression(expression.WithoutTrivia(), ParenthesizedExpression(assignmentInfo.AssignmentExpression));

            ParenthesizedExpressionSyntax newExpression = ParenthesizedExpression(coalesceExpression)
                                                          .WithTriviaFrom(expression);

            StatementSyntax newExpressionStatement = expressionStatement.ReplaceNode(expression, newExpression);

            IEnumerable <SyntaxTrivia> trivia = statementsInfo.Parent.DescendantTrivia(TextSpan.FromBounds(ifStatement.FullSpan.Start, expressionStatement.FullSpan.Start));

            if (trivia.Any(f => !f.IsWhitespaceOrEndOfLineTrivia()))
            {
                newExpressionStatement = newExpressionStatement.PrependToLeadingTrivia(trivia);
            }

            SyntaxList <StatementSyntax> newStatements = statements
                                                         .Replace(expressionStatement, newExpressionStatement)
                                                         .RemoveAt(index);

            return(document.ReplaceStatementsAsync(statementsInfo, newStatements, cancellationToken));
        }
Example #6
0
        public static Task <Document> InlineLazyInitializationAsync(
            Document document,
            IfStatementSyntax ifStatement,
            CancellationToken cancellationToken)
        {
            StatementContainer container = StatementContainer.Create(ifStatement);

            SyntaxList <StatementSyntax> statements = container.Statements;

            int index = statements.IndexOf(ifStatement);

            StatementSyntax expressionStatement = (ExpressionStatementSyntax)statements[index + 1];

            MemberInvocationStatement invocation = MemberInvocationStatement.Create((ExpressionStatementSyntax)expressionStatement);

            ExpressionSyntax expression = invocation.Expression;

            SimpleAssignmentStatement assignment = SimpleAssignmentStatement.Create((ExpressionStatementSyntax)ifStatement.GetSingleStatementOrDefault());

            BinaryExpressionSyntax coalesceExpression = CSharpFactory.CoalesceExpression(expression.WithoutTrivia(), ParenthesizedExpression(assignment.AssignmentExpression));

            ParenthesizedExpressionSyntax newExpression = ParenthesizedExpression(coalesceExpression)
                                                          .WithTriviaFrom(expression);

            StatementSyntax newExpressionStatement = expressionStatement.ReplaceNode(expression, newExpression);

            IEnumerable <SyntaxTrivia> trivia = container.Node.DescendantTrivia(TextSpan.FromBounds(ifStatement.FullSpan.Start, expressionStatement.FullSpan.Start));

            if (trivia.Any(f => !f.IsWhitespaceOrEndOfLineTrivia()))
            {
                newExpressionStatement = newExpressionStatement.PrependToLeadingTrivia(trivia);
            }

            SyntaxList <StatementSyntax> newStatements = statements
                                                         .Replace(expressionStatement, newExpressionStatement)
                                                         .RemoveAt(index);

            return(document.ReplaceNodeAsync(container.Node, container.NodeWithStatements(newStatements), cancellationToken));
        }
Example #7
0
        public static Task <Document> RefactorAsync(
            Document document,
            ConditionalExpressionSyntax conditionalExpression,
            CancellationToken cancellationToken)
        {
            var binaryExpression = (BinaryExpressionSyntax)conditionalExpression.Condition.WalkDownParentheses();

            ExpressionSyntax left = (binaryExpression.IsKind(SyntaxKind.EqualsExpression))
                ? conditionalExpression.WhenFalse
                : conditionalExpression.WhenTrue;

            ExpressionSyntax right = (binaryExpression.IsKind(SyntaxKind.EqualsExpression))
                ? conditionalExpression.WhenTrue
                : conditionalExpression.WhenFalse;

            BinaryExpressionSyntax newNode = CSharpFactory.CoalesceExpression(
                left.WithoutTrivia().Parenthesize().WithSimplifierAnnotation(),
                right.WithoutTrivia().Parenthesize().WithSimplifierAnnotation());

            return(document.ReplaceNodeAsync(
                       conditionalExpression,
                       newNode.WithTriviaFrom(conditionalExpression),
                       cancellationToken));
        }
        public static async Task <Document> RefactorAsync(
            Document document,
            StatementSyntax statement,
            CancellationToken cancellationToken)
        {
            IStatementContainer container;

            if (StatementContainer.TryCreate(statement, out container))
            {
                SyntaxList <StatementSyntax> statements = container.Statements;

                int index = statements.IndexOf(statement);

                switch (statement.Kind())
                {
                case SyntaxKind.IfStatement:
                {
                    var ifStatement = (IfStatementSyntax)statement;

                    var expressionStatement = (ExpressionStatementSyntax)ifStatement.GetSingleStatementOrDefault();

                    var assignment = (AssignmentExpressionSyntax)expressionStatement.Expression;

                    ExpressionSyntax left  = assignment.Left;
                    ExpressionSyntax right = assignment.Right;

                    ParenthesizedExpressionSyntax newLeft = left
                                                            .WithoutLeadingTrivia()
                                                            .WithTrailingTrivia(Space)
                                                            .Parenthesize(moveTrivia: true)
                                                            .WithSimplifierAnnotation();

                    ParenthesizedExpressionSyntax newRight = right
                                                             .WithLeadingTrivia(Space)
                                                             .Parenthesize(moveTrivia: true)
                                                             .WithSimplifierAnnotation();

                    BinaryExpressionSyntax coalesceExpression = CSharpFactory.CoalesceExpression(newLeft, newRight);

                    AssignmentExpressionSyntax newAssignment = assignment.WithRight(coalesceExpression.WithTriviaFrom(right));

                    ExpressionStatementSyntax newNode = expressionStatement.WithExpression(newAssignment);

                    IEnumerable <SyntaxTrivia> trivia = ifStatement.DescendantTrivia(TextSpan.FromBounds(ifStatement.SpanStart, expressionStatement.SpanStart));

                    if (trivia.All(f => f.IsWhitespaceOrEndOfLineTrivia()))
                    {
                        newNode = newNode.WithLeadingTrivia(ifStatement.GetLeadingTrivia());
                    }
                    else
                    {
                        newNode = newNode
                                  .WithLeadingTrivia(ifStatement.GetLeadingTrivia().Concat(trivia))
                                  .WithFormatterAnnotation();
                    }

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

                case SyntaxKind.ExpressionStatement:
                {
                    var expressionStatement = (ExpressionStatementSyntax)statement;

                    var assignment = (AssignmentExpressionSyntax)expressionStatement.Expression;

                    return(await RefactorAsync(document, expressionStatement, (IfStatementSyntax)statements[index + 1], index, container, assignment.Right, cancellationToken).ConfigureAwait(false));
                }

                case SyntaxKind.LocalDeclarationStatement:
                {
                    var localDeclaration = (LocalDeclarationStatementSyntax)statement;

                    ExpressionSyntax value = localDeclaration
                                             .Declaration
                                             .Variables
                                             .First()
                                             .Initializer
                                             .Value;

                    return(await RefactorAsync(document, localDeclaration, (IfStatementSyntax)statements[index + 1], index, container, value, cancellationToken).ConfigureAwait(false));
                }
                }
            }

            Debug.Assert(false, statement.Kind().ToString());

            return(document);
        }