private static Task <Document> RefactorAsync(
            Document document,
            IfStatementSyntax ifStatement,
            StatementsSelection selectedStatements,
            CancellationToken cancellationToken)
        {
            IfStatementInfo ifStatementInfo = SyntaxInfo.IfStatementInfo(ifStatement);

            StatementSyntax newStatement = null;

            if (selectedStatements.Count == 1 &&
                !ifStatementInfo.Nodes.Any(f => f.Statement?.IsKind(SyntaxKind.Block) == true))
            {
                newStatement = selectedStatements.First();
            }
            else
            {
                newStatement = SyntaxFactory.Block(selectedStatements);
            }

            ElseClauseSyntax elseClause = SyntaxFactory.ElseClause(newStatement).WithFormatterAnnotation();

            IfStatementSyntax lastIfStatement = ifStatementInfo.Nodes.Last();

            IfStatementSyntax newIfStatement = ifStatement.ReplaceNode(
                lastIfStatement,
                lastIfStatement.WithElse(elseClause));

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

            for (int i = newStatements.Count - 1; i >= selectedStatements.StartIndex; i--)
            {
                newStatements = newStatements.RemoveAt(i);
            }

            return(document.ReplaceStatementsAsync(selectedStatements.Info, newStatements, cancellationToken));
        }
        public static void ComputeRefactoring(RefactoringContext context, StatementsSelection selectedStatements)
        {
            StatementSyntax lastStatement = selectedStatements.Last();

            if (lastStatement.IsKind(SyntaxKind.ReturnStatement) &&
                selectedStatements.EndIndex == selectedStatements.Statements.IndexOf(lastStatement) &&
                selectedStatements.StartIndex > 0)
            {
                var returnStatement = (ReturnStatementSyntax)lastStatement;

                ExpressionSyntax expression = returnStatement.Expression;

                if (expression != null)
                {
                    StatementSyntax prevStatement = selectedStatements.Statements[selectedStatements.StartIndex - 1];

                    if (prevStatement.IsKind(SyntaxKind.IfStatement))
                    {
                        var ifStatement = (IfStatementSyntax)prevStatement;

                        IfStatementInfo ifStatementInfo = SyntaxInfo.IfStatementInfo(ifStatement);

                        if (ifStatementInfo.EndsWithIf &&
                            ifStatementInfo
                            .Nodes
                            .Where(f => f.IsIf)
                            .All(f => IsLastStatementReturnStatement(f)))
                        {
                            context.RegisterRefactoring(
                                "Wrap in else clause",
                                cancellationToken => RefactorAsync(context.Document, ifStatement, selectedStatements, cancellationToken));
                        }
                    }
                }
            }
        }
Exemplo n.º 3
0
        public static async Task <Document> RefactorAsync(
            Document document,
            StatementSyntax statement,
            CancellationToken cancellationToken)
        {
            SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            StatementsInfo statementsInfo = SyntaxInfo.StatementsInfo(statement);

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

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

                IfStatementInfo ifStatementInfo = SyntaxInfo.IfStatementInfo(ifStatement);

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

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

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

                StatementsInfo newStatementsInfo = await RefactorAsync(
                    document,
                    statementsInfo,
                    ifStatement,
                    newIfStatement,
                    index,
                    ifStatementInfo.Nodes.Length,
                    ifStatementInfo.EndsWithElse,
                    semanticModel,
                    cancellationToken).ConfigureAwait(false);

                return(await document.ReplaceNodeAsync(statementsInfo.Node, newStatementsInfo.Node, cancellationToken).ConfigureAwait(false));
            }

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

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

                SwitchStatementSyntax newSwitchStatement = switchStatement.WithSections(newSections);

                StatementsInfo newStatementsInfo = await RefactorAsync(
                    document,
                    statementsInfo,
                    switchStatement,
                    newSwitchStatement,
                    index,
                    switchStatement.Sections.Count,
                    switchStatement.Sections.Any(f => f.ContainsDefaultLabel()),
                    semanticModel,
                    cancellationToken).ConfigureAwait(false);

                return(await document.ReplaceNodeAsync(statementsInfo.Node, newStatementsInfo.Node, cancellationToken).ConfigureAwait(false));
            }
            }

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

            return(document);
        }