using System; using System.Linq; using System.Text; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Text; namespace GFramework.SourceGenerators.Common.generator; /// /// 基于特性的枚举生成器基类 /// /// 特性类型,必须继承自Attribute public abstract class AttributeEnumGeneratorBase : IIncrementalGenerator where TAttribute : Attribute { /// /// 获取特性的短名称(不包含后缀) /// protected abstract string AttributeShortNameWithoutSuffix { get; } /// /// 初始化增量生成器 /// /// 增量生成器初始化上下文 public void Initialize(IncrementalGeneratorInitializationContext context) { // 查找带有指定特性的枚举声明 var enums = context.SyntaxProvider.CreateSyntaxProvider( (node, _) => node is EnumDeclarationSyntax decl && decl.AttributeLists.SelectMany(a => a.Attributes) .Any(a => a.Name.ToString().Contains(AttributeShortNameWithoutSuffix)), (ctx, _) => { var decl = (EnumDeclarationSyntax)ctx.Node; var symbol = ctx.SemanticModel.GetDeclaredSymbol(decl) as INamedTypeSymbol; return (decl, symbol); }).Where(x => x.symbol != null); // 注册源代码输出 context.RegisterSourceOutput(enums, (spc, pair) => { var attr = pair.symbol!.GetAttributes() .FirstOrDefault(a => a.AttributeClass?.ToDisplayString() == typeof(TAttribute).FullName); if (attr == null) return; var src = Generate(pair.symbol!, attr); spc.AddSource($"{pair.symbol!.Name}.EnumExtensions.g.cs", SourceText.From(src, Encoding.UTF8)); }); } /// /// 生成源代码 /// /// 枚举符号 /// 特性数据 /// 生成的源代码字符串 protected abstract string Generate(INamedTypeSymbol enumSymbol, AttributeData attr); }