public static Task <Document> RefactorAsync(
            Document document,
            IfStatementSyntax ifStatement,
            CancellationToken cancellationToken)
        {
            var statement = (ExpressionStatementSyntax)ifStatement.SingleNonBlockStatementOrDefault();

            SimpleMemberInvocationStatementInfo invocationInfo = SyntaxInfo.SimpleMemberInvocationStatementInfo(statement);

            int             insertIndex  = invocationInfo.Expression.Span.End - statement.FullSpan.Start;
            StatementSyntax newStatement = SyntaxFactory.ParseStatement(statement.ToFullString().Insert(insertIndex, "?"));

            IEnumerable <SyntaxTrivia> leading = ifStatement.DescendantTrivia(TextSpan.FromBounds(ifStatement.SpanStart, statement.SpanStart));

            newStatement = (leading.All(f => f.IsWhitespaceOrEndOfLineTrivia()))
                ? newStatement.WithLeadingTrivia(ifStatement.GetLeadingTrivia())
                : newStatement.WithLeadingTrivia(ifStatement.GetLeadingTrivia().Concat(leading));

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

            newStatement = (leading.All(f => f.IsWhitespaceOrEndOfLineTrivia()))
                ? newStatement.WithTrailingTrivia(ifStatement.GetTrailingTrivia())
                : newStatement.WithTrailingTrivia(trailing.Concat(ifStatement.GetTrailingTrivia()));

            return(document.ReplaceNodeAsync(ifStatement, newStatement, cancellationToken));
        }
        private async Task <Document> ReturnConditionDirectlyAsync(Document document, IfStatementSyntax ifStatement, CancellationToken cancellationToken)
        {
            var semanticModel = await document.GetSemanticModelAsync(cancellationToken);

            var statementInsideIf   = ifStatement.Statement.GetSingleStatementFromPossibleBlock();
            var statementInsideElse = ifStatement.Else.Statement.GetSingleStatementFromPossibleBlock();
            var returnIf            = statementInsideIf as ReturnStatementSyntax;
            var returnElse          = statementInsideElse as ReturnStatementSyntax;
            var condition           = returnIf.Expression is LiteralExpressionSyntax &&
                                      returnIf.Expression.IsKind(SyntaxKind.TrueLiteralExpression) &&
                                      returnElse.Expression is LiteralExpressionSyntax &&
                                      returnElse.Expression.IsKind(SyntaxKind.FalseLiteralExpression)
                ? ifStatement.Condition
                : SyntaxFactory.BinaryExpression(SyntaxKind.EqualsExpression, ifStatement.Condition, SyntaxFactory.LiteralExpression(SyntaxKind.FalseLiteralExpression));
            var newReturn = SyntaxFactory.ReturnStatement(condition)
                            .WithLeadingTrivia(ifStatement.GetLeadingTrivia())
                            .WithTrailingTrivia(ifStatement.GetTrailingTrivia())
                            .WithAdditionalAnnotations(Formatter.Annotation);
            var root = await document.GetSyntaxRootAsync();

            var newRoot     = root.ReplaceNode(ifStatement, newReturn);
            var newDocument = document.WithSyntaxRoot(newRoot);

            return(newDocument);
        }
        private static Task <Document> SplitSimpleIfAsync(
            Document document,
            IfStatementSyntax ifStatement,
            CancellationToken cancellationToken)
        {
            ExpressionSyntax condition = ifStatement.Condition;
            StatementSyntax  statement = ifStatement.Statement.WithoutTrivia();

            List <IfStatementSyntax> ifStatements = SyntaxInfo.BinaryExpressionInfo(condition)
                                                    .AsChain()
                                                    .Select(expression => IfStatement(expression.TrimTrivia(), statement).WithFormatterAnnotation())
                                                    .ToList();

            ifStatements[0] = ifStatements[0].WithLeadingTrivia(ifStatement.GetLeadingTrivia());
            ifStatements[ifStatements.Count - 1] = ifStatements[ifStatements.Count - 1].WithTrailingTrivia(ifStatement.GetTrailingTrivia());

            if (ifStatement.IsEmbedded())
            {
                BlockSyntax block = Block(ifStatements);

                return(document.ReplaceNodeAsync(ifStatement, block, cancellationToken));
            }
            else
            {
                return(document.ReplaceNodeAsync(ifStatement, ifStatements, cancellationToken));
            }
        }
        private static Task <Document> RefactorAsync(
            Document document,
            IfStatementSyntax ifStatement,
            CancellationToken cancellationToken)
        {
            StatementSyntax  statement = ifStatement.Statement.WithoutTrivia();
            ExpressionSyntax condition = ifStatement.Condition;

            var logicalOr = (BinaryExpressionSyntax)condition;

            BinaryExpressionChain chain = BinaryExpressionChain.Create((BinaryExpressionSyntax)condition);

            var ifStatements = new List <IfStatementSyntax>();

            foreach (ExpressionSyntax expression in chain.Expressions)
            {
                ifStatements.Add(SyntaxFactory.IfStatement(expression.TrimTrivia(), statement).WithFormatterAnnotation());
            }

            ifStatements[0] = ifStatements[0].WithLeadingTrivia(ifStatement.GetLeadingTrivia());
            ifStatements[ifStatements.Count - 1] = ifStatements[ifStatements.Count - 1].WithTrailingTrivia(ifStatement.GetTrailingTrivia());

            if (EmbeddedStatementHelper.IsEmbeddedStatement(ifStatement))
            {
                BlockSyntax block = SyntaxFactory.Block(ifStatements);

                return(document.ReplaceNodeAsync(ifStatement, block, cancellationToken));
            }
            else
            {
                return(document.ReplaceNodeAsync(ifStatement, ifStatements, cancellationToken));
            }
        }
