@@ -37,12 +37,11 @@ public override void Initialize(AnalysisContext context)
37
37
context . EnableConcurrentExecution ( ) ;
38
38
context . ConfigureGeneratedCodeAnalysis ( GeneratedCodeAnalysisFlags . None ) ;
39
39
40
- context . RegisterCompilationStartAction ( static context =>
40
+ context . RegisterCompilationStartAction ( context =>
41
41
{
42
42
var knownTypeProvider = WellKnownTypeProvider . GetOrCreate ( context . Compilation ) ;
43
43
INamedTypeSymbol ? readonlySpanType = knownTypeProvider . GetOrCreateTypeByMetadataName ( WellKnownTypeNames . SystemReadOnlySpan1 ) ;
44
44
INamedTypeSymbol ? functionType = knownTypeProvider . GetOrCreateTypeByMetadataName ( WellKnownTypeNames . SystemFunc2 ) ;
45
- INamedTypeSymbol ? readOnlyCollectionType = knownTypeProvider . GetOrCreateTypeByMetadataName ( WellKnownTypeNames . SystemCollectionsObjectModelReadOnlyCollection1 ) ;
46
45
47
46
// Analyzes an argument operation
48
47
context . RegisterOperationAction ( context =>
@@ -60,8 +59,7 @@ public override void Initialize(AnalysisContext context)
60
59
61
60
// If no argument, return
62
61
// 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 ) )
65
63
{
66
64
return ;
67
65
}
@@ -113,12 +111,7 @@ public override void Initialize(AnalysisContext context)
113
111
string ? paramName = null ;
114
112
if ( argumentOperation is not null )
115
113
{
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 ) )
122
115
{
123
116
return ;
124
117
}
@@ -153,12 +146,39 @@ public override void Initialize(AnalysisContext context)
153
146
} ) ;
154
147
}
155
148
156
- private static bool IsPassedToStaticReadOnlyCollection ( IArgumentOperation argument , INamedTypeSymbol ? readOnlyCollectionType )
149
+ private static bool IsInitializingStaticOrReadOnlyFieldOrProperty ( IOperation operation )
157
150
{
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 ;
162
182
}
163
183
}
164
184
}
0 commit comments