@@ -30,32 +30,32 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
3030
3131 context . RegisterSourceOutput ( compilationAndClasses , static ( spc , source ) =>
3232 {
33- var ( compilation , classNodes ) = source ;
33+ var ( compilation , classNodes ) = source ;
3434
35- foreach ( var classNode in classNodes )
36- {
37- var model = compilation . GetSemanticModel ( classNode . SyntaxTree ) ;
38- if ( model . GetDeclaredSymbol ( classNode ) is not INamedTypeSymbol symbol ) continue ;
35+ foreach ( var classNode in classNodes )
36+ {
37+ var model = compilation . GetSemanticModel ( classNode . SyntaxTree ) ;
38+ if ( model . GetDeclaredSymbol ( classNode ) is not INamedTypeSymbol symbol ) continue ;
3939
40- if ( ! symbol . GetAttributes ( ) . Any ( attr => attr . AttributeClass ? . Name == "ViewModelAttribute" ) ) continue ;
40+ if ( ! symbol . GetAttributes ( ) . Any ( attr => attr . AttributeClass ? . Name == "ViewModelAttribute" ) ) continue ;
4141
42- var className = symbol . Name ;
43- var generatedName = $ "{ className } ";
44- var namespaceName = symbol . ContainingNamespace . ToDisplayString ( ) ;
42+ var className = symbol . Name ;
43+ var generatedName = $ "{ className } ";
44+ var namespaceName = symbol . ContainingNamespace . ToDisplayString ( ) ;
4545
46- var bindFields = symbol . GetMembers ( )
47- . OfType < IFieldSymbol > ( )
48- . Where ( f => f . GetAttributes ( ) . Any ( attr => attr . AttributeClass ? . Name == "BindAttribute" ) )
49- . ToList ( ) ;
46+ var bindFields = symbol . GetMembers ( )
47+ . OfType < IFieldSymbol > ( )
48+ . Where ( f => f . GetAttributes ( ) . Any ( attr => attr . AttributeClass ? . Name == "BindAttribute" ) )
49+ . ToList ( ) ;
5050
51- var commandMethods = symbol . GetMembers ( )
52- . OfType < IMethodSymbol > ( )
53- . Where ( m => m . MethodKind == MethodKind . Ordinary &&
54- m . GetAttributes ( ) . Any ( attr => attr . AttributeClass ? . Name == "CommandAttribute" ) )
55- . ToList ( ) ;
51+ var commandMethods = symbol . GetMembers ( )
52+ . OfType < IMethodSymbol > ( )
53+ . Where ( m => m . MethodKind == MethodKind . Ordinary &&
54+ m . GetAttributes ( ) . Any ( attr => attr . AttributeClass ? . Name == "CommandAttribute" ) )
55+ . ToList ( ) ;
5656
57- // Generate ViewModel partial class
58- var viewModelBuilder = new StringBuilder (
57+ // Generate ViewModel partial class
58+ var viewModelBuilder = new StringBuilder (
5959$@ "// <auto-generated />
6060#nullable enable
6161using SimpleViewModel.BaseClasses;
@@ -65,29 +65,39 @@ namespace {namespaceName}
6565 public partial class { className } : BaseViewModel
6666 {{
6767" ) ;
68- foreach ( var field in bindFields )
69- {
70- var fieldType = field . Type . ToDisplayString ( ) ;
71- var fieldName = ToPascal ( field . Name ) ;
68+ foreach ( var field in bindFields )
69+ {
70+ var fieldType = field . Type . ToDisplayString ( ) ;
71+ var fieldName = ToPascal ( field . Name ) ;
7272
73- viewModelBuilder . AppendLine (
73+ viewModelBuilder . AppendLine (
7474$@ " public { fieldType } { fieldName } {{ get => { field . Name } ;
7575 set
7676 {{
7777 SetProperty(ref { field . Name } , value);" ) ;
7878
79- var onChange = GetOnChangeMethodName ( field ) ;
79+ var onChange = GetOnChangeMethodName ( field ) ;
8080 if ( ! string . IsNullOrWhiteSpace ( onChange ) )
8181 viewModelBuilder . AppendLine ( $ " { onChange } ();") ;
82- viewModelBuilder . AppendLine ( " }}" ) ;
83- }
82+ viewModelBuilder . AppendLine ( " }}" ) ;
83+ }
84+ viewModelBuilder . AppendLine ( " }" ) ; // <-- FIX: close property
8485
85- foreach ( var method in commandMethods )
86- {
87- var commandClassName = $ "Command_{ method . Name } ";
88- var commandFieldName = $ "{ ToPascal ( method . Name ) } Command";
89- viewModelBuilder . AppendLine ( $ " private { commandClassName } ? _{ commandFieldName } {{ get; set; }}") ;
90- viewModelBuilder . AppendLine ( $ " public { commandClassName } { commandFieldName } => _{ commandFieldName } ??= new(this);") ;
86+ foreach ( var method in commandMethods )
87+ {
88+ var commandClassName = $ "Command_{ method . Name } ";
89+ var commandFieldName = $ "{ ToPascal ( method . Name ) } Command";
90+ viewModelBuilder . AppendLine ( $ " private { commandClassName } ? _{ commandFieldName } {{ get; set; }}") ;
91+ viewModelBuilder . AppendLine ( $ " public { commandClassName } { commandFieldName } => _{ commandFieldName } ??= new(this);") ;
92+
93+ // Check for AcceptParameter property on CommandAttribute
94+ var acceptParameter = method . GetAttributes ( )
95+ . FirstOrDefault ( attr => attr . AttributeClass ? . Name == "CommandAttribute" ) ?
96+ . NamedArguments . FirstOrDefault ( arg => arg . Key == "AcceptParameter" ) . Value . Value as bool ? ?? false ;
97+
98+ // Check if method has a single parameter
99+ var hasParameter = method . Parameters . Length == 1 ;
100+ var paramType = hasParameter ? method . Parameters [ 0 ] . Type . ToDisplayString ( ) : null ;
91101
92102 // Generate command class per method
93103 var commandBuilder = new StringBuilder (
@@ -108,11 +118,21 @@ public sealed class {commandClassName} : BaseCommand
108118
109119 public override void Execute(object? parameter)
110120 {{
111- vm.{ method . Name } ();
112- }}
113121" ) ;
122+ if ( acceptParameter && hasParameter )
123+ {
124+ // Pass parameter to method
125+ commandBuilder . AppendLine ( $ " vm.{ method . Name } (({ paramType } )parameter!);") ;
126+ }
127+ else
128+ {
129+ // Call parameterless method
130+ commandBuilder . AppendLine ( $ " vm.{ method . Name } ();") ;
131+ }
132+
133+ commandBuilder . AppendLine ( " }" ) ;
114134 var canExecute = GetCanExecuteMethodName ( method ) ;
115- if ( ! string . IsNullOrWhiteSpace ( canExecute ) )
135+ if ( ! string . IsNullOrWhiteSpace ( canExecute ) )
116136 commandBuilder . AppendLine ( $ " public override bool CanExecute(object? parameter) => vm.{ canExecute } ();") ;
117137 commandBuilder . AppendLine ( " }" ) ;
118138 commandBuilder . AppendLine ( "}" ) ;
0 commit comments