public static void ComputeRefactoring(RefactoringContext context, SelectedStatementsInfo info)
        {
            if (info.IsSingleSelected)
            {
                StatementSyntax[] statements = info.SelectedNodes().ToArray();

                StatementSyntax first = statements[0];

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

                    if (IfElseAnalysis.IsTopmostIf(ifStatement) &&
                        CanBeReplacedWithSwitch(ifStatement))
                    {
                        string title = (IfElseAnalysis.IsIsolatedIf(ifStatement))
                            ? "Replace if with switch"
                            : "Replace if-else with switch";

                        context.RegisterRefactoring(
                            title,
                            cancellationToken =>
                        {
                            return(RefactorAsync(
                                       context.Document,
                                       ifStatement,
                                       cancellationToken));
                        });
                    }
                }
            }
        }
示例#2
0
        private void AnalyzeStatement(SyntaxNodeAnalysisContext context)
        {
            if (GeneratedCodeAnalyzer?.IsGeneratedCode(context) == true)
            {
                return;
            }

            AnalyzeEmbeddedStatement(context);

            if (context.Node.IsKind(SyntaxKind.IfStatement) &&
                !IfElseAnalysis.IsIsolatedIf((IfStatementSyntax)context.Node))
            {
                return;
            }

            StatementSyntax statement = EmbeddedStatementAnalysis.GetEmbeddedStatementThatShouldBeInsideBlock(context.Node);

            if (statement != null)
            {
                context.ReportDiagnostic(
                    DiagnosticDescriptors.AddBraces,
                    statement.GetLocation(),
                    SyntaxHelper.GetNodeTitle(context.Node));
            }
        }
示例#3
0
            public override SyntaxNode VisitIfStatement(IfStatementSyntax node)
            {
                if (node == null)
                {
                    throw new ArgumentNullException(nameof(node));
                }

                if (_previousIf == null || _previousIf.Equals(IfElseAnalysis.GetPreviousIf(node)))
                {
                    if (node.Statement != null &&
                        !node.Statement.IsKind(SyntaxKind.Block))
                    {
                        IfStatementSyntax ifStatement = node.WithStatement(SyntaxFactory.Block(node.Statement));

                        _previousIf = ifStatement;

                        return(base.VisitIfStatement(ifStatement));
                    }
                    else
                    {
                        _previousIf = node;
                    }
                }

                return(base.VisitIfStatement(node));
            }
示例#4
0
        private void AnalyzeStatement(SyntaxNodeAnalysisContext context)
        {
            if (GeneratedCodeAnalyzer?.IsGeneratedCode(context) == true)
            {
                return;
            }

            if (!context.Node.IsKind(SyntaxKind.IfStatement) ||
                IfElseAnalysis.IsIsolatedIf((IfStatementSyntax)context.Node))
            {
                BlockSyntax block = EmbeddedStatementAnalysis.GetBlockThatCanBeEmbeddedStatement(context.Node);

                if (block != null &&
                    !block.OpenBraceToken.IsMissing &&
                    !block.CloseBraceToken.IsMissing &&
                    block.OpenBraceToken.LeadingTrivia.All(f => f.IsWhitespaceOrEndOfLineTrivia()) &&
                    block.OpenBraceToken.TrailingTrivia.All(f => f.IsWhitespaceOrEndOfLineTrivia()) &&
                    block.CloseBraceToken.LeadingTrivia.All(f => f.IsWhitespaceOrEndOfLineTrivia()) &&
                    block.CloseBraceToken.TrailingTrivia.All(f => f.IsWhitespaceOrEndOfLineTrivia()))
                {
                    context.ReportDiagnostic(
                        DiagnosticDescriptors.RemoveBraces,
                        block.GetLocation(),
                        SyntaxHelper.GetNodeTitle(context.Node));

                    context.FadeOutBraces(DiagnosticDescriptors.RemoveBracesFadeOut, block);
                }
            }
        }
