Beispiel #1
0
        private static Task <Document> RefactorAsync(
            Document document,
            IfStatementSyntax ifStatement,
            StatementListSelection selectedStatements,
            CancellationToken cancellationToken)
        {
            int count = selectedStatements.Count;

            StatementSyntax newStatement;

            if (count == 1 &&
                !ifStatement.AsCascade().Any(f => f.Statement?.Kind() == SyntaxKind.Block))
            {
                newStatement = selectedStatements.First();
            }
            else
            {
                newStatement = SyntaxFactory.Block(selectedStatements);
            }

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

            IfStatementSyntax lastIfStatement = ifStatement.AsCascade().Last();

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

            SyntaxList <StatementSyntax> newStatements = selectedStatements
                                                         .UnderlyingList
                                                         .Replace(ifStatement, newIfStatement)
                                                         .RemoveRange(selectedStatements.FirstIndex, count);

            return(document.ReplaceStatementsAsync(SyntaxInfo.StatementListInfo(selectedStatements), newStatements, cancellationToken));
        }
        private static IfStatementSyntax CreateNewIfStatement(IfStatementSyntax ifStatement)
        {
            IEnumerable <StatementSyntax> statements = ifStatement
                                                       .AsCascade()
                                                       .Select(ifOrElse =>
            {
                StatementSyntax statement = ifOrElse.Statement;

                if (statement is BlockSyntax block)
                {
                    statement = block.Statements.Last();
                }

                return(statement);
            });

            return(ifStatement.ReplaceNodes(
                       statements,
                       (statement, _) =>
            {
                if (statement.IsKind(SyntaxKind.ThrowStatement))
                {
                    return statement;
                }

                var expressionStatement = (ExpressionStatementSyntax)statement;

                var assignment = (AssignmentExpressionSyntax)expressionStatement.Expression;

                return ReturnStatement(assignment.Right).WithTriviaFrom(statement);
            }));
        }
        private static HashSet <AwaitExpressionSyntax> GetAwaitExpressionsFromIfStatement(
            IfStatementSyntax ifStatement,
            bool endsWithElse)
        {
            HashSet <AwaitExpressionSyntax> awaitExpressions = null;

            foreach (IfStatementOrElseClause ifOrElse in ifStatement.AsCascade())
            {
                if (ifOrElse.IsElse &&
                    !endsWithElse)
                {
                    return(null);
                }

                AwaitExpressionSyntax awaitExpression = GetLastReturnAwaitExpressionOfDefault(ifOrElse.Statement);

                if (awaitExpression != null)
                {
                    (awaitExpressions ?? (awaitExpressions = new HashSet <AwaitExpressionSyntax>())).Add(awaitExpression);
                }
                else
                {
                    return(null);
                }
            }

            return(awaitExpressions);
        }
        private static IEnumerable <SwitchSectionSyntax> CreateSwitchSections(IfStatementSyntax ifStatement)
        {
            foreach (IfStatementOrElseClause ifOrElse in ifStatement.AsCascade())
            {
                if (ifOrElse.IsIf)
                {
                    ifStatement = ifOrElse.AsIf();

                    var condition = ifStatement.Condition.WalkDownParentheses() as BinaryExpressionSyntax;

                    List <SwitchLabelSyntax> labels = CreateSwitchLabels(condition, new List <SwitchLabelSyntax>());
                    labels.Reverse();

                    SwitchSectionSyntax section = SwitchSection(
                        List(labels),
                        AddBreakStatementIfNecessary(ifStatement.Statement));

                    yield return(section);
                }
                else
                {
                    yield return(DefaultSwitchSection(AddBreakStatementIfNecessary(ifOrElse.Statement)));
                }
            }
        }
        public static async Task ComputeRefactoringAsync(RefactoringContext context, IfStatementSyntax ifStatement)
        {
            if (!ifStatement.IsTopmostIf())
            {
                return;
            }

            SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

            foreach (IfStatementOrElseClause ifOrElse in ifStatement.AsCascade())
            {
                if (ifOrElse.IsIf)
                {
                    if (!CanRefactor(ifOrElse.AsIf(), semanticModel, context.CancellationToken))
                    {
                        return;
                    }
                }
                else if (ContainsBreakStatementThatBelongsToParentLoop(ifOrElse.AsElse().Statement))
                {
                    return;
                }
            }

            context.RegisterRefactoring(
                (ifStatement.IsSimpleIf()) ? "Replace if with switch" : "Replace if-else with switch",
                cancellationToken => RefactorAsync(context.Document, ifStatement, cancellationToken),
                RefactoringIdentifiers.ReplaceIfWithSwitch);
        }
        private static bool VerifyIfStatement(
            IfStatementSyntax ifStatement,
            int expectedCount,
            bool endsWithElse)
        {
            int count = 0;

            foreach (IfStatementOrElseClause ifOrElse in ifStatement.AsCascade())
            {
                if (ifOrElse.IsElse &&
                    !endsWithElse)
                {
                    return(false);
                }

                AwaitExpressionSyntax awaitExpression = GetAwaitExpression(ifOrElse.Statement);

                if (awaitExpression == null)
                {
                    return(false);
                }

                count++;
            }

            return(expectedCount == count);
        }
