Skip to content

Commit 23acb10

Browse files
committed
Fix more edge cases in code fixer
1 parent a68ed9f commit 23acb10

File tree

2 files changed

+28
-7
lines changed

2 files changed

+28
-7
lines changed

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

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -502,8 +502,18 @@ void HandleSetAccessor(IPropertySymbol propertySymbol, PropertyFlags propertyFla
502502
continue;
503503
}
504504

505-
// Execute the deferred default value validation, if necessary
506-
if (fieldFlags.DefaultValueOperation is not null)
505+
// Execute the deferred default value validation, if necessary. If we have an operation
506+
// here, it means we had some constructed property metadata. Otherwise, it was 'null'.
507+
if (fieldFlags.DefaultValueOperation is null)
508+
{
509+
// Special case: the whole property metadata is 'null', and the metadata type is nullable, but
510+
// the property type isn't. In this case, we need to ensure the explicit 'null' is preserved.
511+
if (fieldFlags.IsExplicitConversionFromNonNullableToNullableMetdataType(pair.Key.Type))
512+
{
513+
fieldFlags.DefaultValue = TypedConstantInfo.Null.Instance;
514+
}
515+
}
516+
else
507517
{
508518
bool isNullableValueType = pair.Key.Type.IsNullableValueType();
509519

@@ -523,9 +533,7 @@ void HandleSetAccessor(IPropertySymbol propertySymbol, PropertyFlags propertyFla
523533
{
524534
fieldFlags.DefaultValue = TypedConstantInfo.Null.Instance;
525535
}
526-
else if (!SymbolEqualityComparer.Default.Equals(pair.Key.Type, fieldFlags.PropertyType) &&
527-
!pair.Key.Type.IsNullableValueType() &&
528-
fieldFlags.PropertyType!.IsDefaultValueNull())
536+
else if (fieldFlags.IsExplicitConversionFromNonNullableToNullableMetdataType(pair.Key.Type))
529537
{
530538
// Special case: the property type is not nullable, but the property metadata type is explicitly declared as
531539
// a nullable type, and the default value is set to 'null'. In this case, we need to preserve this value.
@@ -773,6 +781,19 @@ private sealed class FieldFlags
773781
/// The location of the target field being initialized.
774782
/// </summary>
775783
public Location? FieldLocation;
784+
785+
/// <summary>
786+
/// Checks whether the field has an explicit conversion to a nullable metadata type (where the property isn't).
787+
/// </summary>
788+
/// <param name="propertyType">The property type.</param>
789+
/// <returns>Whether the field has an explicit conversion to a nullable metadata type</returns>
790+
public bool IsExplicitConversionFromNonNullableToNullableMetdataType(ITypeSymbol propertyType)
791+
{
792+
return
793+
!SymbolEqualityComparer.Default.Equals(propertyType, PropertyType) &&
794+
!propertyType.IsDefaultValueNull() &&
795+
PropertyType!.IsDefaultValueNull();
796+
}
776797
}
777798
}
778799

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2448,7 +2448,7 @@ public abstract partial class KeyFrame<TValue, TKeyFrame> : DependencyObject
24482448
[DataRow("Visibility", "Visibility", "new PropertyMetadata(default(Visibility))", "")]
24492449
[DataRow("Visibility", "Visibility", "new PropertyMetadata(Visibility.Visible)", "")]
24502450
[DataRow("Visibility", "Visibility", "new PropertyMetadata(Visibility.Collapsed)", "(DefaultValue = Visibility.Collapsed)")]
2451-
//[DataRow("Visibility", "object", "null", "(PropertyType = typeof(object), DefaultValue = null)")]
2451+
[DataRow("Visibility", "object", "null", "(PropertyType = typeof(object), DefaultValue = null)")]
24522452
[DataRow("Visibility", "object", "new PropertyMetadata(null)", "(PropertyType = typeof(object), DefaultValue = null)")]
24532453
[DataRow("Visibility", "object", "new PropertyMetadata(default(Visibility))", "(PropertyType = typeof(object))")]
24542454
[DataRow("Visibility", "object", "new PropertyMetadata(Visibility.Visible)", "(PropertyType = typeof(object))")]
@@ -2469,7 +2469,7 @@ public abstract partial class KeyFrame<TValue, TKeyFrame> : DependencyObject
24692469
[DataRow("MyEnum", "MyEnum", "new PropertyMetadata(default(MyEnum))", "")]
24702470
[DataRow("MyEnum", "MyEnum", "new PropertyMetadata(MyEnum.A)", "")]
24712471
[DataRow("MyEnum", "MyEnum", "new PropertyMetadata(MyEnum.B)", "(DefaultValue = MyEnum.B)")]
2472-
//[DataRow("MyEnum", "object", "null", "(PropertyType = typeof(object), DefaultValue = null)")]
2472+
[DataRow("MyEnum", "object", "null", "(PropertyType = typeof(object), DefaultValue = null)")]
24732473
[DataRow("MyEnum", "object", "new PropertyMetadata(null)", "(PropertyType = typeof(object), DefaultValue = null)")]
24742474
[DataRow("MyEnum", "object", "new PropertyMetadata(default(MyEnum))", "(PropertyType = typeof(object))")]
24752475
[DataRow("MyEnum", "object", "new PropertyMetadata(MyEnum.A)", "(PropertyType = typeof(object))")]

0 commit comments

Comments
 (0)