private static bool IsFixable(IfStatementSyntax ifStatement)
 {
     return(ifStatement.IsSimpleIf() &&
            ifStatement.Condition?.IsMissing == false &&
            ifStatement.Statement?.IsKind(SyntaxKind.Block) == true &&
            ifStatement.IsParentKind(SyntaxKind.Block));
 }
        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);
        }
Beispiel #3
0
        internal static SimpleIfStatementInfo Create(
            IfStatementSyntax ifStatement,
            bool walkDownParentheses = true,
            bool allowMissing        = false)
        {
            if (ifStatement?.IsSimpleIf() != true)
            {
                return(Default);
            }

            ExpressionSyntax condition = WalkAndCheck(ifStatement.Condition, allowMissing, walkDownParentheses);

            if (condition == null)
            {
                return(Default);
            }

            StatementSyntax statement = ifStatement.Statement;

            if (!Check(statement, allowMissing))
            {
                return(Default);
            }

            return(new SimpleIfStatementInfo(ifStatement, condition, statement));
        }
        private static bool TryCreateCore(IfStatementSyntax ifStatement, out SimpleIfStatementWithSingleStatement result)
        {
            if (ifStatement.IsSimpleIf())
            {
                StatementSyntax statement = ifStatement.Statement;

                if (statement != null)
                {
                    if (statement.IsKind(SyntaxKind.Block))
                    {
                        StatementSyntax singleStatement = ((BlockSyntax)statement).Statements.SingleOrDefault(throwException: false);

                        if (singleStatement != null)
                        {
                            result = new SimpleIfStatementWithSingleStatement(ifStatement.Condition, statement, singleStatement);
                            return(true);
                        }
                    }
                    else
                    {
                        result = new SimpleIfStatementWithSingleStatement(ifStatement.Condition, statement, statement);
                        return(true);
                    }
                }
            }

            result = default(SimpleIfStatementWithSingleStatement);
            return(false);
        }
        public static SimpleIfStatementWithSingleStatement Create(IfStatementSyntax ifStatement)
        {
            if (ifStatement == null)
            {
                throw new ArgumentNullException(nameof(ifStatement));
            }

            if (!ifStatement.IsSimpleIf())
            {
                throw new ArgumentException("", nameof(ifStatement));
            }

            StatementSyntax statement = ifStatement.Statement;

            if (statement == null)
            {
                throw new ArgumentException("", nameof(ifStatement));
            }

            if (statement.IsKind(SyntaxKind.Block))
            {
                StatementSyntax singleStatement = ((BlockSyntax)statement).Statements.SingleOrDefault(throwException: false);

                if (singleStatement == null)
                {
                    throw new ArgumentException("", nameof(ifStatement));
                }

                return(new SimpleIfStatementWithSingleStatement(ifStatement.Condition, statement, singleStatement));
            }
            else
            {
                return(new SimpleIfStatementWithSingleStatement(ifStatement.Condition, statement, statement));
            }
        }
        internal static bool IsFixable(IfStatementSyntax ifStatement)
        {
            if (ifStatement == null)
            {
                return(false);
            }

            if (!ifStatement.IsSimpleIf())
            {
                return(false);
            }

            if (ifStatement.Condition?.IsMissing != false)
            {
                return(false);
            }

            if (!(ifStatement.Statement is BlockSyntax block))
            {
                return(false);
            }

            SyntaxList <StatementSyntax> statements = block.Statements;

            if (!statements.Any())
            {
                return(false);
            }

            return(statements.Count > 1 ||
                   GetJumpKind(statements[0]) == SyntaxKind.None);
        }
Beispiel #7
0
 internal static SimpleIfStatementInfo Create(
     IfStatementSyntax ifStatement,
     bool walkDownParentheses = true,
     bool allowMissing        = false)
 {
     if (ifStatement?.IsSimpleIf() != true)
     {
         return(default);
 private static bool IsFixable(IfStatementSyntax ifStatement)
 {
     return(ifStatement.IsSimpleIf() &&
            ifStatement.Condition?.IsMissing == false &&
            ifStatement.IsParentKind(SyntaxKind.Block) &&
            (ifStatement.Statement is BlockSyntax block) &&
            block.Statements.Any());
 }
Beispiel #9
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));
            }
        }
Beispiel #10
0
 public static IfToReturnWithBooleanExpressionAnalysis Create(IfStatementSyntax ifStatement, ExpressionSyntax expression1, ExpressionSyntax expression2, SemanticModel semanticModel, bool isYield)
 {
     if (isYield)
     {
         return(new IfElseToYieldReturnWithBooleanExpressionAnalysis(ifStatement, expression1, expression2, semanticModel));
     }
     else if (ifStatement.IsSimpleIf())
     {
         return(new IfReturnToReturnWithBooleanExpressionAnalysis(ifStatement, expression1, expression2, semanticModel));
     }
     else
     {
         return(new IfElseToReturnWithBooleanExpressionAnalysis(ifStatement, expression1, expression2, semanticModel));
     }
 }
