diff --git a/GFramework.Core.SourceGenerators/Bases/PriorityGenerator.cs b/GFramework.Core.SourceGenerators/Bases/PriorityGenerator.cs index ee534f8a..5c415e4a 100644 --- a/GFramework.Core.SourceGenerators/Bases/PriorityGenerator.cs +++ b/GFramework.Core.SourceGenerators/Bases/PriorityGenerator.cs @@ -118,6 +118,9 @@ public sealed class PriorityGenerator : MetadataAttributeClassGeneratorBase ? $"<{string.Join(", ", symbol.TypeParameters.Select(tp => tp.Name))}>" : string.Empty; + sb.AppendLine("/// "); + sb.AppendLine("/// 为当前分部类型补充自动生成的优先级契约实现。"); + sb.AppendLine("/// "); sb.AppendLine( $"partial class {symbol.Name}{typeParameters} : global::GFramework.Core.Abstractions.Bases.IPrioritized"); sb.AppendLine("{"); diff --git a/GFramework.Core.SourceGenerators/Enums/EnumExtensionsGenerator.cs b/GFramework.Core.SourceGenerators/Enums/EnumExtensionsGenerator.cs index a73d076d..32a4715a 100644 --- a/GFramework.Core.SourceGenerators/Enums/EnumExtensionsGenerator.cs +++ b/GFramework.Core.SourceGenerators/Enums/EnumExtensionsGenerator.cs @@ -95,6 +95,9 @@ public sealed class EnumExtensionsGenerator : AttributeEnumGeneratorBase sb.AppendLine("{"); + sb.AppendLine(" /// "); + sb.AppendLine($" /// 为 提供自动生成的扩展方法。"); + sb.AppendLine(" /// "); sb.AppendLine($" public static partial class {enumName}Extensions"); sb.AppendLine(" {"); @@ -176,7 +179,13 @@ public sealed class EnumExtensionsGenerator : AttributeEnumGeneratorBase builder.AppendLine(); } - builder.AppendLine($" /// 是否为 {memberName}"); + builder.AppendLine(" /// "); + builder.AppendLine( + $" /// 判断给定值是否为 。"); + builder.AppendLine(" /// "); + builder.AppendLine(" /// 要检查的枚举值。"); + builder.AppendLine( + $" /// 等于 时返回 ;否则返回 "); builder.AppendLine( $" public static bool Is{memberName}(this {fullEnumName} value) => value == {fullEnumName}.{memberName};"); hasGeneratedMembers = true; @@ -192,7 +201,13 @@ public sealed class EnumExtensionsGenerator : AttributeEnumGeneratorBase /// 枚举的完整类型名。 private static void AppendIsInMethod(StringBuilder builder, string fullEnumName) { - builder.AppendLine(" /// 判断是否属于指定集合"); + builder.AppendLine(" /// "); + builder.AppendLine(" /// 判断给定值是否属于指定候选集合。"); + builder.AppendLine(" /// "); + builder.AppendLine(" /// 要检查的枚举值。"); + builder.AppendLine(" /// 用于匹配的候选枚举值集合。"); + builder.AppendLine( + " /// 命中任一候选值时返回 ;否则返回 "); builder.AppendLine( $" public static bool IsIn(this {fullEnumName} value, params {fullEnumName}[] values)"); builder.AppendLine(" {"); diff --git a/GFramework.Core.SourceGenerators/Logging/LoggerGenerator.cs b/GFramework.Core.SourceGenerators/Logging/LoggerGenerator.cs index 2be4a1d4..7d875d0c 100644 --- a/GFramework.Core.SourceGenerators/Logging/LoggerGenerator.cs +++ b/GFramework.Core.SourceGenerators/Logging/LoggerGenerator.cs @@ -71,13 +71,18 @@ public sealed class LoggerGenerator : TypeAttributeClassGeneratorBase .AppendLine($"namespace {ns};"); sb.AppendLine() + .AppendLine("/// ") + .AppendLine("/// 为当前分部类型提供自动生成的日志字段。") + .AppendLine("/// ") .AppendLine($"partial {typeKind} {className}{generics.Parameters}"); foreach (var c in generics.Constraints) sb.AppendLine($" {c}"); sb.AppendLine("{") - .AppendLine(" /// Auto-generated logger") + .AppendLine(" /// ") + .AppendLine(" /// 自动生成的日志字段。") + .AppendLine(" /// ") .AppendLine( $" {access} {staticKeyword}readonly ILogger {fieldName} = " + $"LoggerFactoryResolver.Provider.CreateLogger(\"{logName}\");") diff --git a/GFramework.Core.SourceGenerators/Rule/ContextAwareGenerator.cs b/GFramework.Core.SourceGenerators/Rule/ContextAwareGenerator.cs index 9bdeb3f9..0fd15fb7 100644 --- a/GFramework.Core.SourceGenerators/Rule/ContextAwareGenerator.cs +++ b/GFramework.Core.SourceGenerators/Rule/ContextAwareGenerator.cs @@ -96,6 +96,9 @@ public sealed class ContextAwareGenerator : MetadataAttributeClassGeneratorBase var interfaceName = iContextAware.ToDisplayString( SymbolDisplayFormat.FullyQualifiedFormat); + sb.AppendLine("/// "); + sb.AppendLine("/// 为当前规则类型补充自动生成的架构上下文访问实现。"); + sb.AppendLine("/// "); sb.AppendLine($"partial class {symbol.Name} : {interfaceName}"); sb.AppendLine("{"); @@ -128,6 +131,7 @@ public sealed class ContextAwareGenerator : MetadataAttributeClassGeneratorBase 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(" /// "); sb.AppendLine(" /// 自动获取的架构上下文(懒加载,默认使用 GameContextProvider)"); @@ -136,14 +140,20 @@ public sealed class ContextAwareGenerator : MetadataAttributeClassGeneratorBase 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;"); sb.AppendLine(" }"); - sb.AppendLine(); - sb.AppendLine(" return _context;"); sb.AppendLine(" }"); sb.AppendLine(" }"); sb.AppendLine(); @@ -154,7 +164,10 @@ public sealed class ContextAwareGenerator : MetadataAttributeClassGeneratorBase 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(" /// "); @@ -162,7 +175,10 @@ public sealed class ContextAwareGenerator : MetadataAttributeClassGeneratorBase sb.AppendLine(" /// "); sb.AppendLine(" public static void ResetContextProvider()"); sb.AppendLine(" {"); - sb.AppendLine(" _contextProvider = null;"); + sb.AppendLine(" lock (_contextSync)"); + sb.AppendLine(" {"); + sb.AppendLine(" _contextProvider = null;"); + sb.AppendLine(" }"); sb.AppendLine(" }"); sb.AppendLine(); } diff --git a/GFramework.Cqrs.SourceGenerators/Cqrs/CqrsHandlerRegistryGenerator.cs b/GFramework.Cqrs.SourceGenerators/Cqrs/CqrsHandlerRegistryGenerator.cs index 0d2c621c..a1cb10a6 100644 --- a/GFramework.Cqrs.SourceGenerators/Cqrs/CqrsHandlerRegistryGenerator.cs +++ b/GFramework.Cqrs.SourceGenerators/Cqrs/CqrsHandlerRegistryGenerator.cs @@ -165,8 +165,9 @@ public sealed class CqrsHandlerRegistryGenerator : IIncrementalGenerator .Cast() .ToArray(); - if (fallbackHandlerTypeMetadataNames.Length > 0 && - !generationEnvironment.SupportsReflectionFallbackAttribute) + if (!CanEmitGeneratedRegistry( + generationEnvironment.SupportsReflectionFallbackAttribute, + fallbackHandlerTypeMetadataNames.Length)) { return; } @@ -176,6 +177,26 @@ public sealed class CqrsHandlerRegistryGenerator : IIncrementalGenerator GenerateSource(generationEnvironment, registrations, fallbackHandlerTypeMetadataNames)); } + /// + /// 判断当前轮次是否允许输出生成注册器。 + /// + /// + /// runtime 合同中是否存在 CqrsReflectionFallbackAttribute,以承载生成器无法静态精确表达的 handler 回退元数据。 + /// + /// + /// 当前轮次需要依赖程序集级 reflection fallback 元数据恢复的 handler 数量。 + /// + /// + /// 当没有 handler 依赖 fallback,或 runtime 已提供承载该元数据的特性契约时返回 ; + /// 否则返回 ,调用方必须放弃生成以避免输出会静默漏注册的半成品注册器。 + /// + private static bool CanEmitGeneratedRegistry( + bool supportsReflectionFallbackAttribute, + int fallbackHandlerTypeCount) + { + return fallbackHandlerTypeCount == 0 || supportsReflectionFallbackAttribute; + } + private static List CollectRegistrations( ImmutableArray candidates) { diff --git a/GFramework.SourceGenerators.Tests/Bases/snapshots/PriorityGenerator/BasicPriority/TestApp_MySystem.Priority.g.cs b/GFramework.SourceGenerators.Tests/Bases/snapshots/PriorityGenerator/BasicPriority/TestApp_MySystem.Priority.g.cs index 2a6756fe..fec15e5d 100644 --- a/GFramework.SourceGenerators.Tests/Bases/snapshots/PriorityGenerator/BasicPriority/TestApp_MySystem.Priority.g.cs +++ b/GFramework.SourceGenerators.Tests/Bases/snapshots/PriorityGenerator/BasicPriority/TestApp_MySystem.Priority.g.cs @@ -3,10 +3,13 @@ namespace TestApp; +/// +/// 为当前分部类型补充自动生成的优先级契约实现。 +/// partial class MySystem : global::GFramework.Core.Abstractions.Bases.IPrioritized { /// /// 获取优先级值: 10 /// public int Priority => 10; -} \ No newline at end of file +} diff --git a/GFramework.SourceGenerators.Tests/Bases/snapshots/PriorityGenerator/GenericClass/TestApp_GenericSystem_T_.Priority.g.cs b/GFramework.SourceGenerators.Tests/Bases/snapshots/PriorityGenerator/GenericClass/TestApp_GenericSystem_T_.Priority.g.cs index a0ce6997..c339c989 100644 --- a/GFramework.SourceGenerators.Tests/Bases/snapshots/PriorityGenerator/GenericClass/TestApp_GenericSystem_T_.Priority.g.cs +++ b/GFramework.SourceGenerators.Tests/Bases/snapshots/PriorityGenerator/GenericClass/TestApp_GenericSystem_T_.Priority.g.cs @@ -3,10 +3,13 @@ namespace TestApp; +/// +/// 为当前分部类型补充自动生成的优先级契约实现。 +/// partial class GenericSystem : global::GFramework.Core.Abstractions.Bases.IPrioritized { /// /// 获取优先级值: 20 /// public int Priority => 20; -} \ No newline at end of file +} diff --git a/GFramework.SourceGenerators.Tests/Bases/snapshots/PriorityGenerator/NegativePriority/TestApp_CriticalSystem.Priority.g.cs b/GFramework.SourceGenerators.Tests/Bases/snapshots/PriorityGenerator/NegativePriority/TestApp_CriticalSystem.Priority.g.cs index bd6b4af3..03f57f91 100644 --- a/GFramework.SourceGenerators.Tests/Bases/snapshots/PriorityGenerator/NegativePriority/TestApp_CriticalSystem.Priority.g.cs +++ b/GFramework.SourceGenerators.Tests/Bases/snapshots/PriorityGenerator/NegativePriority/TestApp_CriticalSystem.Priority.g.cs @@ -3,10 +3,13 @@ namespace TestApp; +/// +/// 为当前分部类型补充自动生成的优先级契约实现。 +/// partial class CriticalSystem : global::GFramework.Core.Abstractions.Bases.IPrioritized { /// /// 获取优先级值: -100 /// public int Priority => -100; -} \ No newline at end of file +} diff --git a/GFramework.SourceGenerators.Tests/Bases/snapshots/PriorityGenerator/PriorityGroup/TestApp_HighPrioritySystem.Priority.g.cs b/GFramework.SourceGenerators.Tests/Bases/snapshots/PriorityGenerator/PriorityGroup/TestApp_HighPrioritySystem.Priority.g.cs index 737acd1a..49fb10aa 100644 --- a/GFramework.SourceGenerators.Tests/Bases/snapshots/PriorityGenerator/PriorityGroup/TestApp_HighPrioritySystem.Priority.g.cs +++ b/GFramework.SourceGenerators.Tests/Bases/snapshots/PriorityGenerator/PriorityGroup/TestApp_HighPrioritySystem.Priority.g.cs @@ -3,10 +3,13 @@ namespace TestApp; +/// +/// 为当前分部类型补充自动生成的优先级契约实现。 +/// partial class HighPrioritySystem : global::GFramework.Core.Abstractions.Bases.IPrioritized { /// /// 获取优先级值: -50 /// public int Priority => -50; -} \ No newline at end of file +} diff --git a/GFramework.SourceGenerators.Tests/Core/GeneratorSnapshotTest.cs b/GFramework.SourceGenerators.Tests/Core/GeneratorSnapshotTest.cs index f464cb74..d8726a2f 100644 --- a/GFramework.SourceGenerators.Tests/Core/GeneratorSnapshotTest.cs +++ b/GFramework.SourceGenerators.Tests/Core/GeneratorSnapshotTest.cs @@ -42,7 +42,7 @@ public static class GeneratorSnapshotTest compilationErrors, Is.Empty, () => - $"编译生成的代码时出现错误:{Environment.NewLine}{string.Join(Environment.NewLine, compilationErrors.Select(static diagnostic => diagnostic.ToString()))}"); + $"编译生成的代码时出现错误:{Environment.NewLine}{string.Join(Environment.NewLine, compilationErrors.Select(static diagnostic => diagnostic.ToString()))}"); var runResult = driver.GetRunResult(); var generated = runResult.Results @@ -53,7 +53,7 @@ public static class GeneratorSnapshotTest Assert.That( generated, Is.Not.Empty, - $"Generator '{typeof(TGenerator).FullName}' did not produce any sources."); + $"生成器 '{typeof(TGenerator).FullName}' 未产生任何输出。"); foreach (var (filename, content) in generated) { @@ -70,7 +70,7 @@ public static class GeneratorSnapshotTest await File.WriteAllTextAsync(path, content.ToString()); Assert.Fail( - $"Snapshot not found. Generated new snapshot at:\n{path}"); + $"未找到快照文件,已在以下路径生成新快照:\n{path}"); } var expected = await File.ReadAllTextAsync(path); @@ -78,7 +78,7 @@ public static class GeneratorSnapshotTest Assert.That( Normalize(expected), Is.EqualTo(Normalize(content.ToString())), - $"Snapshot mismatch: {snapshotFileName}"); + $"快照不匹配:{snapshotFileName}"); } } diff --git a/GFramework.SourceGenerators.Tests/Cqrs/CqrsHandlerRegistryGeneratorTests.cs b/GFramework.SourceGenerators.Tests/Cqrs/CqrsHandlerRegistryGeneratorTests.cs index 28e80f6d..50483a08 100644 --- a/GFramework.SourceGenerators.Tests/Cqrs/CqrsHandlerRegistryGeneratorTests.cs +++ b/GFramework.SourceGenerators.Tests/Cqrs/CqrsHandlerRegistryGeneratorTests.cs @@ -1168,6 +1168,32 @@ public class CqrsHandlerRegistryGeneratorTests ("CqrsHandlerRegistry.g.cs", HiddenNestedHandlerSelfRegistrationExpected)); } + /// + /// 验证当某轮生成仍然需要程序集级 reflection fallback 元数据时, + /// 若 runtime 合同未提供对应特性契约,生成器会放弃输出注册器以避免静默漏注册。 + /// + [Test] + public void + Rejects_Registry_Emission_When_Fallback_Metadata_Is_Required_But_Runtime_Contract_Lacks_Fallback_Attribute() + { + var method = typeof(CqrsHandlerRegistryGenerator).GetMethod( + "CanEmitGeneratedRegistry", + BindingFlags.NonPublic | BindingFlags.Static); + + Assert.That(method, Is.Not.Null); + + var canEmitWithoutFallbackRequirement = (bool?)method!.Invoke(null, [false, 0]); + var canEmitWithSupportedFallbackAttribute = (bool?)method.Invoke(null, [true, 1]); + var canEmitWithoutSupportedFallbackAttribute = (bool?)method.Invoke(null, [false, 1]); + + Assert.Multiple(() => + { + Assert.That(canEmitWithoutFallbackRequirement, Is.True); + Assert.That(canEmitWithSupportedFallbackAttribute, Is.True); + Assert.That(canEmitWithoutSupportedFallbackAttribute, Is.False); + }); + } + /// /// 验证日志字符串转义会覆盖换行、反斜杠和双引号,避免生成代码中的字符串字面量被意外截断。 /// diff --git a/GFramework.SourceGenerators.Tests/Enums/EnumExtensionsGeneratorSnapshotTests.cs b/GFramework.SourceGenerators.Tests/Enums/EnumExtensionsGeneratorSnapshotTests.cs index f5fa2157..e5720826 100644 --- a/GFramework.SourceGenerators.Tests/Enums/EnumExtensionsGeneratorSnapshotTests.cs +++ b/GFramework.SourceGenerators.Tests/Enums/EnumExtensionsGeneratorSnapshotTests.cs @@ -15,6 +15,7 @@ public class EnumExtensionsGeneratorSnapshotTests /// /// 验证默认配置会为普通枚举生成逐项判断方法与集合判断方法。 /// + /// 异步任务。 [Test] public async Task Snapshot_BasicEnum_IsMethods() { @@ -37,6 +38,7 @@ public class EnumExtensionsGeneratorSnapshotTests /// /// 验证未提供快照文件名映射时,会直接按生成文件名进行快照比对。 /// + /// 异步任务。 [Test] public async Task Snapshot_BasicEnum_IsMethods_DefaultSnapshotFileNameSelector() { @@ -57,6 +59,7 @@ public class EnumExtensionsGeneratorSnapshotTests /// /// 验证默认配置在较小枚举上仍会生成集合判断方法。 /// + /// 异步任务。 [Test] public async Task Snapshot_BasicEnum_IsInMethod() { @@ -78,6 +81,7 @@ public class EnumExtensionsGeneratorSnapshotTests /// /// 验证带显式位标志值的枚举也会生成对应扩展方法。 /// + /// 异步任务。 [Test] public async Task Snapshot_EnumWithFlagValues() { @@ -102,6 +106,7 @@ public class EnumExtensionsGeneratorSnapshotTests /// /// 验证关闭逐项判断开关后仅保留集合判断方法。 /// + /// 异步任务。 [Test] public async Task Snapshot_DisableIsMethods() { @@ -124,6 +129,7 @@ public class EnumExtensionsGeneratorSnapshotTests /// /// 验证关闭集合判断开关后仅保留逐项判断方法。 /// + /// 异步任务。 [Test] public async Task Snapshot_DisableIsInMethod() { @@ -146,6 +152,7 @@ public class EnumExtensionsGeneratorSnapshotTests /// /// 验证同时关闭两个生成开关时不会输出任何扩展方法。 /// + /// 异步任务。 [Test] public async Task Snapshot_DisableAllGeneratedMethods() { diff --git a/GFramework.SourceGenerators.Tests/Enums/snapshots/EnumExtensionsGenerator/BasicEnum_IsInMethod/Status.EnumExtensions.g.txt b/GFramework.SourceGenerators.Tests/Enums/snapshots/EnumExtensionsGenerator/BasicEnum_IsInMethod/Status.EnumExtensions.g.txt index 2897d09c..89db6bdb 100644 --- a/GFramework.SourceGenerators.Tests/Enums/snapshots/EnumExtensionsGenerator/BasicEnum_IsInMethod/Status.EnumExtensions.g.txt +++ b/GFramework.SourceGenerators.Tests/Enums/snapshots/EnumExtensionsGenerator/BasicEnum_IsInMethod/Status.EnumExtensions.g.txt @@ -2,15 +2,31 @@ using System; namespace TestApp { + /// + /// 为 提供自动生成的扩展方法。 + /// public static partial class StatusExtensions { - /// 是否为 Active + /// + /// 判断给定值是否为 。 + /// + /// 要检查的枚举值。 + /// 等于 时返回 ;否则返回 public static bool IsActive(this TestApp.Status value) => value == TestApp.Status.Active; - /// 是否为 Inactive + /// + /// 判断给定值是否为 。 + /// + /// 要检查的枚举值。 + /// 等于 时返回 ;否则返回 public static bool IsInactive(this TestApp.Status value) => value == TestApp.Status.Inactive; - /// 判断是否属于指定集合 + /// + /// 判断给定值是否属于指定候选集合。 + /// + /// 要检查的枚举值。 + /// 用于匹配的候选枚举值集合。 + /// 命中任一候选值时返回 ;否则返回 public static bool IsIn(this TestApp.Status value, params TestApp.Status[] values) { if (values == null) return false; diff --git a/GFramework.SourceGenerators.Tests/Enums/snapshots/EnumExtensionsGenerator/BasicEnum_IsMethods/Status.EnumExtensions.g.txt b/GFramework.SourceGenerators.Tests/Enums/snapshots/EnumExtensionsGenerator/BasicEnum_IsMethods/Status.EnumExtensions.g.txt index db9fa7ba..1709ecf7 100644 --- a/GFramework.SourceGenerators.Tests/Enums/snapshots/EnumExtensionsGenerator/BasicEnum_IsMethods/Status.EnumExtensions.g.txt +++ b/GFramework.SourceGenerators.Tests/Enums/snapshots/EnumExtensionsGenerator/BasicEnum_IsMethods/Status.EnumExtensions.g.txt @@ -2,18 +2,38 @@ using System; namespace TestApp { + /// + /// 为 提供自动生成的扩展方法。 + /// public static partial class StatusExtensions { - /// 是否为 Active + /// + /// 判断给定值是否为 。 + /// + /// 要检查的枚举值。 + /// 等于 时返回 ;否则返回 public static bool IsActive(this TestApp.Status value) => value == TestApp.Status.Active; - /// 是否为 Inactive + /// + /// 判断给定值是否为 。 + /// + /// 要检查的枚举值。 + /// 等于 时返回 ;否则返回 public static bool IsInactive(this TestApp.Status value) => value == TestApp.Status.Inactive; - /// 是否为 Pending + /// + /// 判断给定值是否为 。 + /// + /// 要检查的枚举值。 + /// 等于 时返回 ;否则返回 public static bool IsPending(this TestApp.Status value) => value == TestApp.Status.Pending; - /// 判断是否属于指定集合 + /// + /// 判断给定值是否属于指定候选集合。 + /// + /// 要检查的枚举值。 + /// 用于匹配的候选枚举值集合。 + /// 命中任一候选值时返回 ;否则返回 public static bool IsIn(this TestApp.Status value, params TestApp.Status[] values) { if (values == null) return false; diff --git a/GFramework.SourceGenerators.Tests/Enums/snapshots/EnumExtensionsGenerator/BasicEnum_IsMethods_DefaultSnapshotFileNameSelector/Status.EnumExtensions.g.cs b/GFramework.SourceGenerators.Tests/Enums/snapshots/EnumExtensionsGenerator/BasicEnum_IsMethods_DefaultSnapshotFileNameSelector/Status.EnumExtensions.g.cs index 2897d09c..89db6bdb 100644 --- a/GFramework.SourceGenerators.Tests/Enums/snapshots/EnumExtensionsGenerator/BasicEnum_IsMethods_DefaultSnapshotFileNameSelector/Status.EnumExtensions.g.cs +++ b/GFramework.SourceGenerators.Tests/Enums/snapshots/EnumExtensionsGenerator/BasicEnum_IsMethods_DefaultSnapshotFileNameSelector/Status.EnumExtensions.g.cs @@ -2,15 +2,31 @@ using System; namespace TestApp { + /// + /// 为 提供自动生成的扩展方法。 + /// public static partial class StatusExtensions { - /// 是否为 Active + /// + /// 判断给定值是否为 。 + /// + /// 要检查的枚举值。 + /// 等于 时返回 ;否则返回 public static bool IsActive(this TestApp.Status value) => value == TestApp.Status.Active; - /// 是否为 Inactive + /// + /// 判断给定值是否为 。 + /// + /// 要检查的枚举值。 + /// 等于 时返回 ;否则返回 public static bool IsInactive(this TestApp.Status value) => value == TestApp.Status.Inactive; - /// 判断是否属于指定集合 + /// + /// 判断给定值是否属于指定候选集合。 + /// + /// 要检查的枚举值。 + /// 用于匹配的候选枚举值集合。 + /// 命中任一候选值时返回 ;否则返回 public static bool IsIn(this TestApp.Status value, params TestApp.Status[] values) { if (values == null) return false; diff --git a/GFramework.SourceGenerators.Tests/Enums/snapshots/EnumExtensionsGenerator/DisableAllGeneratedMethods/Status.EnumExtensions.g.txt b/GFramework.SourceGenerators.Tests/Enums/snapshots/EnumExtensionsGenerator/DisableAllGeneratedMethods/Status.EnumExtensions.g.txt index 74b39b20..23ea0fa5 100644 --- a/GFramework.SourceGenerators.Tests/Enums/snapshots/EnumExtensionsGenerator/DisableAllGeneratedMethods/Status.EnumExtensions.g.txt +++ b/GFramework.SourceGenerators.Tests/Enums/snapshots/EnumExtensionsGenerator/DisableAllGeneratedMethods/Status.EnumExtensions.g.txt @@ -2,6 +2,9 @@ using System; namespace TestApp { + /// + /// 为 提供自动生成的扩展方法。 + /// public static partial class StatusExtensions { } diff --git a/GFramework.SourceGenerators.Tests/Enums/snapshots/EnumExtensionsGenerator/DisableIsInMethod/Status.EnumExtensions.g.txt b/GFramework.SourceGenerators.Tests/Enums/snapshots/EnumExtensionsGenerator/DisableIsInMethod/Status.EnumExtensions.g.txt index 3563db50..c79e62ef 100644 --- a/GFramework.SourceGenerators.Tests/Enums/snapshots/EnumExtensionsGenerator/DisableIsInMethod/Status.EnumExtensions.g.txt +++ b/GFramework.SourceGenerators.Tests/Enums/snapshots/EnumExtensionsGenerator/DisableIsInMethod/Status.EnumExtensions.g.txt @@ -2,12 +2,23 @@ using System; namespace TestApp { + /// + /// 为 提供自动生成的扩展方法。 + /// public static partial class StatusExtensions { - /// 是否为 Active + /// + /// 判断给定值是否为 。 + /// + /// 要检查的枚举值。 + /// 等于 时返回 ;否则返回 public static bool IsActive(this TestApp.Status value) => value == TestApp.Status.Active; - /// 是否为 Inactive + /// + /// 判断给定值是否为 。 + /// + /// 要检查的枚举值。 + /// 等于 时返回 ;否则返回 public static bool IsInactive(this TestApp.Status value) => value == TestApp.Status.Inactive; } } diff --git a/GFramework.SourceGenerators.Tests/Enums/snapshots/EnumExtensionsGenerator/DisableIsMethods/Status.EnumExtensions.g.txt b/GFramework.SourceGenerators.Tests/Enums/snapshots/EnumExtensionsGenerator/DisableIsMethods/Status.EnumExtensions.g.txt index 41154546..dc9086bb 100644 --- a/GFramework.SourceGenerators.Tests/Enums/snapshots/EnumExtensionsGenerator/DisableIsMethods/Status.EnumExtensions.g.txt +++ b/GFramework.SourceGenerators.Tests/Enums/snapshots/EnumExtensionsGenerator/DisableIsMethods/Status.EnumExtensions.g.txt @@ -2,9 +2,17 @@ using System; namespace TestApp { + /// + /// 为 提供自动生成的扩展方法。 + /// public static partial class StatusExtensions { - /// 判断是否属于指定集合 + /// + /// 判断给定值是否属于指定候选集合。 + /// + /// 要检查的枚举值。 + /// 用于匹配的候选枚举值集合。 + /// 命中任一候选值时返回 ;否则返回 public static bool IsIn(this TestApp.Status value, params TestApp.Status[] values) { if (values == null) return false; diff --git a/GFramework.SourceGenerators.Tests/Enums/snapshots/EnumExtensionsGenerator/EnumWithFlagValues/Permissions.EnumExtensions.g.txt b/GFramework.SourceGenerators.Tests/Enums/snapshots/EnumExtensionsGenerator/EnumWithFlagValues/Permissions.EnumExtensions.g.txt index ebd87525..e99878fd 100644 --- a/GFramework.SourceGenerators.Tests/Enums/snapshots/EnumExtensionsGenerator/EnumWithFlagValues/Permissions.EnumExtensions.g.txt +++ b/GFramework.SourceGenerators.Tests/Enums/snapshots/EnumExtensionsGenerator/EnumWithFlagValues/Permissions.EnumExtensions.g.txt @@ -2,21 +2,45 @@ using System; namespace TestApp { + /// + /// 为 提供自动生成的扩展方法。 + /// public static partial class PermissionsExtensions { - /// 是否为 None + /// + /// 判断给定值是否为 。 + /// + /// 要检查的枚举值。 + /// 等于 时返回 ;否则返回 public static bool IsNone(this TestApp.Permissions value) => value == TestApp.Permissions.None; - /// 是否为 Read + /// + /// 判断给定值是否为 。 + /// + /// 要检查的枚举值。 + /// 等于 时返回 ;否则返回 public static bool IsRead(this TestApp.Permissions value) => value == TestApp.Permissions.Read; - /// 是否为 Write + /// + /// 判断给定值是否为 。 + /// + /// 要检查的枚举值。 + /// 等于 时返回 ;否则返回 public static bool IsWrite(this TestApp.Permissions value) => value == TestApp.Permissions.Write; - /// 是否为 Execute + /// + /// 判断给定值是否为 。 + /// + /// 要检查的枚举值。 + /// 等于 时返回 ;否则返回 public static bool IsExecute(this TestApp.Permissions value) => value == TestApp.Permissions.Execute; - /// 判断是否属于指定集合 + /// + /// 判断给定值是否属于指定候选集合。 + /// + /// 要检查的枚举值。 + /// 用于匹配的候选枚举值集合。 + /// 命中任一候选值时返回 ;否则返回 public static bool IsIn(this TestApp.Permissions value, params TestApp.Permissions[] values) { if (values == null) return false; diff --git a/GFramework.SourceGenerators.Tests/Logging/snapshots/LoggerGenerator/CustomFieldName_Class/MyService.Logger.g.cs b/GFramework.SourceGenerators.Tests/Logging/snapshots/LoggerGenerator/CustomFieldName_Class/MyService.Logger.g.cs index bc4a50ae..00a34a72 100644 --- a/GFramework.SourceGenerators.Tests/Logging/snapshots/LoggerGenerator/CustomFieldName_Class/MyService.Logger.g.cs +++ b/GFramework.SourceGenerators.Tests/Logging/snapshots/LoggerGenerator/CustomFieldName_Class/MyService.Logger.g.cs @@ -4,8 +4,13 @@ using GFramework.Core.Logging; namespace TestApp; +/// +/// 为当前分部类型提供自动生成的日志字段。 +/// partial class MyService { - /// Auto-generated logger + /// + /// 自动生成的日志字段。 + /// private static readonly ILogger MyLogger = LoggerFactoryResolver.Provider.CreateLogger("MyService"); } diff --git a/GFramework.SourceGenerators.Tests/Logging/snapshots/LoggerGenerator/CustomName_Class/MyService.Logger.g.cs b/GFramework.SourceGenerators.Tests/Logging/snapshots/LoggerGenerator/CustomName_Class/MyService.Logger.g.cs index 02bcfad9..f355acc6 100644 --- a/GFramework.SourceGenerators.Tests/Logging/snapshots/LoggerGenerator/CustomName_Class/MyService.Logger.g.cs +++ b/GFramework.SourceGenerators.Tests/Logging/snapshots/LoggerGenerator/CustomName_Class/MyService.Logger.g.cs @@ -4,8 +4,13 @@ using GFramework.Core.Logging; namespace TestApp; +/// +/// 为当前分部类型提供自动生成的日志字段。 +/// partial class MyService { - /// Auto-generated logger + /// + /// 自动生成的日志字段。 + /// private static readonly ILogger _log = LoggerFactoryResolver.Provider.CreateLogger("MyService"); } diff --git a/GFramework.SourceGenerators.Tests/Logging/snapshots/LoggerGenerator/DefaultConfiguration_Class/MyService.Logger.g.cs b/GFramework.SourceGenerators.Tests/Logging/snapshots/LoggerGenerator/DefaultConfiguration_Class/MyService.Logger.g.cs index 02bcfad9..f355acc6 100644 --- a/GFramework.SourceGenerators.Tests/Logging/snapshots/LoggerGenerator/DefaultConfiguration_Class/MyService.Logger.g.cs +++ b/GFramework.SourceGenerators.Tests/Logging/snapshots/LoggerGenerator/DefaultConfiguration_Class/MyService.Logger.g.cs @@ -4,8 +4,13 @@ using GFramework.Core.Logging; namespace TestApp; +/// +/// 为当前分部类型提供自动生成的日志字段。 +/// partial class MyService { - /// Auto-generated logger + /// + /// 自动生成的日志字段。 + /// private static readonly ILogger _log = LoggerFactoryResolver.Provider.CreateLogger("MyService"); } diff --git a/GFramework.SourceGenerators.Tests/Logging/snapshots/LoggerGenerator/GenericClass/MyService.Logger.g.cs b/GFramework.SourceGenerators.Tests/Logging/snapshots/LoggerGenerator/GenericClass/MyService.Logger.g.cs index f06bd74d..231551aa 100644 --- a/GFramework.SourceGenerators.Tests/Logging/snapshots/LoggerGenerator/GenericClass/MyService.Logger.g.cs +++ b/GFramework.SourceGenerators.Tests/Logging/snapshots/LoggerGenerator/GenericClass/MyService.Logger.g.cs @@ -4,8 +4,13 @@ using GFramework.Core.Logging; namespace TestApp; +/// +/// 为当前分部类型提供自动生成的日志字段。 +/// partial class MyService { - /// Auto-generated logger + /// + /// 自动生成的日志字段。 + /// private static readonly ILogger _log = LoggerFactoryResolver.Provider.CreateLogger("MyService"); } diff --git a/GFramework.SourceGenerators.Tests/Logging/snapshots/LoggerGenerator/InstanceField_Class/MyService.Logger.g.cs b/GFramework.SourceGenerators.Tests/Logging/snapshots/LoggerGenerator/InstanceField_Class/MyService.Logger.g.cs index 05e566e4..f1e73e53 100644 --- a/GFramework.SourceGenerators.Tests/Logging/snapshots/LoggerGenerator/InstanceField_Class/MyService.Logger.g.cs +++ b/GFramework.SourceGenerators.Tests/Logging/snapshots/LoggerGenerator/InstanceField_Class/MyService.Logger.g.cs @@ -4,8 +4,13 @@ using GFramework.Core.Logging; namespace TestApp; +/// +/// 为当前分部类型提供自动生成的日志字段。 +/// partial class MyService { - /// Auto-generated logger + /// + /// 自动生成的日志字段。 + /// private readonly ILogger _log = LoggerFactoryResolver.Provider.CreateLogger("MyService"); } diff --git a/GFramework.SourceGenerators.Tests/Logging/snapshots/LoggerGenerator/PublicField_Class/MyService.Logger.g.cs b/GFramework.SourceGenerators.Tests/Logging/snapshots/LoggerGenerator/PublicField_Class/MyService.Logger.g.cs index 19326d76..fef90ca3 100644 --- a/GFramework.SourceGenerators.Tests/Logging/snapshots/LoggerGenerator/PublicField_Class/MyService.Logger.g.cs +++ b/GFramework.SourceGenerators.Tests/Logging/snapshots/LoggerGenerator/PublicField_Class/MyService.Logger.g.cs @@ -4,8 +4,13 @@ using GFramework.Core.Logging; namespace TestApp; +/// +/// 为当前分部类型提供自动生成的日志字段。 +/// partial class MyService { - /// Auto-generated logger + /// + /// 自动生成的日志字段。 + /// public static readonly ILogger _log = LoggerFactoryResolver.Provider.CreateLogger("MyService"); } diff --git a/GFramework.SourceGenerators.Tests/Rule/snapshots/ContextAwareGenerator/MyRule.ContextAware.g.cs b/GFramework.SourceGenerators.Tests/Rule/snapshots/ContextAwareGenerator/MyRule.ContextAware.g.cs index 54df8881..ea081e93 100644 --- a/GFramework.SourceGenerators.Tests/Rule/snapshots/ContextAwareGenerator/MyRule.ContextAware.g.cs +++ b/GFramework.SourceGenerators.Tests/Rule/snapshots/ContextAwareGenerator/MyRule.ContextAware.g.cs @@ -3,10 +3,14 @@ namespace TestApp; +/// +/// 为当前规则类型补充自动生成的架构上下文访问实现。 +/// partial class MyRule : global::GFramework.Core.Abstractions.Rule.IContextAware { private global::GFramework.Core.Abstractions.Architectures.IArchitectureContext? _context; private static global::GFramework.Core.Abstractions.Architectures.IArchitectureContextProvider? _contextProvider; + private static readonly object _contextSync = new(); /// /// 自动获取的架构上下文(懒加载,默认使用 GameContextProvider) @@ -15,13 +19,19 @@ partial class MyRule : global::GFramework.Core.Abstractions.Rule.IContextAware { get { - if (_context == null) + var context = _context; + if (context is not null) { - _contextProvider ??= new global::GFramework.Core.Architectures.GameContextProvider(); - _context = _contextProvider.GetContext(); + return context; } - return _context; + // 在同一个同步域内协调懒加载与 provider 切换,避免读取到被并发重置的空提供者。 + lock (_contextSync) + { + _contextProvider ??= new global::GFramework.Core.Architectures.GameContextProvider(); + _context ??= _contextProvider.GetContext(); + return _context; + } } } @@ -31,7 +41,10 @@ partial class MyRule : global::GFramework.Core.Abstractions.Rule.IContextAware /// 上下文提供者实例 public static void SetContextProvider(global::GFramework.Core.Abstractions.Architectures.IArchitectureContextProvider provider) { - _contextProvider = provider; + lock (_contextSync) + { + _contextProvider = provider; + } } /// @@ -39,7 +52,10 @@ partial class MyRule : global::GFramework.Core.Abstractions.Rule.IContextAware /// public static void ResetContextProvider() { - _contextProvider = null; + lock (_contextSync) + { + _contextProvider = null; + } } void global::GFramework.Core.Abstractions.Rule.IContextAware.SetContext(global::GFramework.Core.Abstractions.Architectures.IArchitectureContext context) @@ -52,4 +68,4 @@ partial class MyRule : global::GFramework.Core.Abstractions.Rule.IContextAware return Context; } -} \ No newline at end of file +}