Exemplo n.º 1
0
        public override async Task <Document> RefactorAsync(Document document, CancellationToken cancellationToken = default(CancellationToken))
        {
            StatementContainer container = StatementContainer.Create(IfStatement);

            SyntaxList <StatementSyntax> statements = container.Statements;

            int index = statements.IndexOf(IfStatement);

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

            ExpressionSyntax expression = IfRefactoringHelper.GetBooleanExpression(
                IfStatement.Condition,
                Expression1,
                Expression2,
                semanticModel,
                cancellationToken);

            StatementSyntax newStatement = CreateStatement(expression)
                                           .WithLeadingTrivia(IfStatement.GetLeadingTrivia())
                                           .WithTrailingTrivia(statements[index + 1].GetTrailingTrivia())
                                           .WithFormatterAnnotation();

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

            return(await document.ReplaceNodeAsync(container.Node, container.NodeWithStatements(newStatements), cancellationToken).ConfigureAwait(false));
        }
Exemplo n.º 2
0
        public override async Task <Document> RefactorAsync(Document document, CancellationToken cancellationToken)
        {
            IStatementContainer container = StatementContainer.Create(IfStatement);

            SyntaxList <StatementSyntax> statements = container.Statements;

            int index = statements.IndexOf(IfStatement);

            ExpressionSyntax left  = Left.WithoutTrivia();
            ExpressionSyntax right = Right.WithoutTrivia();

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

            right = AddCastExpressionIfNecessary(right, semanticModel, IfStatement.SpanStart, cancellationToken);

            StatementSyntax newNode = CreateStatement(
                CoalesceExpression(
                    left.Parenthesize().WithSimplifierAnnotation(),
                    right.Parenthesize().WithSimplifierAnnotation()));

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

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

            return(await document.ReplaceNodeAsync(container.Node, container.NodeWithStatements(newStatements), cancellationToken).ConfigureAwait(false));
        }
        public static Task <Document> RefactorAsync(
            Document document,
            UsingStatementSyntax usingStatement,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            StatementContainer container = StatementContainer.Create(usingStatement);

            int index = container.Statements.IndexOf(usingStatement);

            StatementContainer newContainer = container.RemoveStatementAt(index);

            var statements = new List <StatementSyntax>()
            {
                SyntaxFactory.LocalDeclarationStatement(usingStatement.Declaration)
            };

            statements.AddRange(GetStatements(usingStatement));

            if (statements.Count > 0)
            {
                statements[0] = statements[0]
                                .WithLeadingTrivia(usingStatement.GetLeadingTrivia());

                statements[statements.Count - 1] = statements[statements.Count - 1]
                                                   .WithTrailingTrivia(usingStatement.GetTrailingTrivia());
            }

            newContainer = newContainer.WithStatements(newContainer.Statements.InsertRange(index, statements));

            return(document.ReplaceNodeAsync(container.Node, newContainer.Node.WithFormatterAnnotation(), cancellationToken));
        }
