Skip to content

Commit 62f883d

Browse files
committed
Added handling for optional INotifyPropertyChanging in properties
1 parent 263d406 commit 62f883d

File tree

1 file changed

+19
-3
lines changed

1 file changed

+19
-3
lines changed

Microsoft.Toolkit.Mvvm.SourceGenerators/ComponentModel/ObservablePropertyGenerator.cs

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// See the LICENSE file in the project root for more information.
44

55
using System.Collections.Generic;
6+
using System.ComponentModel;
67
using System.Diagnostics.Contracts;
78
using System.Linq;
89
using System.Text;
@@ -62,6 +63,17 @@ private void OnExecute(
6263
INamedTypeSymbol classDeclarationSymbol,
6364
IEnumerable<SyntaxReceiver.Item> items)
6465
{
66+
// Check whether INotifyPropertyChanging is present as well
67+
INamedTypeSymbol
68+
iNotifyPropertyChangingSymbol = context.Compilation.GetTypeByMetadataName(typeof(INotifyPropertyChanging).FullName)!,
69+
observableObjectSymbol = context.Compilation.GetTypeByMetadataName("Microsoft.Toolkit.Mvvm.ComponentModel.ObservableObject")!,
70+
observableObjectAttributeSymbol = context.Compilation.GetTypeByMetadataName(typeof(ObservableObjectAttribute).FullName)!;
71+
72+
bool isNotifyPropertyChanging =
73+
classDeclarationSymbol.AllInterfaces.Contains(iNotifyPropertyChangingSymbol, SymbolEqualityComparer.Default) ||
74+
classDeclarationSymbol.InheritsFrom(observableObjectSymbol) ||
75+
classDeclarationSymbol.GetAttributes().Any(a => SymbolEqualityComparer.Default.Equals(a.AttributeClass, observableObjectAttributeSymbol));
76+
6577
// Create the class declaration for the user type. This will produce a tree as follows:
6678
//
6779
// <MODIFIERS> <CLASS_NAME>
@@ -71,7 +83,7 @@ private void OnExecute(
7183
var classDeclarationSyntax =
7284
ClassDeclaration(classDeclarationSymbol.Name)
7385
.WithModifiers(classDeclaration.Modifiers)
74-
.AddMembers(items.Select(item => CreatePropertyDeclaration(item.LeadingTrivia, item.FieldSymbol)).ToArray());
86+
.AddMembers(items.Select(item => CreatePropertyDeclaration(item.LeadingTrivia, item.FieldSymbol, isNotifyPropertyChanging)).ToArray());
7587

7688
TypeDeclarationSyntax typeDeclarationSyntax = classDeclarationSyntax;
7789

@@ -111,9 +123,10 @@ private void OnExecute(
111123
/// </summary>
112124
/// <param name="leadingTrivia">The leading trivia for the field to process.</param>
113125
/// <param name="fieldSymbol">The input <see cref="IFieldSymbol"/> instance to process.</param>
126+
/// <param name="isNotifyPropertyChanging">Indicates whether or not <see cref="INotifyPropertyChanging"/> is also implemented.</param>
114127
/// <returns>A generated <see cref="PropertyDeclarationSyntax"/> instance for the input field.</returns>
115128
[Pure]
116-
private PropertyDeclarationSyntax CreatePropertyDeclaration(SyntaxTriviaList leadingTrivia, IFieldSymbol fieldSymbol)
129+
private PropertyDeclarationSyntax CreatePropertyDeclaration(SyntaxTriviaList leadingTrivia, IFieldSymbol fieldSymbol, bool isNotifyPropertyChanging)
117130
{
118131
// Get the field type and the target property name
119132
string
@@ -134,7 +147,10 @@ private PropertyDeclarationSyntax CreatePropertyDeclaration(SyntaxTriviaList lea
134147
BlockSyntax setter = Block();
135148

136149
// Add the OnPropertyChanging() call if necessary
137-
setter = setter.AddStatements(ExpressionStatement(InvocationExpression(IdentifierName("OnPropertyChanging"))));
150+
if (isNotifyPropertyChanging)
151+
{
152+
setter = setter.AddStatements(ExpressionStatement(InvocationExpression(IdentifierName("OnPropertyChanging"))));
153+
}
138154

139155
// Add the following statements:
140156
//

0 commit comments

Comments
 (0)