示例#5
0
        private static Task <Document> IfReturnToReturnWithConditionalExpressionAsync(
            Document document,
            IfReturnToReturnWithConditionalExpressionAnalysis analysis,
            CancellationToken cancellationToken = default)
        {
            IfStatementSyntax ifStatement = analysis.IfStatement;

            StatementListInfo statementsInfo = SyntaxInfo.StatementListInfo(ifStatement);

            SyntaxList <StatementSyntax> statements = statementsInfo.Statements;

            int index = statements.IndexOf(ifStatement);

            ConditionalExpressionSyntax conditionalExpression = CreateConditionalExpression(ifStatement.Condition, analysis.Expression1, analysis.Expression2);

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

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

            return(document.ReplaceStatementsAsync(statementsInfo, newStatements, cancellationToken));
        }
        private async Task <Document> RemoveIfStatement2(Document document, IfStatementSyntax node, CancellationToken cancellationToken)
        {
            var root = await document.GetSyntaxRootAsync(cancellationToken);

            var leadingTrivia  = node.GetLeadingTrivia();
            var trailingTrivia = node.GetTrailingTrivia();

            SyntaxNode replaceNode = node.Statement;
            SyntaxNode ifBlock     = node.Statement;

            if (ifBlock is BlockSyntax block)
            {
                StatementSyntax statement = block.Statements[0];

                trailingTrivia = trailingTrivia.AddRange(block.CloseBraceToken.LeadingTrivia);

                replaceNode = statement.WithLeadingTrivia(leadingTrivia);
            }
            else
            {
                replaceNode = replaceNode.WithLeadingTrivia(leadingTrivia);
            }
            var newLine = SyntaxFactory.SyntaxTrivia(SyntaxKind.WhitespaceTrivia, Environment.NewLine);

            replaceNode = replaceNode.WithTrailingTrivia(trailingTrivia.Insert(0, newLine));

            root = root.ReplaceNode(node, replaceNode).WithAdditionalAnnotations(Formatter.Annotation);

            return(document.WithSyntaxRoot(root));
        }
示例#7
0
        private static SyntaxNode GetNewRoot(
            SyntaxNode root,
            IfStatementSyntax ifStatement,
            ReturnStatementSyntax newReturnStatement)
        {
            if (ifStatement.Else != null)
            {
                newReturnStatement = newReturnStatement.WithTriviaFrom(ifStatement);

                return(root.ReplaceNode(ifStatement, newReturnStatement));
            }
            else
            {
                var block = (BlockSyntax)ifStatement.Parent;

                int index = block.Statements.IndexOf(ifStatement);

                var returnStatement = (ReturnStatementSyntax)block.Statements[index + 1];

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

                SyntaxList <StatementSyntax> statements = block.Statements
                                                          .RemoveAt(index);

                statements = statements
                             .Replace(statements[index], newReturnStatement);

                return(root.ReplaceNode(block, block.WithStatements(statements)));
            }
        }
示例#8
0
        public static async Task <Document> RefactorAsync(
            Document document,
            StatementContainer container,
            IfStatementSyntax ifStatement,
            ReturnStatementSyntax returnStatement,
            CancellationToken cancellationToken)
        {
            ExpressionSyntax expression = ReplaceIfWithStatementRefactoring.GetExpression(
                ifStatement.Condition,
                ReplaceIfWithStatementRefactoring.GetReturnExpression(ifStatement),
                returnStatement.Expression);

            ReturnStatementSyntax newReturnStatement = ReturnStatement(expression);

            SyntaxList <StatementSyntax> statements = container.Statements;

            int index = statements.IndexOf(ifStatement);

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

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

            return(await document.ReplaceNodeAsync(container.Node, container.NodeWithStatements(newStatements), cancellationToken).ConfigureAwait(false));
        }
示例#9
0
        private static async Task <Document> RefactorAsync(
            Document document,
            StatementContainer container,
            IfStatementSyntax ifStatement,
            ReturnStatementSyntax returnStatement,
            ExpressionSyntax whenTrue,
            ExpressionSyntax whenFalse,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            SyntaxList <StatementSyntax> statements = container.Statements;

            int index = statements.IndexOf(ifStatement);

            ConditionalExpressionSyntax conditionalExpression = ReplaceIfWithStatementRefactoring.CreateConditionalExpression(ifStatement.Condition, whenTrue, whenFalse);

            ReturnStatementSyntax newReturnStatement = ReturnStatement(conditionalExpression)
                                                       .WithLeadingTrivia(ifStatement.GetLeadingTrivia())
                                                       .WithTrailingTrivia(returnStatement.GetTrailingTrivia())
                                                       .WithFormatterAnnotation();

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

            return(await document.ReplaceNodeAsync(container.Node, container.NodeWithStatements(newStatements), cancellationToken).ConfigureAwait(false));
        }
        public static Task <Document> RefactorAsync(
            Document document,
            IfStatementSyntax ifStatement,
            CancellationToken cancellationToken)
        {
            ReturnStatementSyntax newReturnStatement = CreateReturnStatement(ifStatement);

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

                return(document.ReplaceNodeAsync(ifStatement, newReturnStatement, cancellationToken));
            }
            else
            {
                var block = (BlockSyntax)ifStatement.Parent;
                SyntaxList <StatementSyntax> statements = block.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);

                return(document.ReplaceNodeAsync(block, block.WithStatements(newStatements), cancellationToken));
            }
        }
示例#11
0
 public override SyntaxNode VisitIfStatement(IfStatementSyntax node)
 {
     if (RemoveTestTriviaAnnotation(node.GetLeadingTrivia()))
     {
         return(null);
     }
     return(base.VisitIfStatement(node));
 }
