diff --git a/GFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorTests.cs b/GFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorTests.cs index b5895819..51c2c766 100644 --- a/GFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorTests.cs +++ b/GFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorTests.cs @@ -6,6 +6,67 @@ namespace GFramework.SourceGenerators.Tests.Config; [TestFixture] public class SchemaConfigGeneratorTests { + // Keep shared fixture sources at class scope so MA0051 reduction does not change generator inputs. + private const string DummySource = """ + namespace TestApp + { + public sealed class Dummy + { + } + } + """; + + // These runtime contracts mirror the minimal consumer surface the generator expects when emitting registration helpers. + private const string ConfigRuntimeSource = """ + using System; + using System.Collections.Generic; + + namespace GFramework.Game.Abstractions.Config + { + public interface IConfigTable + { + Type KeyType { get; } + Type ValueType { get; } + int Count { get; } + } + + public interface IConfigTable : IConfigTable + where TKey : notnull + { + TValue Get(TKey key); + bool TryGet(TKey key, out TValue? value); + bool ContainsKey(TKey key); + IReadOnlyCollection All(); + } + + public interface IConfigRegistry + { + IConfigTable GetTable(string name) + where TKey : notnull; + + bool TryGetTable(string name, out IConfigTable? table) + where TKey : notnull; + } + } + + namespace GFramework.Game.Config + { + public sealed class YamlConfigLoader + { + public YamlConfigLoader RegisterTable( + string tableName, + string relativePath, + string schemaRelativePath, + Func keySelector, + IEqualityComparer? comparer = null) + where TKey : notnull + { + return this; + } + } + } + """; + /// /// 验证 AdditionalFiles 读取被取消时会向上传播取消,而不是伪造成 schema 诊断。 /// @@ -1404,15 +1465,6 @@ public class SchemaConfigGeneratorTests [Test] public void Run_Should_Write_IfThenElse_Constraint_Into_Generated_Documentation() { - const string source = """ - namespace TestApp - { - public sealed class Dummy - { - } - } - """; - const string schema = """ { "type": "object", @@ -1454,19 +1506,9 @@ public class SchemaConfigGeneratorTests } """; - var result = SchemaGeneratorTestDriver.Run( - source, + var generatedSources = RunAndCollectGeneratedSources( + DummySource, ("monster.schema.json", schema)); - - var generatedSources = result.Results - .Single() - .GeneratedSources - .ToDictionary( - static sourceResult => sourceResult.HintName, - static sourceResult => sourceResult.SourceText.ToString(), - StringComparer.Ordinal); - - Assert.That(result.Results.Single().Diagnostics, Is.Empty); Assert.That( generatedSources["MonsterConfig.g.cs"], Does.Contain( @@ -2024,56 +2066,6 @@ public class SchemaConfigGeneratorTests [Test] public void Run_Should_Use_Custom_Config_Path_Metadata_For_Generated_Registration() { - const string source = """ - using System; - using System.Collections.Generic; - - namespace GFramework.Game.Abstractions.Config - { - public interface IConfigTable - { - Type KeyType { get; } - Type ValueType { get; } - int Count { get; } - } - - public interface IConfigTable : IConfigTable - where TKey : notnull - { - TValue Get(TKey key); - bool TryGet(TKey key, out TValue? value); - bool ContainsKey(TKey key); - IReadOnlyCollection All(); - } - - public interface IConfigRegistry - { - IConfigTable GetTable(string name) - where TKey : notnull; - - bool TryGetTable(string name, out IConfigTable? table) - where TKey : notnull; - } - } - - namespace GFramework.Game.Config - { - public sealed class YamlConfigLoader - { - public YamlConfigLoader RegisterTable( - string tableName, - string relativePath, - string schemaRelativePath, - Func keySelector, - IEqualityComparer? comparer = null) - where TKey : notnull - { - return this; - } - } - } - """; - const string schema = """ { "type": "object", @@ -2086,19 +2078,9 @@ public class SchemaConfigGeneratorTests } """; - var result = SchemaGeneratorTestDriver.Run( - source, + var generatedSources = RunAndCollectGeneratedSources( + ConfigRuntimeSource, ("monster.schema.json", schema)); - - var generatedSources = result.Results - .Single() - .GeneratedSources - .ToDictionary( - static sourceResult => sourceResult.HintName, - static sourceResult => sourceResult.SourceText.ToString(), - StringComparer.Ordinal); - - Assert.That(result.Results.Single().Diagnostics, Is.Empty); Assert.That(generatedSources["MonsterConfigBindings.g.cs"], Does.Contain("public const string ConfigRelativePath = \"config/monster\";")); Assert.That(generatedSources["MonsterConfigBindings.g.cs"], Does.Contain("Metadata.ConfigRelativePath,")); @@ -2126,56 +2108,6 @@ public class SchemaConfigGeneratorTests [Test] public void Run_Should_Skip_Runtime_Null_Keys_When_Generating_Indexed_Lookups() { - const string source = """ - using System; - using System.Collections.Generic; - - namespace GFramework.Game.Abstractions.Config - { - public interface IConfigTable - { - Type KeyType { get; } - Type ValueType { get; } - int Count { get; } - } - - public interface IConfigTable : IConfigTable - where TKey : notnull - { - TValue Get(TKey key); - bool TryGet(TKey key, out TValue? value); - bool ContainsKey(TKey key); - IReadOnlyCollection All(); - } - - public interface IConfigRegistry - { - IConfigTable GetTable(string name) - where TKey : notnull; - - bool TryGetTable(string name, out IConfigTable? table) - where TKey : notnull; - } - } - - namespace GFramework.Game.Config - { - public sealed class YamlConfigLoader - { - public YamlConfigLoader RegisterTable( - string tableName, - string relativePath, - string schemaRelativePath, - Func keySelector, - IEqualityComparer? comparer = null) - where TKey : notnull - { - return this; - } - } - } - """; - const string schema = """ { "type": "object", @@ -2190,19 +2122,9 @@ public class SchemaConfigGeneratorTests } """; - var result = SchemaGeneratorTestDriver.Run( - source, + var generatedSources = RunAndCollectGeneratedSources( + ConfigRuntimeSource, ("monster.schema.json", schema)); - - var generatedSources = result.Results - .Single() - .GeneratedSources - .ToDictionary( - static sourceResult => sourceResult.HintName, - static sourceResult => sourceResult.SourceText.ToString(), - StringComparer.Ordinal); - - Assert.That(result.Results.Single().Diagnostics, Is.Empty); Assert.That(generatedSources["MonsterTable.g.cs"], Does.Contain("if (key is null)")); Assert.That(generatedSources["MonsterTable.g.cs"], Does.Contain("Throwing here would permanently poison the cached index for this wrapper instance.")); @@ -2391,56 +2313,6 @@ public class SchemaConfigGeneratorTests [Test] public void Run_Should_Allow_Lookup_Index_For_Direct_Root_Property_With_Dotted_Schema_Key() { - const string source = """ - using System; - using System.Collections.Generic; - - namespace GFramework.Game.Abstractions.Config - { - public interface IConfigTable - { - Type KeyType { get; } - Type ValueType { get; } - int Count { get; } - } - - public interface IConfigTable : IConfigTable - where TKey : notnull - { - TValue Get(TKey key); - bool TryGet(TKey key, out TValue? value); - bool ContainsKey(TKey key); - IReadOnlyCollection All(); - } - - public interface IConfigRegistry - { - IConfigTable GetTable(string name) - where TKey : notnull; - - bool TryGetTable(string name, out IConfigTable? table) - where TKey : notnull; - } - } - - namespace GFramework.Game.Config - { - public sealed class YamlConfigLoader - { - public YamlConfigLoader RegisterTable( - string tableName, - string relativePath, - string schemaRelativePath, - Func keySelector, - IEqualityComparer? comparer = null) - where TKey : notnull - { - return this; - } - } - } - """; - const string schema = """ { "type": "object", @@ -2455,19 +2327,9 @@ public class SchemaConfigGeneratorTests } """; - var result = SchemaGeneratorTestDriver.Run( - source, + var generatedSources = RunAndCollectGeneratedSources( + ConfigRuntimeSource, ("monster.schema.json", schema)); - - var generatedSources = result.Results - .Single() - .GeneratedSources - .ToDictionary( - static sourceResult => sourceResult.HintName, - static sourceResult => sourceResult.SourceText.ToString(), - StringComparer.Ordinal); - - Assert.That(result.Results.Single().Diagnostics, Is.Empty); Assert.That(generatedSources["MonsterTable.g.cs"], Does.Contain("FindByDisplayName(string value)")); Assert.That(generatedSources["MonsterTable.g.cs"], Does.Contain("_displayNameIndex")); } @@ -2478,56 +2340,6 @@ public class SchemaConfigGeneratorTests [Test] public void Run_Should_Assign_Globally_Unique_Reference_Metadata_Member_Names() { - const string source = """ - using System; - using System.Collections.Generic; - - namespace GFramework.Game.Abstractions.Config - { - public interface IConfigTable - { - Type KeyType { get; } - Type ValueType { get; } - int Count { get; } - } - - public interface IConfigTable : IConfigTable - where TKey : notnull - { - TValue Get(TKey key); - bool TryGet(TKey key, out TValue? value); - bool ContainsKey(TKey key); - IReadOnlyCollection All(); - } - - public interface IConfigRegistry - { - IConfigTable GetTable(string name) - where TKey : notnull; - - bool TryGetTable(string name, out IConfigTable? table) - where TKey : notnull; - } - } - - namespace GFramework.Game.Config - { - public sealed class YamlConfigLoader - { - public YamlConfigLoader RegisterTable( - string tableName, - string relativePath, - string schemaRelativePath, - Func keySelector, - IEqualityComparer? comparer = null) - where TKey : notnull - { - return this; - } - } - } - """; - const string schema = """ { "type": "object", @@ -2561,19 +2373,9 @@ public class SchemaConfigGeneratorTests } """; - var result = SchemaGeneratorTestDriver.Run( - source, + var generatedSources = RunAndCollectGeneratedSources( + ConfigRuntimeSource, ("monster.schema.json", schema)); - - var generatedSources = result.Results - .Single() - .GeneratedSources - .ToDictionary( - static sourceResult => sourceResult.HintName, - static sourceResult => sourceResult.SourceText.ToString(), - StringComparer.Ordinal); - - Assert.That(result.Results.Single().Diagnostics, Is.Empty); Assert.That(generatedSources.TryGetValue("MonsterConfigBindings.g.cs", out var bindingsSource), Is.True); Assert.That(bindingsSource, Does.Contain("public static readonly ReferenceMetadata DropItems =")); Assert.That(bindingsSource, Does.Contain("public static readonly ReferenceMetadata DropItems1 =")); @@ -2588,56 +2390,6 @@ public class SchemaConfigGeneratorTests [Test] public void Run_Should_Generate_Query_Helpers_Only_For_Top_Level_Scalar_Properties() { - const string source = """ - using System; - using System.Collections.Generic; - - namespace GFramework.Game.Abstractions.Config - { - public interface IConfigTable - { - Type KeyType { get; } - Type ValueType { get; } - int Count { get; } - } - - public interface IConfigTable : IConfigTable - where TKey : notnull - { - TValue Get(TKey key); - bool TryGet(TKey key, out TValue? value); - bool ContainsKey(TKey key); - IReadOnlyCollection All(); - } - - public interface IConfigRegistry - { - IConfigTable GetTable(string name) - where TKey : notnull; - - bool TryGetTable(string name, out IConfigTable? table) - where TKey : notnull; - } - } - - namespace GFramework.Game.Config - { - public sealed class YamlConfigLoader - { - public YamlConfigLoader RegisterTable( - string tableName, - string relativePath, - string schemaRelativePath, - Func keySelector, - IEqualityComparer? comparer = null) - where TKey : notnull - { - return this; - } - } - } - """; - const string schema = """ { "type": "object", @@ -2667,19 +2419,9 @@ public class SchemaConfigGeneratorTests } """; - var result = SchemaGeneratorTestDriver.Run( - source, + var generatedSources = RunAndCollectGeneratedSources( + ConfigRuntimeSource, ("monster.schema.json", schema)); - - var generatedSources = result.Results - .Single() - .GeneratedSources - .ToDictionary( - static sourceResult => sourceResult.HintName, - static sourceResult => sourceResult.SourceText.ToString(), - StringComparer.Ordinal); - - Assert.That(result.Results.Single().Diagnostics, Is.Empty); Assert.That(generatedSources.TryGetValue("MonsterTable.g.cs", out var tableSource), Is.True); Assert.Multiple(() => @@ -2713,56 +2455,6 @@ public class SchemaConfigGeneratorTests [Test] public void Run_Should_Generate_Project_Level_Registration_Catalog() { - const string source = """ - using System; - using System.Collections.Generic; - - namespace GFramework.Game.Abstractions.Config - { - public interface IConfigTable - { - Type KeyType { get; } - Type ValueType { get; } - int Count { get; } - } - - public interface IConfigTable : IConfigTable - where TKey : notnull - { - TValue Get(TKey key); - bool TryGet(TKey key, out TValue? value); - bool ContainsKey(TKey key); - IReadOnlyCollection All(); - } - - public interface IConfigRegistry - { - IConfigTable GetTable(string name) - where TKey : notnull; - - bool TryGetTable(string name, out IConfigTable? table) - where TKey : notnull; - } - } - - namespace GFramework.Game.Config - { - public sealed class YamlConfigLoader - { - public YamlConfigLoader RegisterTable( - string tableName, - string relativePath, - string schemaRelativePath, - Func keySelector, - IEqualityComparer? comparer = null) - where TKey : notnull - { - return this; - } - } - } - """; - const string monsterSchema = """ { "type": "object", @@ -2785,22 +2477,24 @@ public class SchemaConfigGeneratorTests } """; - var result = SchemaGeneratorTestDriver.Run( - source, + var generatedSources = RunAndCollectGeneratedSources( + ConfigRuntimeSource, ("monster.schema.json", monsterSchema), ("item.schema.json", itemSchema)); + if (!generatedSources.TryGetValue("GeneratedConfigCatalog.g.cs", out var catalogSource)) + { + Assert.Fail("Expected GeneratedConfigCatalog.g.cs to be generated."); + } - var generatedSources = result.Results - .Single() - .GeneratedSources - .ToDictionary( - static sourceResult => sourceResult.HintName, - static sourceResult => sourceResult.SourceText.ToString(), - StringComparer.Ordinal); - - Assert.That(result.Results.Single().Diagnostics, Is.Empty); - Assert.That(generatedSources.TryGetValue("GeneratedConfigCatalog.g.cs", out var catalogSource), Is.True); + AssertGeneratedRegistrationCatalogContract(catalogSource!); + } + /// + /// 断言聚合注册目录保留筛选选项、比较器透传和按条件注册的生成契约。 + /// + /// `GeneratedConfigCatalog.g.cs` 的生成源码。 + private static void AssertGeneratedRegistrationCatalogContract(string catalogSource) + { Assert.Multiple(() => { Assert.That(catalogSource, Does.Contain("public static class GeneratedConfigCatalog")); @@ -2852,4 +2546,24 @@ public class SchemaConfigGeneratorTests Assert.That(catalogSource, Does.Contain("private static bool MatchesOptionalAllowList(")); }); } + + /// + /// 运行 schema 生成器并收集生成输出,同时断言本次场景不产生诊断。 + /// + /// 测试输入源码。 + /// 参与本次生成的 schema 文件集合。 + /// 按 HintName 索引的生成源码字典。 + private static global::System.Collections.Generic.IReadOnlyDictionary RunAndCollectGeneratedSources( + string source, + params (string path, string content)[] additionalFiles) + { + var result = SchemaGeneratorTestDriver.Run(source, additionalFiles); + var runResult = result.Results.Single(); + Assert.That(runResult.Diagnostics, Is.Empty); + + return runResult.GeneratedSources.ToDictionary( + static sourceResult => sourceResult.HintName, + static sourceResult => sourceResult.SourceText.ToString(), + StringComparer.Ordinal); + } } diff --git a/ai-plan/public/analyzer-warning-reduction/todos/analyzer-warning-reduction-tracking.md b/ai-plan/public/analyzer-warning-reduction/todos/analyzer-warning-reduction-tracking.md index 496f4465..06034cb3 100644 --- a/ai-plan/public/analyzer-warning-reduction/todos/analyzer-warning-reduction-tracking.md +++ b/ai-plan/public/analyzer-warning-reduction/todos/analyzer-warning-reduction-tracking.md @@ -7,9 +7,27 @@ ## 当前恢复点 -- 恢复点编号:`ANALYZER-WARNING-REDUCTION-RP-034` -- 当前阶段:`Phase 34` +- 恢复点编号:`ANALYZER-WARNING-REDUCTION-RP-036` +- 当前阶段:`Phase 36` - 当前焦点: + - 已完成 `GFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorTests.cs` 的 `MA0051` 收口: + 将共享 consumer runtime fixture 提取到类级常量,并把生成结果收集与 catalog 契约断言拆成小 helper, + 保持 schema 文本、断言语义与生成输出契约不变 + - 当前 `GFramework.SourceGenerators.Tests` Release warnings-only 基线已从 `22` 条降到 `15` 条; + `SchemaConfigGeneratorTests.cs` 已不再出现在 `MA0051` 列表中,剩余热点全部集中在 + `CqrsHandlerRegistryGeneratorTests.cs` + - 已完成 `SchemaConfigGeneratorTests` 定向验证:串行重跑 `50` 个用例全部通过;并确认先前并行 build/test + 触发的 `MSB3030` / `CS0006` 属于共享输出竞争噪音,不是代码回归 + - 已按 `gframework-boot` 重新恢复当前 worktree:确认分支 `fix/analyzer-warning-reduction-batch` 仍映射到 + `analyzer-warning-reduction`,且当前不存在 `ai-plan/private/` 私有恢复上下文 + - 已重新抓取当前分支关联的 PR #273 review 状态:PR 已处于 `CLOSED`,latest-head review 仍显示 `2` 条 + CodeRabbit open thread,但本地复核后 `GeneratorSnapshotTest` 的 snapshot 路径空值防御已显式改为 + `InvalidOperationException` 防御,`SchemaConfigGenerator` 的 `dependentSchemas` / `allOf` / conditional helper + 也已补齐 XML 文档,当前更像历史线程未随已关闭 PR 一起收敛 + - 已重新以 `GFramework.SourceGenerators.Tests` Release warnings-only build 复核当前 `MA0051` 热点: + 基线现为 `22` 条,且已不再落在 `GeneratorSnapshotTest`、`ContextRegistrationAnalyzerTests` 或 + `ContextGetGeneratorTests`,而是集中在 `CqrsHandlerRegistryGeneratorTests.cs`(`15` 条)与 + `SchemaConfigGeneratorTests.cs`(`7` 条) - 已完成 `GFramework.Core` 当前 `MA0016` / `MA0002` / `MA0015` / `MA0077` 低风险收口批次 - 已复核 `net10.0` 下的 `MA0158` 基线:`GFramework.Core` / `GFramework.Cqrs` 当前共有 `16` 个 object lock 建议点,属于跨 target 兼容性风险,不在本轮直接批量替换 @@ -124,6 +142,11 @@ `40` 条,并通过 focused generator tests 保持输出契约不变 - 已完成 `SchemaConfigGeneratorSnapshotTests` 的单文件 `MA0051` 收口;当前 `GFramework.SourceGenerators.Tests` Release build 基线已降到 `39` 条,并通过 focused snapshot test 保持生成输出契约不变 +- 已完成 `RP-035` 启动复核:确认 PR #273 已关闭、历史 open thread 暂无新的本地修复点,且 + `GFramework.SourceGenerators.Tests` 当前剩余 `MA0051` 已重排为 `CqrsHandlerRegistryGeneratorTests` / + `SchemaConfigGeneratorTests` 两个测试写集 +- 已完成 `RP-036`:清空 `SchemaConfigGeneratorTests.cs` 当前 `MA0051`,并将 + `GFramework.SourceGenerators.Tests` Release warnings-only 基线进一步降到 `15` 条 ## 当前活跃事实 @@ -168,6 +191,12 @@ 生成文件名、断言路径与源生成输出不变;`GFramework.SourceGenerators.Tests` warnings-only 基线由 `43` 降至 `40` - `RP-033` 已完成 `SchemaConfigGeneratorSnapshotTests` 的 `MA0051` 收口:monster schema 运行时契约与 schema 输入已提取为 类级常量,生成结果映射与快照目录解析已拆为小 helper;`GFramework.SourceGenerators.Tests` warnings-only 基线由 `40` 降至 `39` +- `RP-035` 已完成启动级恢复核对:当前分支对应的 GitHub PR #273 已关闭,因此 remaining open thread 仅作为历史信号参考; + 下一轮应以本地 `warnings-only` build 的实时热点为主,而不是继续按已过时的 `GeneratorSnapshotTest` / + `ContextRegistrationAnalyzerTests` 建议恢复 +- `RP-036` 已完成 `SchemaConfigGeneratorTests` 的单文件 `MA0051` 收口:共享 runtime fixture、 + generated-source 收集与 catalog 契约断言均已拆出 helper;当前测试项目剩余 `MA0051` 已全部收敛到 + `CqrsHandlerRegistryGeneratorTests` - `RP-021` 使用 `$gframework-pr-review` 复核当前分支 PR #269 后,修复仍在本地成立的 4 个项:将 `CqrsHandlerRegistryGenerator` 拆分为职责清晰的 partial 文件、为 `ContextAwareGenerator` 生成字段增加稳定前缀并补上 `SetContextProvider` 的运行时 null 校验、为 `Option` 补齐 ``,并新增字段重名场景的生成器快照测试 @@ -389,13 +418,27 @@ - 结果:`39 Warning(s)`,`0 Error(s)`;`SchemaConfigGeneratorSnapshotTests.cs` 已不再出现在 `MA0051` 列表中 - `dotnet test GFramework.SourceGenerators.Tests/GFramework.SourceGenerators.Tests.csproj -c Release --no-build --disable-build-servers --filter FullyQualifiedName~SchemaConfigGeneratorSnapshotTests -m:1 -p:RestoreFallbackFolders="" -nologo` - 结果:`1 Passed`,`0 Failed` +- `RP-035` 的验证结果: + - `python3 .agents/skills/gframework-pr-review/scripts/fetch_current_pr_review.py --json-output /tmp/current-pr-review.json` + - 结果:成功定位当前分支关联的 `PR #273`;状态为 `CLOSED`,latest-head review threads 仍显示 `2` 条 open thread, + test report 均为通过,MegaLinter 仅保留 docstring coverage / `dotnet-format` 历史信号 + - `dotnet build GFramework.SourceGenerators.Tests/GFramework.SourceGenerators.Tests.csproj -c Release -t:Rebuild --no-restore --disable-build-servers -m:1 -p:UseSharedCompilation=false -p:RestoreFallbackFolders="" -nologo -clp:"Summary;WarningsOnly"` + - 结果:`22 Warning(s)`,`0 Error(s)`;剩余 `MA0051` 全部集中在 `CqrsHandlerRegistryGeneratorTests.cs` 与 + `SchemaConfigGeneratorTests.cs` +- `RP-036` 的验证结果: + - `dotnet restore GFramework.SourceGenerators.Tests/GFramework.SourceGenerators.Tests.csproj -p:RestoreFallbackFolders="" -nologo` + - 结果:通过;刷新测试依赖输出,规避 `--no-build` 场景下的缺包噪音 + - `dotnet build GFramework.SourceGenerators.Tests/GFramework.SourceGenerators.Tests.csproj -c Release -t:Rebuild --no-restore --disable-build-servers -m:1 -p:UseSharedCompilation=false -p:RestoreFallbackFolders="" -nologo -clp:"Summary;WarningsOnly"` + - 结果:`15 Warning(s)`,`0 Error(s)`;`SchemaConfigGeneratorTests.cs` 已不再出现在 `MA0051` 列表中 + - `dotnet test GFramework.SourceGenerators.Tests/GFramework.SourceGenerators.Tests.csproj -c Release --no-build --disable-build-servers --filter FullyQualifiedName~SchemaConfigGeneratorTests -m:1 -p:RestoreFallbackFolders="" -nologo` + - 结果:`50 Passed`,`0 Failed` - active 跟踪文件只保留当前恢复点、活跃事实、风险与下一步,不再重复保存已完成阶段的长篇历史 ## 下一步 1. 若要继续该主题,先读 active tracking,再按需展开历史归档中的 warning 热点与验证记录 -2. 下一轮优先继续 `GFramework.SourceGenerators.Tests` 的 `MA0051` 收口,先在 `GeneratorSnapshotTest`、 - `ContextRegistrationAnalyzerTests` 或 `ContextGetGeneratorTests` 中选择一个单写集推进,不再把已清零的 `MA0004` / `MA0048` 混回写集 +2. 下一轮优先继续 `GFramework.SourceGenerators.Tests` 的 `MA0051` 收口,并直接进入唯一剩余热点 + `CqrsHandlerRegistryGeneratorTests.cs` 3. 若改回推进 `MA0158`,先设计 `net8.0` / `net9.0` / `net10.0` 多 target 条件编译方案,不直接批量替换共享源码中的 `object` lock 4. 若后续继续改动 `GFramework.Godot`,先修复该项目的 Linux 侧 restore 资产,再补跑独立 build diff --git a/ai-plan/public/analyzer-warning-reduction/traces/analyzer-warning-reduction-trace.md b/ai-plan/public/analyzer-warning-reduction/traces/analyzer-warning-reduction-trace.md index 620d2928..fd20b9a3 100644 --- a/ai-plan/public/analyzer-warning-reduction/traces/analyzer-warning-reduction-trace.md +++ b/ai-plan/public/analyzer-warning-reduction/traces/analyzer-warning-reduction-trace.md @@ -1,5 +1,60 @@ # Analyzer Warning Reduction 追踪 +## 2026-04-23 — RP-036 + +### 阶段:`SchemaConfigGeneratorTests.cs` `MA0051` 收口(RP-036) + +- 启动复核: + - 依据 `RP-035` 的恢复结论,选择低风险单写集 `GFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorTests.cs` + 继续推进,而不直接跳入剩余 warning 数量更多的 `CqrsHandlerRegistryGeneratorTests.cs` + - 先用 `dotnet build ... -clp:"Summary;WarningsOnly"` 复核当前热点,确认该文件仍承担 `7` 条 `MA0051` +- 决策: + - 保持全部 schema 文本、断言字符串和生成文件名不变,只收敛测试方法结构 + - 将共享 consumer runtime fixture 提到类级常量,并把 generated-source 收集与 registration catalog 契约断言 + 抽成 helper,避免重复内联样板把测试方法重新撑长 + - 继续避免并行运行同一测试项目的 build/test;该 worktree 下并发验证会触发 `MSB3030` / `CS0006` 级别的输出竞争噪音 +- 实施调整: + - 为 `SchemaConfigGeneratorTests` 新增 `DummySource` 与 `ConfigRuntimeSource` 类级常量 + - 新增 `RunAndCollectGeneratedSources(...)` 与 `AssertGeneratedRegistrationCatalogContract(...)` helper + - 将 `if/then/else` 文档、config path、lookup index、reference metadata、query helper 与 project-level catalog + 等长测试方法切换为复用共享 fixture / helper +- 验证结果: + - `dotnet restore GFramework.SourceGenerators.Tests/GFramework.SourceGenerators.Tests.csproj -p:RestoreFallbackFolders="" -nologo` + - 结果:通过 + - `dotnet build GFramework.SourceGenerators.Tests/GFramework.SourceGenerators.Tests.csproj -c Release -t:Rebuild --no-restore --disable-build-servers -m:1 -p:UseSharedCompilation=false -p:RestoreFallbackFolders="" -nologo -clp:"Summary;WarningsOnly"` + - 结果:`15 Warning(s)`,`0 Error(s)`;`SchemaConfigGeneratorTests.cs` 已不再出现在 `MA0051` 列表中 + - `dotnet test GFramework.SourceGenerators.Tests/GFramework.SourceGenerators.Tests.csproj -c Release --no-build --disable-build-servers --filter FullyQualifiedName~SchemaConfigGeneratorTests -m:1 -p:RestoreFallbackFolders="" -nologo` + - 结果:`50 Passed`,`0 Failed` +- 下一步建议: + - 继续进入 `GFramework.SourceGenerators.Tests/Cqrs/CqrsHandlerRegistryGeneratorTests.cs`,这是当前项目唯一剩余 `MA0051` 热点 + - 若需要再次做定向测试,保持串行执行,避免把共享输出竞争误判成实现回退 + +## 2026-04-23 — RP-035 + +### 阶段:`boot` 恢复点重建与实时热点复核(RP-035) + +- 启动复核: + - 按 `gframework-boot` 流程读取 `AGENTS.md`、`.ai/environment/tools.ai.yaml`、`ai-plan/public/README.md` + 与 `analyzer-warning-reduction` active tracking / trace,确认当前 worktree `GFramework-analyzer` + 仍对应分支 `fix/analyzer-warning-reduction-batch` + - 额外检查 `ai-plan/private/`,确认当前 worktree 没有私有恢复上下文需要合并 + - 使用 `gframework-pr-review` 脚本抓取当前分支关联 PR,确认 `PR #273` 已为 `CLOSED` +- 决策: + - 不再把已关闭 PR 上残留的 open thread 直接当作下一轮主驱动信号;先以当前本地代码和实时 build 结果判断问题是否仍成立 + - 将后续恢复入口从“继续看 `GeneratorSnapshotTest` / `ContextRegistrationAnalyzerTests`”切回 + “重新跑 `warnings-only` build 后按真实热点推进” +- 现场结论: + - `GeneratorSnapshotTest` 中关于 snapshot 路径的 `Path.GetDirectoryName(...)` 已改为显式空值防御, + 相关 CodeRabbit 线程更像历史残留 + - `SchemaConfigGenerator` 在 `dependentSchemas` / `allOf` / conditional schema 校验 helper 周围已经补齐 XML 文档, + 当前也没有新的本地缺口需要仅为关闭旧线程而继续改动 + - `dotnet build GFramework.SourceGenerators.Tests/GFramework.SourceGenerators.Tests.csproj -c Release -t:Rebuild --no-restore --disable-build-servers -m:1 -p:UseSharedCompilation=false -p:RestoreFallbackFolders="" -nologo -clp:"Summary;WarningsOnly"` + 结果为 `22 Warning(s)`、`0 Error(s)`;剩余 `MA0051` 已集中到 + `CqrsHandlerRegistryGeneratorTests.cs`(`15` 条)与 `SchemaConfigGeneratorTests.cs`(`7` 条) +- 下一步建议: + - 若保持低风险单写集,先进入 `SchemaConfigGeneratorTests.cs` + - 若优先按 warning 数量收敛,则进入 `CqrsHandlerRegistryGeneratorTests.cs` + ## 2026-04-23 — RP-033 ### 阶段:`SchemaConfigGeneratorSnapshotTests.cs` `MA0051` 收口(RP-033)