Skip to content

Commit 922b016

Browse files
committed
Don't warn on instance fields and properties
Also fix some other misc bugs, eg. around trivia
1 parent 0d01d5c commit 922b016

File tree

7 files changed

+38
-58
lines changed

7 files changed

+38
-58
lines changed

components/DependencyPropertyGenerator/CommunityToolkit.DependencyPropertyGenerator.CodeFixers/UseFieldDeclarationCodeFixer.cs

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,6 @@ private static bool IsCodeFixSupportedForPropertyDeclaration(PropertyDeclaration
7474
return false;
7575
}
7676

77-
bool isStatic = false;
78-
7977
foreach (SyntaxToken modifier in propertyDeclaration.Modifiers)
8078
{
8179
// Accessibility modifiers are allowed (the property will however become public)
@@ -84,35 +82,21 @@ private static bool IsCodeFixSupportedForPropertyDeclaration(PropertyDeclaration
8482
continue;
8583
}
8684

87-
// Track whether the property is static
88-
if (modifier.IsKind(SyntaxKind.StaticKeyword))
89-
{
90-
isStatic = true;
91-
92-
continue;
93-
}
94-
9585
// If the property is abstract or an override, or other weird things (which shouldn't really happen), we don't support it
9686
if (modifier.Kind() is SyntaxKind.AbstractKeyword or SyntaxKind.OverrideKeyword or SyntaxKind.PartialKeyword or SyntaxKind.ExternKeyword)
9787
{
9888
return false;
9989
}
10090
}
10191

102-
// We don't support fixing instance properties automatically, as that might break code
103-
if (!isStatic)
104-
{
105-
return false;
106-
}
107-
10892
// Properties with an expression body are supported and will be converted to field initializers
10993
if (propertyDeclaration.ExpressionBody is not null)
11094
{
11195
return true;
11296
}
11397

11498
// The property must have at least an accessor
115-
if (propertyDeclaration.AccessorList is not { Accessors: { Count: > 0 } } accessorList)
99+
if (propertyDeclaration.AccessorList is not { Accessors.Count: > 0 } accessorList)
116100
{
117101
return false;
118102
}

