refactor(generator): 重构ContextAwareGenerator实现

- 移除IContextAware接口的继承要求
- 添加partial关键字检查验证
- 更新诊断规则描述和错误消息
- 修改代码生成逻辑以自动实现IContextAware接口
- 调整Analyzer发布文档格式和链接地址
This commit is contained in:
GwWuYou 2026-01-01 10:55:13 +08:00
parent 95add80c6d
commit 42d6590edd
5 changed files with 35 additions and 32 deletions

View File

@ -1,10 +1,10 @@
using GFramework.Core.Abstractions.rule; namespace GFramework.Core.Abstractions.controller;
namespace GFramework.Core.Abstractions.controller;
/// <summary> /// <summary>
/// 控制器接口,定义了控制器需要实现的所有功能契约 /// 控制器接口,定义了控制器的基本契约和行为规范
/// 该接口继承了多个框架核心接口,用于支持控制器的各种能力
/// 包括架构归属、命令发送、系统获取、模型获取、事件注册、查询发送和工具获取等功能
/// </summary> /// </summary>
public interface IController : IContextAware; /// <remarks>
/// 该接口为框架中的控制器组件提供统一的抽象定义,
/// 用于实现控制器的标准功能和生命周期管理
/// </remarks>
public interface IController;

View File

@ -1,3 +1,3 @@
; Shipped analyzer releases ; Shipped analyzer releases
; https://github.com/dotnet/roslyn-analyzers/blob/main/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md ; https://github.com/dotnet/roslyn/blob/main/src/RoslynAnalyzers/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md

View File

@ -1,9 +1,8 @@
; Unshipped analyzer release ; Unshipped analyzer release
; https://github.com/dotnet/roslyn-analyzers/blob/main/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md ; https://github.com/dotnet/roslyn/blob/main/src/RoslynAnalyzers/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md
### New Rules ### New Rules
Rule ID | Category | Severity | Notes Rule ID | Category | Severity | Notes
----------------|----------------------------------|----------|------------------------ -------------|----------------------------------|----------|------------------------
GF_Logging_001 | GFramework.Godot.Logging | Warning | LoggerDiagnostics
GF_Rule_001 | GFramework.SourceGenerators.rule | Error | ContextAwareDiagnostic GF_Rule_001 | GFramework.SourceGenerators.rule | Error | ContextAwareDiagnostic

View File

@ -8,19 +8,12 @@ namespace GFramework.SourceGenerators.diagnostics;
public static class ContextAwareDiagnostic public static class ContextAwareDiagnostic
{ {
/// <summary> /// <summary>
/// 定义类必须实现IContextAware接口的诊断规则 /// 诊断规则ContextAwareAttribute只能应用于类
/// </summary> /// </summary>
/// <remarks> public static readonly DiagnosticDescriptor ContextAwareOnlyForClass = new(
/// 诊断ID: GF_Rule_001
/// 诊断类别: GFramework.SourceGenerators.rule
/// 严重级别: 错误
/// 启用状态: true
/// 消息格式: "Class '{0}' must implement IContextAware"
/// </remarks>
public static readonly DiagnosticDescriptor ClassMustImplementIContextAware = new(
"GF_Rule_001", "GF_Rule_001",
"Class must implement IContextAware", "ContextAware can only be applied to class",
"Class '{0}' must implement IContextAware", "ContextAwareAttribute can only be applied to class '{0}'",
"GFramework.SourceGenerators.rule", "GFramework.SourceGenerators.rule",
DiagnosticSeverity.Error, DiagnosticSeverity.Error,
true true

View File

@ -1,9 +1,11 @@
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using GFramework.SourceGenerators.Common.constants; using GFramework.SourceGenerators.Common.constants;
using GFramework.SourceGenerators.Common.diagnostics;
using GFramework.SourceGenerators.Common.generator; using GFramework.SourceGenerators.Common.generator;
using GFramework.SourceGenerators.diagnostics; using GFramework.SourceGenerators.diagnostics;
using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Syntax;
namespace GFramework.SourceGenerators.rule; namespace GFramework.SourceGenerators.rule;
@ -41,15 +43,21 @@ public sealed class ContextAwareGenerator : MetadataAttributeClassGeneratorBase
INamedTypeSymbol symbol, INamedTypeSymbol symbol,
AttributeData attr) AttributeData attr)
{ {
var iContextAware = compilation.GetTypeByMetadataName( // 1. 必须是 partial
$"{PathContests.CoreAbstractionsNamespace}.rule.IContextAware"); if (!syntax.Modifiers.Any(SyntaxKind.PartialKeyword))
if (iContextAware is null ||
!symbol.AllInterfaces.Any(i =>
SymbolEqualityComparer.Default.Equals(i, iContextAware)))
{ {
context.ReportDiagnostic(Diagnostic.Create( context.ReportDiagnostic(Diagnostic.Create(
ContextAwareDiagnostic.ClassMustImplementIContextAware, CommonDiagnostics.ClassMustBePartial,
syntax.Identifier.GetLocation(),
symbol.Name));
return false;
}
// 2. 必须是 class
if (symbol.TypeKind != TypeKind.Class)
{
context.ReportDiagnostic(Diagnostic.Create(
ContextAwareDiagnostic.ContextAwareOnlyForClass,
syntax.Identifier.GetLocation(), syntax.Identifier.GetLocation(),
symbol.Name)); symbol.Name));
return false; return false;
@ -58,6 +66,7 @@ public sealed class ContextAwareGenerator : MetadataAttributeClassGeneratorBase
return true; return true;
} }
/// <summary> /// <summary>
/// 生成源代码 /// 生成源代码
/// </summary> /// </summary>
@ -90,7 +99,9 @@ public sealed class ContextAwareGenerator : MetadataAttributeClassGeneratorBase
sb.AppendLine(); sb.AppendLine();
} }
sb.AppendLine($"partial class {symbol.Name}"); var interfaceName = iContextAware.ToDisplayString(
SymbolDisplayFormat.FullyQualifiedFormat);
sb.AppendLine($"partial class {symbol.Name} : {interfaceName}");
sb.AppendLine("{"); sb.AppendLine("{");
GenerateContextProperty(sb); GenerateContextProperty(sb);