Skip to content

Commit

Permalink
Fix false positive for PreferTestCleanupOverDispose on non-test classes
Browse files Browse the repository at this point in the history
  • Loading branch information
Youssef1313 committed Dec 18, 2024
1 parent 6663992 commit b63e4f5
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -40,22 +40,28 @@ public override void Initialize(AnalysisContext context)

context.RegisterCompilationStartAction(context =>
{
if (context.Compilation.TryGetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemIDisposable, out INamedTypeSymbol? idisposableSymbol))
if (context.Compilation.TryGetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemIDisposable, out INamedTypeSymbol? idisposableSymbol) &&
context.Compilation.TryGetOrCreateTypeByMetadataName(WellKnownTypeNames.MicrosoftVisualStudioTestToolsUnitTestingTestClassAttribute, out INamedTypeSymbol? testClassAttributeSymbol))
{
INamedTypeSymbol? iasyncDisposableSymbol = context.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemIAsyncDisposable);
INamedTypeSymbol? valueTaskSymbol = context.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemThreadingTasksValueTask);
context.RegisterSymbolAction(context => AnalyzeSymbol(context, idisposableSymbol, iasyncDisposableSymbol, valueTaskSymbol), SymbolKind.Method);
context.RegisterSymbolAction(context => AnalyzeSymbol(context, testClassAttributeSymbol, idisposableSymbol, iasyncDisposableSymbol, valueTaskSymbol), SymbolKind.Method);
}
});
}

private static void AnalyzeSymbol(SymbolAnalysisContext context, INamedTypeSymbol idisposableSymbol, INamedTypeSymbol? iasyncDisposableSymbol,
private static void AnalyzeSymbol(
SymbolAnalysisContext context,
INamedTypeSymbol testClassAttributeSymbol,
INamedTypeSymbol idisposableSymbol,
INamedTypeSymbol? iasyncDisposableSymbol,
INamedTypeSymbol? valueTaskSymbol)
{
var methodSymbol = (IMethodSymbol)context.Symbol;

if (methodSymbol.IsAsyncDisposeImplementation(iasyncDisposableSymbol, valueTaskSymbol)
|| methodSymbol.IsDisposeImplementation(idisposableSymbol))
if (methodSymbol.ContainingType.GetAttributes().Any(x => x.AttributeClass.Inherits(testClassAttributeSymbol)) &&
(methodSymbol.IsAsyncDisposeImplementation(iasyncDisposableSymbol, valueTaskSymbol)
|| methodSymbol.IsDisposeImplementation(idisposableSymbol)))
{
context.ReportDiagnostic(methodSymbol.CreateDiagnostic(Rule));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,23 @@ namespace MSTest.Analyzers.Test;
[TestGroup]
public sealed class PreferTestCleanupOverDisposeAnalyzerTests(ITestExecutionContext testExecutionContext) : TestBase(testExecutionContext)
{
public async Task WhenNonTestClassHasDispose_NoDiagnostic()
{
string code = """
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
public class MyNonTestClass : IDisposable
{
public void Dispose()
{
}
}
""";

await VerifyCS.VerifyCodeFixAsync(code, code);
}

public async Task WhenTestClassHasDispose_Diagnostic()
{
string code = """
Expand Down

0 comments on commit b63e4f5

Please sign in to comment.