Skip to content

Commit befdc3a

Browse files
committed
Do not warn on static initializers
1 parent 14c7057 commit befdc3a

File tree

2 files changed

+36
-15
lines changed

2 files changed

+36
-15
lines changed

src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/AvoidConstArrays.cs

Lines changed: 35 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,11 @@ public override void Initialize(AnalysisContext context)
3737
context.EnableConcurrentExecution();
3838
context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
3939

40-
context.RegisterCompilationStartAction(static context =>
40+
context.RegisterCompilationStartAction(context =>
4141
{
4242
var knownTypeProvider = WellKnownTypeProvider.GetOrCreate(context.Compilation);
4343
INamedTypeSymbol? readonlySpanType = knownTypeProvider.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemReadOnlySpan1);
4444
INamedTypeSymbol? functionType = knownTypeProvider.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemFunc2);
45-
INamedTypeSymbol? readOnlyCollectionType = knownTypeProvider.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemCollectionsObjectModelReadOnlyCollection1);
4645

4746
// Analyzes an argument operation
4847
context.RegisterOperationAction(context =>
@@ -60,8 +59,7 @@ public override void Initialize(AnalysisContext context)
6059

6160
// If no argument, return
6261
// If argument is passed as a params array but isn't itself an array, return
63-
// If argument is passed to a static ReadOnlyCollection<T>, return
64-
if (argumentOperation is null || (argumentOperation.Parameter.IsParams && arrayCreationOperation.IsImplicit) || IsPassedToStaticReadOnlyCollection(argumentOperation, readOnlyCollectionType))
62+
if (argumentOperation is null || (argumentOperation.Parameter.IsParams && arrayCreationOperation.IsImplicit))
6563
{
6664
return;
6765
}
@@ -113,12 +111,7 @@ public override void Initialize(AnalysisContext context)
113111
string? paramName = null;
114112
if (argumentOperation is not null)
115113
{
116-
IFieldInitializerOperation? fieldInitializer = argumentOperation.GetAncestor<IFieldInitializerOperation>(
117-
OperationKind.FieldInitializer, f => f.InitializedFields.Any(x => x.IsReadOnly));
118-
IPropertyInitializerOperation? propertyInitializer = argumentOperation.GetAncestor<IPropertyInitializerOperation>(
119-
OperationKind.PropertyInitializer, p => p.InitializedProperties.Any(x => x.IsReadOnly));
120-
121-
if (fieldInitializer is not null || propertyInitializer is not null)
114+
if (IsInitializingStaticOrReadOnlyFieldOrProperty(argumentOperation))
122115
{
123116
return;
124117
}
@@ -153,12 +146,39 @@ public override void Initialize(AnalysisContext context)
153146
});
154147
}
155148

156-
private static bool IsPassedToStaticReadOnlyCollection(IArgumentOperation argument, INamedTypeSymbol? readOnlyCollectionType)
149+
private static bool IsInitializingStaticOrReadOnlyFieldOrProperty(IOperation operation)
157150
{
158-
return argument.Parent is IObjectCreationOperation objectCreation
159-
&& objectCreation.Type.OriginalDefinition.Equals(readOnlyCollectionType, SymbolEqualityComparer.Default)
160-
&& objectCreation.Parent is IAssignmentOperation { Target: IMemberReferenceOperation memberReference }
161-
&& memberReference.Member.IsStatic;
151+
var ancestor = operation;
152+
do
153+
{
154+
ancestor = ancestor!.Parent;
155+
} while (ancestor != null && !(ancestor.Kind == OperationKind.FieldInitializer || ancestor.Kind == OperationKind.PropertyInitializer ||
156+
ancestor.Kind == OperationKind.CoalesceAssignment || ancestor.Kind == OperationKind.SimpleAssignment));
157+
158+
if (ancestor != null)
159+
{
160+
switch (ancestor)
161+
{
162+
case IFieldInitializerOperation fieldInitializer:
163+
return fieldInitializer.InitializedFields.Any(x => x.IsStatic || x.IsReadOnly);
164+
case IPropertyInitializerOperation propertyInitializer:
165+
return propertyInitializer.InitializedProperties.Any(x => x.IsStatic || x.IsReadOnly);
166+
case IAssignmentOperation assignmentOperation:
167+
if (assignmentOperation.Target is IFieldReferenceOperation fieldReference && fieldReference.Field.IsStatic)
168+
{
169+
return true;
170+
}
171+
172+
if (assignmentOperation.Target is IPropertyReferenceOperation propertyReference && propertyReference.Property.IsStatic)
173+
{
174+
return true;
175+
}
176+
177+
break;
178+
}
179+
}
180+
181+
return false;
162182
}
163183
}
164184
}

src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/AvoidConstArraysTests.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -768,6 +768,7 @@ await VerifyCS.VerifyAnalyzerAsync(@"
768768
769769
public class A
770770
{
771+
public readonly List<string> Field1 = GetValues(new string[] { ""close"" });
771772
public static readonly A Field;
772773
public static List<string> Property { get; } = GetValues(new string[] { ""close"" });
773774
public static string[] Property2 { get; } = new string[] { ""close"" };

0 commit comments

Comments
 (0)