示例#12
0
        public static async Task <Document> RefactorAsync(
            Document document,
            IfStatementSyntax ifStatement,
            CancellationToken cancellationToken)
        {
            var statement = (ExpressionStatementSyntax)ifStatement.SingleNonBlockStatementOrDefault();

            StatementSyntax newStatement = statement;

            NullCheckExpressionInfo nullCheck = SyntaxInfo.NullCheckExpressionInfo(ifStatement.Condition, NullCheckStyles.NotEqualsToNull);

            SimpleMemberInvocationStatementInfo invocationInfo = SyntaxInfo.SimpleMemberInvocationStatementInfo(statement);

            ExpressionSyntax expression = invocationInfo.Expression;

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

            if (semanticModel.GetTypeSymbol(nullCheck.Expression, cancellationToken).IsNullableType())
            {
                var memberAccess = (MemberAccessExpressionSyntax)invocationInfo.Expression;

                newStatement = statement.ReplaceNode(memberAccess, memberAccess.Expression.WithTrailingTrivia(memberAccess.GetTrailingTrivia()));

                expression = memberAccess.Expression;
            }

            int insertIndex = expression.Span.End - statement.FullSpan.Start;

            newStatement = SyntaxFactory.ParseStatement(newStatement.ToFullString().Insert(insertIndex, "?"));

            IEnumerable <SyntaxTrivia> leading = ifStatement.DescendantTrivia(TextSpan.FromBounds(ifStatement.SpanStart, statement.SpanStart));

            newStatement = (leading.All(f => f.IsWhitespaceOrEndOfLineTrivia()))
                ? newStatement.WithLeadingTrivia(ifStatement.GetLeadingTrivia())
                : newStatement.WithLeadingTrivia(ifStatement.GetLeadingTrivia().Concat(leading));

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

            newStatement = (leading.All(f => f.IsWhitespaceOrEndOfLineTrivia()))
                ? newStatement.WithTrailingTrivia(ifStatement.GetTrailingTrivia())
                : newStatement.WithTrailingTrivia(trailing.Concat(ifStatement.GetTrailingTrivia()));

            return(await document.ReplaceNodeAsync(ifStatement, newStatement, cancellationToken).ConfigureAwait(false));
        }
示例#13
0
        private static Task <Document> IfToReturnWithExpressionAsync(
            Document document,
            IfToReturnWithExpressionAnalysis analysis,
            CancellationToken cancellationToken = default)
        {
            ExpressionSyntax expression = analysis.Expression;

            if (analysis.Invert)
            {
                expression = SyntaxInverter.LogicallyInvert(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));
            }
        }
 private static async Task<Document> UseExistenceOperatorAsyncWithReturnAsync(Document document, IfStatementSyntax ifStatement, CancellationToken cancellationToken, ReturnStatementSyntax returnIf)
 {
     var newMemberAccess = ((MemberAccessExpressionSyntax)returnIf.Expression).ToConditionalAccessExpression();
     var newReturn = SyntaxFactory.ReturnStatement(newMemberAccess)
         .WithLeadingTrivia(ifStatement.GetLeadingTrivia())
         .WithTrailingTrivia(ifStatement.GetTrailingTrivia())
         .WithAdditionalAnnotations(Formatter.Annotation);
     var root = await document.GetSyntaxRootAsync(cancellationToken);
     var newRoot = root.ReplaceNode(ifStatement, newReturn);
     var newDocument = document.WithSyntaxRoot(newRoot);
     return newDocument;
 }
 private static async Task<Document> UseExistenceOperatorAsyncWithAssignmentAsync(Document document, IfStatementSyntax ifStatement, CancellationToken cancellationToken, ExpressionStatementSyntax expressionIf)
 {
     var memberAccessAssignment = (AssignmentExpressionSyntax)expressionIf.Expression;
     var newMemberAccess = ((MemberAccessExpressionSyntax)memberAccessAssignment.Right).ToConditionalAccessExpression();
     var newExpressionStatement = SyntaxFactory.ExpressionStatement(SyntaxFactory.AssignmentExpression(SyntaxKind.SimpleAssignmentExpression, memberAccessAssignment.Left, newMemberAccess))
         .WithLeadingTrivia(ifStatement.GetLeadingTrivia())
         .WithTrailingTrivia(ifStatement.GetTrailingTrivia())
         .WithAdditionalAnnotations(Formatter.Annotation);
     var root = await document.GetSyntaxRootAsync(cancellationToken);
     var newRoot = root.ReplaceNode(ifStatement, newExpressionStatement);
     var newDocument = document.WithSyntaxRoot(newRoot);
     return newDocument;
 }
 private static SyntaxNode MergeIfs(IfStatementSyntax ifStatement, SyntaxNode root)
 {
     var nestedIf = (IfStatementSyntax)ifStatement.Statement.GetSingleStatementFromPossibleBlock();
     var newIf = ifStatement
         .WithCondition(SyntaxFactory.BinaryExpression(SyntaxKind.LogicalAndExpression, ifStatement.Condition, nestedIf.Condition))
         .WithStatement(nestedIf.Statement)
         .WithLeadingTrivia(ifStatement.GetLeadingTrivia().AddRange(nestedIf.GetLeadingTrivia()))
         .WithAdditionalAnnotations(Formatter.Annotation);
     if (ifStatement.HasTrailingTrivia && nestedIf.HasTrailingTrivia && !ifStatement.GetTrailingTrivia().Equals(nestedIf.GetTrailingTrivia()))
         newIf = newIf.WithTrailingTrivia(ifStatement.GetTrailingTrivia().AddRange(nestedIf.GetTrailingTrivia()));
     var newRoot = root.ReplaceNode(ifStatement, newIf);
     return newRoot;
 }
