Skip to content
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/Analyzers/MSTest.Analyzers/AnalyzerReleases.Unshipped.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,8 @@
; Unshipped analyzer release
; https://github.com/dotnet/roslyn-analyzers/blob/main/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md

### New Rules

Rule ID | Category | Severity | Notes
--------|----------|----------|-------
MSTEST0058 | Usage | Warning | DoNotUseParallelizeAndDoNotParallelizeTogetherAnalyzer
1 change: 1 addition & 0 deletions src/Analyzers/MSTest.Analyzers/Helpers/DiagnosticIds.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,5 @@ internal static class DiagnosticIds
public const string IgnoreStringMethodReturnValueRuleId = "MSTEST0055";
public const string TestMethodAttributeShouldSetDisplayNameCorrectlyRuleId = "MSTEST0056";
public const string TestMethodAttributeShouldPropagateSourceInformationRuleId = "MSTEST0057";
public const string DoNotUseParallelizeAndDoNotParallelizeTogetherRuleId = "MSTEST0058";
}
12 changes: 12 additions & 0 deletions src/Analyzers/MSTest.Analyzers/Resources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -684,4 +684,16 @@ The type declaring these methods should also respect the following rules:
<data name="IgnoreStringMethodReturnValueDescription" xml:space="preserve">
<value>Methods like Contains, StartsWith, and EndsWith return boolean values that indicate whether the condition was met. Ignoring these return values is likely a mistake.</value>
</data>
<data name="DoNotUseParallelizeAndDoNotParallelizeTogetherTitle" xml:space="preserve">
<value>Do not use both Parallelize and DoNotParallelize attributes</value>
<comment>{Locked="Parallelize","DoNotParallelize"}</comment>
</data>
<data name="DoNotUseParallelizeAndDoNotParallelizeTogetherMessageFormat" xml:space="preserve">
<value>Assembly has both '[Parallelize]' and '[DoNotParallelize]' attributes which creates ambiguity</value>
<comment>{Locked="[Parallelize]","[DoNotParallelize]"}</comment>
</data>
<data name="DoNotUseParallelizeAndDoNotParallelizeTogetherDescription" xml:space="preserve">
<value>An assembly should have either [Parallelize] or [DoNotParallelize] attribute, but not both. Having both attributes creates an ambiguous configuration that can lead to unexpected test execution behavior.</value>
<comment>{Locked="[Parallelize]","[DoNotParallelize]"}</comment>
</data>
</root>
64 changes: 48 additions & 16 deletions src/Analyzers/MSTest.Analyzers/UseParallelizeAttributeAnalyzer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ namespace MSTest.Analyzers;

/// <summary>
/// MSTEST0001: <inheritdoc cref="Resources.UseParallelizeAttributeAnalyzerTitle"/>.
/// MSTEST0058: <inheritdoc cref="Resources.DoNotUseParallelizeAndDoNotParallelizeTogetherTitle"/>.
/// </summary>
[DiagnosticAnalyzer(LanguageNames.CSharp, LanguageNames.VisualBasic)]
public sealed class UseParallelizeAttributeAnalyzer : DiagnosticAnalyzer
Expand All @@ -22,6 +23,10 @@ public sealed class UseParallelizeAttributeAnalyzer : DiagnosticAnalyzer
private static readonly LocalizableResourceString MessageFormat = new(nameof(Resources.UseParallelizeAttributeAnalyzerMessageFormat), Resources.ResourceManager, typeof(Resources));
private static readonly LocalizableResourceString Description = new(nameof(Resources.UseParallelizeAttributeAnalyzerDescription), Resources.ResourceManager, typeof(Resources));

private static readonly LocalizableResourceString BothAttributesTitle = new(nameof(Resources.DoNotUseParallelizeAndDoNotParallelizeTogetherTitle), Resources.ResourceManager, typeof(Resources));
private static readonly LocalizableResourceString BothAttributesMessageFormat = new(nameof(Resources.DoNotUseParallelizeAndDoNotParallelizeTogetherMessageFormat), Resources.ResourceManager, typeof(Resources));
private static readonly LocalizableResourceString BothAttributesDescription = new(nameof(Resources.DoNotUseParallelizeAndDoNotParallelizeTogetherDescription), Resources.ResourceManager, typeof(Resources));

/// <inheritdoc cref="Resources.UseParallelizeAttributeAnalyzerTitle" />
public static readonly DiagnosticDescriptor Rule = DiagnosticDescriptorHelper.Create(
DiagnosticIds.UseParallelizedAttributeRuleId,
Expand All @@ -32,9 +37,19 @@ public sealed class UseParallelizeAttributeAnalyzer : DiagnosticAnalyzer
DiagnosticSeverity.Warning,
isEnabledByDefault: true);

