diff --git a/build/targets/codeanalysis/CodeAnalysis.props b/build/targets/codeanalysis/CodeAnalysis.props
index f25d9b626..040a92c92 100644
--- a/build/targets/codeanalysis/CodeAnalysis.props
+++ b/build/targets/codeanalysis/CodeAnalysis.props
@@ -26,6 +26,10 @@
all
runtime; build; native; contentfiles; analyzers
+
+ all
+ runtime; build; native; contentfiles; analyzers
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/build/targets/codeanalysis/Packages.props b/build/targets/codeanalysis/Packages.props
index 0b6b01952..53a897b36 100644
--- a/build/targets/codeanalysis/Packages.props
+++ b/build/targets/codeanalysis/Packages.props
@@ -3,6 +3,7 @@
+
diff --git a/build/targets/compiler/Compiler.props b/build/targets/compiler/Compiler.props
index 7f9eb03a2..307c61826 100644
--- a/build/targets/compiler/Compiler.props
+++ b/build/targets/compiler/Compiler.props
@@ -6,7 +6,7 @@
-
+
all
runtime; build; native; contentfiles; analyzers
diff --git a/build/targets/compiler/Packages.props b/build/targets/compiler/Packages.props
index e1375feb1..bc58eca9d 100644
--- a/build/targets/compiler/Packages.props
+++ b/build/targets/compiler/Packages.props
@@ -1,5 +1,5 @@
-
-
+
+
diff --git a/src/Analyzers/AsShouldBeUsedOnlyForInterfaceAnalyzer.cs b/src/Analyzers/AsShouldBeUsedOnlyForInterfaceAnalyzer.cs
index 5ec398e9e..990334ff0 100644
--- a/src/Analyzers/AsShouldBeUsedOnlyForInterfaceAnalyzer.cs
+++ b/src/Analyzers/AsShouldBeUsedOnlyForInterfaceAnalyzer.cs
@@ -34,21 +34,18 @@ public override void Initialize(AnalysisContext context)
private static void RegisterCompilationStartAction(CompilationStartAnalysisContext context)
{
+ MoqKnownSymbols knownSymbols = new(context.Compilation);
+
// Ensure Moq is referenced in the compilation
- ImmutableArray mockTypes = context.Compilation.GetMoqMock();
- if (mockTypes.IsEmpty)
+ if (!knownSymbols.IsMockReferenced())
{
return;
}
// 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(WellKnownMoqNames.AsMethodName))
- .OfType()
- .Where(method => method.IsGenericMethod)
- .ToImmutableArray();
-#pragma warning restore ECS0900 // Minimize boxing and unboxing
+ ImmutableArray asMethods = ImmutableArray.CreateRange([
+ ..knownSymbols.MockAs,
+ ..knownSymbols.Mock1As]);
if (asMethods.IsEmpty)
{
diff --git a/src/Analyzers/CallbackSignatureShouldMatchMockedMethodAnalyzer.cs b/src/Analyzers/CallbackSignatureShouldMatchMockedMethodAnalyzer.cs
index 21e5f1953..0cc12de9f 100644
--- a/src/Analyzers/CallbackSignatureShouldMatchMockedMethodAnalyzer.cs
+++ b/src/Analyzers/CallbackSignatureShouldMatchMockedMethodAnalyzer.cs
@@ -31,6 +31,8 @@ public override void Initialize(AnalysisContext context)
private static void Analyze(SyntaxNodeAnalysisContext context)
{
+ MoqKnownSymbols knownSymbols = new(context.SemanticModel.Compilation);
+
InvocationExpressionSyntax callbackOrReturnsInvocation = (InvocationExpressionSyntax)context.Node;
SeparatedSyntaxList callbackOrReturnsMethodArguments = callbackOrReturnsInvocation.ArgumentList.Arguments;
@@ -49,7 +51,7 @@ private static void Analyze(SyntaxNodeAnalysisContext context)
SeparatedSyntaxList lambdaParameters = callbackLambda.ParameterList.Parameters;
if (lambdaParameters.Count == 0) return;
- InvocationExpressionSyntax? setupInvocation = context.SemanticModel.FindSetupMethodFromCallbackInvocation(callbackOrReturnsInvocation, context.CancellationToken);
+ InvocationExpressionSyntax? setupInvocation = context.SemanticModel.FindSetupMethodFromCallbackInvocation(knownSymbols, callbackOrReturnsInvocation, context.CancellationToken);
InvocationExpressionSyntax? mockedMethodInvocation = setupInvocation.FindMockedMethodInvocationFromSetupMethod();
if (mockedMethodInvocation == null) return;
diff --git a/src/Analyzers/ConstructorArgumentsShouldMatchAnalyzer.cs b/src/Analyzers/ConstructorArgumentsShouldMatchAnalyzer.cs
index 228ec5f92..ae93b7ede 100644
--- a/src/Analyzers/ConstructorArgumentsShouldMatchAnalyzer.cs
+++ b/src/Analyzers/ConstructorArgumentsShouldMatchAnalyzer.cs
@@ -68,65 +68,42 @@ public override void Initialize(AnalysisContext context)
return null;
}
- private static bool IsExpressionMockBehavior(SyntaxNodeAnalysisContext context, ExpressionSyntax? expression)
+ private static bool IsExpressionMockBehavior(SyntaxNodeAnalysisContext context, MoqKnownSymbols knownSymbols, ExpressionSyntax? expression)
{
- if (expression == null)
+ if (expression is null)
{
return false;
}
- if (expression is MemberAccessExpressionSyntax memberAccessExpressionSyntax)
+ SymbolInfo symbolInfo = context.SemanticModel.GetSymbolInfo(expression, context.CancellationToken);
+
+ if (symbolInfo.Symbol is null)
{
- if (memberAccessExpressionSyntax.Expression is IdentifierNameSyntax identifierNameSyntax
- && string.Equals(identifierNameSyntax.Identifier.ValueText, WellKnownMoqNames.MockBehaviorTypeName, StringComparison.Ordinal))
- {
- return true;
- }
+ return false;
}
- else if (expression is IdentifierNameSyntax identifierNameSyntax)
- {
- SymbolInfo symbolInfo = context.SemanticModel.GetSymbolInfo(identifierNameSyntax, context.CancellationToken);
-
- if (symbolInfo.Symbol == null)
- {
- return false;
- }
- ITypeSymbol? typeSymbol = null;
- if (symbolInfo.Symbol is IParameterSymbol parameterSymbol)
- {
- typeSymbol = parameterSymbol.Type;
- }
- else if (symbolInfo.Symbol is ILocalSymbol localSymbol)
- {
- typeSymbol = localSymbol.Type;
- }
- else if (symbolInfo.Symbol is IFieldSymbol fieldSymbol)
- {
- typeSymbol = fieldSymbol.Type;
- }
-
- if (typeSymbol != null
- && string.Equals(typeSymbol.Name, WellKnownMoqNames.MockBehaviorTypeName, StringComparison.Ordinal))
- {
- return true;
- }
+ ISymbol targetSymbol = symbolInfo.Symbol;
+ if (symbolInfo.Symbol is IParameterSymbol parameterSymbol)
+ {
+ targetSymbol = parameterSymbol.Type;
}
-
- // Crude fallback to check if the expression is a Moq.MockBehavior enum
- if (expression.ToString().StartsWith(WellKnownMoqNames.FullyQualifiedMoqBehaviorTypeName, StringComparison.Ordinal))
+ else if (symbolInfo.Symbol is ILocalSymbol localSymbol)
{
- return true;
+ targetSymbol = localSymbol.Type;
+ }
+ else if (symbolInfo.Symbol is IFieldSymbol fieldSymbol)
+ {
+ targetSymbol = fieldSymbol.Type;
}
- return false;
+ return targetSymbol.IsInstanceOf(knownSymbols.MockBehavior);
}
- private static bool IsFirstArgumentMockBehavior(SyntaxNodeAnalysisContext context, ArgumentListSyntax? argumentList)
+ private static bool IsFirstArgumentMockBehavior(SyntaxNodeAnalysisContext context, MoqKnownSymbols knownSymbols, ArgumentListSyntax? argumentList)
{
ExpressionSyntax? expression = argumentList?.Arguments[0].Expression;
- return IsExpressionMockBehavior(context, expression);
+ return IsExpressionMockBehavior(context, knownSymbols, expression);
}
private static void VerifyDelegateMockAttempt(
@@ -174,59 +151,38 @@ private static void AnalyzeCompilation(CompilationStartAnalysisContext context)
return;
}
+ MoqKnownSymbols knownSymbols = new(context.Compilation);
+
// We're interested in the few ways to create mocks:
// - new Mock()
// - Mock.Of()
// - MockRepository.Create()
//
// Ensure Moq is referenced in the compilation
- ImmutableArray mockTypes = context.Compilation.GetMoqMock();
- if (mockTypes.IsEmpty)
+ if (!knownSymbols.IsMockReferenced())
{
return;
}
// These are for classes
- context.RegisterSyntaxNodeAction(AnalyzeNewObject, SyntaxKind.ObjectCreationExpression);
- context.RegisterSyntaxNodeAction(AnalyzeInstanceCall, SyntaxKind.InvocationExpression);
+ context.RegisterSyntaxNodeAction(context => AnalyzeNewObject(context, knownSymbols), SyntaxKind.ObjectCreationExpression);
+ context.RegisterSyntaxNodeAction(context => AnalyzeInstanceCall(context, knownSymbols), SyntaxKind.InvocationExpression);
}
- private static void AnalyzeInstanceCall(SyntaxNodeAnalysisContext context)
+ private static void AnalyzeInstanceCall(SyntaxNodeAnalysisContext context, MoqKnownSymbols knownSymbols)
{
InvocationExpressionSyntax invocationExpressionSyntax = (InvocationExpressionSyntax)context.Node;
- if (invocationExpressionSyntax.Expression is not MemberAccessExpressionSyntax memberAccessExpressionSyntax)
- {
- return;
- }
-
- if (memberAccessExpressionSyntax.Name is not GenericNameSyntax genericNameSyntax)
- {
- return;
- }
-
- if (genericNameSyntax.Identifier.Value is not string genericNameSyntaxIdentifierValue)
- {
- return;
- }
-
- if (string.Equals(genericNameSyntaxIdentifierValue, WellKnownMoqNames.CreateMethodName, StringComparison.Ordinal))
- {
- AnalyzeInvocation(context, invocationExpressionSyntax, WellKnownMoqNames.MockFactoryTypeName, true, true);
- }
- else if (string.Equals(genericNameSyntaxIdentifierValue, WellKnownMoqNames.OfMethodName, StringComparison.Ordinal))
- {
- AnalyzeInvocation(context, invocationExpressionSyntax, WellKnownMoqNames.MockTypeName, false, true);
- }
+ AnalyzeInvocation(context, knownSymbols, invocationExpressionSyntax);
}
private static void AnalyzeInvocation(
SyntaxNodeAnalysisContext context,
- InvocationExpressionSyntax invocationExpressionSyntax,
- string expectedClassName,
- bool hasReturnedMock,
- bool hasMockBehavior)
+ MoqKnownSymbols knownSymbols,
+ InvocationExpressionSyntax invocationExpressionSyntax)
{
+ bool hasReturnedMock = true;
+ bool hasMockBehavior = true;
SymbolInfo symbol = context.SemanticModel.GetSymbolInfo(invocationExpressionSyntax, context.CancellationToken);
if (symbol.Symbol is not IMethodSymbol method)
@@ -234,38 +190,39 @@ private static void AnalyzeInvocation(
return;
}
- if (!string.Equals(method.ContainingType.Name, expectedClassName, StringComparison.Ordinal))
+ if (!method.IsInstanceOf(knownSymbols.MockOf) && !method.IsInstanceOf(knownSymbols.MockRepositoryCreate))
{
return;
}
- ITypeSymbol returnType = method.ReturnType;
- if (hasReturnedMock)
- {
- if (returnType is not INamedTypeSymbol { IsGenericType: true } typeSymbol)
- {
- return;
- }
-
- returnType = typeSymbol.TypeArguments[0];
- }
-
// We are calling MockRepository.Create or Mock.Of, determine which
ArgumentListSyntax? argumentList = null;
- if (WellKnownMoqNames.OfMethodName.Equals(method.Name, StringComparison.Ordinal))
+ if (method.IsInstanceOf(knownSymbols.MockOf))
{
// Mock.Of can specify condition for construction and MockBehavior, but
// cannot specify constructor parameters
//
// The only parameters that can be passed are not relevant for verification
// to just strip them
+ hasReturnedMock = false;
}
else
{
argumentList = invocationExpressionSyntax.ArgumentList;
}
- VerifyMockAttempt(context, returnType, argumentList, hasMockBehavior);
+ ITypeSymbol returnType = method.ReturnType;
+ if (hasReturnedMock)
+ {
+ if (returnType is not INamedTypeSymbol { IsGenericType: true } typeSymbol)
+ {
+ return;
+ }
+
+ returnType = typeSymbol.TypeArguments[0];
+ }
+
+ VerifyMockAttempt(context, knownSymbols, returnType, argumentList, hasMockBehavior);
}
///
@@ -273,7 +230,8 @@ private static void AnalyzeInvocation(
/// match an existing constructor of the mocked class.
///
/// The context.
- private static void AnalyzeNewObject(SyntaxNodeAnalysisContext context)
+ /// The used to lookup symbols against Moq types.
+ private static void AnalyzeNewObject(SyntaxNodeAnalysisContext context, MoqKnownSymbols knownSymbols)
{
ObjectCreationExpressionSyntax newExpression = (ObjectCreationExpressionSyntax)context.Node;
@@ -283,33 +241,24 @@ private static void AnalyzeNewObject(SyntaxNodeAnalysisContext context)
return;
}
- // Quick check
- if (!string.Equals(
- genericNameSyntax.Identifier.ValueText,
- WellKnownMoqNames.MockTypeName,
- StringComparison.Ordinal))
- {
- return;
- }
-
- // Full check
SymbolInfo symbolInfo = context.SemanticModel.GetSymbolInfo(newExpression, context.CancellationToken);
- if (symbolInfo.Symbol is not IMethodSymbol mockConstructorMethod
- || mockConstructorMethod.MethodKind != MethodKind.Constructor
- || !string.Equals(mockConstructorMethod.ContainingType.ConstructedFrom.ContainingSymbol.Name, WellKnownMoqNames.MoqSymbolName, StringComparison.Ordinal))
+ if (!symbolInfo
+ .Symbol?
+ .IsInstanceOf(knownSymbols.Mock1?.Constructors ?? ImmutableArray.Empty)
+ ?? false)
{
return;
}
- if (mockConstructorMethod.ReceiverType is not INamedTypeSymbol { IsGenericType: true } typeSymbol)
+ if (symbolInfo.Symbol?.ContainingType is not INamedTypeSymbol { IsGenericType: true } typeSymbol)
{
return;
}
ITypeSymbol mockedClass = typeSymbol.TypeArguments[0];
- VerifyMockAttempt(context, mockedClass, newExpression.ArgumentList, true);
+ VerifyMockAttempt(context, knownSymbols, mockedClass, newExpression.ArgumentList, true);
}
///
@@ -423,6 +372,7 @@ private static (bool IsEmpty, Location Location) ConstructorIsEmpty(
private static void VerifyMockAttempt(
SyntaxNodeAnalysisContext context,
+ MoqKnownSymbols knownSymbols,
ITypeSymbol mockedClass,
ArgumentListSyntax? argumentList,
bool hasMockBehavior)
@@ -436,7 +386,7 @@ private static void VerifyMockAttempt(
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))
+ if (hasMockBehavior && arguments.Length > 0 && IsFirstArgumentMockBehavior(context, knownSymbols, argumentList))
{
// They passed a mock behavior as the first argument; ignore as Moq swallows it
arguments = arguments.RemoveAt(0);
diff --git a/src/Analyzers/SetExplicitMockBehaviorAnalyzer.cs b/src/Analyzers/SetExplicitMockBehaviorAnalyzer.cs
index 5752907c7..567073202 100644
--- a/src/Analyzers/SetExplicitMockBehaviorAnalyzer.cs
+++ b/src/Analyzers/SetExplicitMockBehaviorAnalyzer.cs
@@ -34,28 +34,28 @@ public override void Initialize(AnalysisContext context)
private static void RegisterCompilationStartAction(CompilationStartAnalysisContext context)
{
+ MoqKnownSymbols knownSymbols = new(context.Compilation);
+
// Ensure Moq is referenced in the compilation
- ImmutableArray mockTypes = context.Compilation.GetMoqMock();
- if (mockTypes.IsEmpty)
+ if (!knownSymbols.IsMockReferenced())
{
return;
}
// Look for the MockBehavior type and provide it to Analyze to avoid looking it up multiple times.
- INamedTypeSymbol? mockBehaviorSymbol = context.Compilation.GetTypeByMetadataName(WellKnownMoqNames.FullyQualifiedMoqBehaviorTypeName);
+ INamedTypeSymbol? mockBehaviorSymbol = knownSymbols.MockBehavior;
if (mockBehaviorSymbol is null)
{
return;
}
// Look for the Mock.Of() method and provide it to Analyze to avoid looking it up multiple times.
-#pragma warning disable ECS0900 // Minimize boxing and unboxing
- ImmutableArray ofMethods = mockTypes
- .SelectMany(mockType => mockType.GetMembers(WellKnownMoqNames.OfMethodName))
- .OfType()
- .Where(method => method.IsGenericMethod)
+ ImmutableArray ofMethods = knownSymbols.MockOf;
+
+ ImmutableArray mockTypes =
+ new INamedTypeSymbol?[] { knownSymbols.Mock1, knownSymbols.MockRepository }
+ .WhereNotNull()
.ToImmutableArray();
-#pragma warning restore ECS0900 // Minimize boxing and unboxing
context.RegisterOperationAction(
context => AnalyzeNewObject(context, mockTypes, mockBehaviorSymbol),
diff --git a/src/Analyzers/SetupShouldBeUsedOnlyForOverridableMembersAnalyzer.cs b/src/Analyzers/SetupShouldBeUsedOnlyForOverridableMembersAnalyzer.cs
index d4bdd265f..71c11409d 100644
--- a/src/Analyzers/SetupShouldBeUsedOnlyForOverridableMembersAnalyzer.cs
+++ b/src/Analyzers/SetupShouldBeUsedOnlyForOverridableMembersAnalyzer.cs
@@ -1,5 +1,4 @@
-using System.Runtime.CompilerServices;
-using ISymbolExtensions = Microsoft.CodeAnalysis.ISymbolExtensions;
+using System.Diagnostics.CodeAnalysis;
namespace Moq.Analyzers;
@@ -32,12 +31,20 @@ public override void Initialize(AnalysisContext context)
context.RegisterSyntaxNodeAction(Analyze, SyntaxKind.InvocationExpression);
}
+ [SuppressMessage("Design", "MA0051:Method is too long", Justification = "Should be fixed. Ignoring for now to avoid additional churn as part of larger refactor.")]
private static void Analyze(SyntaxNodeAnalysisContext context)
{
InvocationExpressionSyntax setupInvocation = (InvocationExpressionSyntax)context.Node;
- if (setupInvocation.Expression is not MemberAccessExpressionSyntax memberAccessExpression
- || !context.SemanticModel.IsMoqSetupMethod(memberAccessExpression, context.CancellationToken))
+ MoqKnownSymbols knownSymbols = new(context.SemanticModel.Compilation);
+
+ if (setupInvocation.Expression is not MemberAccessExpressionSyntax memberAccessExpression)
+ {
+ return;
+ }
+
+ SymbolInfo memberAccessSymbolInfo = context.SemanticModel.GetSymbolInfo(memberAccessExpression, context.CancellationToken);
+ if (memberAccessSymbolInfo.Symbol is null || !context.SemanticModel.IsMoqSetupMethod(knownSymbols, memberAccessSymbolInfo.Symbol, context.CancellationToken))
{
return;
}
@@ -66,17 +73,12 @@ private static void Analyze(SyntaxNodeAnalysisContext context)
{
case IPropertySymbol propertySymbol:
// Check if the property is Task.Result and skip diagnostic if it is
- if (IsTaskResultProperty(propertySymbol, context))
- {
- return;
- }
-
- if (propertySymbol.IsOverridable())
+ if (IsTaskResultProperty(propertySymbol, knownSymbols))
{
return;
}
- if (propertySymbol.IsMethodReturnTypeTask())
+ if (propertySymbol.IsOverridable() || propertySymbol.IsMethodReturnTypeTask())
{
return;
}
@@ -95,7 +97,7 @@ private static void Analyze(SyntaxNodeAnalysisContext context)
context.ReportDiagnostic(diagnostic);
}
- private static bool IsTaskResultProperty(IPropertySymbol propertySymbol, SyntaxNodeAnalysisContext context)
+ private static bool IsTaskResultProperty(IPropertySymbol propertySymbol, MoqKnownSymbols knownSymbols)
{
// Check if the property is named "Result"
if (!string.Equals(propertySymbol.Name, "Result", StringComparison.Ordinal))
@@ -104,7 +106,7 @@ private static bool IsTaskResultProperty(IPropertySymbol propertySymbol, SyntaxN
}
// Check if the containing type is Task
- INamedTypeSymbol? taskOfTType = context.SemanticModel.Compilation.GetTypeByMetadataName("System.Threading.Tasks.Task`1");
+ INamedTypeSymbol? taskOfTType = knownSymbols.Task1;
if (taskOfTType == null)
{
diff --git a/src/Analyzers/SetupShouldNotIncludeAsyncResultAnalyzer.cs b/src/Analyzers/SetupShouldNotIncludeAsyncResultAnalyzer.cs
index 057b30c1e..d630941b8 100644
--- a/src/Analyzers/SetupShouldNotIncludeAsyncResultAnalyzer.cs
+++ b/src/Analyzers/SetupShouldNotIncludeAsyncResultAnalyzer.cs
@@ -40,10 +40,17 @@ private static void Analyze(SyntaxNodeAnalysisContext context)
return;
}
+ MoqKnownSymbols knownSymbols = new(context.SemanticModel.Compilation);
+
InvocationExpressionSyntax setupInvocation = (InvocationExpressionSyntax)context.Node;
- if (setupInvocation.Expression is not MemberAccessExpressionSyntax memberAccessExpression ||
- !context.SemanticModel.IsMoqSetupMethod(memberAccessExpression, context.CancellationToken))
+ if (setupInvocation.Expression is not MemberAccessExpressionSyntax memberAccessExpression)
+ {
+ return;
+ }
+
+ SymbolInfo memberAccessSymbolInfo = context.SemanticModel.GetSymbolInfo(memberAccessExpression, context.CancellationToken);
+ if (memberAccessSymbolInfo.Symbol is null || !context.SemanticModel.IsMoqSetupMethod(knownSymbols, memberAccessSymbolInfo.Symbol, context.CancellationToken))
{
return;
}
diff --git a/src/Analyzers/SquiggleCop.Baseline.yaml b/src/Analyzers/SquiggleCop.Baseline.yaml
index ad284559f..54cf4f75c 100644
--- a/src/Analyzers/SquiggleCop.Baseline.yaml
+++ b/src/Analyzers/SquiggleCop.Baseline.yaml
@@ -307,6 +307,15 @@
- {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: CS0419, Title: Ambiguous reference in cref attribute, Category: Compiler, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Warning], IsEverSuppressed: true}
+- {Id: CS0649, Title: 'Field is never assigned to, and will always have its default value', Category: Compiler, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Warning], IsEverSuppressed: true}
+- {Id: CS1570, Title: XML comment has badly formed XML, Category: Compiler, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Warning], IsEverSuppressed: true}
+- {Id: CS1572, Title: 'XML comment has a param tag, but there is no parameter by that name', Category: Compiler, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Warning], IsEverSuppressed: true}
+- {Id: CS1573, Title: Parameter has no matching param tag in the XML comment (but other parameters do), Category: Compiler, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Warning], IsEverSuppressed: true}
+- {Id: CS1574, Title: XML comment has cref attribute that could not be resolved, Category: Compiler, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Warning], IsEverSuppressed: true}
+- {Id: CS1734, Title: 'XML comment has a paramref tag, but there is no parameter by that name', Category: Compiler, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Warning], IsEverSuppressed: true}
+- {Id: CS8669, Title: The annotation for nullable reference types should only be used in code within a '#nullable' annotations context. Auto-generated code requires an explicit '#nullable' directive in source., Category: Compiler, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Warning], IsEverSuppressed: true}
+- {Id: CS9216, Title: A value of type 'System.Threading.Lock' converted to a different type will use likely unintended monitor-based locking in 'lock' statement., 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}
@@ -330,8 +339,24 @@
- {Id: EM0104, Title: Duplicate Closed Attribute, Category: Logic, DefaultSeverity: Error, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
- {Id: EM0105, Title: Duplicate Case Type, Category: Logic, DefaultSeverity: Error, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
- {Id: EnableGenerateDocumentationFile, Title: Set MSBuild property 'GenerateDocumentationFile' to 'true', Category: Style, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: HAA0101, Title: Array allocation for params parameter, Category: Performance, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: HAA0102, Title: Non-overridden virtual method call on value type, Category: Performance, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: HAA0201, Title: Implicit string concatenation allocation, Category: Performance, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: HAA0202, Title: Value type to reference type conversion allocation for string concatenation, Category: Performance, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: HAA0301, Title: Closure Allocation Source, Category: Performance, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: HAA0302, Title: Display class allocation to capture closure, Category: Performance, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: HAA0303, Title: Lambda or anonymous method in a generic method allocates a delegate instance, Category: Performance, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: HAA0401, Title: Possible allocation of reference type enumerator, Category: Performance, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: HAA0501, Title: Explicit new array type allocation, Category: Performance, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Note], IsEverSuppressed: false}
+- {Id: HAA0502, Title: Explicit new reference type allocation, Category: Performance, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Note], IsEverSuppressed: false}
+- {Id: HAA0503, Title: Explicit new anonymous object allocation, Category: Performance, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Note], IsEverSuppressed: false}
+- {Id: HAA0506, Title: Let clause induced allocation, Category: Performance, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Note], IsEverSuppressed: false}
+- {Id: HAA0601, Title: Value type to reference type conversion causing boxing allocation, Category: Performance, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: HAA0602, Title: Delegate on struct instance caused a boxing allocation, Category: Performance, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: HAA0603, Title: Delegate allocation from a method group, Category: Performance, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: HAA0604, Title: Delegate allocation from a method group, Category: Performance, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Note], IsEverSuppressed: false}
- {Id: IDE0004, Title: Remove Unnecessary Cast, Category: Style, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Note], IsEverSuppressed: true}
-- {Id: IDE0005, Title: Using directive is unnecessary., Category: Style, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Note], IsEverSuppressed: true}
+- {Id: IDE0005, Title: Using directive is unnecessary., Category: Style, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Note], IsEverSuppressed: false}
- {Id: IDE0005_gen, Title: Using directive is unnecessary., Category: Style, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Note], IsEverSuppressed: true}
- {Id: IDE0007, Title: Use implicit type, Category: Style, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Note], IsEverSuppressed: false}
- {Id: IDE0008, Title: Use explicit type, Category: Style, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Note], IsEverSuppressed: false}
@@ -603,7 +628,6 @@
- {Id: MA0163, Title: UseShellExecute must be false when redirecting standard input or output, Category: Usage, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
- {Id: MA0164, Title: Use parentheses to make not pattern clearer, Category: Style, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
- {Id: MA0165, Title: Make interpolated string, Category: Usage, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Note], IsEverSuppressed: true}
-- {Id: POLYSP0003, Title: Unsupported C# language version, Category: Microsoft.CodeAnalysis.CSharp.CSharpParseOptions, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
- {Id: RCS1001, Title: Add braces (when expression spans over multiple lines), Category: Roslynator, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Note], IsEverSuppressed: false}
- {Id: RCS1002, Title: Remove braces, Category: Roslynator, DefaultSeverity: Note, IsEnabledByDefault: false, EffectiveSeverities: [None], IsEverSuppressed: false}
- {Id: RCS1002FadeOut, Title: Remove braces, Category: Roslynator, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Note], IsEverSuppressed: false}
@@ -886,7 +910,7 @@
- {Id: RS1032, Title: Define diagnostic message correctly, Category: MicrosoftCodeAnalysisDesign, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
- {Id: RS1033, Title: Define diagnostic description correctly, Category: MicrosoftCodeAnalysisDesign, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
- {Id: RS1034, Title: Prefer 'IsKind' for checking syntax kinds, Category: MicrosoftCodeAnalysisPerformance, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
-- {Id: RS1035, Title: Do not use APIs banned for analyzers, Category: MicrosoftCodeAnalysisCorrectness, DefaultSeverity: Error, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: RS1035, Title: Do not use APIs banned for analyzers, Category: MicrosoftCodeAnalysisCorrectness, DefaultSeverity: Error, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: true}
- {Id: RS1036, Title: Specify analyzer banned API enforcement setting, Category: MicrosoftCodeAnalysisCorrectness, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
- {Id: RS1037, Title: Add "CompilationEnd" custom tag to compilation end diagnostic descriptor, Category: MicrosoftCodeAnalysisDesign, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
- {Id: RS1038, Title: Compiler extensions should be implemented in assemblies with compiler-provided references, Category: MicrosoftCodeAnalysisCorrectness, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
@@ -1404,7 +1428,7 @@
- {Id: SA1027, Title: Use tabs correctly, Category: StyleCop.CSharp.SpacingRules, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
- {Id: SA1028, Title: Code should not contain trailing whitespace, Category: StyleCop.CSharp.SpacingRules, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
- {Id: SA1100, Title: Do not prefix calls with base unless local implementation exists, Category: StyleCop.CSharp.ReadabilityRules, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
-- {Id: SA1101, Title: Prefix local calls with this, Category: StyleCop.CSharp.ReadabilityRules, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error, Note], IsEverSuppressed: false}
+- {Id: SA1101, Title: Prefix local calls with this, Category: StyleCop.CSharp.ReadabilityRules, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error, Note], IsEverSuppressed: true}
- {Id: SA1102, Title: Query clause should follow previous clause, Category: StyleCop.CSharp.ReadabilityRules, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
- {Id: SA1103, Title: Query clauses should be on separate lines or all on one line, Category: StyleCop.CSharp.ReadabilityRules, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
- {Id: SA1104, Title: Query clause should begin on new line when previous clause spans multiple lines, Category: StyleCop.CSharp.ReadabilityRules, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
@@ -1581,7 +1605,7 @@
- {Id: VSTHRD102, Title: Implement internal logic asynchronously, Category: Usage, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Note], IsEverSuppressed: false}
- {Id: VSTHRD103, Title: Call async methods when in an async method, Category: Usage, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
- {Id: VSTHRD104, Title: Offer async methods, Category: Usage, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Note], IsEverSuppressed: false}
-- {Id: VSTHRD105, Title: Avoid method overloads that assume TaskScheduler.Current, Category: Usage, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: VSTHRD105, Title: Avoid method overloads that assume TaskScheduler.Current, Category: Usage, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: true}
- {Id: VSTHRD106, Title: Use InvokeAsync to raise async events, Category: Usage, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
- {Id: VSTHRD107, Title: Await Task within using expression, Category: Usage, DefaultSeverity: Error, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
- {Id: VSTHRD108, Title: Assert thread affinity unconditionally, Category: Usage, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
diff --git a/src/BannedSymbols.txt b/src/BannedSymbols.txt
index 9f786f1f4..9e4720b50 100644
--- a/src/BannedSymbols.txt
+++ b/src/BannedSymbols.txt
@@ -6,3 +6,7 @@ M:Microsoft.CodeAnalysis.Diagnostic.Create(Microsoft.CodeAnalysis.DiagnosticDesc
M:Microsoft.CodeAnalysis.Diagnostic.Create(Microsoft.CodeAnalysis.DiagnosticDescriptor,Microsoft.CodeAnalysis.Location,Microsoft.CodeAnalysis.DiagnosticSeverity,System.Collections.Generic.IEnumerable{Microsoft.CodeAnalysis.Location},System.Collections.Immutable.ImmutableDictionary{System.String,System.String},System.Object[]);Use DiagnosticExtensions.CreateDiagnostic;Use DiagnosticExtensions.CreateDiagnostic
M:Microsoft.CodeAnalysis.Diagnostic.Create(System.String,System.String,Microsoft.CodeAnalysis.LocalizableString,Microsoft.CodeAnalysis.DiagnosticSeverity,Microsoft.CodeAnalysis.DiagnosticSeverity,System.Boolean,System.Int32,Microsoft.CodeAnalysis.LocalizableString,Microsoft.CodeAnalysis.LocalizableString,System.String,Microsoft.CodeAnalysis.Location,System.Collections.Generic.IEnumerable{Microsoft.CodeAnalysis.Location},System.Collections.Generic.IEnumerable{System.String},System.Collections.Immutable.ImmutableDictionary{System.String,System.String});Use DiagnosticExtensions.CreateDiagnostic
M:Microsoft.CodeAnalysis.Diagnostic.Create(System.String,System.String,Microsoft.CodeAnalysis.LocalizableString,Microsoft.CodeAnalysis.DiagnosticSeverity,Microsoft.CodeAnalysis.DiagnosticSeverity,System.Boolean,System.Int32,System.Boolean,Microsoft.CodeAnalysis.LocalizableString,Microsoft.CodeAnalysis.LocalizableString,System.String,Microsoft.CodeAnalysis.Location,System.Collections.Generic.IEnumerable{Microsoft.CodeAnalysis.Location},System.Collections.Generic.IEnumerable{System.String},System.Collections.Immutable.ImmutableDictionary{System.String,System.String});Use DiagnosticExtensions.CreateDiagnostic
+
+// Prefer KnownSymbols over Compilation.GetTypeByMetadataName
+M:Microsoft.CodeAnalysis.Compilation.GetTypeByMetadataName(System.String); Use KnownSymbols
+M:Microsoft.CodeAnalysis.Compilation.GetTypesByMetadataName(System.String); Use KnownSymbols
diff --git a/src/CodeFixes/CallbackSignatureShouldMatchMockedMethodCodeFix.cs b/src/CodeFixes/CallbackSignatureShouldMatchMockedMethodCodeFix.cs
index bf799d8ab..3fe5007e9 100644
--- a/src/CodeFixes/CallbackSignatureShouldMatchMockedMethodCodeFix.cs
+++ b/src/CodeFixes/CallbackSignatureShouldMatchMockedMethodCodeFix.cs
@@ -52,17 +52,19 @@ private static async Task FixCallbackSignatureAsync(SyntaxNode root, D
{
SemanticModel? semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
- if (semanticModel == null)
+ if (semanticModel is null)
{
return document;
}
+ MoqKnownSymbols knownSymbols = new(semanticModel.Compilation);
+
if (oldParameters?.Parent?.Parent?.Parent?.Parent is not InvocationExpressionSyntax callbackInvocation)
{
return document;
}
- InvocationExpressionSyntax? setupMethodInvocation = semanticModel.FindSetupMethodFromCallbackInvocation(callbackInvocation, cancellationToken);
+ InvocationExpressionSyntax? setupMethodInvocation = semanticModel.FindSetupMethodFromCallbackInvocation(knownSymbols, callbackInvocation, cancellationToken);
Debug.Assert(setupMethodInvocation != null, nameof(setupMethodInvocation) + " != null");
IMethodSymbol[] matchingMockedMethods = semanticModel.GetAllMatchingMockedMethodSymbolsFromSetupMethodInvocation(setupMethodInvocation).ToArray();
diff --git a/src/CodeFixes/SquiggleCop.Baseline.yaml b/src/CodeFixes/SquiggleCop.Baseline.yaml
index 6c13ce870..e1d8ca6ad 100644
--- a/src/CodeFixes/SquiggleCop.Baseline.yaml
+++ b/src/CodeFixes/SquiggleCop.Baseline.yaml
@@ -307,6 +307,15 @@
- {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: CS0419, Title: Ambiguous reference in cref attribute, Category: Compiler, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Warning], IsEverSuppressed: true}
+- {Id: CS0649, Title: 'Field is never assigned to, and will always have its default value', Category: Compiler, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Warning], IsEverSuppressed: true}
+- {Id: CS1570, Title: XML comment has badly formed XML, Category: Compiler, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Warning], IsEverSuppressed: true}
+- {Id: CS1572, Title: 'XML comment has a param tag, but there is no parameter by that name', Category: Compiler, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Warning], IsEverSuppressed: true}
+- {Id: CS1573, Title: Parameter has no matching param tag in the XML comment (but other parameters do), Category: Compiler, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Warning], IsEverSuppressed: true}
+- {Id: CS1574, Title: XML comment has cref attribute that could not be resolved, Category: Compiler, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Warning], IsEverSuppressed: true}
+- {Id: CS1734, Title: 'XML comment has a paramref tag, but there is no parameter by that name', Category: Compiler, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Warning], IsEverSuppressed: true}
+- {Id: CS8669, Title: The annotation for nullable reference types should only be used in code within a '#nullable' annotations context. Auto-generated code requires an explicit '#nullable' directive in source., Category: Compiler, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Warning], IsEverSuppressed: true}
+- {Id: CS9216, Title: A value of type 'System.Threading.Lock' converted to a different type will use likely unintended monitor-based locking in 'lock' statement., 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}
@@ -314,7 +323,7 @@
- {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: 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}
@@ -330,6 +339,22 @@
- {Id: EM0104, Title: Duplicate Closed Attribute, Category: Logic, DefaultSeverity: Error, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
- {Id: EM0105, Title: Duplicate Case Type, Category: Logic, DefaultSeverity: Error, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
- {Id: EnableGenerateDocumentationFile, Title: Set MSBuild property 'GenerateDocumentationFile' to 'true', Category: Style, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: HAA0101, Title: Array allocation for params parameter, Category: Performance, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: HAA0102, Title: Non-overridden virtual method call on value type, Category: Performance, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: HAA0201, Title: Implicit string concatenation allocation, Category: Performance, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: HAA0202, Title: Value type to reference type conversion allocation for string concatenation, Category: Performance, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: HAA0301, Title: Closure Allocation Source, Category: Performance, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: HAA0302, Title: Display class allocation to capture closure, Category: Performance, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: HAA0303, Title: Lambda or anonymous method in a generic method allocates a delegate instance, Category: Performance, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: HAA0401, Title: Possible allocation of reference type enumerator, Category: Performance, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: HAA0501, Title: Explicit new array type allocation, Category: Performance, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Note], IsEverSuppressed: false}
+- {Id: HAA0502, Title: Explicit new reference type allocation, Category: Performance, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Note], IsEverSuppressed: false}
+- {Id: HAA0503, Title: Explicit new anonymous object allocation, Category: Performance, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Note], IsEverSuppressed: false}
+- {Id: HAA0506, Title: Let clause induced allocation, Category: Performance, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Note], IsEverSuppressed: false}
+- {Id: HAA0601, Title: Value type to reference type conversion causing boxing allocation, Category: Performance, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: HAA0602, Title: Delegate on struct instance caused a boxing allocation, Category: Performance, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: HAA0603, Title: Delegate allocation from a method group, Category: Performance, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: HAA0604, Title: Delegate allocation from a method group, Category: Performance, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Note], IsEverSuppressed: false}
- {Id: IDE0004, Title: Remove Unnecessary Cast, Category: Style, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Note], IsEverSuppressed: true}
- {Id: IDE0005, Title: Using directive is unnecessary., Category: Style, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Note], IsEverSuppressed: true}
- {Id: IDE0005_gen, Title: Using directive is unnecessary., Category: Style, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Note], IsEverSuppressed: true}
@@ -488,7 +513,7 @@
- {Id: MA0048, Title: File name must match type name, Category: Design, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
- {Id: MA0049, Title: Type name should not match containing namespace, Category: Design, DefaultSeverity: Error, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
- {Id: MA0050, Title: Validate arguments correctly in iterator methods, Category: Design, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Note], IsEverSuppressed: false}
-- {Id: MA0051, Title: Method is too long, Category: Design, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: MA0051, Title: Method is too long, Category: Design, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: true}
- {Id: MA0052, Title: Replace constant Enum.ToString with nameof, Category: Performance, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Note], IsEverSuppressed: false}
- {Id: MA0053, Title: Make class sealed, Category: Design, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Note], IsEverSuppressed: false}
- {Id: MA0054, Title: Embed the caught exception as innerException, Category: Design, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
@@ -603,7 +628,6 @@
- {Id: MA0163, Title: UseShellExecute must be false when redirecting standard input or output, Category: Usage, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
- {Id: MA0164, Title: Use parentheses to make not pattern clearer, Category: Style, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
- {Id: MA0165, Title: Make interpolated string, Category: Usage, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Note], IsEverSuppressed: true}
-- {Id: POLYSP0003, Title: Unsupported C# language version, Category: Microsoft.CodeAnalysis.CSharp.CSharpParseOptions, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
- {Id: RCS1001, Title: Add braces (when expression spans over multiple lines), Category: Roslynator, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Note], IsEverSuppressed: false}
- {Id: RCS1002, Title: Remove braces, Category: Roslynator, DefaultSeverity: Note, IsEnabledByDefault: false, EffectiveSeverities: [None], IsEverSuppressed: false}
- {Id: RCS1002FadeOut, Title: Remove braces, Category: Roslynator, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Note], IsEverSuppressed: false}
@@ -1404,7 +1428,7 @@
- {Id: SA1027, Title: Use tabs correctly, Category: StyleCop.CSharp.SpacingRules, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
- {Id: SA1028, Title: Code should not contain trailing whitespace, Category: StyleCop.CSharp.SpacingRules, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
- {Id: SA1100, Title: Do not prefix calls with base unless local implementation exists, Category: StyleCop.CSharp.ReadabilityRules, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
-- {Id: SA1101, Title: Prefix local calls with this, Category: StyleCop.CSharp.ReadabilityRules, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error, Note], IsEverSuppressed: false}
+- {Id: SA1101, Title: Prefix local calls with this, Category: StyleCop.CSharp.ReadabilityRules, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error, Note], IsEverSuppressed: true}
- {Id: SA1102, Title: Query clause should follow previous clause, Category: StyleCop.CSharp.ReadabilityRules, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
- {Id: SA1103, Title: Query clauses should be on separate lines or all on one line, Category: StyleCop.CSharp.ReadabilityRules, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
- {Id: SA1104, Title: Query clause should begin on new line when previous clause spans multiple lines, Category: StyleCop.CSharp.ReadabilityRules, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
@@ -1581,7 +1605,7 @@
- {Id: VSTHRD102, Title: Implement internal logic asynchronously, Category: Usage, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Note], IsEverSuppressed: false}
- {Id: VSTHRD103, Title: Call async methods when in an async method, Category: Usage, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
- {Id: VSTHRD104, Title: Offer async methods, Category: Usage, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Note], IsEverSuppressed: false}
-- {Id: VSTHRD105, Title: Avoid method overloads that assume TaskScheduler.Current, Category: Usage, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: VSTHRD105, Title: Avoid method overloads that assume TaskScheduler.Current, Category: Usage, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: true}
- {Id: VSTHRD106, Title: Use InvokeAsync to raise async events, Category: Usage, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
- {Id: VSTHRD107, Title: Await Task within using expression, Category: Usage, DefaultSeverity: Error, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
- {Id: VSTHRD108, Title: Assert thread affinity unconditionally, Category: Usage, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
diff --git a/src/Common/Caching/BoundedCacheWithFactory.cs b/src/Common/Caching/BoundedCacheWithFactory.cs
new file mode 100644
index 000000000..db39f7d3e
--- /dev/null
+++ b/src/Common/Caching/BoundedCacheWithFactory.cs
@@ -0,0 +1,78 @@
+// Forked from https://github.com/dotnet/roslyn-analyzers/blob/5dd0dd5db8fa79932517f153854c0f2c24ac98a3/src/Utilities/Compiler/BoundedCacheWithFactory.cs
+
+namespace Moq.Analyzers.Common.Caching;
+
+///
+/// Provides bounded cache for analyzers.
+/// Acts as a good alternative to
+/// when the cached value has a cyclic reference to the key preventing early garbage collection of entries.
+///
+/// The type to use as a cache key.
+/// The type to use as the cached value.
+internal class BoundedCacheWithFactory
+ where TKey : class
+{
+ // Bounded weak reference cache.
+ // Size 5 is an arbitrarily chosen bound, which can be tuned in future as required.
+ private readonly List> _weakReferencedEntries = new()
+ {
+ new WeakReference(null),
+ new WeakReference(null),
+ new WeakReference(null),
+ new WeakReference(null),
+ new WeakReference(null),
+ };
+
+ public TValue GetOrCreateValue(TKey key, Func valueFactory)
+ {
+ lock (_weakReferencedEntries)
+ {
+ int indexToSetTarget = -1;
+ for (int i = 0; i < _weakReferencedEntries.Count; i++)
+ {
+ WeakReference weakReferencedEntry = _weakReferencedEntries[i];
+ if (!weakReferencedEntry.TryGetTarget(out Entry? cachedEntry) ||
+ cachedEntry == null)
+ {
+ if (indexToSetTarget == -1)
+ {
+ indexToSetTarget = i;
+ }
+
+ continue;
+ }
+
+ if (Equals(cachedEntry.Key, key))
+ {
+ // Move the cache hit item to the end of the list
+ // so it would be least likely to be evicted on next cache miss.
+ _weakReferencedEntries.RemoveAt(i);
+ _weakReferencedEntries.Add(weakReferencedEntry);
+ return cachedEntry.Value;
+ }
+ }
+
+ if (indexToSetTarget == -1)
+ {
+ indexToSetTarget = 0;
+ }
+
+ Entry newEntry = new Entry(key, valueFactory(key));
+ _weakReferencedEntries[indexToSetTarget].SetTarget(newEntry);
+ return newEntry.Value;
+ }
+ }
+
+ private sealed class Entry
+ {
+ public Entry(TKey key, TValue value)
+ {
+ Key = key;
+ Value = value;
+ }
+
+ public TKey Key { get; }
+
+ public TValue Value { get; }
+ }
+}
diff --git a/src/Common/CompilationExtensions.cs b/src/Common/CompilationExtensions.cs
deleted file mode 100644
index ba775b298..000000000
--- a/src/Common/CompilationExtensions.cs
+++ /dev/null
@@ -1,39 +0,0 @@
-namespace Moq.Analyzers.Common;
-
-internal static class CompilationExtensions
-{
- ///
- /// An extension method that performs for multiple metadata names.
- ///
- /// The to inspect.
- /// A list of type names to query.
- /// if the type can't be found or there was an ambiguity during lookup.
- public static ImmutableArray GetTypesByMetadataNames(this Compilation compilation, ReadOnlySpan metadataNames)
- {
- ImmutableArray.Builder builder = ImmutableArray.CreateBuilder(metadataNames.Length);
-
- foreach (string metadataName in metadataNames)
- {
- INamedTypeSymbol? type = compilation.GetTypeByMetadataName(metadataName);
- if (type is not null)
- {
- builder.Add(type);
- }
- }
-
- return builder.ToImmutable();
- }
-
- ///
- /// Get the Moq.MockRepository, Moq.Mock and Moq.Mock`1 type symbols (if part of the compilation).
- ///
- /// The to inspect.
- ///
- /// s for the Moq.Mock symbols that are part of the compilation.
- /// An empty array if none (never ).
- ///
- public static ImmutableArray GetMoqMock(this Compilation compilation)
- {
- return compilation.GetTypesByMetadataNames([WellKnownMoqNames.FullyQualifiedMoqMockTypeName, WellKnownMoqNames.FullyQualifiedMoqMock1TypeName, WellKnownMoqNames.FullyQualifiedMoqRepositoryTypeName]);
- }
-}
diff --git a/src/Common/EnumerableExtensions.cs b/src/Common/EnumerableExtensions.cs
index b13551681..d02d03509 100644
--- a/src/Common/EnumerableExtensions.cs
+++ b/src/Common/EnumerableExtensions.cs
@@ -40,4 +40,16 @@ internal static class EnumerableExtensions
return item;
}
+
+ public static IEnumerable WhereNotNull(this IEnumerable source)
+ where TSource : class
+ {
+ return source.Where(item => item is not null)!;
+ }
+
+ public static IEnumerable WhereNotNull(this IEnumerable source)
+ where TSource : struct
+ {
+ return source.Where(item => item.HasValue).Select(item => item!.Value);
+ }
}
diff --git a/src/Common/GlobalUsings.cs b/src/Common/GlobalUsings.cs
index 785ced225..c515e83aa 100644
--- a/src/Common/GlobalUsings.cs
+++ b/src/Common/GlobalUsings.cs
@@ -4,3 +4,4 @@
global using Microsoft.CodeAnalysis.CSharp.Syntax;
global using Microsoft.CodeAnalysis.Diagnostics;
global using Moq.Analyzers.Common;
+global using Moq.Analyzers.Common.WellKnown;
diff --git a/src/Common/ISymbolExtensions.cs b/src/Common/ISymbolExtensions.cs
index 10041de45..77bb4e115 100644
--- a/src/Common/ISymbolExtensions.cs
+++ b/src/Common/ISymbolExtensions.cs
@@ -21,7 +21,7 @@ internal static class ISymbolExtensions
///
/// MyType<int>() is an instance of MyType<T>().
///
- public static bool IsInstanceOf(this ISymbol symbol, TSymbol other, SymbolEqualityComparer? symbolEqualityComparer = null)
+ public static bool IsInstanceOf(this ISymbol? symbol, TSymbol? other, SymbolEqualityComparer? symbolEqualityComparer = null)
where TSymbol : class, ISymbol
{
symbolEqualityComparer ??= SymbolEqualityComparer.Default;
@@ -79,4 +79,51 @@ public static bool IsOverridable(this ISymbol symbol)
{
return !symbol.IsSealed && (symbol.IsVirtual || symbol.IsAbstract || symbol.IsOverride);
}
+
+ public static SymbolVisibility GetResultantVisibility(this ISymbol symbol)
+ {
+ // Start by assuming it's visible.
+ SymbolVisibility visibility = SymbolVisibility.Public;
+
+ switch (symbol.Kind)
+ {
+ case SymbolKind.Alias:
+ // Aliases are uber private. They're only visible in the same file that they
+ // were declared in.
+ return SymbolVisibility.Private;
+
+ case SymbolKind.Parameter:
+ // Parameters are only as visible as their containing symbol
+ return GetResultantVisibility(symbol.ContainingSymbol);
+
+ case SymbolKind.TypeParameter:
+ // Type Parameters are private.
+ return SymbolVisibility.Private;
+ }
+
+ while (symbol != null && symbol.Kind != SymbolKind.Namespace)
+ {
+ switch (symbol.DeclaredAccessibility)
+ {
+ // If we see anything private, then the symbol is private.
+ case Accessibility.NotApplicable:
+ case Accessibility.Private:
+ return SymbolVisibility.Private;
+
+ // If we see anything internal, then knock it down from public to
+ // internal.
+ case Accessibility.Internal:
+ case Accessibility.ProtectedAndInternal:
+ visibility = SymbolVisibility.Internal;
+ break;
+
+ // For anything else (Public, Protected, ProtectedOrInternal), the
+ // symbol stays at the level we've gotten so far.
+ }
+
+ symbol = symbol.ContainingSymbol;
+ }
+
+ return visibility;
+ }
}
diff --git a/src/Common/ITypeSymbolExtensions.cs b/src/Common/ITypeSymbolExtensions.cs
new file mode 100644
index 000000000..23134f5e2
--- /dev/null
+++ b/src/Common/ITypeSymbolExtensions.cs
@@ -0,0 +1,22 @@
+namespace Moq.Analyzers.Common;
+
+internal static class ITypeSymbolExtensions
+{
+ ///
+ /// Get the base types of a type, including the type itself.
+ ///
+ ///
+ /// Use this to walk the inheritance chain of a type.
+ ///
+ /// The to walk.
+ /// The type and any inherited types.
+ public static IEnumerable GetBaseTypesAndThis(this ITypeSymbol type)
+ {
+ var current = type;
+ while (current is not null)
+ {
+ yield return current;
+ current = current.BaseType;
+ }
+ }
+}
diff --git a/src/Common/MoqMethodDescriptorBase.cs b/src/Common/MoqMethodDescriptorBase.cs
deleted file mode 100644
index f531b8b71..000000000
--- a/src/Common/MoqMethodDescriptorBase.cs
+++ /dev/null
@@ -1,26 +0,0 @@
-namespace Moq.Analyzers.Common;
-
-///
-/// A base that provides common functionality for identifying if a given
-/// is a specific Moq method.
-///
-///
-/// Currently the abstract method
-/// is specific to because that's the only type of syntax in use. I expect we'll need
-/// to loosen this restriction if we start using other types of syntax.
-///
-internal abstract class MoqMethodDescriptorBase
-{
- private static readonly string ContainingNamespace = WellKnownMoqNames.MoqNamespace;
- private static readonly string ContainingType = WellKnownMoqNames.MockTypeName;
-
- public abstract bool IsMatch(SemanticModel semanticModel, MemberAccessExpressionSyntax memberAccessSyntax, CancellationToken cancellationToken);
-
- protected static bool IsFastMatch(MemberAccessExpressionSyntax memberAccessSyntax, ReadOnlySpan methodName) => memberAccessSyntax.Name.Identifier.Text.AsSpan().SequenceEqual(methodName);
-
- protected static bool IsContainedInMockType(IMethodSymbol methodSymbol) => IsInMoqNamespace(methodSymbol) && IsInMockType(methodSymbol);
-
- private static bool IsInMoqNamespace(ISymbol symbol) => symbol.ContainingNamespace.Name.AsSpan().SequenceEqual(ContainingNamespace.AsSpan());
-
- private static bool IsInMockType(ISymbol symbol) => symbol.ContainingType.Name.AsSpan().SequenceEqual(ContainingType.AsSpan());
-}
diff --git a/src/Common/MoqSetupMethodDescriptor.cs b/src/Common/MoqSetupMethodDescriptor.cs
deleted file mode 100644
index 28d94826b..000000000
--- a/src/Common/MoqSetupMethodDescriptor.cs
+++ /dev/null
@@ -1,32 +0,0 @@
-namespace Moq.Analyzers.Common;
-
-///
-/// A class that, given a and a , determines if
-/// it is a call to the Moq `Mock.Setup()` method.
-///
-internal class MoqSetupMethodDescriptor : MoqMethodDescriptorBase
-{
- private static readonly string MethodName = "Setup";
-
- public override bool IsMatch(SemanticModel semanticModel, MemberAccessExpressionSyntax memberAccessSyntax, CancellationToken cancellationToken)
- {
- if (!IsFastMatch(memberAccessSyntax, MethodName.AsSpan()))
- {
- return false;
- }
-
- ISymbol? symbol = semanticModel.GetSymbolInfo(memberAccessSyntax, cancellationToken).Symbol;
-
- if (symbol is not IMethodSymbol methodSymbol)
- {
- return false;
- }
-
- if (!IsContainedInMockType(methodSymbol))
- {
- return false;
- }
-
- return methodSymbol.Name.AsSpan().SequenceEqual(MethodName.AsSpan()) && methodSymbol.IsGenericMethod;
- }
-}
diff --git a/src/Common/SemanticModelExtensions.cs b/src/Common/SemanticModelExtensions.cs
index fb46aafa6..08620c0b9 100644
--- a/src/Common/SemanticModelExtensions.cs
+++ b/src/Common/SemanticModelExtensions.cs
@@ -7,9 +7,7 @@ namespace Moq.Analyzers.Common;
///
internal static class SemanticModelExtensions
{
- private static readonly MoqMethodDescriptorBase MoqSetupMethodDescriptor = new MoqSetupMethodDescriptor();
-
- internal static InvocationExpressionSyntax? FindSetupMethodFromCallbackInvocation(this SemanticModel semanticModel, ExpressionSyntax expression, CancellationToken cancellationToken)
+ internal static InvocationExpressionSyntax? FindSetupMethodFromCallbackInvocation(this SemanticModel semanticModel, MoqKnownSymbols knownSymbols, ExpressionSyntax expression, CancellationToken cancellationToken)
{
InvocationExpressionSyntax? invocation = expression as InvocationExpressionSyntax;
if (invocation?.Expression is not MemberAccessExpressionSyntax method)
@@ -17,12 +15,18 @@ internal static class SemanticModelExtensions
return null;
}
- if (semanticModel.IsMoqSetupMethod(method, cancellationToken))
+ SymbolInfo symbolInfo = semanticModel.GetSymbolInfo(method, cancellationToken);
+ if (symbolInfo.Symbol is null)
+ {
+ return null;
+ }
+
+ if (semanticModel.IsMoqSetupMethod(knownSymbols, symbolInfo.Symbol, cancellationToken))
{
return invocation;
}
- return semanticModel.FindSetupMethodFromCallbackInvocation(method.Expression, cancellationToken);
+ return semanticModel.FindSetupMethodFromCallbackInvocation(knownSymbols, method.Expression, cancellationToken);
}
internal static IEnumerable GetAllMatchingMockedMethodSymbolsFromSetupMethodInvocation(this SemanticModel semanticModel, InvocationExpressionSyntax? setupMethodInvocation)
@@ -61,9 +65,9 @@ internal static bool IsCallbackOrReturnInvocation(this SemanticModel semanticMod
};
}
- internal static bool IsMoqSetupMethod(this SemanticModel semanticModel, MemberAccessExpressionSyntax method, CancellationToken cancellationToken)
+ internal static bool IsMoqSetupMethod(this SemanticModel semanticModel, MoqKnownSymbols knownSymbols, ISymbol symbol, CancellationToken cancellationToken)
{
- return MoqSetupMethodDescriptor.IsMatch(semanticModel, method, cancellationToken);
+ return symbol.IsInstanceOf(knownSymbols.Mock1Setup) && symbol is IMethodSymbol { IsGenericMethod: true };
}
private static List GetAllMatchingSymbols(this SemanticModel semanticModel, ExpressionSyntax expression)
diff --git a/src/Common/SymbolVisibility.cs b/src/Common/SymbolVisibility.cs
new file mode 100644
index 000000000..78f0136c7
--- /dev/null
+++ b/src/Common/SymbolVisibility.cs
@@ -0,0 +1,24 @@
+namespace Moq.Analyzers.Common;
+
+internal enum SymbolVisibility
+{
+ ///
+ /// Public symbol visibility.
+ ///
+ Public = 0,
+
+ ///
+ /// Internal symbol visibility.
+ ///
+ Internal = 1,
+
+ ///
+ /// Private symbol visibility.
+ ///
+ Private = 2,
+
+ ///
+ /// Internal symbol visibility.
+ ///
+ Friend = Internal,
+}
diff --git a/src/Common/WellKnown/KnownSymbols.cs b/src/Common/WellKnown/KnownSymbols.cs
new file mode 100644
index 000000000..cc522bbdd
--- /dev/null
+++ b/src/Common/WellKnown/KnownSymbols.cs
@@ -0,0 +1,44 @@
+namespace Moq.Analyzers.Common.WellKnown;
+
+///
+/// Main entrypoint to access well-known symbols for the analyzer.
+/// This class handles caching to prevent multiple lookups for the same symbol.
+///
+/// It returns a type derived from in all cases. Use the
+/// when necessary
+/// for comparisons with s.
+///
+internal class KnownSymbols
+{
+ public KnownSymbols(WellKnownTypeProvider typeProvider)
+ {
+ TypeProvider = typeProvider;
+ }
+
+ public KnownSymbols(Compilation compilation)
+ : this(WellKnownTypeProvider.GetOrCreate(compilation))
+ {
+ }
+
+ ///
+ /// Gets the class System.Threading.Tasks.Task.
+ ///
+ public INamedTypeSymbol? Task => TypeProvider.GetOrCreateTypeByMetadataName("System.Threading.Tasks.Task");
+
+ ///
+ /// Gets the class System.Threading.Tasks.Task<T>.
+ ///
+ public INamedTypeSymbol? Task1 => TypeProvider.GetOrCreateTypeByMetadataName("System.Threading.Tasks.Task`1");
+
+ ///
+ /// Gets the class System.Threading.Tasks.ValueTask.
+ ///
+ public INamedTypeSymbol? ValueTask => TypeProvider.GetOrCreateTypeByMetadataName("System.Threading.Tasks.ValueTask");
+
+ ///
+ /// Gets the class System.Threading.Tasks.ValueTask<T>.
+ ///
+ public INamedTypeSymbol? ValueTask1 => TypeProvider.GetOrCreateTypeByMetadataName("System.Threading.Tasks.ValueTask`1");
+
+ protected WellKnownTypeProvider TypeProvider { get; }
+}
diff --git a/src/Common/WellKnown/MoqKnownSymbolExtensions.cs b/src/Common/WellKnown/MoqKnownSymbolExtensions.cs
new file mode 100644
index 000000000..2472a88cd
--- /dev/null
+++ b/src/Common/WellKnown/MoqKnownSymbolExtensions.cs
@@ -0,0 +1,9 @@
+namespace Moq.Analyzers.Common.WellKnown;
+
+internal static class MoqKnownSymbolExtensions
+{
+ public static bool IsMockReferenced(this MoqKnownSymbols mqs)
+ {
+ return mqs.Mock is not null || mqs.Mock1 is not null || mqs.MockRepository is not null;
+ }
+}
diff --git a/src/Common/WellKnown/MoqKnownSymbols.cs b/src/Common/WellKnown/MoqKnownSymbols.cs
new file mode 100644
index 000000000..045ba0f36
--- /dev/null
+++ b/src/Common/WellKnown/MoqKnownSymbols.cs
@@ -0,0 +1,83 @@
+using System.Diagnostics.CodeAnalysis;
+
+namespace Moq.Analyzers.Common.WellKnown;
+
+internal class MoqKnownSymbols : KnownSymbols
+{
+ public MoqKnownSymbols(WellKnownTypeProvider typeProvider)
+ : base(typeProvider)
+ {
+ }
+
+ public MoqKnownSymbols(Compilation compilation)
+ : base(compilation)
+ {
+ }
+
+ ///
+ /// Gets the class Moq.Mock.
+ ///
+ public INamedTypeSymbol? Mock => TypeProvider.GetOrCreateTypeByMetadataName("Moq.Mock");
+
+ ///
+ /// Gets the methods for Moq.Mock.As.
+ ///
+ public ImmutableArray MockAs => Mock?.GetMembers("As").OfType().ToImmutableArray() ?? ImmutableArray.Empty;
+
+ ///
+ /// Gets the methods for Moq.Mock.Of.
+ ///
+ public ImmutableArray MockOf => Mock?.GetMembers("Of").OfType().ToImmutableArray() ?? ImmutableArray.Empty;
+
+ ///
+ /// Gets the class Moq.Mock<T>.
+ ///
+ public INamedTypeSymbol? Mock1 => TypeProvider.GetOrCreateTypeByMetadataName("Moq.Mock`1");
+
+ ///
+ /// Gets the methods for Moq.Mock<T>.As.
+ ///
+ public ImmutableArray Mock1As => Mock1?.GetMembers("As").OfType().ToImmutableArray() ?? ImmutableArray.Empty;
+
+ ///
+ /// Gets the methods for Moq.Mock<T>.Setup.
+ ///
+ public ImmutableArray Mock1Setup => Mock1?.GetMembers("Setup").OfType().ToImmutableArray() ?? ImmutableArray.Empty;
+
+ ///
+ /// Gets the class Moq.MockRepository.
+ ///
+ public INamedTypeSymbol? MockRepository => TypeProvider.GetOrCreateTypeByMetadataName("Moq.MockRepository");
+
+ ///
+ /// Gets the methods for Moq.MockRepository.Of.
+ ///
+ ///
+ /// MockRepository is a subclass of MockFactory.
+ /// However, MockFactory is marked as obsolete. To avoid coupling
+ /// ourselves to this implementation detail, we walk base types
+ /// when looking for members.
+ ///
+ [SuppressMessage("Performance", "ECS0900:Minimize boxing and unboxing", Justification = "Minor perf issues. Should revisit later.")]
+ public ImmutableArray MockRepositoryCreate => MockRepository?.GetBaseTypesAndThis().SelectMany(type => type.GetMembers("Create")).OfType().ToImmutableArray() ?? ImmutableArray.Empty;
+
+ ///
+ /// Gets the enum Moq.MockBehavior.
+ ///
+ public INamedTypeSymbol? MockBehavior => TypeProvider.GetOrCreateTypeByMetadataName("Moq.MockBehavior");
+
+ ///
+ /// Gets the field Moq.MockBehavior.Strict.
+ ///
+ public IFieldSymbol? MockBehaviorStrict => MockBehavior?.GetMembers("Strict").OfType().SingleOrDefault();
+
+ ///
+ /// Gets the field Moq.MockBehavior.Loose.
+ ///
+ public IFieldSymbol? MockBehaviorLoose => MockBehavior?.GetMembers("Loose").OfType().SingleOrDefault();
+
+ ///
+ /// Gets the field Moq.MockBehavior.Default.
+ ///
+ public IFieldSymbol? MockBehaviorDefault => MockBehavior?.GetMembers("Default").OfType().SingleOrDefault();
+}
diff --git a/src/Common/WellKnown/WellKnownTypeProvider.cs b/src/Common/WellKnown/WellKnownTypeProvider.cs
new file mode 100644
index 000000000..32e238765
--- /dev/null
+++ b/src/Common/WellKnown/WellKnownTypeProvider.cs
@@ -0,0 +1,288 @@
+// Forked from https://github.com/dotnet/roslyn-analyzers/blob/5dd0dd5db8fa79932517f153854c0f2c24ac98a3/src/Utilities/Compiler/WellKnownTypeProvider.cs
+
+using System.Collections.Concurrent;
+using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
+using System.Globalization;
+using Moq.Analyzers.Common.Caching;
+using Roslyn.Utilities;
+
+namespace Moq.Analyzers.Common.WellKnown;
+
+///
+/// Provides and caches well known types in a compilation.
+///
+internal class WellKnownTypeProvider
+{
+ private static readonly BoundedCacheWithFactory ProviderCache = new();
+
+ ///
+ /// Static cache of full type names (with namespaces) to namespace name parts,
+ /// so we can query .
+ ///
+ ///
+ /// Example: "System.Collections.Generic.List`1" => [ "System", "Collections", "Generic" ]
+ ///
+ /// https://github.com/dotnet/roslyn/blob/9e786147b8cb884af454db081bb747a5bd36a086/src/Compilers/CSharp/Portable/Symbols/AssemblySymbol.cs#L455
+ /// suggests the TypeNames collection can be checked to avoid expensive operations. But realizing TypeNames seems to be
+ /// as memory intensive as unnecessary calls GetTypeByMetadataName() in some cases. So we'll go with namespace names.
+ ///
+ private static readonly ConcurrentDictionary> _fullTypeNameToNamespaceNames =
+ new(StringComparer.Ordinal);
+
+ ///
+ /// All the referenced assembly symbols.
+ ///
+ ///
+ /// Seems to be less memory intensive than:
+ /// foreach (Compilation.Assembly.Modules)
+ /// foreach (Module.ReferencedAssemblySymbols).
+ ///
+ private readonly Lazy> _referencedAssemblies;
+
+ ///
+ /// Mapping of full name to .
+ ///
+ private readonly ConcurrentDictionary _fullNameToTypeMap;
+
+ [SuppressMessage("Performance", "ECS0900:Minimize boxing and unboxing", Justification = "Skipping for now. Should revisit.")]
+ private WellKnownTypeProvider(Compilation compilation)
+ {
+ Compilation = compilation;
+ _fullNameToTypeMap = new ConcurrentDictionary(StringComparer.Ordinal);
+ _referencedAssemblies = new Lazy>(
+ () =>
+ {
+ return Compilation.Assembly.Modules
+ .SelectMany(m => m.ReferencedAssemblySymbols)
+ .Distinct(SymbolEqualityComparer.Default)
+ .ToImmutableArray();
+ },
+ LazyThreadSafetyMode.ExecutionAndPublication);
+ }
+
+ ///
+ /// Gets the associated with this type provider.
+ ///
+ public Compilation Compilation { get; }
+
+ ///
+ /// Get an existing or create a new for the given .
+ ///
+ /// The to create the type provider from.
+ /// A associated with the given .
+ public static WellKnownTypeProvider GetOrCreate(Compilation compilation)
+ {
+ return ProviderCache.GetOrCreateValue(compilation, CreateWellKnownTypeProvider);
+
+ // Local functions
+ static WellKnownTypeProvider CreateWellKnownTypeProvider(Compilation compilation) => new(compilation);
+ }
+
+ ///
+ /// Attempts to get the type by the full type name.
+ ///
+ /// Namespace + type name, e.g. "System.Exception".
+ /// Named type symbol, if any.
+ /// True if found in the compilation, false otherwise.
+ [PerformanceSensitive("https://github.com/dotnet/roslyn-analyzers/issues/4893", AllowCaptures = false)]
+ public bool TryGetOrCreateTypeByMetadataName(
+ string fullTypeName,
+ [NotNullWhen(returnValue: true)] out INamedTypeSymbol? namedTypeSymbol)
+ {
+ if (_fullNameToTypeMap.TryGetValue(fullTypeName, out namedTypeSymbol))
+ {
+ return namedTypeSymbol is not null;
+ }
+
+ return TryGetOrCreateTypeByMetadataNameSlow(fullTypeName, out namedTypeSymbol);
+ }
+
+ ///
+ /// Gets a type by its full type name.
+ ///
+ /// Namespace + type name, e.g. "System.Exception".
+ /// The if found, null otherwise.
+ public INamedTypeSymbol? GetOrCreateTypeByMetadataName(string fullTypeName)
+ {
+ TryGetOrCreateTypeByMetadataName(fullTypeName, out INamedTypeSymbol? namedTypeSymbol);
+ return namedTypeSymbol;
+ }
+
+ private static ImmutableArray GetNamespaceNamesFromFullTypeName(string fullTypeName)
+ {
+ ImmutableArray.Builder namespaceNamesBuilder = ImmutableArray.CreateBuilder();
+
+ int prevStartIndex = 0;
+ for (int i = 0; i < fullTypeName.Length; i++)
+ {
+ if (fullTypeName[i] == '.')
+ {
+ namespaceNamesBuilder.Add(fullTypeName[prevStartIndex..i]);
+ prevStartIndex = i + 1;
+ }
+ else if (!IsIdentifierPartCharacter(fullTypeName[i]))
+ {
+ break;
+ }
+ }
+
+ return namespaceNamesBuilder.ToImmutable();
+ }
+
+ ///
+ /// Returns true if the Unicode character can be a part of an identifier.
+ ///
+ /// The Unicode character.
+ private static bool IsIdentifierPartCharacter(char ch)
+ {
+ // identifier-part-character:
+ // letter-character
+ // decimal-digit-character
+ // connecting-character
+ // combining-character
+ // formatting-character
+
+ // '\u0061'
+ if (ch < 'a')
+ {
+ // '\u0041'
+ if (ch < 'A')
+ {
+ // '\u0030' and '\u0039'
+ return ch is >= '0'
+ and <= '9';
+ }
+
+ // '\u005A' or '\u005F'
+ return ch is <= 'Z'
+ or '_';
+ }
+
+ // '\u007A'
+ if (ch <= 'z')
+ {
+ return true;
+ }
+
+ // max ASCII
+ if (ch <= '\u007F')
+ {
+ return false;
+ }
+
+ UnicodeCategory cat = CharUnicodeInfo.GetUnicodeCategory(ch);
+
+ return cat switch
+ {
+ // Letter
+ UnicodeCategory.UppercaseLetter
+ or UnicodeCategory.LowercaseLetter
+ or UnicodeCategory.TitlecaseLetter
+ or UnicodeCategory.ModifierLetter
+ or UnicodeCategory.OtherLetter
+ or UnicodeCategory.LetterNumber
+ or UnicodeCategory.DecimalDigitNumber
+ or UnicodeCategory.ConnectorPunctuation
+ or UnicodeCategory.NonSpacingMark
+ or UnicodeCategory.SpacingCombiningMark
+ or UnicodeCategory.Format => true,
+ _ => false,
+ };
+ }
+
+ private static bool IsSubsetOfCollection(ImmutableArray set1, ICollection set2)
+ {
+ if (set1.Length > set2.Count)
+ {
+ return false;
+ }
+
+ for (int i = 0; i < set1.Length; i++)
+ {
+ if (!set2.Contains(set1[i]))
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ [SuppressMessage("Design", "MA0051:Method is too long", Justification = "Forked from upstream. Avoiding refactoring to reduce divergence.")]
+ private bool TryGetOrCreateTypeByMetadataNameSlow(
+ string fullTypeName,
+ [NotNullWhen(returnValue: true)] out INamedTypeSymbol? namedTypeSymbol)
+ {
+ namedTypeSymbol = _fullNameToTypeMap.GetOrAdd(fullTypeName, ValueFactory, fullTypeName);
+
+ return namedTypeSymbol != null;
+
+ [SuppressMessage("Design", "MA0051:Method is too long", Justification = "Forked from upstream. Avoiding refactoring to reduce divergence.")]
+ INamedTypeSymbol? ValueFactory(string fullyQualifiedMetadataName, string fullTypeName)
+ {
+ // Caching null results is intended.
+
+ // sharwell says: Suppose you reference assembly A with public API X.Y, and you reference assembly B with
+ // internal API X.Y. Even though you can use X.Y from assembly A, compilation.GetTypeByMetadataName will
+ // fail outright because it finds two types with the same name.
+ INamedTypeSymbol? type = null;
+
+ ImmutableArray namespaceNames;
+ if (string.IsInterned(fullTypeName) != null)
+ {
+ namespaceNames = _fullTypeNameToNamespaceNames.GetOrAdd(
+ fullTypeName,
+ GetNamespaceNamesFromFullTypeName);
+ }
+ else
+ {
+ namespaceNames = GetNamespaceNamesFromFullTypeName(fullTypeName);
+ }
+
+ if (IsSubsetOfCollection(namespaceNames, Compilation.Assembly.NamespaceNames))
+ {
+ type = Compilation.Assembly.GetTypeByMetadataName(fullyQualifiedMetadataName);
+ }
+
+ if (type is null)
+ {
+ Debug.Assert(namespaceNames != null, $"{nameof(namespaceNames)} should not be null");
+
+ foreach (IAssemblySymbol? referencedAssembly in _referencedAssemblies.Value)
+ {
+ if (!IsSubsetOfCollection(namespaceNames, referencedAssembly.NamespaceNames))
+ {
+ continue;
+ }
+
+ INamedTypeSymbol? currentType = referencedAssembly.GetTypeByMetadataName(fullyQualifiedMetadataName);
+ if (currentType is null)
+ {
+ continue;
+ }
+
+ switch (currentType.GetResultantVisibility())
+ {
+ case SymbolVisibility.Public:
+ case SymbolVisibility.Internal when referencedAssembly.GivesAccessTo(Compilation.Assembly):
+ break;
+
+ default:
+ continue;
+ }
+
+ if (type is object)
+ {
+ // Multiple visible types with the same metadata name are present.
+ return null;
+ }
+
+ type = currentType;
+ }
+ }
+
+ return type;
+ }
+ }
+}
diff --git a/src/Common/WellKnownMoqNames.cs b/src/Common/WellKnownMoqNames.cs
deleted file mode 100644
index fdedd9387..000000000
--- a/src/Common/WellKnownMoqNames.cs
+++ /dev/null
@@ -1,74 +0,0 @@
-namespace Moq.Analyzers.Common;
-
-///
-/// Provides well-known names and fully qualified names for commonly used Moq types, namespaces, and members.
-///
-internal static class WellKnownMoqNames
-{
- ///
- /// Represents the namespace for the Moq library.
- ///
- internal static readonly string MoqNamespace = "Moq";
-
- ///
- /// Symbol name for Moq.
- ///
- internal static readonly string MoqSymbolName = "Moq";
-
- ///
- /// The name of the 'Moq.Mock' type.
- ///
- internal static readonly string MockTypeName = "Mock";
-
- ///
- /// The name of the 'Moq.MockBehavior' type.
- /// This type specifies the behavior of the mock (Strict, Loose, etc.).
- ///
- internal static readonly string MockBehaviorTypeName = "MockBehavior";
-
- ///
- /// The name of the 'Moq.MockFactory' type.
- /// This factory is used for creating multiple mock objects with a shared configuration.
- ///
- internal static readonly string MockFactoryTypeName = "MockFactory";
-
- ///
- /// Fully qualified name for the 'Moq.Mock' type.
- ///
- internal static readonly string FullyQualifiedMoqMockTypeName = $"{MoqNamespace}.{MockTypeName}";
-
- ///
- /// Fully qualified name for the generic version of 'Moq.Mock{T}'.
- /// Represents mocks for specific types.
- ///
- internal static readonly string FullyQualifiedMoqMock1TypeName = $"{FullyQualifiedMoqMockTypeName}`1";
-
- ///
- /// Fully qualified name for the 'Moq.MockBehavior' type.
- ///
- internal static readonly string FullyQualifiedMoqBehaviorTypeName = $"{MoqNamespace}.{MockBehaviorTypeName}";
-
- ///
- /// Fully qualified name for the 'Moq.MockRepository' type.
- /// This type acts as a container for multiple mocks and shared mock configurations.
- ///
- internal static readonly string FullyQualifiedMoqRepositoryTypeName = $"{MoqNamespace}.MockRepository";
-
- ///
- /// Represents the method name for the `As` method in Moq.
- /// This method is used to cast mocks to interfaces.
- ///
- internal static readonly string AsMethodName = "As";
-
- ///
- /// Represents the method name for the `Create` method in Moq.
- /// This method is used to create instances of mocks.
- ///
- internal static readonly string CreateMethodName = "Create";
-
- ///
- /// Represents the method name for the `Of` method in Moq.
- /// This method is used to create a mock from a type without directly specifying the constructor.
- ///
- internal static readonly string OfMethodName = "Of";
-}
diff --git a/tests/Moq.Analyzers.Benchmarks/SquiggleCop.Baseline.yaml b/tests/Moq.Analyzers.Benchmarks/SquiggleCop.Baseline.yaml
index 63b90e5bf..43474dfdc 100644
--- a/tests/Moq.Analyzers.Benchmarks/SquiggleCop.Baseline.yaml
+++ b/tests/Moq.Analyzers.Benchmarks/SquiggleCop.Baseline.yaml
@@ -307,8 +307,15 @@
- {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: CS0419, Title: Ambiguous reference in cref attribute, Category: Compiler, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Warning], IsEverSuppressed: true}
+- {Id: CS1572, Title: 'XML comment has a param tag, but there is no parameter by that name', Category: Compiler, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Warning], IsEverSuppressed: true}
+- {Id: CS1573, Title: Parameter has no matching param tag in the XML comment (but other parameters do), Category: Compiler, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Warning], IsEverSuppressed: true}
+- {Id: CS1574, Title: XML comment has cref attribute that could not be resolved, Category: Compiler, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Warning], 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: CS1734, Title: 'XML comment has a paramref tag, but there is no parameter by that name', Category: Compiler, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Warning], IsEverSuppressed: true}
+- {Id: CS8669, Title: The annotation for nullable reference types should only be used in code within a '#nullable' annotations context. Auto-generated code requires an explicit '#nullable' directive in source., Category: Compiler, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Warning], IsEverSuppressed: true}
- {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: CS9216, Title: A value of type 'System.Threading.Lock' converted to a different type will use likely unintended monitor-based locking in 'lock' statement., 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}
@@ -332,6 +339,22 @@
- {Id: EM0104, Title: Duplicate Closed Attribute, Category: Logic, DefaultSeverity: Error, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
- {Id: EM0105, Title: Duplicate Case Type, Category: Logic, DefaultSeverity: Error, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
- {Id: EnableGenerateDocumentationFile, Title: Set MSBuild property 'GenerateDocumentationFile' to 'true', Category: Style, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: HAA0101, Title: Array allocation for params parameter, Category: Performance, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: HAA0102, Title: Non-overridden virtual method call on value type, Category: Performance, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: HAA0201, Title: Implicit string concatenation allocation, Category: Performance, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: HAA0202, Title: Value type to reference type conversion allocation for string concatenation, Category: Performance, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: HAA0301, Title: Closure Allocation Source, Category: Performance, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: HAA0302, Title: Display class allocation to capture closure, Category: Performance, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: HAA0303, Title: Lambda or anonymous method in a generic method allocates a delegate instance, Category: Performance, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: HAA0401, Title: Possible allocation of reference type enumerator, Category: Performance, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: HAA0501, Title: Explicit new array type allocation, Category: Performance, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Note], IsEverSuppressed: false}
+- {Id: HAA0502, Title: Explicit new reference type allocation, Category: Performance, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Note], IsEverSuppressed: false}
+- {Id: HAA0503, Title: Explicit new anonymous object allocation, Category: Performance, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Note], IsEverSuppressed: false}
+- {Id: HAA0506, Title: Let clause induced allocation, Category: Performance, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Note], IsEverSuppressed: false}
+- {Id: HAA0601, Title: Value type to reference type conversion causing boxing allocation, Category: Performance, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: HAA0602, Title: Delegate on struct instance caused a boxing allocation, Category: Performance, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: HAA0603, Title: Delegate allocation from a method group, Category: Performance, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: HAA0604, Title: Delegate allocation from a method group, Category: Performance, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Note], IsEverSuppressed: false}
- {Id: IDE0004, Title: Remove Unnecessary Cast, Category: Style, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Note], IsEverSuppressed: true}
- {Id: IDE0005, Title: Using directive is unnecessary., Category: Style, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Note], IsEverSuppressed: false}
- {Id: IDE0005_gen, Title: Using directive is unnecessary., Category: Style, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Note], IsEverSuppressed: true}
@@ -604,7 +627,6 @@
- {Id: MA0163, Title: UseShellExecute must be false when redirecting standard input or output, Category: Usage, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
- {Id: MA0164, Title: Use parentheses to make not pattern clearer, Category: Style, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
- {Id: MA0165, Title: Make interpolated string, Category: Usage, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Note], IsEverSuppressed: true}
-- {Id: POLYSP0003, Title: Unsupported C# language version, Category: Microsoft.CodeAnalysis.CSharp.CSharpParseOptions, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
- {Id: RCS1001, Title: Add braces (when expression spans over multiple lines), Category: Roslynator, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Note], IsEverSuppressed: false}
- {Id: RCS1002, Title: Remove braces, Category: Roslynator, DefaultSeverity: Note, IsEnabledByDefault: false, EffectiveSeverities: [None], IsEverSuppressed: false}
- {Id: RCS1002FadeOut, Title: Remove braces, Category: Roslynator, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Note], IsEverSuppressed: false}
diff --git a/tests/Moq.Analyzers.Test.Analyzers/SquiggleCop.Baseline.yaml b/tests/Moq.Analyzers.Test.Analyzers/SquiggleCop.Baseline.yaml
index fde960706..4e92a80a9 100644
--- a/tests/Moq.Analyzers.Test.Analyzers/SquiggleCop.Baseline.yaml
+++ b/tests/Moq.Analyzers.Test.Analyzers/SquiggleCop.Baseline.yaml
@@ -307,6 +307,15 @@
- {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: CS0419, Title: Ambiguous reference in cref attribute, Category: Compiler, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Warning], IsEverSuppressed: true}
+- {Id: CS0649, Title: 'Field is never assigned to, and will always have its default value', Category: Compiler, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Warning], IsEverSuppressed: true}
+- {Id: CS1570, Title: XML comment has badly formed XML, Category: Compiler, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Warning], IsEverSuppressed: true}
+- {Id: CS1572, Title: 'XML comment has a param tag, but there is no parameter by that name', Category: Compiler, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Warning], IsEverSuppressed: true}
+- {Id: CS1573, Title: Parameter has no matching param tag in the XML comment (but other parameters do), Category: Compiler, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Warning], IsEverSuppressed: true}
+- {Id: CS1574, Title: XML comment has cref attribute that could not be resolved, Category: Compiler, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Warning], IsEverSuppressed: true}
+- {Id: CS1734, Title: 'XML comment has a paramref tag, but there is no parameter by that name', Category: Compiler, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Warning], IsEverSuppressed: true}
+- {Id: CS8669, Title: The annotation for nullable reference types should only be used in code within a '#nullable' annotations context. Auto-generated code requires an explicit '#nullable' directive in source., Category: Compiler, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Warning], IsEverSuppressed: true}
+- {Id: CS9216, Title: A value of type 'System.Threading.Lock' converted to a different type will use likely unintended monitor-based locking in 'lock' statement., 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}
@@ -330,6 +339,22 @@
- {Id: EM0104, Title: Duplicate Closed Attribute, Category: Logic, DefaultSeverity: Error, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
- {Id: EM0105, Title: Duplicate Case Type, Category: Logic, DefaultSeverity: Error, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
- {Id: EnableGenerateDocumentationFile, Title: Set MSBuild property 'GenerateDocumentationFile' to 'true', Category: Style, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: HAA0101, Title: Array allocation for params parameter, Category: Performance, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: HAA0102, Title: Non-overridden virtual method call on value type, Category: Performance, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: HAA0201, Title: Implicit string concatenation allocation, Category: Performance, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: HAA0202, Title: Value type to reference type conversion allocation for string concatenation, Category: Performance, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: HAA0301, Title: Closure Allocation Source, Category: Performance, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: HAA0302, Title: Display class allocation to capture closure, Category: Performance, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: HAA0303, Title: Lambda or anonymous method in a generic method allocates a delegate instance, Category: Performance, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: HAA0401, Title: Possible allocation of reference type enumerator, Category: Performance, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: HAA0501, Title: Explicit new array type allocation, Category: Performance, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Note], IsEverSuppressed: false}
+- {Id: HAA0502, Title: Explicit new reference type allocation, Category: Performance, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Note], IsEverSuppressed: false}
+- {Id: HAA0503, Title: Explicit new anonymous object allocation, Category: Performance, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Note], IsEverSuppressed: false}
+- {Id: HAA0506, Title: Let clause induced allocation, Category: Performance, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Note], IsEverSuppressed: false}
+- {Id: HAA0601, Title: Value type to reference type conversion causing boxing allocation, Category: Performance, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: HAA0602, Title: Delegate on struct instance caused a boxing allocation, Category: Performance, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: HAA0603, Title: Delegate allocation from a method group, Category: Performance, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: HAA0604, Title: Delegate allocation from a method group, Category: Performance, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Note], IsEverSuppressed: false}
- {Id: IDE0004, Title: Remove Unnecessary Cast, Category: Style, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Note], IsEverSuppressed: true}
- {Id: IDE0005, Title: Using directive is unnecessary., Category: Style, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Note], IsEverSuppressed: false}
- {Id: IDE0005_gen, Title: Using directive is unnecessary., Category: Style, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Note], IsEverSuppressed: true}
@@ -602,7 +627,6 @@
- {Id: MA0163, Title: UseShellExecute must be false when redirecting standard input or output, Category: Usage, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
- {Id: MA0164, Title: Use parentheses to make not pattern clearer, Category: Style, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
- {Id: MA0165, Title: Make interpolated string, Category: Usage, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Note], IsEverSuppressed: true}
-- {Id: POLYSP0003, Title: Unsupported C# language version, Category: Microsoft.CodeAnalysis.CSharp.CSharpParseOptions, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
- {Id: RCS1001, Title: Add braces (when expression spans over multiple lines), Category: Roslynator, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Note], IsEverSuppressed: false}
- {Id: RCS1002, Title: Remove braces, Category: Roslynator, DefaultSeverity: Note, IsEnabledByDefault: false, EffectiveSeverities: [None], IsEverSuppressed: false}
- {Id: RCS1002FadeOut, Title: Remove braces, Category: Roslynator, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Note], IsEverSuppressed: false}
@@ -885,7 +909,7 @@
- {Id: RS1032, Title: Define diagnostic message correctly, Category: MicrosoftCodeAnalysisDesign, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
- {Id: RS1033, Title: Define diagnostic description correctly, Category: MicrosoftCodeAnalysisDesign, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
- {Id: RS1034, Title: Prefer 'IsKind' for checking syntax kinds, Category: MicrosoftCodeAnalysisPerformance, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
-- {Id: RS1035, Title: Do not use APIs banned for analyzers, Category: MicrosoftCodeAnalysisCorrectness, DefaultSeverity: Error, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: RS1035, Title: Do not use APIs banned for analyzers, Category: MicrosoftCodeAnalysisCorrectness, DefaultSeverity: Error, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: true}
- {Id: RS1036, Title: Specify analyzer banned API enforcement setting, Category: MicrosoftCodeAnalysisCorrectness, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
- {Id: RS1037, Title: Add "CompilationEnd" custom tag to compilation end diagnostic descriptor, Category: MicrosoftCodeAnalysisDesign, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
- {Id: RS1038, Title: Compiler extensions should be implemented in assemblies with compiler-provided references, Category: MicrosoftCodeAnalysisCorrectness, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
@@ -1580,7 +1604,7 @@
- {Id: VSTHRD102, Title: Implement internal logic asynchronously, Category: Usage, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Note], IsEverSuppressed: false}
- {Id: VSTHRD103, Title: Call async methods when in an async method, Category: Usage, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
- {Id: VSTHRD104, Title: Offer async methods, Category: Usage, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Note], IsEverSuppressed: false}
-- {Id: VSTHRD105, Title: Avoid method overloads that assume TaskScheduler.Current, Category: Usage, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: VSTHRD105, Title: Avoid method overloads that assume TaskScheduler.Current, Category: Usage, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: true}
- {Id: VSTHRD106, Title: Use InvokeAsync to raise async events, Category: Usage, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
- {Id: VSTHRD107, Title: Await Task within using expression, Category: Usage, DefaultSeverity: Error, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
- {Id: VSTHRD108, Title: Assert thread affinity unconditionally, Category: Usage, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
diff --git a/tests/Moq.Analyzers.Test/SquiggleCop.Baseline.yaml b/tests/Moq.Analyzers.Test/SquiggleCop.Baseline.yaml
index 3fec38e22..bc706b924 100644
--- a/tests/Moq.Analyzers.Test/SquiggleCop.Baseline.yaml
+++ b/tests/Moq.Analyzers.Test/SquiggleCop.Baseline.yaml
@@ -307,7 +307,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: CS0419, Title: Ambiguous reference in cref attribute, Category: Compiler, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Warning], IsEverSuppressed: true}
+- {Id: CS1572, Title: 'XML comment has a param tag, but there is no parameter by that name', Category: Compiler, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Warning], IsEverSuppressed: true}
+- {Id: CS1573, Title: Parameter has no matching param tag in the XML comment (but other parameters do), Category: Compiler, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Warning], IsEverSuppressed: true}
+- {Id: CS1574, Title: XML comment has cref attribute that could not be resolved, Category: Compiler, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Warning], 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: CS1734, Title: 'XML comment has a paramref tag, but there is no parameter by that name', Category: Compiler, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Warning], IsEverSuppressed: true}
+- {Id: CS8669, Title: The annotation for nullable reference types should only be used in code within a '#nullable' annotations context. Auto-generated code requires an explicit '#nullable' directive in source., Category: Compiler, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Warning], IsEverSuppressed: true}
+- {Id: CS9216, Title: A value of type 'System.Threading.Lock' converted to a different type will use likely unintended monitor-based locking in 'lock' statement., 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}
@@ -331,6 +338,22 @@
- {Id: EM0104, Title: Duplicate Closed Attribute, Category: Logic, DefaultSeverity: Error, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
- {Id: EM0105, Title: Duplicate Case Type, Category: Logic, DefaultSeverity: Error, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
- {Id: EnableGenerateDocumentationFile, Title: Set MSBuild property 'GenerateDocumentationFile' to 'true', Category: Style, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: HAA0101, Title: Array allocation for params parameter, Category: Performance, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: HAA0102, Title: Non-overridden virtual method call on value type, Category: Performance, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: HAA0201, Title: Implicit string concatenation allocation, Category: Performance, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: HAA0202, Title: Value type to reference type conversion allocation for string concatenation, Category: Performance, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: HAA0301, Title: Closure Allocation Source, Category: Performance, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: HAA0302, Title: Display class allocation to capture closure, Category: Performance, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: HAA0303, Title: Lambda or anonymous method in a generic method allocates a delegate instance, Category: Performance, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: HAA0401, Title: Possible allocation of reference type enumerator, Category: Performance, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: HAA0501, Title: Explicit new array type allocation, Category: Performance, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Note], IsEverSuppressed: false}
+- {Id: HAA0502, Title: Explicit new reference type allocation, Category: Performance, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Note], IsEverSuppressed: false}
+- {Id: HAA0503, Title: Explicit new anonymous object allocation, Category: Performance, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Note], IsEverSuppressed: false}
+- {Id: HAA0506, Title: Let clause induced allocation, Category: Performance, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Note], IsEverSuppressed: false}
+- {Id: HAA0601, Title: Value type to reference type conversion causing boxing allocation, Category: Performance, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: HAA0602, Title: Delegate on struct instance caused a boxing allocation, Category: Performance, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: HAA0603, Title: Delegate allocation from a method group, Category: Performance, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
+- {Id: HAA0604, Title: Delegate allocation from a method group, Category: Performance, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Note], IsEverSuppressed: false}
- {Id: IDE0004, Title: Remove Unnecessary Cast, Category: Style, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Note], IsEverSuppressed: true}
- {Id: IDE0005, Title: Using directive is unnecessary., Category: Style, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Note], IsEverSuppressed: false}
- {Id: IDE0005_gen, Title: Using directive is unnecessary., Category: Style, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Note], IsEverSuppressed: true}
@@ -603,7 +626,6 @@
- {Id: MA0163, Title: UseShellExecute must be false when redirecting standard input or output, Category: Usage, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
- {Id: MA0164, Title: Use parentheses to make not pattern clearer, Category: Style, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
- {Id: MA0165, Title: Make interpolated string, Category: Usage, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Note], IsEverSuppressed: true}
-- {Id: POLYSP0003, Title: Unsupported C# language version, Category: Microsoft.CodeAnalysis.CSharp.CSharpParseOptions, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Error], IsEverSuppressed: false}
- {Id: RCS1001, Title: Add braces (when expression spans over multiple lines), Category: Roslynator, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Note], IsEverSuppressed: false}
- {Id: RCS1002, Title: Remove braces, Category: Roslynator, DefaultSeverity: Note, IsEnabledByDefault: false, EffectiveSeverities: [None], IsEverSuppressed: false}
- {Id: RCS1002FadeOut, Title: Remove braces, Category: Roslynator, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Note], IsEverSuppressed: false}