Skip to content

Commit f1f253e

Browse files
authored
Merge pull request #285 from CommunityToolkit/dev/icommand-nullability-annotations
Properly forward nullability annotations for [ICommand]
2 parents 36a3b82 + 9560e3f commit f1f253e

File tree

2 files changed

+42
-7
lines changed

2 files changed

+42
-7
lines changed

CommunityToolkit.Mvvm.SourceGenerators/Input/ICommandGenerator.Execute.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -438,8 +438,8 @@ private static bool TryMapCommandTypesFromMethod(
438438
commandClassType = "global::CommunityToolkit.Mvvm.Input.RelayCommand";
439439
delegateType = "global::System.Action";
440440
supportsCancellation = false;
441-
commandTypeArguments = ImmutableArray.Create(parameter.Type.GetFullyQualifiedName());
442-
delegateTypeArguments = ImmutableArray.Create(parameter.Type.GetFullyQualifiedName());
441+
commandTypeArguments = ImmutableArray.Create(parameter.Type.GetFullyQualifiedNameWithNullabilityAnnotations());
442+
delegateTypeArguments = ImmutableArray.Create(parameter.Type.GetFullyQualifiedNameWithNullabilityAnnotations());
443443

444444
return true;
445445
}
@@ -472,7 +472,7 @@ private static bool TryMapCommandTypesFromMethod(
472472
delegateType = "global::System.Func";
473473
supportsCancellation = true;
474474
commandTypeArguments = ImmutableArray<string>.Empty;
475-
delegateTypeArguments = ImmutableArray.Create(singleParameter.Type.GetFullyQualifiedName(), "global::System.Threading.Tasks.Task");
475+
delegateTypeArguments = ImmutableArray.Create("global::System.Threading.CancellationToken", "global::System.Threading.Tasks.Task");
476476

477477
return true;
478478
}
@@ -482,8 +482,8 @@ private static bool TryMapCommandTypesFromMethod(
482482
commandClassType = "global::CommunityToolkit.Mvvm.Input.AsyncRelayCommand";
483483
delegateType = "global::System.Func";
484484
supportsCancellation = false;
485-
commandTypeArguments = ImmutableArray.Create(singleParameter.Type.GetFullyQualifiedName());
486-
delegateTypeArguments = ImmutableArray.Create(singleParameter.Type.GetFullyQualifiedName(), "global::System.Threading.Tasks.Task");
485+
commandTypeArguments = ImmutableArray.Create(singleParameter.Type.GetFullyQualifiedNameWithNullabilityAnnotations());
486+
delegateTypeArguments = ImmutableArray.Create(singleParameter.Type.GetFullyQualifiedNameWithNullabilityAnnotations(), "global::System.Threading.Tasks.Task");
487487

488488
return true;
489489
}
@@ -498,8 +498,8 @@ private static bool TryMapCommandTypesFromMethod(
498498
commandClassType = "global::CommunityToolkit.Mvvm.Input.AsyncRelayCommand";
499499
delegateType = "global::System.Func";
500500
supportsCancellation = true;
501-
commandTypeArguments = ImmutableArray.Create(firstParameter.Type.GetFullyQualifiedName());
502-
delegateTypeArguments = ImmutableArray.Create(firstParameter.Type.GetFullyQualifiedName(), secondParameter.Type.GetFullyQualifiedName(), "global::System.Threading.Tasks.Task");
501+
commandTypeArguments = ImmutableArray.Create(firstParameter.Type.GetFullyQualifiedNameWithNullabilityAnnotations());
502+
delegateTypeArguments = ImmutableArray.Create(firstParameter.Type.GetFullyQualifiedNameWithNullabilityAnnotations(), "global::System.Threading.CancellationToken", "global::System.Threading.Tasks.Task");
503503

504504
return true;
505505
}

tests/CommunityToolkit.Mvvm.UnitTests/Test_ICommandAttribute.cs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -500,6 +500,23 @@ public async Task Test_ICommandAttribute_WithOnPrefixes()
500500
Assert.IsTrue(model.HasDownloadCommandRun);
501501
}
502502

503+
// See https://github.com/CommunityToolkit/dotnet/issues/283
504+
[TestMethod]
505+
public void Test_ICommandAttribute_VerifyNoWarningsForNullableValues()
506+
{
507+
ModelWithCommandsWithNullabilityAnnotations model = new();
508+
509+
// Here we just need to verify we don't get any warnings.
510+
// That is, that means the generated code has the right nullability annotations.
511+
model.NullableObjectCommand.Execute(null);
512+
model.ListWithNullableTypeCommand.Execute(null);
513+
model.ListWithNullableTypeCommand.Execute(new List<object?>());
514+
model.TupleWithNullableElementsCommand.Execute((DateTime.Now, null, null, null));
515+
model.TupleWithNullableElementsCommand.Execute((DateTime.Now, null, true, new List<string>()));
516+
model.TupleWithNullableElementsCommand.Execute((null, "Hello", null, null));
517+
model.TupleWithNullableElementsCommand.Execute((null, null, null, null));
518+
}
519+
503520
#region Region
504521
public class Region
505522
{
@@ -871,4 +888,22 @@ private async Task OnDownloadAsync()
871888
HasDownloadCommandRun = true;
872889
}
873890
}
891+
892+
partial class ModelWithCommandsWithNullabilityAnnotations
893+
{
894+
[ICommand]
895+
private void NullableObject(object? parameter)
896+
{
897+
}
898+
899+
[ICommand]
900+
private void ListWithNullableType(List<object?> parameter)
901+
{
902+
}
903+
904+
[ICommand]
905+
private void TupleWithNullableElements((DateTime? date, string? message, bool? shouldPrint, List<string>? stringList) parameter)
906+
{
907+
}
908+
}
874909
}

0 commit comments

Comments
 (0)