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; }