Exemplo n.º 4
0
        public static Task <Document> RefactorAsync(
            Document document,
            VariableDeclaratorSyntax declarator,
            CancellationToken cancellationToken)
        {
            var declaration = (VariableDeclarationSyntax)declarator.Parent;

            var localDeclaration = (LocalDeclarationStatementSyntax)declaration.Parent;

            StatementContainer container = StatementContainer.Create(localDeclaration);

            SyntaxList <StatementSyntax> statements = container.Statements;

            int index = statements.IndexOf(localDeclaration);

            StatementSyntax nextStatement = statements[index + 1];

            var expressionStatement = (ExpressionStatementSyntax)nextStatement;

            var assignment = (AssignmentExpressionSyntax)expressionStatement.Expression;

            ExpressionSyntax right = assignment.Right;

            EqualsValueClauseSyntax initializer = declarator.Initializer;

            ExpressionSyntax value = initializer?.Value;

            VariableDeclaratorSyntax newDeclarator = (value != null)
                ? declarator.ReplaceNode(value, right)
                : declarator.WithInitializer(EqualsValueClause(right));

            LocalDeclarationStatementSyntax newLocalDeclaration = localDeclaration.ReplaceNode(declarator, newDeclarator);

            SyntaxTriviaList trailingTrivia = localDeclaration.GetTrailingTrivia();

            if (!trailingTrivia.IsEmptyOrWhitespace())
            {
                newLocalDeclaration = newLocalDeclaration.WithTrailingTrivia(trailingTrivia.Concat(nextStatement.GetTrailingTrivia()));
            }
            else
            {
                newLocalDeclaration = newLocalDeclaration.WithTrailingTrivia(nextStatement.GetTrailingTrivia());
            }

            SyntaxTriviaList leadingTrivia = nextStatement.GetLeadingTrivia();

            if (!leadingTrivia.IsEmptyOrWhitespace())
            {
                newLocalDeclaration = newLocalDeclaration.WithLeadingTrivia(newLocalDeclaration.GetLeadingTrivia().Concat(leadingTrivia));
            }

            SyntaxList <StatementSyntax> newStatements = statements
                                                         .Replace(localDeclaration, newLocalDeclaration)
                                                         .RemoveAt(index + 1);

            return(document.ReplaceNodeAsync(container.Node, container.NodeWithStatements(newStatements), cancellationToken));
        }
        public static async Task <Document> RefactorAsync(
            Document document,
            IfStatementSyntax ifStatement,
            CancellationToken cancellationToken)
        {
            ExpressionSyntax returnExpression = ifStatement.Condition;

            if (GetBooleanLiteral(ifStatement.Statement).Kind() == SyntaxKind.FalseLiteralExpression)
            {
                SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

                returnExpression = CSharpUtility.LogicallyNegate(returnExpression, semanticModel, cancellationToken);
            }

            ReturnStatementSyntax newReturnStatement = ReturnStatement(
                ReturnKeyword().WithTrailingTrivia(Space),
                returnExpression,
                SemicolonToken());

            if (ifStatement.Else != null)
            {
                newReturnStatement = newReturnStatement.WithTriviaFrom(ifStatement);

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

            StatementContainer container = StatementContainer.Create(ifStatement);

            SyntaxList <StatementSyntax> statements = container.Statements;

            int index = statements.IndexOf(ifStatement);

            var returnStatement = (ReturnStatementSyntax)statements[index + 1];

            newReturnStatement = newReturnStatement
                                 .WithLeadingTrivia(ifStatement.GetLeadingTrivia())
                                 .WithTrailingTrivia(returnStatement.GetTrailingTrivia());

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

            //TODO: ReplaceStatementsAsync
            return(await document.ReplaceNodeAsync(container.Node, container.WithStatements(newStatements).Node, cancellationToken).ConfigureAwait(false));
        }
        public override Task <Document> RefactorAsync(
            Document document,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            IStatementContainer container = StatementContainer.Create(IfStatement);

            SyntaxList <StatementSyntax> statements = container.Statements;

            int index = statements.IndexOf(IfStatement);

            TStatement newStatement = CreateNewStatement();

            SyntaxList <StatementSyntax> newStatements = statements
                                                         .RemoveAt(index)
                                                         .ReplaceAt(index - 1, newStatement);

            return(document.ReplaceNodeAsync(container.Node, container.NodeWithStatements(newStatements), cancellationToken));
        }
Exemplo n.º 7
0
        public static async Task <Document> RefactorAsync(
            Document document,
            IfStatementSyntax ifStatement,
            SyntaxKind jumpKind,
            bool recursive,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            StatementContainer container = StatementContainer.Create(ifStatement);

            CSharpSyntaxNode node = container.Node;

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

            var rewriter = new ReduceIfStatementRewriter(jumpKind, recursive, semanticModel, cancellationToken);

            SyntaxNode newNode = rewriter.Visit(node);

            return(await document.ReplaceNodeAsync(node, newNode, cancellationToken).ConfigureAwait(false));
        }
Exemplo n.º 8
0
        public override Task <Document> RefactorAsync(Document document, CancellationToken cancellationToken = default(CancellationToken))
        {
            StatementContainer container = StatementContainer.Create(IfStatement);

            SyntaxList <StatementSyntax> statements = container.Statements;

            int index = statements.IndexOf(IfStatement);

            ConditionalExpressionSyntax conditionalExpression = IfRefactoringHelper.CreateConditionalExpression(IfStatement.Condition, Expression1, Expression2);

            StatementSyntax newStatement = CreateStatement(conditionalExpression)
                                           .WithLeadingTrivia(IfStatement.GetLeadingTrivia())
                                           .WithTrailingTrivia(statements[index + 1].GetTrailingTrivia())
                                           .WithFormatterAnnotation();

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

            return(document.ReplaceNodeAsync(container.Node, container.NodeWithStatements(newStatements), cancellationToken));
        }
Exemplo n.º 9
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));
        }
        private static Task <Document> RefactorAsync(
            Document document,
            LocalDeclarationStatementSyntax localDeclaration,
            ConditionalExpressionSyntax conditionalExpression,
            SemanticModel semanticModel,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            VariableDeclaratorSyntax variableDeclarator = localDeclaration.Declaration.Variables[0];

            LocalDeclarationStatementSyntax newLocalDeclaration = localDeclaration.RemoveNode(variableDeclarator.Initializer, SyntaxRemoveOptions.KeepExteriorTrivia);

            TypeSyntax type = newLocalDeclaration.Declaration.Type;

            if (type.IsVar)
            {
                newLocalDeclaration = newLocalDeclaration.ReplaceNode(
                    type,
                    semanticModel.GetTypeSymbol(conditionalExpression)
                    .ToMinimalTypeSyntax(semanticModel, type.SpanStart)
                    .WithTriviaFrom(type));
            }

            IdentifierNameSyntax left = IdentifierName(variableDeclarator.Identifier.ValueText);

            IfStatementSyntax ifStatement = IfElseStatement(
                conditionalExpression.Condition.WalkDownParentheses().WithoutTrivia(),
                SimpleAssignmentStatement(left, conditionalExpression.WhenTrue.WithoutTrivia()),
                SimpleAssignmentStatement(left, conditionalExpression.WhenFalse.WithoutTrivia()));

            StatementContainer container = StatementContainer.Create(localDeclaration);

            SyntaxList <StatementSyntax> statements = container.Statements;

            SyntaxList <StatementSyntax> newStatements = statements
                                                         .Replace(localDeclaration, newLocalDeclaration.WithFormatterAnnotation())
                                                         .Insert(statements.IndexOf(localDeclaration) + 1, ifStatement.WithFormatterAnnotation());

            return(document.ReplaceNodeAsync(container.Node, container.NodeWithStatements(newStatements), cancellationToken));
        }
        public static async Task <Document> RefactorAsync(
            Document document,
            LocalDeclarationStatementSyntax localDeclaration,
            CancellationToken cancellationToken)
        {
            StatementContainer container = StatementContainer.Create(localDeclaration);

            int index = container.Statements.IndexOf(localDeclaration);

            StatementSyntax nextStatement = container.Statements[index + 1];

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

            ExpressionSyntax value = GetExpressionToInline(localDeclaration, semanticModel, cancellationToken);

            StatementSyntax newStatement = GetStatementWithInlinedExpression(nextStatement, value);

            SyntaxTriviaList leadingTrivia = localDeclaration.GetLeadingTrivia();

            IEnumerable <SyntaxTrivia> trivia = container
                                                .Node
                                                .DescendantTrivia(TextSpan.FromBounds(localDeclaration.SpanStart, nextStatement.Span.Start));

            if (!trivia.All(f => f.IsWhitespaceOrEndOfLineTrivia()))
            {
                newStatement = newStatement.WithLeadingTrivia(leadingTrivia.Concat(trivia));
            }
            else
            {
                newStatement = newStatement.WithLeadingTrivia(leadingTrivia);
            }

            SyntaxList <StatementSyntax> newStatements = container.Statements
                                                         .Replace(nextStatement, newStatement)
                                                         .RemoveAt(index);

            return(await document.ReplaceNodeAsync(container.Node, container.NodeWithStatements(newStatements), cancellationToken).ConfigureAwait(false));
        }
        private static Task <Document> RefactorAsync <TNode>(
            Document document,
            WhileStatementSyntax whileStatement,
            ForStatementSyntax forStatement,
            List <TNode> list,
            CancellationToken cancellationToken) where TNode : StatementSyntax
        {
            forStatement = forStatement
                           .TrimLeadingTrivia()
                           .PrependToLeadingTrivia(list[0].GetLeadingTrivia());

            StatementContainer container = StatementContainer.Create(whileStatement);

            SyntaxList <StatementSyntax> statements = container.Statements;

            int index = statements.IndexOf(list[0]);

            IEnumerable <StatementSyntax> newStatements = statements.Take(index)
                                                          .Concat(new ForStatementSyntax[] { forStatement })
                                                          .Concat(statements.Skip(index + list.Count + 1));

            return(document.ReplaceNodeAsync(container.Node, container.NodeWithStatements(newStatements), cancellationToken));
        }
