55using Certify . SourceGenerators ;
66using Microsoft . CodeAnalysis ;
77using Microsoft . CodeAnalysis . Text ;
8+ using Microsoft . CodeAnalysis . CSharp . Syntax ;
9+ using Microsoft . CodeAnalysis . CSharp ;
810
911namespace SourceGenerator
1012{
@@ -16,7 +18,7 @@ public class GeneratedAPI
1618 public string PublicAPIController { get ; set ; } = string . Empty ;
1719
1820 public string PublicAPIRoute { get ; set ; } = string . Empty ;
19- public List < PermissionSpec > RequiredPermissions { get ; set ; } = [ ] ;
21+ public List < PermissionSpec > RequiredPermissions { get ; set ; } = new List < PermissionSpec > ( ) ;
2022 public bool UseManagementAPI { get ; set ; } = false ;
2123 public string ManagementHubCommandType { get ; set ; } = string . Empty ;
2224 public string ServiceAPIRoute { get ; set ; } = string . Empty ;
@@ -34,47 +36,53 @@ public PermissionSpec(string resourceType, string action)
3436 Action = action ;
3537 }
3638 }
39+
3740 [ Generator ]
38- [ System . Diagnostics . CodeAnalysis . SuppressMessage ( "MicrosoftCodeAnalysisCompatibility" , "RS1042:Implementations of this interface are not allowed" , Justification = "Source generator needs ported to incremental generator" ) ]
39- public class PublicAPISourceGenerator : ISourceGenerator
41+ public class PublicAPISourceGenerator : IIncrementalGenerator
4042 {
41- public void Execute ( GeneratorExecutionContext context )
43+ public void Initialize ( IncrementalGeneratorInitializationContext context )
4244 {
45+ var compilationProvider = context . CompilationProvider ;
46+ var apiDefinitions = context . CompilationProvider
47+ . Select ( ( compilation , _ ) => ApiMethods . GetApiDefinitions ( ) ) ;
4348
44- // get list of items we want to generate for our API glue
45- var list = ApiMethods . GetApiDefinitions ( ) ;
46-
47- Debug . WriteLine ( context . Compilation . AssemblyName ) ;
49+ var combined = compilationProvider . Combine ( apiDefinitions ) ;
4850
49- foreach ( var config in list )
51+ context . RegisterSourceOutput ( combined , ( spc , source ) =>
5052 {
51- var paramSet = config . Params . ToList ( ) ;
52- paramSet . Add ( new KeyValuePair < string , string > ( "authContext" , "AuthContext" ) ) ;
53- var apiParamDecl = paramSet . Any ( ) ? string . Join ( ", " , paramSet . Select ( p => $ "{ p . Value } { p . Key } ") ) : "" ;
54- var apiParamDeclWithoutAuthContext = config . Params . Any ( ) ? string . Join ( ", " , config . Params . Select ( p => $ "{ p . Value } { p . Key } ") ) : "" ;
53+ var compilation = source . Left ;
54+ var list = source . Right ;
55+ var assemblyName = compilation . AssemblyName ;
5556
56- var apiParamCall = paramSet . Any ( ) ? string . Join ( ", " , paramSet . Select ( p => $ "{ p . Key } ") ) : "" ;
57- var apiParamCallWithoutAuthContext = config . Params . Any ( ) ? string . Join ( ", " , config . Params . Select ( p => $ "{ p . Key } ") ) : "" ;
58-
59- if ( context . Compilation . AssemblyName . EndsWith ( "Hub.Api" ) && config . PublicAPIController != null )
57+ foreach ( var config in list )
6058 {
61- ImplementPublicAPI ( context , config , apiParamDeclWithoutAuthContext , apiParamDecl , apiParamCall ) ;
59+ var paramSet = config . Params . ToList ( ) ;
60+ paramSet . Add ( new KeyValuePair < string , string > ( "authContext" , "AuthContext" ) ) ;
61+ var apiParamDecl = paramSet . Any ( ) ? string . Join ( ", " , paramSet . Select ( p => $ "{ p . Value } { p . Key } ") ) : "" ;
62+ var apiParamDeclWithoutAuthContext = config . Params . Any ( ) ? string . Join ( ", " , config . Params . Select ( p => $ "{ p . Value } { p . Key } ") ) : "" ;
63+
64+ var apiParamCall = paramSet . Any ( ) ? string . Join ( ", " , paramSet . Select ( p => $ "{ p . Key } ") ) : "" ;
65+ var apiParamCallWithoutAuthContext = config . Params . Any ( ) ? string . Join ( ", " , config . Params . Select ( p => $ "{ p . Key } ") ) : "" ;
66+
67+ if ( assemblyName . EndsWith ( "Hub.Api" ) && config . PublicAPIController != null )
68+ {
69+ ImplementPublicAPI ( spc , config , apiParamDeclWithoutAuthContext , apiParamDecl , apiParamCall ) ;
70+ }
71+
72+ if ( assemblyName . EndsWith ( "Certify.UI.Blazor" ) )
73+ {
74+ ImplementAppModel ( spc , config , apiParamDeclWithoutAuthContext , apiParamCallWithoutAuthContext ) ;
75+ }
76+
77+ if ( assemblyName . EndsWith ( "Certify.Client" ) && ! config . UseManagementAPI )
78+ {
79+ ImplementInternalAPIClient ( spc , config , apiParamDecl , apiParamCall ) ;
80+ }
6281 }
63-
64- if ( context . Compilation . AssemblyName . EndsWith ( "Certify.UI.Blazor" ) )
65- {
66- ImplementAppModel ( context , config , apiParamDeclWithoutAuthContext , apiParamCallWithoutAuthContext ) ;
67- }
68-
69- if ( context . Compilation . AssemblyName . EndsWith ( "Certify.Client" ) && ! config . UseManagementAPI )
70- {
71- // for methods which directly call the backend service (e.g. main server settings), implement the client API
72- ImplementInternalAPIClient ( context , config , apiParamDecl , apiParamCall ) ;
73- }
74- }
82+ } ) ;
7583 }
7684
77- private static void ImplementAppModel ( GeneratorExecutionContext context , GeneratedAPI config , string apiParamDeclWithoutAuthContext , string apiParamCallWithoutAuthContext )
85+ private static void ImplementAppModel ( SourceProductionContext context , GeneratedAPI config , string apiParamDeclWithoutAuthContext , string apiParamCallWithoutAuthContext )
7886 {
7987 context . AddSource ( $ "AppModel.{ config . OperationName } .g.cs", SourceText . From ( $@ "
8088 using System.Collections.Generic;
@@ -83,20 +91,20 @@ private static void ImplementAppModel(GeneratorExecutionContext context, Generat
8391 using Certify.Models.Providers;
8492 using Certify.Models.Hub;
8593
86- namespace Certify.UI.Client.Core
94+ namespace Certify.UI.Client.Core
95+ {{
96+ public partial class AppModel
8797 {{
88- public partial class AppModel
98+ public async Task< { config . ReturnType } > { config . OperationName } ( { apiParamDeclWithoutAuthContext } )
8999 {{
90- public async Task<{ config . ReturnType } > { config . OperationName } ({ apiParamDeclWithoutAuthContext } )
91- {{
92- return await _api.{ config . OperationName } Async({ apiParamCallWithoutAuthContext } );
93- }}
100+ return await _api.{ config . OperationName } Async({ apiParamCallWithoutAuthContext } );
94101 }}
95102 }}
103+ }}
96104 " , Encoding . UTF8 ) ) ;
97105 }
98106
99- private static void ImplementPublicAPI ( GeneratorExecutionContext context , GeneratedAPI config , string apiParamDeclWithoutAuthContext , string apiParamDecl , string apiParamCall )
107+ private static void ImplementPublicAPI ( SourceProductionContext context , GeneratedAPI config , string apiParamDeclWithoutAuthContext , string apiParamDecl , string apiParamCall )
100108 {
101109 var publicApiSrc = $@ "
102110
@@ -112,7 +120,6 @@ private static void ImplementPublicAPI(GeneratorExecutionContext context, Genera
112120 using Certify.Models;
113121 using Certify.Models.Hub;
114122
115-
116123 namespace Certify.Server.Hub.Api.Controllers
117124 {{
118125 public partial class { config . PublicAPIController } Controller
@@ -134,8 +141,7 @@ public partial class {config.PublicAPIController}Controller
134141 return new OkObjectResult(result);
135142 }}
136143 }}
137- }};
138- " ;
144+ }}" ;
139145
140146 if ( config . RequiredPermissions . Any ( ) )
141147 {
@@ -145,9 +151,7 @@ public partial class {config.PublicAPIController}Controller
145151 fragment += $@ "
146152 if (!await IsAuthorized(_client, ""{ perm . ResourceType } "" , ""{ perm . Action } ""))
147153 {{
148- {{
149- return Unauthorized();
150- }}
154+ return Unauthorized();
151155 }}
152156 " ;
153157 }
@@ -161,8 +165,6 @@ public partial class {config.PublicAPIController}Controller
161165
162166 context . AddSource ( $ "{ config . PublicAPIController } Controller.{ config . OperationName } .g.cs", SourceText . From ( publicApiSrc , Encoding . UTF8 ) ) ;
163167
164- // Management API service
165-
166168 if ( ! string . IsNullOrEmpty ( config . ManagementHubCommandType ) )
167169 {
168170 var src = $@ "
@@ -192,13 +194,12 @@ public partial class ManagementAPI
192194 return await PerformInstanceCommandTaskWithResult<{ config . ReturnType } >(instanceId, args, ""{ config . ManagementHubCommandType } "") ?? [];
193195 }}
194196 }}
195- }}
196- " ;
197+ }}" ;
197198 context . AddSource ( $ "ManagementAPI.{ config . OperationName } .g.cs", SourceText . From ( src , Encoding . UTF8 ) ) ;
198199 }
199200 }
200201
201- private static void ImplementInternalAPIClient ( GeneratorExecutionContext context , GeneratedAPI config , string apiParamDecl , string apiParamCall )
202+ private static void ImplementInternalAPIClient ( SourceProductionContext context , GeneratedAPI config , string apiParamDecl , string apiParamCall )
202203 {
203204 var template = @"
204205 using Certify.Models;
@@ -211,8 +212,7 @@ private static void ImplementInternalAPIClient(GeneratorExecutionContext context
211212 namespace Certify.Client
212213 {
213214 MethodTemplate
214- }
215- " ;
215+ }" ;
216216
217217 if ( config . OperationMethod == "HttpGet" )
218218 {
@@ -225,7 +225,6 @@ public partial interface ICertifyInternalApiClient
225225 /// </summary>
226226 /// <returns></returns>
227227 Task<{ config . ReturnType } > { config . OperationName } ({ apiParamDecl } );
228-
229228 }}
230229
231230 public partial class CertifyApiClient
@@ -239,9 +238,7 @@ public partial class CertifyApiClient
239238 var result = await FetchAsync($""{ config . ServiceAPIRoute } "", authContext);
240239 return JsonToObject<{ config . ReturnType } >(result);
241240 }}
242-
243- }}
244- " ) ;
241+ }}" ) ;
245242 var source = SourceText . From ( code , Encoding . UTF8 ) ;
246243 context . AddSource ( $ "{ config . PublicAPIController } .{ config . OperationName } .ICertifyInternalApiClient.g.cs", source ) ;
247244 }
@@ -267,7 +264,6 @@ public partial interface ICertifyInternalApiClient
267264 /// </summary>
268265 /// <returns></returns>
269266 Task<{ config . ReturnType } > { config . OperationName } ({ postApiParamDecl } );
270-
271267 }}
272268
273269 public partial class CertifyApiClient
@@ -281,8 +277,7 @@ public partial class CertifyApiClient
281277 var result = await PostAsync($""{ postAPIRoute } "", { postApiCall } );
282278 return JsonToObject<{ config . ReturnType } >(await result.Content.ReadAsStringAsync());
283279 }}
284- }}
285- " ) , Encoding . UTF8 ) ) ;
280+ }}" ) , Encoding . UTF8 ) ) ;
286281 }
287282
288283 if ( config . OperationMethod == "HttpDelete" )
@@ -306,25 +301,12 @@ public partial class CertifyApiClient
306301 /// <returns></returns>
307302 public async Task<{ config . ReturnType } > { config . OperationName } ({ apiParamDecl } )
308303 {{
309- var route = $""{ config . ServiceAPIRoute } "";
304+ var route = $""{ config . ServiceAPIRoute } "";
310305 var result = await DeleteAsync(route, authContext);
311306 return JsonToObject<{ config . ReturnType } >(await result.Content.ReadAsStringAsync());
312307 }}
313- }}
314- " ) , Encoding . UTF8 ) ) ;
315- }
316- }
317-
318- public void Initialize ( GeneratorInitializationContext context )
319- {
320- #if DEBUG
321- // uncomment this to launch a debug session which code generation runs
322- // then add a watch on
323- if ( ! Debugger . IsAttached )
324- {
325- // Debugger.Launch();
308+ }}" ) , Encoding . UTF8 ) ) ;
326309 }
327- #endif
328310 }
329311 }
330312}
0 commit comments