コード例 #1
0
        private static void AnalyzeConditionalExpression(SyntaxNodeAnalysisContext context)
        {
            var conditionalExpression = (ConditionalExpressionSyntax)context.Node;

            if (context.Node.ContainsDiagnostics)
            {
                return;
            }

            if (context.Node.SpanContainsDirectives())
            {
                return;
            }

            ConditionalExpressionInfo info = SyntaxInfo.ConditionalExpressionInfo(conditionalExpression);

            if (!info.Success)
            {
                return;
            }

            SyntaxKind trueKind = info.WhenTrue.Kind();

            if (trueKind == SyntaxKind.TrueLiteralExpression)
            {
                if (context.SemanticModel.GetTypeInfo(info.WhenFalse, context.CancellationToken).ConvertedType?.SpecialType == SpecialType.System_Boolean)
                {
                    DiagnosticHelpers.ReportDiagnostic(context, DiagnosticDescriptors.SimplifyConditionalExpression, conditionalExpression);
                }
            }
            else
            {
                SyntaxKind falseKind = info.WhenFalse.Kind();

                if (falseKind == SyntaxKind.FalseLiteralExpression)
                {
                    if (context.SemanticModel.GetTypeInfo(info.WhenTrue, context.CancellationToken).ConvertedType?.SpecialType == SpecialType.System_Boolean)
                    {
                        DiagnosticHelpers.ReportDiagnostic(context, DiagnosticDescriptors.SimplifyConditionalExpression, conditionalExpression);
                    }
                }
                else if (trueKind == SyntaxKind.FalseLiteralExpression &&
                         falseKind == SyntaxKind.TrueLiteralExpression)
                {
                    DiagnosticHelpers.ReportDiagnostic(context, DiagnosticDescriptors.SimplifyConditionalExpression, conditionalExpression);
                }
            }
        }
コード例 #2
0
        public static void AnalyzeConditionalExpression(SyntaxNodeAnalysisContext context)
        {
            var conditionalExpression = (ConditionalExpressionSyntax)context.Node;

            if (context.Node.ContainsDiagnostics)
            {
                return;
            }

            if (context.Node.SpanContainsDirectives())
            {
                return;
            }

            ConditionalExpressionInfo info = SyntaxInfo.ConditionalExpressionInfo(conditionalExpression);

            if (!info.Success)
            {
                return;
            }

            switch (info.WhenTrue.Kind())
            {
            case SyntaxKind.TrueLiteralExpression:
            {
                if (info.WhenFalse.Kind() == SyntaxKind.FalseLiteralExpression)
                {
                    context.ReportDiagnostic(DiagnosticDescriptors.SimplifyConditionalExpression, conditionalExpression);
                }

                break;
            }

            case SyntaxKind.FalseLiteralExpression:
            {
                if (info.WhenFalse.Kind() == SyntaxKind.TrueLiteralExpression)
                {
                    context.ReportDiagnostic(DiagnosticDescriptors.SimplifyConditionalExpression, conditionalExpression);
                }

                break;
            }
            }
        }
コード例 #3
0
        public static void AnalyzeConditionalExpression(SyntaxNodeAnalysisContext context)
        {
            var conditionalExpression = (ConditionalExpressionSyntax)context.Node;

            if (context.Node.ContainsDiagnostics)
            {
                return;
            }

            if (context.Node.SpanContainsDirectives())
            {
                return;
            }

            ConditionalExpressionInfo info = SyntaxInfo.ConditionalExpressionInfo(conditionalExpression);

            if (!info.Success)
            {
                return;
            }

            SyntaxKind trueKind = info.WhenTrue.Kind();

            if (trueKind == SyntaxKind.TrueLiteralExpression)
            {
                context.ReportDiagnostic(DiagnosticDescriptors.SimplifyConditionalExpression, conditionalExpression);
            }
            else
            {
                SyntaxKind falseKind = info.WhenFalse.Kind();

                if (falseKind == SyntaxKind.FalseLiteralExpression)
                {
                    context.ReportDiagnostic(DiagnosticDescriptors.SimplifyConditionalExpression, conditionalExpression);
                }
                else if (trueKind == SyntaxKind.FalseLiteralExpression &&
                         falseKind == SyntaxKind.TrueLiteralExpression)
                {
                    context.ReportDiagnostic(DiagnosticDescriptors.SimplifyConditionalExpression, conditionalExpression);
                }
            }
        }