示例#17
0
        private CodeAction CreateCodeAction(Document document, Diagnostic diagnostic, IfStatementSyntax ifStatement, StatementSyntax statement)
        {
            return(CodeAction.Create(
                       Title,
                       cancellationToken =>
            {
                StatementSyntax newNode = statement
                                          .WithLeadingTrivia(ifStatement.GetLeadingTrivia().AddRange(statement.GetLeadingTrivia().EmptyIfWhitespace()))
                                          .WithTrailingTrivia(statement.GetTrailingTrivia().EmptyIfWhitespace().AddRange(ifStatement.GetTrailingTrivia()));

                return document.ReplaceNodeAsync(ifStatement, newNode, cancellationToken);
            },
                       GetEquivalenceKey(diagnostic)));
        }
示例#18
0
        private async Task <Document> UseExistenceOperatorAsyncWithReturnAsync(Document document, IfStatementSyntax ifStatement, CancellationToken cancellationToken, ReturnStatementSyntax returnIf)
        {
            var newMemberAccess = ((MemberAccessExpressionSyntax)returnIf.Expression).ToConditionalAccessExpression();
            var newReturn       = SyntaxFactory.ReturnStatement(newMemberAccess)
                                  .WithLeadingTrivia(ifStatement.GetLeadingTrivia())
                                  .WithTrailingTrivia(ifStatement.GetTrailingTrivia())
                                  .WithAdditionalAnnotations(Formatter.Annotation);
            var root = await document.GetSyntaxRootAsync(cancellationToken);

            var newRoot     = root.ReplaceNode(ifStatement, newReturn);
            var newDocument = document.WithSyntaxRoot(newRoot);

            return(newDocument);
        }
示例#19
0
        private async Task <Document> UseExistenceOperatorAsyncWithAssignmentAsync(Document document, IfStatementSyntax ifStatement, CancellationToken cancellationToken, ExpressionStatementSyntax expressionIf)
        {
            var memberAccessAssignment = (AssignmentExpressionSyntax)expressionIf.Expression;
            var newMemberAccess        = ((MemberAccessExpressionSyntax)memberAccessAssignment.Right).ToConditionalAccessExpression();
            var newExpressionStatement = SyntaxFactory.ExpressionStatement(SyntaxFactory.AssignmentExpression(SyntaxKind.SimpleAssignmentExpression, memberAccessAssignment.Left, newMemberAccess))
                                         .WithLeadingTrivia(ifStatement.GetLeadingTrivia())
                                         .WithTrailingTrivia(ifStatement.GetTrailingTrivia())
                                         .WithAdditionalAnnotations(Formatter.Annotation);
            var root = await document.GetSyntaxRootAsync(cancellationToken);

            var newRoot     = root.ReplaceNode(ifStatement, newExpressionStatement);
            var newDocument = document.WithSyntaxRoot(newRoot);

            return(newDocument);
        }
示例#20
0
        private async Task <Document> MakeTernaryAsync(Document document, IfStatementSyntax ifStatement, CancellationToken cancellationToken)
        {
            var statementInsideIf   = (ReturnStatementSyntax)(ifStatement.Statement is BlockSyntax ? ((BlockSyntax)ifStatement.Statement).Statements.Single() : ifStatement.Statement);
            var elseStatement       = ifStatement.Else;
            var statementInsideElse = (ReturnStatementSyntax)(elseStatement.Statement is BlockSyntax ? ((BlockSyntax)elseStatement.Statement).Statements.Single() : elseStatement.Statement);
            var ternary             = SyntaxFactory.ParseStatement($"return {ifStatement.Condition.ToString()} ? {statementInsideIf.Expression.ToString()} : {statementInsideElse.Expression.ToString()};")
                                      .WithLeadingTrivia(ifStatement.GetLeadingTrivia())
                                      .WithTrailingTrivia(ifStatement.GetTrailingTrivia())
                                      .WithAdditionalAnnotations(Formatter.Annotation);
            var root = await document.GetSyntaxRootAsync(cancellationToken);

            var newRoot     = root.ReplaceNode(ifStatement, ternary);
            var newDocument = document.WithSyntaxRoot(newRoot);

            return(newDocument);
        }
        private async Task <Document> RemoveIfStatement(Document document, IfStatementSyntax node, CancellationToken cancellationToken)
        {
            var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            SyntaxNode replaceNode = node.Statement;
            SyntaxNode ifBlock     = node.Statement;

            if (ifBlock is BlockSyntax block)
            {
                replaceNode = block.Statements[0].WithLeadingTrivia(node.GetLeadingTrivia());
            }

            root = root.ReplaceNode(node, replaceNode).WithAdditionalAnnotations(Formatter.Annotation);

            return(document.WithSyntaxRoot(root));
        }
        private static SyntaxNode MergeIfs(IfStatementSyntax ifStatement, SyntaxNode root)
        {
            var nestedIf = (IfStatementSyntax)ifStatement.Statement.GetSingleStatementFromPossibleBlock();
            var newIf    = ifStatement
                           .WithCondition(SyntaxFactory.BinaryExpression(SyntaxKind.LogicalAndExpression, ifStatement.Condition, nestedIf.Condition))
                           .WithStatement(nestedIf.Statement)
                           .WithLeadingTrivia(ifStatement.GetLeadingTrivia().AddRange(nestedIf.GetLeadingTrivia()))
                           .WithAdditionalAnnotations(Formatter.Annotation);

            if (ifStatement.HasTrailingTrivia && nestedIf.HasTrailingTrivia && !ifStatement.GetTrailingTrivia().Equals(nestedIf.GetTrailingTrivia()))
            {
                newIf = newIf.WithTrailingTrivia(ifStatement.GetTrailingTrivia().AddRange(nestedIf.GetTrailingTrivia()));
            }
            var newRoot = root.ReplaceNode(ifStatement, newIf);

            return(newRoot);
        }
