11using Microsoft . CodeAnalysis ;
2+ using Microsoft . CodeAnalysis . CSharp . Syntax ;
23using Microsoft . CodeAnalysis . Text ;
34using System ;
45using System . Collections . Generic ;
5- using System . Linq ;
66using System . Text ;
7+ using System . Threading ;
78
89namespace DecoratorGenerator
910{
1011 [ Generator ]
11- public class Main : ISourceGenerator
12+ public class Main : IIncrementalGenerator
1213 {
13- public void Initialize ( GeneratorInitializationContext context ) {
14- // No initialization required for this one
14+ public void Initialize ( IncrementalGeneratorInitializationContext context ) {
15+ var types = context . SyntaxProvider . ForAttributeWithMetadataName (
16+ $ "DecoratorGenerator.{ nameof ( DecorateAttribute ) } ",
17+ predicate : IsSyntaxTargetForGeneration ,
18+ transform : GetSemanticTargetForGeneration
19+ ) ;
20+
21+ context . RegisterSourceOutput ( types , Execute ) ;
1522 }
1623
17- public void Execute ( GeneratorExecutionContext context ) {
18- var types = GetAllDecoratedTypes ( context . Compilation . Assembly . GlobalNamespace ) ;
19-
20- var wrapperSymbolWithoutNamespace = context . Compilation . Assembly . GetTypeByMetadataName ( "WrapperList" ) ;
21- var wrapperListTypes =
22- ( wrapperSymbolWithoutNamespace == null )
23- ? GetAllTypes ( context . Compilation . Assembly . GlobalNamespace , x => x . Name == "WrapperList" )
24- : new [ ] { wrapperSymbolWithoutNamespace } ;
25- var thirdPartyTypes =
26- wrapperListTypes . SelectMany ( x => x . GetMembers ( )
27- . Where ( m => m . Name != ".ctor" )
28- . Select ( m => m as IFieldSymbol )
29- . Select ( f => f . Type )
30- . Select ( t => t as INamedTypeSymbol ) ) ;
31-
32- types = types . Concat ( thirdPartyTypes ) ;
33-
34- var outputs = types . Select ( OutputGenerator . GenerateOutputs ) ;
35-
36- foreach ( var ( source , className ) in outputs ) {
37- // Add the source code to the compilation
38- context . AddSource ( $ "{ className } .generated.cs", SourceText . From ( source , Encoding . UTF8 , SourceHashAlgorithm . Sha256 ) ) ;
39- }
24+ private static bool IsSyntaxTargetForGeneration ( SyntaxNode syntaxNode , CancellationToken token ) {
25+ return syntaxNode is InterfaceDeclarationSyntax ;
4026 }
4127
42- /// <summary>
43- /// Gets all Types inside the namespace matching the predicate including nested namespaces.
44- /// </summary>
45- /// <param name="input"></param>
46- /// <param name="predicate"></param>
47- /// <returns></returns>
48- private IEnumerable < INamedTypeSymbol > GetAllTypes ( INamespaceSymbol input , Func < INamedTypeSymbol , bool > predicate ) {
49- foreach ( var space in input . GetNamespaceMembers ( ) ) {
50- foreach ( var item in space . GetTypeMembers ( ) ) {
51- if ( predicate ( item ) ) {
52- yield return item ;
53- }
54- }
28+ private static INamedTypeSymbol GetSemanticTargetForGeneration ( GeneratorAttributeSyntaxContext context , CancellationToken cancellationToken ) {
29+ var intefaceSyntax = context . TargetNode as InterfaceDeclarationSyntax ;
30+ var symbol = context . SemanticModel . GetDeclaredSymbol ( intefaceSyntax , cancellationToken : cancellationToken ) as INamedTypeSymbol ;
5531
56- foreach ( var nestedItem in GetAllTypes ( space , predicate ) ) {
57- yield return nestedItem ;
58- }
59- }
32+ return symbol ;
6033 }
6134
62- /// <summary>
63- /// Gets all Types in the namespace decorated with the <see cref="DecorateAttribute"/> including nested namespaces.
64- /// </summary>
65- /// <param name="input"></param>
66- /// <returns></returns>
67- private IEnumerable < INamedTypeSymbol > GetAllDecoratedTypes ( INamespaceSymbol input ) {
68- return GetAllTypes ( input , ( x ) => x . GetAttributes ( ) . Any ( att => att . AttributeClass . Name == nameof ( DecorateAttribute ) ) ) ;
35+ private static void Execute ( SourceProductionContext context , INamedTypeSymbol typeSymbol ) {
36+ var ( source , className ) = OutputGenerator . GenerateOutputs ( typeSymbol ) ;
37+
38+ context . AddSource ( $ "{ className } .generated.cs", SourceText . From ( source , Encoding . UTF8 , SourceHashAlgorithm . Sha256 ) ) ;
6939 }
7040 }
7141}
0 commit comments