Exemplo n.º 13
0
        public static Task <Document> RefactorAsync(
            Document document,
            StatementSyntax statement,
            CancellationToken cancellationToken)
        {
            StatementContainer container = StatementContainer.Create(statement);

            SyntaxList <StatementSyntax> statements = container.Statements;

            var returnStatement = (ReturnStatementSyntax)statements.Last(f => !f.IsKind(SyntaxKind.LocalFunctionStatement));

            int returnStatementIndex = statements.IndexOf(returnStatement);

            ExpressionSyntax expression = returnStatement.Expression;

            SyntaxKind kind = statement.Kind();

            if (kind == SyntaxKind.IfStatement)
            {
                var ifStatement = (IfStatementSyntax)statement;

                IfStatement chain = Syntax.IfStatement.Create(ifStatement);

                ExpressionStatementSyntax[] expressionStatements = chain
                                                                   .Nodes
                                                                   .Select(ifOrElse => (ExpressionStatementSyntax)GetLastStatementOrDefault(ifOrElse.Statement))
                                                                   .ToArray();

                IfStatementSyntax newIfStatement = ifStatement.ReplaceNodes(
                    expressionStatements,
                    (f, g) =>
                {
                    var assignment = (AssignmentExpressionSyntax)f.Expression;

                    return(ReturnStatement(assignment.Right).WithTriviaFrom(f));
                });

                SyntaxList <StatementSyntax> newStatements = statements.Replace(ifStatement, newIfStatement);

                StatementContainer newContainer = container.WithStatements(newStatements);

                SyntaxNode newNode = newContainer.Node;

                if (chain.EndsWithElse)
                {
                    newNode = newNode.RemoveStatement(newContainer.Statements[returnStatementIndex]);
                }

                return(document.ReplaceNodeAsync(container.Node, newNode, cancellationToken));
            }
            else if (kind == SyntaxKind.SwitchStatement)
            {
                var switchStatement = (SwitchStatementSyntax)statement;

                SyntaxList <SwitchSectionSyntax> newSections = switchStatement
                                                               .Sections
                                                               .Select(section => CreateNewSection(section))
                                                               .ToSyntaxList();

                SwitchStatementSyntax newSwitchStatement = switchStatement.WithSections(newSections);

                SyntaxList <StatementSyntax> newStatements = statements.Replace(switchStatement, newSwitchStatement);

                StatementContainer newContainer = container.WithStatements(newStatements);

                SyntaxNode newNode = newContainer.Node;

                if (switchStatement.Sections.Any(f => f.ContainsDefaultLabel()))
                {
                    newNode = newNode.RemoveStatement(newContainer.Statements[returnStatementIndex]);
                }

                return(document.ReplaceNodeAsync(container.Node, newNode, cancellationToken));
            }

            Debug.Fail(statement.Kind().ToString());

            return(Task.FromResult(document));
        }
