Skip to content

Commit 4c6d6d4

Browse files
authored
MSTEST0022: Prefer 'TestCleanup' methods over Dispose (#2586)
1 parent 67cd187 commit 4c6d6d4

20 files changed

+312
-1
lines changed

src/Analyzers/MSTest.Analyzers/AnalyzerReleases.Unshipped.md

+1
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@ Rule ID | Category | Severity | Notes
77
MSTEST0017 | Usage | Info | AssertionArgsShouldBePassedInCorrectOrder, [Documentation](https://learn.microsoft.com/dotnet/core/testing/mstest-analyzers/mstest0017)
88
MSTEST0019 | Design | Disabled | PreferTestInitializeOverConstructorAnalyzer, [Documentation](https://learn.microsoft.com/dotnet/core/testing/mstest-analyzers/mstest0019)
99
MSTEST0020 | Design | Disabled | PreferConstructorOverTestInitializeAnalyzer, [Documentation](https://learn.microsoft.com/dotnet/core/testing/mstest-analyzers/mstest0020)
10+
MSTEST0022 | Design | Disabled | PreferTestCleanupOverDisposeAnalyzer, [Documentation](https://learn.microsoft.com/dotnet/core/testing/mstest-analyzers/mstest0022)

src/Analyzers/MSTest.Analyzers/Helpers/DiagnosticIds.cs

+1
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,5 @@ internal static class DiagnosticIds
2424
public const string AssertionArgsShouldBePassedInCorrectOrderRuleId = "MSTEST0017";
2525
public const string PreferTestInitializeOverConstructorRuleId = "MSTEST0019";
2626
public const string PreferConstructorOverTestInitializeRuleId = "MSTEST0020";
27+
public const string PreferTestCleanupOverDisposeRuleId = "MSTEST0022";
2728
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
3+
4+
using System.Collections.Immutable;
5+
6+
using Analyzer.Utilities.Extensions;
7+
8+
using Microsoft.CodeAnalysis;
9+
using Microsoft.CodeAnalysis.Diagnostics;
10+
11+
using MSTest.Analyzers.Helpers;
12+
13+
namespace MSTest.Analyzers;
14+
15+
[DiagnosticAnalyzer(LanguageNames.CSharp, LanguageNames.VisualBasic)]
16+
public sealed class PreferTestCleanupOverDisposeAnalyzer : DiagnosticAnalyzer
17+
{
18+
private static readonly LocalizableResourceString Title = new(nameof(Resources.PreferTestCleanupOverDisposeTitle), Resources.ResourceManager, typeof(Resources));
19+
private static readonly LocalizableResourceString MessageFormat = new(nameof(Resources.PreferTestCleanupOverDisposeMessageFormat), Resources.ResourceManager, typeof(Resources));
20+
21+
internal static readonly DiagnosticDescriptor Rule = DiagnosticDescriptorHelper.Create(
22+
DiagnosticIds.PreferTestCleanupOverDisposeRuleId,
23+
Title,
24+
MessageFormat,
25+
null,
26+
Category.Design,
27+
DiagnosticSeverity.Info,
28+
isEnabledByDefault: false);
29+
30+
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics { get; }
31+
= ImmutableArray.Create(Rule);
32+
33+
public override void Initialize(AnalysisContext context)
34+
{
35+
context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
36+
context.EnableConcurrentExecution();
37+
38+
context.RegisterCompilationStartAction(context =>
39+
{
40+
if (context.Compilation.TryGetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemIDisposable, out var idisposableSymbol))
41+
{
42+
var iasyncDisposableSymbol = context.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemIAsyncDisposable);
43+
var valueTaskSymbol = context.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemThreadingTasksValueTask);
44+
context.RegisterSymbolAction(context => AnalyzeSymbol(context, idisposableSymbol, iasyncDisposableSymbol, valueTaskSymbol), SymbolKind.Method);
45+
}
46+
});
47+
}
48+
49+
private static void AnalyzeSymbol(SymbolAnalysisContext context, INamedTypeSymbol idisposableSymbol, INamedTypeSymbol? iasyncDisposableSymbol,
50+
INamedTypeSymbol? valueTaskSymbol)
51+
{
52+
IMethodSymbol methodSymbol = (IMethodSymbol)context.Symbol;
53+
54+
if (methodSymbol.IsAsyncDisposeImplementation(iasyncDisposableSymbol, valueTaskSymbol)
55+
|| methodSymbol.IsDisposeImplementation(idisposableSymbol))
56+
{
57+
context.ReportDiagnostic(methodSymbol.CreateDiagnostic(Rule));
58+
}
59+
}
60+
}

src/Analyzers/MSTest.Analyzers/Resources.Designer.cs

+18
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Analyzers/MSTest.Analyzers/Resources.resx

+7-1
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,12 @@
307307
<data name="PreferConstructorOverTestInitializeTitle" xml:space="preserve">
308308
<value>Prefer constructors over TestInitialize methods</value>
309309
</data>
310+
<data name="PreferTestCleanupOverDisposeMessageFormat" xml:space="preserve">
311+
<value>Prefer TestCleanup over 'Dispose' methods</value>
312+
</data>
313+
<data name="PreferTestCleanupOverDisposeTitle" xml:space="preserve">
314+
<value>Prefer TestCleanup over 'Dispose' methods</value>
315+
</data>
310316
<data name="PreferTestInitializeOverConstructorMessageFormat" xml:space="preserve">
311317
<value>Prefer TestInitialize methods over constructors</value>
312318
</data>
@@ -511,4 +517,4 @@
511517
<data name="UseParallelizeAttributeAnalyzerTitle" xml:space="preserve">
512518
<value>Explicitly enable or disable tests parallelization</value>
513519
</data>
514-
</root>
520+
</root>

src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf

+10
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,16 @@
333333
<target state="new">Prefer constructors over TestInitialize methods</target>
334334
<note />
335335
</trans-unit>
336+
<trans-unit id="PreferTestCleanupOverDisposeMessageFormat">
337+
<source>Prefer TestCleanup over 'Dispose' methods</source>
338+
<target state="new">Prefer TestCleanup over 'Dispose' methods</target>
339+
<note />
340+
</trans-unit>
341+
<trans-unit id="PreferTestCleanupOverDisposeTitle">
342+
<source>Prefer TestCleanup over 'Dispose' methods</source>
343+
<target state="new">Prefer TestCleanup over 'Dispose' methods</target>
344+
<note />
345+
</trans-unit>
336346
<trans-unit id="PreferTestInitializeOverConstructorMessageFormat">
337347
<source>Prefer TestInitialize methods over constructors</source>
338348
<target state="new">Prefer TestInitialize methods over constructors</target>

src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf

+10
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,16 @@
329329
<target state="new">Prefer constructors over TestInitialize methods</target>
330330
<note />
331331
</trans-unit>
332+
<trans-unit id="PreferTestCleanupOverDisposeMessageFormat">
333+
<source>Prefer TestCleanup over 'Dispose' methods</source>
334+
<target state="new">Prefer TestCleanup over 'Dispose' methods</target>
335+
<note />
336+
</trans-unit>
337+
<trans-unit id="PreferTestCleanupOverDisposeTitle">
338+
<source>Prefer TestCleanup over 'Dispose' methods</source>
339+
<target state="new">Prefer TestCleanup over 'Dispose' methods</target>
340+
<note />
341+
</trans-unit>
332342
<trans-unit id="PreferTestInitializeOverConstructorMessageFormat">
333343
<source>Prefer TestInitialize methods over constructors</source>
334344
<target state="new">Prefer TestInitialize methods over constructors</target>

src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf

+10
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,16 @@
329329
<target state="new">Prefer constructors over TestInitialize methods</target>
330330
<note />
331331
</trans-unit>
332+
<trans-unit id="PreferTestCleanupOverDisposeMessageFormat">
333+
<source>Prefer TestCleanup over 'Dispose' methods</source>
334+
<target state="new">Prefer TestCleanup over 'Dispose' methods</target>
335+
<note />
336+
</trans-unit>
337+
<trans-unit id="PreferTestCleanupOverDisposeTitle">
338+
<source>Prefer TestCleanup over 'Dispose' methods</source>
339+
<target state="new">Prefer TestCleanup over 'Dispose' methods</target>
340+
<note />
341+
</trans-unit>
332342
<trans-unit id="PreferTestInitializeOverConstructorMessageFormat">
333343
<source>Prefer TestInitialize methods over constructors</source>
334344
<target state="new">Prefer TestInitialize methods over constructors</target>

src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf

+10
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,16 @@
329329
<target state="new">Prefer constructors over TestInitialize methods</target>
330330
<note />
331331
</trans-unit>
332+
<trans-unit id="PreferTestCleanupOverDisposeMessageFormat">
333+
<source>Prefer TestCleanup over 'Dispose' methods</source>
334+
<target state="new">Prefer TestCleanup over 'Dispose' methods</target>
335+
<note />
336+
</trans-unit>
337+
<trans-unit id="PreferTestCleanupOverDisposeTitle">
338+
<source>Prefer TestCleanup over 'Dispose' methods</source>
339+
<target state="new">Prefer TestCleanup over 'Dispose' methods</target>
340+
<note />
341+
</trans-unit>
332342
<trans-unit id="PreferTestInitializeOverConstructorMessageFormat">
333343
<source>Prefer TestInitialize methods over constructors</source>
334344
<target state="new">Prefer TestInitialize methods over constructors</target>

src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf

+10
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,16 @@
329329
<target state="new">Prefer constructors over TestInitialize methods</target>
330330
<note />
331331
</trans-unit>
332+
<trans-unit id="PreferTestCleanupOverDisposeMessageFormat">
333+
<source>Prefer TestCleanup over 'Dispose' methods</source>
334+
<target state="new">Prefer TestCleanup over 'Dispose' methods</target>
335+
<note />
336+
</trans-unit>
337+
<trans-unit id="PreferTestCleanupOverDisposeTitle">
338+
<source>Prefer TestCleanup over 'Dispose' methods</source>
339+
<target state="new">Prefer TestCleanup over 'Dispose' methods</target>
340+
<note />
341+
</trans-unit>
332342
<trans-unit id="PreferTestInitializeOverConstructorMessageFormat">
333343
<source>Prefer TestInitialize methods over constructors</source>
334344
<target state="new">Prefer TestInitialize methods over constructors</target>

src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf

+10
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,16 @@
329329
<target state="new">Prefer constructors over TestInitialize methods</target>
330330
<note />
331331
</trans-unit>
332+
<trans-unit id="PreferTestCleanupOverDisposeMessageFormat">
333+
<source>Prefer TestCleanup over 'Dispose' methods</source>
334+
<target state="new">Prefer TestCleanup over 'Dispose' methods</target>
335+
<note />
336+
</trans-unit>
337+
<trans-unit id="PreferTestCleanupOverDisposeTitle">
338+
<source>Prefer TestCleanup over 'Dispose' methods</source>
339+
<target state="new">Prefer TestCleanup over 'Dispose' methods</target>
340+
<note />
341+
</trans-unit>
332342
<trans-unit id="PreferTestInitializeOverConstructorMessageFormat">
333343
<source>Prefer TestInitialize methods over constructors</source>
334344
<target state="new">Prefer TestInitialize methods over constructors</target>

src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf

+10
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,16 @@
329329
<target state="new">Prefer constructors over TestInitialize methods</target>
330330
<note />
331331
</trans-unit>
332+
<trans-unit id="PreferTestCleanupOverDisposeMessageFormat">
333+
<source>Prefer TestCleanup over 'Dispose' methods</source>
334+
<target state="new">Prefer TestCleanup over 'Dispose' methods</target>
335+
<note />
336+
</trans-unit>
337+
<trans-unit id="PreferTestCleanupOverDisposeTitle">
338+
<source>Prefer TestCleanup over 'Dispose' methods</source>
339+
<target state="new">Prefer TestCleanup over 'Dispose' methods</target>
340+
<note />
341+
</trans-unit>
332342
<trans-unit id="PreferTestInitializeOverConstructorMessageFormat">
333343
<source>Prefer TestInitialize methods over constructors</source>
334344
<target state="new">Prefer TestInitialize methods over constructors</target>

src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf

+10
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,16 @@
329329
<target state="new">Prefer constructors over TestInitialize methods</target>
330330
<note />
331331
</trans-unit>
332+
<trans-unit id="PreferTestCleanupOverDisposeMessageFormat">
333+
<source>Prefer TestCleanup over 'Dispose' methods</source>
334+
<target state="new">Prefer TestCleanup over 'Dispose' methods</target>
335+
<note />
336+
</trans-unit>
337+
<trans-unit id="PreferTestCleanupOverDisposeTitle">
338+
<source>Prefer TestCleanup over 'Dispose' methods</source>
339+
<target state="new">Prefer TestCleanup over 'Dispose' methods</target>
340+
<note />
341+
</trans-unit>
332342
<trans-unit id="PreferTestInitializeOverConstructorMessageFormat">
333343
<source>Prefer TestInitialize methods over constructors</source>
334344
<target state="new">Prefer TestInitialize methods over constructors</target>

src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf

+10
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,16 @@
329329
<target state="new">Prefer constructors over TestInitialize methods</target>
330330
<note />
331331
</trans-unit>
332+
<trans-unit id="PreferTestCleanupOverDisposeMessageFormat">
333+
<source>Prefer TestCleanup over 'Dispose' methods</source>
334+
<target state="new">Prefer TestCleanup over 'Dispose' methods</target>
335+
<note />
336+
</trans-unit>
337+
<trans-unit id="PreferTestCleanupOverDisposeTitle">
338+
<source>Prefer TestCleanup over 'Dispose' methods</source>
339+
<target state="new">Prefer TestCleanup over 'Dispose' methods</target>
340+
<note />
341+
</trans-unit>
332342
<trans-unit id="PreferTestInitializeOverConstructorMessageFormat">
333343
<source>Prefer TestInitialize methods over constructors</source>
334344
<target state="new">Prefer TestInitialize methods over constructors</target>

src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf

+10
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,16 @@
329329
<target state="new">Prefer constructors over TestInitialize methods</target>
330330
<note />
331331
</trans-unit>
332+
<trans-unit id="PreferTestCleanupOverDisposeMessageFormat">
333+
<source>Prefer TestCleanup over 'Dispose' methods</source>
334+
<target state="new">Prefer TestCleanup over 'Dispose' methods</target>
335+
<note />
336+
</trans-unit>
337+
<trans-unit id="PreferTestCleanupOverDisposeTitle">
338+
<source>Prefer TestCleanup over 'Dispose' methods</source>
339+
<target state="new">Prefer TestCleanup over 'Dispose' methods</target>
340+
<note />
341+
</trans-unit>
332342
<trans-unit id="PreferTestInitializeOverConstructorMessageFormat">
333343
<source>Prefer TestInitialize methods over constructors</source>
334344
<target state="new">Prefer TestInitialize methods over constructors</target>

src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf

+10
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,16 @@
329329
<target state="new">Prefer constructors over TestInitialize methods</target>
330330
<note />
331331
</trans-unit>
332+
<trans-unit id="PreferTestCleanupOverDisposeMessageFormat">
333+
<source>Prefer TestCleanup over 'Dispose' methods</source>
334+
<target state="new">Prefer TestCleanup over 'Dispose' methods</target>
335+
<note />
336+
</trans-unit>
337+
<trans-unit id="PreferTestCleanupOverDisposeTitle">
338+
<source>Prefer TestCleanup over 'Dispose' methods</source>
339+
<target state="new">Prefer TestCleanup over 'Dispose' methods</target>
340+
<note />
341+
</trans-unit>
332342
<trans-unit id="PreferTestInitializeOverConstructorMessageFormat">
333343
<source>Prefer TestInitialize methods over constructors</source>
334344
<target state="new">Prefer TestInitialize methods over constructors</target>

src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf

+10
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,16 @@
329329
<target state="new">Prefer constructors over TestInitialize methods</target>
330330
<note />
331331
</trans-unit>
332+
<trans-unit id="PreferTestCleanupOverDisposeMessageFormat">
333+
<source>Prefer TestCleanup over 'Dispose' methods</source>
334+
<target state="new">Prefer TestCleanup over 'Dispose' methods</target>
335+
<note />
336+
</trans-unit>
337+
<trans-unit id="PreferTestCleanupOverDisposeTitle">
338+
<source>Prefer TestCleanup over 'Dispose' methods</source>
339+
<target state="new">Prefer TestCleanup over 'Dispose' methods</target>
340+
<note />
341+
</trans-unit>
332342
<trans-unit id="PreferTestInitializeOverConstructorMessageFormat">
333343
<source>Prefer TestInitialize methods over constructors</source>
334344
<target state="new">Prefer TestInitialize methods over constructors</target>

src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf

+10
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,16 @@
329329
<target state="new">Prefer constructors over TestInitialize methods</target>
330330
<note />
331331
</trans-unit>
332+
<trans-unit id="PreferTestCleanupOverDisposeMessageFormat">
333+
<source>Prefer TestCleanup over 'Dispose' methods</source>
334+
<target state="new">Prefer TestCleanup over 'Dispose' methods</target>
335+
<note />
336+
</trans-unit>
337+
<trans-unit id="PreferTestCleanupOverDisposeTitle">
338+
<source>Prefer TestCleanup over 'Dispose' methods</source>
339+
<target state="new">Prefer TestCleanup over 'Dispose' methods</target>
340+
<note />
341+
</trans-unit>
332342
<trans-unit id="PreferTestInitializeOverConstructorMessageFormat">
333343
<source>Prefer TestInitialize methods over constructors</source>
334344
<target state="new">Prefer TestInitialize methods over constructors</target>

0 commit comments

Comments
 (0)