Skip to content

Commit 9e2e2f1

Browse files
authored
Switch to allow list that only specifies concurrent collections (#3978)
1 parent a3e3dcd commit 9e2e2f1

File tree

3 files changed

+86
-149
lines changed

3 files changed

+86
-149
lines changed

src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/UseCountProperly.cs

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -153,33 +153,36 @@ private static void OnCompilationStart(CompilationStartAnalysisContext context)
153153
methods = namedType?.GetMembers(LongCountAsync).OfType<IMethodSymbol>().Where(m => m.Parameters.Length <= 2);
154154
AddIfNotNull(asyncMethods, methods);
155155

156-
// Disallowed types that shouldn't report a diagnosis given that there is no proven benefit on doing so.
157-
ImmutableHashSet<ITypeSymbol>.Builder disallowedTypesBuilder = ImmutableHashSet.CreateBuilder<ITypeSymbol>();
156+
// Allowed types that should report a CA1836 diagnosis given that there is proven benefit on doing so.
157+
ImmutableHashSet<ITypeSymbol>.Builder allowedTypesBuilder = ImmutableHashSet.CreateBuilder<ITypeSymbol>();
158158

159-
namedType = context.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemMemory1);
160-
disallowedTypesBuilder.AddIfNotNull(namedType);
159+
namedType = context.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemCollectionsConcurrentConcurrentBag1);
160+
allowedTypesBuilder.AddIfNotNull(namedType);
161161

162-
namedType = context.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemSpan1);
163-
disallowedTypesBuilder.AddIfNotNull(namedType);
162+
namedType = context.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemCollectionsConcurrentConcurrentDictionary2);
163+
allowedTypesBuilder.AddIfNotNull(namedType);
164164

165-
namedType = context.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemReadOnlyMemory1);
166-
disallowedTypesBuilder.AddIfNotNull(namedType);
165+
namedType = context.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemCollectionsConcurrentConcurrentQueue1);
166+
allowedTypesBuilder.AddIfNotNull(namedType);
167167

168-
namedType = context.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemReadOnlySpan1);
169-
disallowedTypesBuilder.AddIfNotNull(namedType);
168+
namedType = context.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemCollectionsConcurrentConcurrentStack1);
169+
allowedTypesBuilder.AddIfNotNull(namedType);
170170

171-
ImmutableHashSet<ITypeSymbol> disallowedTypesForCA1836 = disallowedTypesBuilder.ToImmutable();
171+
ImmutableHashSet<ITypeSymbol> allowedTypesForCA1836 = allowedTypesBuilder.ToImmutable();
172172

173173
if (syncMethods.Count > 0 || asyncMethods.Count > 0)
174174
{
175175
context.RegisterOperationAction(operationContext => AnalyzeInvocationOperation(
176-
operationContext, syncMethods.ToImmutable(), asyncMethods.ToImmutable(), disallowedTypesForCA1836),
176+
operationContext, syncMethods.ToImmutable(), asyncMethods.ToImmutable(), allowedTypesForCA1836),
177177
OperationKind.Invocation);
178178
}
179179

180-
context.RegisterOperationAction(operationContext => AnalyzePropertyReference(
181-
operationContext, disallowedTypesForCA1836),
182-
OperationKind.PropertyReference);
180+
if (!allowedTypesForCA1836.IsEmpty)
181+
{
182+
context.RegisterOperationAction(operationContext => AnalyzePropertyReference(
183+
operationContext, allowedTypesForCA1836),
184+
OperationKind.PropertyReference);
185+
}
183186