示例#5
0
        private static bool CheckContainingNode(SyntaxNode node)
        {
            switch (node.Kind())
            {
            case SyntaxKind.ForEachStatement:
            case SyntaxKind.ForStatement:
            case SyntaxKind.UsingStatement:
            case SyntaxKind.WhileStatement:
            case SyntaxKind.DoStatement:
            case SyntaxKind.LockStatement:
            case SyntaxKind.FixedStatement:
            case SyntaxKind.UnsafeStatement:
            case SyntaxKind.TryStatement:
            case SyntaxKind.CheckedStatement:
            case SyntaxKind.UncheckedStatement:
                return(true);

            case SyntaxKind.IfStatement:
                return(IfElseAnalysis.IsTopmostIf((IfStatementSyntax)node));

            case SyntaxKind.ElseClause:
                return(IfElseAnalysis.IsEndOfChain((ElseClauseSyntax)node));
            }

            return(false);
        }
        private static IEnumerable <SwitchSectionSyntax> CreateSwitchSections(IfStatementSyntax ifStatement)
        {
            foreach (SyntaxNode node in IfElseAnalysis.GetChain(ifStatement))
            {
                if (node.IsKind(SyntaxKind.IfStatement))
                {
                    ifStatement = (IfStatementSyntax)node;

                    var condition = ifStatement.Condition as BinaryExpressionSyntax;

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

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

                    yield return(section);
                }
                else
                {
                    var elseClause = (ElseClauseSyntax)node;

                    yield return(DefaultSwitchSection(AddBreakStatementIfNecessary(elseClause.Statement)));
                }
            }
        }
示例#7
0
 private static SyntaxNode GetContainingBlock(SyntaxNode node)
 {
     if (node.IsKind(SyntaxKind.ElseClause))
     {
         return(IfElseAnalysis.GetTopmostIf((ElseClauseSyntax)node)?.Parent);
     }
     else
     {
         return(node.Parent);
     }
 }
示例#8
0
        internal IfElseAnalysisResult(IfStatementSyntax ifStatement)
        {
            if (ifStatement == null)
            {
                throw new ArgumentNullException(nameof(ifStatement));
            }

            bool anyHasEmbedded      = false;
            bool anyHasBlock         = false;
            bool allSupportsEmbedded = true;

            int cnt = 0;

            foreach (SyntaxNode node in IfElseAnalysis.GetChain(ifStatement))
            {
                cnt++;

                StatementSyntax statement = GetStatement(node);

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

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

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

                if (cnt > 1 && anyHasEmbedded && !allSupportsEmbedded)
                {
                    AddBraces = true;
                    return;
                }
            }

            if (cnt > 1 &&
                allSupportsEmbedded &&
                anyHasBlock)
            {
                RemoveBraces = true;

                if (anyHasEmbedded)
                {
                    AddBraces = true;
                }
            }
        }
示例#9
0
        public static bool CanRefactor(
            IfStatementSyntax ifStatement,
            SemanticModel semanticModel,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            if (IfElseAnalysis.IsTopmostIf(ifStatement))
            {
                ElseClauseSyntax elseClause = ifStatement.Else;

                if (elseClause != null)
                {
                    ExpressionSyntax condition = ifStatement.Condition;

                    if (condition != null)
                    {
                        ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(condition, cancellationToken);

                        if (typeSymbol?.IsBoolean() == true)
                        {
                            AssignmentExpressionSyntax trueExpression = GetSimpleAssignmentExpression(ifStatement.Statement);

                            ExpressionSyntax trueRight = trueExpression?.Right;

                            if (trueRight?.IsBooleanLiteralExpression() == true)
                            {
                                AssignmentExpressionSyntax falseExpression = GetSimpleAssignmentExpression(elseClause.Statement);

                                ExpressionSyntax falseRight = falseExpression?.Right;

                                if (falseRight?.IsBooleanLiteralExpression() == true)
                                {
                                    var trueBooleanLiteral  = (LiteralExpressionSyntax)trueRight;
                                    var falseBooleanLiteral = (LiteralExpressionSyntax)falseRight;

                                    if (trueBooleanLiteral.IsKind(SyntaxKind.TrueLiteralExpression) != falseBooleanLiteral.IsKind(SyntaxKind.TrueLiteralExpression) &&
                                        trueExpression.Left?.IsEquivalentTo(falseExpression.Left, topLevel: false) == true)
                                    {
                                        return(true);
                                    }
                                }
                            }
                        }
                    }
                }
            }

            return(false);
        }
        private static IfStatementSyntax GetTopmostIf(BlockSyntax block)
        {
            SyntaxNode parent = block.Parent;

            switch (parent?.Kind())
            {
            case SyntaxKind.IfStatement:
                return(IfElseAnalysis.GetTopmostIf((IfStatementSyntax)parent));

            case SyntaxKind.ElseClause:
                return(IfElseAnalysis.GetTopmostIf((ElseClauseSyntax)parent));

            default:
                return(null);
            }
        }
