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;
///
/// 日志生成器,用于为标记了GodotLogAttribute的类自动生成日志字段
///
[Generator]
public sealed class GodotLoggerGenerator : TypeAttributeClassGeneratorBase
{
protected override Type AttributeType => typeof(GodotLogAttribute);
protected override string AttributeShortNameWithoutSuffix => "GodotLog";
///
/// 生成日志字段的源代码
///
/// 类符号
/// GodotLogAttribute属性数据
/// 生成的源代码字符串
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("// ");
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(" /// Auto-generated logger");
sb.AppendLine(
$" {access} {staticKeyword}readonly ILogger {fieldName} = new GodotLoggerFactory().GetLogger(\"{name}\");");
sb.AppendLine(" }");
if (ns is not null)
sb.AppendLine("}");
return sb.ToString();
}
///
/// 获取生成文件的提示名称
///
/// 类型符号
/// 生成文件的提示名称
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;
}