Ejemplo n.º 1
0
        private static void CheckConditionalExpression(SyntaxNodeAnalysisContext c)
        {
            var conditional = (ConditionalExpressionSyntax)c.Node;

            var condition = TernaryOperatorPointless.RemoveParentheses(conditional.Condition);
            var whenTrue  = TernaryOperatorPointless.RemoveParentheses(conditional.WhenTrue);
            var whenFalse = TernaryOperatorPointless.RemoveParentheses(conditional.WhenFalse);

            if (EquivalenceChecker.AreEquivalent(whenTrue, whenFalse))
            {
                /// handled by S2758, <see cref="TernaryOperatorPointless"/>
                return;
            }

            ExpressionSyntax comparedToNull;
            bool             comparedIsNullInTrue;

            if (!TryGetExpressionComparedToNull(condition, out comparedToNull, out comparedIsNullInTrue) ||
                !ExpressionCanBeNull(comparedToNull, c.SemanticModel))
            {
                // expression not compared to null, or can't be null
                return;
            }

            if (CanExpressionBeNullCoalescing(whenTrue, whenFalse, comparedToNull, comparedIsNullInTrue, c.SemanticModel))
            {
                c.ReportDiagnostic(Diagnostic.Create(Rule, conditional.GetLocation(), "??"));
            }
        }
Ejemplo n.º 2
0
        public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            var root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false);

            var diagnostic     = context.Diagnostics.First();
            var diagnosticSpan = diagnostic.Location.SourceSpan;
            var conditional    = root.FindNode(diagnosticSpan, getInnermostNodeForTie: true) as ConditionalExpressionSyntax;

            if (conditional == null)
            {
                return;
            }

            context.RegisterCodeFix(
                CodeAction.Create(
                    Title,
                    c =>
            {
                var newRoot = root.ReplaceNode(
                    conditional,
                    TernaryOperatorPointless.RemoveParentheses(conditional.WhenTrue)
                    .WithAdditionalAnnotations(Formatter.Annotation));
                return(Task.FromResult(context.Document.WithSyntaxRoot(newRoot)));
            }),
                context.Diagnostics);
        }
