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; }