示例#23
0
        private async Task <Document> ConvertToSwitchAsync(Document document, IfStatementSyntax ifStatement, CancellationToken cancellationToken)
        {
            var nestedIfs = ConvertToSwitchAnalyzer.FindNestedIfs(ifStatement).ToArray();

            var sections = new List <SwitchSectionSyntax>();

            foreach (var nestedIf in nestedIfs)
            {
                var label = SyntaxFactory.CaseSwitchLabel(
                    ((BinaryExpressionSyntax)nestedIf.Condition).Right);

                if (nestedIf != ifStatement)
                {
                    label = label.WithLeadingTrivia(nestedIf.Parent.GetLeadingTrivia());
                }

                sections.Add(CreateSection(label, nestedIf.Statement));
            }

            var @else = nestedIfs.Last().Else;

            if (@else != null)
            {
                sections.Add(CreateSection(
                                 SyntaxFactory.DefaultSwitchLabel()
                                 .WithLeadingTrivia(@else.GetLeadingTrivia()),
                                 @else.Statement
                                 ));
            }

            var condition        = ifStatement.Condition as BinaryExpressionSyntax;
            var switchExpression = SyntaxFactory.IdentifierName((condition.Left as IdentifierNameSyntax).Identifier.Text);

            var switchStatement = SyntaxFactory.SwitchStatement(switchExpression)
                                  .WithSections(new SyntaxList <SwitchSectionSyntax>().AddRange(sections))
                                  .WithLeadingTrivia(ifStatement.GetLeadingTrivia())
                                  .WithAdditionalAnnotations(Formatter.Annotation);

            var root = await document.GetSyntaxRootAsync(cancellationToken);

            var newRoot     = root.ReplaceNode(ifStatement, switchStatement);
            var newDocument = document.WithSyntaxRoot(newRoot);

            return(newDocument);
        }
        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));
        }
示例#25
0
        public SyntaxNode VisitIfStatement(IfStatementSyntax node)
        {
            return(node);

            // Generates a node containing only parenthesis
            // with no identifier, no return type and no parameters
            var newNode = SyntaxFactory.MethodDeclaration(SyntaxFactory.IdentifierName(""), "");

            // Removes the parenthesis from the Parameter List
            // and replaces them with MissingTokens
            newNode = newNode.ReplaceNode(newNode.ParameterList,
                                          newNode.ParameterList.WithOpenParenToken(
                                              SyntaxFactory.MissingToken(SyntaxKind.OpenParenToken)).
                                          WithCloseParenToken(SyntaxFactory.MissingToken(SyntaxKind.CloseParenToken)));
            // Returns the new method containing no content
            // but the Leading and Trailing trivia of the previous node
            return(newNode.WithLeadingTrivia(node.GetLeadingTrivia()).
                   WithTrailingTrivia(node.GetTrailingTrivia()));
        }
示例#26
0
        private async Task <Document> MakeTernaryAsync(Document document, IfStatementSyntax ifStatement, CancellationToken cancellationToken)
        {
            var expressionInsideIf   = (ExpressionStatementSyntax)(ifStatement.Statement is BlockSyntax ? ((BlockSyntax)ifStatement.Statement).Statements.Single() : ifStatement.Statement);
            var elseStatement        = ifStatement.Else;
            var expressionInsideElse = (ExpressionStatementSyntax)(elseStatement.Statement is BlockSyntax ? ((BlockSyntax)elseStatement.Statement).Statements.Single() : elseStatement.Statement);

            var assignmentExpressionInsideIf   = (AssignmentExpressionSyntax)expressionInsideIf.Expression;
            var assignmentExpressionInsideElse = (AssignmentExpressionSyntax)expressionInsideElse.Expression;
            var variableIdentifierInsideIf     = assignmentExpressionInsideIf.Left as IdentifierNameSyntax;
            var ternary = SyntaxFactory.ParseStatement($"{variableIdentifierInsideIf.Identifier.Text} = {ifStatement.Condition.ToString()} ? {assignmentExpressionInsideIf.Right.ToString()} : {assignmentExpressionInsideElse.Right.ToString()};")
                          .WithLeadingTrivia(ifStatement.GetLeadingTrivia())
                          .WithTrailingTrivia(ifStatement.GetTrailingTrivia())
                          .WithAdditionalAnnotations(Formatter.Annotation);
            var root = await document.GetSyntaxRootAsync(cancellationToken);

            var newRoot     = root.ReplaceNode(ifStatement, ternary);
            var newDocument = document.WithSyntaxRoot(newRoot);

            return(newDocument);
        }
        private static SyntaxNode GetNewRoot(
            SyntaxNode root,
            IfStatementSyntax ifStatement,
            ReturnStatementSyntax newReturnStatement)
        {
            if (ifStatement.Else != null)
            {
                ReturnStatementSyntax   returnStatement = SimplifyIfStatementToReturnStatementAnalyzer.GetReturnStatement(ifStatement.Statement);
                LiteralExpressionSyntax booleanLiteral  = SimplifyIfStatementToReturnStatementAnalyzer.GetBooleanLiteral(returnStatement);

                newReturnStatement = newReturnStatement.WithTriviaFrom(ifStatement);

                return(root.ReplaceNode(ifStatement, newReturnStatement));
            }
            else
            {
                var block = (BlockSyntax)ifStatement.Parent;

                int index = block.Statements.IndexOf(ifStatement);

                var returnStatement = (ReturnStatementSyntax)block.Statements[index + 1];

                LiteralExpressionSyntax booleanLiteral = SimplifyIfStatementToReturnStatementAnalyzer.GetBooleanLiteral(returnStatement);

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

                SyntaxList <StatementSyntax> statements = block.Statements
                                                          .RemoveAt(index);

                statements = statements
                             .Replace(statements[index], newReturnStatement);

                return(root.ReplaceNode(block, block.WithStatements(statements)));
            }
        }