Ejemplo n.º 3
0
        private static bool CanBeSimplified(StatementSyntax statement1, StatementSyntax statement2,
                                            ExpressionSyntax comparedToNull, bool comparedIsNullInTrue, SemanticModel semanticModel, out bool isNullCoalescing)
        {
            isNullCoalescing = false;
            var return1 = statement1 as ReturnStatementSyntax;
            var return2 = statement2 as ReturnStatementSyntax;

            if (return1 != null && return2 != null)
            {
                var retExpr1 = TernaryOperatorPointless.RemoveParentheses(return1.Expression);
                var retExpr2 = TernaryOperatorPointless.RemoveParentheses(return2.Expression);

                if (!AreTypesCompatible(return1.Expression, return2.Expression, semanticModel))
                {
                    return(false);
                }

                if (comparedToNull != null &&
                    CanExpressionBeNullCoalescing(retExpr1, retExpr2, comparedToNull, comparedIsNullInTrue, semanticModel))
                {
                    isNullCoalescing = true;
                }

                return(true);
            }

            var expressionStatement1 = statement1 as ExpressionStatementSyntax;
            var expressionStatement2 = statement2 as ExpressionStatementSyntax;

            if (expressionStatement1 == null || expressionStatement2 == null)
            {
                return(false);
            }

            var expression1 = TernaryOperatorPointless.RemoveParentheses(expressionStatement1.Expression);
            var expression2 = TernaryOperatorPointless.RemoveParentheses(expressionStatement2.Expression);

            if (AreCandidateAssignments(expression1, expression2, comparedToNull, comparedIsNullInTrue,
                                        semanticModel, out isNullCoalescing))
            {
                return(true);
            }

            if (comparedToNull != null &&
                CanExpressionBeNullCoalescing(expression1, expression2, comparedToNull, comparedIsNullInTrue, semanticModel))
            {
                isNullCoalescing = true;
                return(true);
            }

            if (AreCandidateInvocationsForTernary(expression1, expression2, semanticModel))
            {
                return(true);
            }

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

            var diagnostic     = context.Diagnostics.First();
            var diagnosticSpan = diagnostic.Location.SourceSpan;
            var syntax         = root.FindNode(diagnosticSpan);
            var semanticModel  = await context.Document.GetSemanticModelAsync(context.CancellationToken).ConfigureAwait(false);

            var conditional = syntax as ConditionalExpressionSyntax;

            if (conditional != null)
            {
                var condition = TernaryOperatorPointless.RemoveParentheses(conditional.Condition);
                var whenTrue  = TernaryOperatorPointless.RemoveParentheses(conditional.WhenTrue);
                var whenFalse = TernaryOperatorPointless.RemoveParentheses(conditional.WhenFalse);

                ExpressionSyntax compared;
                bool             comparedIsNullInTrue;
                ConditionalSimplification.TryGetExpressionComparedToNull(condition, out compared, out comparedIsNullInTrue);

                var annotation = new SyntaxAnnotation();
                var coalescing = GetNullCoalescing(whenTrue, whenFalse, compared, semanticModel, annotation);

                context.RegisterCodeFix(
                    GetActionToExecute(context, root, conditional, coalescing, annotation),
                    context.Diagnostics);
            }

            var ifStatement = syntax as IfStatementSyntax;

            if (ifStatement != null)
            {
                var whenTrue  = ConditionalSimplification.ExtractSingleStatement(ifStatement.Statement);
                var whenFalse = ConditionalSimplification.ExtractSingleStatement(ifStatement.Else.Statement);

                ExpressionSyntax compared;
                bool             comparedIsNullInTrue;
                ConditionalSimplification.TryGetExpressionComparedToNull(ifStatement.Condition, out compared, out comparedIsNullInTrue);
                var isNullCoalescing = bool.Parse(diagnostic.Properties[ConditionalSimplification.IsNullCoalescingKey]);

                var annotation = new SyntaxAnnotation();
                var simplified = GetSimplified(whenTrue, whenFalse, ifStatement.Condition, compared, isNullCoalescing, semanticModel, annotation);

                context.RegisterCodeFix(
                    GetActionToExecute(context, root, ifStatement, simplified, annotation),
                    context.Diagnostics);
            }
        }
        private static StatementSyntax GetSimplified(StatementSyntax statement1, StatementSyntax statement2,
                                                     ExpressionSyntax condition, ExpressionSyntax compared, bool isNullCoalescing, SemanticModel semanticModel,
                                                     SyntaxAnnotation annotation)
        {
            var return1 = statement1 as ReturnStatementSyntax;
            var return2 = statement2 as ReturnStatementSyntax;

            if (return1 != null && return2 != null)
            {
                var retExpr1 = TernaryOperatorPointless.RemoveParentheses(return1.Expression);
                var retExpr2 = TernaryOperatorPointless.RemoveParentheses(return2.Expression);

                var createdExpression = isNullCoalescing
                    ? GetNullCoalescing(retExpr1, retExpr2, compared, semanticModel, annotation)
                    : SyntaxFactory.ConditionalExpression(
                    condition,
                    return1.Expression,
                    return2.Expression)
                                        .WithAdditionalAnnotations(annotation);

                return(SyntaxFactory.ReturnStatement(createdExpression));
            }

            var expressionStatement1 = statement1 as ExpressionStatementSyntax;
            var expressionStatement2 = statement2 as ExpressionStatementSyntax;

            var expression1 = TernaryOperatorPointless.RemoveParentheses(expressionStatement1.Expression);
            var expression2 = TernaryOperatorPointless.RemoveParentheses(expressionStatement2.Expression);

            var assignment = GetSimplifiedAssignment(expression1, expression2, condition, compared, isNullCoalescing, semanticModel, annotation);

            if (assignment != null)
            {
                return(SyntaxFactory.ExpressionStatement(assignment));
            }

            var expression = GetSimplificationFromInvocations(expression1, expression2, condition, compared, isNullCoalescing, semanticModel, annotation);

            if (expression != null)
            {
                return(SyntaxFactory.ExpressionStatement(expression));
            }
            return(null);
        }