Beispiel #7
0
        public static BracesAnalysis AnalyzeBraces(IfStatementSyntax ifStatement)
        {
            var anyHasEmbedded      = false;
            var anyHasBlock         = false;
            var allSupportsEmbedded = true;

            int cnt = 0;

            foreach (IfStatementOrElseClause ifOrElse in ifStatement.AsCascade())
            {
                cnt++;

                StatementSyntax statement = ifOrElse.Statement;

                if (!anyHasEmbedded &&
                    statement.Kind() != SyntaxKind.Block)
                {
                    anyHasEmbedded = true;
                }

                if (!anyHasBlock &&
                    statement.Kind() == SyntaxKind.Block)
                {
                    anyHasBlock = true;
                }

                if (allSupportsEmbedded &&
                    !SupportsEmbedded(statement))
                {
                    allSupportsEmbedded = false;
                }

                if (cnt > 1 &&
                    anyHasEmbedded &&
                    !allSupportsEmbedded)
                {
                    return(BracesAnalysisFlags.AddBraces);
                }
            }

            if (cnt > 1 &&
                allSupportsEmbedded &&
                anyHasBlock)
            {
                if (anyHasEmbedded)
                {
                    return(BracesAnalysisFlags.AddBraces | BracesAnalysisFlags.RemoveBraces);
                }
                else
                {
                    return(BracesAnalysisFlags.RemoveBraces);
                }
            }

            return(BracesAnalysisFlags.None);
        private static Task <Document> RefactorAsync(
            Document document,
            IfStatementSyntax ifStatement,
            CancellationToken cancellationToken)
        {
            return(document.ReplaceNodeAsync(ifStatement, GetNewStatements(), cancellationToken));

            IEnumerable <StatementSyntax> GetNewStatements()
            {
                ElseClauseSyntax parentElse = null;

                foreach (IfStatementOrElseClause ifOrElse in ifStatement.AsCascade())
                {
                    if (ifOrElse.IsIf)
                    {
                        IfStatementSyntax newIfStatement = ifOrElse.AsIf();

                        ElseClauseSyntax elseClause = newIfStatement.Else;

                        newIfStatement = newIfStatement.WithElse(null);

                        if (parentElse != null)
                        {
                            newIfStatement = newIfStatement.PrependToLeadingTrivia(parentElse.GetLeadingTrivia());
                        }

                        if (elseClause != null)
                        {
                            newIfStatement = newIfStatement.AppendToTrailingTrivia(CSharpFactory.NewLine());
                        }

                        yield return(newIfStatement.WithFormatterAnnotation());

                        parentElse = ifStatement.Else;
                    }
                    else
                    {
                        StatementSyntax statement = ifOrElse.Statement;

                        if (statement is BlockSyntax block)
                        {
                            foreach (StatementSyntax newStatement in block.Statements.Select(f => f.WithFormatterAnnotation()))
                            {
                                yield return(newStatement);
                            }
                        }
                        else
                        {
                            yield return(statement);
                        }
                    }
                }
            }
        }
        private static IEnumerable <BlockSyntax> GetBlockStatements(IfStatementSyntax ifStatement)
        {
            foreach (IfStatementOrElseClause ifOrElse in ifStatement.AsCascade())
            {
                StatementSyntax statement = ifOrElse.Statement;

                if (statement?.Kind() == SyntaxKind.Block)
                {
                    yield return((BlockSyntax)statement);
                }
            }
        }
        private static IEnumerable <StatementSyntax> GetEmbeddedStatements(IfStatementSyntax topmostIf)
        {
            foreach (IfStatementOrElseClause ifOrElse in topmostIf.AsCascade())
            {
                StatementSyntax statement = ifOrElse.Statement;

                if (statement?.IsKind(SyntaxKind.Block) == false)
                {
                    yield return(statement);
                }
            }
        }
Beispiel #11
0
        /// <summary>
        /// Initializes a new instance of <see cref="IfStatementCascadeInfo"/>.
        /// </summary>
        /// <param name="ifStatement"></param>
        public IfStatementCascadeInfo(IfStatementSyntax ifStatement)
        {
            int count = 0;
            IfStatementOrElseClause last = default;

            foreach (IfStatementOrElseClause ifOrElse in ifStatement.AsCascade())
            {
                count++;
                last = ifOrElse;
            }

            IfStatement = ifStatement;
            Count       = count;
            Last        = last;
        }
        private static IfStatementSyntax CreateNewIfStatement(IfStatementSyntax ifStatement)
        {
            IEnumerable <ExpressionStatementSyntax> expressionStatements = ifStatement
                                                                           .AsCascade()
                                                                           .Select(ifOrElse => (ExpressionStatementSyntax)GetLastStatementOrDefault(ifOrElse.Statement));

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

                return ReturnStatement(assignment.Right).WithTriviaFrom(f);
            }));
        }
        public static void ComputeRefactoring(
            RefactoringContext context,
            IfStatementSyntax ifStatement,
            SemanticModel semanticModel)
        {
            if (!ifStatement.IsTopmostIf())
            {
                return;
            }

            ExpressionSyntax switchExpression = null;

            foreach (IfStatementOrElseClause ifOrElse in ifStatement.AsCascade())
            {
                if (ifOrElse.IsIf)
                {
                    IfStatementSyntax ifStatement2 = ifOrElse.AsIf();

                    (bool success, ExpressionSyntax switchExpression)result = Analyze(ifStatement2.Condition?.WalkDownParentheses(), switchExpression, semanticModel, context.CancellationToken);

                    if (!result.success)
                    {
                        return;
                    }

                    switchExpression = result.switchExpression;

                    if (ContainsBreakStatementThatBelongsToParentIterationStatement(ifStatement2.Statement))
                    {
                        return;
                    }
                }
                else if (ContainsBreakStatementThatBelongsToParentIterationStatement(ifOrElse.AsElse().Statement))
                {
                    return;
                }
            }

            Document document = context.Document;

            context.RegisterRefactoring(
                "Convert to 'switch'",
                ct => RefactorAsync(document, ifStatement, ct),
                RefactoringIdentifiers.ConvertIfToSwitch);
        }
        public static void ComputeRefactoring(RefactoringContext context, IfStatementSyntax ifStatement)
        {
            if (ifStatement.IsParentKind(SyntaxKind.ElseClause))
            {
                return;
            }

            if (ifStatement.Else == null)
            {
                return;
            }

            foreach (IfStatementOrElseClause ifOrElse in ifStatement.AsCascade())
            {
                StatementSyntax statement = ifOrElse.Statement;

                if (statement is BlockSyntax block)
                {
                    statement = block.Statements.LastOrDefault();
                }

                if (statement == null)
                {
                    return;
                }

                if (!statement.IsKind(
                        SyntaxKind.ReturnStatement,
                        SyntaxKind.ContinueStatement,
                        SyntaxKind.BreakStatement,
                        SyntaxKind.ThrowStatement))
                {
                    return;
                }
            }

            context.RegisterRefactoring(
                "Split if-else",
                cancellationToken => RefactorAsync(context.Document, ifStatement, cancellationToken),
                RefactoringIdentifiers.SplitIfElse);
        }