示例#28
0
        private CodeAction CreateCodeAction(Document document, Diagnostic diagnostic, IfStatementSyntax ifStatement, SyntaxList <StatementSyntax> statements)
        {
            return(CodeAction.Create(
                       Title,
                       cancellationToken =>
            {
                StatementSyntax firstStatement = statements[0];

                StatementSyntax newFirstStatement = firstStatement
                                                    .WithLeadingTrivia(ifStatement.GetLeadingTrivia().AddRange(firstStatement.GetLeadingTrivia().EmptyIfWhitespace()));

                statements = statements.Replace(firstStatement, newFirstStatement);

                StatementSyntax lastStatement = statements.Last();

                StatementSyntax newLastStatement = lastStatement
                                                   .WithTrailingTrivia(lastStatement.GetTrailingTrivia().EmptyIfWhitespace().AddRange(ifStatement.GetTrailingTrivia()));

                statements = statements.Replace(lastStatement, newLastStatement);

                return document.ReplaceNodeAsync(ifStatement, statements, cancellationToken);
            },
                       GetEquivalenceKey(diagnostic)));
        }
示例#29
0
        private Decisions TraverseIfStatements(IfStatementSyntax iss, ref int exitPoints, bool nested = false)
        {
            Decisions retDecision = new Decisions();
            IfStatement ifStm = new IfStatement();
            if (iss.HasLeadingTrivia)
            {
                SetOuterComments(ifStm, iss.GetLeadingTrivia().ToFullString());
            }

            if (iss.HasTrailingTrivia)
            {
                SetInnerComments(ifStm, iss.GetTrailingTrivia().ToFullString());
            }
            ifStm.IsNested = nested;
            //public int ExpressionListEndLn { get; set; }
            //public int ExpressionListStartLn { get; set; }
            //public bool IsNested { get; set; }
            ExpressionSyntax es = iss.Condition;
            var binaryExpressions = from aBinaryExpression in iss.Condition.DescendantNodesAndSelf().OfType<BinaryExpressionSyntax>() select aBinaryExpression;
            ifStm.ConditionCount = binaryExpressions.Count();
            //This area is for the conditions i.e. the stuff in the () of if ()
            foreach (BinaryExpressionSyntax bes in binaryExpressions)
            {
                Method tempMethod = TraverseBinaryExpression(bes);
                ifStm.AccessedVars.AddRange(tempMethod.AccessedVariables);
                ifStm.InvokedMethods.AddRange(tempMethod.InvokedMethods);
            }
            //TODO handle catches (if there are even catches inside if statements)
            var catches = from aCatch in iss.ChildNodes().OfType<CatchClauseSyntax>() select aCatch;
            foreach (CatchClauseSyntax ccs in catches)
            {
                Decisions tempCatch = TraverseCatchClauses(ccs, ref exitPoints, true);
                ifStm.Nested.AddRange(tempCatch.Catches);
            }
            //TODO need to handle else clauses
            var elses = from aElse in iss.ChildNodes().OfType<ElseClauseSyntax>() select aElse;
            foreach (ElseClauseSyntax ecs in elses)
            {
                //TODO
                //Traverse ElseClauseSyntax
                Decisions tempElse = TraverseElseClauses(ecs, ref exitPoints, true);
                ifStm.Nested.AddRange(tempElse.ElseStatements);
                #region old code with method return
                //ifStm.InvokedMethods.AddRange(tempElse.InvokedMethods);
                //ifStm.AccessedVars.AddRange(tempElse.AccessedVars);
                //ifStm.Nested.Add(tempElse);
                //foreach (BaseDecisions bd in ifStm.Nested)
                //{
                //    bd.IsNested = true;
                //}
                #endregion
            }
            //TODO need to find a way to return both nested
            //and invoked methods / accessedvars to the parent method
            var statements = from aStatement in iss.Statement.ChildNodes().OfType<StatementSyntax>() select aStatement;
            List<BaseDecisions> retBd = new List<BaseDecisions>();
            List<InvokedMethod> retIm = new List<InvokedMethod>();
            #region Nested and Invoked Methods and accessed vars
            foreach (StatementSyntax ss in statements)
            {

                //if (ss is BreakStatementSyntax)
                //{
                //}
                //else if (ss is CheckedStatementSyntax)
                //{
                //}
                //else if (ss is ContinueStatementSyntax)
                //{
                //}
                if (ss is DoStatementSyntax)
                {
                    Decisions dwl = TraverseDoStatements(ss as DoStatementSyntax, ref exitPoints, true);
                    ifStm.Nested.AddRange(dwl.DoWhileLoops);
                    //dwl.IsNested = true;
                    //ifStm.Nested.Add(dwl);
                }
                //else if (ss is EmptyStatementSyntax)
                //{
                //}
                else if (ss is ExpressionStatementSyntax)
                {
                    Method tempMethod = TraverseExpressionStatementSyntax(ss as ExpressionStatementSyntax);
                    ifStm.AccessedVars.AddRange(tempMethod.AccessedVariables);
                    ifStm.InvokedMethods.AddRange(tempMethod.InvokedMethods);
                }
                //else if (ss is FixedStatementSyntax)
                //{
                //}
                else if (ss is ForEachStatementSyntax)
                {
                    Decisions fes = TraverseForEachStatements(ss as ForEachStatementSyntax, ref exitPoints, true);
                    ifStm.Nested.AddRange(fes.ForEachStatements);
                    //fes.IsNested = true;
                    //ifStm.Nested.Add(fes);
                }
                else if (ss is ForStatementSyntax)
                {
                    Decisions fs = TraverseForStatements(ss as ForStatementSyntax, ref exitPoints, true);
                    ifStm.Nested.AddRange(fs.ForStatements);
                    //fs.IsNested = true;
                    //ifStm.Nested.Add(fs);
                }
                //else if (ss is GotoStatementSyntax)
                //{
                //}
                else if (ss is IfStatementSyntax)
                {
                    Decisions decision = TraverseIfStatements(ss as IfStatementSyntax, ref exitPoints, true);
                    ifStm.Nested.AddRange(decision.IfStatements);
                }
                //else if (ss is LabeledStatementSyntax)
                //{
                //    BaseDecisions bd = new BaseDecisions();
                //    bd.IsNested = true;
                //    bd.Nested.Add(TraverseLabelStatements(ss as LabeledStatementSyntax));
                //    retIf.Nested.Add(bd);
                //}
                else if (ss is LocalDeclarationStatementSyntax)
                {
                    Model.Type tempType = new Model.Type();
                    LocalDeclarationStatementSyntax ldss = ss as LocalDeclarationStatementSyntax;
                    if (ldss.Declaration != null)
                    {
                        VariableDeclarationSyntax vds = ldss.Declaration;
                        tempType.Name = vds.Type.ToString();
                        tempType.IsKnownType = true;
                        tempType.IsNotUserDefined = true;
                    }
                    Method tempMethod = TransverseAccessVars(ss as LocalDeclarationStatementSyntax);
                    //NOT SURE if this will work but here goes
                    tempMethod.AccessedVariables[0].Type = tempType;
                    ifStm.AccessedVars.AddRange(tempMethod.AccessedVariables);
                    ifStm.InvokedMethods.AddRange(tempMethod.InvokedMethods);
                }
                //else if (ss is LockStatementSyntax)
                //{
                //}
                else if (ss is ReturnStatementSyntax)
                {
                    exitPoints++;
                }
                else if (ss is SwitchStatementSyntax)
                {
                    Decisions switchStm = TraverseSwitchStatements(ss as SwitchStatementSyntax, ref exitPoints, true);
                    ifStm.Nested.AddRange(switchStm.SwitchStatements);
                    //switchStm.IsNested = true;
                    //ifStm.Nested.Add(switchStm);
                }
                //else if (ss is ThrowStatementSyntax)
                //{
                //}
                //else if (ss is TryStatementSyntax)
                //{
                //}
                //else if (ss is UnsafeStatementSyntax)
                //{
                //}
                //else if (ss is UsingStatementSyntax)
                //{
                //    //using list?
                //}
                else if (ss is WhileStatementSyntax)
                {
                    Decisions wl = TraverseWhileLoops(ss as WhileStatementSyntax, ref exitPoints, true);
                    ifStm.Nested.AddRange(wl.WhileLoops);
                    //wl.IsNested = true;
                    //ifStm.Nested.Add(wl);
                }
                //else if (ss is YieldStatementSyntax)
                //{
                //}
            }
            #endregion

            retDecision.IfStatements.Add(ifStm);

            return retDecision;
        }