Beispiel #11
0
 public static IfToReturnWithBooleanExpression Create(IfStatementSyntax ifStatement, ExpressionSyntax expression1, ExpressionSyntax expression2, bool isYield)
 {
     if (isYield)
     {
         return(new IfElseToYieldReturnWithBooleanExpression(ifStatement, expression1, expression2));
     }
     else if (ifStatement.IsSimpleIf())
     {
         return(new IfReturnToReturnWithBooleanExpression(ifStatement, expression1, expression2));
     }
     else
     {
         return(new IfElseToReturnWithBooleanExpression(ifStatement, expression1, expression2));
     }
 }
Beispiel #12
0
        public static void Analyze(SyntaxNodeAnalysisContext context, IfStatementSyntax ifStatement)
        {
            if (ifStatement.IsSimpleIf() &&
                CheckCondition(ifStatement.Condition))
            {
                IfStatementSyntax nestedIf = GetNestedIfStatement(ifStatement);

                if (nestedIf != null &&
                    nestedIf.Else == null &&
                    CheckCondition(nestedIf.Condition) &&
                    CheckTrivia(ifStatement, nestedIf) &&
                    !ifStatement.SpanContainsDirectives())
                {
                    ReportDiagnostic(context, ifStatement, nestedIf);
                }
            }
        }
        internal static void ComputeRefactoring(RefactoringContext context, IfStatementSyntax ifStatement)
        {
            if (ifStatement.IsSimpleIf())
            {
                StatementSyntax statement = ifStatement.Statement;

                if (statement?.IsMissing == false)
                {
                    ExpressionSyntax condition = ifStatement.Condition;

                    if (condition?.Kind() == SyntaxKind.LogicalOrExpression)
                    {
                        context.RegisterRefactoring(
                            "Split if",
                            cancellationToken => RefactorAsync(context.Document, ifStatement, cancellationToken));
                    }
                }
            }
        }
        public static async Task ComputeRefactoringAsync(RefactoringContext context, IfStatementSyntax ifStatement)
        {
            if (IfElseChain.IsTopmostIf(ifStatement))
            {
                SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                if (GetIfStatements(ifStatement)
                    .All(f => IsValidIf(f, semanticModel, context.CancellationToken)))
                {
                    string title = (ifStatement.IsSimpleIf())
                        ? "Replace if with switch"
                        : "Replace if-else with switch";

                    context.RegisterRefactoring(
                        title,
                        cancellationToken => RefactorAsync(context.Document, ifStatement, cancellationToken));
                }
            }
        }
Beispiel #15
0
        private static ImmutableArray <IfRefactoring> Analyze(
            IfStatementSyntax ifStatement,
            ExpressionSyntax condition,
            ExpressionSyntax expression1,
            ExpressionSyntax expression2,
            IfAnalysisOptions options,
            bool isYield,
            SemanticModel semanticModel,
            CancellationToken cancellationToken)
        {
            if (expression1?.IsMissing != false)
            {
                return(Empty);
            }

            if (expression2?.IsMissing != false)
            {
                return(Empty);
            }

            if (options.UseCoalesceExpression ||
                options.UseExpression)
            {
                SyntaxKind kind1 = expression1.Kind();
                SyntaxKind kind2 = expression2.Kind();

                if (kind1.IsBooleanLiteralExpression() &&
                    kind2.IsBooleanLiteralExpression() &&
                    kind1 != kind2)
                {
                    if (options.UseExpression)
                    {
                        if (ifStatement.IsSimpleIf() &&
                            (ifStatement.PreviousStatementOrDefault() is IfStatementSyntax previousIf) &&
                            previousIf.IsSimpleIf() &&
                            (previousIf.GetSingleStatementOrDefault() is ReturnStatementSyntax returnStatement) &&
                            returnStatement.Expression?.WalkDownParentheses().Kind() == kind1)
                        {
                            return(Empty);
                        }

                        return(new IfToReturnWithExpression(ifStatement, condition, isYield, negate: kind1 == SyntaxKind.FalseLiteralExpression).ToImmutableArray());
                    }

                    return(Empty);
                }

                NullCheckExpressionInfo nullCheck = SyntaxInfo.NullCheckExpressionInfo(condition, semanticModel: semanticModel, cancellationToken: cancellationToken);

                if (nullCheck.Success)
                {
                    IfRefactoring refactoring = CreateIfToReturnStatement(
                        ifStatement,
                        (nullCheck.IsCheckingNull) ? expression2 : expression1,
                        (nullCheck.IsCheckingNull) ? expression1 : expression2,
                        nullCheck,
                        options,
                        isYield,
                        semanticModel,
                        cancellationToken);

                    if (refactoring != null)
                    {
                        return(refactoring.ToImmutableArray());
                    }
                }
            }

            IfToReturnWithBooleanExpression ifToReturnWithBooleanExpression = null;

            if (options.UseBooleanExpression &&
                (expression1.Kind().IsBooleanLiteralExpression() || expression2.Kind().IsBooleanLiteralExpression()) &&
                semanticModel.GetTypeSymbol(expression1, cancellationToken)?.IsBoolean() == true &&
                semanticModel.GetTypeSymbol(expression2, cancellationToken)?.IsBoolean() == true)
            {
                ifToReturnWithBooleanExpression = IfToReturnWithBooleanExpression.Create(ifStatement, expression1, expression2, isYield);
            }

            IfToReturnWithConditionalExpression ifToReturnWithConditionalExpression = null;

            if (options.UseConditionalExpression &&
                (!expression1.Kind().IsBooleanLiteralExpression() || !expression2.Kind().IsBooleanLiteralExpression()))
            {
                ifToReturnWithConditionalExpression = IfToReturnWithConditionalExpression.Create(ifStatement, expression1, expression2, isYield);
            }

            return(ToImmutableArray(ifToReturnWithBooleanExpression, ifToReturnWithConditionalExpression));
        }