示例#11
0
        private static SyntaxNode GetNewRoot(StatementSyntax statement, SyntaxNode oldRoot, IEnumerable <StatementSyntax> newNodes)
        {
            if (statement.Parent.IsKind(SyntaxKind.ElseClause))
            {
                IfStatementSyntax ifStatement = IfElseAnalysis.GetTopmostIf((ElseClauseSyntax)statement.Parent);
                var block = (BlockSyntax)ifStatement.Parent;
                int index = block.Statements.IndexOf(ifStatement);

                BlockSyntax newBlock = block.RemoveNode(statement.Parent, SyntaxRemoveOptions.KeepNoTrivia);

                newBlock = newBlock.WithStatements(newBlock.Statements.InsertRange(index + 1, newNodes));

                return(oldRoot.ReplaceNode(block, newBlock));
            }
            else
            {
                return(oldRoot.ReplaceNode(statement.Parent, newNodes));
            }
        }
示例#12
0
        public static void Analyze(SyntaxNodeAnalysisContext context, IfStatementSyntax ifStatement)
        {
            if (IfElseAnalysis.IsIsolatedIf(ifStatement) &&
                ConditionAllowsMerging(ifStatement.Condition))
            {
                IfStatementSyntax nestedIf = GetNestedIfStatement(ifStatement);

                if (nestedIf != null &&
                    nestedIf.Else == null &&
                    ConditionAllowsMerging(nestedIf.Condition) &&
                    TriviaAllowsMerging(ifStatement, nestedIf))
                {
                    context.ReportDiagnostic(
                        DiagnosticDescriptors.MergeIfStatementWithNestedIfStatement,
                        ifStatement.GetLocation());

                    FadeOut(context, ifStatement, nestedIf);
                }
            }
        }
        private static bool CanBeReplacedWithSwitch(IfStatementSyntax ifStatement)
        {
            foreach (SyntaxNode node in IfElseAnalysis.GetChain(ifStatement))
            {
                if (node.IsKind(SyntaxKind.IfStatement))
                {
                    ifStatement = (IfStatementSyntax)node;

                    var condition = ifStatement.Condition as BinaryExpressionSyntax;

                    if (condition == null ||
                        !IsValidCondition(condition, null))
                    {
                        return(false);
                    }
                }
            }

            return(true);
        }
        public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            SyntaxNode root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false);

            IfStatementSyntax ifStatement = root
                                            .FindNode(context.Span, getInnermostNodeForTie: true)?
                                            .FirstAncestorOrSelf <IfStatementSyntax>();

            if (ifStatement == null)
            {
                return;
            }

            ifStatement = IfElseAnalysis.GetTopmostIf(ifStatement);

            CodeAction codeAction = CodeAction.Create(
                "Add braces to if-else",
                cancellationToken => AddBracesToIfElseRefactoring.RefactorAsync(context.Document, ifStatement, cancellationToken),
                DiagnosticIdentifiers.AddBracesToIfElse + EquivalenceKeySuffix);

            context.RegisterCodeFix(codeAction, context.Diagnostics);
        }
        private static IfStatementSyntax GetTopmostIf(StatementSyntax statement)
        {
            SyntaxNode parent = statement.Parent;

            if (parent != null)
            {
                if (parent.IsKind(SyntaxKind.ElseClause))
                {
                    return(IfElseAnalysis.GetTopmostIf((ElseClauseSyntax)parent));
                }
                else
                {
                    var parentStatement = parent as IfStatementSyntax;

                    if (parentStatement != null)
                    {
                        return(IfElseAnalysis.GetTopmostIf(parentStatement));
                    }
                }
            }

            return(null);
        }
        public static async Task ComputeRefactoringsAsync(RefactoringContext context, IfStatementSyntax ifStatement)
        {
            if (context.IsAnyRefactoringEnabled(
                    RefactoringIdentifiers.SwapStatementsInIfElse,
                    RefactoringIdentifiers.ReplaceIfElseWithConditionalExpression) &&
                IfElseAnalysis.IsTopmostIf(ifStatement) &&
                context.Span.IsBetweenSpans(ifStatement))
            {
                if (context.IsRefactoringEnabled(RefactoringIdentifiers.ReplaceIfElseWithConditionalExpression))
                {
                    ReplaceIfElseWithConditionalExpressionRefactoring.ComputeRefactoring(context, ifStatement);
                }

                if (context.IsRefactoringEnabled(RefactoringIdentifiers.SwapStatementsInIfElse) &&
                    SwapStatementInIfElseRefactoring.CanRefactor(ifStatement))
                {
                    context.RegisterRefactoring(
                        "Swap statements in if-else",
                        cancellationToken =>
                    {
                        return(SwapStatementInIfElseRefactoring.RefactorAsync(
                                   context.Document,
                                   ifStatement,
                                   cancellationToken));
                    });
                }
            }

            if (context.IsRefactoringEnabled(RefactoringIdentifiers.AddBooleanComparison) &&
                ifStatement.Condition != null &&
                ifStatement.Condition.Span.Contains(context.Span) &&
                context.SupportsSemanticModel)
            {
                await AddBooleanComparisonRefactoring.ComputeRefactoringAsync(context, ifStatement.Condition).ConfigureAwait(false);
            }
        }
        private static IEnumerable <StatementSyntax> GetEmbeddedStatements(IfStatementSyntax topmostIf)
        {
            foreach (SyntaxNode node in IfElseAnalysis.GetChain(topmostIf))
            {
                switch (node.Kind())
                {
                case SyntaxKind.IfStatement:
                {
                    var ifStatement = (IfStatementSyntax)node;

                    StatementSyntax statement = ifStatement.Statement;

                    if (statement?.IsKind(SyntaxKind.Block) == false)
                    {
                        yield return(statement);
                    }

                    break;
                }

                case SyntaxKind.ElseClause:
                {
                    var elseClause = (ElseClauseSyntax)node;

                    StatementSyntax statement = elseClause.Statement;

                    if (statement?.IsKind(SyntaxKind.Block) == false)
                    {
                        yield return(statement);
                    }

                    break;
                }
                }
            }
        }