コード例 #4
0
        private static void AnalyzeConditionalExpression(SyntaxNodeAnalysisContext context)
        {
            var conditionalExpression = (ConditionalExpressionSyntax)context.Node;

            if (conditionalExpression.ContainsDiagnostics)
            {
                return;
            }

            ConditionalExpressionInfo info = SyntaxInfo.ConditionalExpressionInfo(conditionalExpression, walkDownParentheses: false);

            if (!info.Success)
            {
                return;
            }

            if (info.Condition.Kind() == SyntaxKind.ParenthesizedExpression)
            {
                return;
            }

            DiagnosticHelpers.ReportDiagnostic(context, DiagnosticDescriptors.ParenthesizeConditionInConditionalExpression, info.Condition);
        }
コード例 #5
0
        private static void AnalyzeConditionalExpression(SyntaxNodeAnalysisContext context)
        {
            var conditionalExpression = (ConditionalExpressionSyntax)context.Node;

            if (context.Node.ContainsDiagnostics)
            {
                return;
            }

            if (context.Node.SpanContainsDirectives())
            {
                return;
            }

            ConditionalExpressionInfo info = SyntaxInfo.ConditionalExpressionInfo(conditionalExpression);

            if (!info.Success)
            {
                return;
            }

            SyntaxKind trueKind  = info.WhenTrue.Kind();
            SyntaxKind falseKind = info.WhenFalse.Kind();

            if (trueKind == SyntaxKind.TrueLiteralExpression)
            {
                // a ? true : false >>> a
                // a ? true : b >>> a || b
                if (falseKind == SyntaxKind.FalseLiteralExpression ||
                    context.SemanticModel.GetTypeInfo(info.WhenFalse, context.CancellationToken).ConvertedType?.SpecialType == SpecialType.System_Boolean)
                {
                    Report(DiagnosticDescriptors.SimplifyConditionalExpression);
                }
            }
            else if (trueKind == SyntaxKind.FalseLiteralExpression)
            {
                /// a ? false : true >>> !a
                if (falseKind == SyntaxKind.TrueLiteralExpression)
                {
                    Report(DiagnosticDescriptors.SimplifyConditionalExpression);
                }
                /// a ? false : b >>> !a && b
                else if (context.SemanticModel.GetTypeInfo(info.WhenFalse, context.CancellationToken).ConvertedType?.SpecialType == SpecialType.System_Boolean)
                {
                    Report(DiagnosticDescriptors.SimplifyConditionalExpression2);
                }
            }
            else if (falseKind == SyntaxKind.TrueLiteralExpression)
            {
                // a ? b : true >>> !a || b
                if (context.SemanticModel.GetTypeInfo(info.WhenTrue, context.CancellationToken).ConvertedType?.SpecialType == SpecialType.System_Boolean)
                {
                    Report(DiagnosticDescriptors.SimplifyConditionalExpression2);
                }
            }
            else if (falseKind == SyntaxKind.FalseLiteralExpression)
            {
                // a ? b : false >>> a && b
                if (context.SemanticModel.GetTypeInfo(info.WhenTrue, context.CancellationToken).ConvertedType?.SpecialType == SpecialType.System_Boolean)
                {
                    Report(DiagnosticDescriptors.SimplifyConditionalExpression);
                }
            }

            void Report(DiagnosticDescriptor descriptor)
            {
                DiagnosticHelpers.ReportDiagnosticIfNotSuppressed(context, descriptor, conditionalExpression);
            }
        }
