using System.Text; using GFramework.SourceGenerators.Abstractions.logging; using GFramework.SourceGenerators.Common.constants; using GFramework.SourceGenerators.Common.extensions; using GFramework.SourceGenerators.Common.generator; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp.Syntax; namespace GFramework.SourceGenerators.logging; /// /// 日志生成器,用于为标记了LogAttribute的类自动生成日志字段 /// [Generator] public sealed class LoggerGenerator : TypeAttributeClassGeneratorBase { /// /// 获取属性元数据的完整名称,用于标识日志属性的完全限定名 /// protected override Type AttributeType => typeof(LogAttribute); /// /// 用于语法快速筛选 /// protected override string AttributeShortNameWithoutSuffix => "Log"; /// /// 对类进行额外语义校验(可选) /// protected override bool ValidateSymbol( SourceProductionContext context, Compilation compilation, ClassDeclarationSyntax syntax, INamedTypeSymbol symbol, AttributeData attr) { // 可以加自定义规则,比如确保类是 public 或实现某接口 return true; } /// /// 生成源代码 /// /// 源生产上下文 /// 编译对象 /// 命名类型符号 /// 属性数据 /// 生成的源代码字符串 protected override string Generate( SourceProductionContext context, Compilation compilation, INamedTypeSymbol symbol, AttributeData attr) { var ns = symbol.GetNamespace(); var className = symbol.GetFullClassName(); var typeKind = symbol.ResolveTypeKind(); var generics = symbol.ResolveGenerics(); var logName = attr.GetFirstCtorString(className); var fieldName = attr.GetNamedArgument("FieldName", "_log"); var access = attr.GetNamedArgument("AccessModifier", "private"); var isStatic = attr.GetNamedArgument("IsStatic", true); var staticKeyword = isStatic ? "static " : ""; var sb = new StringBuilder() .AppendLine("// ") .AppendLine($"using {PathContests.CoreAbstractionsNamespace}.logging;") .AppendLine($"using {PathContests.CoreNamespace}.logging;"); if (ns is not null) sb.AppendLine() .AppendLine($"namespace {ns};"); sb.AppendLine() .AppendLine($"partial {typeKind} {className}{generics.Parameters}"); foreach (var c in generics.Constraints) sb.AppendLine($" {c}"); sb.AppendLine("{") .AppendLine(" /// Auto-generated logger") .AppendLine( $" {access} {staticKeyword}readonly ILogger {fieldName} = " + $"LoggerFactoryResolver.Provider.CreateLogger(\"{logName}\");") .AppendLine("}"); return sb.ToString(); } /// /// 可以自定义生成文件名 /// protected override string GetHintName(INamedTypeSymbol symbol) { return $"{symbol.Name}.Logger.g.cs"; } }