Skip to content

Commit 8742886

Browse files
authored
Merge pull request #277 from CommunityToolkit/dev/duplicate-base-icommand-diagnostics
Add diagnostic for duplicate ICommand-s in base types
2 parents 95c30fa + 4920161 commit 8742886

File tree

2 files changed

+47
-0
lines changed

2 files changed

+47
-0
lines changed

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

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,25 @@ public static ImmutableArray<MemberDeclarationSyntax> GetSyntax(CommandInfo comm
315315
/// <returns>Whether or not <paramref name="methodSymbol"/> was unique within its containing type.</returns>
316316
private static bool IsCommandDefinitionUnique(IMethodSymbol methodSymbol, ImmutableArray<Diagnostic>.Builder diagnostics)
317317
{
318+
// If a duplicate is present in any of the base types, always emit a diagnostic for the current method.
319+
// That is, there is no need to check the order: we assume the priority is top-down in the type hierarchy.
320+
// This check has to be done first, as otherwise there would always be a false positive for the current type.
321+
foreach (ISymbol symbol in methodSymbol.ContainingType.BaseType?.GetAllMembers(methodSymbol.Name) ?? Enumerable.Empty<ISymbol>())
322+
{
323+
if (symbol is IMethodSymbol otherSymbol &&
324+
otherSymbol.HasAttributeWithFullyQualifiedName("global::CommunityToolkit.Mvvm.Input.ICommandAttribute"))
325+
{
326+
diagnostics.Add(
327+
MultipleICommandMethodOverloadsError,
328+
methodSymbol,
329+
methodSymbol.ContainingType,
330+
methodSymbol);
331+
332+
return false;
333+
}
334+
}
335+
336+
// Check for duplicates in the containing type for the annotated method
318337
foreach (ISymbol symbol in methodSymbol.ContainingType.GetMembers(methodSymbol.Name))
319338
{
320339
if (symbol is IMethodSymbol otherSymbol &&

tests/CommunityToolkit.Mvvm.SourceGenerators.UnitTests/Test_SourceGeneratorsDiagnostics.cs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1105,6 +1105,34 @@ private void GreetUser(object value)
11051105
VerifyGeneratedDiagnostics<ICommandGenerator>(source, "MVVMTK0023");
11061106
}
11071107

1108+
[TestMethod]
1109+
public void MultipleICommandMethodOverloads_WithOverloadInBaseType()
1110+
{
1111+
string source = @"
1112+
using CommunityToolkit.Mvvm.Input;
1113+
1114+
namespace MyApp
1115+
{
1116+
public partial class BaseViewModel
1117+
{
1118+
[ICommand]
1119+
private void GreetUser()
1120+
{
1121+
}
1122+
}
1123+
1124+
public partial class SampleViewModel : BaseViewModel
1125+
{
1126+
[ICommand]
1127+
private void GreetUser(object value)
1128+
{
1129+
}
1130+
}
1131+
}";
1132+
1133+
VerifyGeneratedDiagnostics<ICommandGenerator>(source, "MVVMTK0023");
1134+
}
1135+
11081136
[TestMethod]
11091137
public void InvalidObservablePropertyError_Object()
11101138
{

0 commit comments

Comments
 (0)