Skip to content

Commit 22363a9

Browse files
committed
Refine logic to emit nullable diagnostics
1 parent 9aaaaea commit 22363a9

File tree

2 files changed

+26
-25
lines changed

2 files changed

+26
-25
lines changed

components/DependencyPropertyGenerator/CommunityToolkit.DependencyPropertyGenerator.SourceGenerators/Diagnostics/Analyzers/InvalidPropertyNullableAnnotationAnalyzer.cs

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -91,30 +91,31 @@ public override void Initialize(AnalysisContext context)
9191
return;
9292
}
9393

94+
// If the getter is null-resilient, then we never need to emit a warning here
95+
if (IsAccessorMethodMarkedAsNotNull(propertySymbol, SyntaxKind.GetAccessorDeclaration, notNullAttributeSymbols))
96+
{
97+
return;
98+
}
99+
94100
// If setting 'null' values is allowed, then the initial state (and the default value) don't matter anymore.
95101
// In order to be correct, we must have '[NotNull]' on any implemented getter or setter methods (same as above).
96-
if (propertySymbol.HasAttributeWithAnyType(allowNullAttributeSymbols))
102+
if (propertySymbol.HasAttributeWithAnyType(allowNullAttributeSymbols) &&
103+
!IsAccessorMethodMarkedAsNotNull(propertySymbol, SyntaxKind.SetAccessorDeclaration, notNullAttributeSymbols))
97104
{
98-
if (!IsAccessorMethodMarkedAsNotNull(propertySymbol, SyntaxKind.GetAccessorDeclaration, notNullAttributeSymbols) &&
99-
!IsAccessorMethodMarkedAsNotNull(propertySymbol, SyntaxKind.SetAccessorDeclaration, notNullAttributeSymbols))
100-
{
101-
context.ReportDiagnostic(Diagnostic.Create(
102-
NotNullResilientAccessorsForNotNullablePropertyDeclaration,
103-
attributeData.GetLocation(),
104-
propertySymbol));
105-
}
105+
context.ReportDiagnostic(Diagnostic.Create(
106+
NotNullResilientAccessorsForNotNullablePropertyDeclaration,
107+
attributeData.GetLocation(),
108+
propertySymbol));
106109
}
107-
else
110+
111+
// In either case, we need to check that either the property is required, or that the default value is not 'null'.
112+
// This is because when the nullability of the setter is correct, then the default value takes precedence.
113+
if (!propertySymbol.IsRequired && !IsDefaultValueNotNull(propertySymbol, attributeData, maybeNullAttributeSymbols, notNullAttributeSymbols))
108114
{
109-
// Otherwise, we need to check that either the property is required, or that the default value is not 'null'.
110-
// This is because when the nullability of the setter is correct, then the default value takes precedence.
111-
if (!propertySymbol.IsRequired && !IsDefaultValueNotNull(propertySymbol, attributeData, maybeNullAttributeSymbols, notNullAttributeSymbols))
112-
{
113-
context.ReportDiagnostic(Diagnostic.Create(
114-
NonNullablePropertyDeclarationIsNotEnforced,
115-
attributeData.GetLocation(),
116-
propertySymbol));
117-
}
115+
context.ReportDiagnostic(Diagnostic.Create(
116+
NonNullablePropertyDeclarationIsNotEnforced,
117+
attributeData.GetLocation(),
118+
propertySymbol));
118119
}
119120
}
120121
}, SymbolKind.Property);

components/DependencyPropertyGenerator/CommunityToolkit.DependencyPropertyGenerator.Tests/Test_Analyzers.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -903,7 +903,7 @@ public partial class MyControl : Control
903903
}
904904

905905
[TestMethod]
906-
public async Task InvalidPropertyNullableAnnotationAnalyzer_NotNullableType_AllowNull_WithNullResilientSetter_Object_DoesNotWarn()
906+
public async Task InvalidPropertyNullableAnnotationAnalyzer_NotNullableType_AllowNull_WithNullResilientSetter_Object_Warns()
907907
{
908908
const string source = """
909909
using System.Diagnostics.CodeAnalysis;
@@ -916,7 +916,7 @@ namespace MyApp;
916916
917917
public partial class MyControl : Control
918918
{
919-
[GeneratedDependencyProperty]
919+
[{|WCTDP0009:GeneratedDependencyProperty|}]
920920
[AllowNull]
921921
public partial string {|CS9248:Name|} { get; set; }
922922
@@ -959,7 +959,7 @@ public partial class MyControl : Control
959959
}
960960

961961
[TestMethod]
962-
public async Task InvalidPropertyNullableAnnotationAnalyzer_NotNullableType_AllowNull_WithNullResilientSetter_DoesNotWarn()
962+
public async Task InvalidPropertyNullableAnnotationAnalyzer_NotNullableType_AllowNull_WithNullResilientSetter_Warns()
963963
{
964964
const string source = """
965965
using System.Diagnostics.CodeAnalysis;
@@ -972,7 +972,7 @@ namespace MyApp;
972972
973973
public partial class MyControl : Control
974974
{
975-
[GeneratedDependencyProperty]
975+
[{|WCTDP0009:GeneratedDependencyProperty|}]
976976
[AllowNull]
977977
public partial string {|CS9248:Name|} { get; set; }
978978
@@ -1028,7 +1028,7 @@ namespace MyApp;
10281028
10291029
public partial class MyControl : Control
10301030
{
1031-
[{|WCTDP0024:GeneratedDependencyProperty|}]
1031+
[{|WCTDP0009:{|WCTDP0024:GeneratedDependencyProperty|}|}]
10321032
[AllowNull]
10331033
public partial string {|CS9248:Name|} { get; set; }
10341034
@@ -1055,7 +1055,7 @@ namespace MyApp;
10551055
10561056
public partial class MyControl : Control
10571057
{
1058-
[{|WCTDP0024:GeneratedDependencyProperty|}]
1058+
[{|WCTDP0009:{|WCTDP0024:GeneratedDependencyProperty|}|}]
10591059
[AllowNull]
10601060
public partial string {|CS9248:Name|} { get; set; }
10611061
}

0 commit comments

Comments
 (0)