public override void VisitBinaryOperatorExpression(BinaryOperatorExpression binaryOperatorExpression) { base.VisitBinaryOperatorExpression(binaryOperatorExpression); if (binaryOperatorExpression.Operator != BinaryOperatorType.NullCoalescing) { //The issue is not applicable return; } var parentFunction = GetParentFunctionNode(binaryOperatorExpression); var analysis = GetAnalysis(parentFunction); NullValueStatus leftStatus = analysis.GetExpressionResult(binaryOperatorExpression.Left); if (leftStatus == NullValueStatus.DefinitelyNotNull) { AddIssue(new CodeIssue(binaryOperatorExpression.OperatorToken.StartLocation, binaryOperatorExpression.Right.EndLocation, ctx.TranslateString("Redundant ??. Left side is never null."), ctx.TranslateString("Remove redundant right side"), script => { script.Replace(binaryOperatorExpression, binaryOperatorExpression.Left.Clone()); }) { IssueMarker = IssueMarker.GrayOut }); return; } if (leftStatus == NullValueStatus.DefinitelyNull) { AddIssue(new CodeIssue(binaryOperatorExpression.Left.StartLocation, binaryOperatorExpression.OperatorToken.EndLocation, ctx.TranslateString("Redundant ??. Left side is always null."), ctx.TranslateString("Remove redundant left side"), script => { script.Replace(binaryOperatorExpression, binaryOperatorExpression.Right.Clone()); })); return; } NullValueStatus rightStatus = analysis.GetExpressionResult(binaryOperatorExpression.Right); if (rightStatus == NullValueStatus.DefinitelyNull) { AddIssue(new CodeIssue(binaryOperatorExpression.OperatorToken.StartLocation, binaryOperatorExpression.Right.EndLocation, ctx.TranslateString("Redundant ??. Right side is always null."), ctx.TranslateString("Remove redundant right side"), script => { script.Replace(binaryOperatorExpression, binaryOperatorExpression.Left.Clone()); })); return; } }
public static bool IsDefiniteValue(this NullValueStatus self) { return(self == NullValueStatus.DefinitelyNull || self == NullValueStatus.DefinitelyNotNull); }