コード例 #6
0
        public static async Task <Document> RefactorAsync(
            Document document,
            ConditionalExpressionSyntax conditionalExpression,
            CancellationToken cancellationToken)
        {
            ConditionalExpressionInfo info = SyntaxInfo.ConditionalExpressionInfo(conditionalExpression);

            ExpressionSyntax whenTrue  = info.WhenTrue;
            ExpressionSyntax whenFalse = info.WhenFalse;

            SyntaxKind trueKind  = whenTrue.Kind();
            SyntaxKind falseKind = whenFalse.Kind();

            ExpressionSyntax newNode = null;

            if (trueKind == SyntaxKind.TrueLiteralExpression)
            {
                if (falseKind == SyntaxKind.FalseLiteralExpression)
                {
                    newNode = CreateNewNode(conditionalExpression, info.Condition);
                }
                else
                {
                    SyntaxTriviaList trailingTrivia = info
                                                      .QuestionToken
                                                      .LeadingTrivia
                                                      .AddRange(info.QuestionToken.TrailingTrivia)
                                                      .AddRange(whenTrue.GetLeadingTrivia())
                                                      .EmptyIfWhitespace();

                    newNode = LogicalOrExpression(
                        conditionalExpression.Condition.Parenthesize().AppendToTrailingTrivia(trailingTrivia),
                        Token(info.ColonToken.LeadingTrivia, SyntaxKind.BarBarToken, info.ColonToken.TrailingTrivia),
                        whenFalse.Parenthesize());
                }
            }
            else if (falseKind == SyntaxKind.FalseLiteralExpression)
            {
                SyntaxTriviaList trailingTrivia = whenTrue
                                                  .GetTrailingTrivia()
                                                  .AddRange(info.ColonToken.LeadingTrivia)
                                                  .AddRange(info.ColonToken.TrailingTrivia)
                                                  .AddRange(whenFalse.GetLeadingTrivia())
                                                  .EmptyIfWhitespace()
                                                  .AddRange(whenFalse.GetTrailingTrivia());

                newNode = LogicalAndExpression(
                    conditionalExpression.Condition.Parenthesize(),
                    Token(info.QuestionToken.LeadingTrivia, SyntaxKind.AmpersandAmpersandToken, info.QuestionToken.TrailingTrivia),
                    whenTrue.WithTrailingTrivia(trailingTrivia).Parenthesize());
            }
            else if (trueKind == SyntaxKind.FalseLiteralExpression &&
                     falseKind == SyntaxKind.TrueLiteralExpression)
            {
                SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

                newNode = CreateNewNode(conditionalExpression, Inverter.LogicallyNegate(info.Condition, semanticModel, cancellationToken));
            }

            newNode = newNode.Parenthesize();

            return(await document.ReplaceNodeAsync(conditionalExpression, newNode, cancellationToken).ConfigureAwait(false));
        }
コード例 #7
0
        public static void AnalyzeConditionalExpression(SyntaxNodeAnalysisContext context)
        {
            if (context.Node.SpanContainsDirectives())
            {
                return;
            }

            var conditionalExpression = (ConditionalExpressionSyntax)context.Node;

            ConditionalExpressionInfo conditionalExpressionInfo = SyntaxInfo.ConditionalExpressionInfo(conditionalExpression);

            if (!conditionalExpressionInfo.Success)
            {
                return;
            }

            SemanticModel     semanticModel     = context.SemanticModel;
            CancellationToken cancellationToken = context.CancellationToken;

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

            if (!nullCheck.Success)
            {
                return;
            }

            ExpressionSyntax whenNotNull = (nullCheck.IsCheckingNotNull) ? conditionalExpressionInfo.WhenTrue : conditionalExpressionInfo.WhenFalse;

            ExpressionSyntax whenNull = (nullCheck.IsCheckingNotNull) ? conditionalExpressionInfo.WhenFalse : conditionalExpressionInfo.WhenTrue;

            if (CSharpFactory.AreEquivalent(nullCheck.Expression, whenNotNull))
            {
                if (!context.IsAnalyzerSuppressed(DiagnosticDescriptors.UseCoalesceExpressionInsteadOfConditionalExpression) &&
                    semanticModel
                    .GetTypeSymbol(nullCheck.Expression, cancellationToken)?
                    .IsReferenceTypeOrNullableType() == true)
                {
                    DiagnosticHelpers.ReportDiagnostic(context,
                                                       DiagnosticDescriptors.UseCoalesceExpressionInsteadOfConditionalExpression,
                                                       conditionalExpression);
                }
            }
            else if (whenNotNull.IsKind(
                         SyntaxKind.SimpleMemberAccessExpression,
                         SyntaxKind.ElementAccessExpression,
                         SyntaxKind.ConditionalAccessExpression,
                         SyntaxKind.InvocationExpression))
            {
                ExpressionSyntax expression = UseConditionalAccessAnalyzer.FindExpressionThatCanBeConditionallyAccessed(
                    nullCheck.Expression,
                    whenNotNull,
                    semanticModel,
                    cancellationToken);

                if (expression == null)
                {
                    return;
                }

                ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(nullCheck.Expression, cancellationToken);

                if (typeSymbol == null)
                {
                    return;
                }

                if (typeSymbol.IsReferenceType)
                {
                    Analyze(context, conditionalExpressionInfo, whenNull, whenNotNull, semanticModel, cancellationToken);
                }
                else if (typeSymbol.IsNullableType())
                {
                    if (expression.IsParentKind(SyntaxKind.SimpleMemberAccessExpression))
                    {
                        var memberAccessExpression = (MemberAccessExpressionSyntax)expression.Parent;

                        if (!memberAccessExpression.IsParentKind(SyntaxKind.InvocationExpression) &&
                            (memberAccessExpression.Name as IdentifierNameSyntax)?.Identifier.ValueText == "Value")
                        {
                            if (memberAccessExpression == whenNotNull)
                            {
                                if (!context.IsAnalyzerSuppressed(DiagnosticDescriptors.UseCoalesceExpressionInsteadOfConditionalExpression))
                                {
                                    DiagnosticHelpers.ReportDiagnostic(
                                        context,
                                        DiagnosticDescriptors.UseCoalesceExpressionInsteadOfConditionalExpression,
                                        conditionalExpression);
                                }
                            }
                            else
                            {
                                Analyze(context, conditionalExpressionInfo, whenNull, whenNotNull, semanticModel, cancellationToken);
                            }
                        }
                    }
                }
            }
            else if (!context.IsAnalyzerSuppressed(DiagnosticDescriptors.UseConditionalAccessInsteadOfConditionalExpression) &&
                     whenNotNull.IsKind(SyntaxKind.CastExpression) &&
                     whenNull.IsKind(SyntaxKind.NullLiteralExpression, SyntaxKind.DefaultLiteralExpression))
            {
                var castExpression = (CastExpressionSyntax)whenNotNull;

                if (castExpression.Type.IsKind(SyntaxKind.NullableType) &&
                    castExpression.Expression.IsKind(SyntaxKind.InvocationExpression, SyntaxKind.SimpleMemberAccessExpression, SyntaxKind.ElementAccessExpression))
                {
                    ExpressionSyntax expression = UseConditionalAccessAnalyzer.FindExpressionThatCanBeConditionallyAccessed(
                        nullCheck.Expression,
                        castExpression.Expression,
                        isNullable: true,
                        semanticModel,
                        cancellationToken);

                    if (expression != null)
                    {
                        ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(nullCheck.Expression, cancellationToken);

                        if (typeSymbol?.OriginalDefinition.SpecialType == SpecialType.System_Nullable_T)
                        {
                            DiagnosticHelpers.ReportDiagnostic(context,
                                                               DiagnosticDescriptors.UseConditionalAccessInsteadOfConditionalExpression,
                                                               conditionalExpression);
                        }
                    }
                }
            }
        }