示例#18
0
        private static StatementSyntax GetStatement(
            RefactoringContext context,
            BlockSyntax block,
            SyntaxNode parent)
        {
            switch (parent?.Kind())
            {
            case SyntaxKind.WhileStatement:
            case SyntaxKind.DoStatement:
            case SyntaxKind.ForStatement:
            case SyntaxKind.ForEachStatement:
            case SyntaxKind.FixedStatement:
            case SyntaxKind.CheckedStatement:
            case SyntaxKind.UncheckedStatement:
            case SyntaxKind.UnsafeStatement:
            case SyntaxKind.UsingStatement:
            case SyntaxKind.LockStatement:
            {
                if (block.OpenBraceToken.Span.Contains(context.Span) ||
                    block.CloseBraceToken.Span.Contains(context.Span))
                {
                    if (parent.IsKind(SyntaxKind.UsingStatement))
                    {
                        var usingStatement = (UsingStatementSyntax)parent;

                        while (usingStatement.Parent?.IsKind(SyntaxKind.UsingStatement) == true)
                        {
                            usingStatement = (UsingStatementSyntax)usingStatement.Parent;
                        }

                        return(usingStatement);
                    }

                    return((StatementSyntax)parent);
                }

                break;
            }

            case SyntaxKind.TryStatement:
            {
                var tryStatement = (TryStatementSyntax)parent;

                if (tryStatement.Block?.OpenBraceToken.Span.Contains(context.Span) == true)
                {
                    return((StatementSyntax)parent);
                }

                break;
            }

            case SyntaxKind.IfStatement:
            {
                var ifStatement = (IfStatementSyntax)parent;

                if (IfElseAnalysis.IsTopmostIf(ifStatement) &&
                    block.OpenBraceToken.Span.Contains(context.Span))
                {
                    return(ifStatement);
                }

                if (ifStatement.Else == null &&
                    block.CloseBraceToken.Span.Contains(context.Span))
                {
                    return(ifStatement);
                }

                break;
            }

            case SyntaxKind.ElseClause:
            {
                var elseClause = (ElseClauseSyntax)parent;

                if (block.CloseBraceToken.Span.Contains(context.Span))
                {
                    return(IfElseAnalysis.GetTopmostIf(elseClause));
                }

                break;
            }

            case SyntaxKind.CatchClause:
            {
                var catchClause = (CatchClauseSyntax)parent;

                if (catchClause.Parent?.IsKind(SyntaxKind.TryStatement) == true)
                {
                    var tryStatement = (TryStatementSyntax)catchClause.Parent;

                    if (tryStatement.Finally == null &&
                        catchClause.Block?.CloseBraceToken.Span.Contains(context.Span) == true)
                    {
                        return(tryStatement);
                    }
                }

                break;
            }

            case SyntaxKind.FinallyClause:
            {
                var finallyClause = (FinallyClauseSyntax)parent;

                if (finallyClause.Parent?.IsKind(SyntaxKind.TryStatement) == true)
                {
                    var tryStatement = (TryStatementSyntax)finallyClause.Parent;

                    if (finallyClause.Block?.CloseBraceToken.Span.Contains(context.Span) == true)
                    {
                        return(tryStatement);
                    }
                }

                break;
            }
            }

            return(null);
        }
        public static void ComputeRefactoring(RefactoringContext context, IfStatementSyntax ifStatement)
        {
            if (IfElseAnalysis.IsTopmostIf(ifStatement))
            {
                ElseClauseSyntax elseClause = ifStatement.Else;

                if (elseClause != null)
                {
                    StatementSyntax statement2 = elseClause.Statement;

                    if (statement2?.IsKind(SyntaxKind.IfStatement) == false)
                    {
                        StatementSyntax statement1 = GetStatementOrDefault(ifStatement.Statement);

                        if (statement1 != null)
                        {
                            statement2 = GetStatementOrDefault(statement2);

                            if (statement2 != null)
                            {
                                SyntaxKind kind1 = statement1.Kind();
                                SyntaxKind kind2 = statement2.Kind();

                                if (kind1 == SyntaxKind.ReturnStatement)
                                {
                                    if (kind2 == SyntaxKind.ReturnStatement)
                                    {
                                        ComputeRefactoring(
                                            context,
                                            ifStatement,
                                            (ReturnStatementSyntax)statement1,
                                            (ReturnStatementSyntax)statement2);
                                    }
                                }
                                else if (kind1 == SyntaxKind.YieldReturnStatement)
                                {
                                    if (kind2 == SyntaxKind.YieldReturnStatement)
                                    {
                                        ComputeRefactoring(
                                            context,
                                            ifStatement,
                                            (YieldStatementSyntax)statement1,
                                            (YieldStatementSyntax)statement2);
                                    }
                                }
                                else if (kind1 == SyntaxKind.ExpressionStatement)
                                {
                                    if (kind2 == SyntaxKind.ExpressionStatement)
                                    {
                                        ComputeRefactoring(
                                            context,
                                            ifStatement,
                                            (ExpressionStatementSyntax)statement1,
                                            (ExpressionStatementSyntax)statement2);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }