@@ -13,26 +13,31 @@ public class EnumGenerator : IIncrementalGenerator
1313
1414 public void Initialize ( IncrementalGeneratorInitializationContext context )
1515 {
16- context . RegisterPostInitializationOutput ( ctx => ctx . AddSource (
16+ context . RegisterPostInitializationOutput ( static ctx => ctx . AddSource (
1717 "EnumExtensionsAttribute.g.cs" , SourceText . From ( SourceGenerationHelper . Attribute , Encoding . UTF8 ) ) ) ;
1818
19- IncrementalValuesProvider < EnumDeclarationSyntax > enumDeclarations = context . SyntaxProvider
19+ IncrementalValuesProvider < EnumToGenerate ? > enumsToGenerate = context . SyntaxProvider
2020 . CreateSyntaxProvider (
2121 predicate : static ( s , _ ) => IsSyntaxTargetForGeneration ( s ) ,
2222 transform : static ( ctx , _ ) => GetSemanticTargetForGeneration ( ctx ) )
23- . Where ( static m => m is not null ) ! ;
24-
25- IncrementalValueProvider < ( Compilation , ImmutableArray < EnumDeclarationSyntax > ) > compilationAndEnums
26- = context . CompilationProvider . Combine ( enumDeclarations . Collect ( ) ) ;
27-
28- context . RegisterSourceOutput ( compilationAndEnums ,
29- static ( spc , source ) => Execute ( source . Item1 , source . Item2 , spc ) ) ;
23+ . Where ( static m => m is not null ) ;
24+
25+ // If you're targeting the .NET 7 SDK, use this version instead:
26+ // IncrementalValuesProvider<EnumToGenerate?> enumsToGenerate = context.SyntaxProvider
27+ // .ForAttributeWithMetadataName(
28+ // "NetEscapades.EnumGenerators.EnumExtensionsAttribute",
29+ // predicate: static (s, _) => true,
30+ // transform: static (ctx, _) => GetEnumToGenerate(ctx.SemanticModel, ctx.TargetNode))
31+ // .Where(static m => m is not null);
32+
33+ context . RegisterSourceOutput ( enumsToGenerate ,
34+ static ( spc , source ) => Execute ( source , spc ) ) ;
3035 }
3136
3237 static bool IsSyntaxTargetForGeneration ( SyntaxNode node )
3338 => node is EnumDeclarationSyntax m && m . AttributeLists . Count > 0 ;
3439
35- static EnumDeclarationSyntax ? GetSemanticTargetForGeneration ( GeneratorSyntaxContext context )
40+ static EnumToGenerate ? GetSemanticTargetForGeneration ( GeneratorSyntaxContext context )
3641 {
3742 // we know the node is a EnumDeclarationSyntax thanks to IsSyntaxTargetForGeneration
3843 var enumDeclarationSyntax = ( EnumDeclarationSyntax ) context . Node ;
@@ -55,7 +60,7 @@ static bool IsSyntaxTargetForGeneration(SyntaxNode node)
5560 if ( fullName == EnumExtensionsAttribute )
5661 {
5762 // return the enum
58- return enumDeclarationSyntax ;
63+ return GetEnumToGenerate ( context . SemanticModel , enumDeclarationSyntax ) ;
5964 }
6065 }
6166 }
@@ -64,67 +69,36 @@ static bool IsSyntaxTargetForGeneration(SyntaxNode node)
6469 return null ;
6570 }
6671
67- static void Execute ( Compilation compilation , ImmutableArray < EnumDeclarationSyntax > enums , SourceProductionContext context )
72+ static void Execute ( EnumToGenerate ? enumToGenerate , SourceProductionContext context )
6873 {
69- if ( enums . IsDefaultOrEmpty )
70- {
71- // nothing to do yet
72- return ;
73- }
74-
75- // I'm not sure if this is actually necessary, but `[LoggerMessage]` does it, so seems like a good idea!
76- IEnumerable < EnumDeclarationSyntax > distinctEnums = enums . Distinct ( ) ;
77-
78- // Convert each EnumDeclarationSyntax to an EnumToGenerate
79- List < EnumToGenerate > enumsToGenerate = GetTypesToGenerate ( compilation , distinctEnums , context . CancellationToken ) ;
80-
81- // If there were errors in the EnumDeclarationSyntax, we won't create an
82- // EnumToGenerate for it, so make sure we have something to generate
83- if ( enumsToGenerate . Count > 0 )
74+ if ( enumToGenerate is { } value )
8475 {
8576 // generate the source code and add it to the output
86- string result = SourceGenerationHelper . GenerateExtensionClass ( enumsToGenerate ) ;
87- context . AddSource ( "EnumExtensions.g.cs" , SourceText . From ( result , Encoding . UTF8 ) ) ;
77+ string result = SourceGenerationHelper . GenerateExtensionClass ( value ) ;
78+ context . AddSource ( $ "EnumExtensions. { value . Name } .g.cs", SourceText . From ( result , Encoding . UTF8 ) ) ;
8879 }
8980 }
9081
91- static List < EnumToGenerate > GetTypesToGenerate ( Compilation compilation , IEnumerable < EnumDeclarationSyntax > enums , CancellationToken ct )
82+ static EnumToGenerate ? GetEnumToGenerate ( SemanticModel semanticModel , SyntaxNode enumDeclarationSyntax )
9283 {
93- var enumsToGenerate = new List < EnumToGenerate > ( ) ;
94- INamedTypeSymbol ? enumAttribute = compilation . GetTypeByMetadataName ( EnumExtensionsAttribute ) ;
95- if ( enumAttribute == null )
84+ if ( semanticModel . GetDeclaredSymbol ( enumDeclarationSyntax ) is not INamedTypeSymbol enumSymbol )
9685 {
97- // nothing to do if this type isn't available
98- return enumsToGenerate ;
86+ // something went wrong
87+ return null ;
9988 }
10089
101- foreach ( var enumDeclarationSyntax in enums )
102- {
103- // stop if we're asked to
104- ct . ThrowIfCancellationRequested ( ) ;
105-
106- SemanticModel semanticModel = compilation . GetSemanticModel ( enumDeclarationSyntax . SyntaxTree ) ;
107- if ( semanticModel . GetDeclaredSymbol ( enumDeclarationSyntax ) is not INamedTypeSymbol enumSymbol )
108- {
109- // something went wrong
110- continue ;
111- }
112-
113- string enumName = enumSymbol . ToString ( ) ;
114- ImmutableArray < ISymbol > enumMembers = enumSymbol . GetMembers ( ) ;
115- var members = new List < string > ( enumMembers . Length ) ;
90+ string enumName = enumSymbol . ToString ( ) ;
91+ ImmutableArray < ISymbol > enumMembers = enumSymbol . GetMembers ( ) ;
92+ var members = new List < string > ( enumMembers . Length ) ;
11693
117- foreach ( ISymbol member in enumMembers )
94+ foreach ( ISymbol member in enumMembers )
95+ {
96+ if ( member is IFieldSymbol field && field . ConstantValue is not null )
11897 {
119- if ( member is IFieldSymbol field && field . ConstantValue is not null )
120- {
121- members . Add ( member . Name ) ;
122- }
98+ members . Add ( member . Name ) ;
12399 }
124-
125- enumsToGenerate . Add ( new EnumToGenerate ( enumName , members ) ) ;
126100 }
127101
128- return enumsToGenerate ;
102+ return new EnumToGenerate ( enumName , members ) ;
129103 }
130104}
0 commit comments