示例#30
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();
            }
        }
示例#31
0
        private static Task <Document> IfToReturnWithCoalesceExpressionAsync(
            Document document,
            IfToReturnWithCoalesceExpressionAnalysis analysis,
            CancellationToken cancellationToken = default)
        {
            IfStatementSyntax ifStatement = analysis.IfStatement;
            int position = ifStatement.SpanStart;

            ITypeSymbol targetType = GetTargetType();

            BinaryExpressionSyntax coalesceExpression = CreateCoalesceExpression(
                analysis.Left.WithoutTrivia(),
                analysis.Right.WithoutTrivia(),
                targetType,
                position,
                analysis.SemanticModel);

            StatementSyntax statement;

            if (analysis.IsYield)
            {
                statement = YieldReturnStatement(coalesceExpression);
            }
            else
            {
                statement = ReturnStatement(coalesceExpression);
            }

            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));
            }

            ITypeSymbol GetTargetType()
            {
                IMethodSymbol methodSymbol = analysis.SemanticModel.GetEnclosingSymbol <IMethodSymbol>(position, cancellationToken);

                Debug.Assert(methodSymbol != null, "");

                if (methodSymbol?.IsErrorType() == false)
                {
                    ITypeSymbol returnType = methodSymbol.ReturnType;

                    if (!returnType.IsErrorType())
                    {
                        if (methodSymbol.IsAsync)
                        {
                            if (returnType.OriginalDefinition.EqualsOrInheritsFrom(MetadataNames.System_Threading_Tasks_Task_T))
                            {
                                return(((INamedTypeSymbol)returnType).TypeArguments[0]);
                            }
                        }
                        else if (!analysis.IsYield)
                        {
                            return(returnType);
                        }
                        else if (returnType.SpecialType == SpecialType.System_Collections_IEnumerable)
                        {
                            return(analysis.SemanticModel.Compilation.ObjectType);
                        }
                        else if (returnType.OriginalDefinition.IsIEnumerableOfT())
                        {
                            return(((INamedTypeSymbol)returnType).TypeArguments[0]);
                        }
                    }
                }

                return(null);
            }
        }
示例#32
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();
        }
