refactor(generator): 重构源代码生成器基础类和诊断功能

- 为 ValidateSymbol 方法添加 Compilation 参数以支持类型解析
- 实现基于 Compilation 的接口类型验证,替代字符串比较方式
- 添加源代码生成器跟踪诊断功能,便于调试生成过程
- 在 AttributeClassGeneratorBase 中增加详细的执行流程跟踪日志
- 更新诊断描述符配置,添加跟踪信息的诊断支持
- 优化 ContextAwareGenerator 中的接口验证逻辑
This commit is contained in:
GwWuYou 2025-12-28 16:17:08 +08:00
parent 414e49c413
commit 3262e111f4
6 changed files with 100 additions and 16 deletions

View File

@ -5,4 +5,5 @@
Rule ID | Category | Severity | Notes Rule ID | Category | Severity | Notes
---------------------|-------------------|----------|------------------- ---------------------|-------------------|----------|-------------------
GF_Common_Class_001 | GFramework.Common | Error | CommonDiagnostics GF_Common_Class_001 | GFramework.Common | Error | CommonDiagnostics
GF_Common_Trace_001 | GFramework.Trace | Info | CommonDiagnostics

View File

@ -24,6 +24,37 @@ public static class CommonDiagnostics
"Class '{0}' must be declared partial for code generation", "Class '{0}' must be declared partial for code generation",
"GFramework.Common", "GFramework.Common",
DiagnosticSeverity.Error, DiagnosticSeverity.Error,
true isEnabledByDefault: true
); );
/// <summary>
/// 定义源代码生成器跟踪信息的诊断描述符
/// </summary>
/// <remarks>
/// 诊断ID: GF_Common_Trace_001
/// 诊断消息: "{0}"
/// 分类: GFramework.Trace
/// 严重性: Info
/// 是否启用: true
/// </remarks>
public static readonly DiagnosticDescriptor GeneratorTrace =
new(
"GF_Common_Trace_001",
"Source generator trace",
"{0}",
"GFramework.Trace",
DiagnosticSeverity.Info,
isEnabledByDefault: true
);
/// <summary>
/// 源代码生成器跟踪信息
/// </summary>
public static void Trace(SourceProductionContext context, string message)
{
context.ReportDiagnostic(Diagnostic.Create(
GeneratorTrace,
Location.None,
message));
}
} }

View File

@ -70,22 +70,49 @@ public abstract class AttributeClassGeneratorBase : IIncrementalGenerator
ClassDeclarationSyntax classDecl, ClassDeclarationSyntax classDecl,
INamedTypeSymbol symbol) INamedTypeSymbol symbol)
{ {
var attr = ResolveAttribute(compilation, symbol); // ① 进入 Execute
if (attr is null) CommonDiagnostics.Trace(context, $"[GEN] Enter Execute: {symbol.ToDisplayString()}");
return;
var attr = ResolveAttribute(compilation, symbol);
// ② 属性是否解析到
if (attr is null)
{
CommonDiagnostics.Trace(context,
$"[GEN] Attribute NOT resolved on {symbol.ToDisplayString()}");
return;
}
CommonDiagnostics.Trace(context,
$"[GEN] Attribute resolved: {attr.AttributeClass?.ToDisplayString()}");
// ③ partial 校验
if (!classDecl.Modifiers.Any(SyntaxKind.PartialKeyword)) if (!classDecl.Modifiers.Any(SyntaxKind.PartialKeyword))
{ {
CommonDiagnostics.Trace(context,
$"[GEN] Class is NOT partial: {symbol.Name}");
ReportClassMustBePartial(context, classDecl, symbol); ReportClassMustBePartial(context, classDecl, symbol);
return; return;
} }
if (!ValidateSymbol(context, classDecl, symbol, attr)) // ④ ValidateSymbol
if (!ValidateSymbol(context, compilation, classDecl, symbol, attr))
{
CommonDiagnostics.Trace(context,
$"[GEN] ValidateSymbol FAILED: {symbol.ToDisplayString()}");
return; return;
}
context.AddSource(GetHintName(symbol), Generate(symbol, attr)); // ⑤ Generate
var hintName = GetHintName(symbol);
CommonDiagnostics.Trace(context,
$"[GEN] Generating source: {hintName}");
context.AddSource(hintName, Generate(symbol, attr));
} }
/// <summary> /// <summary>
/// 验证符号的有效性 /// 验证符号的有效性
/// </summary> /// </summary>
@ -96,9 +123,11 @@ public abstract class AttributeClassGeneratorBase : IIncrementalGenerator
/// <returns>验证是否通过</returns> /// <returns>验证是否通过</returns>
protected virtual bool ValidateSymbol( protected virtual bool ValidateSymbol(
SourceProductionContext context, SourceProductionContext context,
Compilation compilation,
ClassDeclarationSyntax syntax, ClassDeclarationSyntax syntax,
INamedTypeSymbol symbol, INamedTypeSymbol symbol,
AttributeData attr) => true; AttributeData attr)
=> true;
/// <summary> /// <summary>
/// 生成源代码 /// 生成源代码

