File: RelaxTestNamingSuppressor.cs
Web Access
Project: src\tools-local\Microsoft.ML.InternalCodeAnalyzer\Microsoft.ML.InternalCodeAnalyzer.csproj (Microsoft.ML.InternalCodeAnalyzer)
// 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.
 
using System.Collections.Concurrent;
using System.Collections.Immutable;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Diagnostics;
 
namespace Microsoft.ML.InternalCodeAnalyzer
{
    [DiagnosticAnalyzer(LanguageNames.CSharp)]
    public sealed class RelaxTestNamingSuppressor : DiagnosticSuppressor
    {
        private const string Id = "MSML_RelaxTestNaming";
        private const string SuppressedDiagnosticId = "VSTHRD200";
        private const string Justification = "Asynchronous test methods do not require the 'Async' suffix.";
 
        internal static readonly SuppressionDescriptor Rule =
            new SuppressionDescriptor(Id, SuppressedDiagnosticId, Justification);
 
        public override ImmutableArray<SuppressionDescriptor> SupportedSuppressions { get; } = ImmutableArray.Create(Rule);
 
        public override void ReportSuppressions(SuppressionAnalysisContext context)
        {
            if (!(context.Compilation.GetTypeByMetadataName("Xunit.FactAttribute") is { } factAttribute))
            {
                return;
            }
 
            var knownTestAttributes = new ConcurrentDictionary<INamedTypeSymbol, bool>();
 
            foreach (var diagnostic in context.ReportedDiagnostics)
            {
                // The diagnostic is reported on the test method
                if (!(diagnostic.Location.SourceTree is { } tree))
                {
                    continue;
                }
 
                var root = tree.GetRoot(context.CancellationToken);
                var node = root.FindNode(diagnostic.Location.SourceSpan, getInnermostNodeForTie: true);
 
                var semanticModel = context.GetSemanticModel(tree);
                var declaredSymbol = semanticModel.GetDeclaredSymbol(node, context.CancellationToken);
                if (declaredSymbol is IMethodSymbol method
                    && method.IsTestMethod(knownTestAttributes, factAttribute))
                {
                    context.ReportSuppression(Suppression.Create(Rule, diagnostic));
                }
            }
        }
    }
}