Skip to content

Commit 109d346

Browse files
committed
Handle explicit 'null' callbacks in metadata
1 parent 9dc6710 commit 109d346

File tree

2 files changed

+119
-1
lines changed

2 files changed

+119
-1
lines changed

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -409,7 +409,7 @@ void HandleSetAccessor(IPropertySymbol propertySymbol, PropertyFlags propertyFla
409409
else
410410
{
411411
// Next, check if the argument is 'new PropertyMetadata(...)' with the default value for the property type
412-
if (propertyMetadataArgument.Value is not IObjectCreationOperation { Arguments: [{ } defaultValueArgument] } objectCreationOperation)
412+
if (propertyMetadataArgument.Value is not IObjectCreationOperation { Arguments: [{ } defaultValueArgument, ..] } objectCreationOperation)
413413
{
414414
return;
415415
}
@@ -420,6 +420,12 @@ void HandleSetAccessor(IPropertySymbol propertySymbol, PropertyFlags propertyFla
420420
return;
421421
}
422422

423+
// If we have a second argument, a 'null' literal is the only supported value for it
424+
if (objectCreationOperation.Arguments is not ([_] or [_, { Value.ConstantValue: { HasValue: true, Value: null } }]))
425+
{
426+
return;
427+
}
428+
423429
// The argument should be a conversion operation (boxing)
424430
if (defaultValueArgument.Value is not IConversionOperation { IsTryCast: false, Type.SpecialType: SpecialType.System_Object } conversionOperation)
425431
{

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

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1310,4 +1310,116 @@ public partial class MyNestedObject : DependencyObject
13101310

13111311
await test.RunAsync();
13121312
}
1313+
1314+
[TestMethod]
1315+
public async Task SimpleProperty_ExplicitNullCallbackArgument_IsHandledCorrectly1()
1316+
{
1317+
const string original = """
1318+
using Windows.UI.Xaml;
1319+
1320+
#nullable enable
1321+
1322+
namespace MyApp;
1323+
1324+
public class MyObject : DependencyObject
1325+
{
1326+
public class MyNestedObject : DependencyObject
1327+
{
1328+
public static readonly DependencyProperty NameProperty = DependencyProperty.Register(
1329+
name: "Name",
1330+
propertyType: typeof(string),
1331+
ownerType: typeof(MyNestedObject),
1332+
typeMetadata: new PropertyMetadata(null, null));
1333+
1334+
public string? [|Name|]
1335+
{
1336+
get => (string?)GetValue(NameProperty);
1337+
set => SetValue(NameProperty, value);
1338+
}
1339+
}
1340+
}
1341+
""";
1342+
1343+
const string @fixed = """
1344+
using CommunityToolkit.WinUI;
1345+
using Windows.UI.Xaml;
1346+
1347+
#nullable enable
1348+
1349+
namespace MyApp;
1350+
1351+
public partial class MyObject : DependencyObject
1352+
{
1353+
public partial class MyNestedObject : DependencyObject
1354+
{
1355+
[GeneratedDependencyProperty]
1356+
public partial string? {|CS9248:Name|} { get; set; }
1357+
}
1358+
}
1359+
""";
1360+
1361+
CSharpCodeFixTest test = new(LanguageVersion.Preview)
1362+
{
1363+
TestCode = original,
1364+
FixedCode = @fixed
1365+
};
1366+
1367+
await test.RunAsync();
1368+
}
1369+
1370+
[TestMethod]
1371+
public async Task SimpleProperty_ExplicitNullCallbackArgument_IsHandledCorrectly2()
1372+
{
1373+
const string original = """
1374+
using Windows.UI.Xaml;
1375+
1376+
#nullable enable
1377+
1378+
namespace MyApp;
1379+
1380+
public class MyObject : DependencyObject
1381+
{
1382+
public class MyNestedObject : DependencyObject
1383+
{
1384+
public static readonly DependencyProperty NameProperty = DependencyProperty.Register(
1385+
name: "Name",
1386+
propertyType: typeof(string),
1387+
ownerType: typeof(MyNestedObject),
1388+
typeMetadata: new PropertyMetadata("", null));
1389+
1390+
public string? [|Name|]
1391+
{
1392+
get => (string?)GetValue(NameProperty);
1393+
set => SetValue(NameProperty, value);
1394+
}
1395+
}
1396+
}
1397+
""";
1398+
1399+
const string @fixed = """
1400+
using CommunityToolkit.WinUI;
1401+
using Windows.UI.Xaml;
1402+
1403+
#nullable enable
1404+
1405+
namespace MyApp;
1406+
1407+
public partial class MyObject : DependencyObject
1408+
{
1409+
public partial class MyNestedObject : DependencyObject
1410+
{
1411+
[GeneratedDependencyProperty(DefaultValue = "")]
1412+
public partial string? {|CS9248:Name|} { get; set; }
1413+
}
1414+
}
1415+
""";
1416+
1417+
CSharpCodeFixTest test = new(LanguageVersion.Preview)
1418+
{
1419+
TestCode = original,
1420+
FixedCode = @fixed
1421+
};
1422+
1423+
await test.RunAsync();
1424+
}
13131425
}

0 commit comments

Comments
 (0)