/// <inheritdoc cref="Resources.DoNotUseParallelizeAndDoNotParallelizeTogetherTitle" />
public static readonly DiagnosticDescriptor DoNotUseBothAttributesRule = DiagnosticDescriptorHelper.Create(
DiagnosticIds.DoNotUseParallelizeAndDoNotParallelizeTogetherRuleId,
BothAttributesTitle,
BothAttributesMessageFormat,
BothAttributesDescription,
Category.Usage,
DiagnosticSeverity.Warning,
isEnabledByDefault: true);

/// <inheritdoc />
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics { get; }
= ImmutableArray.Create(Rule);
= ImmutableArray.Create(Rule, DoNotUseBothAttributesRule);

/// <inheritdoc />
public override void Initialize(AnalysisContext context)
Expand All @@ -47,35 +62,52 @@ public override void Initialize(AnalysisContext context)

private static void AnalyzeCompilation(CompilationAnalysisContext context)
{
bool hasTestAdapter = context.Options.AnalyzerConfigOptionsProvider.GlobalOptions.TryGetValue("build_property.IsMSTestTestAdapterReferenced", out string? isAdapterReferenced) &&
bool.TryParse(isAdapterReferenced, out bool isAdapterReferencedValue) &&
isAdapterReferencedValue;

if (!hasTestAdapter)
{
// We shouldn't produce a diagnostic if only the test framework is referenced, but not the adapter.
return;
}

INamedTypeSymbol? parallelizeAttributeSymbol = context.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.MicrosoftVisualStudioTestToolsUnitTestingParallelizeAttribute);
INamedTypeSymbol? doNotParallelizeAttributeSymbol = context.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.MicrosoftVisualStudioTestToolsUnitTestingDoNotParallelizeAttribute);

bool hasParallelizeAttribute = false;
bool hasDoNotParallelizeAttribute = false;
AttributeData? parallelizeAttribute = null;
AttributeData? doNotParallelizeAttribute = null;
foreach (AttributeData attribute in context.Compilation.Assembly.GetAttributes())
{
if (SymbolEqualityComparer.Default.Equals(attribute.AttributeClass, parallelizeAttributeSymbol))
{
hasParallelizeAttribute = true;
parallelizeAttribute = attribute;
}

if (SymbolEqualityComparer.Default.Equals(attribute.AttributeClass, doNotParallelizeAttributeSymbol))
{
hasDoNotParallelizeAttribute = true;
doNotParallelizeAttribute = attribute;
}
}

if (parallelizeAttribute is not null && doNotParallelizeAttribute is not null)
{
// Both attributes are present - this is an error
// Report on both attribute locations
if (parallelizeAttribute.ApplicationSyntaxReference is not null)
{
context.ReportDiagnostic(parallelizeAttribute.ApplicationSyntaxReference.CreateDiagnostic(DoNotUseBothAttributesRule, context.CancellationToken));
}

if (doNotParallelizeAttribute.ApplicationSyntaxReference is not null)
{
context.ReportDiagnostic(doNotParallelizeAttribute.ApplicationSyntaxReference.CreateDiagnostic(DoNotUseBothAttributesRule, context.CancellationToken));
}

return;
}

bool hasTestAdapter = context.Options.AnalyzerConfigOptionsProvider.GlobalOptions.TryGetValue("build_property.IsMSTestTestAdapterReferenced", out string? isAdapterReferenced) &&
bool.TryParse(isAdapterReferenced, out bool isAdapterReferencedValue) &&
isAdapterReferencedValue;

if (!hasTestAdapter)
{
// We shouldn't produce a diagnostic if only the test framework is referenced, but not the adapter.
return;
}