components/DependencyPropertyGenerator/CommunityToolkit.DependencyPropertyGenerator.CodeFixers/UseFieldDeclarationCorrectlyCodeFixer.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,9 @@ private static async Task<Document> FixDependencyPropertyFieldDeclaration(Docume
6868
// We use the lambda overload mostly for convenient, so we can easily get a generator to use
6969
syntaxEditor.ReplaceNode(fieldDeclaration, (node, generator) =>
7070
{
71+
// Keep the original node to get the trivia back from it
72+
SyntaxNode originalNode = node;
73+
7174
// Update the field to ensure it's declared as 'public static readonly'
7275
node = generator.WithAccessibility(node, Accessibility.Public);
7376
node = generator.WithModifiers(node, DeclarationModifiers.Static | DeclarationModifiers.ReadOnly);
@@ -82,7 +85,7 @@ private static async Task<Document> FixDependencyPropertyFieldDeclaration(Docume
8285
node = ((FieldDeclarationSyntax)node).WithDeclaration(variableDeclaration.WithType(typeDeclaration));
8386
}
8487

85-
return node;
88+
return node.WithTriviaFrom(originalNode);
8689
});
8790

8891
// Create the new document with the single change

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,18 @@ public override void Initialize(AnalysisContext context)
4747
{
4848
IPropertySymbol propertySymbol = (IPropertySymbol)context.Symbol;
4949

50+
// Ignore instance properties (same as in the other analyzer), and interface members
51+
if (propertySymbol is { IsStatic: false } or { ContainingType.TypeKind: TypeKind.Interface })
52+
{
53+
return;
54+
}
55+
56+
// Also ignore properties that are write-only (there can't really be normal dependency properties)
57+
if (propertySymbol.IsWriteOnly)
58+
{
59+
return;
60+
}
61+
5062
// We only care about properties which are of type 'DependencyProperty'
5163
if (!SymbolEqualityComparer.Default.Equals(propertySymbol.Type, dependencyPropertySymbol))
5264
{

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,13 @@ public override void Initialize(AnalysisContext context)
4242
{
4343
IFieldSymbol fieldSymbol = (IFieldSymbol)context.Symbol;
4444

45+
// Ignore instance fields, to reduce false positives. There might be edge cases
46+
// where property instances are used as state, and that's technically not invalid.
47+
if (!fieldSymbol.IsStatic)
48+
{
49+
return;
50+
}
51+
4552
// We only care about fields which are of type 'DependencyProperty'
4653
if (!SymbolEqualityComparer.Default.Equals(fieldSymbol.Type, dependencyPropertySymbol))
4754
{
@@ -51,7 +58,6 @@ public override void Initialize(AnalysisContext context)
5158
// Fields should always be public, static, readonly, and with nothing else on them
5259
if (fieldSymbol is
5360
{ DeclaredAccessibility: not Accessibility.Public } or
54-
{ IsStatic: false } or
5561
{ IsRequired: true } or
5662
{ IsReadOnly: false } or
5763
{ IsVolatile: true } or

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

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1850,7 +1850,6 @@ public class MyObject : DependencyObject
18501850

18511851
[TestMethod]
18521852
[DataRow("private static readonly DependencyProperty")]
1853-
[DataRow("public readonly DependencyProperty")]
18541853
[DataRow("public static DependencyProperty")]
18551854
[DataRow("public static volatile DependencyProperty")]
18561855
[DataRow("public static readonly DependencyProperty?")]
@@ -1964,7 +1963,7 @@ public abstract class MyBase : DependencyObject
19641963
}
19651964

19661965
[TestMethod]
1967-
public async Task UseFieldDeclarationAnalyzer_WithNoSetter_DoesNotWarn()
1966+
public async Task UseFieldDeclarationAnalyzer_WithNoGetter_DoesNotWarn()
19681967
{
19691968
const string source = """
19701969
using Windows.UI.Xaml;
@@ -1991,7 +1990,7 @@ public class MyObject : DependencyObject
19911990
{
19921991
public static DependencyProperty {|WCTDP0021:Test1Property|} => DependencyProperty.Register("Test1", typeof(string), typeof(MyObject), null);
19931992
public static DependencyProperty {|WCTDP0021:Test2Property|} { get; } = DependencyProperty.Register("Test2", typeof(string), typeof(MyObject), null);
1994-
public DependencyProperty {|WCTDP0021:Test3Property|} { get; set; }
1993+
public static DependencyProperty {|WCTDP0021:Test3Property|} { get; set; }
19951994
}
19961995
""";
19971996

components/DependencyPropertyGenerator/CommunityToolkit.DependencyPropertyGenerator.Tests/Test_UseFieldDeclarationCodeFixer.cs

Lines changed: 6 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -137,17 +137,10 @@ public class MyObject : DependencyObject
137137
typeof(MyObject),
138138
null);
139139
140-
public DependencyProperty [|Test4Property|] => DependencyProperty.Register(
141-
"Test4",
142-
typeof(string),
143-
typeof(MyObject),
144-
null);
145-
146-
public static DependencyProperty [|Test5Property|] { get; }
147-
public virtual DependencyProperty [|Test6Property|] { get; }
140+
public static DependencyProperty [|Test4Property|] { get; }
148141
149142
[Test]
150-
public static DependencyProperty [|Test7Property|] { get; }
143+
public static DependencyProperty [|Test5Property|] { get; }
151144
}
152145
153146
public class TestAttribute : Attribute;
@@ -179,17 +172,10 @@ public class MyObject : DependencyObject
179172
typeof(MyObject),
180173
null);
181174
182-
public DependencyProperty Test4Property => DependencyProperty.Register(
183-
"Test4",
184-
typeof(string),
185-
typeof(MyObject),
186-
null);
187-
188-
public static readonly DependencyProperty Test5Property;
189-
public virtual DependencyProperty Test6Property { get; }
175+
public static readonly DependencyProperty Test4Property;
190176
191177
[Test]
192-
public static DependencyProperty [|Test7Property|] { get; }
178+
public static DependencyProperty Test5Property { get; }
193179
}
194180
195181
public class TestAttribute : Attribute;
@@ -203,14 +189,8 @@ public class TestAttribute : Attribute;
203189

204190
test.FixedState.ExpectedDiagnostics.AddRange(
205191
[
206-
// /0/Test0.cs(26,31): warning WCTDP0021: The property 'MyApp.MyObject.Test4Property' is a dependency property, which is not the correct declaration type (all dependency properties should be declared as fields, unless implementing interface members or in authored WinRT component types)
207-
CSharpCodeFixVerifier.Diagnostic().WithSpan(26, 31, 26, 44).WithArguments("MyApp.MyObject.Test4Property"),
208-
209-
// /0/Test0.cs(33,39): warning WCTDP0021: The property 'MyApp.MyObject.Test6Property' is a dependency property, which is not the correct declaration type (all dependency properties should be declared as fields, unless implementing interface members or in authored WinRT component types)
210-
CSharpCodeFixVerifier.Diagnostic().WithSpan(33, 39, 33, 52).WithArguments("MyApp.MyObject.Test6Property"),
211-
212-
// /0/Test0.cs(36,38): warning WCTDP0021: The property 'MyApp.MyObject.Test7Property' is a dependency property, which is not the correct declaration type (all dependency properties should be declared as fields, unless implementing interface members or in authored WinRT component types)
213-
CSharpCodeFixVerifier.Diagnostic().WithSpan(36, 38, 36, 51).WithArguments("MyApp.MyObject.Test7Property")
192+
// /0/Test0.cs(29,38): warning WCTDP0021: The property 'MyApp.MyObject.Test5Property' is a dependency property, which is not the correct declaration type (all dependency properties should be declared as fields, unless implementing interface members or in authored WinRT component types)
193+
CSharpCodeFixVerifier.Diagnostic().WithSpan(29, 38, 29, 51).WithArguments("MyApp.MyObject.Test5Property")
214194
]);
215195

216196
await test.RunAsync();

components/DependencyPropertyGenerator/CommunityToolkit.DependencyPropertyGenerator.Tests/Test_UseFieldDeclarationCorrectlyCodeFixer.cs

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ public class Test_UseFieldDeclarationCorrectlyCodeFixer
1616
{
1717
[TestMethod]
1818
[DataRow("private static readonly DependencyProperty")]
19-
[DataRow("public readonly DependencyProperty")]
2019
[DataRow("public static DependencyProperty")]
2120
[DataRow("public static volatile DependencyProperty")]
2221
[DataRow("public static readonly DependencyProperty?")]
@@ -59,7 +58,6 @@ public class MyObject : DependencyObject
5958

6059
[TestMethod]
6160
[DataRow("private static readonly DependencyProperty")]
62-
[DataRow("public readonly DependencyProperty")]
6361
[DataRow("public static DependencyProperty")]
6462
[DataRow("public static volatile DependencyProperty")]
6563
[DataRow("public static readonly DependencyProperty?")]
@@ -121,13 +119,12 @@ namespace MyApp;
121119
public class MyObject : DependencyObject
122120
{
123121
private static readonly DependencyProperty [|Test1Property|];
124-
public readonly DependencyProperty [|Test2Property|];
125-
public static DependencyProperty [|Test3Property|];
126-
public static readonly DependencyProperty Test4Property;
127-
public static volatile DependencyProperty [|Test5Property|];
128-
public static readonly DependencyProperty? [|Test6Property|];
122+
public static DependencyProperty [|Test2Property|];
123+
public static readonly DependencyProperty Test3Property;
124+
public static volatile DependencyProperty [|Test4Property|];
125+
public static readonly DependencyProperty? [|Test5Property|];
126+
public static readonly DependencyProperty Test6Property;
129127
public static readonly DependencyProperty Test7Property;
130-
public static readonly DependencyProperty Test8Property;
131128
}
132129
""";
133130

@@ -147,7 +144,6 @@ public class MyObject : DependencyObject
147144
public static readonly DependencyProperty Test5Property;
148145
public static readonly DependencyProperty Test6Property;
149146
public static readonly DependencyProperty Test7Property;
150-
public static readonly DependencyProperty Test8Property;
151147
}
152148
""";
153149

@@ -178,7 +174,7 @@ public class MyObject : DependencyObject
178174
typeof(MyObject),
179175
null);
180176
181-
public readonly DependencyProperty [|Test2Property|] = DependencyProperty.Register(
177+
internal static volatile DependencyProperty [|Test2Property|] = DependencyProperty.Register(
182178
"Test2",
183179
typeof(string),
184180
typeof(MyObject),

0 commit comments

Comments
 (0)