mirror of
https://github.com/GeWuYou/GFramework.git
synced 2026-03-25 21:34:28 +08:00
- 新增 Core API 参考文档,涵盖架构与模块、数据模型与系统、命令与查询等核心组件 - 添加事件系统接口详细文档,包括 IEvent、IEventBus、IUnRegister 等接口说明 - 提供完整的 API 使用示例路径、最佳实践与性能建议 - 包含架构图、依赖关系图与故障排查指南 - 添加测试用例参考与扩展方法说明 - [skip ci]
20 KiB
20 KiB
源代码生成器
**本文档引用的文件** - [GFramework.SourceGenerators.csproj](file://GFramework.SourceGenerators/GFramework.SourceGenerators.csproj) - [GFramework.SourceGenerators.Abstractions.csproj](file://GFramework.SourceGenerators.Abstractions/GFramework.SourceGenerators.Abstractions.csproj) - [GFramework.SourceGenerators.Common.csproj](file://GFramework.SourceGenerators.Common/GFramework.SourceGenerators.Common.csproj) - [GFramework.Godot.SourceGenerators.csproj](file://GFramework.Godot.SourceGenerators/GFramework.Godot.SourceGenerators.csproj) - [GFramework.Godot.SourceGenerators.Abstractions.csproj](file://GFramework.Godot.SourceGenerators.Abstractions/GFramework.Godot.SourceGenerators.Abstractions.csproj) - [LoggerGenerator.cs](file://GFramework.SourceGenerators/logging/LoggerGenerator.cs) - [ContextAwareGenerator.cs](file://GFramework.SourceGenerators/rule/ContextAwareGenerator.cs) - [EnumExtensionsGenerator.cs](file://GFramework.SourceGenerators/enums/EnumExtensionsGenerator.cs) - [LogAttribute.cs](file://GFramework.SourceGenerators.Abstractions/logging/LogAttribute.cs) - [ContextAwareAttribute.cs](file://GFramework.SourceGenerators.Abstractions/rule/ContextAwareAttribute.cs) - [GenerateEnumExtensionsAttribute.cs](file://GFramework.SourceGenerators.Abstractions/enums/GenerateEnumExtensionsAttribute.cs) - [AttributeClassGeneratorBase.cs](file://GFramework.SourceGenerators.Common/generator/AttributeClassGeneratorBase.cs) - [AttributeEnumGeneratorBase.cs](file://GFramework.SourceGenerators.Common/generator/AttributeEnumGeneratorBase.cs) - [LoggerDiagnostic.cs](file://GFramework.SourceGenerators/diagnostics/LoggerDiagnostic.cs) - [GodotModuleMarker.cs](file://GFramework.Godot.SourceGenerators.Abstractions/GodotModuleMarker.cs)目录
简介
本文件面向 GFramework 源代码生成器模块,系统化阐述通用与 Godot 特殊场景下的代码生成能力与实现原理。重点覆盖以下主题:
- 通用源代码生成器:LoggerGenerator 的日志字段自动生成、ContextAwareGenerator 的上下文感知接口实现、EnumExtensionsGenerator 的枚举扩展方法生成
- Godot 源代码生成器的特殊功能:GodotModuleMarker 的标记生成与 Godot 特定代码的自动生成
- 抽象层设计:生成器接口定义、通用工具类与诊断系统
- 工作流程:从属性标记到代码生成的完整过程
- 配置选项、使用方法与最佳实践
- 测试策略与验证方法
- 零运行时开销的设计目标
- 故障排除与常见问题
项目结构
GFramework 源代码生成器由多个子项目组成,分为“通用生成器”、“抽象层”、“公共工具”以及“Godot 专用生成器”。各项目职责清晰,遵循“只打包运行期依赖,不打包生成器本体”的原则,确保生成器在编译期工作、零运行时开销。
graph TB
subgraph "通用生成器"
SG["GFramework.SourceGenerators<br/>核心生成器项目"]
Abst["GFramework.SourceGenerators.Abstractions<br/>属性与接口定义"]
Common["GFramework.SourceGenerators.Common<br/>通用生成器基类与工具"]
end
subgraph "Godot 生成器"
GSG["GFramework.Godot.SourceGenerators<br/>Godot 专用生成器项目"]
GSAbst["GFramework.Godot.SourceGenerators.Abstractions<br/>Godot 标记与接口"]
end
subgraph "核心抽象"
CoreAbst["GFramework.Core.Abstractions<br/>核心接口与常量"]
end
SG --> Abst
SG --> Common
SG --> CoreAbst
GSG --> GSAbst
GSG --> Common
GSG -. 使用 .-> CoreAbst
图表来源
- GFramework.SourceGenerators.csproj
- GFramework.SourceGenerators.Abstractions.csproj
- GFramework.SourceGenerators.Common.csproj
- GFramework.Godot.SourceGenerators.csproj
- GFramework.Godot.SourceGenerators.Abstractions.csproj
章节来源
- GFramework.SourceGenerators.csproj
- GFramework.SourceGenerators.Abstractions.csproj
- GFramework.SourceGenerators.Common.csproj
- GFramework.Godot.SourceGenerators.csproj
- GFramework.Godot.SourceGenerators.Abstractions.csproj
核心组件
本节概述三大通用生成器及其职责与交互方式:
- LoggerGenerator:为带 LogAttribute 的类自动生成日志字段
- ContextAwareGenerator:为带 ContextAwareAttribute 的类自动生成 IContextAware 接口实现
- EnumExtensionsGenerator:为带 GenerateEnumExtensionsAttribute 的枚举生成扩展方法
classDiagram
class AttributeClassGeneratorBase {
+Initialize(context)
+ResolveAttribute(compilation, symbol)
+Execute(context, compilation, classDecl, symbol)
+ValidateSymbol(...)
+Generate(...)
+GetHintName(symbol)
+ReportClassMustBePartial(...)
}
class AttributeEnumGeneratorBase {
+Initialize(context)
+ResolveAttribute(compilation, symbol)
+Execute(context, compilation, enumSyntax, symbol)
+ValidateSymbol(...)
+Generate(...)
+GetHintName(symbol)
}
class LoggerGenerator {
+AttributeType
+AttributeShortNameWithoutSuffix
+ValidateSymbol(...)
+Generate(...)
+GetHintName(symbol)
}
class ContextAwareGenerator {
+AttributeMetadataName
+AttributeShortNameWithoutSuffix
+ValidateSymbol(...)
+Generate(...)
+GetHintName(symbol)
-GenerateContextProperty(sb)
-GenerateInterfaceImplementations(sb, interfaceSymbol)
-GenerateMethod(...)
-GenerateMethodBody(...)
}
class EnumExtensionsGenerator {
+AttributeMetadataName
+AttributeShortNameWithoutSuffix
+ResolveAttribute(...)
+ValidateSymbol(...)
+Generate(symbol, attr)
+GetHintName(symbol)
}
AttributeClassGeneratorBase <|-- LoggerGenerator
AttributeClassGeneratorBase <|-- ContextAwareGenerator
AttributeEnumGeneratorBase <|-- EnumExtensionsGenerator
图表来源
- AttributeClassGeneratorBase.cs
- AttributeEnumGeneratorBase.cs
- LoggerGenerator.cs
- ContextAwareGenerator.cs
- EnumExtensionsGenerator.cs
章节来源
- AttributeClassGeneratorBase.cs
- AttributeEnumGeneratorBase.cs
- LoggerGenerator.cs
- ContextAwareGenerator.cs
- EnumExtensionsGenerator.cs
架构总览
生成器采用增量生成器模式,结合语法提供程序与语义模型,对候选节点进行筛选、验证与代码生成。整体流程如下:
sequenceDiagram
participant IDE as "IDE/MSBuild"
participant SP as "语法提供程序"
participant CP as "编译提供程序"
participant GEN as "具体生成器"
participant DIA as "诊断系统"
participant OUT as "源输出"
IDE->>SP : 触发语法提供程序
SP-->>CP : 返回候选节点与语义符号
CP-->>GEN : 传入 Compilation
GEN->>GEN : ResolveAttribute/ValidateSymbol
GEN->>DIA : ReportDiagnostic(可选)
GEN->>OUT : AddSource(生成的源代码)
OUT-->>IDE : 编译期注入生成代码
图表来源
章节来源
详细组件分析
LoggerGenerator(日志字段生成)
- 功能:为标记了 LogAttribute 的类自动生成日志字段,支持命名空间、泛型、静态/实例、访问修饰符等参数化控制
- 关键点:
- 基于 AttributeClassGeneratorBase,通过 ResolveAttribute 解析属性元数据
- 生成代码包含命名空间声明、partial 类、只读日志字段与工厂解析
- 文件提示名形如 “ClassName.Logger.g.cs”
- 生成内容要点(不展示代码,仅说明结构):
- 使用核心抽象命名空间与核心日志接口
- 生成只读日志字段,初始化时通过 LoggerFactoryResolver.Provider.CreateLogger(name)
- 支持 static 与非 static 字段,支持 private/public 等访问修饰符
flowchart TD
Start(["进入 Generate"]) --> NS["解析命名空间与类名"]
NS --> Kind["解析类型种类与泛型约束"]
Kind --> Attr["解析 LogAttribute 参数<br/>名称/字段名/访问修饰符/是否静态"]
Attr --> Build["拼接 using 与 namespace 块"]
Build --> Partial{"类是否为 partial?"}
Partial --> |否| Diag["报告类必须为 partial 的诊断"]
Diag --> End
Partial --> |是| Append["追加 partial 类与字段声明"]
Append --> Hint["设置提示文件名 *.Logger.g.cs"]
Hint --> End(["完成"])
图表来源
章节来源
ContextAwareGenerator(上下文感知接口实现)
- 功能:为标记了 ContextAwareAttribute 的类自动生成 IContextAware 接口实现,包含 Context 属性与显式接口实现
- 关键点:
- 基于 MetadataAttributeClassGeneratorBase,使用元数据名匹配特性
- 强制要求类为 partial class;否则报告诊断
- 生成 Context 属性(懒加载,首次使用时解析第一个架构上下文)
- 遍历 IContextAware 接口方法,生成显式接口实现方法体
- 生成内容要点(不展示代码,仅说明结构):
- 生成 partial class 并显式实现 IContextAware
- 生成 Context 属性与 SetContext/GetContext 的实现
- 其他未支持方法抛出 NotImplementedException(void)
sequenceDiagram
participant GEN as "ContextAwareGenerator"
participant SEM as "语义模型"
participant INT as "IContextAware 接口符号"
participant SB as "StringBuilder"
GEN->>SEM : 查找并解析 ContextAwareAttribute
GEN->>SEM : 获取 IContextAware 符号
GEN->>GEN : ValidateSymbol(必须为 partial class)
GEN->>SB : 生成 partial class 与命名空间
GEN->>SB : 生成 Context 属性(懒加载)
GEN->>SB : 遍历 IContextAware 方法并生成显式实现
GEN-->>OUT : AddSource(生成的源代码)
图表来源
- ContextAwareGenerator.cs
- ContextAwareGenerator.cs
- ContextAwareGenerator.cs
- ContextAwareGenerator.cs
- ContextAwareGenerator.cs
章节来源
EnumExtensionsGenerator(枚举扩展方法生成)
- 功能:为标记了 GenerateEnumExtensionsAttribute 的枚举生成扩展方法,包括 IsX 与 IsIn
- 关键点:
- 基于 AttributeEnumGeneratorBase,针对枚举声明进行筛选与生成
- 仅对枚举类型有效;非枚举类型报告诊断
- 生成 IsX 方法(每个枚举项一个),以及 IsIn(params T[]) 方法
- 文件提示名形如 “EnumName.EnumExtensions.g.cs”
- 生成内容要点(不展示代码,仅说明结构):
- 生成静态 partial 扩展类
- 为每个枚举成员生成 IsX 判断方法
- 生成 IsIn 多值判断方法(空值安全)
flowchart TD
Start(["进入 Generate"]) --> NS["解析命名空间与枚举全名"]
NS --> Members["提取枚举成员(常量值)"]
Members --> Build["拼接 using 与命名空间"]
Build --> Ext["生成静态 partial 扩展类"]
Ext --> IsX["为每个成员生成 IsX 方法"]
IsX --> IsIn["生成 IsIn(params T[]) 方法"]
IsIn --> Hint["设置提示文件名 *.EnumExtensions.g.cs"]
Hint --> End(["完成"])
图表来源
章节来源
Godot 源代码生成器(特殊功能)
- GodotModuleMarker:作为 Godot 模块命名空间的占位类型,用于标记与识别 Godot 相关生成逻辑
- Godot 专用生成器:在 Godot 项目中,结合 Godot 特定接口与约定,自动生成模块标记与相关代码
classDiagram
class GodotModuleMarker {
<<sealed>>
+internal
}
图表来源
章节来源
依赖关系分析
- 通用生成器依赖:
- Abstractions:属性与接口定义(LogAttribute、ContextAwareAttribute、GenerateEnumExtensionsAttribute)
- Common:生成器基类与通用工具(AttributeClassGeneratorBase、AttributeEnumGeneratorBase)
- Core.Abstractions:核心接口与常量(用于生成代码中的类型引用)
- Godot 生成器依赖:
- Godot.Abstractions:Godot 特定标记(如 GodotModuleMarker)
- Common:复用通用生成器基类与工具
- 打包策略:
- 生成器本体仅打包到 analyzers 下,不打包到 lib
- 运行期依赖(Abstractions/Common)打包到 lib,供编译期引用
graph LR
SG["GFramework.SourceGenerators"] --> Abst["Abstractions"]
SG --> Common["Common"]
SG --> CoreAbst["Core.Abstractions"]
GSG["GFramework.Godot.SourceGenerators"] --> GSAbst["Godot.Abstractions"]
GSG --> Common
GSG -. 引用 .-> CoreAbst
Abst -. 定义 .-> SG
Common -. 基类 .-> SG
CoreAbst -. 接口 .-> SG
图表来源
章节来源
性能考量
- 零运行时开销:生成器仅在编译期工作,生成的代码在运行时直接执行,不引入额外运行时依赖
- 增量生成:使用 IIncrementalGenerator 与语法提供程序,仅对受影响的节点进行再生成
- 诊断与早失败:在 ValidateSymbol 阶段尽早报告无效标记或不兼容类型,避免无效生成
- 生成代码最小化:按需生成必要接口实现与字段,不生成冗余代码
故障排除指南
- 类必须为 partial:当类未声明为 partial 时,ContextAwareGenerator 会报告诊断;请将类声明为 partial
- 非枚举类型:EnumExtensionsGenerator 要求标记在枚举上;请确保目标类型为 enum
- LogAttribute 无效:若日志生成未生效,检查类是否为 partial、命名空间是否正确、属性参数是否合法
- 诊断信息:生成器在关键路径输出 Trace 诊断,便于定位问题
章节来源
结论
GFramework 源代码生成器通过清晰的抽象层与通用基类,实现了三类高价值的编译期代码生成:日志字段、上下文感知接口与枚举扩展方法。Godot 专用生成器在此基础上提供了模块标记与特定约定支持。整体设计遵循零运行时开销原则,结合增量生成与严格诊断,确保生成质量与开发体验。
附录
使用方法与配置选项
- LoggerGenerator
- 在类上添加 LogAttribute,可配置 Name、FieldName、AccessModifier、IsStatic 等参数
- 生成结果:partial 类内包含只读日志字段,初始化自 LoggerFactoryResolver
- ContextAwareGenerator
- 在类上添加 ContextAwareAttribute,类必须为 partial class
- 生成结果:显式实现 IContextAware,包含 Context 属性与 SetContext/GetContext
- EnumExtensionsGenerator
- 在枚举上添加 GenerateEnumExtensionsAttribute,可配置是否生成 IsX 与 IsIn 方法
- 生成结果:静态 partial 扩展类,包含 IsX 与 IsIn 扩展方法
章节来源
最佳实践
- 将生成器生成的 partial 类与手写部分分离,避免冲突
- 在 Godot 项目中,优先使用 Godot 专用生成器与标记类型
- 合理使用 IsStatic 与访问修饰符,确保日志字段可见性与性能需求平衡
- 对枚举扩展方法进行统一命名规范,保持 IsX 与 IsIn 的一致性
测试策略与验证方法
- 快照测试:对生成的源代码进行快照比对,确保生成结果稳定
- 单元测试:验证生成器在不同输入组合下的行为与诊断输出
- 集成测试:在真实项目中验证生成代码的编译与运行效果