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