Repository: dotnet/roslyn
File: src/Analyzers/CSharp/Analyzers/UseNullPropagation/CSharpUseNullPropagationDiagnosticAnalyzer.cs (C#)

Code before:

        if (pattern is not ConstantPatternSyntax constantPattern)
            return false;

        if (!syntaxFacts.IsNullLiteralExpression(constantPattern.Expression))
            return false;

        conditionPartToCheck = patternExpression.Expression;
        return true;
    }

    public override IfStatementAnalysisResult? AnalyzeIfStatement(
        SemanticModel semanticModel,
        IMethodSymbol? referenceEqualsMethod,
        IfStatementSyntax ifStatement,
        CancellationToken cancellationToken)
    {
        // Check if the if-statement has a block statement with preprocessor directives.
        // If so, we can't convert to null propagation because the directives (like #if DEBUG)
        // would be lost or cause compilation issues. We check the entire block rather than
        // just the close brace to handle cases where directives appear anywhere in the block.
        if (ifStatement.Statement is BlockSyntax block)
        {
            if (block.ContainsDirectives)
                return null;
        }

        return base.AnalyzeIfStatement(semanticModel, referenceEqualsMethod, ifStatement, cancellationToken);
    }

    protected override bool TryGetPartsOfIfStatement(
        IfStatementSyntax ifStatement,
        [NotNullWhen(true)] out ExpressionSyntax? condition,
        out ImmutableArray<StatementSyntax> trueStatements)
    {
        // has to be of the form:
        //
        //   if (...)
        //      statement
        //
        // or
        //
        //   if (...)
        //   {
        //       statement
        //   }
        //
        // or
        //
        //   if (...)
        //   {

Review comment (suggestion):
@copilot actually you can just check if it .ContainsDirectives, regardless of whether or not it is a block.  And that means this check can move into the base class, and you can avoid needing the virtual/override. 

Also, please add a test where the if-statement doesn't have a block, but just a single-statement with a `#if/#else/#endif`..  

Code after:

        if (pattern is not ConstantPatternSyntax constantPattern)
            return false;

        if (!syntaxFacts.IsNullLiteralExpression(constantPattern.Expression))
            return false;

        conditionPartToCheck = patternExpression.Expression;
        return true;
    }

    protected override bool TryGetPartsOfIfStatement(
        IfStatementSyntax ifStatement,
        [NotNullWhen(true)] out ExpressionSyntax? condition,
        out ImmutableArray<StatementSyntax> trueStatements)
    {
        // has to be of the form:
        //
        //   if (...)
        //      statement
        //
        // or
        //
        //   if (...)
        //   {
        //       statement
        //   }
        //
        // or
        //
        //   if (...)
        //   {
        //       statement
        //       val = null;
        //   }

        condition = ifStatement.Condition;

        trueStatements = [];
        if (ifStatement.Else == null)
        {
            trueStatements = ifStatement.Statement is BlockSyntax block
                ? [.. block.Statements]
                : [ifStatement.Statement];
        }

        return true;
    }

    public override IfStatementAnalysisResult? AnalyzeIfStatement(
        SemanticModel semanticModel,