@@ -30,37 +30,14 @@ public partial class ReactiveCommandGenerator
30
30
private const string Create = ".Create" ;
31
31
private const string CreateO = ".CreateFromObservable" ;
32
32
private const string CreateT = ".CreateFromTask" ;
33
+ private const string ObsoleteReason = "Commands are initialized automatically. Method will be removed in future version." ;
33
34
34
35
/// <summary>
35
36
/// A container for all the logic for <see cref="ReactiveCommandGenerator"/>.
36
37
/// </summary>
37
38
internal static class Execute
38
39
{
39
- internal static MethodDeclarationSyntax GetCommandInitiliser ( CommandInfo [ ] commandExtensionInfos )
40
- {
41
- using var commandInitilisers = ImmutableArrayBuilder < StatementSyntax > . Rent ( ) ;
42
-
43
- // Add the command initializations
44
- foreach ( var commandExtensionInfo in commandExtensionInfos )
45
- {
46
- var commandName = GetGeneratedCommandName ( commandExtensionInfo . MethodName ) ;
47
- var outputType = commandExtensionInfo . GetOutputTypeText ( ) ;
48
- var inputType = commandExtensionInfo . GetInputTypeText ( ) ;
49
- if ( commandExtensionInfo . ArgumentType == null )
50
- {
51
- commandInitilisers . Add ( GenerateBasicCommand ( commandExtensionInfo , commandName ) ) ;
52
- }
53
- else if ( commandExtensionInfo . ArgumentType != null && commandExtensionInfo . IsReturnTypeVoid )
54
- {
55
- commandInitilisers . Add ( GenerateInCommand ( commandExtensionInfo , commandName , inputType ) ) ;
56
- }
57
- else if ( commandExtensionInfo . ArgumentType != null && ! commandExtensionInfo . IsReturnTypeVoid )
58
- {
59
- commandInitilisers . Add ( GenerateInOutCommand ( commandExtensionInfo , commandName , outputType , inputType ) ) ;
60
- }
61
- }
62
-
63
- return MethodDeclaration (
40
+ internal static MethodDeclarationSyntax GetCommandInitiliser ( ) => MethodDeclaration (
64
41
PredefinedType ( Token ( SyntaxKind . VoidKeyword ) ) ,
65
42
Identifier ( "InitializeCommands" ) )
66
43
. AddAttributeLists (
@@ -69,59 +46,45 @@ internal static MethodDeclarationSyntax GetCommandInitiliser(CommandInfo[] comma
69
46
. AddArgumentListArguments (
70
47
AttributeArgument ( LiteralExpression ( SyntaxKind . StringLiteralExpression , Literal ( typeof ( ReactiveGenerator ) . FullName ) ) ) ,
71
48
AttributeArgument ( LiteralExpression ( SyntaxKind . StringLiteralExpression , Literal ( typeof ( ReactiveGenerator ) . Assembly . GetName ( ) . Version . ToString ( ) ) ) ) ) ) ) ,
72
- AttributeList ( SingletonSeparatedList ( Attribute ( IdentifierName ( AttributeDefinitions . ExcludeFromCodeCoverage ) ) ) ) )
49
+ AttributeList ( SingletonSeparatedList ( Attribute ( IdentifierName ( AttributeDefinitions . ExcludeFromCodeCoverage ) ) ) ) ,
50
+ AttributeList ( SingletonSeparatedList ( Attribute ( IdentifierName ( AttributeDefinitions . Obsolete ) )
51
+ . AddArgumentListArguments (
52
+ AttributeArgument ( LiteralExpression ( SyntaxKind . StringLiteralExpression , Literal ( ObsoleteReason ) ) ) ) ) ) )
73
53
. WithModifiers ( TokenList ( Token ( SyntaxKind . ProtectedKeyword ) ) )
74
- . WithBody ( Block ( commandInitilisers . ToImmutable ( ) ) ) ;
54
+ . WithBody ( Block ( ) ) ;
75
55
76
- static StatementSyntax GenerateBasicCommand ( CommandInfo commandExtensionInfo , string commandName )
77
- {
78
- var commandType = commandExtensionInfo . IsObservable ? CreateO : commandExtensionInfo . IsTask ? CreateT : Create ;
79
- if ( string . IsNullOrEmpty ( commandExtensionInfo . CanExecuteObservableName ) )
80
- {
81
- return ParseStatement ( $ "{ commandName } = { RxCmd } { commandType } ({ commandExtensionInfo . MethodName } );") ;
82
- }
56
+ internal static MemberDeclarationSyntax [ ] GetCommandProperty ( CommandInfo commandExtensionInfo )
57
+ {
58
+ var outputType = commandExtensionInfo . GetOutputTypeText ( ) ;
59
+ var inputType = commandExtensionInfo . GetInputTypeText ( ) ;
60
+ var commandName = GetGeneratedCommandName ( commandExtensionInfo . MethodName ) ;
61
+ var fieldName = GetGeneratedFieldName ( commandName ) ;
83
62
84
- return ParseStatement ( $ "{ commandName } = { RxCmd } { commandType } ({ commandExtensionInfo . MethodName } , { commandExtensionInfo . CanExecuteObservableName } { ( commandExtensionInfo . CanExecuteTypeInfo == CanExecuteTypeInfo . MethodObservable ? "()" : string . Empty ) } );") ;
63
+ ExpressionSyntax initializer ;
64
+ if ( commandExtensionInfo . ArgumentType == null )
65
+ {
66
+ initializer = GenerateBasicCommand ( commandExtensionInfo , fieldName ) ;
85
67
}
86
-
87
- static StatementSyntax GenerateInOutCommand ( CommandInfo commandExtensionInfo , string commandName , string outputType , string inputType )
68
+ else if ( commandExtensionInfo . ArgumentType != null && commandExtensionInfo . IsReturnTypeVoid )
88
69
{
89
- var commandType = commandExtensionInfo . IsObservable ? CreateO : commandExtensionInfo . IsTask ? CreateT : Create ;
90
- if ( string . IsNullOrEmpty ( commandExtensionInfo . CanExecuteObservableName ) )
91
- {
92
- return ParseStatement ( $ "{ commandName } = { RxCmd } { commandType } <{ inputType } , { outputType } >({ commandExtensionInfo . MethodName } );") ;
93
- }
94
-
95
- return ParseStatement ( $ "{ commandName } = { RxCmd } { commandType } <{ inputType } , { outputType } >({ commandExtensionInfo . MethodName } , { commandExtensionInfo . CanExecuteObservableName } { ( commandExtensionInfo . CanExecuteTypeInfo == CanExecuteTypeInfo . MethodObservable ? "()" : string . Empty ) } );") ;
70
+ initializer = GenerateInCommand ( commandExtensionInfo , fieldName , inputType ) ;
96
71
}
97
-
98
- static StatementSyntax GenerateInCommand ( CommandInfo commandExtensionInfo , string commandName , string inputType )
72
+ else if ( commandExtensionInfo . ArgumentType != null && ! commandExtensionInfo . IsReturnTypeVoid )
99
73
{
100
- var commandType = commandExtensionInfo . IsTask ? CreateT : Create ;
101
- if ( string . IsNullOrEmpty ( commandExtensionInfo . CanExecuteObservableName ) )
102
- {
103
- return ParseStatement ( $ "{ commandName } = { RxCmd } { commandType } <{ inputType } >({ commandExtensionInfo . MethodName } );") ;
104
- }
105
-
106
- return ParseStatement ( $ "{ commandName } = { RxCmd } { commandType } <{ inputType } >({ commandExtensionInfo . MethodName } , { commandExtensionInfo . CanExecuteObservableName } { ( commandExtensionInfo . CanExecuteTypeInfo == CanExecuteTypeInfo . MethodObservable ? "()" : string . Empty ) } );") ;
74
+ initializer = GenerateInOutCommand ( commandExtensionInfo , fieldName , outputType , inputType ) ;
75
+ }
76
+ else
77
+ {
78
+ return [ ] ;
107
79
}
108
- }
109
-
110
- internal static MemberDeclarationSyntax GetCommandProperty ( CommandInfo commandExtensionInfo )
111
- {
112
- var outputType = commandExtensionInfo . GetOutputTypeText ( ) ;
113
- var inputType = commandExtensionInfo . GetInputTypeText ( ) ;
114
- var commandName = GetGeneratedCommandName ( commandExtensionInfo . MethodName ) ;
115
80
116
81
// Prepare any forwarded property attributes
117
82
var forwardedPropertyAttributes =
118
83
commandExtensionInfo . ForwardedPropertyAttributes
119
84
. Select ( static a => AttributeList ( SingletonSeparatedList ( a . GetSyntax ( ) ) ) )
120
85
. ToImmutableArray ( ) ;
121
86
122
- var commandDeclaration = PropertyDeclaration (
123
- NullableType (
124
- QualifiedName (
87
+ var qualifiedName = QualifiedName (
125
88
IdentifierName ( ReactiveUI ) ,
126
89
GenericName (
127
90
Identifier ( ReactiveCommand ) )
@@ -133,18 +96,63 @@ internal static MemberDeclarationSyntax GetCommandProperty(CommandInfo commandEx
133
96
IdentifierName ( inputType ) ,
134
97
Token ( SyntaxKind . CommaToken ) ,
135
98
IdentifierName ( outputType )
136
- } ) ) ) ) ) ,
99
+ } ) ) ) ) ;
100
+
101
+ var fieldDeclaration = FieldDeclaration (
102
+ VariableDeclaration ( NullableType ( qualifiedName ) ) )
103
+ . AddDeclarationVariables ( VariableDeclarator ( fieldName ) )
104
+ . AddAttributeLists ( AttributeList ( SingletonSeparatedList (
105
+ Attribute ( IdentifierName ( AttributeDefinitions . GeneratedCode ) )
106
+ . AddArgumentListArguments (
107
+ AttributeArgument ( LiteralExpression ( SyntaxKind . StringLiteralExpression , Literal ( typeof ( ReactiveCommandGenerator ) . FullName ) ) ) ,
108
+ AttributeArgument ( LiteralExpression ( SyntaxKind . StringLiteralExpression , Literal ( typeof ( ReactiveCommandGenerator ) . Assembly . GetName ( ) . Version . ToString ( ) ) ) ) ) ) ) )
109
+ . AddModifiers (
110
+ Token ( SyntaxKind . PrivateKeyword ) )
111
+ . NormalizeWhitespace ( ) ;
112
+
113
+ var commandDeclaration = PropertyDeclaration (
114
+ qualifiedName ,
137
115
Identifier ( commandName ) )
138
116
. AddModifiers ( Token ( SyntaxKind . PublicKeyword ) )
139
117
. AddAccessorListAccessors (
140
118
AccessorDeclaration ( SyntaxKind . GetAccessorDeclaration )
141
- . WithSemicolonToken ( Token ( SyntaxKind . SemicolonToken ) ) ,
142
- AccessorDeclaration ( SyntaxKind . SetAccessorDeclaration )
143
- . WithModifiers ( TokenList ( Token ( SyntaxKind . PrivateKeyword ) ) )
144
- . WithSemicolonToken ( Token ( SyntaxKind . SemicolonToken ) ) )
119
+ . WithExpressionBody ( ArrowExpressionClause ( initializer ) ) )
145
120
. AddAttributeLists ( [ .. forwardedPropertyAttributes ] )
146
121
. NormalizeWhitespace ( ) ;
147
- return commandDeclaration ;
122
+ return [ fieldDeclaration , commandDeclaration ] ;
123
+
124
+ static ExpressionSyntax GenerateBasicCommand ( CommandInfo commandExtensionInfo , string fieldName )
125
+ {
126
+ var commandType = commandExtensionInfo . IsObservable ? CreateO : commandExtensionInfo . IsTask ? CreateT : Create ;
127
+ if ( string . IsNullOrEmpty ( commandExtensionInfo . CanExecuteObservableName ) )
128
+ {
129
+ return ParseExpression ( $ "{ fieldName } ??= { RxCmd } { commandType } ({ commandExtensionInfo . MethodName } );") ;
130
+ }
131
+
132
+ return ParseExpression ( $ "{ fieldName } ??= { RxCmd } { commandType } ({ commandExtensionInfo . MethodName } , { commandExtensionInfo . CanExecuteObservableName } { ( commandExtensionInfo . CanExecuteTypeInfo == CanExecuteTypeInfo . MethodObservable ? "()" : string . Empty ) } );") ;
133
+ }
134
+
135
+ static ExpressionSyntax GenerateInOutCommand ( CommandInfo commandExtensionInfo , string fieldName , string outputType , string inputType )
136
+ {
137
+ var commandType = commandExtensionInfo . IsObservable ? CreateO : commandExtensionInfo . IsTask ? CreateT : Create ;
138
+ if ( string . IsNullOrEmpty ( commandExtensionInfo . CanExecuteObservableName ) )
139
+ {
140
+ return ParseExpression ( $ "{ fieldName } ??= { RxCmd } { commandType } <{ inputType } , { outputType } >({ commandExtensionInfo . MethodName } );") ;
141
+ }
142
+
143
+ return ParseExpression ( $ "{ fieldName } ??= { RxCmd } { commandType } <{ inputType } , { outputType } >({ commandExtensionInfo . MethodName } , { commandExtensionInfo . CanExecuteObservableName } { ( commandExtensionInfo . CanExecuteTypeInfo == CanExecuteTypeInfo . MethodObservable ? "()" : string . Empty ) } );") ;
144
+ }
145
+
146
+ static ExpressionSyntax GenerateInCommand ( CommandInfo commandExtensionInfo , string fieldName , string inputType )
147
+ {
148
+ var commandType = commandExtensionInfo . IsTask ? CreateT : Create ;
149
+ if ( string . IsNullOrEmpty ( commandExtensionInfo . CanExecuteObservableName ) )
150
+ {
151
+ return ParseExpression ( $ "{ fieldName } ??= { RxCmd } { commandType } <{ inputType } >({ commandExtensionInfo . MethodName } );") ;
152
+ }
153
+
154
+ return ParseExpression ( $ "{ fieldName } ??= { RxCmd } { commandType } <{ inputType } >({ commandExtensionInfo . MethodName } , { commandExtensionInfo . CanExecuteObservableName } { ( commandExtensionInfo . CanExecuteTypeInfo == CanExecuteTypeInfo . MethodObservable ? "()" : string . Empty ) } );") ;
155
+ }
148
156
}
149
157
150
158
internal static bool IsTaskReturnType ( ITypeSymbol ? typeSymbol )
@@ -458,5 +466,8 @@ internal static string GetGeneratedCommandName(string methodName)
458
466
459
467
return $ "{ char . ToUpper ( commandName [ 0 ] , CultureInfo . InvariantCulture ) } { commandName . Substring ( 1 ) } Command";
460
468
}
469
+
470
+ internal static string GetGeneratedFieldName ( string generatedCommandName ) =>
471
+ $ "_{ char . ToLower ( generatedCommandName [ 0 ] , CultureInfo . InvariantCulture ) } { generatedCommandName . Substring ( 1 ) } ";
461
472
}
462
473
}
0 commit comments