Skip to content

Commit eb41f89

Browse files
committed
Add diagnostics for invalid [ObservableRecipient] target type
1 parent 5cb0a73 commit eb41f89

File tree

4 files changed

+49
-0
lines changed

4 files changed

+49
-0
lines changed

CommunityToolkit.Mvvm.SourceGenerators/AnalyzerReleases.Unshipped.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,4 @@ MVVMTK0017 | CommunityToolkit.Mvvm.SourceGenerators.INotifyPropertyChangedGenera
2525
MVVMTK0018 | CommunityToolkit.Mvvm.SourceGenerators.ObservableObjectGenerator | Error | See https://aka.ms/mvvmtoolkit/error
2626
MVVMTK0019 | CommunityToolkit.Mvvm.SourceGenerators.ObservablePropertyGenerator | Error | See https://aka.ms/mvvmtoolkit/error
2727
MVVMTK0020 | CommunityToolkit.Mvvm.SourceGenerators.ObservablePropertyGenerator | Error | See https://aka.ms/mvvmtoolkit/error
28+
MVVMTK0021 | CommunityToolkit.Mvvm.SourceGenerators.ObservableRecipientGenerator | Error | See https://aka.ms/mvvmtoolkit/error

CommunityToolkit.Mvvm.SourceGenerators/ComponentModel/ObservableRecipientGenerator.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,16 @@ protected override bool ValidateTargetType(INamedTypeSymbol typeSymbol, Observab
7979
return false;
8080
}
8181

82+
// Check if the type already inherits [ObservableRecipient]
83+
if (typeSymbol.InheritsAttributeWithFullyQualifiedName("global::CommunityToolkit.Mvvm.ComponentModel.ObservableRecipientAttribute"))
84+
{
85+
builder.Add(InvalidAttributeCombinationForObservableRecipientAttributeError, typeSymbol, typeSymbol);
86+
87+
diagnostics = builder.ToImmutable();
88+
89+
return false;
90+
}
91+
8292
// In order to use [ObservableRecipient], the target type needs to inherit from ObservableObject,
8393
// or be annotated with [ObservableObject] or [INotifyPropertyChanged] (with additional helpers).
8494
if (!typeSymbol.InheritsFromFullyQualifiedName("global::CommunityToolkit.Mvvm.ComponentModel.ObservableObject") &&

CommunityToolkit.Mvvm.SourceGenerators/Diagnostics/DiagnosticDescriptors.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,4 +331,20 @@ internal static class DiagnosticDescriptors
331331
isEnabledByDefault: true,
332332
description: "Fields not annotated with [ObservableProperty] cannot use [AlsoNotifyChangeFor] and [AlsoNotifyCanExecuteFor].",
333333
helpLinkUri: "https://aka.ms/mvvmtoolkit");
334+
335+
/// <summary>
336+
/// Gets a <see cref="DiagnosticDescriptor"/> indicating when <c>[ObservableRecipient]</c> is applied to a type with an attribute already.
337+
/// <para>
338+
/// Format: <c>"Cannot apply [ObservableRecipient] to type {0}, as it already inherits this attribute from a base type"</c>.
339+
/// </para>
340+
/// </summary>
341+
public static readonly DiagnosticDescriptor InvalidAttributeCombinationForObservableRecipientAttributeError = new DiagnosticDescriptor(
342+
id: "MVVMTK0021",
343+
title: "Invalid target type for [ObservableRecipient]",
344+
messageFormat: "Cannot apply [ObservableRecipient] to type {0}, as it already inherits this attribute from a base type",
345+
category: typeof(ObservableRecipientGenerator).FullName,
346+
defaultSeverity: DiagnosticSeverity.Error,
347+
isEnabledByDefault: true,
348+
description: "Cannot apply [ObservableRecipient] to a type that already inherits this attribute from a base type.",
349+
helpLinkUri: "https://aka.ms/mvvmtoolkit");
334350
}

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

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -998,6 +998,28 @@ public partial class MyViewModel
998998
VerifyGeneratedDiagnostics<ObservablePropertyGenerator>(source, "MVVMTK0020");
999999
}
10001000

1001+
[TestMethod]
1002+
public void InvalidAttributeCombinationForObservableRecipientAttributeError()
1003+
{
1004+
string source = @"
1005+
using CommunityToolkit.Mvvm.ComponentModel;
1006+
1007+
namespace MyApp
1008+
{
1009+
[ObservableRecipient]
1010+
public partial class A : ObservableObject
1011+
{
1012+
}
1013+
1014+
[ObservableRecipient]
1015+
public partial class B : A
1016+
{
1017+
}
1018+
}";
1019+
1020+
VerifyGeneratedDiagnostics<ObservableRecipientGenerator>(source, "MVVMTK0021");
1021+
}
1022+
10011023
/// <summary>
10021024
/// Verifies the output of a source generator.
10031025
/// </summary>

0 commit comments

Comments
 (0)