@@ -12,8 +12,10 @@ namespace System.Windows.Forms.CSharp.Analyzers.MissingPropertySerializationConf
1212[ DiagnosticAnalyzer ( LanguageNames . CSharp ) ]
1313public class MissingPropertySerializationConfigurationAnalyzer : DiagnosticAnalyzer
1414{
15- public override ImmutableArray < DiagnosticDescriptor > SupportedDiagnostics
16- => [ CSharpDiagnosticDescriptors . s_missingPropertySerializationConfiguration ] ;
15+ private const string SystemComponentModelName = "System.ComponentModel" ;
16+
17+ public override ImmutableArray < DiagnosticDescriptor > SupportedDiagnostics =>
18+ [ CSharpDiagnosticDescriptors . s_missingPropertySerializationConfiguration ] ;
1719
1820 public override void Initialize ( AnalysisContext context )
1921 {
@@ -24,26 +26,53 @@ public override void Initialize(AnalysisContext context)
2426
2527 private static void AnalyzeSymbol ( SymbolAnalysisContext context )
2628 {
27- // We analyze only properties.
28- var propertySymbol = ( IPropertySymbol ) context . Symbol ;
29+ // We never flag a property named Site of type of ISite
30+ if ( context . Symbol is not IPropertySymbol propertySymbol
31+ || propertySymbol . IsStatic )
32+ {
33+ return ;
34+ }
2935
30- // Does the property belong to a class which derives from Component?
31- if ( propertySymbol . ContainingType is null
32- || ! propertySymbol
33- . ContainingType
34- . AllInterfaces
35- . Any ( i => i . Name == nameof ( IComponent ) ) )
36+ // A property of System.ComponentModel.ISite we never flag.
37+ if ( propertySymbol . Type . Name == nameof ( ISite )
38+ && propertySymbol . Type . ContainingNamespace . ToString ( ) == SystemComponentModelName )
3639 {
3740 return ;
3841 }
3942
40- // Is the property read/write and at least internal?
41- if ( propertySymbol . SetMethod is null
43+ // Is the property read/write and at least internal and doesn't have a private setter?
44+ if ( propertySymbol . SetMethod is not IMethodSymbol propertySetter
45+ || propertySetter . DeclaredAccessibility == Accessibility . Private
4246 || propertySymbol . DeclaredAccessibility < Accessibility . Internal )
4347 {
4448 return ;
4549 }
4650
51+ // Skip overridden properties since the base property should already
52+ // have the appropriate serialization configuration
53+ if ( propertySymbol . IsOverride )
54+ {
55+ return ;
56+ }
57+
58+ // If the property is part of any interface named IComponent, we're out.
59+ if ( propertySymbol . ContainingType . Name == nameof ( IComponent ) )
60+ {
61+ return ;
62+ }
63+
64+ // Does the property belong to a class which implements the System.ComponentModel.IComponent interface?
65+ if ( propertySymbol . ContainingType is null
66+ || ! propertySymbol
67+ . ContainingType
68+ . AllInterfaces
69+ . Any ( i => i . Name == nameof ( IComponent ) &&
70+ i . ContainingNamespace is not null &&
71+ i . ContainingNamespace . ToString ( ) == SystemComponentModelName ) )
72+ {
73+ return ;
74+ }
75+
4776 // Is the property attributed with DesignerSerializationVisibility or DefaultValue?
4877 if ( propertySymbol . GetAttributes ( )
4978 . Any ( a => a ? . AttributeClass ? . Name is ( nameof ( DesignerSerializationVisibilityAttribute ) )
0 commit comments