Skip to content

Commit 1d9ba0a

Browse files
committed
Support target-typed 'new()' expressions for metadata
1 parent 9a56de0 commit 1d9ba0a

File tree

3 files changed

+89
-1
lines changed

3 files changed

+89
-1
lines changed

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

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -512,7 +512,16 @@ void HandleSetAccessor(IPropertySymbol propertySymbol, PropertyFlags propertyFla
512512
// Next, check if the argument is 'new PropertyMetadata(...)' with the default value for the property type
513513
if (propertyMetadataArgument.Value is not IObjectCreationOperation { Arguments: [{ } defaultValueArgument, ..] } objectCreationOperation)
514514
{
515-
return;
515+
// Before failing, check whether the argument is 'new (...)`. In this case, the target type is 'PropertyMetadata' anyway,
516+
// which we also validate right after this check as well anyway. With 'new()', we expect a conversion operation instead.
517+
if (propertyMetadataArgument.Value is not IConversionOperation { IsImplicit: true } objectCreationConversionOperation ||
518+
objectCreationConversionOperation.Operand is not IObjectCreationOperation { Arguments: [_, ..] } conversionObjectCreationOperation)
519+
{
520+
return;
521+
}
522+
523+
defaultValueArgument = conversionObjectCreationOperation.Arguments[0];
524+
objectCreationOperation = conversionObjectCreationOperation;
516525
}
517526

518527
// Make sure the object being created is actually 'PropertyMetadata'

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

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3338,6 +3338,35 @@ public partial class MyObject<T, TOther> : DependencyObject {{typeConstraints}}
33383338
await CSharpAnalyzerTest<UseGeneratedDependencyPropertyOnManualPropertyAnalyzer>.VerifyAnalyzerAsync(source, LanguageVersion.CSharp13);
33393339
}
33403340

3341+
// Regression test for a case found in the Microsoft Store
3342+
[TestMethod]
3343+
public async Task UseGeneratedDependencyPropertyOnManualPropertyAnalyzer_ValidProperty_WithTargetTypedPropertyMetadataNew_Warns()
3344+
{
3345+
const string source = """
3346+
using Windows.Foundation;
3347+
using Windows.UI.Xaml;
3348+
3349+
namespace MyApp;
3350+
3351+
public class MyObject : DependencyObject
3352+
{
3353+
public static readonly DependencyProperty VisibleAreaProperty = DependencyProperty.Register(
3354+
nameof(VisibleArea),
3355+
typeof(Rect),
3356+
typeof(MyObject),
3357+
new(default(Rect)));
3358+
3359+
public Rect {|WCTDPG0017:VisibleArea|}
3360+
{
3361+
get => (Rect)GetValue(VisibleAreaProperty);
3362+
private set => SetValue(VisibleAreaProperty, value);
3363+
}
3364+
}
3365+
""";
3366+
3367+
await CSharpAnalyzerTest<UseGeneratedDependencyPropertyOnManualPropertyAnalyzer>.VerifyAnalyzerAsync(source, LanguageVersion.CSharp13);
3368+
}
3369+
33413370
[TestMethod]
33423371
[DataRow("where T : struct")]
33433372
[DataRow("where T : unmanaged")]

components/DependencyPropertyGenerator/CommunityToolkit.DependencyPropertyGenerator.Tests/Test_UseGeneratedDependencyPropertyOnManualPropertyCodeFixer.cs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2755,4 +2755,54 @@ public enum MyEnum { A, B }
27552755

27562756
await test.RunAsync();
27572757
}
2758+
2759+
// Regression test for a case found in the Microsoft Store
2760+
[TestMethod]
2761+
public async Task SimpleProperty_WithTargetTypedPropertyMetadataNew()
2762+
{
2763+
const string original = """
2764+
using Windows.Foundation;
2765+
using Windows.UI.Xaml;
2766+
2767+
namespace MyApp;
2768+
2769+
public class MyObject : DependencyObject
2770+
{
2771+
public static readonly DependencyProperty VisibleAreaProperty = DependencyProperty.Register(
2772+
nameof(VisibleArea),
2773+
typeof(Rect),
2774+
typeof(MyObject),
2775+
new(default(Rect)));
2776+
2777+
public Rect {|WCTDPG0017:VisibleArea|}
2778+
{
2779+
get => (Rect)GetValue(VisibleAreaProperty);
2780+
private set => SetValue(VisibleAreaProperty, value);
2781+
}
2782+
}
2783+
""";
2784+
2785+
const string @fixed = """
2786+
using CommunityToolkit.WinUI;
2787+
using Windows.Foundation;
2788+
using Windows.UI.Xaml;
2789+
2790+
namespace MyApp;
2791+
2792+
public partial class MyObject : DependencyObject
2793+
{
2794+
[GeneratedDependencyProperty]
2795+
public partial Rect {|CS9248:VisibleArea|} { get; private set; }
2796+
}
2797+
""";
2798+
2799+
CSharpCodeFixTest test = new(LanguageVersion.Preview)
2800+
{
2801+
TestCode = original,
2802+
FixedCode = @fixed,
2803+
MarkupOptions = MarkupOptions.UseFirstDescriptor
2804+
};
2805+
2806+
await test.RunAsync();
2807+
}
27582808
}

0 commit comments

Comments
 (0)