mirror of
https://github.com/GeWuYou/GFramework.git
synced 2026-03-22 10:34:30 +08:00
refactor(generator): 重构源代码生成器基础类和诊断功能
- 为 ValidateSymbol 方法添加 Compilation 参数以支持类型解析 - 实现基于 Compilation 的接口类型验证,替代字符串比较方式 - 添加源代码生成器跟踪诊断功能,便于调试生成过程 - 在 AttributeClassGeneratorBase 中增加详细的执行流程跟踪日志 - 更新诊断描述符配置,添加跟踪信息的诊断支持 - 优化 ContextAwareGenerator 中的接口验证逻辑
This commit is contained in:
parent
414e49c413
commit
3262e111f4
@ -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
|
||||||
@ -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));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -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>
|
||||||
/// 生成源代码
|
/// 生成源代码
|
||||||
|
|||||||
@ -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)
|
||||||
|
|||||||
@ -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)
|
||||||
|
|||||||
@ -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>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user