GFramework/GFramework.SourceGenerators/rule/ContextAwareGenerator.cs
GwWuYou a191228d85 refactor(source-generators): 重构命名空间引用和代码生成逻辑
- 将硬编码的命名空间路径替换为常量类中的动态引用
- 添加 PathContests 常量类统一管理框架命名空间
- 更新 LoggerGenerator 使用动态命名空间引用
- 重构 ContextAwareGenerator 生成的代码格式和命名空间引用
- 为 ContextAware 生成的属性添加 XML 文档注释
- 简化 ContextAware 生成文件的路径命名规则
- 更新测试代码以匹配新的命名空间引用方式
2025-12-28 12:39:11 +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.generator;
using GFramework.SourceGenerators.constants;
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";
}
}