コード例 #8
0
 public static bool CanRefactor(ConditionalExpressionSyntax conditionalExpression)
 {
     return(SyntaxInfo.ConditionalExpressionInfo(conditionalExpression).Success);
 }
コード例 #9
0
        public static async Task <Document> RefactorAsync(
            Document document,
            ConditionalExpressionSyntax conditionalExpression,
            CancellationToken cancellationToken)
        {
            SemanticModel semanticModel = await document.GetSemanticModelAsync().ConfigureAwait(false);

            ConditionalExpressionInfo conditionalExpressionInfo = SyntaxInfo.ConditionalExpressionInfo(conditionalExpression);

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

            ExpressionSyntax whenNotNull = (nullCheck.IsCheckingNotNull) ? conditionalExpressionInfo.WhenTrue : conditionalExpressionInfo.WhenFalse;

            ExpressionSyntax whenNull = (nullCheck.IsCheckingNotNull) ? conditionalExpressionInfo.WhenFalse : conditionalExpressionInfo.WhenTrue;

            ExpressionSyntax expression = UseConditionalAccessAnalyzer.FindExpressionThatCanBeConditionallyAccessed(nullCheck.Expression, whenNotNull);

            bool coalesce = false;

            ExpressionSyntax newNode = null;

            if (CSharpFactory.AreEquivalent(nullCheck.Expression, whenNotNull))
            {
                newNode  = nullCheck.Expression;
                coalesce = true;
            }
            else if (semanticModel
                     .GetTypeSymbol(nullCheck.Expression, cancellationToken)
                     .IsNullableType())
            {
                if (expression.IsParentKind(SyntaxKind.SimpleMemberAccessExpression))
                {
                    var memberAccessExpression = (MemberAccessExpressionSyntax)expression.Parent;

                    if (!memberAccessExpression.IsParentKind(SyntaxKind.InvocationExpression) &&
                        (memberAccessExpression.Name as IdentifierNameSyntax)?.Identifier.ValueText == "Value")
                    {
                        if (memberAccessExpression == whenNotNull)
                        {
                            newNode  = nullCheck.Expression;
                            coalesce = true;
                        }
                        else
                        {
                            newNode = ParseExpression($"{expression}?{whenNotNull.ToString().Substring(memberAccessExpression.Span.End - whenNotNull.SpanStart)}");
                        }
                    }
                }
            }

            if (newNode == null)
            {
                newNode = ParseExpression(whenNotNull.ToString().Insert(expression.Span.End - whenNotNull.SpanStart, "?"));
            }

            if (coalesce || !semanticModel.GetTypeSymbol(whenNotNull, cancellationToken).IsReferenceType)
            {
                newNode = CoalesceExpression(newNode.Parenthesize(), whenNull.Parenthesize());
            }

            newNode = newNode
                      .WithTriviaFrom(conditionalExpression)
                      .Parenthesize();

            return(await document.ReplaceNodeAsync(conditionalExpression, newNode, cancellationToken).ConfigureAwait(false));
        }