示例#33
0
        public static Task <Document> InlineLazyInitializationAsync(
            Document document,
            IfStatementSyntax ifStatement,
            CancellationToken cancellationToken = default)
        {
            StatementListInfo statementsInfo = SyntaxInfo.StatementListInfo(ifStatement);

            var assignmentStatement = (ExpressionStatementSyntax)ifStatement.SingleNonBlockStatementOrDefault();

            SimpleAssignmentStatementInfo assignmentInfo = SyntaxInfo.SimpleAssignmentStatementInfo(assignmentStatement, walkDownParentheses: false);

            ExpressionSyntax right = assignmentInfo.Right;

            int index = statementsInfo.IndexOf(ifStatement);

            var expressionStatement2 = (ExpressionStatementSyntax)statementsInfo[index + 1];

            SimpleMemberInvocationStatementInfo invocationInfo = SyntaxInfo.SimpleMemberInvocationStatementInfo(expressionStatement2);

            ExpressionSyntax expression = invocationInfo.Expression;

            var newLeading = new List <SyntaxTrivia>(ifStatement.GetLeadingTrivia());

            ExpressionSyntax coalesceExpression;

            if (document.SupportsLanguageFeature(CSharpLanguageFeature.NullCoalescingAssignmentOperator))
            {
                AddTrivia(ifStatement.DescendantTrivia(TextSpan.FromBounds(ifStatement.SpanStart, right.SpanStart)).ToSyntaxTriviaList());

                coalesceExpression = CoalesceAssignmentExpression(expression.WithoutTrivia(), right.WithoutTrivia());
            }
            else
            {
                AddTrivia(ifStatement.DescendantTrivia(TextSpan.FromBounds(ifStatement.SpanStart, assignmentInfo.AssignmentExpression.SpanStart)).ToSyntaxTriviaList());

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

            AddTrivia(ifStatement.DescendantTrivia(TextSpan.FromBounds(right.Span.End, ifStatement.Span.End)).ToSyntaxTriviaList());
            AddTrivia(ifStatement.GetTrailingTrivia());
            AddTrivia(expressionStatement2.GetLeadingTrivia());

            ParenthesizedExpressionSyntax newExpression = ParenthesizedExpression(coalesceExpression)
                                                          .WithLeadingTrivia(newLeading)
                                                          .WithTrailingTrivia(expression.GetTrailingTrivia());

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

            StatementListInfo newStatements = statementsInfo
                                              .Replace(expressionStatement2, newExpressionStatement)
                                              .RemoveAt(index);

            return(document.ReplaceStatementsAsync(statementsInfo, newStatements, cancellationToken));

            void AddTrivia(SyntaxTriviaList trivia)
            {
                if (!trivia.IsEmptyOrWhitespace())
                {
                    newLeading.AddRange(trivia);
                }
            }
        }
示例#34
0
        public override async Task ComputeRefactoringsAsync(CodeRefactoringContext context)
        {
            var document = context.Document;

            if (document.Project.Solution.Workspace.Kind == WorkspaceKind.MiscellaneousFiles)
            {
                return;
            }
            var span = context.Span;

            if (!span.IsEmpty)
            {
                return;
            }
            var cancellationToken = context.CancellationToken;

            if (cancellationToken.IsCancellationRequested)
            {
                return;
            }
            var model = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            if (model.IsFromGeneratedCode(cancellationToken))
            {
                return;
            }
            var root = await model.SyntaxTree.GetRootAsync(cancellationToken).ConfigureAwait(false);

            var node = root.FindNode(span) as SwitchStatementSyntax;

            if (node == null || node.Sections.Count == 0 || node.Sections.All(l => l.Labels.Any(s => s.Keyword.IsKind(SyntaxKind.DefaultKeyword))))
            {
                return;
            }

            foreach (var section in node.Sections)
            {
                var lastStatement = section.Statements.LastOrDefault();
                //ignore non-trailing breaks
                if (HasNonTrailingBreaks(section, lastStatement as BreakStatementSyntax))
                {
                    return;
                }
            }

            context.RegisterRefactoring(
                CodeActionFactory.Create(
                    span,
                    DiagnosticSeverity.Info,
                    GettextCatalog.GetString("To 'if'"),
                    t2 =>
            {
                var ifNodes = new List <IfStatementSyntax>();
                ElseClauseSyntax defaultElse = null;

                foreach (var section in node.Sections)
                {
                    var condition = CollectCondition(node.Expression, section.Labels);
                    var body      = SyntaxFactory.Block();
                    var last      = section.Statements.LastOrDefault();
                    foreach (var statement in section.Statements)
                    {
                        if (statement.IsEquivalentTo(last) && statement is BreakStatementSyntax)
                        {
                            continue;
                        }
                        body = body.WithStatements(body.Statements.Add(statement));
                    }

                    //default => else
                    if (condition == null)
                    {
                        defaultElse = SyntaxFactory.ElseClause(body)
                                      .WithLeadingTrivia(section.GetLeadingTrivia())
                                      .WithTrailingTrivia(section.GetTrailingTrivia());
                        break;
                    }
                    ifNodes.Add(SyntaxFactory.IfStatement(condition, body).WithLeadingTrivia(section.GetLeadingTrivia()));
                }

                IfStatementSyntax ifStatement = null;
                //reverse the list and chain them
                foreach (IfStatementSyntax ifs in ifNodes.Reverse <IfStatementSyntax>())
                {
                    if (ifStatement == null)
                    {
                        ifStatement = ifs;
                        if (defaultElse != null)
                        {
                            ifStatement = ifStatement.WithElse(defaultElse);
                        }
                    }
                    else
                    {
                        ifStatement = ifs.WithElse(SyntaxFactory.ElseClause(ifStatement));
                    }
                }

                ifStatement = ifStatement.WithLeadingTrivia(node.GetLeadingTrivia().Concat(ifStatement.GetLeadingTrivia())).WithTrailingTrivia(node.GetTrailingTrivia());

                return(Task.FromResult(document.WithSyntaxRoot(root.ReplaceNode((SyntaxNode)node, ifStatement.WithAdditionalAnnotations(Formatter.Annotation)))));
            })
                );
        }