GFramework/GFramework.SourceGenerators/rule/ContextAwareGenerator.cs
GwWuYou eed07a1a4b refactor(constants): 将路径常量类移动到通用模块并更新引用
- 将 PathContests 类从 GFramework.SourceGenerators.constants 移动到 GFramework.SourceGenerators.Common.constants
- 删除旧的 GFramework.Godot.SourceGenerators.constants.PathContests 文件
- 更新 GodotLoggerGenerator 中的命名空间引用
- 更新 LoggerGenerator 和 ContextAwareGenerator 的常量引用
- 为 PathContests 类添加详细的 XML 文档注释
- 扩展 PathContests 类,添加多个模块的命名空间常量定义
2025-12-28 13:45:37 +08:00

106 lines
3.2 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Linq;
using System.Text;
using GFramework.Core.Abstractions.rule;
using GFramework.SourceGenerators.Abstractions.rule;
using GFramework.SourceGenerators.Common.constants;
using GFramework.SourceGenerators.Common.generator;
using GFramework.SourceGenerators.diagnostics;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
namespace GFramework.SourceGenerators.rule;
[Generator]
public sealed class ContextAwareGenerator : AttributeClassGeneratorBase
{
/// <summary>
/// 使用强类型 Attribute替代字符串
/// </summary>
protected override Type AttributeType => typeof(ContextAwareAttribute);
/// <summary>
/// 仅用于 Syntax 粗筛选
/// </summary>
protected override string AttributeShortNameWithoutSuffix => "ContextAware";
/// <summary>
/// 额外语义校验:必须实现 IContextAware
/// </summary>
protected override bool ValidateSymbol(
SourceProductionContext context,
ClassDeclarationSyntax syntax,
INamedTypeSymbol symbol,
AttributeData attr)
{
if (!symbol.AllInterfaces.Any(i =>
i.ToDisplayString() == typeof(IContextAware).FullName))
{
context.ReportDiagnostic(Diagnostic.Create(
ContextAwareDiagnostic.ClassMustImplementIContextAware,
syntax.Identifier.GetLocation(),
symbol.Name));
return false;
}
return true;
}
/// <summary>
/// 生成源码
/// </summary>
protected override string Generate(
INamedTypeSymbol symbol,
AttributeData attr)
{
var ns = symbol.ContainingNamespace.IsGlobalNamespace
? null
: symbol.ContainingNamespace.ToDisplayString();
var sb = new StringBuilder();
sb.AppendLine("// <auto-generated/>");
sb.AppendLine("#nullable enable");
sb.AppendLine();
if (ns is not null)
{
sb.AppendLine($"namespace {ns};");
sb.AppendLine();
}
sb.AppendLine($"partial class {symbol.Name}");
sb.AppendLine("{");
// 属性
sb.AppendLine(" /// <summary>");
sb.AppendLine(" /// 自动注入的架构上下文");
sb.AppendLine(" /// </summary>");
sb.AppendLine(
$" protected {PathContests.CoreAbstractionsNamespace}.architecture.IArchitectureContext Context {{ get; private set; }} = null!;");
sb.AppendLine();
// 方法
sb.AppendLine(
$" void {PathContests.CoreAbstractionsNamespace}.rule.IContextAware.SetContext(");
sb.AppendLine(
$" {PathContests.CoreAbstractionsNamespace}.architecture.IArchitectureContext context)");
sb.AppendLine(" {");
sb.AppendLine(" Context = context;");
sb.AppendLine(" }");
sb.AppendLine("}");
return sb.ToString().TrimEnd();
}
/// <summary>
/// 自定义生成文件名
/// </summary>
protected override string GetHintName(INamedTypeSymbol symbol)
{
// 包含命名空间和生成器类名路径
return
$"{symbol.Name}.ContextAware.g.cs";
}
}