@@ -24,13 +24,12 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
2424 {
2525 // Get all app service class implementations, and only enable this branch if the target is not a UWP app (the component)
2626 IncrementalValuesProvider < ( HierarchyInfo Hierarchy , AppServiceInfo Info ) > appServiceComponentInfo =
27- context . SyntaxProvider
28- . CreateSyntaxProvider (
27+ context . CreateSyntaxProviderWithOptions (
2928 static ( node , _ ) => node is ClassDeclarationSyntax classDeclaration && classDeclaration . HasOrPotentiallyHasBaseTypes ( ) ,
3029 static ( context , token ) =>
3130 {
3231 // Only retrieve host info if the target is not a UWP application
33- if ( Helpers . IsUwpTarget ( context . SemanticModel . Compilation ) )
32+ if ( Helpers . IsUwpTarget ( context . SemanticModel . Compilation , context . GlobalOptions ) )
3433 {
3534 return default ;
3635 }
@@ -79,15 +78,14 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
7978 } ) ;
8079
8180 // Gather all interfaces, and only enable this branch if the target is a UWP app (the host)
82- IncrementalValuesProvider < ( HierarchyInfo Hierarchy , AppServiceInfo Info ) > appServiceHostInfo =
83- context . SyntaxProvider
84- . ForAttributeWithMetadataName (
81+ IncrementalValuesProvider < ( HierarchyInfo , AppServiceInfo ) > appServiceHostInfo =
82+ context . ForAttributeWithMetadataNameAndOptions (
8583 "CommunityToolkit.AppServices.AppServiceAttribute" ,
8684 static ( node , _ ) => node is InterfaceDeclarationSyntax ,
8785 static ( context , token ) =>
8886 {
8987 // Only retrieve host info if the target is a UWP application
90- if ( ! Helpers . IsUwpTarget ( context . SemanticModel . Compilation ) )
88+ if ( ! Helpers . IsUwpTarget ( context . SemanticModel . Compilation , context . GlobalOptions ) )
9189 {
9290 return default ;
9391 }
@@ -107,6 +105,7 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
107105
108106 token . ThrowIfCancellationRequested ( ) ;
109107
108+ // Gather all methods for the app service type
110109 ImmutableArray < MethodInfo > methods = MethodInfo . From ( typeSymbol , token ) ;
111110
112111 token . ThrowIfCancellationRequested ( ) ;
@@ -115,8 +114,47 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
115114 } )
116115 . Where ( static item => item . Hierarchy is not null ) ;
117116
118- // Produce the host type
119- context . RegisterSourceOutput ( appServiceHostInfo , static ( context , item ) =>
117+ // Also gather all explicitly requested host implementation types
118+ IncrementalValuesProvider < ( HierarchyInfo , AppServiceInfo ) > additionalAppServiceHostInfo =
119+ context . ForAttributeWithMetadataNameAndOptions (
120+ "CommunityToolkit.AppServices.GeneratedAppServiceHostAttribute" ,
121+ static ( node , _ ) => true ,
122+ static ( context , token ) =>
123+ {
124+ // Only retrieve host info if the target is a UWP application
125+ if ( ! Helpers . IsUwpTarget ( context . SemanticModel . Compilation , context . GlobalOptions ) )
126+ {
127+ return default ;
128+ }
129+
130+ // Get the target interface
131+ if ( context . Attributes [ 0 ] . ConstructorArguments is not [ { Kind : TypedConstantKind . Type , Value : INamedTypeSymbol appServiceType } ] )
132+ {
133+ return default ;
134+ }
135+
136+ // Check if the current interface is in fact an app service type
137+ if ( ! appServiceType . TryGetAppServicesNameFromAttribute ( out string ? appServiceName ) )
138+ {
139+ return default ;
140+ }
141+
142+ token . ThrowIfCancellationRequested ( ) ;
143+
144+ HierarchyInfo hierarchy = HierarchyInfo . From ( appServiceType , appServiceType . Name . Substring ( 1 ) ) ;
145+
146+ token . ThrowIfCancellationRequested ( ) ;
147+
148+ ImmutableArray < MethodInfo > methods = MethodInfo . From ( appServiceType , token ) ;
149+
150+ token . ThrowIfCancellationRequested ( ) ;
151+
152+ return ( Hierarchy : hierarchy , new AppServiceInfo ( methods , appServiceName , appServiceType . GetFullyQualifiedName ( ) ) ) ;
153+ } )
154+ . Where ( static item => item . Hierarchy is not null ) ;
155+
156+ // Shared helper to emit all discovered types
157+ static void GenerateAppServiceHostType ( SourceProductionContext context , ( HierarchyInfo Hierarchy , AppServiceInfo Info ) item )
120158 {
121159 ConstructorDeclarationSyntax constructorSyntax = Host . GetConstructorSyntax ( item . Hierarchy , item . Info ) ;
122160 ImmutableArray < MethodDeclarationSyntax > methodDeclarations = Host . GetMethodDeclarationsSyntax ( item . Info ) ;
@@ -128,6 +166,10 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
128166 $ "/// <summary>A generated host implementation for the <see cref=\" { item . Info . InterfaceFullyQualifiedName } \" /> interface.</summary>") ;
129167
130168 context . AddSource ( $ "{ item . Hierarchy . FilenameHint } .g.cs", compilationUnit . GetText ( Encoding . UTF8 ) ) ;
131- } ) ;
169+ }
170+
171+ // Produce the host types
172+ context . RegisterSourceOutput ( appServiceHostInfo , GenerateAppServiceHostType ) ;
173+ context . RegisterSourceOutput ( additionalAppServiceHostInfo , GenerateAppServiceHostType ) ;
132174 }
133175}
0 commit comments