if (!hasParallelizeAttribute && !hasDoNotParallelizeAttribute)
if (parallelizeAttribute is null && doNotParallelizeAttribute is null)
{
// We cannot provide any good location for assembly level missing attributes
context.ReportNoLocationDiagnostic(Rule);
Expand Down
15 changes: 15 additions & 0 deletions src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -989,6 +989,21 @@ Typ deklarující tyto metody by měl také respektovat následující pravidla:
<target state="translated">Parametr Assert.Throws by měl obsahovat jenom jeden příkaz nebo výraz</target>
<note />
</trans-unit>
<trans-unit id="DoNotUseParallelizeAndDoNotParallelizeTogetherDescription">
<source>An assembly should have either [Parallelize] or [DoNotParallelize] attribute, but not both. Having both attributes creates an ambiguous configuration that can lead to unexpected test execution behavior.</source>
<target state="new">An assembly should have either [Parallelize] or [DoNotParallelize] attribute, but not both. Having both attributes creates an ambiguous configuration that can lead to unexpected test execution behavior.</target>
<note />
</trans-unit>
<trans-unit id="DoNotUseParallelizeAndDoNotParallelizeTogetherMessageFormat">
<source>Assembly has both [Parallelize] and [DoNotParallelize] attributes which creates ambiguity</source>
<target state="new">Assembly has both [Parallelize] and [DoNotParallelize] attributes which creates ambiguity</target>
<note />
</trans-unit>
<trans-unit id="DoNotUseParallelizeAndDoNotParallelizeTogetherTitle">
<source>Do not use both Parallelize and DoNotParallelize attributes</source>
<target state="new">Do not use both Parallelize and DoNotParallelize attributes</target>
<note />
</trans-unit>
</body>
</file>
</xliff>
15 changes: 15 additions & 0 deletions src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -990,6 +990,21 @@ Der Typ, der diese Methoden deklariert, sollte auch die folgenden Regeln beachte
<target state="translated">Assert.Throws darf nur eine einzelne Anweisung/einen einzelnen Ausdruck enthalten</target>
<note />
</trans-unit>
<trans-unit id="DoNotUseParallelizeAndDoNotParallelizeTogetherDescription">
<source>An assembly should have either [Parallelize] or [DoNotParallelize] attribute, but not both. Having both attributes creates an ambiguous configuration that can lead to unexpected test execution behavior.</source>
<target state="new">An assembly should have either [Parallelize] or [DoNotParallelize] attribute, but not both. Having both attributes creates an ambiguous configuration that can lead to unexpected test execution behavior.</target>
<note />
</trans-unit>
<trans-unit id="DoNotUseParallelizeAndDoNotParallelizeTogetherMessageFormat">
<source>Assembly has both [Parallelize] and [DoNotParallelize] attributes which creates ambiguity</source>
<target state="new">Assembly has both [Parallelize] and [DoNotParallelize] attributes which creates ambiguity</target>
<note />
</trans-unit>
<trans-unit id="DoNotUseParallelizeAndDoNotParallelizeTogetherTitle">
<source>Do not use both Parallelize and DoNotParallelize attributes</source>
<target state="new">Do not use both Parallelize and DoNotParallelize attributes</target>
<note />
</trans-unit>
</body>
</file>
</xliff>
15 changes: 15 additions & 0 deletions src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -989,6 +989,21 @@ El tipo que declara estos métodos también debe respetar las reglas siguientes:
<target state="translated">Assert.Throws debe contener solo una única instrucción o expresión</target>
<note />
</trans-unit>
<trans-unit id="DoNotUseParallelizeAndDoNotParallelizeTogetherDescription">
<source>An assembly should have either [Parallelize] or [DoNotParallelize] attribute, but not both. Having both attributes creates an ambiguous configuration that can lead to unexpected test execution behavior.</source>
<target state="new">An assembly should have either [Parallelize] or [DoNotParallelize] attribute, but not both. Having both attributes creates an ambiguous configuration that can lead to unexpected test execution behavior.</target>
<note />
</trans-unit>
<trans-unit id="DoNotUseParallelizeAndDoNotParallelizeTogetherMessageFormat">
<source>Assembly has both [Parallelize] and [DoNotParallelize] attributes which creates ambiguity</source>
<target state="new">Assembly has both [Parallelize] and [DoNotParallelize] attributes which creates ambiguity</target>
<note />
</trans-unit>
<trans-unit id="DoNotUseParallelizeAndDoNotParallelizeTogetherTitle">
<source>Do not use both Parallelize and DoNotParallelize attributes</source>
<target state="new">Do not use both Parallelize and DoNotParallelize attributes</target>
<note />
</trans-unit>
</body>
</file>
</xliff>
15 changes: 15 additions & 0 deletions src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -989,6 +989,21 @@ Le type doit être une classe
<target state="translated">Assert.Throws ne doit contenir qu’une seule instruction</target>
<note />
</trans-unit>
<trans-unit id="DoNotUseParallelizeAndDoNotParallelizeTogetherDescription">
<source>An assembly should have either [Parallelize] or [DoNotParallelize] attribute, but not both. Having both attributes creates an ambiguous configuration that can lead to unexpected test execution behavior.</source>
<target state="new">An assembly should have either [Parallelize] or [DoNotParallelize] attribute, but not both. Having both attributes creates an ambiguous configuration that can lead to unexpected test execution behavior.</target>
<note />
</trans-unit>
<trans-unit id="DoNotUseParallelizeAndDoNotParallelizeTogetherMessageFormat">
<source>Assembly has both [Parallelize] and [DoNotParallelize] attributes which creates ambiguity</source>
<target state="new">Assembly has both [Parallelize] and [DoNotParallelize] attributes which creates ambiguity</target>
<note />
</trans-unit>
<trans-unit id="DoNotUseParallelizeAndDoNotParallelizeTogetherTitle">
<source>Do not use both Parallelize and DoNotParallelize attributes</source>
<target state="new">Do not use both Parallelize and DoNotParallelize attributes</target>
<note />
</trans-unit>
</body>
</file>
</xliff>
15 changes: 15 additions & 0 deletions src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -989,6 +989,21 @@ Anche il tipo che dichiara questi metodi deve rispettare le regole seguenti:
<target state="translated">Assert.Throws deve contenere solo una singola istruzione/espressione</target>
<note />
</trans-unit>
<trans-unit id="DoNotUseParallelizeAndDoNotParallelizeTogetherDescription">
<source>An assembly should have either [Parallelize] or [DoNotParallelize] attribute, but not both. Having both attributes creates an ambiguous configuration that can lead to unexpected test execution behavior.</source>
<target state="new">An assembly should have either [Parallelize] or [DoNotParallelize] attribute, but not both. Having both attributes creates an ambiguous configuration that can lead to unexpected test execution behavior.</target>
<note />
</trans-unit>
<trans-unit id="DoNotUseParallelizeAndDoNotParallelizeTogetherMessageFormat">
<source>Assembly has both [Parallelize] and [DoNotParallelize] attributes which creates ambiguity</source>
<target state="new">Assembly has both [Parallelize] and [DoNotParallelize] attributes which creates ambiguity</target>
<note />
</trans-unit>
<trans-unit id="DoNotUseParallelizeAndDoNotParallelizeTogetherTitle">
<source>Do not use both Parallelize and DoNotParallelize attributes</source>
<target state="new">Do not use both Parallelize and DoNotParallelize attributes</target>
<note />
</trans-unit>
</body>
</file>
</xliff>
15 changes: 15 additions & 0 deletions src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -989,6 +989,21 @@ The type declaring these methods should also respect the following rules:
<target state="translated">Assert.Throws には 1 つのステートメントまたは式のみを含める必要があります</target>
<note />
</trans-unit>
<trans-unit id="DoNotUseParallelizeAndDoNotParallelizeTogetherDescription">
<source>An assembly should have either [Parallelize] or [DoNotParallelize] attribute, but not both. Having both attributes creates an ambiguous configuration that can lead to unexpected test execution behavior.</source>
<target state="new">An assembly should have either [Parallelize] or [DoNotParallelize] attribute, but not both. Having both attributes creates an ambiguous configuration that can lead to unexpected test execution behavior.</target>
<note />
</trans-unit>
<trans-unit id="DoNotUseParallelizeAndDoNotParallelizeTogetherMessageFormat">
<source>Assembly has both [Parallelize] and [DoNotParallelize] attributes which creates ambiguity</source>
<target state="new">Assembly has both [Parallelize] and [DoNotParallelize] attributes which creates ambiguity</target>
<note />
</trans-unit>
<trans-unit id="DoNotUseParallelizeAndDoNotParallelizeTogetherTitle">
<source>Do not use both Parallelize and DoNotParallelize attributes</source>
<target state="new">Do not use both Parallelize and DoNotParallelize attributes</target>
<note />
</trans-unit>
</body>
</file>
</xliff>
15 changes: 15 additions & 0 deletions src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -989,6 +989,21 @@ The type declaring these methods should also respect the following rules:
<target state="translated">Assert.Throws는 단일 문/식만 포함해야 합니다.</target>
<note />
</trans-unit>
<trans-unit id="DoNotUseParallelizeAndDoNotParallelizeTogetherDescription">
<source>An assembly should have either [Parallelize] or [DoNotParallelize] attribute, but not both. Having both attributes creates an ambiguous configuration that can lead to unexpected test execution behavior.</source>
<target state="new">An assembly should have either [Parallelize] or [DoNotParallelize] attribute, but not both. Having both attributes creates an ambiguous configuration that can lead to unexpected test execution behavior.</target>
<note />
</trans-unit>
<trans-unit id="DoNotUseParallelizeAndDoNotParallelizeTogetherMessageFormat">
<source>Assembly has both [Parallelize] and [DoNotParallelize] attributes which creates ambiguity</source>
<target state="new">Assembly has both [Parallelize] and [DoNotParallelize] attributes which creates ambiguity</target>
<note />
</trans-unit>
<trans-unit id="DoNotUseParallelizeAndDoNotParallelizeTogetherTitle">
<source>Do not use both Parallelize and DoNotParallelize attributes</source>
<target state="new">Do not use both Parallelize and DoNotParallelize attributes</target>
<note />
</trans-unit>
</body>
</file>
</xliff>
Loading
Loading