コード例 #10
0
        private static void AnalyzeConditionalExpression(SyntaxNodeAnalysisContext context)
        {
            if (context.Node.ContainsDiagnostics)
            {
                return;
            }

            if (context.Node.SpanContainsDirectives())
            {
                return;
            }

            var conditionalExpression = (ConditionalExpressionSyntax)context.Node;

            ConditionalExpressionInfo info = SyntaxInfo.ConditionalExpressionInfo(conditionalExpression);

            if (!info.Success)
            {
                return;
            }

            SyntaxKind trueKind  = info.WhenTrue.Kind();
            SyntaxKind falseKind = info.WhenFalse.Kind();

            if (trueKind == SyntaxKind.TrueLiteralExpression)
            {
                // a ? true : false >>> a
                // a ? true : b >>> a || b
                if (falseKind == SyntaxKind.FalseLiteralExpression ||
                    (falseKind != SyntaxKind.ThrowExpression &&
                     context.SemanticModel.GetTypeInfo(info.WhenFalse, context.CancellationToken).ConvertedType?.SpecialType == SpecialType.System_Boolean))
                {
                    ReportDiagnostic();
                }
            }
            else if (trueKind == SyntaxKind.FalseLiteralExpression)
            {
                /// a ? false : true >>> !a
                if (falseKind == SyntaxKind.TrueLiteralExpression)
                {
                    ReportDiagnostic();
                }
                /// a ? false : b >>> !a && b
                else if (falseKind != SyntaxKind.ThrowExpression &&
                         !AnalyzerOptions.DoNotSimplifyConditionalExpressionWhenConditionIsInverted.IsEnabled(context) &&
                         context.SemanticModel.GetTypeInfo(info.WhenFalse, context.CancellationToken).ConvertedType?.SpecialType == SpecialType.System_Boolean)
                {
                    DiagnosticHelpers.ReportDiagnostic(context, DiagnosticRules.SimplifyConditionalExpression, conditionalExpression, AnalyzerOptions.DoNotSimplifyConditionalExpressionWhenConditionIsInverted);
                }
            }
            else if (falseKind == SyntaxKind.TrueLiteralExpression)
            {
                // a ? b : true >>> !a || b
                if (trueKind != SyntaxKind.ThrowExpression &&
                    !AnalyzerOptions.DoNotSimplifyConditionalExpressionWhenConditionIsInverted.IsEnabled(context) &&
                    context.SemanticModel.GetTypeInfo(info.WhenTrue, context.CancellationToken).ConvertedType?.SpecialType == SpecialType.System_Boolean)
                {
                    DiagnosticHelpers.ReportDiagnostic(context, DiagnosticRules.SimplifyConditionalExpression, conditionalExpression, AnalyzerOptions.DoNotSimplifyConditionalExpressionWhenConditionIsInverted);
                }
            }
            else if (falseKind == SyntaxKind.FalseLiteralExpression)
            {
                // a ? b : false >>> a && b
                if (trueKind != SyntaxKind.ThrowExpression &&
                    context.SemanticModel.GetTypeInfo(info.WhenTrue, context.CancellationToken).ConvertedType?.SpecialType == SpecialType.System_Boolean)
                {
                    ReportDiagnostic();
                }
            }

            void ReportDiagnostic()
            {
                DiagnosticHelpers.ReportDiagnostic(context, DiagnosticRules.SimplifyConditionalExpression, conditionalExpression);
            }
        }