Beispiel #16
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);
            }
        }
Beispiel #17
0
        private static ImmutableArray <IfAnalysis> Analyze(
            IfStatementSyntax ifStatement,
            ExpressionSyntax condition,
            ExpressionSyntax expression1,
            ExpressionSyntax expression2,
            IfAnalysisOptions options,
            bool isYield,
            SemanticModel semanticModel,
            CancellationToken cancellationToken)
        {
            if (expression1?.IsMissing != false)
            {
                return(Empty);
            }

            if (expression2?.IsMissing != false)
            {
                return(Empty);
            }

            if (options.UseCoalesceExpression ||
                options.UseExpression)
            {
                SyntaxKind kind1 = expression1.Kind();
                SyntaxKind kind2 = expression2.Kind();

                if (IsBooleanLiteralExpression(kind1) &&
                    IsBooleanLiteralExpression(kind2) &&
                    kind1 != kind2)
                {
                    if (options.UseExpression)
                    {
                        if (ifStatement.IsSimpleIf() &&
                            (ifStatement.PreviousStatement() is IfStatementSyntax previousIf) &&
                            previousIf.IsSimpleIf() &&
                            (previousIf.SingleNonBlockStatementOrDefault() is ReturnStatementSyntax returnStatement) &&
                            returnStatement.Expression?.WalkDownParentheses().Kind() == kind1)
                        {
                            return(Empty);
                        }

                        return(new IfToReturnWithExpressionAnalysis(ifStatement, condition, isYield, invert: kind1 == SyntaxKind.FalseLiteralExpression, semanticModel: semanticModel).ToImmutableArray());
                    }

                    return(Empty);
                }

                NullCheckExpressionInfo nullCheck = SyntaxInfo.NullCheckExpressionInfo(condition, semanticModel: semanticModel, cancellationToken: cancellationToken);

                if (nullCheck.Success)
                {
                    IfAnalysis refactoring = CreateIfToReturnStatement(
                        ifStatement,
                        (nullCheck.IsCheckingNull) ? expression2 : expression1,
                        (nullCheck.IsCheckingNull) ? expression1 : expression2,
                        nullCheck,
                        options,
                        isYield,
                        semanticModel,
                        cancellationToken);

                    if (refactoring != null)
                    {
                        return(refactoring.ToImmutableArray());
                    }
                }
            }

            IfToReturnWithBooleanExpressionAnalysis ifToReturnWithBooleanExpression = null;

            if (options.UseBooleanExpression &&
                (IsBooleanLiteralExpression(expression1.Kind()) || IsBooleanLiteralExpression(expression2.Kind())) &&
                semanticModel.GetTypeSymbol(expression1, cancellationToken)?.SpecialType == SpecialType.System_Boolean &&
                semanticModel.GetTypeSymbol(expression2, cancellationToken)?.SpecialType == SpecialType.System_Boolean)
            {
                ifToReturnWithBooleanExpression = IfToReturnWithBooleanExpressionAnalysis.Create(ifStatement, expression1, expression2, semanticModel, isYield);
            }

            IfToReturnWithConditionalExpressionAnalysis ifToReturnWithConditionalExpression = null;

            if (options.UseConditionalExpression &&
                (!IsBooleanLiteralExpression(expression1.Kind()) || !IsBooleanLiteralExpression(expression2.Kind())) &&
                !IsNullLiteralConvertedToNullableOfT(expression1, semanticModel, cancellationToken) &&
                !IsNullLiteralConvertedToNullableOfT(expression2, semanticModel, cancellationToken))
            {
                ifToReturnWithConditionalExpression = IfToReturnWithConditionalExpressionAnalysis.Create(ifStatement, expression1, expression2, semanticModel, isYield);
            }

            return(ToImmutableArray(ifToReturnWithBooleanExpression, ifToReturnWithConditionalExpression));
        }