mirror of
https://github.com/GeWuYou/GFramework.git
synced 2026-03-23 03:04:29 +08:00
- 将 AttributeClassGeneratorBase 抽象基类拆分为 MetadataAttributeClassGeneratorBase 和 TypeAttributeClassGeneratorBase - 为 GodotLoggerGenerator 实现 TypeAttributeClassGeneratorBase 基类 - 为 EnumExtensionsGenerator 实现 MetadataAttributeClassGeneratorBase 基类 - 为 LoggerGenerator 实现 TypeAttributeClassGeneratorBase 基类 - 为 ContextAwareGenerator 实现 MetadataAttributeClassGeneratorBase 基类 - 添加 ContextAwareGenerator 中对 IContextAware 接口实现的验证逻辑 - 简化 AttributeClassGeneratorBase 中的语法提供程序实现 - 移除 AttributeClassGeneratorBase 中的异常处理和错误输出逻辑 - 优化属性解析机制,使用元数据名称或类型进行特性查找
90 lines
3.2 KiB
C#
90 lines
3.2 KiB
C#
using System;
|
||
using System.Linq;
|
||
using System.Text;
|
||
using GFramework.Godot.SourceGenerators.Abstractions.logging;
|
||
using GFramework.SourceGenerators.Common.constants;
|
||
using GFramework.SourceGenerators.Common.generator;
|
||
using Microsoft.CodeAnalysis;
|
||
|
||
namespace GFramework.Godot.SourceGenerators.logging;
|
||
|
||
/// <summary>
|
||
/// 日志生成器,用于为标记了GodotLogAttribute的类自动生成日志字段
|
||
/// </summary>
|
||
[Generator]
|
||
public sealed class GodotLoggerGenerator : TypeAttributeClassGeneratorBase
|
||
{
|
||
protected override Type AttributeType => typeof(GodotLogAttribute);
|
||
|
||
|
||
protected override string AttributeShortNameWithoutSuffix => "GodotLog";
|
||
|
||
/// <summary>
|
||
/// 生成日志字段的源代码
|
||
/// </summary>
|
||
/// <param name="symbol">类符号</param>
|
||
/// <param name="attr">GodotLogAttribute属性数据</param>
|
||
/// <returns>生成的源代码字符串</returns>
|
||
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 && attr.ConstructorArguments[0].Value is string s &&
|
||
!string.IsNullOrWhiteSpace(s))
|
||
{
|
||
name = s;
|
||
}
|
||
|
||
// 解析命名参数
|
||
var fieldName = GetNamedArg(attr, "FieldName")?.ToString() ?? "_log";
|
||
var access = GetNamedArg(attr, "AccessModifier")?.ToString() ?? "private";
|
||
var isStatic = GetNamedArg(attr, "IsStatic") is not bool b || b;
|
||
var staticKeyword = isStatic ? "static " : "";
|
||
|
||
var sb = new StringBuilder();
|
||
sb.AppendLine("// <auto-generated />");
|
||
sb.AppendLine($"using {PathContests.CoreAbstractionsNamespace}.logging;");
|
||
sb.AppendLine($"using {PathContests.GodotNamespace}.logging;");
|
||
sb.AppendLine();
|
||
|
||
if (ns is not null)
|
||
{
|
||
sb.AppendLine($"namespace {ns}");
|
||
sb.AppendLine("{");
|
||
}
|
||
|
||
sb.AppendLine($" public partial class {className}");
|
||
sb.AppendLine(" {");
|
||
sb.AppendLine(" /// <summary>Auto-generated logger</summary>");
|
||
sb.AppendLine(
|
||
$" {access} {staticKeyword}readonly ILogger {fieldName} = new GodotLoggerFactory().GetLogger(\"{name}\");");
|
||
sb.AppendLine(" }");
|
||
|
||
if (ns is not null)
|
||
sb.AppendLine("}");
|
||
|
||
return sb.ToString();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取生成文件的提示名称
|
||
/// </summary>
|
||
/// <param name="symbol">类型符号</param>
|
||
/// <returns>生成文件的提示名称</returns>
|
||
protected override string GetHintName(INamedTypeSymbol symbol)
|
||
=> $"{symbol.Name}.Logger.g.cs";
|
||
|
||
/// <summary>
|
||
/// 获取属性的命名参数值
|
||
/// </summary>
|
||
/// <param name="attr">属性数据</param>
|
||
/// <param name="name">参数名称</param>
|
||
/// <returns>参数值</returns>
|
||
private static object? GetNamedArg(AttributeData attr, string name)
|
||
=> attr.NamedArguments.FirstOrDefault(kv => kv.Key == name).Value.Value;
|
||
} |