mirror of
https://github.com/chylex/.NET-Community-Toolkit.git
synced 2025-02-21 16:45:59 +01:00
Rename [NotifyRecipients] to [NotifyPropertyChangedRecipients]
This commit is contained in:
parent
32285a10e9
commit
0267515b9d
CommunityToolkit.Mvvm.SourceGenerators
ComponentModel
Diagnostics
CommunityToolkit.Mvvm/ComponentModel/Attributes
tests
CommunityToolkit.Mvvm.SourceGenerators.UnitTests
CommunityToolkit.Mvvm.UnitTests
@ -20,7 +20,7 @@ namespace CommunityToolkit.Mvvm.SourceGenerators.ComponentModel.Models;
|
||||
/// <param name="PropertyChangingNames">The sequence of property changing properties to notify.</param>
|
||||
/// <param name="PropertyChangedNames">The sequence of property changed properties to notify.</param>
|
||||
/// <param name="NotifiedCommandNames">The sequence of commands to notify.</param>
|
||||
/// <param name="NotifyRecipients">Whether or not the generated property also broadcasts changes.</param>
|
||||
/// <param name="NotifyPropertyChangedRecipients">Whether or not the generated property also broadcasts changes.</param>
|
||||
/// <param name="NotifyDataErrorInfo">Whether or not the generated property also validates its value.</param>
|
||||
/// <param name="ForwardedAttributes">The sequence of forwarded attributes for the generated property.</param>
|
||||
internal sealed record PropertyInfo(
|
||||
@ -30,7 +30,7 @@ internal sealed record PropertyInfo(
|
||||
ImmutableArray<string> PropertyChangingNames,
|
||||
ImmutableArray<string> PropertyChangedNames,
|
||||
ImmutableArray<string> NotifiedCommandNames,
|
||||
bool NotifyRecipients,
|
||||
bool NotifyPropertyChangedRecipients,
|
||||
bool NotifyDataErrorInfo,
|
||||
ImmutableArray<AttributeInfo> ForwardedAttributes)
|
||||
{
|
||||
@ -48,7 +48,7 @@ protected override void AddToHashCode(ref HashCode hashCode, PropertyInfo obj)
|
||||
hashCode.AddRange(obj.PropertyChangingNames);
|
||||
hashCode.AddRange(obj.PropertyChangedNames);
|
||||
hashCode.AddRange(obj.NotifiedCommandNames);
|
||||
hashCode.Add(obj.NotifyRecipients);
|
||||
hashCode.Add(obj.NotifyPropertyChangedRecipients);
|
||||
hashCode.Add(obj.NotifyDataErrorInfo);
|
||||
hashCode.AddRange(obj.ForwardedAttributes, AttributeInfo.Comparer.Default);
|
||||
}
|
||||
@ -63,7 +63,7 @@ protected override bool AreEqual(PropertyInfo x, PropertyInfo y)
|
||||
x.PropertyChangingNames.SequenceEqual(y.PropertyChangingNames) &&
|
||||
x.PropertyChangedNames.SequenceEqual(y.PropertyChangedNames) &&
|
||||
x.NotifiedCommandNames.SequenceEqual(y.NotifiedCommandNames) &&
|
||||
x.NotifyRecipients == y.NotifyRecipients &&
|
||||
x.NotifyPropertyChangedRecipients == y.NotifyPropertyChangedRecipients &&
|
||||
x.NotifyDataErrorInfo == y.NotifyDataErrorInfo &&
|
||||
x.ForwardedAttributes.SequenceEqual(y.ForwardedAttributes, AttributeInfo.Comparer.Default);
|
||||
}
|
||||
|
@ -91,7 +91,7 @@ internal static class Execute
|
||||
ImmutableArray<AttributeInfo>.Builder forwardedAttributes = ImmutableArray.CreateBuilder<AttributeInfo>();
|
||||
bool notifyRecipients = false;
|
||||
bool notifyDataErrorInfo = false;
|
||||
bool hasOrInheritsClassLevelNotifyRecipients = false;
|
||||
bool hasOrInheritsClassLevelNotifyPropertyChangedRecipients = false;
|
||||
bool hasOrInheritsClassLevelNotifyDataErrorInfo = false;
|
||||
bool hasAnyValidationAttributes = false;
|
||||
|
||||
@ -104,11 +104,11 @@ internal static class Execute
|
||||
// The current property is always notified
|
||||
propertyChangedNames.Add(propertyName);
|
||||
|
||||
// Get the class-level [NotifyRecipients] setting, if any
|
||||
// Get the class-level [NotifyPropertyChangedRecipients] setting, if any
|
||||
if (TryGetIsNotifyingRecipients(fieldSymbol, out bool isBroadcastTargetValid))
|
||||
{
|
||||
notifyRecipients = isBroadcastTargetValid;
|
||||
hasOrInheritsClassLevelNotifyRecipients = true;
|
||||
hasOrInheritsClassLevelNotifyPropertyChangedRecipients = true;
|
||||
}
|
||||
|
||||
// Get the class-level [NotifyDataErrorInfo] setting, if any
|
||||
@ -129,7 +129,7 @@ internal static class Execute
|
||||
}
|
||||
|
||||
// Check whether the property should also notify recipients
|
||||
if (TryGetIsNotifyingRecipients(fieldSymbol, attributeData, builder, hasOrInheritsClassLevelNotifyRecipients, out isBroadcastTargetValid))
|
||||
if (TryGetIsNotifyingRecipients(fieldSymbol, attributeData, builder, hasOrInheritsClassLevelNotifyPropertyChangedRecipients, out isBroadcastTargetValid))
|
||||
{
|
||||
notifyRecipients = isBroadcastTargetValid;
|
||||
|
||||
@ -424,10 +424,10 @@ bool IsCommandNameValidWithGeneratedMembers(string commandName)
|
||||
/// </summary>
|
||||
/// <param name="fieldSymbol">The input <see cref="IFieldSymbol"/> instance to process.</param>
|
||||
/// <param name="isBroadcastTargetValid">Whether or not the the property is in a valid target that can notify recipients.</param>
|
||||
/// <returns>Whether or not the generated property for <paramref name="fieldSymbol"/> is in a type annotated with <c>[NotifyRecipients]</c>.</returns>
|
||||
/// <returns>Whether or not the generated property for <paramref name="fieldSymbol"/> is in a type annotated with <c>[NotifyPropertyChangedRecipients]</c>.</returns>
|
||||
private static bool TryGetIsNotifyingRecipients(IFieldSymbol fieldSymbol, out bool isBroadcastTargetValid)
|
||||
{
|
||||
if (fieldSymbol.ContainingType?.HasOrInheritsAttributeWithFullyQualifiedName("global::CommunityToolkit.Mvvm.ComponentModel.NotifyRecipientsAttribute") == true)
|
||||
if (fieldSymbol.ContainingType?.HasOrInheritsAttributeWithFullyQualifiedName("global::CommunityToolkit.Mvvm.ComponentModel.NotifyPropertyChangedRecipientsAttribute") == true)
|
||||
{
|
||||
// If the containing type is valid, track it
|
||||
if (fieldSymbol.ContainingType.InheritsFromFullyQualifiedName("global::CommunityToolkit.Mvvm.ComponentModel.ObservableRecipient") ||
|
||||
@ -456,23 +456,23 @@ private static bool TryGetIsNotifyingRecipients(IFieldSymbol fieldSymbol, out bo
|
||||
/// <param name="fieldSymbol">The input <see cref="IFieldSymbol"/> instance to process.</param>
|
||||
/// <param name="attributeData">The <see cref="AttributeData"/> instance for <paramref name="fieldSymbol"/>.</param>
|
||||
/// <param name="diagnostics">The current collection of gathered diagnostics.</param>
|
||||
/// <param name="hasOrInheritsClassLevelNotifyRecipients">Indicates wether the containing type of <paramref name="fieldSymbol"/> has or inherits <c>[NotifyRecipients]</c>.</param>
|
||||
/// <param name="hasOrInheritsClassLevelNotifyPropertyChangedRecipients">Indicates wether the containing type of <paramref name="fieldSymbol"/> has or inherits <c>[NotifyPropertyChangedRecipients]</c>.</param>
|
||||
/// <param name="isBroadcastTargetValid">Whether or not the the property is in a valid target that can notify recipients.</param>
|
||||
/// <returns>Whether or not the generated property for <paramref name="fieldSymbol"/> used <c>[NotifyRecipients]</c>.</returns>
|
||||
/// <returns>Whether or not the generated property for <paramref name="fieldSymbol"/> used <c>[NotifyPropertyChangedRecipients]</c>.</returns>
|
||||
private static bool TryGetIsNotifyingRecipients(
|
||||
IFieldSymbol fieldSymbol,
|
||||
AttributeData attributeData,
|
||||
ImmutableArray<Diagnostic>.Builder diagnostics,
|
||||
bool hasOrInheritsClassLevelNotifyRecipients,
|
||||
bool hasOrInheritsClassLevelNotifyPropertyChangedRecipients,
|
||||
out bool isBroadcastTargetValid)
|
||||
{
|
||||
if (attributeData.AttributeClass?.HasFullyQualifiedName("global::CommunityToolkit.Mvvm.ComponentModel.NotifyRecipientsAttribute") == true)
|
||||
if (attributeData.AttributeClass?.HasFullyQualifiedName("global::CommunityToolkit.Mvvm.ComponentModel.NotifyPropertyChangedRecipientsAttribute") == true)
|
||||
{
|
||||
// Emit a diagnostic if the attribute is unnecessary
|
||||
if (hasOrInheritsClassLevelNotifyRecipients)
|
||||
if (hasOrInheritsClassLevelNotifyPropertyChangedRecipients)
|
||||
{
|
||||
diagnostics.Add(
|
||||
UnnecessaryNotifyRecipientsAttributeOnFieldWarning,
|
||||
UnnecessaryNotifyPropertyChangedRecipientsAttributeOnFieldWarning,
|
||||
fieldSymbol,
|
||||
fieldSymbol.ContainingType,
|
||||
fieldSymbol.Name);
|
||||
@ -489,7 +489,7 @@ private static bool TryGetIsNotifyingRecipients(
|
||||
|
||||
// Otherwise just emit the diagnostic and then ignore the attribute
|
||||
diagnostics.Add(
|
||||
InvalidContainingTypeForNotifyRecipientsFieldError,
|
||||
InvalidContainingTypeForNotifyPropertyChangedRecipientsFieldError,
|
||||
fieldSymbol,
|
||||
fieldSymbol.ContainingType,
|
||||
fieldSymbol.Name);
|
||||
@ -505,7 +505,7 @@ private static bool TryGetIsNotifyingRecipients(
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether a given type using <c>[NotifyRecipients]</c> is valid and creates a <see cref="Diagnostic"/> if not.
|
||||
/// Checks whether a given type using <c>[NotifyPropertyChangedRecipients]</c> is valid and creates a <see cref="Diagnostic"/> if not.
|
||||
/// </summary>
|
||||
/// <param name="typeSymbol">The input <see cref="INamedTypeSymbol"/> instance to process.</param>
|
||||
/// <returns>The <see cref="Diagnostic"/> for <paramref name="typeSymbol"/>, if not a valid type.</returns>
|
||||
@ -516,7 +516,7 @@ private static bool TryGetIsNotifyingRecipients(
|
||||
!typeSymbol.HasOrInheritsAttributeWithFullyQualifiedName("global::CommunityToolkit.Mvvm.ComponentModel.ObservableRecipientAttribute"))
|
||||
{
|
||||
return Diagnostic.Create(
|
||||
InvalidTypeForNotifyRecipientsError,
|
||||
InvalidTypeForNotifyPropertyChangedRecipientsError,
|
||||
typeSymbol.Locations.FirstOrDefault(),
|
||||
typeSymbol);
|
||||
}
|
||||
@ -671,7 +671,7 @@ public static MemberDeclarationSyntax GetPropertySyntax(PropertyInfo propertyInf
|
||||
string name => IdentifierName(name)
|
||||
};
|
||||
|
||||
if (propertyInfo.NotifyRecipients)
|
||||
if (propertyInfo.NotifyPropertyChangedRecipients)
|
||||
{
|
||||
// If broadcasting changes are required, also store the old value.
|
||||
// This code generates a statement as follows:
|
||||
@ -769,7 +769,7 @@ public static MemberDeclarationSyntax GetPropertySyntax(PropertyInfo propertyInf
|
||||
}
|
||||
|
||||
// Also broadcast the change, if requested
|
||||
if (propertyInfo.NotifyRecipients)
|
||||
if (propertyInfo.NotifyPropertyChangedRecipients)
|
||||
{
|
||||
// This code generates a statement as follows:
|
||||
//
|
||||
|
@ -38,13 +38,13 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
|
||||
fieldSymbols
|
||||
.Where(static item => item.HasAttributeWithFullyQualifiedName("global::CommunityToolkit.Mvvm.ComponentModel.ObservablePropertyAttribute"));
|
||||
|
||||
// Get diagnostics for fields using [NotifyPropertyChangedFor], [NotifyCanExecuteChangedFor], [NotifyRecipients] and [NotifyDataErrorInfo], but not [ObservableProperty]
|
||||
// Get diagnostics for fields using [NotifyPropertyChangedFor], [NotifyCanExecuteChangedFor], [NotifyPropertyChangedRecipients] and [NotifyDataErrorInfo], but not [ObservableProperty]
|
||||
IncrementalValuesProvider<Diagnostic> fieldSymbolsWithOrphanedDependentAttributeWithErrors =
|
||||
fieldSymbols
|
||||
.Where(static item =>
|
||||
(item.HasAttributeWithFullyQualifiedName("global::CommunityToolkit.Mvvm.ComponentModel.NotifyPropertyChangedForAttribute") ||
|
||||
item.HasAttributeWithFullyQualifiedName("global::CommunityToolkit.Mvvm.ComponentModel.NotifyCanExecuteChangedForAttribute") ||
|
||||
item.HasAttributeWithFullyQualifiedName("global::CommunityToolkit.Mvvm.ComponentModel.NotifyRecipientsAttribute") ||
|
||||
item.HasAttributeWithFullyQualifiedName("global::CommunityToolkit.Mvvm.ComponentModel.NotifyPropertyChangedRecipientsAttribute") ||
|
||||
item.HasAttributeWithFullyQualifiedName("global::CommunityToolkit.Mvvm.ComponentModel.NotifyDataErrorInfoAttribute")) &&
|
||||
!item.HasAttributeWithFullyQualifiedName("global::CommunityToolkit.Mvvm.ComponentModel.ObservablePropertyAttribute"))
|
||||
.Select(static (item, _) => Execute.GetDiagnosticForFieldWithOrphanedDependentAttributes(item));
|
||||
@ -143,14 +143,14 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
|
||||
static (node, _) => node is ClassDeclarationSyntax { AttributeLists.Count: > 0 },
|
||||
static (context, _) => (INamedTypeSymbol)context.SemanticModel.GetDeclaredSymbol(context.Node)!);
|
||||
|
||||
// Filter only the type symbols with [NotifyRecipients] and create diagnostics for them
|
||||
// Filter only the type symbols with [NotifyPropertyChangedRecipients] and create diagnostics for them
|
||||
IncrementalValuesProvider<Diagnostic> notifyRecipientsErrors =
|
||||
classSymbols
|
||||
.Where(static item => item.HasAttributeWithFullyQualifiedName("global::CommunityToolkit.Mvvm.ComponentModel.NotifyRecipientsAttribute"))
|
||||
.Where(static item => item.HasAttributeWithFullyQualifiedName("global::CommunityToolkit.Mvvm.ComponentModel.NotifyPropertyChangedRecipientsAttribute"))
|
||||
.Select(static (item, _) => Execute.GetIsNotifyingRecipientsDiagnosticForType(item))
|
||||
.Where(static item => item is not null)!;
|
||||
|
||||
// Output the diagnostics for [NotifyRecipients]
|
||||
// Output the diagnostics for [NotifyPropertyChangedRecipients]
|
||||
context.ReportDiagnostics(notifyRecipientsErrors);
|
||||
|
||||
// Filter only the type symbols with [NotifyDataErrorInfo] and create diagnostics for them
|
||||
|
@ -319,17 +319,17 @@ internal static class DiagnosticDescriptors
|
||||
/// <summary>
|
||||
/// Gets a <see cref="DiagnosticDescriptor"/> indicating when <c>[ObservableProperty]</c> is applied to a field in an invalid type.
|
||||
/// <para>
|
||||
/// Format: <c>"The field {0}.{1} needs to be annotated with [ObservableProperty] in order to enable using [NotifyPropertyChangedFor], [NotifyCanExecuteChangedFor], [NotifyRecipients] and [NotifyDataErrorInfo]"</c>.
|
||||
/// Format: <c>"The field {0}.{1} needs to be annotated with [ObservableProperty] in order to enable using [NotifyPropertyChangedFor], [NotifyCanExecuteChangedFor], [NotifyPropertyChangedRecipients] and [NotifyDataErrorInfo]"</c>.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
public static readonly DiagnosticDescriptor FieldWithOrphanedDependentObservablePropertyAttributesError = new DiagnosticDescriptor(
|
||||
id: "MVVMTK0020",
|
||||
title: "Invalid use of attributes dependent on [ObservableProperty]",
|
||||
messageFormat: "The field {0}.{1} needs to be annotated with [ObservableProperty] in order to enable using [NotifyPropertyChangedFor], [NotifyCanExecuteChangedFor], [NotifyRecipients] and [NotifyDataErrorInfo]",
|
||||
messageFormat: "The field {0}.{1} needs to be annotated with [ObservableProperty] in order to enable using [NotifyPropertyChangedFor], [NotifyCanExecuteChangedFor], [NotifyPropertyChangedRecipients] and [NotifyDataErrorInfo]",
|
||||
category: typeof(ObservablePropertyGenerator).FullName,
|
||||
defaultSeverity: DiagnosticSeverity.Error,
|
||||
isEnabledByDefault: true,
|
||||
description: "Fields not annotated with [ObservableProperty] cannot use [NotifyPropertyChangedFor], [NotifyCanExecuteChangedFor], [NotifyRecipients] and [NotifyDataErrorInfo].",
|
||||
description: "Fields not annotated with [ObservableProperty] cannot use [NotifyPropertyChangedFor], [NotifyCanExecuteChangedFor], [NotifyPropertyChangedRecipients] and [NotifyDataErrorInfo].",
|
||||
helpLinkUri: "https://aka.ms/mvvmtoolkit");
|
||||
|
||||
/// <summary>
|
||||
@ -349,19 +349,19 @@ internal static class DiagnosticDescriptors
|
||||
helpLinkUri: "https://aka.ms/mvvmtoolkit");
|
||||
|
||||
/// <summary>
|
||||
/// Gets a <see cref="DiagnosticDescriptor"/> indicating when <c>[NotifyRecipients]</c> is applied to a field in an invalid type.
|
||||
/// Gets a <see cref="DiagnosticDescriptor"/> indicating when <c>[NotifyPropertyChangedRecipients]</c> is applied to a field in an invalid type.
|
||||
/// <para>
|
||||
/// Format: <c>"The field {0}.{1} cannot be annotated with [NotifyRecipients], as its containing type doesn't inherit from ObservableRecipient, nor does it use [ObservableRecipient]"</c>.
|
||||
/// Format: <c>"The field {0}.{1} cannot be annotated with [NotifyPropertyChangedRecipients], as its containing type doesn't inherit from ObservableRecipient, nor does it use [ObservableRecipient]"</c>.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
public static readonly DiagnosticDescriptor InvalidContainingTypeForNotifyRecipientsFieldError = new DiagnosticDescriptor(
|
||||
public static readonly DiagnosticDescriptor InvalidContainingTypeForNotifyPropertyChangedRecipientsFieldError = new DiagnosticDescriptor(
|
||||
id: "MVVMTK0022",
|
||||
title: "Invalid containing type for [ObservableProperty] field",
|
||||
messageFormat: "The field {0}.{1} cannot be annotated with [NotifyRecipients], as its containing type doesn't inherit from ObservableRecipient, nor does it use [ObservableRecipient]",
|
||||
messageFormat: "The field {0}.{1} cannot be annotated with [NotifyPropertyChangedRecipients], as its containing type doesn't inherit from ObservableRecipient, nor does it use [ObservableRecipient]",
|
||||
category: typeof(ObservablePropertyGenerator).FullName,
|
||||
defaultSeverity: DiagnosticSeverity.Error,
|
||||
isEnabledByDefault: true,
|
||||
description: "Fields annotated with [NotifyRecipients] must be contained in a type that inherits from ObservableRecipient or that is annotated with [ObservableRecipient] (including base types).",
|
||||
description: "Fields annotated with [NotifyPropertyChangedRecipients] must be contained in a type that inherits from ObservableRecipient or that is annotated with [ObservableRecipient] (including base types).",
|
||||
helpLinkUri: "https://aka.ms/mvvmtoolkit");
|
||||
|
||||
/// <summary>
|
||||
@ -429,19 +429,19 @@ internal static class DiagnosticDescriptors
|
||||
helpLinkUri: "https://aka.ms/mvvmtoolkit");
|
||||
|
||||
/// <summary>
|
||||
/// Gets a <see cref="DiagnosticDescriptor"/> indicating when <c>[NotifyRecipients]</c> is applied to an invalid type.
|
||||
/// Gets a <see cref="DiagnosticDescriptor"/> indicating when <c>[NotifyPropertyChangedRecipients]</c> is applied to an invalid type.
|
||||
/// <para>
|
||||
/// Format: <c>"The type {0} cannot be annotated with [NotifyRecipients], as it doesn't inherit from ObservableRecipient, nor does it use [ObservableRecipient]"</c>.
|
||||
/// Format: <c>"The type {0} cannot be annotated with [NotifyPropertyChangedRecipients], as it doesn't inherit from ObservableRecipient, nor does it use [ObservableRecipient]"</c>.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
public static readonly DiagnosticDescriptor InvalidTypeForNotifyRecipientsError = new DiagnosticDescriptor(
|
||||
public static readonly DiagnosticDescriptor InvalidTypeForNotifyPropertyChangedRecipientsError = new DiagnosticDescriptor(
|
||||
id: "MVVMTK0027",
|
||||
title: "Invalid type for [NotifyRecipients] attribute",
|
||||
messageFormat: "The type {0} cannot be annotated with [NotifyRecipients], as it doesn't inherit from ObservableRecipient, nor does it use [ObservableRecipient]",
|
||||
title: "Invalid type for [NotifyPropertyChangedRecipients] attribute",
|
||||
messageFormat: "The type {0} cannot be annotated with [NotifyPropertyChangedRecipients], as it doesn't inherit from ObservableRecipient, nor does it use [ObservableRecipient]",
|
||||
category: typeof(ObservablePropertyGenerator).FullName,
|
||||
defaultSeverity: DiagnosticSeverity.Error,
|
||||
isEnabledByDefault: true,
|
||||
description: "Types annotated with [NotifyRecipients] must inherit from ObservableRecipient or be annotated with [ObservableRecipient] (including base types).",
|
||||
description: "Types annotated with [NotifyPropertyChangedRecipients] must inherit from ObservableRecipient or be annotated with [ObservableRecipient] (including base types).",
|
||||
helpLinkUri: "https://aka.ms/mvvmtoolkit");
|
||||
|
||||
/// <summary>
|
||||
@ -461,19 +461,19 @@ internal static class DiagnosticDescriptors
|
||||
helpLinkUri: "https://aka.ms/mvvmtoolkit");
|
||||
|
||||
/// <summary>
|
||||
/// Gets a <see cref="DiagnosticDescriptor"/> indicating when <c>[NotifyRecipients]</c> is applied to a field in a class with <c>[NotifyRecipients]</c> used at the class-level.
|
||||
/// Gets a <see cref="DiagnosticDescriptor"/> indicating when <c>[NotifyPropertyChangedRecipients]</c> is applied to a field in a class with <c>[NotifyPropertyChangedRecipients]</c> used at the class-level.
|
||||
/// <para>
|
||||
/// Format: <c>"The field {0}.{1} is annotated with [NotifyRecipients], but that is not needed since its containing type already uses or inherits [NotifyRecipients] at the class-level"</c>.
|
||||
/// Format: <c>"The field {0}.{1} is annotated with [NotifyPropertyChangedRecipients], but that is not needed since its containing type already uses or inherits [NotifyPropertyChangedRecipients] at the class-level"</c>.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
public static readonly DiagnosticDescriptor UnnecessaryNotifyRecipientsAttributeOnFieldWarning = new DiagnosticDescriptor(
|
||||
public static readonly DiagnosticDescriptor UnnecessaryNotifyPropertyChangedRecipientsAttributeOnFieldWarning = new DiagnosticDescriptor(
|
||||
id: "MVVMTK0029",
|
||||
title: "Unnecessary [NotifyRecipients] field annotation",
|
||||
messageFormat: "The field {0}.{1} is annotated with [NotifyRecipients], but that is not needed since its containing type already uses or inherits [NotifyRecipients] at the class-level",
|
||||
title: "Unnecessary [NotifyPropertyChangedRecipients] field annotation",
|
||||
messageFormat: "The field {0}.{1} is annotated with [NotifyPropertyChangedRecipients], but that is not needed since its containing type already uses or inherits [NotifyPropertyChangedRecipients] at the class-level",
|
||||
category: typeof(ObservablePropertyGenerator).FullName,
|
||||
defaultSeverity: DiagnosticSeverity.Warning,
|
||||
isEnabledByDefault: true,
|
||||
description: "Annotating a field with [NotifyRecipients] is not necessary if the containing type has or inherits [NotifyRecipients] at the class-level.",
|
||||
description: "Annotating a field with [NotifyPropertyChangedRecipients] is not necessary if the containing type has or inherits [NotifyPropertyChangedRecipients] at the class-level.",
|
||||
helpLinkUri: "https://aka.ms/mvvmtoolkit");
|
||||
|
||||
/// <summary>
|
||||
|
@ -17,7 +17,7 @@ namespace CommunityToolkit.Mvvm.ComponentModel;
|
||||
/// partial class MyViewModel : ObservableRecipient
|
||||
/// {
|
||||
/// [ObservableProperty]
|
||||
/// [NotifyRecipients]
|
||||
/// [NotifyPropertyChangedRecipients]
|
||||
/// private string username;
|
||||
/// }
|
||||
/// </code>
|
||||
@ -40,6 +40,6 @@ namespace CommunityToolkit.Mvvm.ComponentModel;
|
||||
/// </para>
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
|
||||
public sealed class NotifyRecipientsAttribute : Attribute
|
||||
public sealed class NotifyPropertyChangedRecipientsAttribute : Attribute
|
||||
{
|
||||
}
|
@ -999,7 +999,7 @@ public partial class MyViewModel
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void FieldWithOrphanedDependentObservablePropertyAttributesError_NotifyRecipients()
|
||||
public void FieldWithOrphanedDependentObservablePropertyAttributesError_NotifyPropertyChangedRecipients()
|
||||
{
|
||||
string source = @"
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
@ -1008,7 +1008,7 @@ namespace MyApp
|
||||
{
|
||||
public partial class MyViewModel
|
||||
{
|
||||
[NotifyRecipients]
|
||||
[NotifyPropertyChangedRecipients]
|
||||
public int number;
|
||||
}
|
||||
}";
|
||||
@ -1031,7 +1031,7 @@ public partial class MyViewModel
|
||||
[NotifyPropertyChangedFor("")]
|
||||
[NotifyCanExecuteChangedFor("")]
|
||||
[NotifyCanExecuteChangedFor("")]
|
||||
[NotifyRecipients]
|
||||
[NotifyPropertyChangedRecipients]
|
||||
public int number;
|
||||
}
|
||||
}";
|
||||
@ -1062,7 +1062,7 @@ public partial class B : A
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void InvalidContainingTypeForNotifyRecipientsFieldError_ObservableObject()
|
||||
public void InvalidContainingTypeForNotifyPropertyChangedRecipientsFieldError_ObservableObject()
|
||||
{
|
||||
string source = @"
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
@ -1072,7 +1072,7 @@ namespace MyApp
|
||||
public partial class MyViewModel : ObservableObject
|
||||
{
|
||||
[ObservableProperty]
|
||||
[NotifyRecipients]
|
||||
[NotifyPropertyChangedRecipients]
|
||||
public int number;
|
||||
}
|
||||
}";
|
||||
@ -1259,14 +1259,14 @@ public partial class SampleViewModel : ObservableValidator
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void InvalidTypeForNotifyRecipientsError()
|
||||
public void InvalidTypeForNotifyPropertyChangedRecipientsError()
|
||||
{
|
||||
string source = @"
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
|
||||
namespace MyApp
|
||||
{
|
||||
[NotifyRecipients]
|
||||
[NotifyPropertyChangedRecipients]
|
||||
public partial class MyViewModel : ObservableObject
|
||||
{
|
||||
[ObservableProperty]
|
||||
@ -1299,18 +1299,18 @@ public partial class SampleViewModel : ObservableObject
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void UnnecessaryNotifyRecipientsWarning_SameType()
|
||||
public void UnnecessaryNotifyPropertyChangedRecipientsWarning_SameType()
|
||||
{
|
||||
string source = @"
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
|
||||
namespace MyApp
|
||||
{
|
||||
[NotifyRecipients]
|
||||
[NotifyPropertyChangedRecipients]
|
||||
public partial class MyViewModel : ObservableRecipient
|
||||
{
|
||||
[ObservableProperty]
|
||||
[NotifyRecipients]
|
||||
[NotifyPropertyChangedRecipients]
|
||||
public int number;
|
||||
}
|
||||
}";
|
||||
@ -1319,14 +1319,14 @@ public partial class MyViewModel : ObservableRecipient
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void UnnecessaryNotifyRecipientsWarning_BaseType()
|
||||
public void UnnecessaryNotifyPropertyChangedRecipientsWarning_BaseType()
|
||||
{
|
||||
string source = @"
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
|
||||
namespace MyApp
|
||||
{
|
||||
[NotifyRecipients]
|
||||
[NotifyPropertyChangedRecipients]
|
||||
public class MyBaseViewModel : ObservableRecipient
|
||||
{
|
||||
}
|
||||
@ -1334,7 +1334,7 @@ public class MyBaseViewModel : ObservableRecipient
|
||||
public partial class MyViewModel : MyBaseViewModel
|
||||
{
|
||||
[ObservableProperty]
|
||||
[NotifyRecipients]
|
||||
[NotifyPropertyChangedRecipients]
|
||||
public int number;
|
||||
}
|
||||
}";
|
||||
|
@ -450,69 +450,69 @@ public void Test_OnPropertyChangingAndChangedPartialMethodWithAdditionalValidati
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Test_NotifyRecipients_WithObservableObject()
|
||||
public void Test_NotifyPropertyChangedRecipients_WithObservableObject()
|
||||
{
|
||||
Test_NotifyRecipients_Test(
|
||||
Test_NotifyPropertyChangedRecipients_Test(
|
||||
factory: static messenger => new BroadcastingViewModel(messenger),
|
||||
setter: static (model, value) => model.Name = value,
|
||||
propertyName: nameof(BroadcastingViewModel.Name));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Test_NotifyRecipients_WithObservableRecipientAttribute()
|
||||
public void Test_NotifyPropertyChangedRecipients_WithObservableRecipientAttribute()
|
||||
{
|
||||
Test_NotifyRecipients_Test(
|
||||
Test_NotifyPropertyChangedRecipients_Test(
|
||||
factory: static messenger => new BroadcastingViewModelWithAttribute(messenger),
|
||||
setter: static (model, value) => model.Name = value,
|
||||
propertyName: nameof(BroadcastingViewModelWithAttribute.Name));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Test_NotifyRecipients_WithInheritedObservableRecipientAttribute()
|
||||
public void Test_NotifyPropertyChangedRecipients_WithInheritedObservableRecipientAttribute()
|
||||
{
|
||||
Test_NotifyRecipients_Test(
|
||||
Test_NotifyPropertyChangedRecipients_Test(
|
||||
factory: static messenger => new BroadcastingViewModelWithInheritedAttribute(messenger),
|
||||
setter: static (model, value) => model.Name2 = value,
|
||||
propertyName: nameof(BroadcastingViewModelWithInheritedAttribute.Name2));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Test_NotifyRecipients_WithObservableObject_WithClassLevelAttribute()
|
||||
public void Test_NotifyPropertyChangedRecipients_WithObservableObject_WithClassLevelAttribute()
|
||||
{
|
||||
Test_NotifyRecipients_Test(
|
||||
Test_NotifyPropertyChangedRecipients_Test(
|
||||
factory: static messenger => new BroadcastingViewModelWithClassLevelAttribute(messenger),
|
||||
setter: static (model, value) => model.Name = value,
|
||||
propertyName: nameof(BroadcastingViewModelWithClassLevelAttribute.Name));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Test_NotifyRecipients_WithObservableRecipientAttribute_WithClassLevelAttribute()
|
||||
public void Test_NotifyPropertyChangedRecipients_WithObservableRecipientAttribute_WithClassLevelAttribute()
|
||||
{
|
||||
Test_NotifyRecipients_Test(
|
||||
Test_NotifyPropertyChangedRecipients_Test(
|
||||
factory: static messenger => new BroadcastingViewModelWithAttributeAndClassLevelAttribute(messenger),
|
||||
setter: static (model, value) => model.Name = value,
|
||||
propertyName: nameof(BroadcastingViewModelWithAttributeAndClassLevelAttribute.Name));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Test_NotifyRecipients_WithInheritedObservableRecipientAttribute_WithClassLevelAttribute()
|
||||
public void Test_NotifyPropertyChangedRecipients_WithInheritedObservableRecipientAttribute_WithClassLevelAttribute()
|
||||
{
|
||||
Test_NotifyRecipients_Test(
|
||||
Test_NotifyPropertyChangedRecipients_Test(
|
||||
factory: static messenger => new BroadcastingViewModelWithInheritedClassLevelAttribute(messenger),
|
||||
setter: static (model, value) => model.Name2 = value,
|
||||
propertyName: nameof(BroadcastingViewModelWithInheritedClassLevelAttribute.Name2));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Test_NotifyRecipients_WithInheritedObservableRecipientAttributeAndClassLevelAttribute()
|
||||
public void Test_NotifyPropertyChangedRecipients_WithInheritedObservableRecipientAttributeAndClassLevelAttribute()
|
||||
{
|
||||
Test_NotifyRecipients_Test(
|
||||
Test_NotifyPropertyChangedRecipients_Test(
|
||||
factory: static messenger => new BroadcastingViewModelWithInheritedAttributeAndClassLevelAttribute(messenger),
|
||||
setter: static (model, value) => model.Name2 = value,
|
||||
propertyName: nameof(BroadcastingViewModelWithInheritedAttributeAndClassLevelAttribute.Name2));
|
||||
}
|
||||
|
||||
private void Test_NotifyRecipients_Test<T>(Func<IMessenger, T> factory, Action<T, string?> setter, string propertyName)
|
||||
private void Test_NotifyPropertyChangedRecipients_Test<T>(Func<IMessenger, T> factory, Action<T, string?> setter, string propertyName)
|
||||
where T : notnull
|
||||
{
|
||||
IMessenger messenger = new StrongReferenceMessenger();
|
||||
@ -554,7 +554,7 @@ public void Test_ObservableProperty_ObservableRecipientDoesNotBroadcastByDefault
|
||||
model.Name = "Alice";
|
||||
model.Name = null;
|
||||
|
||||
// The [NotifyRecipients] attribute wasn't used, so no messages should have been sent
|
||||
// The [NotifyPropertyChangedRecipients] attribute wasn't used, so no messages should have been sent
|
||||
Assert.AreEqual(messages.Count, 0);
|
||||
}
|
||||
|
||||
@ -749,10 +749,10 @@ public void Test_ObservableProperty_ModelWithCultureAwarePropertyName()
|
||||
|
||||
// See https://github.com/CommunityToolkit/dotnet/issues/242
|
||||
[TestMethod]
|
||||
public void Test_ObservableProperty_ModelWithNotifyRecipientsAndDisplayAttributeLast()
|
||||
public void Test_ObservableProperty_ModelWithNotifyPropertyChangedRecipientsAndDisplayAttributeLast()
|
||||
{
|
||||
IMessenger messenger = new StrongReferenceMessenger();
|
||||
ModelWithNotifyRecipientsAndDisplayAttributeLast model = new(messenger);
|
||||
ModelWithNotifyPropertyChangedRecipientsAndDisplayAttributeLast model = new(messenger);
|
||||
|
||||
List<string?> propertyNames = new();
|
||||
|
||||
@ -1199,7 +1199,7 @@ public BroadcastingViewModel(IMessenger messenger)
|
||||
}
|
||||
|
||||
[ObservableProperty]
|
||||
[NotifyRecipients]
|
||||
[NotifyPropertyChangedRecipients]
|
||||
private string? name;
|
||||
}
|
||||
|
||||
@ -1218,7 +1218,7 @@ public RecipientWithNonBroadcastingProperty(IMessenger messenger)
|
||||
partial class BroadcastingViewModelWithAttribute : ObservableObject
|
||||
{
|
||||
[ObservableProperty]
|
||||
[NotifyRecipients]
|
||||
[NotifyPropertyChangedRecipients]
|
||||
private string? name;
|
||||
}
|
||||
|
||||
@ -1230,11 +1230,11 @@ public BroadcastingViewModelWithInheritedAttribute(IMessenger messenger)
|
||||
}
|
||||
|
||||
[ObservableProperty]
|
||||
[NotifyRecipients]
|
||||
[NotifyPropertyChangedRecipients]
|
||||
private string? name2;
|
||||
}
|
||||
|
||||
[NotifyRecipients]
|
||||
[NotifyPropertyChangedRecipients]
|
||||
partial class BroadcastingViewModelWithClassLevelAttribute : ObservableRecipient
|
||||
{
|
||||
public BroadcastingViewModelWithClassLevelAttribute(IMessenger messenger)
|
||||
@ -1258,7 +1258,7 @@ public BroadcastingViewModelWithInheritedClassLevelAttribute(IMessenger messenge
|
||||
}
|
||||
|
||||
[ObservableRecipient]
|
||||
[NotifyRecipients]
|
||||
[NotifyPropertyChangedRecipients]
|
||||
partial class BroadcastingViewModelWithAttributeAndClassLevelAttribute : ObservableObject
|
||||
{
|
||||
[ObservableProperty]
|
||||
@ -1335,10 +1335,10 @@ partial class ModelWithCultureAwarePropertyName
|
||||
}
|
||||
|
||||
[ObservableRecipient]
|
||||
public sealed partial class ModelWithNotifyRecipientsAndDisplayAttributeLast : ObservableValidator
|
||||
public sealed partial class ModelWithNotifyPropertyChangedRecipientsAndDisplayAttributeLast : ObservableValidator
|
||||
{
|
||||
[ObservableProperty]
|
||||
[NotifyRecipients]
|
||||
[NotifyPropertyChangedRecipients]
|
||||
[Display(Name = "Foo bar baz")]
|
||||
private object? _someProperty;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user