Skip to content

Commit e3e90d7

Browse files
committed
Fix some default enum scenarios, add tests
1 parent 909923d commit e3e90d7

File tree

2 files changed

+111
-0
lines changed

2 files changed

+111
-0
lines changed

components/DependencyPropertyGenerator/CommunityToolkit.DependencyPropertyGenerator.SourceGenerators/Extensions/IOperationExtensions.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,23 @@ public static bool IsConstantValueDefault(this IOperation operation)
3636
return true;
3737
}
3838

39+
// Special case enum types as well (enum types only support a subset of primitive types)
40+
if (operation.Type is INamedTypeSymbol { TypeKind: TypeKind.Enum, EnumUnderlyingType: { } underlyingType })
41+
{
42+
return (underlyingType.SpecialType, operation.ConstantValue.Value) switch
43+
{
44+
(SpecialType.System_Byte, default(byte)) or
45+
(SpecialType.System_SByte, default(sbyte)) or
46+
(SpecialType.System_Int16, default(short)) or
47+
(SpecialType.System_UInt16, default(ushort)) or
48+
(SpecialType.System_Int32, default(int)) or
49+
(SpecialType.System_UInt32, default(uint)) or
50+
(SpecialType.System_Int64, default(long)) or
51+
(SpecialType.System_UInt64, default(ulong)) => true,
52+
_ => false
53+
};
54+
}
55+
3956
// Manually match for known primitive types (this should be kept in sync with 'IsWellKnownWinRTProjectedValueType')
4057
return (operation.Type.SpecialType, operation.ConstantValue.Value) switch
4158
{

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

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2429,4 +2429,98 @@ public abstract partial class KeyFrame<TValue, TKeyFrame> : DependencyObject
24292429

24302430
await test.RunAsync();
24312431
}
2432+
2433+
// Some mixed scenarios with enum types, nullable types, and different property metadata types.
2434+
// Not all of these are a 1:1 match with the code fixer (some aren't even fully valid) just yet.
2435+
[TestMethod]
2436+
[DataRow("int?", "int?", "new PropertyMetadata(default(int))", "(DefaultValue = 0)")]
2437+
//[DataRow("int?", "object", "new PropertyMetadata(default(int))", "(PropertyType = typeof(object), DefaultValue = 0)")]
2438+
[DataRow("Visibility", "Visibility", "null", "")]
2439+
[DataRow("Visibility", "Visibility", "new PropertyMetadata(null)", "(DefaultValue = null)")]
2440+
[DataRow("Visibility", "Visibility", "new PropertyMetadata(default(Visibility))", "")]
2441+
//[DataRow("Visibility", "object", "null", "(PropertyType = typeof(object), DefaultValue = null)")]
2442+
//[DataRow("Visibility", "object", "new PropertyMetadata(null)", "(PropertyType = typeof(object), DefaultValue = null)")]
2443+
[DataRow("Visibility", "object", "new PropertyMetadata(default(Visibility))", "(PropertyType = typeof(object))")]
2444+
[DataRow("Visibility?", "Visibility?", "null", "")]
2445+
[DataRow("Visibility?", "Visibility?", "new PropertyMetadata(null)", "")]
2446+
//[DataRow("Visibility?", "Visibility?", "new PropertyMetadata(default(Visibility))", "(DefaultValue = Visibility.Visible)")]
2447+
//[DataRow("Visibility?", "Visibility?", "new PropertyMetadata(Visibility.Visible)", "(DefaultValue = Visibility.Visible)")]
2448+
[DataRow("Visibility?", "Visibility?", "new PropertyMetadata(Visibility.Collapsed)", "(DefaultValue = Visibility.Collapsed)")]
2449+
[DataRow("Visibility?", "object", "null", "(PropertyType = typeof(object))")]
2450+
[DataRow("Visibility?", "object", "new PropertyMetadata(null)", "(PropertyType = typeof(object))")]
2451+
//[DataRow("Visibility?", "object", "new PropertyMetadata(default(Visibility))", "(PropertyType = typeof(object), DefaultValue = Visibility.Visible)")]
2452+
//[DataRow("Visibility?", "object", "new PropertyMetadata(Visibility.Visible)", "(PropertyType = typeof(object), DefaultValue = Visibility.Visible)")]
2453+
[DataRow("Visibility?", "object", "new PropertyMetadata(Visibility.Collapsed)", "(PropertyType = typeof(object), DefaultValue = Visibility.Collapsed)")]
2454+
[DataRow("MyEnum", "MyEnum", "null", "(DefaultValue = null)")]
2455+
[DataRow("MyEnum", "MyEnum", "new PropertyMetadata(null)", "(DefaultValue = null)")]
2456+
[DataRow("MyEnum", "MyEnum", "new PropertyMetadata(default(MyEnum))", "")]
2457+
//[DataRow("MyEnum", "object", "null", "(PropertyType = typeof(object), DefaultValue = null)")]
2458+
//[DataRow("MyEnum", "object", "new PropertyMetadata(null)", "(PropertyType = typeof(object), DefaultValue = null)")]
2459+
[DataRow("MyEnum", "object", "new PropertyMetadata(default(MyEnum))", "(PropertyType = typeof(object))")]
2460+
[DataRow("MyEnum?", "MyEnum?", "null", "")]
2461+
[DataRow("MyEnum?", "MyEnum?", "new PropertyMetadata(null)", "")]
2462+
//[DataRow("MyEnum?", "MyEnum?", "new PropertyMetadata(default(MyEnum))", "(DefaultValue = MyEnum.A)")]
2463+
[DataRow("MyEnum?", "MyEnum?", "new PropertyMetadata(MyEnum.A)", "(DefaultValue = MyEnum.A)")]
2464+
[DataRow("MyEnum?", "MyEnum?", "new PropertyMetadata(MyEnum.B)", "(DefaultValue = MyEnum.B)")]
2465+
[DataRow("MyEnum?", "object", "null", "(PropertyType = typeof(object))")]
2466+
[DataRow("MyEnum?", "object", "new PropertyMetadata(null)", "(PropertyType = typeof(object))")]
2467+
//[DataRow("MyEnum?", "object", "new PropertyMetadata(default(MyEnum))", "(PropertyType = typeof(object), DefaultValue = MyEnum.A)")]
2468+
//[DataRow("MyEnum?", "object", "new PropertyMetadata(MyEnum.A)", "(PropertyType = typeof(object), DefaultValue = MyEnum.A)")]
2469+
[DataRow("MyEnum?", "object", "new PropertyMetadata(MyEnum.B)", "(PropertyType = typeof(object), DefaultValue = MyEnum.B)")]
2470+
public async Task SimpleProperty_MixedEnumAndNullable_WithPropertyType_HandlesAllScenariosCorrectly(
2471+
string declaredType,
2472+
string propertyType,
2473+
string propertyMetadataExpression,
2474+
string attributeArguments)
2475+
{
2476+
string original = $$"""
2477+
using Windows.UI.Xaml;
2478+
2479+
#nullable enable
2480+
2481+
namespace MyApp;
2482+
2483+
public class MyObject : DependencyObject
2484+
{
2485+
public static readonly DependencyProperty NameProperty = DependencyProperty.Register(
2486+
name: "Name",
2487+
propertyType: typeof({{propertyType}}),
2488+
ownerType: typeof(MyObject),
2489+
typeMetadata: {{propertyMetadataExpression}});
2490+
2491+
public {{declaredType}} [|Name|]
2492+
{
2493+
get => ({{declaredType}})GetValue(NameProperty);
2494+
set => SetValue(NameProperty, value);
2495+
}
2496+
}
2497+
2498+
public enum MyEnum { A, B }
2499+
""";
2500+
2501+
string @fixed = $$"""
2502+
using CommunityToolkit.WinUI;
2503+
using Windows.UI.Xaml;
2504+
2505+
#nullable enable
2506+
2507+
namespace MyApp;
2508+
2509+
public partial class MyObject : DependencyObject
2510+
{
2511+
[GeneratedDependencyProperty{{attributeArguments}}]
2512+
public partial {{declaredType}} {|CS9248:Name|} { get; set; }
2513+
}
2514+
2515+
public enum MyEnum { A, B }
2516+
""";
2517+
2518+
CSharpCodeFixTest test = new(LanguageVersion.Preview)
2519+
{
2520+
TestCode = original,
2521+
FixedCode = @fixed
2522+
};
2523+
2524+
await test.RunAsync();
2525+
}
24322526
}

0 commit comments

Comments
 (0)