@@ -26,6 +26,8 @@ protected class BuilderGen : FeatureGenerator
2626 private static readonly IdentifierNameSyntax ToImmutableMethodName = SyntaxFactory . IdentifierName ( "ToImmutable" ) ;
2727 private static readonly IdentifierNameSyntax CreateBuilderMethodName = SyntaxFactory . IdentifierName ( "CreateBuilder" ) ;
2828 private static readonly IdentifierNameSyntax ImmutableFieldName = SyntaxFactory . IdentifierName ( "immutable" ) ;
29+ private static readonly TypeSyntax INotifyPropertyChanged = SyntaxFactory . ParseTypeName ( "System.ComponentModel.INotifyPropertyChanged" ) ;
30+ private static readonly IdentifierNameSyntax OnPropertyChangedMethodName = SyntaxFactory . IdentifierName ( "OnPropertyChanged" ) ;
2931
3032 public BuilderGen ( CodeGen generator )
3133 : base ( generator )
@@ -52,10 +54,13 @@ protected override void GenerateCore()
5254 builderMembers . Add ( this . CreateConstructor ( ) ) ;
5355 builderMembers . AddRange ( this . CreateMutableProperties ( ) ) ;
5456 builderMembers . Add ( this . CreateToImmutableMethod ( ) ) ;
57+ builderMembers . Add ( this . CreatePropertyChangedEvent ( ) ) ;
58+ builderMembers . Add ( this . CreateOnPropertyChangedMethod ( ) ) ;
5559 var builderType = SyntaxFactory . ClassDeclaration ( BuilderTypeName . Identifier )
5660 . AddModifiers (
5761 SyntaxFactory . Token ( SyntaxKind . PublicKeyword ) ,
5862 SyntaxFactory . Token ( SyntaxKind . PartialKeyword ) )
63+ . AddBaseListTypes ( SyntaxFactory . SimpleBaseType ( INotifyPropertyChanged ) )
5964 . WithMembers ( SyntaxFactory . List ( builderMembers ) ) ;
6065 if ( this . generator . applyToMetaType . HasAncestor )
6166 {
@@ -206,7 +211,13 @@ protected IReadOnlyList<MemberDeclarationSyntax> CreateMutableProperties()
206211 SyntaxFactory . ExpressionStatement ( SyntaxFactory . AssignmentExpression (
207212 SyntaxKind . SimpleAssignmentExpression ,
208213 thisField ,
209- SyntaxFactory . IdentifierName ( "value" ) ) ) ) ;
214+ SyntaxFactory . IdentifierName ( "value" ) ) ) ,
215+ SyntaxFactory . ExpressionStatement (
216+ SyntaxFactory . InvocationExpression (
217+ SyntaxFactory . MemberAccessExpression (
218+ SyntaxKind . SimpleMemberAccessExpression ,
219+ SyntaxFactory . ThisExpression ( ) ,
220+ OnPropertyChangedMethodName ) ) ) ) ;
210221
211222 var property = SyntaxFactory . PropertyDeclaration (
212223 this . GetPropertyTypeForBuilder ( field ) ,
@@ -239,6 +250,51 @@ protected NameSyntax GetFieldTypeForBuilder(MetaField field)
239250 : typeBasis ;
240251 }
241252
253+ protected EventFieldDeclarationSyntax CreatePropertyChangedEvent ( )
254+ {
255+ var handler = SyntaxFactory . ParseTypeName ( "System.ComponentModel.PropertyChangedEventHandler" ) ;
256+ return SyntaxFactory . EventFieldDeclaration (
257+ SyntaxFactory . VariableDeclaration ( handler )
258+ . AddVariables ( SyntaxFactory . VariableDeclarator ( nameof ( System . ComponentModel . INotifyPropertyChanged . PropertyChanged ) ) ) )
259+ . WithModifiers ( SyntaxFactory . TokenList ( SyntaxFactory . Token ( SyntaxKind . PublicKeyword ) ) ) ;
260+ }
261+
262+ protected MethodDeclarationSyntax CreateOnPropertyChangedMethod ( )
263+ {
264+ var callerMemberName = SyntaxFactory . ParseName ( "System.Runtime.CompilerServices.CallerMemberNameAttribute" ) ;
265+ var propertyNameParameterName = SyntaxFactory . IdentifierName ( "propertyName" ) ;
266+ var evt = SyntaxFactory . MemberAccessExpression (
267+ SyntaxKind . SimpleMemberAccessExpression ,
268+ SyntaxFactory . ThisExpression ( ) ,
269+ SyntaxFactory . IdentifierName ( nameof ( System . ComponentModel . INotifyPropertyChanged . PropertyChanged ) ) ) ;
270+ var invokeMethod = SyntaxFactory . ConditionalAccessExpression (
271+ evt ,
272+ SyntaxFactory . InvocationExpression (
273+ SyntaxFactory . MemberBindingExpression ( SyntaxFactory . IdentifierName ( nameof ( System . ComponentModel . PropertyChangedEventHandler . Invoke ) ) ) ,
274+ SyntaxFactory . ArgumentList ( ) . AddArguments (
275+ SyntaxFactory . Argument ( SyntaxFactory . ThisExpression ( ) ) ,
276+ SyntaxFactory . Argument (
277+ SyntaxFactory . ObjectCreationExpression (
278+ SyntaxFactory . ParseTypeName ( "System.ComponentModel.PropertyChangedEventArgs" ) ,
279+ SyntaxFactory . ArgumentList ( ) . AddArguments (
280+ SyntaxFactory . Argument ( propertyNameParameterName ) ) ,
281+ null ) ) ) ) ) ;
282+ var body = SyntaxFactory . Block (
283+ SyntaxFactory . ExpressionStatement ( invokeMethod ) ) ;
284+ return SyntaxFactory . MethodDeclaration (
285+ SyntaxFactory . PredefinedType ( SyntaxFactory . Token ( SyntaxKind . VoidKeyword ) ) ,
286+ OnPropertyChangedMethodName . Identifier )
287+ . AddParameterListParameters (
288+ SyntaxFactory . Parameter ( propertyNameParameterName . Identifier )
289+ . WithType ( SyntaxFactory . PredefinedType ( SyntaxFactory . Token ( SyntaxKind . StringKeyword ) ) )
290+ . AddAttributeLists ( SyntaxFactory . AttributeList ( ) . AddAttributes ( SyntaxFactory . Attribute ( callerMemberName ) ) )
291+ . WithDefault ( SyntaxFactory . EqualsValueClause ( SyntaxFactory . LiteralExpression ( SyntaxKind . StringLiteralExpression , SyntaxFactory . Literal ( string . Empty ) ) ) ) )
292+ . AddModifiers (
293+ SyntaxFactory . Token ( SyntaxKind . ProtectedKeyword ) ,
294+ SyntaxFactory . Token ( SyntaxKind . VirtualKeyword ) )
295+ . WithBody ( body ) ;
296+ }
297+
242298 protected MethodDeclarationSyntax CreateToImmutableMethod ( )
243299 {
244300 // var fieldName = this.fieldName.IsDefined ? this.fieldName.Value?.ToImmutable() : this.immutable.FieldName;
0 commit comments