diff --git a/build/targets/codeanalysis/.globalconfig b/build/targets/codeanalysis/.globalconfig
index 0b6e8efa..2106bae7 100644
--- a/build/targets/codeanalysis/.globalconfig
+++ b/build/targets/codeanalysis/.globalconfig
@@ -7,3 +7,24 @@ is_global=true
# AV2210 : Pass -warnaserror to the compiler or add True to your project file
# This is set as part of the CI build. It is intentionally not set locally to allow for a fast inner dev loop.
dotnet_diagnostic.AV2210.severity = none
+
+# Enable Effective C# Analyzers
+dotnet_diagnostic.ECS0100.severity = warning
+dotnet_diagnostic.ECS0200.severity = warning
+dotnet_diagnostic.ECS0300.severity = warning
+dotnet_diagnostic.ECS0400.severity = warning
+dotnet_diagnostic.ECS0500.severity = warning
+dotnet_diagnostic.ECS0600.severity = warning
+dotnet_diagnostic.ECS0700.severity = warning
+dotnet_diagnostic.ECS0800.severity = warning
+dotnet_diagnostic.ECS0900.severity = warning
+dotnet_diagnostic.ECS1000.severity = warning
+dotnet_diagnostic.ECS1100.severity = warning
+dotnet_diagnostic.ECS1200.severity = warning
+dotnet_diagnostic.ECS1300.severity = warning
+dotnet_diagnostic.ECS1400.severity = warning
+dotnet_diagnostic.ECS1500.severity = warning
+dotnet_diagnostic.ECS1600.severity = warning
+dotnet_diagnostic.ECS1700.severity = warning
+dotnet_diagnostic.ECS1800.severity = warning
+dotnet_diagnostic.ECS1900.severity = warning
diff --git a/build/targets/codeanalysis/CodeAnalysis.props b/build/targets/codeanalysis/CodeAnalysis.props
index e83bbdce..fdd66631 100644
--- a/build/targets/codeanalysis/CodeAnalysis.props
+++ b/build/targets/codeanalysis/CodeAnalysis.props
@@ -39,5 +39,9 @@
runtime; build; native; contentfiles; analyzers; buildtransitive
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
diff --git a/build/targets/codeanalysis/Packages.props b/build/targets/codeanalysis/Packages.props
index b490b5b8..04febe30 100644
--- a/build/targets/codeanalysis/Packages.props
+++ b/build/targets/codeanalysis/Packages.props
@@ -8,5 +8,6 @@
+
diff --git a/src/Moq.Analyzers/AsShouldBeUsedOnlyForInterfaceAnalyzer.cs b/src/Moq.Analyzers/AsShouldBeUsedOnlyForInterfaceAnalyzer.cs
index fcaecd1f..c5f8bedb 100644
--- a/src/Moq.Analyzers/AsShouldBeUsedOnlyForInterfaceAnalyzer.cs
+++ b/src/Moq.Analyzers/AsShouldBeUsedOnlyForInterfaceAnalyzer.cs
@@ -8,8 +8,8 @@ namespace Moq.Analyzers;
[DiagnosticAnalyzer(LanguageNames.CSharp)]
public class AsShouldBeUsedOnlyForInterfaceAnalyzer : DiagnosticAnalyzer
{
- private const string Title = "Moq: Invalid As type parameter";
- private const string Message = "Mock.As() should take interfaces only";
+ private static readonly LocalizableString Title = "Moq: Invalid As type parameter";
+ private static readonly LocalizableString Message = "Mock.As() should take interfaces only";
private static readonly DiagnosticDescriptor Rule = new(
DiagnosticIds.AsShouldOnlyBeUsedForInterfacesRuleId,
@@ -42,11 +42,13 @@ private static void RegisterCompilationStartAction(CompilationStartAnalysisConte
}
// Look for the Mock.As() method and provide it to Analyze to avoid looking it up multiple times.
+#pragma warning disable ECS0900 // Minimize boxing and unboxing
ImmutableArray asMethods = mockTypes
.SelectMany(mockType => mockType.GetMembers(WellKnownTypeNames.As))
.OfType()
.Where(method => method.IsGenericMethod)
.ToImmutableArray();
+#pragma warning restore ECS0900 // Minimize boxing and unboxing
if (asMethods.IsEmpty)
{
@@ -66,10 +68,12 @@ private static void Analyze(OperationAnalysisContext context, ImmutableArray typeArguments = targetMethod.TypeArguments;
if (typeArguments.Length != 1)
diff --git a/src/Moq.Analyzers/CallbackSignatureShouldMatchMockedMethodAnalyzer.cs b/src/Moq.Analyzers/CallbackSignatureShouldMatchMockedMethodAnalyzer.cs
index 90a4d0e0..ead2b873 100644
--- a/src/Moq.Analyzers/CallbackSignatureShouldMatchMockedMethodAnalyzer.cs
+++ b/src/Moq.Analyzers/CallbackSignatureShouldMatchMockedMethodAnalyzer.cs
@@ -6,24 +6,20 @@ namespace Moq.Analyzers;
[DiagnosticAnalyzer(LanguageNames.CSharp)]
public class CallbackSignatureShouldMatchMockedMethodAnalyzer : DiagnosticAnalyzer
{
- internal const string RuleId = DiagnosticIds.BadCallbackParameters;
- private const string Title = "Moq: Bad callback parameters";
- private const string Message = "Callback signature must match the signature of the mocked method";
+ private static readonly LocalizableString Title = "Moq: Bad callback parameters";
+ private static readonly LocalizableString Message = "Callback signature must match the signature of the mocked method";
private static readonly DiagnosticDescriptor Rule = new(
- RuleId,
+ DiagnosticIds.BadCallbackParameters,
Title,
Message,
DiagnosticCategory.Moq,
DiagnosticSeverity.Warning,
isEnabledByDefault: true,
- helpLinkUri: $"https://github.com/rjmurillo/moq.analyzers/blob/{ThisAssembly.GitCommitId}/docs/rules/{RuleId}.md");
+ helpLinkUri: $"https://github.com/rjmurillo/moq.analyzers/blob/{ThisAssembly.GitCommitId}/docs/rules/{DiagnosticIds.BadCallbackParameters}.md");
///
- public override ImmutableArray SupportedDiagnostics
- {
- get { return ImmutableArray.Create(Rule); }
- }
+ public override ImmutableArray SupportedDiagnostics { get; } = ImmutableArray.Create(Rule);
///
public override void Initialize(AnalysisContext context)
diff --git a/src/Moq.Analyzers/CallbackSignatureShouldMatchMockedMethodCodeFix.cs b/src/Moq.Analyzers/CallbackSignatureShouldMatchMockedMethodCodeFix.cs
index d84e6b2d..7afedde0 100644
--- a/src/Moq.Analyzers/CallbackSignatureShouldMatchMockedMethodCodeFix.cs
+++ b/src/Moq.Analyzers/CallbackSignatureShouldMatchMockedMethodCodeFix.cs
@@ -14,16 +14,10 @@ namespace Moq.Analyzers;
public class CallbackSignatureShouldMatchMockedMethodCodeFix : CodeFixProvider
{
///
- public sealed override ImmutableArray FixableDiagnosticIds
- {
- get { return ImmutableArray.Create(CallbackSignatureShouldMatchMockedMethodAnalyzer.RuleId); }
- }
+ public sealed override ImmutableArray FixableDiagnosticIds => ImmutableArray.Create(DiagnosticIds.BadCallbackParameters);
///
- public sealed override FixAllProvider GetFixAllProvider()
- {
- return WellKnownFixAllProviders.BatchFixer;
- }
+ public sealed override FixAllProvider GetFixAllProvider() => WellKnownFixAllProviders.BatchFixer;
///
public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
diff --git a/src/Moq.Analyzers/Common/ArrayExtensions.cs b/src/Moq.Analyzers/Common/ArrayExtensions.cs
new file mode 100644
index 00000000..eb19cfa0
--- /dev/null
+++ b/src/Moq.Analyzers/Common/ArrayExtensions.cs
@@ -0,0 +1,53 @@
+using ArgumentOutOfRangeException = System.ArgumentOutOfRangeException;
+
+namespace Moq.Analyzers.Common;
+
+internal static class ArrayExtensions
+{
+ ///
+ /// Returns an array with the element at the specified position removed.
+ ///
+ /// The array type.
+ /// The array.
+ /// The 0-based index into the array for the element to omit from the returned array.
+ /// The new array.
+ internal static T[] RemoveAt(this T[] array, int index)
+ {
+ return RemoveRange(array, index, 1);
+ }
+
+ ///
+ /// Returns an array with the elements at the specified position removed.
+ ///
+ /// The array type.
+ /// The array.
+ /// The 0-based index into the array for the element to omit from the returned array.
+ /// The number of elements to remove.
+ /// The new array.
+ private static T[] RemoveRange(this T[] array, int index, int length)
+ {
+ // Range check
+ if (index < 0 || index >= array.Length)
+ {
+ throw new ArgumentOutOfRangeException(nameof(index));
+ }
+
+ if (length < 0 || index + length > array.Length)
+ {
+ throw new ArgumentOutOfRangeException(nameof(length));
+ }
+
+#pragma warning disable S2583 // Change condition so it doesn't always evaluate to false
+ if (array.Length == 0)
+#pragma warning restore S2583
+ {
+ return array;
+ }
+
+ T[] tmp = new T[array.Length - length];
+ Array.Copy(array, tmp, index);
+ Array.Copy(array, index + length, tmp, index, array.Length - index - length);
+
+ return tmp;
+ }
+}
diff --git a/src/Moq.Analyzers/Common/DiagnosticCategory.cs b/src/Moq.Analyzers/Common/DiagnosticCategory.cs
index 34f922e0..9907bdc1 100644
--- a/src/Moq.Analyzers/Common/DiagnosticCategory.cs
+++ b/src/Moq.Analyzers/Common/DiagnosticCategory.cs
@@ -1,5 +1,7 @@
namespace Moq.Analyzers.Common;
+#pragma warning disable ECS0200 // Consider using readonly instead of const for flexibility
+
internal static class DiagnosticCategory
{
internal const string Moq = nameof(Moq);
diff --git a/src/Moq.Analyzers/Common/DiagnosticExtensions.cs b/src/Moq.Analyzers/Common/DiagnosticExtensions.cs
index 596d9a8e..562ac267 100644
--- a/src/Moq.Analyzers/Common/DiagnosticExtensions.cs
+++ b/src/Moq.Analyzers/Common/DiagnosticExtensions.cs
@@ -13,12 +13,12 @@ public static Diagnostic CreateDiagnostic(
DiagnosticDescriptor rule,
ImmutableDictionary? properties,
params object?[]? messageArgs)
- => node.CreateDiagnostic(rule, additionalLocations: ImmutableArray.Empty, properties, messageArgs);
+ => node.CreateDiagnostic(rule, additionalLocations: Array.Empty(), properties, messageArgs);
public static Diagnostic CreateDiagnostic(
this SyntaxNode node,
DiagnosticDescriptor rule,
- ImmutableArray additionalLocations,
+ IEnumerable? additionalLocations,
ImmutableDictionary? properties,
params object?[]? messageArgs)
=> node
@@ -44,12 +44,12 @@ public static Diagnostic CreateDiagnostic(
DiagnosticDescriptor rule,
ImmutableDictionary? properties,
params object?[]? messageArgs)
- => location.CreateDiagnostic(rule, ImmutableArray.Empty, properties, messageArgs);
+ => location.CreateDiagnostic(rule, Array.Empty(), properties, messageArgs);
public static Diagnostic CreateDiagnostic(
this Location location,
DiagnosticDescriptor rule,
- ImmutableArray additionalLocations,
+ IEnumerable? additionalLocations,
ImmutableDictionary? properties,
params object?[]? messageArgs)
{
diff --git a/src/Moq.Analyzers/Common/DiagnosticIds.cs b/src/Moq.Analyzers/Common/DiagnosticIds.cs
index 9807c038..8e143e18 100644
--- a/src/Moq.Analyzers/Common/DiagnosticIds.cs
+++ b/src/Moq.Analyzers/Common/DiagnosticIds.cs
@@ -1,5 +1,7 @@
namespace Moq.Analyzers.Common;
+#pragma warning disable ECS0200 // Consider using readonly instead of const for flexibility
+
internal static class DiagnosticIds
{
internal const string SealedClassCannotBeMocked = "Moq1000";
diff --git a/src/Moq.Analyzers/Common/MoqMethodDescriptorBase.cs b/src/Moq.Analyzers/Common/MoqMethodDescriptorBase.cs
index 7111ad57..26392264 100644
--- a/src/Moq.Analyzers/Common/MoqMethodDescriptorBase.cs
+++ b/src/Moq.Analyzers/Common/MoqMethodDescriptorBase.cs
@@ -11,28 +11,16 @@
///
internal abstract class MoqMethodDescriptorBase
{
- private const string ContainingNamespace = WellKnownTypeNames.Moq;
- private const string ContainingType = WellKnownTypeNames.MockName;
+ private static readonly string ContainingNamespace = WellKnownTypeNames.Moq;
+ private static readonly string ContainingType = WellKnownTypeNames.MockName;
public abstract bool IsMatch(SemanticModel semanticModel, MemberAccessExpressionSyntax memberAccessSyntax, CancellationToken cancellationToken);
- protected static bool IsFastMatch(MemberAccessExpressionSyntax memberAccessSyntax, ReadOnlySpan methodName)
- {
- return memberAccessSyntax.Name.Identifier.Text.AsSpan().SequenceEqual(methodName);
- }
+ protected static bool IsFastMatch(MemberAccessExpressionSyntax memberAccessSyntax, ReadOnlySpan methodName) => memberAccessSyntax.Name.Identifier.Text.AsSpan().SequenceEqual(methodName);
- protected static bool IsContainedInMockType(IMethodSymbol methodSymbol)
- {
- return IsInMoqNamespace(methodSymbol) && IsInMockType(methodSymbol);
- }
+ protected static bool IsContainedInMockType(IMethodSymbol methodSymbol) => IsInMoqNamespace(methodSymbol) && IsInMockType(methodSymbol);
- private static bool IsInMoqNamespace(ISymbol symbol)
- {
- return symbol.ContainingNamespace.Name.AsSpan().SequenceEqual(ContainingNamespace.AsSpan());
- }
+ private static bool IsInMoqNamespace(ISymbol symbol) => symbol.ContainingNamespace.Name.AsSpan().SequenceEqual(ContainingNamespace.AsSpan());
- private static bool IsInMockType(ISymbol symbol)
- {
- return symbol.ContainingType.Name.AsSpan().SequenceEqual(ContainingType.AsSpan());
- }
+ private static bool IsInMockType(ISymbol symbol) => symbol.ContainingType.Name.AsSpan().SequenceEqual(ContainingType.AsSpan());
}
diff --git a/src/Moq.Analyzers/Common/WellKnownTypeNames.cs b/src/Moq.Analyzers/Common/WellKnownTypeNames.cs
index 4ebeeb8f..e47bc65d 100644
--- a/src/Moq.Analyzers/Common/WellKnownTypeNames.cs
+++ b/src/Moq.Analyzers/Common/WellKnownTypeNames.cs
@@ -1,16 +1,18 @@
namespace Moq.Analyzers.Common;
+#pragma warning disable ECS0200 // Consider using readonly instead of const for flexibility
+
internal static class WellKnownTypeNames
{
- internal const string Moq = "Moq";
+ internal const string Moq = nameof(Moq);
internal const string MockName = "Mock";
- internal const string MockBehavior = "MockBehavior";
- internal const string MockFactory = "MockFactory";
+ internal const string MockBehavior = nameof(MockBehavior);
+ internal const string MockFactory = nameof(MockFactory);
internal const string MoqMock = $"{Moq}.{MockName}";
internal const string MoqMock1 = $"{MoqMock}`1";
internal const string MoqBehavior = $"{Moq}.{MockBehavior}";
internal const string MoqRepository = $"{Moq}.MockRepository";
- internal const string As = "As";
- internal const string Create = "Create";
- internal const string Of = "Of";
+ internal const string As = nameof(As);
+ internal const string Create = nameof(Create);
+ internal const string Of = nameof(Of);
}
diff --git a/src/Moq.Analyzers/ConstructorArgumentsShouldMatchAnalyzer.cs b/src/Moq.Analyzers/ConstructorArgumentsShouldMatchAnalyzer.cs
index 5c9c23e8..5b89efa5 100644
--- a/src/Moq.Analyzers/ConstructorArgumentsShouldMatchAnalyzer.cs
+++ b/src/Moq.Analyzers/ConstructorArgumentsShouldMatchAnalyzer.cs
@@ -132,7 +132,7 @@ private static bool IsFirstArgumentMockBehavior(SyntaxNodeAnalysisContext contex
private static void VerifyDelegateMockAttempt(
SyntaxNodeAnalysisContext context,
ArgumentListSyntax? argumentList,
- ImmutableArray arguments)
+ ArgumentSyntax[] arguments)
{
if (arguments.Length == 0)
{
@@ -149,7 +149,7 @@ private static void VerifyDelegateMockAttempt(
private static void VerifyInterfaceMockAttempt(
SyntaxNodeAnalysisContext context,
ArgumentListSyntax? argumentList,
- ImmutableArray arguments)
+ ArgumentSyntax[] arguments)
{
// Interfaces and delegates don't have ctors, so bail out early
if (arguments.Length == 0)
@@ -322,8 +322,8 @@ private static void AnalyzeNewObject(SyntaxNodeAnalysisContext context)
/// Handles and optional parameters.
[SuppressMessage("Design", "MA0051:Method is too long", Justification = "This should be refactored; suppressing for now to enable TreatWarningsAsErrors in CI.")]
private static bool AnyConstructorsFound(
- ImmutableArray constructors,
- ImmutableArray arguments,
+ IMethodSymbol[] constructors,
+ ArgumentSyntax[] arguments,
SyntaxNodeAnalysisContext context)
{
for (int constructorIndex = 0; constructorIndex < constructors.Length; constructorIndex++)
@@ -331,7 +331,9 @@ private static bool AnyConstructorsFound(
IMethodSymbol constructor = constructors[constructorIndex];
bool hasParams = constructor.Parameters.Length > 0 && constructor.Parameters[^1].IsParams;
int fixedParametersCount = hasParams ? constructor.Parameters.Length - 1 : constructor.Parameters.Length;
+#pragma warning disable ECS0900 // Consider using an alternative implementation to avoid boxing and unboxing
int requiredParameters = constructor.Parameters.Count(parameterSymbol => !parameterSymbol.IsOptional);
+#pragma warning restore ECS0900 // Consider using an alternative implementation to avoid boxing and unboxing
bool allParametersMatch = true;
// Check if the number of arguments is valid considering params
@@ -401,7 +403,7 @@ private static bool AnyConstructorsFound(
}
private static (bool IsEmpty, Location Location) ConstructorIsEmpty(
- ImmutableArray constructors,
+ IMethodSymbol[] constructors,
ArgumentListSyntax? argumentList,
SyntaxNodeAnalysisContext context)
{
@@ -416,7 +418,7 @@ private static (bool IsEmpty, Location Location) ConstructorIsEmpty(
location = context.Node.GetLocation();
}
- return (constructors.IsEmpty, location);
+ return (constructors.Length == 0, location);
}
private static void VerifyMockAttempt(
@@ -430,9 +432,9 @@ private static void VerifyMockAttempt(
return;
}
- ImmutableArray arguments =
- argumentList?.Arguments.ToImmutableArray()
- ?? ImmutableArray.Empty;
+#pragma warning disable ECS0900 // Consider using an alternative implementation to avoid boxing and unboxing
+ ArgumentSyntax[] arguments = argumentList?.Arguments.ToArray() ?? [];
+#pragma warning restore ECS0900 // Consider using an alternative implementation to avoid boxing and unboxing
if (hasMockBehavior && arguments.Length > 0 && IsFirstArgumentMockBehavior(context, argumentList))
{
@@ -463,13 +465,13 @@ private static void VerifyClassMockAttempt(
SyntaxNodeAnalysisContext context,
ITypeSymbol mockedClass,
ArgumentListSyntax? argumentList,
- ImmutableArray arguments)
+ ArgumentSyntax[] arguments)
{
- ImmutableArray constructors = mockedClass
+ IMethodSymbol[] constructors = mockedClass
.GetMembers()
.OfType()
.Where(methodSymbol => methodSymbol.IsConstructor())
- .ToImmutableArray();
+ .ToArray();
// Bail out early if there are no arguments on constructors or no constructors at all
(bool IsEmpty, Location Location) constructorIsEmpty = ConstructorIsEmpty(constructors, argumentList, context);
diff --git a/src/Moq.Analyzers/MoqSetupMethodDescriptor.cs b/src/Moq.Analyzers/MoqSetupMethodDescriptor.cs
index 9ca4f1ad..ee81d8dc 100644
--- a/src/Moq.Analyzers/MoqSetupMethodDescriptor.cs
+++ b/src/Moq.Analyzers/MoqSetupMethodDescriptor.cs
@@ -6,7 +6,7 @@
///
internal class MoqSetupMethodDescriptor : MoqMethodDescriptorBase
{
- private const string MethodName = "Setup";
+ private static readonly string MethodName = "Setup";
[System.Diagnostics.CodeAnalysis.SuppressMessage("Maintainability", "AV1500:Member or local function contains too many statements", Justification = "Tracked in https://github.com/rjmurillo/moq.analyzers/issues/90")]
public override bool IsMatch(SemanticModel semanticModel, MemberAccessExpressionSyntax memberAccessSyntax, CancellationToken cancellationToken)
diff --git a/src/Moq.Analyzers/NoMethodsInPropertySetupAnalyzer.cs b/src/Moq.Analyzers/NoMethodsInPropertySetupAnalyzer.cs
index c5d8cfbf..c5545803 100644
--- a/src/Moq.Analyzers/NoMethodsInPropertySetupAnalyzer.cs
+++ b/src/Moq.Analyzers/NoMethodsInPropertySetupAnalyzer.cs
@@ -6,18 +6,17 @@ namespace Moq.Analyzers;
[DiagnosticAnalyzer(LanguageNames.CSharp)]
public class NoMethodsInPropertySetupAnalyzer : DiagnosticAnalyzer
{
- internal const string RuleId = DiagnosticIds.PropertySetupUsedForMethod;
- private const string Title = "Moq: Property setup used for a method";
- private const string Message = "SetupGet/SetupSet should be used for properties, not for methods";
+ private static readonly LocalizableString Title = "Moq: Property setup used for a method";
+ private static readonly LocalizableString Message = "SetupGet/SetupSet should be used for properties, not for methods";
private static readonly DiagnosticDescriptor Rule = new(
- RuleId,
+ DiagnosticIds.PropertySetupUsedForMethod,
Title,
Message,
DiagnosticCategory.Moq,
DiagnosticSeverity.Warning,
isEnabledByDefault: true,
- helpLinkUri: $"https://github.com/rjmurillo/moq.analyzers/blob/{ThisAssembly.GitCommitId}/docs/rules/{RuleId}.md");
+ helpLinkUri: $"https://github.com/rjmurillo/moq.analyzers/blob/{ThisAssembly.GitCommitId}/docs/rules/{DiagnosticIds.PropertySetupUsedForMethod}.md");
///
public override ImmutableArray SupportedDiagnostics { get; } = ImmutableArray.Create(Rule);
diff --git a/src/Moq.Analyzers/NoSealedClassMocksAnalyzer.cs b/src/Moq.Analyzers/NoSealedClassMocksAnalyzer.cs
index b44d616e..63642004 100644
--- a/src/Moq.Analyzers/NoSealedClassMocksAnalyzer.cs
+++ b/src/Moq.Analyzers/NoSealedClassMocksAnalyzer.cs
@@ -6,18 +6,17 @@ namespace Moq.Analyzers;
[DiagnosticAnalyzer(LanguageNames.CSharp)]
public class NoSealedClassMocksAnalyzer : DiagnosticAnalyzer
{
- internal const string RuleId = DiagnosticIds.SealedClassCannotBeMocked;
- private const string Title = "Moq: Sealed class mocked";
- private const string Message = "Sealed classes cannot be mocked";
+ private static readonly LocalizableString Title = "Moq: Sealed class mocked";
+ private static readonly LocalizableString Message = "Sealed classes cannot be mocked";
private static readonly DiagnosticDescriptor Rule = new(
- RuleId,
+ DiagnosticIds.SealedClassCannotBeMocked,
Title,
Message,
DiagnosticCategory.Moq,
DiagnosticSeverity.Warning,
isEnabledByDefault: true,
- helpLinkUri: $"https://github.com/rjmurillo/moq.analyzers/blob/{ThisAssembly.GitCommitId}/docs/rules/{RuleId}.md");
+ helpLinkUri: $"https://github.com/rjmurillo/moq.analyzers/blob/{ThisAssembly.GitCommitId}/docs/rules/{DiagnosticIds.SealedClassCannotBeMocked}.md");
///
public override ImmutableArray SupportedDiagnostics { get; } = ImmutableArray.Create(Rule);
diff --git a/src/Moq.Analyzers/SetupShouldBeUsedOnlyForOverridableMembersAnalyzer.cs b/src/Moq.Analyzers/SetupShouldBeUsedOnlyForOverridableMembersAnalyzer.cs
index 6d851eda..9e058440 100644
--- a/src/Moq.Analyzers/SetupShouldBeUsedOnlyForOverridableMembersAnalyzer.cs
+++ b/src/Moq.Analyzers/SetupShouldBeUsedOnlyForOverridableMembersAnalyzer.cs
@@ -6,18 +6,17 @@ namespace Moq.Analyzers;
[DiagnosticAnalyzer(LanguageNames.CSharp)]
public class SetupShouldBeUsedOnlyForOverridableMembersAnalyzer : DiagnosticAnalyzer
{
- internal const string RuleId = DiagnosticIds.SetupOnlyUsedForOverridableMembers;
- private const string Title = "Moq: Invalid setup parameter";
- private const string Message = "Setup should be used only for overridable members";
+ private static readonly LocalizableString Title = "Moq: Invalid setup parameter";
+ private static readonly LocalizableString Message = "Setup should be used only for overridable members";
private static readonly DiagnosticDescriptor Rule = new(
- RuleId,
+ DiagnosticIds.SetupOnlyUsedForOverridableMembers,
Title,
Message,
DiagnosticCategory.Moq,
DiagnosticSeverity.Error,
isEnabledByDefault: true,
- helpLinkUri: $"https://github.com/rjmurillo/moq.analyzers/blob/{ThisAssembly.GitCommitId}/docs/rules/{RuleId}.md");
+ helpLinkUri: $"https://github.com/rjmurillo/moq.analyzers/blob/{ThisAssembly.GitCommitId}/docs/rules/{DiagnosticIds.SetupOnlyUsedForOverridableMembers}.md");
///
public override ImmutableArray SupportedDiagnostics { get; } = ImmutableArray.Create(Rule);
diff --git a/src/Moq.Analyzers/SetupShouldNotIncludeAsyncResultAnalyzer.cs b/src/Moq.Analyzers/SetupShouldNotIncludeAsyncResultAnalyzer.cs
index 642bf63d..8489fabd 100644
--- a/src/Moq.Analyzers/SetupShouldNotIncludeAsyncResultAnalyzer.cs
+++ b/src/Moq.Analyzers/SetupShouldNotIncludeAsyncResultAnalyzer.cs
@@ -6,18 +6,17 @@
[DiagnosticAnalyzer(LanguageNames.CSharp)]
public class SetupShouldNotIncludeAsyncResultAnalyzer : DiagnosticAnalyzer
{
- internal const string RuleId = DiagnosticIds.AsyncUsesReturnsAsyncInsteadOfResult;
- private const string Title = "Moq: Invalid setup parameter";
- private const string Message = "Setup of async methods should use ReturnsAsync instead of .Result";
+ private static readonly LocalizableString Title = "Moq: Invalid setup parameter";
+ private static readonly LocalizableString Message = "Setup of async methods should use ReturnsAsync instead of .Result";
private static readonly DiagnosticDescriptor Rule = new(
- RuleId,
+ DiagnosticIds.AsyncUsesReturnsAsyncInsteadOfResult,
Title,
Message,
DiagnosticCategory.Moq,
DiagnosticSeverity.Error,
isEnabledByDefault: true,
- helpLinkUri: $"https://github.com/rjmurillo/moq.analyzers/blob/{ThisAssembly.GitCommitId}/docs/rules/{RuleId}.md");
+ helpLinkUri: $"https://github.com/rjmurillo/moq.analyzers/blob/{ThisAssembly.GitCommitId}/docs/rules/{DiagnosticIds.AsyncUsesReturnsAsyncInsteadOfResult}.md");
///
public override ImmutableArray SupportedDiagnostics { get; } = ImmutableArray.Create(Rule);
diff --git a/src/Moq.Analyzers/SquiggleCop.Baseline.yaml b/src/Moq.Analyzers/SquiggleCop.Baseline.yaml
index 7989daec..39400c30 100644
--- a/src/Moq.Analyzers/SquiggleCop.Baseline.yaml
+++ b/src/Moq.Analyzers/SquiggleCop.Baseline.yaml
@@ -35,7 +35,7 @@
- {Id: CA1056, Title: URI-like properties should not be strings, Category: Design, DefaultSeverity: Warning, IsEnabledByDefault: false, EffectiveSeverities: [None], IsEverSuppressed: true}
- {Id: CA1058, Title: Types should not extend certain base types, Category: Design, DefaultSeverity: Warning, IsEnabledByDefault: false, EffectiveSeverities: [None], IsEverSuppressed: true}
- {Id: CA1060, Title: Move pinvokes to native methods class, Category: Design, DefaultSeverity: Warning, IsEnabledByDefault: false, EffectiveSeverities: [None], IsEverSuppressed: true}
-- {Id: CA1061, Title: Do not hide base class methods, Category: Design, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Note], IsEverSuppressed: false}
+- {Id: CA1061, Title: Do not hide base class methods, Category: Design, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
- {Id: CA1062, Title: Validate arguments of public methods, Category: Design, DefaultSeverity: Warning, IsEnabledByDefault: false, EffectiveSeverities: [None], IsEverSuppressed: true}
- {Id: CA1063, Title: Implement IDisposable Correctly, Category: Design, DefaultSeverity: Warning, IsEnabledByDefault: false, EffectiveSeverities: [None], IsEverSuppressed: true}
- {Id: CA1064, Title: Exceptions should be public, Category: Design, DefaultSeverity: Warning, IsEnabledByDefault: false, EffectiveSeverities: [None], IsEverSuppressed: true}
@@ -298,6 +298,14 @@
- {Id: CA5403, Title: Do not hard-code certificate, Category: Security, DefaultSeverity: Warning, IsEnabledByDefault: false, EffectiveSeverities: [None], IsEverSuppressed: true}
- {Id: CA5404, Title: Do not disable token validation checks, Category: Security, DefaultSeverity: Warning, IsEnabledByDefault: false, EffectiveSeverities: [None], IsEverSuppressed: true}
- {Id: CA5405, Title: Do not always skip token validation in delegates, Category: Security, DefaultSeverity: Warning, IsEnabledByDefault: false, EffectiveSeverities: [None], IsEverSuppressed: true}
+- {Id: ECS0100, Title: Prefer implicitly typed local variables, Category: Style, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: ECS0200, Title: Prefer readonly over const, Category: Maintainability, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: true}
+- {Id: ECS0400, Title: Replace string.Format with interpolated string, Category: Style, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: ECS0500, Title: Prefer FormattableString or string.Create for culture-specific strings, Category: Globalization, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: ECS0600, Title: Avoid stringly-typed APIs, Category: Refactoring, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: ECS0700, Title: Express callbacks with delegates, Category: Design, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: ECS0800, Title: Use the Null Conditional Operator for Event Invocations, Category: Usage, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: ECS0900, Title: Minimize boxing and unboxing, Category: Performance, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: true}
- {Id: EM0001, Title: Switch on Enum Not Exhaustive, Category: Logic, DefaultSeverity: Error, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
- {Id: EM0002, Title: Switch on Nullable Enum Not Exhaustive, Category: Logic, DefaultSeverity: Error, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
- {Id: EM0003, Title: Switch on Closed Type Not Exhaustive, Category: Logic, DefaultSeverity: Error, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
@@ -1022,7 +1030,7 @@
- {Id: S2479, Title: Whitespace and control characters in string literals should be explicit, Category: Critical Code Smell, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
- {Id: S2486, Title: Generic exceptions should not be ignored, Category: Minor Code Smell, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
- {Id: S2551, Title: Shared resources should not be used for locking, Category: Critical Bug, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
-- {Id: S2583, Title: Conditionally executed code should be reachable, Category: Major Bug, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: S2583, Title: Conditionally executed code should be reachable, Category: Major Bug, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: true}
- {Id: S2589, Title: Boolean expressions should not be gratuitous, Category: Major Code Smell, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: true}
- {Id: S2612, Title: Setting loose file permissions is security-sensitive, Category: Major Security Hotspot, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
- {Id: S2629, Title: Logging templates should be constant, Category: Major Code Smell, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
diff --git a/src/tools/PerfDiff/.editorconfig b/src/tools/PerfDiff/.editorconfig
index 7324b7e2..2cf1d833 100644
--- a/src/tools/PerfDiff/.editorconfig
+++ b/src/tools/PerfDiff/.editorconfig
@@ -112,3 +112,24 @@ dotnet_diagnostic.MA0076.severity = none
dotnet_diagnostic.RCS1192.severity = none
# S1135: Track uses of "TODO" tags
dotnet_diagnostic.S1135.severity = none
+
+# Enable Effective C# Analyzers
+dotnet_diagnostic.ECS0100.severity = none
+dotnet_diagnostic.ECS0200.severity = none
+dotnet_diagnostic.ECS0300.severity = none
+dotnet_diagnostic.ECS0400.severity = none
+dotnet_diagnostic.ECS0500.severity = none
+dotnet_diagnostic.ECS0600.severity = none
+dotnet_diagnostic.ECS0700.severity = none
+dotnet_diagnostic.ECS0800.severity = none
+dotnet_diagnostic.ECS0900.severity = none
+dotnet_diagnostic.ECS1000.severity = none
+dotnet_diagnostic.ECS1100.severity = none
+dotnet_diagnostic.ECS1200.severity = none
+dotnet_diagnostic.ECS1300.severity = none
+dotnet_diagnostic.ECS1400.severity = none
+dotnet_diagnostic.ECS1500.severity = none
+dotnet_diagnostic.ECS1600.severity = none
+dotnet_diagnostic.ECS1700.severity = none
+dotnet_diagnostic.ECS1800.severity = none
+dotnet_diagnostic.ECS1900.severity = none
diff --git a/src/tools/PerfDiff/SquiggleCop.Baseline.yaml b/src/tools/PerfDiff/SquiggleCop.Baseline.yaml
index fc3c8dbd..8937fe75 100644
--- a/src/tools/PerfDiff/SquiggleCop.Baseline.yaml
+++ b/src/tools/PerfDiff/SquiggleCop.Baseline.yaml
@@ -35,7 +35,7 @@
- {Id: CA1056, Title: URI-like properties should not be strings, Category: Design, DefaultSeverity: Warning, IsEnabledByDefault: false, EffectiveSeverities: [None], IsEverSuppressed: true}
- {Id: CA1058, Title: Types should not extend certain base types, Category: Design, DefaultSeverity: Warning, IsEnabledByDefault: false, EffectiveSeverities: [None], IsEverSuppressed: true}
- {Id: CA1060, Title: Move pinvokes to native methods class, Category: Design, DefaultSeverity: Warning, IsEnabledByDefault: false, EffectiveSeverities: [None], IsEverSuppressed: true}
-- {Id: CA1061, Title: Do not hide base class methods, Category: Design, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Note], IsEverSuppressed: false}
+- {Id: CA1061, Title: Do not hide base class methods, Category: Design, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
- {Id: CA1062, Title: Validate arguments of public methods, Category: Design, DefaultSeverity: Warning, IsEnabledByDefault: false, EffectiveSeverities: [None], IsEverSuppressed: true}
- {Id: CA1063, Title: Implement IDisposable Correctly, Category: Design, DefaultSeverity: Warning, IsEnabledByDefault: false, EffectiveSeverities: [None], IsEverSuppressed: true}
- {Id: CA1064, Title: Exceptions should be public, Category: Design, DefaultSeverity: Warning, IsEnabledByDefault: false, EffectiveSeverities: [None], IsEverSuppressed: true}
@@ -298,6 +298,14 @@
- {Id: CA5403, Title: Do not hard-code certificate, Category: Security, DefaultSeverity: Warning, IsEnabledByDefault: false, EffectiveSeverities: [None], IsEverSuppressed: true}
- {Id: CA5404, Title: Do not disable token validation checks, Category: Security, DefaultSeverity: Warning, IsEnabledByDefault: false, EffectiveSeverities: [None], IsEverSuppressed: true}
- {Id: CA5405, Title: Do not always skip token validation in delegates, Category: Security, DefaultSeverity: Warning, IsEnabledByDefault: false, EffectiveSeverities: [None], IsEverSuppressed: true}
+- {Id: ECS0100, Title: Prefer implicitly typed local variables, Category: Style, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Error, None], IsEverSuppressed: true}
+- {Id: ECS0200, Title: Prefer readonly over const, Category: Maintainability, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Error, None], IsEverSuppressed: true}
+- {Id: ECS0400, Title: Replace string.Format with interpolated string, Category: Style, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Error, None], IsEverSuppressed: true}
+- {Id: ECS0500, Title: Prefer FormattableString or string.Create for culture-specific strings, Category: Globalization, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Error, None], IsEverSuppressed: true}
+- {Id: ECS0600, Title: Avoid stringly-typed APIs, Category: Refactoring, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Error, None], IsEverSuppressed: true}
+- {Id: ECS0700, Title: Express callbacks with delegates, Category: Design, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Error, None], IsEverSuppressed: true}
+- {Id: ECS0800, Title: Use the Null Conditional Operator for Event Invocations, Category: Usage, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Error, None], IsEverSuppressed: true}
+- {Id: ECS0900, Title: Minimize boxing and unboxing, Category: Performance, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Error, None], IsEverSuppressed: true}
- {Id: EM0001, Title: Switch on Enum Not Exhaustive, Category: Logic, DefaultSeverity: Error, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
- {Id: EM0002, Title: Switch on Nullable Enum Not Exhaustive, Category: Logic, DefaultSeverity: Error, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
- {Id: EM0003, Title: Switch on Closed Type Not Exhaustive, Category: Logic, DefaultSeverity: Error, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
diff --git a/tests/Moq.Analyzers.Benchmarks/Constants.cs b/tests/Moq.Analyzers.Benchmarks/Constants.cs
index 338f9f04..6070a45d 100644
--- a/tests/Moq.Analyzers.Benchmarks/Constants.cs
+++ b/tests/Moq.Analyzers.Benchmarks/Constants.cs
@@ -1,5 +1,7 @@
namespace Moq.Analyzers.Benchmarks;
+#pragma warning disable ECS0200 // Consider using readonly instead of const for flexibility
+
internal static class Constants
{
public const int NumberOfCodeFiles = 1_000;
diff --git a/tests/Moq.Analyzers.Benchmarks/Helpers/CompilationCreator.cs b/tests/Moq.Analyzers.Benchmarks/Helpers/CompilationCreator.cs
index d3c73a03..3840df2f 100644
--- a/tests/Moq.Analyzers.Benchmarks/Helpers/CompilationCreator.cs
+++ b/tests/Moq.Analyzers.Benchmarks/Helpers/CompilationCreator.cs
@@ -100,7 +100,9 @@ private static async Task CreateSolutionAsync(
async () =>
{
AttributedPartDiscovery discovery = new(Resolver.DefaultInstance, isNonPublicSupported: true);
+#pragma warning disable ECS0900 // Minimize boxing and unboxing
DiscoveredParts parts = await discovery.CreatePartsAsync(MefHostServices.DefaultAssemblies).ConfigureAwait(false);
+#pragma warning restore ECS0900 // Minimize boxing and unboxing
ComposableCatalog catalog = ComposableCatalog.Create(Resolver.DefaultInstance).AddParts(parts);
CompositionConfiguration configuration = CompositionConfiguration.Create(catalog);
@@ -119,7 +121,9 @@ private static async Task CreateSolutionAsync(
.WithProjectParseOptions(projectId, parseOptions);
ImmutableArray metadataReferences = await referenceAssemblies.ResolveAsync(projectState.Language, CancellationToken.None).ConfigureAwait(false);
+#pragma warning disable ECS0900 // Minimize boxing and unboxing
solution = solution.AddMetadataReferences(projectId, metadataReferences);
+#pragma warning restore ECS0900 // Minimize boxing and unboxing
return solution;
}
diff --git a/tests/Moq.Analyzers.Benchmarks/Helpers/ExportProviderExtensions.cs b/tests/Moq.Analyzers.Benchmarks/Helpers/ExportProviderExtensions.cs
index 57323710..216721de 100644
--- a/tests/Moq.Analyzers.Benchmarks/Helpers/ExportProviderExtensions.cs
+++ b/tests/Moq.Analyzers.Benchmarks/Helpers/ExportProviderExtensions.cs
@@ -27,7 +27,9 @@ public CompositionContextShim(ExportProvider exportProvider)
[SuppressMessage("Maintainability", "AV1500:Member or local function contains too many statements", Justification = "Minimizing divergence from upstream")]
public override bool TryGetExport(CompositionContract contract, [NotNullWhen(true)] out object? export)
{
+#pragma warning disable ECS0900 // Minimize boxing and unboxing
bool importMany = contract.MetadataConstraints.Contains(new KeyValuePair("IsImportMany", true));
+#pragma warning restore ECS0900 // Minimize boxing and unboxing
(Type contractType, Type? metadataType) = GetContractType(contract.ContractType, importMany);
if (metadataType != null)
diff --git a/tests/Moq.Analyzers.Benchmarks/SquiggleCop.Baseline.yaml b/tests/Moq.Analyzers.Benchmarks/SquiggleCop.Baseline.yaml
index c3579d00..f5573d04 100644
--- a/tests/Moq.Analyzers.Benchmarks/SquiggleCop.Baseline.yaml
+++ b/tests/Moq.Analyzers.Benchmarks/SquiggleCop.Baseline.yaml
@@ -35,7 +35,7 @@
- {Id: CA1056, Title: URI-like properties should not be strings, Category: Design, DefaultSeverity: Warning, IsEnabledByDefault: false, EffectiveSeverities: [None], IsEverSuppressed: true}
- {Id: CA1058, Title: Types should not extend certain base types, Category: Design, DefaultSeverity: Warning, IsEnabledByDefault: false, EffectiveSeverities: [None], IsEverSuppressed: true}
- {Id: CA1060, Title: Move pinvokes to native methods class, Category: Design, DefaultSeverity: Warning, IsEnabledByDefault: false, EffectiveSeverities: [None], IsEverSuppressed: true}
-- {Id: CA1061, Title: Do not hide base class methods, Category: Design, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Note], IsEverSuppressed: false}
+- {Id: CA1061, Title: Do not hide base class methods, Category: Design, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
- {Id: CA1062, Title: Validate arguments of public methods, Category: Design, DefaultSeverity: Warning, IsEnabledByDefault: false, EffectiveSeverities: [None], IsEverSuppressed: true}
- {Id: CA1063, Title: Implement IDisposable Correctly, Category: Design, DefaultSeverity: Warning, IsEnabledByDefault: false, EffectiveSeverities: [None], IsEverSuppressed: true}
- {Id: CA1064, Title: Exceptions should be public, Category: Design, DefaultSeverity: Warning, IsEnabledByDefault: false, EffectiveSeverities: [None], IsEverSuppressed: true}
@@ -300,6 +300,14 @@
- {Id: CA5405, Title: Do not always skip token validation in delegates, Category: Security, DefaultSeverity: Warning, IsEnabledByDefault: false, EffectiveSeverities: [None], IsEverSuppressed: true}
- {Id: CS1591, Title: Missing XML comment for publicly visible type or member, Category: Compiler, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Warning], IsEverSuppressed: false}
- {Id: CS8762, Title: Parameter must have a non-null value when exiting in some condition., Category: Compiler, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Warning], IsEverSuppressed: true}
+- {Id: ECS0100, Title: Prefer implicitly typed local variables, Category: Style, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: ECS0200, Title: Prefer readonly over const, Category: Maintainability, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: true}
+- {Id: ECS0400, Title: Replace string.Format with interpolated string, Category: Style, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: ECS0500, Title: Prefer FormattableString or string.Create for culture-specific strings, Category: Globalization, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: ECS0600, Title: Avoid stringly-typed APIs, Category: Refactoring, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: ECS0700, Title: Express callbacks with delegates, Category: Design, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: ECS0800, Title: Use the Null Conditional Operator for Event Invocations, Category: Usage, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: ECS0900, Title: Minimize boxing and unboxing, Category: Performance, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: true}
- {Id: EM0001, Title: Switch on Enum Not Exhaustive, Category: Logic, DefaultSeverity: Error, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
- {Id: EM0002, Title: Switch on Nullable Enum Not Exhaustive, Category: Logic, DefaultSeverity: Error, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
- {Id: EM0003, Title: Switch on Closed Type Not Exhaustive, Category: Logic, DefaultSeverity: Error, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
diff --git a/tests/Moq.Analyzers.Test/CompositeAnalyzer.cs b/tests/Moq.Analyzers.Test/CompositeAnalyzer.cs
index 56998a73..bed6ddf1 100644
--- a/tests/Moq.Analyzers.Test/CompositeAnalyzer.cs
+++ b/tests/Moq.Analyzers.Test/CompositeAnalyzer.cs
@@ -17,7 +17,9 @@ public class CompositeAnalyzer : DiagnosticAnalyzer
public CompositeAnalyzer()
{
_analyzers = [.. DiagnosticAnalyzers()];
+#pragma warning disable ECS0900 // Consider using an alternative implementation to avoid boxing and unboxing
_supportedDiagnostics = [.. _analyzers.SelectMany(diagnosticAnalyzer => diagnosticAnalyzer.SupportedDiagnostics)];
+#pragma warning restore ECS0900
}
///
diff --git a/tests/Moq.Analyzers.Test/SquiggleCop.Baseline.yaml b/tests/Moq.Analyzers.Test/SquiggleCop.Baseline.yaml
index 25ac3575..b0e281a2 100644
--- a/tests/Moq.Analyzers.Test/SquiggleCop.Baseline.yaml
+++ b/tests/Moq.Analyzers.Test/SquiggleCop.Baseline.yaml
@@ -35,7 +35,7 @@
- {Id: CA1056, Title: URI-like properties should not be strings, Category: Design, DefaultSeverity: Warning, IsEnabledByDefault: false, EffectiveSeverities: [None], IsEverSuppressed: true}
- {Id: CA1058, Title: Types should not extend certain base types, Category: Design, DefaultSeverity: Warning, IsEnabledByDefault: false, EffectiveSeverities: [None], IsEverSuppressed: true}
- {Id: CA1060, Title: Move pinvokes to native methods class, Category: Design, DefaultSeverity: Warning, IsEnabledByDefault: false, EffectiveSeverities: [None], IsEverSuppressed: true}
-- {Id: CA1061, Title: Do not hide base class methods, Category: Design, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Note], IsEverSuppressed: false}
+- {Id: CA1061, Title: Do not hide base class methods, Category: Design, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
- {Id: CA1062, Title: Validate arguments of public methods, Category: Design, DefaultSeverity: Warning, IsEnabledByDefault: false, EffectiveSeverities: [None], IsEverSuppressed: true}
- {Id: CA1063, Title: Implement IDisposable Correctly, Category: Design, DefaultSeverity: Warning, IsEnabledByDefault: false, EffectiveSeverities: [None], IsEverSuppressed: true}
- {Id: CA1064, Title: Exceptions should be public, Category: Design, DefaultSeverity: Warning, IsEnabledByDefault: false, EffectiveSeverities: [None], IsEverSuppressed: true}
@@ -299,6 +299,14 @@
- {Id: CA5404, Title: Do not disable token validation checks, Category: Security, DefaultSeverity: Warning, IsEnabledByDefault: false, EffectiveSeverities: [None], IsEverSuppressed: true}
- {Id: CA5405, Title: Do not always skip token validation in delegates, Category: Security, DefaultSeverity: Warning, IsEnabledByDefault: false, EffectiveSeverities: [None], IsEverSuppressed: true}
- {Id: CS1591, Title: Missing XML comment for publicly visible type or member, Category: Compiler, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Warning], IsEverSuppressed: true}
+- {Id: ECS0100, Title: Prefer implicitly typed local variables, Category: Style, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: ECS0200, Title: Prefer readonly over const, Category: Maintainability, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: ECS0400, Title: Replace string.Format with interpolated string, Category: Style, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: ECS0500, Title: Prefer FormattableString or string.Create for culture-specific strings, Category: Globalization, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: ECS0600, Title: Avoid stringly-typed APIs, Category: Refactoring, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: ECS0700, Title: Express callbacks with delegates, Category: Design, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: ECS0800, Title: Use the Null Conditional Operator for Event Invocations, Category: Usage, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: ECS0900, Title: Minimize boxing and unboxing, Category: Performance, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: true}
- {Id: EM0001, Title: Switch on Enum Not Exhaustive, Category: Logic, DefaultSeverity: Error, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
- {Id: EM0002, Title: Switch on Nullable Enum Not Exhaustive, Category: Logic, DefaultSeverity: Error, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
- {Id: EM0003, Title: Switch on Closed Type Not Exhaustive, Category: Logic, DefaultSeverity: Error, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}