Example #1
0
        protected sealed override async Task RegisterCodeFixesAsync(SyntaxNode root, CodeFixContext context)
        {
            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 = conditional.Condition.RemoveParentheses();
                var whenTrue  = conditional.WhenTrue.RemoveParentheses();
                var whenFalse = conditional.WhenFalse.RemoveParentheses();

                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, semanticModel, annotation, isNullCoalescing);

                context.RegisterCodeFix(
                    GetActionToExecute(context, root, ifStatement, simplified, annotation),
                    context.Diagnostics);
            }
        }
        private static SyntaxNode Simplify(Diagnostic diagnostic, SemanticModel semanticModel, SyntaxNode oldNode, out SyntaxAnnotation annotation)
        {
            ExpressionSyntax compared;

            switch (oldNode)
            {
            case ConditionalExpressionSyntax conditional:
                var condition = conditional.Condition.RemoveParentheses();
                var whenTrue  = conditional.WhenTrue.RemoveParentheses();
                var whenFalse = conditional.WhenFalse.RemoveParentheses();
                ConditionalSimplification.TryGetExpressionComparedToNull(condition, out compared, out _);
                return(SimplifyCoalesceExpression(new ComparedContext(diagnostic, semanticModel, compared, out annotation), whenTrue, whenFalse));

            case IfStatementSyntax ifStatement:
                var ifPart   = ConditionalSimplification.ExtractSingleStatement(ifStatement.Statement);
                var elsePart = ConditionalSimplification.ExtractSingleStatement(ifStatement.Else?.Statement);
                ConditionalSimplification.TryGetExpressionComparedToNull(ifStatement.Condition, out compared, out var _);
                return(SimplifyIfStatement(new ComparedContext(diagnostic, semanticModel, compared, out annotation), ifPart, elsePart, ifStatement.Condition.RemoveParentheses()));

            case AssignmentExpressionSyntax assignment:
                var context = new ComparedContext(diagnostic, semanticModel, null, out annotation);
                var right   = assignment.Right.RemoveParentheses();
                if (right is BinaryExpressionSyntax binaryExpression && binaryExpression.Kind() == SyntaxKind.CoalesceExpression)
                {
                    return(CoalesceAssignmentExpression(context, assignment.Left, binaryExpression.Right));
                }
                else if (right is ConditionalExpressionSyntax conditional)
                {
                    ConditionalSimplification.TryGetExpressionComparedToNull(conditional.Condition, out compared, out var comparedIsNullInTrue);
                    if (context.IsCoalesceAssignmentSupported && ConditionalSimplification.IsCoalesceAssignmentCandidate(conditional, compared))
                    {
                        return(CoalesceAssignmentExpression(context,
                                                            (conditional.GetFirstNonParenthesizedParent() as AssignmentExpressionSyntax).Left,
                                                            (comparedIsNullInTrue ? conditional.WhenTrue : conditional.WhenFalse).RemoveParentheses()));
                    }
                }
                break;
            }