File: Diagnostics\CompilationWithAnalyzersTests.cs
Web Access
Project: src\src\Compilers\Core\CodeAnalysisTest\Microsoft.CodeAnalysis.UnitTests.csproj (Microsoft.CodeAnalysis.UnitTests)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
 
#nullable disable
 
using System;
using System.Collections.Immutable;
using System.Threading;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.Diagnostics;
using Roslyn.Test.Utilities;
using Xunit;
using static Microsoft.CodeAnalysis.CommonDiagnosticAnalyzers;
using KeyValuePairUtil = Roslyn.Utilities.KeyValuePairUtil;
 
namespace Microsoft.CodeAnalysis.UnitTests.Diagnostics
{
    using SimpleDiagnostic = Diagnostic.SimpleDiagnostic;
 
    public class CompilationWithAnalyzersTests : TestBase
    {
        private static readonly CSharpCompilationOptions s_dllWithMaxWarningLevel = new(OutputKind.DynamicallyLinkedLibrary, warningLevel: CodeAnalysis.Diagnostic.MaxWarningLevel);
 
        [Fact]
        public void GetEffectiveDiagnostics_Errors()
        {
            var c = CSharpCompilation.Create("c");
            var ds = new[] { (Diagnostic)null };
 
            Assert.Throws<ArgumentNullException>(() => CompilationWithAnalyzers.GetEffectiveDiagnostics(default(ImmutableArray<Diagnostic>), c));
            Assert.Throws<ArgumentNullException>(() => CompilationWithAnalyzers.GetEffectiveDiagnostics(null, c));
            Assert.Throws<ArgumentNullException>(() => CompilationWithAnalyzers.GetEffectiveDiagnostics(ds, null));
        }
 
        [Fact]
        public void GetEffectiveDiagnostics()
        {
            var c = CSharpCompilation.Create("c", options: s_dllWithMaxWarningLevel.
                WithSpecificDiagnosticOptions(
                    new[] { KeyValuePairUtil.Create($"CS{(int)ErrorCode.WRN_AlwaysNull:D4}", ReportDiagnostic.Suppress) }));
 
            var d1 = SimpleDiagnostic.Create(MessageProvider.Instance, (int)ErrorCode.WRN_AlignmentMagnitude, "1", "2");
            var d2 = SimpleDiagnostic.Create(MessageProvider.Instance, (int)ErrorCode.WRN_AlwaysNull, "1");
            var ds = new[] { null, d1, d2 };
 
            var filtered = CompilationWithAnalyzers.GetEffectiveDiagnostics(ds, c);
 
            // overwrite the original value to test eagerness:
            ds[1] = null;
 
            AssertEx.Equal(new[] { d1 }, filtered);
        }
 
        [Fact]
        public void GetAnalyzerTelemetry()
        {
            var compilation = CSharpCompilation.Create("c", options: s_dllWithMaxWarningLevel);
            DiagnosticAnalyzer analyzer = new AnalyzerWithDisabledRules();
            var analyzers = ImmutableArray.Create(analyzer);
            var analyzerOptions = new AnalyzerOptions(ImmutableArray<AdditionalText>.Empty);
            var compWithAnalyzers = new CompilationWithAnalyzers(compilation, analyzers, analyzerOptions);
 
            var analysisResult = compWithAnalyzers.GetAnalysisResultAsync(CancellationToken.None).Result;
            Assert.Empty(analysisResult.CompilationDiagnostics);
 
            // Even though the analyzer registers a symbol action, it should never be invoked because all of its rules are disabled.
            var analyzerTelemetry = compWithAnalyzers.GetAnalyzerTelemetryInfoAsync(analyzer, CancellationToken.None).Result;
            Assert.Equal(0, analyzerTelemetry.SymbolActionsCount);
        }
 
        [Fact, Obsolete(message: "IsDiagnosticAnalyzerSuppressed is an obsolete public API")]
        public void TestIsDiagnosticAnalyzerSuppressedWithExceptionInSupportedDiagnostics()
        {
            // Verify IsDiagnosticAnalyzerSuppressed does not throw an exception when 'onAnalyzerException' is null.
            var analyzer = new AnalyzerThatThrowsInSupportedDiagnostics();
            _ = CompilationWithAnalyzers.IsDiagnosticAnalyzerSuppressed(analyzer, s_dllWithMaxWarningLevel, onAnalyzerException: null);
        }
    }
}