184187
static void AddIfNotNull(ImmutableHashSet<IMethodSymbol>.Builder set, IEnumerable<IMethodSymbol>? others)
185188
{
@@ -194,7 +197,7 @@ private static void AnalyzeInvocationOperation(
194197
OperationAnalysisContext context,
195198
ImmutableHashSet<IMethodSymbol> syncMethods,
196199
ImmutableHashSet<IMethodSymbol> asyncMethods,
197-
ImmutableHashSet<ITypeSymbol> disallowedTypesForCA1836)
200+
ImmutableHashSet<ITypeSymbol> allowedTypesForCA1836)
198201
{
199202
var invocationOperation = (IInvocationOperation)context.Operation;
200203

@@ -236,10 +239,10 @@ private static void AnalyzeInvocationOperation(
236239
bool shouldReplaceParent = ShouldReplaceParent(ref parentOperation, out string? operationKey, out bool shouldNegateIsEmpty);
237240

238241
DetermineReportForInvocationAnalysis(context, invocationOperation, parentOperation,
239-
shouldReplaceParent, isAsync, shouldNegateIsEmpty, hasPredicate, originalDefinition.Name, operationKey, disallowedTypesForCA1836);
242+
shouldReplaceParent, isAsync, shouldNegateIsEmpty, hasPredicate, originalDefinition.Name, operationKey, allowedTypesForCA1836);
240243
}
241244

242-
private static void AnalyzePropertyReference(OperationAnalysisContext context, ImmutableHashSet<ITypeSymbol> disallowedTypesForCA1836)
245+
private static void AnalyzePropertyReference(OperationAnalysisContext context, ImmutableHashSet<ITypeSymbol> allowedTypesForCA1836)
243246
{
244247
var propertyReferenceOperation = (IPropertyReferenceOperation)context.Operation;
245248

@@ -259,7 +262,7 @@ private static void AnalyzePropertyReference(OperationAnalysisContext context, I
259262
if (shouldReplaceParent)
260263
{
261264
DetermineReportForPropertyReference(context, propertyReferenceOperation, parentOperation,
262-
operationKey, shouldNegateIsEmpty, disallowedTypesForCA1836);
265+
operationKey, shouldNegateIsEmpty, allowedTypesForCA1836);
263266
}
264267
}
265268

@@ -409,7 +412,7 @@ private static void DetermineReportForInvocationAnalysis(
409412
OperationAnalysisContext context,
410413
IInvocationOperation invocationOperation, IOperation parent,
411414
bool shouldReplaceParent, bool isAsync, bool shouldNegateIsEmpty, bool hasPredicate, string methodName, string? operationKey,
412-
ImmutableHashSet<ITypeSymbol> disallowedTypesForCA1836)
415+
ImmutableHashSet<ITypeSymbol> allowedTypesForCA1836)
413416
{
414417
if (!shouldReplaceParent)
415418
{
@@ -438,7 +441,7 @@ private static void DetermineReportForInvocationAnalysis(
438441
}
439442
else
440443
{
441-
if (!disallowedTypesForCA1836.Contains(type.OriginalDefinition) &&
444+
if (allowedTypesForCA1836.Contains(type.OriginalDefinition) &&
442445
TypeContainsVisibleProperty(context, type, IsEmpty, SpecialType.System_Boolean, out ISymbol? isEmptyPropertySymbol) &&
443446
!IsPropertyGetOfIsEmptyUsingThisInstance(context, invocationOperation, isEmptyPropertySymbol!))
444447
{
@@ -465,12 +468,12 @@ private static void DetermineReportForInvocationAnalysis(
465468
private static void DetermineReportForPropertyReference(
466469
OperationAnalysisContext context, IOperation operation, IOperation parent,
467470
string? operationKey, bool shouldNegateIsEmpty,
468-
ImmutableHashSet<ITypeSymbol> disallowedTypesForCA1836)
471+
ImmutableHashSet<ITypeSymbol> allowedTypesForCA1836)
469472
{
470473
ITypeSymbol? type = operation.GetInstanceType();
471474
if (type != null)
472475
{
473-
if (!disallowedTypesForCA1836.Contains(type.OriginalDefinition) &&
476+
if (allowedTypesForCA1836.Contains(type.OriginalDefinition) &&
474477
TypeContainsVisibleProperty(context, type, IsEmpty, SpecialType.System_Boolean, out ISymbol? isEmptyPropertySymbol) &&
475478
!IsPropertyGetOfIsEmptyUsingThisInstance(context, operation, isEmptyPropertySymbol!))
476479
{

0 commit comments

Comments
 (0)