public static async Task <Document> RefactorAsync(
            Document document,
            DoStatementSyntax doStatement,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            SyntaxNode oldRoot = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            SyntaxTriviaList trailingTrivia = doStatement.Statement
                                              .GetTrailingTrivia()
                                              .AddRange(doStatement.CloseParenToken.TrailingTrivia)
                                              .AddRange(doStatement.SemicolonToken.LeadingTrivia)
                                              .AddRange(doStatement.SemicolonToken.TrailingTrivia);

            WhileStatementSyntax newNode = WhileStatement(
                doStatement.WhileKeyword.WithLeadingTrivia(doStatement.DoKeyword.LeadingTrivia),
                doStatement.OpenParenToken,
                doStatement.Condition,
                doStatement.CloseParenToken.WithTrailingTrivia(doStatement.DoKeyword.TrailingTrivia),
                doStatement.Statement.WithTrailingTrivia(trailingTrivia));

            newNode = newNode.WithFormatterAnnotation();

            SyntaxNode newRoot = oldRoot.ReplaceNode(doStatement, newNode);

            return(document.WithSyntaxRoot(newRoot));
        }
コード例 #2
0
        private static async Task <Document> RefactorAsync(
            Document document,
            ForEachStatementSyntax forEachStatement,
            CancellationToken cancellationToken)
        {
            int position = forEachStatement.SpanStart;

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

            string name = NameGenerator.Default.EnsureUniqueLocalName(DefaultNames.EnumeratorVariable, semanticModel, position, cancellationToken: cancellationToken);

            InvocationExpressionSyntax expression = SimpleMemberInvocationExpression(forEachStatement.Expression, IdentifierName(WellKnownMemberNames.GetEnumeratorMethodName));

            VariableDeclarationSyntax variableDeclaration = VariableDeclaration(VarType(), Identifier(name).WithRenameAnnotation(), expression);

            MemberAccessExpressionSyntax currentExpression = SimpleMemberAccessExpression(IdentifierName(name), IdentifierName("Current"));

            ILocalSymbol localSymbol = semanticModel.GetDeclaredSymbol(forEachStatement, cancellationToken);

            StatementSyntax statement = forEachStatement.Statement;

            StatementSyntax newStatement = statement.ReplaceNodes(
                statement
                .DescendantNodes()
                .Where(node => node.Kind() == SyntaxKind.IdentifierName && localSymbol.Equals(semanticModel.GetSymbol(node, cancellationToken))),
                (node, _) => currentExpression.WithTriviaFrom(node));

            WhileStatementSyntax whileStatement = WhileStatement(
                SimpleMemberInvocationExpression(IdentifierName(name), IdentifierName("MoveNext")),
                newStatement);

            if (semanticModel
                .GetSpeculativeMethodSymbol(position, expression)?
                .ReturnType
                .Implements(SpecialType.System_IDisposable, allInterfaces: true) == true)
            {
                UsingStatementSyntax usingStatement = UsingStatement(
                    variableDeclaration,
                    default(ExpressionSyntax),
                    Block(whileStatement));

                usingStatement = usingStatement
                                 .WithLeadingTrivia(forEachStatement.GetLeadingTrivia())
                                 .WithFormatterAnnotation();

                return(await document.ReplaceNodeAsync(forEachStatement, usingStatement, cancellationToken).ConfigureAwait(false));
            }
            else
            {
                LocalDeclarationStatementSyntax localDeclaration = LocalDeclarationStatement(variableDeclaration)
                                                                   .WithLeadingTrivia(forEachStatement.GetLeadingTrivia())
                                                                   .WithFormatterAnnotation();

                var newStatements = new StatementSyntax[] { localDeclaration, whileStatement.WithFormatterAnnotation() };

                return(await document.ReplaceNodeAsync(forEachStatement, newStatements, cancellationToken).ConfigureAwait(false));
            }
        }
コード例 #3
0
        public static Task <Document> RefactorAsync(
            Document document,
            DoStatementSyntax doStatement,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            SyntaxTriviaList trailingTrivia = doStatement.Statement
                                              .GetTrailingTrivia()
                                              .AddRange(doStatement.CloseParenToken.TrailingTrivia)
                                              .AddRange(doStatement.SemicolonToken.LeadingTrivia)
                                              .AddRange(doStatement.SemicolonToken.TrailingTrivia);

            WhileStatementSyntax newNode = WhileStatement(
                doStatement.WhileKeyword.WithLeadingTrivia(doStatement.DoKeyword.LeadingTrivia),
                doStatement.OpenParenToken,
                doStatement.Condition,
                doStatement.CloseParenToken.WithTrailingTrivia(doStatement.DoKeyword.TrailingTrivia),
                doStatement.Statement.WithTrailingTrivia(trailingTrivia));

            newNode = newNode.WithFormatterAnnotation();

            return(document.ReplaceNodeAsync(doStatement, newNode, cancellationToken));
        }
コード例 #4
0
        public static async Task <Document> RefactorAsync(
            Document document,
            BinaryExpressionSyntax condition,
            ExpressionSyntax expression,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            SyntaxNode root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            var whileStatement = (WhileStatementSyntax)condition.Parent;

            WhileStatementSyntax newWhileStatement = whileStatement.ReplaceNode(
                expression.Parent,
                ExtractExpressionFromConditionRefactoring.GetNewCondition(condition, expression));

            newWhileStatement = newWhileStatement.WithFormatterAnnotation();

            root = root.ReplaceNode(
                whileStatement,
                ExtractExpressionToNestedIf(expression, whileStatement, newWhileStatement));

            return(document.WithSyntaxRoot(root));
        }
コード例 #5
0
        private static async Task <Document> RefactorAsync(
            Document document,
            IfStatementSyntax ifStatement,
            CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();

            ExpressionSyntax condition = ifStatement.Condition;

            ElseClauseSyntax elseClause = ifStatement.Else;

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

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

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

                StatementSyntax statement = elseClause.Statement;

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

                    statement = nestedIf.Statement;
                }

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

                newIfStatement = newIfStatement.WithFormatterAnnotation();

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

                SyntaxList <StatementSyntax> statements;

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

                WhileStatementSyntax whileStatement;

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

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

                    block = Block(statements);
                }

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

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

                newWhileStatement = newWhileStatement.WithFormatterAnnotation();

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

                SyntaxList <StatementSyntax> statements = block.Statements;

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

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

                SyntaxNode newNode;

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

                    break;
                }

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

                    break;
                }

                default:
                {
                    throw new InvalidOperationException();
                }
                }

                newNode = newNode.WithFormatterAnnotation();

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

                var doStatement = (DoStatementSyntax)statement;

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

                whileStatement = whileStatement.WithFormatterAnnotation();

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

            ElseClauseSyntax elseClause = ifStatement.Else;

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

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

                StatementSyntax statement = elseClause.Statement;

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

                    statement = nestedIf.Statement;
                }

                cancellationToken.ThrowIfCancellationRequested();

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

                newNode = newNode.WithFormatterAnnotation();

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

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

                cancellationToken.ThrowIfCancellationRequested();

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

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

                newNode = newNode.WithFormatterAnnotation();

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

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

                    SyntaxList <StatementSyntax> statements = block.Statements;

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

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

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

                    SyntaxNode newNode = block.Parent;

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

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

                        break;
                    }

                    case DoStatementSyntax doStatement:
                    {
                        cancellationToken.ThrowIfCancellationRequested();

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

                        break;
                    }

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

                    newNode = newNode.WithFormatterAnnotation();

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

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

                    whileStatement = whileStatement.WithFormatterAnnotation();

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

            throw new InvalidOperationException();
        }