refactor(logging): 优化 LoggerGenerator 属性查找逻辑

- 简化 LogAttribute 元数据名称定义
- 移除不必要的注释和步骤编号
- 重构属性筛选逻辑,直接在候选结果中查找匹配属性
- 简化源代码输出注册过程
- 移除冗余的符号合并操作
This commit is contained in:
GwWuYou 2025-12-23 22:54:31 +08:00
parent d4b37345db
commit 1f370dfdc9

View File

@ -14,7 +14,7 @@ namespace GFramework.Generator.generator.logging
public sealed class LoggerGenerator : IIncrementalGenerator public sealed class LoggerGenerator : IIncrementalGenerator
{ {
private const string AttributeMetadataName = private const string AttributeMetadataName =
"GFramework.Generator.Attributes.generator.logging.LogAttribute"; "GFramework.Generator.Attributes.LogAttribute";
/// <summary> /// <summary>
/// 初始化增量生成器 /// 初始化增量生成器
@ -22,12 +22,7 @@ namespace GFramework.Generator.generator.logging
/// <param name="context">增量生成器初始化上下文</param> /// <param name="context">增量生成器初始化上下文</param>
public void Initialize(IncrementalGeneratorInitializationContext context) public void Initialize(IncrementalGeneratorInitializationContext context)
{ {
// 1. 拿到 LogAttribute Symbol // 查找所有类声明语法节点,并获取对应的符号信息
var logAttributeSymbol =
context.CompilationProvider.Select((compilation, _) =>
compilation.GetTypeByMetadataName(AttributeMetadataName));
// 2. 在 SyntaxProvider 阶段就拿到 SemanticModel
var candidates = var candidates =
context.SyntaxProvider.CreateSyntaxProvider( context.SyntaxProvider.CreateSyntaxProvider(
static (node, _) => node is ClassDeclarationSyntax, static (node, _) => node is ClassDeclarationSyntax,
@ -39,44 +34,41 @@ namespace GFramework.Generator.generator.logging
}) })
.Where(x => x.Symbol is not null); .Where(x => x.Symbol is not null);
// 3. 合并 Attribute Symbol 并筛选 // 筛选出带有指定属性标记的类
var targets = var targets =
candidates.Combine(logAttributeSymbol) candidates.Where(x =>
.Where(pair => x.Symbol!.GetAttributes().Any(a =>
{ {
var symbol = pair.Left.Symbol!; var c = a.AttributeClass;
var attrSymbol = pair.Right; if (c is null) return false;
if (attrSymbol is null) return false; return c.ToDisplayString() == AttributeMetadataName
|| c.Name == "LogAttribute";
}));
return symbol.GetAttributes().Any(a => // 注册源代码输出,为符合条件的类生成日志相关的源代码
SymbolEqualityComparer.Default.Equals(a.AttributeClass, attrSymbol));
});
// 4. 输出代码
context.RegisterSourceOutput(targets, (spc, pair) => context.RegisterSourceOutput(targets, (spc, pair) =>
{ {
var classDecl = pair.Left.ClassDecl; var classDecl = pair.ClassDecl;
var classSymbol = pair.Left.Symbol!; var classSymbol = pair.Symbol!;
// 必须是 partial
if (!classDecl.Modifiers.Any(SyntaxKind.PartialKeyword)) if (!classDecl.Modifiers.Any(SyntaxKind.PartialKeyword))
{ {
spc.ReportDiagnostic( spc.ReportDiagnostic(
Diagnostic.Create( Diagnostic.Create(
Diagnostics.MustBePartial, Diagnostics.MustBePartial,
classDecl.Identifier.GetLocation(), classDecl.Identifier.GetLocation(),
classSymbol.Name classSymbol.Name));
));
return; return;
} }
var source = Generate(classSymbol, spc); var source = Generate(classSymbol, spc);
spc.AddSource( spc.AddSource($"{classSymbol.Name}.Logger.g.cs",
$"{classSymbol.Name}.Logger.g.cs",
SourceText.From(source, Encoding.UTF8)); SourceText.From(source, Encoding.UTF8));
}); });
} }
/// <summary> /// <summary>
/// 生成日志字段代码 /// 生成日志字段代码
/// </summary> /// </summary>