From 3262e111f440f280f4117a5b45ee9b7849bba07d Mon Sep 17 00:00:00 2001 From: GwWuYou <95328647+GeWuYou@users.noreply.github.com> Date: Sun, 28 Dec 2025 16:17:08 +0800 Subject: [PATCH] =?UTF-8?q?refactor(generator):=20=E9=87=8D=E6=9E=84?= =?UTF-8?q?=E6=BA=90=E4=BB=A3=E7=A0=81=E7=94=9F=E6=88=90=E5=99=A8=E5=9F=BA?= =?UTF-8?q?=E7=A1=80=E7=B1=BB=E5=92=8C=E8=AF=8A=E6=96=AD=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 为 ValidateSymbol 方法添加 Compilation 参数以支持类型解析 - 实现基于 Compilation 的接口类型验证,替代字符串比较方式 - 添加源代码生成器跟踪诊断功能,便于调试生成过程 - 在 AttributeClassGeneratorBase 中增加详细的执行流程跟踪日志 - 更新诊断描述符配置,添加跟踪信息的诊断支持 - 优化 ContextAwareGenerator 中的接口验证逻辑 --- .../AnalyzerReleases.Unshipped.md | 3 +- .../diagnostics/CommonDiagnostics.cs | 33 ++++++++++++++- .../generator/AttributeClassGeneratorBase.cs | 41 ++++++++++++++++--- .../enums/EnumExtensionsGenerator.cs | 2 + .../logging/LoggerGenerator.cs | 1 + .../rule/ContextAwareGenerator.cs | 36 ++++++++++++---- 6 files changed, 100 insertions(+), 16 deletions(-) diff --git a/GFramework.SourceGenerators.Common/AnalyzerReleases.Unshipped.md b/GFramework.SourceGenerators.Common/AnalyzerReleases.Unshipped.md index 7f402e3..84445da 100644 --- a/GFramework.SourceGenerators.Common/AnalyzerReleases.Unshipped.md +++ b/GFramework.SourceGenerators.Common/AnalyzerReleases.Unshipped.md @@ -5,4 +5,5 @@ Rule ID | Category | Severity | Notes ---------------------|-------------------|----------|------------------- - GF_Common_Class_001 | GFramework.Common | Error | CommonDiagnostics \ No newline at end of file + GF_Common_Class_001 | GFramework.Common | Error | CommonDiagnostics + GF_Common_Trace_001 | GFramework.Trace | Info | CommonDiagnostics \ No newline at end of file diff --git a/GFramework.SourceGenerators.Common/diagnostics/CommonDiagnostics.cs b/GFramework.SourceGenerators.Common/diagnostics/CommonDiagnostics.cs index e55ebac..fad409b 100644 --- a/GFramework.SourceGenerators.Common/diagnostics/CommonDiagnostics.cs +++ b/GFramework.SourceGenerators.Common/diagnostics/CommonDiagnostics.cs @@ -24,6 +24,37 @@ public static class CommonDiagnostics "Class '{0}' must be declared partial for code generation", "GFramework.Common", DiagnosticSeverity.Error, - true + isEnabledByDefault: true ); + + /// + /// 定义源代码生成器跟踪信息的诊断描述符 + /// + /// + /// 诊断ID: GF_Common_Trace_001 + /// 诊断消息: "{0}" + /// 分类: GFramework.Trace + /// 严重性: Info + /// 是否启用: true + /// + public static readonly DiagnosticDescriptor GeneratorTrace = + new( + "GF_Common_Trace_001", + "Source generator trace", + "{0}", + "GFramework.Trace", + DiagnosticSeverity.Info, + isEnabledByDefault: true + ); + + /// + /// 源代码生成器跟踪信息 + /// + public static void Trace(SourceProductionContext context, string message) + { + context.ReportDiagnostic(Diagnostic.Create( + GeneratorTrace, + Location.None, + message)); + } } \ No newline at end of file diff --git a/GFramework.SourceGenerators.Common/generator/AttributeClassGeneratorBase.cs b/GFramework.SourceGenerators.Common/generator/AttributeClassGeneratorBase.cs index 28d972f..80efdd8 100644 --- a/GFramework.SourceGenerators.Common/generator/AttributeClassGeneratorBase.cs +++ b/GFramework.SourceGenerators.Common/generator/AttributeClassGeneratorBase.cs @@ -70,22 +70,49 @@ public abstract class AttributeClassGeneratorBase : IIncrementalGenerator ClassDeclarationSyntax classDecl, INamedTypeSymbol symbol) { - var attr = ResolveAttribute(compilation, symbol); - if (attr is null) - return; + // ① 进入 Execute + CommonDiagnostics.Trace(context, $"[GEN] Enter Execute: {symbol.ToDisplayString()}"); + 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)) { + CommonDiagnostics.Trace(context, + $"[GEN] Class is NOT partial: {symbol.Name}"); + ReportClassMustBePartial(context, classDecl, symbol); return; } - if (!ValidateSymbol(context, classDecl, symbol, attr)) + // ④ ValidateSymbol + if (!ValidateSymbol(context, compilation, classDecl, symbol, attr)) + { + CommonDiagnostics.Trace(context, + $"[GEN] ValidateSymbol FAILED: {symbol.ToDisplayString()}"); 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)); } + /// /// 验证符号的有效性 /// @@ -96,9 +123,11 @@ public abstract class AttributeClassGeneratorBase : IIncrementalGenerator /// 验证是否通过 protected virtual bool ValidateSymbol( SourceProductionContext context, + Compilation compilation, ClassDeclarationSyntax syntax, INamedTypeSymbol symbol, - AttributeData attr) => true; + AttributeData attr) + => true; /// /// 生成源代码 diff --git a/GFramework.SourceGenerators/enums/EnumExtensionsGenerator.cs b/GFramework.SourceGenerators/enums/EnumExtensionsGenerator.cs index dea3a3c..62fa564 100644 --- a/GFramework.SourceGenerators/enums/EnumExtensionsGenerator.cs +++ b/GFramework.SourceGenerators/enums/EnumExtensionsGenerator.cs @@ -26,12 +26,14 @@ public sealed class EnumExtensionsGenerator : MetadataAttributeClassGeneratorBas /// 验证符号是否为有效的枚举类型 /// /// 源生产上下文 + /// 编译对象 /// 类声明语法节点 /// 命名类型符号 /// 属性数据 /// 验证是否通过 protected override bool ValidateSymbol( SourceProductionContext context, + Compilation compilation, ClassDeclarationSyntax syntax, INamedTypeSymbol symbol, AttributeData attr) diff --git a/GFramework.SourceGenerators/logging/LoggerGenerator.cs b/GFramework.SourceGenerators/logging/LoggerGenerator.cs index 90064fe..f8c1292 100644 --- a/GFramework.SourceGenerators/logging/LoggerGenerator.cs +++ b/GFramework.SourceGenerators/logging/LoggerGenerator.cs @@ -31,6 +31,7 @@ public sealed class LoggerGenerator : TypeAttributeClassGeneratorBase /// protected override bool ValidateSymbol( SourceProductionContext context, + Compilation compilation, ClassDeclarationSyntax syntax, INamedTypeSymbol symbol, AttributeData attr) diff --git a/GFramework.SourceGenerators/rule/ContextAwareGenerator.cs b/GFramework.SourceGenerators/rule/ContextAwareGenerator.cs index 09efa4b..b8fd5a7 100644 --- a/GFramework.SourceGenerators/rule/ContextAwareGenerator.cs +++ b/GFramework.SourceGenerators/rule/ContextAwareGenerator.cs @@ -1,6 +1,5 @@ using System.Linq; using System.Text; -using GFramework.Core.Abstractions.rule; using GFramework.SourceGenerators.Common.constants; using GFramework.SourceGenerators.Common.generator; using GFramework.SourceGenerators.diagnostics; @@ -31,19 +30,40 @@ public sealed class ContextAwareGenerator : MetadataAttributeClassGeneratorBase /// protected override bool ValidateSymbol( SourceProductionContext context, + Compilation compilation, ClassDeclarationSyntax syntax, INamedTypeSymbol symbol, AttributeData attr) { - if (symbol.AllInterfaces.Any(i => - i.ToDisplayString() == typeof(IContextAware).FullName)) return true; - context.ReportDiagnostic(Diagnostic.Create( - ContextAwareDiagnostic.ClassMustImplementIContextAware, - syntax.Identifier.GetLocation(), - symbol.Name)); - return false; + var iContextAware = compilation + .GetTypeByMetadataName( + $"{PathContests.CoreAbstractionsNamespace}.rule.IContextAware"); + + if (iContextAware is null) + { + 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; } + /// /// 生成源码 ///