Skip to content
3 changes: 3 additions & 0 deletions GFramework.Core.SourceGenerators/Bases/PriorityGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,9 @@ protected override string Generate(
? $"<{string.Join(", ", symbol.TypeParameters.Select(tp => tp.Name))}>"
: string.Empty;

sb.AppendLine("/// <summary>");
sb.AppendLine("/// 为当前分部类型补充自动生成的优先级契约实现。");
sb.AppendLine("/// </summary>");
sb.AppendLine(
$"partial class {symbol.Name}{typeParameters} : global::GFramework.Core.Abstractions.Bases.IPrioritized");
sb.AppendLine("{");
Expand Down
20 changes: 18 additions & 2 deletions GFramework.Core.SourceGenerators/Enums/EnumExtensionsGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,9 @@ protected override string Generate(INamedTypeSymbol symbol, AttributeData attr)

sb.AppendLine("{");

sb.AppendLine(" /// <summary>");
sb.AppendLine($" /// 为 <see cref=\"{fullEnumName}\" /> 提供自动生成的扩展方法。");
sb.AppendLine(" /// </summary>");
sb.AppendLine($" public static partial class {enumName}Extensions");
sb.AppendLine(" {");

Expand Down Expand Up @@ -176,7 +179,13 @@ private static bool AppendIsMethods(StringBuilder builder, IEnumerable<IFieldSym
builder.AppendLine();
}

builder.AppendLine($" /// <summary>是否为 {memberName}</summary>");
builder.AppendLine(" /// <summary>");
builder.AppendLine(
$" /// 判断给定值是否为 <see cref=\"{fullEnumName}.{memberName}\" />。");
builder.AppendLine(" /// </summary>");
builder.AppendLine(" /// <param name=\"value\">要检查的枚举值。</param>");
builder.AppendLine(
$" /// <returns>当 <paramref name=\"value\" /> 等于 <see cref=\"{fullEnumName}.{memberName}\" /> 时返回 <see langword=\"true\" />;否则返回 <see langword=\"false\" />。</returns>");
builder.AppendLine(
$" public static bool Is{memberName}(this {fullEnumName} value) => value == {fullEnumName}.{memberName};");
hasGeneratedMembers = true;
Expand All @@ -192,7 +201,14 @@ private static bool AppendIsMethods(StringBuilder builder, IEnumerable<IFieldSym
/// <param name="fullEnumName">枚举的完整类型名。</param>
private static void AppendIsInMethod(StringBuilder builder, string fullEnumName)
{
builder.AppendLine(" /// <summary>判断是否属于指定集合</summary>");
builder.AppendLine(" /// <summary>");
builder.AppendLine(" /// 判断给定值是否属于指定候选集合。");
builder.AppendLine(" /// </summary>");
builder.AppendLine(" /// <param name=\"value\">要检查的枚举值。</param>");
builder.AppendLine(
" /// <param name=\"values\">用于匹配的候选枚举值集合;当为 <see langword=\"null\" /> 时返回 <see langword=\"false\" />。</param>");
builder.AppendLine(
" /// <returns>当 <paramref name=\"value\" /> 命中任一候选值时返回 <see langword=\"true\" />;否则返回 <see langword=\"false\" />。</returns>");
builder.AppendLine(
$" public static bool IsIn(this {fullEnumName} value, params {fullEnumName}[] values)");
builder.AppendLine(" {");
Expand Down
7 changes: 6 additions & 1 deletion GFramework.Core.SourceGenerators/Logging/LoggerGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,13 +71,18 @@ protected override string Generate(
.AppendLine($"namespace {ns};");

sb.AppendLine()
.AppendLine("/// <summary>")
.AppendLine("/// 为当前分部类型提供自动生成的日志字段。")
.AppendLine("/// </summary>")
.AppendLine($"partial {typeKind} {className}{generics.Parameters}");

foreach (var c in generics.Constraints)
sb.AppendLine($" {c}");

sb.AppendLine("{")
.AppendLine(" /// <summary>Auto-generated logger</summary>")
.AppendLine(" /// <summary>")
.AppendLine(" /// 自动生成的日志字段。")
.AppendLine(" /// </summary>")
.AppendLine(
$" {access} {staticKeyword}readonly ILogger {fieldName} = " +
$"LoggerFactoryResolver.Provider.CreateLogger(\"{logName}\");")
Expand Down
72 changes: 61 additions & 11 deletions GFramework.Core.SourceGenerators/Rule/ContextAwareGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,17 @@ protected override string Generate(

var interfaceName = iContextAware.ToDisplayString(
SymbolDisplayFormat.FullyQualifiedFormat);
sb.AppendLine("/// <summary>");
sb.AppendLine("/// 为当前规则类型补充自动生成的架构上下文访问实现。");
sb.AppendLine("/// </summary>");
sb.AppendLine("/// <remarks>");
sb.AppendLine(
"/// 生成代码会在实例级缓存首次解析到的上下文,并在未显式配置提供者时回退到 <see cref=\"GFramework.Core.Architectures.GameContextProvider\" />。");
sb.AppendLine(
"/// 同一生成类型的所有实例共享一个静态上下文提供者;切换或重置提供者只会影响尚未缓存上下文的新实例或未初始化实例,");
sb.AppendLine(
"/// 已缓存的实例上下文需要通过 <see cref=\"GFramework.Core.Abstractions.Rule.IContextAware.SetContext(GFramework.Core.Abstractions.Architectures.IArchitectureContext)\" /> 显式覆盖。");
sb.AppendLine("/// </remarks>");
sb.AppendLine($"partial class {symbol.Name} : {interfaceName}");
sb.AppendLine("{");

Expand Down Expand Up @@ -128,41 +139,76 @@ private static void GenerateContextProperty(StringBuilder sb)
sb.AppendLine(" private global::GFramework.Core.Abstractions.Architectures.IArchitectureContext? _context;");
sb.AppendLine(
" private static global::GFramework.Core.Abstractions.Architectures.IArchitectureContextProvider? _contextProvider;");
sb.AppendLine(" private static readonly object _contextSync = new();");
sb.AppendLine();
sb.AppendLine(" /// <summary>");
sb.AppendLine(" /// 自动获取的架构上下文(懒加载,默认使用 GameContextProvider)");
sb.AppendLine(" /// 获取当前实例绑定的架构上下文。");
sb.AppendLine(" /// </summary>");
sb.AppendLine(" /// <remarks>");
sb.AppendLine(
" /// 该属性会先返回通过 <c>IContextAware.SetContext(...)</c> 显式注入的实例上下文;若尚未设置,则在同一个同步域内惰性初始化共享提供者。");
sb.AppendLine(
" /// 当静态提供者尚未配置时,生成代码会回退到 <see cref=\"GFramework.Core.Architectures.GameContextProvider\" />。");
sb.AppendLine(
" /// 一旦某个实例成功缓存上下文,后续 <see cref=\"SetContextProvider(GFramework.Core.Abstractions.Architectures.IArchitectureContextProvider)\" />");
sb.AppendLine(
" /// 或 <see cref=\"ResetContextProvider\" /> 不会自动清除此缓存;如需覆盖,请显式调用 <c>IContextAware.SetContext(...)</c>。");
sb.AppendLine(" /// </remarks>");
sb.AppendLine(" protected global::GFramework.Core.Abstractions.Architectures.IArchitectureContext Context");
sb.AppendLine(" {");
sb.AppendLine(" get");
sb.AppendLine(" {");
sb.AppendLine(" if (_context == null)");
sb.AppendLine(" var context = _context;");
sb.AppendLine(" if (context is not null)");
sb.AppendLine(" {");
sb.AppendLine(" return context;");
sb.AppendLine(" }");
sb.AppendLine();
sb.AppendLine(" // 在同一个同步域内协调懒加载与 provider 切换,避免读取到被并发重置的空提供者。");
sb.AppendLine(" lock (_contextSync)");
sb.AppendLine(" {");
sb.AppendLine(
" _contextProvider ??= new global::GFramework.Core.Architectures.GameContextProvider();");
sb.AppendLine(" _context = _contextProvider.GetContext();");
sb.AppendLine(" _context ??= _contextProvider.GetContext();");
sb.AppendLine(" return _context;");
Comment thread
coderabbitai[bot] marked this conversation as resolved.
sb.AppendLine(" }");
sb.AppendLine();
sb.AppendLine(" return _context;");
sb.AppendLine(" }");
sb.AppendLine(" }");
sb.AppendLine();
sb.AppendLine(" /// <summary>");
sb.AppendLine(" /// 配置上下文提供者(用于测试或多架构场景)");
sb.AppendLine(" /// 配置当前生成类型共享的上下文提供者。");
sb.AppendLine(" /// </summary>");
sb.AppendLine(" /// <param name=\"provider\">上下文提供者实例</param>");
sb.AppendLine(" /// <param name=\"provider\">后续懒加载上下文时要使用的提供者实例。</param>");
sb.AppendLine(" /// <remarks>");
sb.AppendLine(" /// 该方法使用与 <see cref=\"Context\" /> 相同的同步锁,避免提供者切换与惰性初始化交错。");
sb.AppendLine(
" /// 已经缓存上下文的实例不会因为提供者切换而自动失效;该变更仅影响尚未初始化上下文的新实例或未缓存实例。");
sb.AppendLine(" /// 如需覆盖已有实例的上下文,请显式调用 <c>IContextAware.SetContext(...)</c>。");
sb.AppendLine(" /// </remarks>");
sb.AppendLine(
" public static void SetContextProvider(global::GFramework.Core.Abstractions.Architectures.IArchitectureContextProvider provider)");
sb.AppendLine(" {");
sb.AppendLine(" _contextProvider = provider;");
sb.AppendLine(" lock (_contextSync)");
sb.AppendLine(" {");
sb.AppendLine(" _contextProvider = provider;");
sb.AppendLine(" }");
sb.AppendLine(" }");
sb.AppendLine();
sb.AppendLine(" /// <summary>");
sb.AppendLine(" /// 重置上下文提供者为默认值(用于测试清理)");
sb.AppendLine(" /// 重置共享上下文提供者,使后续懒加载回退到默认提供者。");
sb.AppendLine(" /// </summary>");
sb.AppendLine(" /// <remarks>");
sb.AppendLine(" /// 该方法主要用于测试清理或跨用例恢复默认行为。");
sb.AppendLine(
" /// 它不会清除已经缓存到实例字段中的上下文;只有后续尚未初始化上下文的实例会重新回退到 <see cref=\"GFramework.Core.Architectures.GameContextProvider\" />。");
sb.AppendLine(" /// 如需覆盖已有实例的上下文,请显式调用 <c>IContextAware.SetContext(...)</c>。");
sb.AppendLine(" /// </remarks>");
sb.AppendLine(" public static void ResetContextProvider()");
sb.AppendLine(" {");
sb.AppendLine(" _contextProvider = null;");
sb.AppendLine(" lock (_contextSync)");
sb.AppendLine(" {");
sb.AppendLine(" _contextProvider = null;");
sb.AppendLine(" }");
Comment thread
coderabbitai[bot] marked this conversation as resolved.
sb.AppendLine(" }");
sb.AppendLine();
}
Expand Down Expand Up @@ -232,7 +278,11 @@ private static void GenerateMethodBody(
switch (method.Name)
{
case "SetContext":
sb.AppendLine(" _context = context;");
sb.AppendLine(" // 与 Context getter 共享同一同步协议,避免显式注入被并发懒加载覆盖。");
sb.AppendLine(" lock (_contextSync)");
sb.AppendLine(" {");
sb.AppendLine(" _context = context;");
sb.AppendLine(" }");
break;

case "GetContext":
Expand Down
2 changes: 2 additions & 0 deletions GFramework.Cqrs.SourceGenerators/AnalyzerReleases.Shipped.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
; Shipped analyzer releases
; https://github.com/dotnet/roslyn/blob/main/src/RoslynAnalyzers/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
; Unshipped analyzer release
; https://github.com/dotnet/roslyn/blob/main/src/RoslynAnalyzers/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md

### New Rules

Rule ID | Category | Severity | Notes
-------------|----------------------------------|----------|------------------------------
GF_Cqrs_001 | GFramework.Cqrs.SourceGenerators | Error | CqrsHandlerRegistryGenerator
Loading
Loading