GwWuYou a191228d85 refactor(source-generators): 重构命名空间引用和代码生成逻辑
- 将硬编码的命名空间路径替换为常量类中的动态引用
- 添加 PathContests 常量类统一管理框架命名空间
- 更新 LoggerGenerator 使用动态命名空间引用
- 重构 ContextAwareGenerator 生成的代码格式和命名空间引用
- 为 ContextAware 生成的属性添加 XML 文档注释
- 简化 ContextAware 生成文件的路径命名规则
- 更新测试代码以匹配新的命名空间引用方式
2025-12-28 12:39:11 +08:00

98 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.SourceGenerators.Abstractions.logging;
using GFramework.SourceGenerators.Common.generator;
using GFramework.SourceGenerators.constants;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
namespace GFramework.SourceGenerators.logging;
/// <summary>
/// 日志生成器用于为标记了LogAttribute的类自动生成日志字段
/// </summary>
[Generator]
public sealed class LoggerGenerator : AttributeClassGeneratorBase
{
/// <summary>
/// 强类型 Attribute
/// </summary>
protected override Type AttributeType => typeof(LogAttribute);
/// <summary>
/// 用于语法快速筛选
/// </summary>
protected override string AttributeShortNameWithoutSuffix => "Log";
/// <summary>
/// 对类进行额外语义校验(可选)
/// </summary>
protected override bool ValidateSymbol(
SourceProductionContext context,
ClassDeclarationSyntax syntax,
INamedTypeSymbol symbol,
AttributeData attr)
{
// 可以加自定义规则,比如确保类是 public 或实现某接口
return true;
}
/// <summary>
/// 生成 Logger 字段的代码
/// </summary>
protected override string Generate(INamedTypeSymbol symbol, AttributeData attr)
{
var ns = symbol.ContainingNamespace.IsGlobalNamespace
? null
: symbol.ContainingNamespace.ToDisplayString();
var className = symbol.Name;
// 解析构造函数参数
var name = className;
if (attr.ConstructorArguments.Length > 0)
{
var argValue = attr.ConstructorArguments[0].Value;
name = argValue is string s && !string.IsNullOrWhiteSpace(s)
? s
: className;
}
// 解析命名参数
var fieldName = GetNamedArg(attr, "FieldName")?.ToString() ?? "_log";
var access = GetNamedArg(attr, "AccessModifier")?.ToString() ?? "private";
var isStaticObj = GetNamedArg(attr, "IsStatic");
var isStatic = isStaticObj is not bool b || b; // 默认 true
var staticKeyword = isStatic ? "static " : "";
var sb = new StringBuilder();
sb.AppendLine("// <auto-generated />");
sb.AppendLine($"using {PathContests.CoreAbstractionsNamespace}.logging;");
sb.AppendLine($"using {PathContests.CoreNamespace}.logging;");
if (ns is not null)
{
sb.AppendLine($"namespace {ns};");
sb.AppendLine();
}
sb.AppendLine($"partial class {className}");
sb.AppendLine("{");
sb.AppendLine(" /// <summary>Auto-generated logger</summary>");
sb.AppendLine(
$" {access} {staticKeyword}readonly ILogger {fieldName} = new ConsoleLoggerFactory().GetLogger(\"{name}\");");
sb.AppendLine("}");
return sb.ToString().TrimEnd();
}
/// <summary>
/// 可以自定义生成文件名
/// </summary>
protected override string GetHintName(INamedTypeSymbol symbol)
=> $"{symbol.Name}.Logger.g.cs";
private static object? GetNamedArg(AttributeData attr, string name)
=> attr.NamedArguments.FirstOrDefault(kv => kv.Key == name).Value.Value;
}