using System; using System.Linq; using System.Text; using GFramework.Core.Abstractions.rule; using GFramework.SourceGenerators.Abstractions.rule; using GFramework.SourceGenerators.Common.constants; using GFramework.SourceGenerators.Common.generator; using GFramework.SourceGenerators.diagnostics; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp.Syntax; namespace GFramework.SourceGenerators.rule; [Generator] public sealed class ContextAwareGenerator : AttributeClassGeneratorBase { /// /// 使用强类型 Attribute,替代字符串 /// protected override Type AttributeType => typeof(ContextAwareAttribute); /// /// 仅用于 Syntax 粗筛选 /// protected override string AttributeShortNameWithoutSuffix => "ContextAware"; /// /// 额外语义校验:必须实现 IContextAware /// protected override bool ValidateSymbol( SourceProductionContext context, ClassDeclarationSyntax syntax, INamedTypeSymbol symbol, AttributeData attr) { if (!symbol.AllInterfaces.Any(i => i.ToDisplayString() == typeof(IContextAware).FullName)) { context.ReportDiagnostic(Diagnostic.Create( ContextAwareDiagnostic.ClassMustImplementIContextAware, syntax.Identifier.GetLocation(), symbol.Name)); return false; } return true; } /// /// 生成源码 /// protected override string Generate( INamedTypeSymbol symbol, AttributeData attr) { var ns = symbol.ContainingNamespace.IsGlobalNamespace ? null : symbol.ContainingNamespace.ToDisplayString(); var sb = new StringBuilder(); sb.AppendLine("// "); sb.AppendLine("#nullable enable"); sb.AppendLine(); if (ns is not null) { sb.AppendLine($"namespace {ns};"); sb.AppendLine(); } sb.AppendLine($"partial class {symbol.Name}"); sb.AppendLine("{"); // 属性 sb.AppendLine(" /// "); sb.AppendLine(" /// 自动注入的架构上下文"); sb.AppendLine(" /// "); sb.AppendLine( $" protected {PathContests.CoreAbstractionsNamespace}.architecture.IArchitectureContext Context {{ get; private set; }} = null!;"); sb.AppendLine(); // 方法 sb.AppendLine( $" void {PathContests.CoreAbstractionsNamespace}.rule.IContextAware.SetContext("); sb.AppendLine( $" {PathContests.CoreAbstractionsNamespace}.architecture.IArchitectureContext context)"); sb.AppendLine(" {"); sb.AppendLine(" Context = context;"); sb.AppendLine(" }"); sb.AppendLine("}"); return sb.ToString().TrimEnd(); } /// /// 自定义生成文件名 /// protected override string GetHintName(INamedTypeSymbol symbol) { // 包含命名空间和生成器类名路径 return $"{symbol.Name}.ContextAware.g.cs"; } }