Beispiel #15
0
        public static BracesAnalysis AnalyzeBraces(IfStatementSyntax ifStatement)
        {
            bool anyHasEmbedded      = false;
            bool anyHasBlock         = false;
            bool allSupportsEmbedded = true;

            int cnt = 0;

            foreach (IfStatementOrElseClause ifOrElse in ifStatement.AsCascade())
            {
                cnt++;

                StatementSyntax statement = ifOrElse.Statement;

                if (!anyHasEmbedded &&
                    statement.Kind() != SyntaxKind.Block)
                {
                    anyHasEmbedded = true;
                }

                if (!anyHasBlock &&
                    statement.Kind() == SyntaxKind.Block)
                {
                    anyHasBlock = true;
                }

                if (allSupportsEmbedded &&
                    !SupportsEmbedded(statement))
                {
                    allSupportsEmbedded = false;
                }

                if (cnt > 1 &&
                    anyHasEmbedded &&
                    !allSupportsEmbedded)
                {
                    return(BracesAnalysisFlags.AddBraces);
                }
            }

            if (cnt > 1 &&
                allSupportsEmbedded &&
                anyHasBlock)
            {
                if (anyHasEmbedded)
                {
                    return(BracesAnalysisFlags.AddBraces | BracesAnalysisFlags.RemoveBraces);
                }
                else
                {
                    return(BracesAnalysisFlags.RemoveBraces);
                }
            }

            return(BracesAnalysisFlags.None);

            bool SupportsEmbedded(StatementSyntax statement)
            {
                if (statement.IsParentKind(SyntaxKind.IfStatement) &&
                    ((IfStatementSyntax)statement.Parent).Condition?.IsMultiLine() == true)
                {
                    return(false);
                }

                if (statement.Kind() == SyntaxKind.Block)
                {
                    var block = (BlockSyntax)statement;

                    if (!block.OpenBraceToken.TrailingTrivia.IsEmptyOrWhitespace())
                    {
                        return(false);
                    }

                    if (!block.CloseBraceToken.LeadingTrivia.IsEmptyOrWhitespace())
                    {
                        return(false);
                    }

                    statement = block.Statements.SingleOrDefault(shouldThrow: false);

                    if (statement == null)
                    {
                        return(false);
                    }

                    if (statement.Kind() == SyntaxKind.IfStatement &&
                        block.IsParentKind(SyntaxKind.IfStatement) &&
                        ((IfStatementSyntax)block.Parent).Else != null &&
                        ((IfStatementSyntax)statement).GetCascadeInfo().EndsWithIf)
                    {
                        return(false);
                    }
                }

                return(!statement.IsKind(SyntaxKind.LocalDeclarationStatement, SyntaxKind.LabeledStatement) &&
                       statement.IsSingleLine());
            }
        }