Exemplo n.º 14
0
        public static async Task <Document> RefactorAsync(
            Document document,
            StatementSyntax statement,
            CancellationToken cancellationToken)
        {
            SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            StatementContainer container = StatementContainer.Create(statement);

            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;

                BinaryExpressionSyntax coalesceExpression = RefactoringHelper.CreateCoalesceExpression(
                    semanticModel.GetTypeSymbol(left, cancellationToken),
                    left.WithoutLeadingTrivia().WithTrailingTrivia(Space),
                    right.WithLeadingTrivia(Space),
                    ifStatement.SpanStart,
                    semanticModel);

                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, semanticModel, 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, semanticModel, cancellationToken).ConfigureAwait(false));
            }

            default:
            {
                Debug.Fail(statement.Kind().ToString());

                return(document);
            }
            }
        }
        public static async Task <Document> RefactorAsync(
            Document document,
            ExpressionStatementSyntax expressionStatement,
            CancellationToken cancellationToken)
        {
            SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            INamedTypeSymbol symbol = semanticModel.GetTypeByMetadataName(MetadataNames.System_Text_StringBuilder);

            var invocationExpression = (InvocationExpressionSyntax)expressionStatement.Expression;

            MemberInvocationExpression memberInvocation = MemberInvocationExpression.Create(invocationExpression);

            ExpressionSyntax expression = GetFirstInvocationInMethodChain(memberInvocation, symbol, semanticModel, cancellationToken).Expression;

            StatementContainer statementContainer = StatementContainer.Create(expressionStatement);

            SyntaxList <StatementSyntax> statements = statementContainer.Statements;

            int index = statements.IndexOf(expressionStatement);

            string indentation = CSharpFormatter.GetIncreasedIndentation(expressionStatement, cancellationToken).ToString();

            var sb = new StringBuilder(invocationExpression.ToString());

            int j = index;

            while (j < statements.Count - 1)
            {
                StatementSyntax statement = statements[j + 1];

                if (!IsFixable(statement, expression, symbol, semanticModel, cancellationToken))
                {
                    break;
                }

                sb.AppendLine();
                sb.Append(indentation);
                sb.Append(GetTextToAppend((ExpressionStatementSyntax)statement, symbol, semanticModel, cancellationToken));

                j++;
            }

            StatementSyntax lastStatement = statements[j];

            SyntaxList <StatementSyntax> newStatements = statements;

            while (j > index)
            {
                newStatements = newStatements.RemoveAt(j);
                j--;
            }

            ExpressionSyntax newInvocationExpression = SyntaxFactory.ParseExpression(sb.ToString());

            SyntaxTriviaList trailingTrivia = statementContainer
                                              .Node
                                              .DescendantTrivia(TextSpan.FromBounds(invocationExpression.Span.End, lastStatement.Span.End))
                                              .ToSyntaxTriviaList()
                                              .EmptyIfWhitespace()
                                              .AddRange(lastStatement.GetTrailingTrivia());

            ExpressionStatementSyntax newExpressionStatement = expressionStatement
                                                               .WithExpression(newInvocationExpression)
                                                               .WithLeadingTrivia(expressionStatement.GetLeadingTrivia())
                                                               .WithTrailingTrivia(trailingTrivia)
                                                               .WithFormatterAndSimplifierAnnotations();

            newStatements = newStatements.ReplaceAt(index, newExpressionStatement);

            return(await document.ReplaceNodeAsync(statementContainer.Node, statementContainer.NodeWithStatements(newStatements), cancellationToken).ConfigureAwait(false));
        }
        public static async Task <Document> RefactorAsync(
            Document document,
            StatementSyntax statement,
            CancellationToken cancellationToken)
        {
            SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            StatementContainer container = StatementContainer.Create(statement);

            int index = container.Statements.IndexOf(statement);

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

                IfStatement chain = Syntax.IfStatement.Create(ifStatement);

                IEnumerable <ExpressionStatementSyntax> expressionStatements = chain
                                                                               .Nodes
                                                                               .Select(ifOrElse => (ExpressionStatementSyntax)GetLastStatementOrDefault(ifOrElse.Statement));

                IfStatementSyntax newIfStatement = ifStatement.ReplaceNodes(
                    expressionStatements,
                    (f, g) =>
                    {
                        var assignment = (AssignmentExpressionSyntax)f.Expression;

                        return(ReturnStatement(assignment.Right).WithTriviaFrom(f));
                    });

                StatementContainer newContainer = await RefactorAsync(
                    document,
                    container,
                    ifStatement,
                    newIfStatement,
                    index,
                    chain.Nodes.Length,
                    semanticModel,
                    cancellationToken,
                    chain.EndsWithElse).ConfigureAwait(false);

                return(await document.ReplaceNodeAsync(container.Node, newContainer.Node, cancellationToken).ConfigureAwait(false));
            }

            case SyntaxKind.SwitchStatement:
            {
                var switchStatement = (SwitchStatementSyntax)statement;

                SyntaxList <SwitchSectionSyntax> newSections = switchStatement
                                                               .Sections
                                                               .Select(section => CreateNewSection(section))
                                                               .ToSyntaxList();

                SwitchStatementSyntax newSwitchStatement = switchStatement.WithSections(newSections);

                StatementContainer newContainer = await RefactorAsync(
                    document,
                    container,
                    switchStatement,
                    newSwitchStatement,
                    index,
                    switchStatement.Sections.Count,
                    semanticModel,
                    cancellationToken,
                    switchStatement.Sections.Any(f => f.ContainsDefaultLabel())).ConfigureAwait(false);

                return(await document.ReplaceNodeAsync(container.Node, newContainer.Node, cancellationToken).ConfigureAwait(false));
            }
            }

            Debug.Fail(statement.Kind().ToString());

            return(document);
        }