View File

@ -26,12 +26,14 @@ public sealed class EnumExtensionsGenerator : MetadataAttributeClassGeneratorBas
/// 验证符号是否为有效的枚举类型 /// 验证符号是否为有效的枚举类型
/// </summary> /// </summary>
/// <param name="context">源生产上下文</param> /// <param name="context">源生产上下文</param>
/// <param name="compilation">编译对象</param>
/// <param name="syntax">类声明语法节点</param> /// <param name="syntax">类声明语法节点</param>
/// <param name="symbol">命名类型符号</param> /// <param name="symbol">命名类型符号</param>
/// <param name="attr">属性数据</param> /// <param name="attr">属性数据</param>
/// <returns>验证是否通过</returns> /// <returns>验证是否通过</returns>
protected override bool ValidateSymbol( protected override bool ValidateSymbol(
SourceProductionContext context, SourceProductionContext context,
Compilation compilation,
ClassDeclarationSyntax syntax, ClassDeclarationSyntax syntax,
INamedTypeSymbol symbol, INamedTypeSymbol symbol,
AttributeData attr) AttributeData attr)

View File

@ -31,6 +31,7 @@ public sealed class LoggerGenerator : TypeAttributeClassGeneratorBase
/// </summary> /// </summary>
protected override bool ValidateSymbol( protected override bool ValidateSymbol(
SourceProductionContext context, SourceProductionContext context,
Compilation compilation,
ClassDeclarationSyntax syntax, ClassDeclarationSyntax syntax,
INamedTypeSymbol symbol, INamedTypeSymbol symbol,
AttributeData attr) AttributeData attr)

View File

@ -1,6 +1,5 @@
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using GFramework.Core.Abstractions.rule;
using GFramework.SourceGenerators.Common.constants; using GFramework.SourceGenerators.Common.constants;
using GFramework.SourceGenerators.Common.generator; using GFramework.SourceGenerators.Common.generator;
using GFramework.SourceGenerators.diagnostics; using GFramework.SourceGenerators.diagnostics;
@ -31,19 +30,40 @@ public sealed class ContextAwareGenerator : MetadataAttributeClassGeneratorBase
/// </summary> /// </summary>
protected override bool ValidateSymbol( protected override bool ValidateSymbol(
SourceProductionContext context, SourceProductionContext context,
Compilation compilation,
ClassDeclarationSyntax syntax, ClassDeclarationSyntax syntax,
INamedTypeSymbol symbol, INamedTypeSymbol symbol,
AttributeData attr) AttributeData attr)
{ {
if (symbol.AllInterfaces.Any(i => var iContextAware = compilation
i.ToDisplayString() == typeof(IContextAware).FullName)) return true; .GetTypeByMetadataName(
context.ReportDiagnostic(Diagnostic.Create( $"{PathContests.CoreAbstractionsNamespace}.rule.IContextAware");
ContextAwareDiagnostic.ClassMustImplementIContextAware,
syntax.Identifier.GetLocation(), if (iContextAware is null)
symbol.Name)); {
return false; context.ReportDiagnostic(Diagnostic.Create(
ContextAwareDiagnostic.ClassMustImplementIContextAware,
syntax.Identifier.GetLocation(),
symbol.Name));
return false;
}
if (!symbol.AllInterfaces.Any(i =>
SymbolEqualityComparer.Default.Equals(i, iContextAware)))
{
context.ReportDiagnostic(Diagnostic.Create(
ContextAwareDiagnostic.ClassMustImplementIContextAware,
syntax.Identifier.GetLocation(),
symbol.Name));
return false;
}
return true;
} }
/// <summary> /// <summary>
/// 生成源码 /// 生成源码
/// </summary> /// </summary>