Skip to content

docs(config): 添加游戏内容配置系统完整文档与验证工具实现#207

Merged
GeWuYou merged 3 commits into
mainfrom
feat/config-system-docs-and-validation
Apr 10, 2026
Merged

docs(config): 添加游戏内容配置系统完整文档与验证工具实现#207
GeWuYou merged 3 commits into
mainfrom
feat/config-system-docs-and-validation

Conversation

@GeWuYou

@GeWuYou GeWuYou commented Apr 10, 2026

Copy link
Copy Markdown
Owner
  • 新增游戏内容配置系统详细文档,涵盖 YAML 配置、JSON Schema 结构、目录组织等核心概念
  • 实现配置验证工具,支持运行时校验、类型检查、引用验证等功能
  • 提供完整的接入模板,包括项目结构、CSProj 配置、启动帮助器等推荐实践
  • 集成 VS Code 插件支持,提供配置浏览、表单编辑、递归校验等开发期工具能力
  • 实现热重载机制,支持开发期配置文件变更自动刷新运行时表
  • 添加详细的 Schema 示例和 YAML 示例,展示怪物、物品等游戏内容配置的实际应用
  • 提供 Architecture 接入模板,支持与现有架构的无缝集成
  • 实现跨表引用校验,确保配置数据的一致性和完整性

Summary by Sourcery

在 YAML 运行时验证器、Node.js 工具链、VS Code 扩展和源码生成器中新增对 JSON Schema const 约束的通用支持,并在游戏配置系统文档中记录这一新行为。

New Features:

  • 在 YAML 配置模式验证器中,为标量、数组和对象字段提供 JSON Schema const 约束支持,并在运行时强制执行和提供诊断信息。
  • 在 Node.js 配置工具链中暴露并消费 const 元数据,包括可比较键、可编辑值和本地化校验消息,并在 VS Code 表单编辑器中以类似默认值和提示的形式呈现。
  • 在生成的配置类型 XML 文档和快照输出中包含 const 约束信息。

Enhancements:

  • 统一标量关键字归一化逻辑,使 enumconst 在运行时和工具链中共享一致的比较语义。
  • 使用序号语义对可编辑的模式字段键和 object-const 键进行排序,以保持 C# 和 JavaScript 实现之间的一致性。
  • 扩展中文游戏配置系统文档,描述共享的 const 支持,以及它与运行时验证、工具和热重载工作流的交互方式。

Tests:

  • 新增完整的运行时测试,覆盖标量、数组和嵌套对象的 const 违反与匹配情况,包括空对象场景。
  • 为 Node.js 工具链新增测试,用于解析、归一化和验证 const 元数据,以及为由 const 支持的字段生成示例 YAML 和 UI 行为。
  • 更新源码生成器测试和快照,验证包括空字符串常量在内的 const 约束会被保留在生成的 XML 文档中。
Original summary in English

Summary by Sourcery

Add shared support for JSON Schema const constraints across the YAML runtime validator, Node.js tooling, VS Code extension, and source generator, and document the new behavior in the game config system docs.

New Features:

  • Support JSON Schema const constraints for scalar, array, and object fields in the YAML config schema validator with runtime enforcement and diagnostics.
  • Expose and consume const metadata in the Node.js config tooling, including comparable keys, editable values, and localized validation messages, and surface it in the VS Code form editor as default-like values and hints.
  • Include const constraint information in generated configuration type XML documentation and snapshot outputs.

Enhancements:

  • Unify scalar keyword normalization logic so enum and const share consistent comparison semantics in both runtime and tooling.
  • Sort editable schema field keys and object-const keys using ordinal semantics to stay aligned between C# and JavaScript implementations.
  • Extend Chinese game config system documentation to describe shared const support and how it interacts with runtime validation, tools, and hot-reload workflows.

Tests:

  • Add comprehensive runtime tests covering scalar, array, and nested object const violations and matches, including empty-object cases.
  • Add Node.js tooling tests for parsing, normalizing, and validating const metadata, as well as sample YAML generation and UI behavior for const-backed fields.
  • Update source generator tests and snapshots to verify that const constraints, including empty-string constants, are preserved in generated XML documentation.

新功能:

  • 在 YAML 运行时校验器中,为标量、数组和对象类型的配置字段提供 schema const 约束支持。
  • 在 Node.js 校验/工具层中暴露 const 元数据(包括 UI 提示和本地化诊断信息),并按照运行时比较语义一致地强制执行。
  • 在 VS Code 扩展的表单编辑器中,将 const 约束以默认字段值和可读性良好的提示形式呈现。
  • 在由 schema 源生成的配置类型 XML 文档中包含 const 约束信息。

增强改进:

  • 统一标量关键字归一化逻辑,使 enumconst 在运行时和工具中共享相同的比较语义。
  • 扩展游戏配置系统文档,记录共享的 const 支持,以及其在运行时、工具和热重载工作流中的行为。

测试:

  • 新增运行时测试,覆盖 YAML 配置中标量、数组和嵌套对象字段的 const 违规情况。
  • 新增工具测试,确保 schema 解析能捕获 const 元数据,并在标量、对象和数组常量不匹配时报告校验错误。
  • 更新源码生成器快照测试,以验证生成的配置文档中正确输出 const 约束。
Original summary in English

Summary by Sourcery

在 YAML 运行时验证器、Node.js 工具链、VS Code 扩展和源码生成器中新增对 JSON Schema const 约束的通用支持,并在游戏配置系统文档中记录这一新行为。

New Features:

  • 在 YAML 配置模式验证器中,为标量、数组和对象字段提供 JSON Schema const 约束支持,并在运行时强制执行和提供诊断信息。
  • 在 Node.js 配置工具链中暴露并消费 const 元数据,包括可比较键、可编辑值和本地化校验消息,并在 VS Code 表单编辑器中以类似默认值和提示的形式呈现。
  • 在生成的配置类型 XML 文档和快照输出中包含 const 约束信息。

Enhancements:

  • 统一标量关键字归一化逻辑,使 enumconst 在运行时和工具链中共享一致的比较语义。
  • 使用序号语义对可编辑的模式字段键和 object-const 键进行排序,以保持 C# 和 JavaScript 实现之间的一致性。
  • 扩展中文游戏配置系统文档,描述共享的 const 支持,以及它与运行时验证、工具和热重载工作流的交互方式。

Tests:

  • 新增完整的运行时测试,覆盖标量、数组和嵌套对象的 const 违反与匹配情况,包括空对象场景。
  • 为 Node.js 工具链新增测试,用于解析、归一化和验证 const 元数据,以及为由 const 支持的字段生成示例 YAML 和 UI 行为。
  • 更新源码生成器测试和快照,验证包括空字符串常量在内的 const 约束会被保留在生成的 XML 文档中。
Original summary in English

Summary by Sourcery

Add shared support for JSON Schema const constraints across the YAML runtime validator, Node.js tooling, VS Code extension, and source generator, and document the new behavior in the game config system docs.

New Features:

  • Support JSON Schema const constraints for scalar, array, and object fields in the YAML config schema validator with runtime enforcement and diagnostics.
  • Expose and consume const metadata in the Node.js config tooling, including comparable keys, editable values, and localized validation messages, and surface it in the VS Code form editor as default-like values and hints.
  • Include const constraint information in generated configuration type XML documentation and snapshot outputs.

Enhancements:

  • Unify scalar keyword normalization logic so enum and const share consistent comparison semantics in both runtime and tooling.
  • Sort editable schema field keys and object-const keys using ordinal semantics to stay aligned between C# and JavaScript implementations.
  • Extend Chinese game config system documentation to describe shared const support and how it interacts with runtime validation, tools, and hot-reload workflows.

Tests:

  • Add comprehensive runtime tests covering scalar, array, and nested object const violations and matches, including empty-object cases.
  • Add Node.js tooling tests for parsing, normalizing, and validating const metadata, as well as sample YAML generation and UI behavior for const-backed fields.
  • Update source generator tests and snapshots to verify that const constraints, including empty-string constants, are preserved in generated XML documentation.

Summary by CodeRabbit

  • 新功能
    • 配置系统、生成器与编辑器全面支持 JSON Schema const,表单提示与样例优先显示 const 值,生成文档/注释包含 const 描述。
  • 错误修复 / 验证
    • 运行时与编辑器会对 const 不匹配产生清晰诊断(含路径与差异);对象比对忽略字段顺序,数组保留顺序,标量按规范化规则比较。
  • 测试
    • 大量新增单元测试覆盖标量/数组/嵌套对象的正负案例及空对象/空字符串等边界。
  • 文档
    • 更新中文文档与本地化文本,说明 const 语义及跨工具一致性。

- 新增游戏内容配置系统详细文档,涵盖 YAML 配置、JSON Schema 结构、目录组织等核心概念
- 实现配置验证工具,支持运行时校验、类型检查、引用验证等功能
- 提供完整的接入模板,包括项目结构、CSProj 配置、启动帮助器等推荐实践
- 集成 VS Code 插件支持,提供配置浏览、表单编辑、递归校验等开发期工具能力
- 实现热重载机制,支持开发期配置文件变更自动刷新运行时表
- 添加详细的 Schema 示例和 YAML 示例,展示怪物、物品等游戏内容配置的实际应用
- 提供 Architecture 接入模板,支持与现有架构的无缝集成
- 实现跨表引用校验,确保配置数据的一致性和完整性
@sourcery-ai

sourcery-ai Bot commented Apr 10, 2026

Copy link
Copy Markdown

Reviewer's Guide

在 YAML 运行时验证器、Node.js 配置工具、VS Code 扩展、源码生成器和文档中新增对 JSON Schema const 的一等支持,包括一致的比较语义、诊断信息以及文档输出。

运行时 YAML const 校验失败的时序图

sequenceDiagram
    actor ConfigAuthor
    participant YamlConfigLoader
    participant YamlConfigSchemaValidator
    participant YamlConfigSchemaNode
    participant ConfigRegistry

    ConfigAuthor->>YamlConfigLoader: Call LoadAsync(registry)
    YamlConfigLoader->>YamlConfigSchemaValidator: Parse schema JSON
    YamlConfigSchemaValidator->>YamlConfigSchemaValidator: ParseConstantValue for field with const
    YamlConfigSchemaValidator->>YamlConfigSchemaNode: WithConstantValue(new YamlConfigConstantValue)
    YamlConfigLoader->>YamlConfigSchemaValidator: Validate YAML document

    loop For each YAML node
        YamlConfigSchemaValidator->>YamlConfigSchemaValidator: BuildComparableNodeValue(node, schemaNode)
        YamlConfigSchemaValidator->>YamlConfigSchemaValidator: ValidateConstantValue(tableName, yamlPath, displayPath, node, schemaNode)
        YamlConfigSchemaValidator-->>YamlConfigSchemaValidator: Compare with schemaNode.ConstantValue.ComparableValue
    end

    alt Comparable value matches const
        YamlConfigSchemaValidator-->>YamlConfigLoader: Node accepted
        YamlConfigLoader->>ConfigRegistry: Register row
        YamlConfigLoader-->>ConfigAuthor: LoadAsync completes
    else Comparable value does not match const
        YamlConfigSchemaValidator-->>YamlConfigLoader: Throw ConfigLoadException
        YamlConfigLoader-->>ConfigAuthor: LoadAsync faulted with ConfigLoadException
        ConfigAuthor-->>ConfigAuthor: Inspect message mentioning constant value
    end
Loading

YAML 模式常量值支持的类图

classDiagram
    class YamlConfigSchemaNode {
        +YamlConfigSchemaPropertyType NodeType
        +YamlConfigConstantValue ConstantValue
        +string SchemaPathHint
        +YamlConfigArrayConstraints ArrayConstraints
        +YamlConfigObjectConstraints ObjectConstraints
        +string ReferenceTableName
        +IReadOnlyCollection~string~ AllowedValues
        +YamlConfigSchemaNode WithReferenceTable(string referenceTableName)
        +YamlConfigSchemaNode WithConstantValue(YamlConfigConstantValue constantValue)
        +static YamlConfigSchemaNode CreateObject(IReadOnlyDictionary~string,YamlConfigSchemaNode~ properties, IReadOnlyCollection~string~ requiredProperties, YamlConfigObjectConstraints objectConstraints, string schemaPathHint)
        +static YamlConfigSchemaNode CreateArray(YamlConfigSchemaNode itemNode, YamlConfigArrayConstraints arrayConstraints, string schemaPathHint)
        +static YamlConfigSchemaNode CreateScalar(YamlConfigSchemaPropertyType nodeType, string referenceTableName, IReadOnlyCollection~string~ allowedValues, YamlConfigScalarConstraints constraints, string schemaPathHint)
    }

    class YamlConfigConstantValue {
        +YamlConfigConstantValue(string comparableValue, string displayValue)
        +string ComparableValue
        +string DisplayValue
    }

    class YamlConfigSchemaValidator {
        +YamlConfigSchemaNode ParseObjectNode(string tableName, string schemaPath, string propertyPath, JsonElement element)
        +YamlConfigSchemaNode ParseArrayNode(string tableName, string schemaPath, string propertyPath, JsonElement element)
        +YamlConfigSchemaNode CreateScalarNode(string tableName, string schemaPath, string propertyPath, JsonElement element, YamlConfigSchemaPropertyType nodeType, string referenceTableName)
        -YamlConfigConstantValue ParseConstantValue(string tableName, string schemaPath, string propertyPath, JsonElement element, YamlConfigSchemaNode schemaNode)
        -string BuildComparableConstantValue(string tableName, string schemaPath, string propertyPath, string keywordName, JsonElement element, YamlConfigSchemaNode schemaNode)
        -string BuildComparableConstantObjectValue(string tableName, string schemaPath, string propertyPath, string keywordName, JsonElement element, YamlConfigSchemaNode schemaNode)
        -string BuildComparableConstantArrayValue(string tableName, string schemaPath, string propertyPath, string keywordName, JsonElement element, YamlConfigSchemaNode schemaNode)
        -string BuildComparableConstantScalarValue(string tableName, string schemaPath, string propertyPath, string keywordName, JsonElement element, YamlConfigSchemaNode schemaNode)
        -string NormalizeKeywordScalarValue(string tableName, string schemaPath, string propertyPath, string keywordName, YamlConfigSchemaPropertyType expectedType, JsonElement item)
        -void ValidateConstantValue(string tableName, string yamlPath, string displayPath, YamlNode node, YamlConfigSchemaNode schemaNode)
        -string BuildComparableNodeValue(YamlNode node, YamlConfigSchemaNode schemaNode)
    }

    class NodeValidation {
        +string ReferenceTableName
        +IReadOnlyCollection~string~ AllowedValues
        +YamlConfigScalarConstraints Constraints
        +YamlConfigArrayConstraints ArrayConstraints
        +YamlConfigObjectConstraints ObjectConstraints
        +YamlConfigConstantValue ConstantValue
        +NodeValidation WithReferenceTable(string referenceTableName)
        +NodeValidation WithConstantValue(YamlConfigConstantValue constantValue)
    }

    YamlConfigSchemaNode o-- NodeValidation : encapsulates
    YamlConfigSchemaNode o-- YamlConfigConstantValue : holds
    YamlConfigSchemaValidator ..> YamlConfigSchemaNode : creates and validates
    YamlConfigSchemaValidator ..> YamlConfigConstantValue : parses
    YamlConfigSchemaValidator ..> NodeValidation : uses
Loading

Node.js 工具链中 const 元数据与校验的流程图

flowchart TD
    A[Load JSON Schema file] --> B[parseSchemaNode for root]
    B --> C[For each property
parseSchemaNode]
    C --> D[applyConstMetadata
with raw const]
    D --> E[formatSchemaConstEditableValue
-> constValue]
    D --> F[formatSchemaConstDisplayValue
-> constDisplayValue]
    D --> G[buildSchemaConstComparableValue
-> constComparableValue]

    G --> G1{schemaNode.type}
    G1 -->|object| H[buildSchemaConstObjectComparableValue
validate shape
normalize child values
sort keys
join key=value segments]
    G1 -->|array| I[buildSchemaConstArrayComparableValue
validate array
normalize each item
preserve order]
    G1 -->|scalar| J[buildSchemaConstScalarComparableValue
normalizeSchemaConstScalarValue
prefix with type and length]

    E --> K[SchemaNode has
constValue]
    F --> K
    G --> K

    subgraph Validation
        L[validateNode
per YAML node] --> M[validateConstComparableValue]
        M --> N{schemaNode.constComparableValue
is defined}
        N -->|no| O[Skip const check]
        N -->|yes| P[buildComparableNodeValue
for YAML node]
        P --> Q{comparable equal
schema vs YAML}
        Q -->|yes| R[Accept node]
        Q -->|no| S[Push diagnostic
ValidationMessageKeys.constMismatch
with constDisplayValue or constValue]
    end

    K --> L

    subgraph VS_Code_Form
        T[collectFormFields / collectObjectArrayItemFields]
        T --> U[getScalarFieldValue
uses constValue or defaultValue]
        T --> V[renderFieldHint]
        V --> W[webview.hint.const /
webview.hint.itemConst
using constDisplayValue]
    end

    K --> T
Loading

文件级变更

Change Details Files
运行时 YAML 验证器现在会解析、规范化并强制执行标量、数组和对象节点上的 JSON Schema const 约束,使用统一的可比键机制。
  • 增强对象、数组和标量模式节点的创建逻辑,从 JSON Schema 的 const 元素中解析并附加构建好的 YamlConfigConstantValue。
  • 引入 BuildComparableConstantValue 帮助方法,用于对象、数组和标量,将 const 值规范化为稳定的比较键,并与 BuildComparableNodeValue 的语义保持一致(对象键顺序无关,数组保持顺序,标量按类型规范化)。
  • 新增 ValidateConstantValue,用于将运行时 YAML 节点与模式中的 const 可比值进行比较,在不匹配时抛出带有丰富诊断信息的 ConfigLoadException。
  • 通过用通用的 NormalizeKeywordScalarValue 替换 NormalizeEnumValue 来统一 enum 和 const 标量的规范化逻辑,该方法同时服务于这两个关键字。
  • 扩展 YamlConfigSchemaNode 及其内部验证状态以承载 ConstantValue,并提供 WithConstantValue,以不可变方式附加 const 元数据。
GFramework.Game/Config/YamlConfigSchemaValidator.cs
Node.js 配置验证/工具层会解析 const 元数据,对其进行比较用规范化,将其暴露给调用方,并在验证时强制执行 const,提供本地化诊断信息。
  • 新增 compareStringsOrdinal,以镜像 C# 的 string.CompareOrdinal,从而实现一致的键排序。
  • 扩展 parseSchemaNode 以读取 value.const,通过 applyConstMetadata 构建 constValue/constDisplayValue/constComparableValue,并将它们附加到标量、数组和对象类型的 SchemaNode 上。
  • 引入 buildSchemaConstComparableValue 及对象/数组/标量的辅助函数,将 const 值规范化为可比键,与运行时语义相匹配,包括通过 normalizeSchemaConstScalarValue 进行标量规范化。
  • 新增 validateConstComparableValue,在验证标量、数组和对象节点时检查 YAML 节点是否与 schemaNode.constComparableValue 匹配,并在不匹配时发出 ValidationMessageKeys.constMismatch 诊断信息。
  • 更新 buildComparableNodeValue,使对象键使用 ordinal 语义排序,从而让工具链比较结果与运行时一致,并在本地化键中新增 ValidationMessageKeys.constMismatch。
tools/gframework-config-tool/src/configValidation.js
tools/gframework-config-tool/src/localizationKeys.js
VS Code 扩展中的表单编辑器把 const 暴露为优先默认值,并为字段和数组项提供更易读的提示信息。
  • 更新表单字段收集逻辑,在计算已编辑字段值时,将 constValue 作为标量的首选回退值(优先于 defaultValue)。
  • 修改 getScalarFieldValue,使其使用模式提供的通用回退值(const 或 default),同时在 YAML 已提供标量值时保持现有行为。
  • 扩展 renderFieldHint,使用本地化字符串和 constDisplayValue/constValue 来展示 const 和 itemConst 提示,包括数组项的模式。
  • 在英文和中文消息映射中新增 const 提示相关的本地化字符串。
tools/gframework-config-tool/src/extension.js
tools/gframework-config-tool/src/localization.js
配置工具在生成示例 YAML 和为批量编辑排序模式键时,现在会尊重 const。
  • 修改 getEditableSchemaFields,使用 compareStringsOrdinal 对键进行排序,以在各工具之间实现一致的 ordinal 排序。
  • 在生成示例配置 YAML 时,让 getSampleScalarValue 优先使用 schemaNode.constValue,而非 defaultValue。
  • 通过 formatSchemaConstEditableValue 确保在生成示例 YAML 和可编辑值时,空字符串标量 const 值能够被精确保留。
tools/gframework-config-tool/src/configValidation.js
tools/gframework-config-tool/test/configValidation.test.js
源码生成器会在生成的 XML 配置文档中输出 const 信息,包括空字符串和复杂常量。
  • 更新文档,说明生成器在汇总模式约束时,会将 const 元数据与 default/enum/ref-table 一并映射。
  • 新增 TryBuildConstDocumentation,用于为 XML 注释格式化 const 值,对字符串、数组和对象保留精确的 JSON 字面量,对数字/布尔值按类型格式化。
  • 在组合约束汇总字符串时,如存在 const,则将其注入文档中,以便生成的代码在注释中暴露 const 信息。
  • 新增测试(包括快照更新),确保在生成的文档输出中,空字符串 const 与数字 const 能被精确保留。
GFramework.SourceGenerators/Config/SchemaConfigGenerator.cs
GFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorTests.cs
GFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorSnapshotTests.cs
GFramework.SourceGenerators.Tests/Config/snapshots/SchemaConfigGenerator/MonsterConfig.g.txt
运行时、工具链和文档在 const 行为和比较语义上保持一致,并补充了测试和文档更新。
  • 新增大量 Node.js 测试,覆盖标量、对象、数组、整数、布尔节点的 const 元数据解析;空字符串 const 的处理;可比值中对象键的 ordinal 排序;以及 const 校验在匹配/不匹配和类型规范化场景下的行为。
  • 新增 C# 运行时测试,覆盖标量/数组/对象 const 违规、接受空对象 const、错误消息内容,以及在失败时确保注册表保持为空。
  • 更新中文配置系统文档,列出 const 作为运行时/生成器/工具链间共享的约束,描述其行为(对象键顺序无关、数组顺序保持、标量规范化),并提及与 const 相关的验证案例和 VS Code UI 提示。
  • 完善 AGENTS.md,增加在 WSL 中解决 git.exe 路径问题的指导,以保持工具链一致性。
tools/gframework-config-tool/test/configValidation.test.js
GFramework.Game.Tests/Config/YamlConfigLoaderTests.cs
docs/zh-CN/game/config-system.md
AGENTS.md

技巧与命令

与 Sourcery 交互

  • 触发一次新评审: 在 pull request 上评论 @sourcery-ai review
  • 继续讨论: 直接回复 Sourcery 的评审评论。
  • 从评审评论生成 GitHub issue: 在评审评论下回复,要求 Sourcery 从该评论创建 issue。你也可以直接回复 @sourcery-ai issue,从该评论创建一个 issue。
  • 生成 pull request 标题: 在 pull request 标题的任意位置写上 @sourcery-ai,即可随时生成标题。你也可以在 pull request 上评论 @sourcery-ai title 来(重新)生成标题。
  • 生成 pull request 摘要: 在 pull request 正文的任意位置写上 @sourcery-ai summary,即可在指定位置生成 PR 摘要。你也可以在 pull request 上评论 @sourcery-ai summary 来随时(重新)生成摘要。
  • 生成 Reviewer's Guide: 在 pull request 上评论 @sourcery-ai guide,即可随时(重新)生成 reviewer's guide。
  • 一次性解决所有 Sourcery 评论: 在 pull request 上评论 @sourcery-ai resolve,即可将所有 Sourcery 评论标记为已解决。如果你已经处理完所有评论且不希望再看到它们,这会很有用。
  • 撤销所有 Sourcery 评审: 在 pull request 上评论 @sourcery-ai dismiss,即可撤销所有现有的 Sourcery 评审。如果你希望从一次全新的评审开始,尤其有用 —— 记得再次评论 @sourcery-ai review 来触发新评审!

自定义体验

访问你的 dashboard 以:

  • 启用或禁用评审功能,例如 Sourcery 自动生成的 pull request 摘要、reviewer's guide 等。
  • 更改评审语言。
  • 添加、移除或编辑自定义评审指令。
  • 调整其他评审设置。

获取帮助

Original review guide in English

Reviewer's Guide

Add first-class JSON Schema const support across the YAML runtime validator, Node.js config tooling, VS Code extension, source generator, and docs, including consistent comparison semantics, diagnostics, and documentation output.

Sequence diagram for runtime YAML const validation failure

sequenceDiagram
    actor ConfigAuthor
    participant YamlConfigLoader
    participant YamlConfigSchemaValidator
    participant YamlConfigSchemaNode
    participant ConfigRegistry

    ConfigAuthor->>YamlConfigLoader: Call LoadAsync(registry)
    YamlConfigLoader->>YamlConfigSchemaValidator: Parse schema JSON
    YamlConfigSchemaValidator->>YamlConfigSchemaValidator: ParseConstantValue for field with const
    YamlConfigSchemaValidator->>YamlConfigSchemaNode: WithConstantValue(new YamlConfigConstantValue)
    YamlConfigLoader->>YamlConfigSchemaValidator: Validate YAML document

    loop For each YAML node
        YamlConfigSchemaValidator->>YamlConfigSchemaValidator: BuildComparableNodeValue(node, schemaNode)
        YamlConfigSchemaValidator->>YamlConfigSchemaValidator: ValidateConstantValue(tableName, yamlPath, displayPath, node, schemaNode)
        YamlConfigSchemaValidator-->>YamlConfigSchemaValidator: Compare with schemaNode.ConstantValue.ComparableValue
    end

    alt Comparable value matches const
        YamlConfigSchemaValidator-->>YamlConfigLoader: Node accepted
        YamlConfigLoader->>ConfigRegistry: Register row
        YamlConfigLoader-->>ConfigAuthor: LoadAsync completes
    else Comparable value does not match const
        YamlConfigSchemaValidator-->>YamlConfigLoader: Throw ConfigLoadException
        YamlConfigLoader-->>ConfigAuthor: LoadAsync faulted with ConfigLoadException
        ConfigAuthor-->>ConfigAuthor: Inspect message mentioning constant value
    end
Loading

Class diagram for YAML schema constant value support

classDiagram
    class YamlConfigSchemaNode {
        +YamlConfigSchemaPropertyType NodeType
        +YamlConfigConstantValue ConstantValue
        +string SchemaPathHint
        +YamlConfigArrayConstraints ArrayConstraints
        +YamlConfigObjectConstraints ObjectConstraints
        +string ReferenceTableName
        +IReadOnlyCollection~string~ AllowedValues
        +YamlConfigSchemaNode WithReferenceTable(string referenceTableName)
        +YamlConfigSchemaNode WithConstantValue(YamlConfigConstantValue constantValue)
        +static YamlConfigSchemaNode CreateObject(IReadOnlyDictionary~string,YamlConfigSchemaNode~ properties, IReadOnlyCollection~string~ requiredProperties, YamlConfigObjectConstraints objectConstraints, string schemaPathHint)
        +static YamlConfigSchemaNode CreateArray(YamlConfigSchemaNode itemNode, YamlConfigArrayConstraints arrayConstraints, string schemaPathHint)
        +static YamlConfigSchemaNode CreateScalar(YamlConfigSchemaPropertyType nodeType, string referenceTableName, IReadOnlyCollection~string~ allowedValues, YamlConfigScalarConstraints constraints, string schemaPathHint)
    }

    class YamlConfigConstantValue {
        +YamlConfigConstantValue(string comparableValue, string displayValue)
        +string ComparableValue
        +string DisplayValue
    }

    class YamlConfigSchemaValidator {
        +YamlConfigSchemaNode ParseObjectNode(string tableName, string schemaPath, string propertyPath, JsonElement element)
        +YamlConfigSchemaNode ParseArrayNode(string tableName, string schemaPath, string propertyPath, JsonElement element)
        +YamlConfigSchemaNode CreateScalarNode(string tableName, string schemaPath, string propertyPath, JsonElement element, YamlConfigSchemaPropertyType nodeType, string referenceTableName)
        -YamlConfigConstantValue ParseConstantValue(string tableName, string schemaPath, string propertyPath, JsonElement element, YamlConfigSchemaNode schemaNode)
        -string BuildComparableConstantValue(string tableName, string schemaPath, string propertyPath, string keywordName, JsonElement element, YamlConfigSchemaNode schemaNode)
        -string BuildComparableConstantObjectValue(string tableName, string schemaPath, string propertyPath, string keywordName, JsonElement element, YamlConfigSchemaNode schemaNode)
        -string BuildComparableConstantArrayValue(string tableName, string schemaPath, string propertyPath, string keywordName, JsonElement element, YamlConfigSchemaNode schemaNode)
        -string BuildComparableConstantScalarValue(string tableName, string schemaPath, string propertyPath, string keywordName, JsonElement element, YamlConfigSchemaNode schemaNode)
        -string NormalizeKeywordScalarValue(string tableName, string schemaPath, string propertyPath, string keywordName, YamlConfigSchemaPropertyType expectedType, JsonElement item)
        -void ValidateConstantValue(string tableName, string yamlPath, string displayPath, YamlNode node, YamlConfigSchemaNode schemaNode)
        -string BuildComparableNodeValue(YamlNode node, YamlConfigSchemaNode schemaNode)
    }

    class NodeValidation {
        +string ReferenceTableName
        +IReadOnlyCollection~string~ AllowedValues
        +YamlConfigScalarConstraints Constraints
        +YamlConfigArrayConstraints ArrayConstraints
        +YamlConfigObjectConstraints ObjectConstraints
        +YamlConfigConstantValue ConstantValue
        +NodeValidation WithReferenceTable(string referenceTableName)
        +NodeValidation WithConstantValue(YamlConfigConstantValue constantValue)
    }

    YamlConfigSchemaNode o-- NodeValidation : encapsulates
    YamlConfigSchemaNode o-- YamlConfigConstantValue : holds
    YamlConfigSchemaValidator ..> YamlConfigSchemaNode : creates and validates
    YamlConfigSchemaValidator ..> YamlConfigConstantValue : parses
    YamlConfigSchemaValidator ..> NodeValidation : uses
Loading

Flow diagram for Node.js tooling const metadata and validation

flowchart TD
    A[Load JSON Schema file] --> B[parseSchemaNode for root]
    B --> C[For each property
parseSchemaNode]
    C --> D[applyConstMetadata
with raw const]
    D --> E[formatSchemaConstEditableValue
-> constValue]
    D --> F[formatSchemaConstDisplayValue
-> constDisplayValue]
    D --> G[buildSchemaConstComparableValue
-> constComparableValue]

    G --> G1{schemaNode.type}
    G1 -->|object| H[buildSchemaConstObjectComparableValue
validate shape
normalize child values
sort keys
join key=value segments]
    G1 -->|array| I[buildSchemaConstArrayComparableValue
validate array
normalize each item
preserve order]
    G1 -->|scalar| J[buildSchemaConstScalarComparableValue
normalizeSchemaConstScalarValue
prefix with type and length]

    E --> K[SchemaNode has
constValue]
    F --> K
    G --> K

    subgraph Validation
        L[validateNode
per YAML node] --> M[validateConstComparableValue]
        M --> N{schemaNode.constComparableValue
is defined}
        N -->|no| O[Skip const check]
        N -->|yes| P[buildComparableNodeValue
for YAML node]
        P --> Q{comparable equal
schema vs YAML}
        Q -->|yes| R[Accept node]
        Q -->|no| S[Push diagnostic
ValidationMessageKeys.constMismatch
with constDisplayValue or constValue]
    end

    K --> L

    subgraph VS_Code_Form
        T[collectFormFields / collectObjectArrayItemFields]
        T --> U[getScalarFieldValue
uses constValue or defaultValue]
        T --> V[renderFieldHint]
        V --> W[webview.hint.const /
webview.hint.itemConst
using constDisplayValue]
    end

    K --> T
Loading

File-Level Changes

Change Details Files
Runtime YAML validator now parses, normalizes, and enforces JSON Schema const constraints for scalar, array, and object nodes using a shared comparable-key mechanism.
  • Augment object, array, and scalar schema node creation to attach a parsed YamlConfigConstantValue built from the JSON Schema const element.
  • Introduce BuildComparableConstantValue helpers for objects, arrays, and scalars that normalize const values into stable comparison keys aligned with BuildComparableNodeValue semantics (object key-order insensitive, array order preserving, scalar type-normalized).
  • Add ValidateConstantValue to compare runtime YAML nodes against the schema const comparable value and throw ConfigLoadException with rich diagnostics when mismatched.
  • Unify enum and const scalar normalization by replacing NormalizeEnumValue with a generalized NormalizeKeywordScalarValue used for both keywords.
  • Extend YamlConfigSchemaNode and its internal validation state to carry ConstantValue and provide WithConstantValue for immutably adding const metadata.
GFramework.Game/Config/YamlConfigSchemaValidator.cs
Node.js config validation/tooling layer parses const metadata, normalizes it for comparison, surfaces it to callers, and enforces const at validation time with localized diagnostics.
  • Add compareStringsOrdinal to mirror C# string.CompareOrdinal for consistent key sorting.
  • Extend parseSchemaNode to read value.const, build constValue/constDisplayValue/constComparableValue via applyConstMetadata, and carry them on SchemaNode for scalar, array, and object types.
  • Introduce buildSchemaConstComparableValue and helpers for object/array/scalar to normalize const values into comparable keys that match runtime semantics, including scalar normalization with normalizeSchemaConstScalarValue.
  • Add validateConstComparableValue to check YAML nodes against schemaNode.constComparableValue during validation for scalar, array, and object nodes and emit ValidationMessageKeys.constMismatch diagnostics.
  • Update buildComparableNodeValue to sort object keys using ordinal semantics so tooling comparison matches runtime and add new ValidationMessageKeys.constMismatch to localization keys.
tools/gframework-config-tool/src/configValidation.js
tools/gframework-config-tool/src/localizationKeys.js
VS Code extension form editor surfaces const as preferred default values and human-readable hints for fields and array items.
  • Update form field collection to feed constValue as the primary scalar fallback value before defaultValue when computing edited field values.
  • Change getScalarFieldValue to use a generic schema-provided fallback (const or default) while preserving existing behavior when YAML has a scalar.
  • Extend renderFieldHint to display const and itemConst hints using localized strings and constDisplayValue/constValue, including for array item schemas.
  • Add new localization strings for const hints in both English and Chinese message maps.
tools/gframework-config-tool/src/extension.js
tools/gframework-config-tool/src/localization.js
Config tooling now respects const when generating sample YAML and ordering schema keys for batch editing.
  • Change getEditableSchemaFields to sort keys with compareStringsOrdinal for consistent ordinal ordering across tools.
  • Make getSampleScalarValue prefer schemaNode.constValue over defaultValue when generating sample config YAML.
  • Ensure empty-string scalar const values are preserved exactly in generated sample YAML and editable values via formatSchemaConstEditableValue.
tools/gframework-config-tool/src/configValidation.js
tools/gframework-config-tool/test/configValidation.test.js
Source generator emits const information into generated XML configuration documentation, including empty-string and complex constants.
  • Document that the generator now maps const metadata alongside default/enum/ref-table when summarizing schema constraints.
  • Add TryBuildConstDocumentation to format const values for XML comments, preserving exact JSON literals for strings, arrays, and objects and numeric/boolean formatting per type.
  • Inject const documentation into the composed constraint summary string when present so generated code surfaces const in comments.
  • Add tests (including snapshot updates) to assert empty-string const and numeric const are preserved in generated documentation output.
GFramework.SourceGenerators/Config/SchemaConfigGenerator.cs
GFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorTests.cs
GFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorSnapshotTests.cs
GFramework.SourceGenerators.Tests/Config/snapshots/SchemaConfigGenerator/MonsterConfig.g.txt
Runtime, tooling, and docs are aligned around const behavior and comparison semantics, with expanded tests and documentation updates.
  • Add extensive Node.js tests to cover parsing const metadata across scalar, object, array, integer, boolean nodes; handling empty-string const; ordinal ordering of object keys in comparable values; and const validation behavior for matches/mismatches and type normalization.
  • Add C# runtime tests for scalar/array/object const violations, acceptance of empty-object const, error messaging content, and ensuring registry stays empty on failure.
  • Update Chinese config-system documentation to list const as a shared constraint across runtime/generator/tooling, describe its behavior (object key-order insensitivity, array order preservation, scalar normalization), and mention const-related validation cases and VS Code UI hints.
  • Refine AGENTS.md with additional guidance for resolving git.exe path issues in WSL to keep tooling consistent.
tools/gframework-config-tool/test/configValidation.test.js
GFramework.Game.Tests/Config/YamlConfigLoaderTests.cs
docs/zh-CN/game/config-system.md
AGENTS.md

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@coderabbitai

coderabbitai Bot commented Apr 10, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

在运行时、源生成器与工具链中引入并验证 JSON Schema 的 const 约束;同时补充单元/集成测试、VS Code 扩展提示、本地化与生成文档输出以覆盖 const 行为。

Changes

Cohort / File(s) Summary
C# 运行时验证
GFramework.Game/Config/YamlConfigSchemaValidator.cs
为模式节点新增 ConstantValueYamlConfigConstantValue),在对象/数组/标量解析处捕获并规范化 const,并在验证流程中追加 const 匹配检查;不匹配时抛出 ConstraintViolation。
C# 测试覆盖
GFramework.Game.Tests/Config/YamlConfigLoaderTests.cs
新增多个 NUnit 测试覆盖标量、数组、嵌套对象的 const 失败场景与空对象 const 的通过场景,断言异常消息内容与注册表状态。
源生成器与快照
GFramework.SourceGenerators/Config/SchemaConfigGenerator.cs, GFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorSnapshotTests.cs, GFramework.SourceGenerators.Tests/Config/snapshots/.../MonsterConfig.g.txt
生成器将 const 纳入支持元数据并在约束文档中输出 const = ... 片段;更新测试输入与快照反映 const(包含空字符串 const 保留)。
工具端验证与编辑器核心
tools/gframework-config-tool/src/configValidation.js, tools/gframework-config-tool/test/configValidation.test.js
解析并存储 constValue/constDisplayValue/constComparableValue,对象比较采用 UTF-16(ordinal)键排序,新增 constMismatch 诊断并覆盖相应测试。
VS Code 扩展 UI 与本地化
tools/gframework-config-tool/src/extension.js, tools/gframework-config-tool/src/localization.js, tools/gframework-config-tool/src/localizationKeys.js
表单字段初始值优先使用 constValue,渲染字段提示显示 const 元数据;新增本地化键与 constMismatch 消息(中/英)。
文档与指南
docs/zh-CN/game/config-system.md, AGENTS.md
文档将 const 列入共享约束与验证规则说明;AGENTS.md 添加 WSL/Windows Git 解析建议。

Sequence Diagram(s)

sequenceDiagram
  participant Schema as "Schema (file/Generator)"
  participant Generator as "Source Generator"
  participant Tool as "VSCode Tool"
  participant Loader as "Yaml Loader"
  participant Validator as "Runtime Validator"
  participant Registry as "Config Registry"

  Schema->>Generator: 提供含 `const` 的模式
  Generator->>Schema: 在生成文档/注释中输出 `const` 描述
  Schema->>Tool: 导出 `constValue`/`constDisplayValue`/`constComparableValue`
  Tool->>Tool: 渲染字段提示、样例 YAML(优先显示/生成 const)
  Loader->>Validator: 加载 YAML,逐节点执行验证(包含 const 检查)
  Validator-->>Loader: 返回验证通过或抛出 ConstraintViolation(含路径与显示值)
  Loader->>Registry: 仅在验证通过时写入配置注册表
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed 标题准确反映了PR的核心内容,包括文档编写和验证工具实现的两个主要变更方向,与changeset中的多个改动点相符合。
Docstring Coverage ✅ Passed Docstring coverage is 93.44% which is sufficient. The required threshold is 80.00%.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/config-system-docs-and-validation

Comment @coderabbitai help to get the list of available commands and usage tips.

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - 我发现了 3 个问题,并留下了一些高层次的反馈:

  • 在 VS Code 工具中,collectFormFieldscollectObjectArrayItemFieldspropertySchema.constValue || propertySchema.defaultValue 传给 getScalarFieldValue,这样一来,一个合法的空字符串 const 会被忽略,而优先使用 default。建议把 constValuedefaultValue 分开传入,或者显式检查是否为 undefined 而不是用 ||,以便保留空字符串常量。
  • BuildComparableConstantValue(C#)中,default 分支会对不支持的节点类型抛出 InvalidOperationException,这会在运行时表现为内部错误;建议将其改为抛出带有 SchemaUnsupportedConfigLoadException,这样当在不支持的类型上使用 const 时,schema 作者可以获得一致且可诊断的错误。
  • 运行时时(C# 中的 BuildComparableConstant*)和工具侧(JS 中的 buildSchemaConst*)都各自实现了一套 const 归一化/可比较键逻辑;可以考虑加上醒目的注释说明这两条路径必须保持同步,或者把共享规则抽出到一个小的规范 helper 中,以减少只在一侧修改时产生偏离的风险。
给 AI 代理的提示
Please address the comments from this code review:

## Overall Comments
- In the VS Code tooling, `collectFormFields` and `collectObjectArrayItemFields` pass `propertySchema.constValue || propertySchema.defaultValue` into `getScalarFieldValue`, so a valid empty-string `const` will be ignored in favor of `default`; consider passing `constValue` and `defaultValue` separately or checking explicitly for `undefined` instead of using `||` so empty-string constants are preserved.
- In `BuildComparableConstantValue` (C#) the default branch throws `InvalidOperationException` for unsupported node types, which will surface as an internal error at runtime; consider converting this into a `ConfigLoadException` with `SchemaUnsupported` so schema authors get a consistent, diagnosable error when `const` is used on an unsupported type.
- Both the runtime (`BuildComparableConstant*` in C#) and the tooling (`buildSchemaConst*` in JS) implement their own const normalization/comparable-key logic; it may be worth adding prominent comments that these two paths must stay in sync or factoring shared rules into a small spec helper to reduce the risk of divergence when one side is modified.

## Individual Comments

### Comment 1
<location path="tools/gframework-config-tool/src/configValidation.js" line_range="570" />
<code_context>
+        objectEntries.push([key, childComparableValue]);
+    }
+
+    objectEntries.sort((left, right) => left[0].localeCompare(right[0]));
+    return objectEntries.map(([key, value]) => `${key.length}:${key}=${value.length}:${value}`).join("|");
+}
</code_context>
<issue_to_address>
**suggestion (bug_risk):** Use a locale-independent sort for const object key normalization.

The current use of `localeCompare` makes ordering dependent on the runtime locale and is slower than a simple ordinal comparison. For deterministic behavior across environments (and to match `string.CompareOrdinal` on the C# side), switch to a locale-independent comparison, e.g. comparing `left[0]` and `right[0]` directly or via `codePointAt(0)` and returning -1/0/1 accordingly.

```suggestion
    objectEntries.sort((left, right) => {
        if (left[0] < right[0]) {
            return -1;
        }

        if (left[0] > right[0]) {
            return 1;
        }

        return 0;
    });
```
</issue_to_address>

### Comment 2
<location path="tools/gframework-config-tool/test/configValidation.test.js" line_range="68-77" />
<code_context>
+test("parseSchemaContent should capture const metadata for scalar, object, and array nodes", () => {
</code_context>
<issue_to_address>
**suggestion (testing):** Complement const metadata tests with coverage for comparable values and successful validation.

These tests confirm parsing and mismatch reporting, but we’re missing validation-side coverage. Please add: (1) a case where YAML matches scalar/object/array const values and `validateParsedConfig` yields no diagnostics; (2) a case that asserts `schemaNode.constComparableValue` is set and that `validateParsedConfig` respects the same normalization as `buildComparableNodeValue` (e.g., object key reordering and array order behavior); and (3) numeric and boolean const cases to exercise `normalizeSchemaConstScalarValue` (e.g., integer vs non-integer and boolean type mismatches).

Suggested implementation:

```javascript
test("parseSchemaContent should capture const metadata for scalar, object, and array nodes", () => {
    const schema = parseSchemaContent(`
        {
          "type": "object",
          "properties": {
            "rarity": {
              "type": "string",
              "const": "common"
            },
            "reward": {
              "type": "object",
              "const": {
                "gold": 100,
                "items": [
                  "potion",
                  "sword"
                ]
              }
            },
            "tags": {
              "type": "array",
              "items": {
                "type": "string"
              },
              "const": [
                "daily",
                "quest"
              ]
            },
            "maxAttempts": {
              "type": "integer",
              "const": 3
            },
            "allowRetry": {
              "type": "boolean",
              "const": true
            }
          }
        }
      `);

      const rarityNode = schema.properties.rarity;
      assert.strictEqual(rarityNode.const, "common");
      assert.ok(
        rarityNode.constComparableValue,
        "scalar const should have constComparableValue"
      );

      const rewardNode = schema.properties.reward;
      assert.deepEqual(rewardNode.const, {
        gold: 100,
        items: ["potion", "sword"],
      });
      assert.ok(
        rewardNode.constComparableValue,
        "object const should have constComparableValue"
      );

      // Object key order should not affect constComparableValue
      const reorderedRewardComparable = buildComparableNodeValue({
        items: ["potion", "sword"],
        gold: 100,
      });
      assert.deepEqual(
        rewardNode.constComparableValue,
        reorderedRewardComparable,
        "object constComparableValue should be key-order-insensitive",
      );

      const tagsNode = schema.properties.tags;
      assert.deepEqual(tagsNode.const, ["daily", "quest"]);
      assert.ok(
        tagsNode.constComparableValue,
        "array const should have constComparableValue"
      );

      const maxAttemptsNode = schema.properties.maxAttempts;
      assert.strictEqual(maxAttemptsNode.const, 3);
      assert.ok(
        maxAttemptsNode.constComparableValue,
        "numeric const should have constComparableValue"
      );

      const allowRetryNode = schema.properties.allowRetry;
      assert.strictEqual(allowRetryNode.const, true);
      assert.ok(
        allowRetryNode.constComparableValue,
        "boolean const should have constComparableValue"
      );
});

```

To fully implement your review comment, the following additional changes should be made elsewhere in the same test file, matching the existing testing conventions:

1. **Add a validation-success test** that uses the above schema and a YAML config whose values exactly match the scalar, object, array, numeric, and boolean const values:
   - Parse the same schema via `parseSchemaContent`.
   - Parse a YAML document (using the same helper the file already uses, e.g. `parseConfigContent` or equivalent).
   - Call `validateParsedConfig(schema, parsedConfig, /* path/ctx as used in other tests */)`.
   - Assert that the returned diagnostics array is empty (or that no diagnostics have `severity === "error"`, depending on existing conventions).

2. **Add a normalization/comparable-value validation test**:
   - Use a schema with an object const like the `reward` node above and an array const like `tags`.
   - Provide a YAML config where the object keys are in a different order (e.g. `{ items: ["potion", "sword"], gold: 100 }`) and the array is in the same order as the const.
   - Call `validateParsedConfig` and assert that there are **no** const-mismatch diagnostics, demonstrating that `validateParsedConfig` uses the same normalization behavior as `buildComparableNodeValue`.
   - Optionally, also include a negative case (e.g. array with different order/contents) and assert that `validateParsedConfig` reports a const mismatch diagnostic.

3. **Add numeric and boolean const validation tests** to exercise `normalizeSchemaConstScalarValue` through the validation path:
   - A matching case: integer const vs integer YAML value, boolean const vs boolean YAML value → no diagnostics.
   - A mismatching numeric case: schema `{"type": "integer", "const": 3}` vs YAML `3.5` or `"3"` → expect a const-mismatch diagnostic.
   - A mismatching boolean case: schema `{"type": "boolean", "const": true}` vs YAML `"true"` or `0` → expect a const-mismatch diagnostic.
   - Structure the assertions (diagnostic codes/messages, node paths) consistently with how other diagnostics are asserted in this file.

When adding these tests, reuse helper functions already imported in `configValidation.test.js` (e.g. schema/config parsing helpers, diagnostic helpers) and follow the same assertion style (`assert.deepEqual`, helper-based filtering of diagnostics, etc.) that the existing validation tests use.
</issue_to_address>

### Comment 3
<location path="tools/gframework-config-tool/test/configValidation.test.js" line_range="86" />
<code_context>
  * @returns {string} Sample scalar value.
  */
 function getSampleScalarValue(schemaNode) {
+    if (schemaNode.constValue !== undefined) {
+        return schemaNode.constValue;
+    }
+
     if (schemaNode.defaultValue !== undefined) {
</code_context>
<issue_to_address>
**suggestion (testing):** Add a test to verify getSampleScalarValue prefers const over default.

`getSampleScalarValue` now prefers `schemaNode.constValue` over `defaultValue`, but there’s no test capturing this behavior. Please add a unit test with a scalar field that has both `const` and `default` and assert that the sample value/placeholder uses `const`. This will help prevent regressions where the UI diverges from the runtime `const` semantics.
</issue_to_address>

Sourcery 对开源项目免费——如果你觉得我们的评审有帮助,欢迎帮忙分享 ✨
帮我变得更有用!请在每条评论上点 👍 或 👎,我会根据你的反馈改进以后的评审。
Original comment in English

Hey - I've found 3 issues, and left some high level feedback:

  • In the VS Code tooling, collectFormFields and collectObjectArrayItemFields pass propertySchema.constValue || propertySchema.defaultValue into getScalarFieldValue, so a valid empty-string const will be ignored in favor of default; consider passing constValue and defaultValue separately or checking explicitly for undefined instead of using || so empty-string constants are preserved.
  • In BuildComparableConstantValue (C#) the default branch throws InvalidOperationException for unsupported node types, which will surface as an internal error at runtime; consider converting this into a ConfigLoadException with SchemaUnsupported so schema authors get a consistent, diagnosable error when const is used on an unsupported type.
  • Both the runtime (BuildComparableConstant* in C#) and the tooling (buildSchemaConst* in JS) implement their own const normalization/comparable-key logic; it may be worth adding prominent comments that these two paths must stay in sync or factoring shared rules into a small spec helper to reduce the risk of divergence when one side is modified.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In the VS Code tooling, `collectFormFields` and `collectObjectArrayItemFields` pass `propertySchema.constValue || propertySchema.defaultValue` into `getScalarFieldValue`, so a valid empty-string `const` will be ignored in favor of `default`; consider passing `constValue` and `defaultValue` separately or checking explicitly for `undefined` instead of using `||` so empty-string constants are preserved.
- In `BuildComparableConstantValue` (C#) the default branch throws `InvalidOperationException` for unsupported node types, which will surface as an internal error at runtime; consider converting this into a `ConfigLoadException` with `SchemaUnsupported` so schema authors get a consistent, diagnosable error when `const` is used on an unsupported type.
- Both the runtime (`BuildComparableConstant*` in C#) and the tooling (`buildSchemaConst*` in JS) implement their own const normalization/comparable-key logic; it may be worth adding prominent comments that these two paths must stay in sync or factoring shared rules into a small spec helper to reduce the risk of divergence when one side is modified.

## Individual Comments

### Comment 1
<location path="tools/gframework-config-tool/src/configValidation.js" line_range="570" />
<code_context>
+        objectEntries.push([key, childComparableValue]);
+    }
+
+    objectEntries.sort((left, right) => left[0].localeCompare(right[0]));
+    return objectEntries.map(([key, value]) => `${key.length}:${key}=${value.length}:${value}`).join("|");
+}
</code_context>
<issue_to_address>
**suggestion (bug_risk):** Use a locale-independent sort for const object key normalization.

The current use of `localeCompare` makes ordering dependent on the runtime locale and is slower than a simple ordinal comparison. For deterministic behavior across environments (and to match `string.CompareOrdinal` on the C# side), switch to a locale-independent comparison, e.g. comparing `left[0]` and `right[0]` directly or via `codePointAt(0)` and returning -1/0/1 accordingly.

```suggestion
    objectEntries.sort((left, right) => {
        if (left[0] < right[0]) {
            return -1;
        }

        if (left[0] > right[0]) {
            return 1;
        }

        return 0;
    });
```
</issue_to_address>

### Comment 2
<location path="tools/gframework-config-tool/test/configValidation.test.js" line_range="68-77" />
<code_context>
+test("parseSchemaContent should capture const metadata for scalar, object, and array nodes", () => {
</code_context>
<issue_to_address>
**suggestion (testing):** Complement const metadata tests with coverage for comparable values and successful validation.

These tests confirm parsing and mismatch reporting, but we’re missing validation-side coverage. Please add: (1) a case where YAML matches scalar/object/array const values and `validateParsedConfig` yields no diagnostics; (2) a case that asserts `schemaNode.constComparableValue` is set and that `validateParsedConfig` respects the same normalization as `buildComparableNodeValue` (e.g., object key reordering and array order behavior); and (3) numeric and boolean const cases to exercise `normalizeSchemaConstScalarValue` (e.g., integer vs non-integer and boolean type mismatches).

Suggested implementation:

```javascript
test("parseSchemaContent should capture const metadata for scalar, object, and array nodes", () => {
    const schema = parseSchemaContent(`
        {
          "type": "object",
          "properties": {
            "rarity": {
              "type": "string",
              "const": "common"
            },
            "reward": {
              "type": "object",
              "const": {
                "gold": 100,
                "items": [
                  "potion",
                  "sword"
                ]
              }
            },
            "tags": {
              "type": "array",
              "items": {
                "type": "string"
              },
              "const": [
                "daily",
                "quest"
              ]
            },
            "maxAttempts": {
              "type": "integer",
              "const": 3
            },
            "allowRetry": {
              "type": "boolean",
              "const": true
            }
          }
        }
      `);

      const rarityNode = schema.properties.rarity;
      assert.strictEqual(rarityNode.const, "common");
      assert.ok(
        rarityNode.constComparableValue,
        "scalar const should have constComparableValue"
      );

      const rewardNode = schema.properties.reward;
      assert.deepEqual(rewardNode.const, {
        gold: 100,
        items: ["potion", "sword"],
      });
      assert.ok(
        rewardNode.constComparableValue,
        "object const should have constComparableValue"
      );

      // Object key order should not affect constComparableValue
      const reorderedRewardComparable = buildComparableNodeValue({
        items: ["potion", "sword"],
        gold: 100,
      });
      assert.deepEqual(
        rewardNode.constComparableValue,
        reorderedRewardComparable,
        "object constComparableValue should be key-order-insensitive",
      );

      const tagsNode = schema.properties.tags;
      assert.deepEqual(tagsNode.const, ["daily", "quest"]);
      assert.ok(
        tagsNode.constComparableValue,
        "array const should have constComparableValue"
      );

      const maxAttemptsNode = schema.properties.maxAttempts;
      assert.strictEqual(maxAttemptsNode.const, 3);
      assert.ok(
        maxAttemptsNode.constComparableValue,
        "numeric const should have constComparableValue"
      );

      const allowRetryNode = schema.properties.allowRetry;
      assert.strictEqual(allowRetryNode.const, true);
      assert.ok(
        allowRetryNode.constComparableValue,
        "boolean const should have constComparableValue"
      );
});

```

To fully implement your review comment, the following additional changes should be made elsewhere in the same test file, matching the existing testing conventions:

1. **Add a validation-success test** that uses the above schema and a YAML config whose values exactly match the scalar, object, array, numeric, and boolean const values:
   - Parse the same schema via `parseSchemaContent`.
   - Parse a YAML document (using the same helper the file already uses, e.g. `parseConfigContent` or equivalent).
   - Call `validateParsedConfig(schema, parsedConfig, /* path/ctx as used in other tests */)`.
   - Assert that the returned diagnostics array is empty (or that no diagnostics have `severity === "error"`, depending on existing conventions).

2. **Add a normalization/comparable-value validation test**:
   - Use a schema with an object const like the `reward` node above and an array const like `tags`.
   - Provide a YAML config where the object keys are in a different order (e.g. `{ items: ["potion", "sword"], gold: 100 }`) and the array is in the same order as the const.
   - Call `validateParsedConfig` and assert that there are **no** const-mismatch diagnostics, demonstrating that `validateParsedConfig` uses the same normalization behavior as `buildComparableNodeValue`.
   - Optionally, also include a negative case (e.g. array with different order/contents) and assert that `validateParsedConfig` reports a const mismatch diagnostic.

3. **Add numeric and boolean const validation tests** to exercise `normalizeSchemaConstScalarValue` through the validation path:
   - A matching case: integer const vs integer YAML value, boolean const vs boolean YAML value → no diagnostics.
   - A mismatching numeric case: schema `{"type": "integer", "const": 3}` vs YAML `3.5` or `"3"` → expect a const-mismatch diagnostic.
   - A mismatching boolean case: schema `{"type": "boolean", "const": true}` vs YAML `"true"` or `0` → expect a const-mismatch diagnostic.
   - Structure the assertions (diagnostic codes/messages, node paths) consistently with how other diagnostics are asserted in this file.

When adding these tests, reuse helper functions already imported in `configValidation.test.js` (e.g. schema/config parsing helpers, diagnostic helpers) and follow the same assertion style (`assert.deepEqual`, helper-based filtering of diagnostics, etc.) that the existing validation tests use.
</issue_to_address>

### Comment 3
<location path="tools/gframework-config-tool/test/configValidation.test.js" line_range="86" />
<code_context>
  * @returns {string} Sample scalar value.
  */
 function getSampleScalarValue(schemaNode) {
+    if (schemaNode.constValue !== undefined) {
+        return schemaNode.constValue;
+    }
+
     if (schemaNode.defaultValue !== undefined) {
</code_context>
<issue_to_address>
**suggestion (testing):** Add a test to verify getSampleScalarValue prefers const over default.

`getSampleScalarValue` now prefers `schemaNode.constValue` over `defaultValue`, but there’s no test capturing this behavior. Please add a unit test with a scalar field that has both `const` and `default` and assert that the sample value/placeholder uses `const`. This will help prevent regressions where the UI diverges from the runtime `const` semantics.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread tools/gframework-config-tool/src/configValidation.js Outdated
Comment thread tools/gframework-config-tool/test/configValidation.test.js Outdated
Comment thread tools/gframework-config-tool/test/configValidation.test.js
@greptile-apps

greptile-apps Bot commented Apr 10, 2026

Copy link
Copy Markdown

Greptile Summary

This PR adds first-class support for JSON Schema const constraints across the C# runtime validator (YamlConfigSchemaValidator.cs), the Node.js config tooling (configValidation.js), the VS Code extension (extension.js), and the Roslyn source generator (SchemaConfigGenerator.cs). It also resolves the prior review concern about localeCompare vs ordinal comparison by introducing compareStringsOrdinal.

Key changes:

  • C# runtime: New YamlConfigConstantValue class holds a pre-normalized comparable key and display text. ParseConstantValue / BuildComparableConstantValue build ordinal-sorted comparable keys at schema-parse time so runtime validation is a simple string equality check. ValidateConstantValue is called at the tail of each node-type validator (scalar / array / object), after type and structural guards.
  • JS tooling: compareStringsOrdinal replaces localeCompare to match C#'s string.CompareOrdinal. applyConstMetadata / buildSchemaConstComparableValue mirror the C# normalization path. validateConstComparableValue follows the same post-type-check placement, meaning type mismatches cause an early return and const is never double-reported.
  • VS Code extension: constValue is preferred over defaultValue as form field seed using ??, and a "Const: …" hint is rendered alongside other metadata hints.
  • Source generator: TryBuildConstDocumentation emits const = value into generated XML doc.
  • Tests: Positive and negative cases added for scalars, arrays, nested objects, and empty objects in both C# and JS. Snapshot updated to include const = 10.
  • Docs: config-system.md updated to describe const support and its cross-system comparison semantics.

Confidence Score: 4/5

Safe to merge; no correctness or security issues — three P2 style suggestions remain.

The prior review concern about localeCompare vs ordinal sort has been fully resolved by compareStringsOrdinal. The C# and JS comparable-key formats are aligned, the early-return ordering in scalar validation correctly prevents double-reporting, and both runtimes share the same comparison semantics. Test coverage is comprehensive across all three node types. The three P2 comments are non-blocking polish items.

tools/gframework-config-tool/test/configValidation.test.js — integer const mismatch code path is not directly exercised; GFramework.Game/Config/YamlConfigSchemaValidator.cs — minor constructor guard semantics.

Important Files Changed

Filename Overview
GFramework.Game/Config/YamlConfigSchemaValidator.cs Adds const constraint support across scalar, array, and object schema nodes; reuses the existing BuildComparableNodeValue / comparable-key infrastructure so ordering and normalization stay aligned with uniqueItems; well-documented with XML comments.
tools/gframework-config-tool/src/configValidation.js Introduces compareStringsOrdinal to replace localeCompare, resolving the prior review comment; adds const metadata parsing, comparable-key builders, and validation helper; placement after type checks prevents double-reporting.
GFramework.Game.Tests/Config/YamlConfigLoaderTests.cs Adds four new const tests (scalar mismatch, array mismatch, nested-object mismatch, empty-object match); all follow established test patterns; coverage is good but lacks a positive match test for non-empty array const.
tools/gframework-config-tool/test/configValidation.test.js Comprehensive new tests for const metadata parsing, comparable-key ordinal ordering, scalar/array/object validation, empty-string edge cases, and ordinal sort in getEditableSchemaFields; integer const mismatch (valid integer, wrong value) is not exercised — only type mismatch is tested for integers.
GFramework.SourceGenerators/Config/SchemaConfigGenerator.cs Adds TryBuildConstDocumentation to emit const = value into generated XML docs; handles integer, number, boolean, string, array, and object kinds; type-kind alignment avoids mis-formatting.
tools/gframework-config-tool/src/extension.js Correctly prefers constValue over defaultValue as form field seed using ??; adds const and item-const hint rendering; parameter rename from defaultValue to fallbackValue reflects the broadened semantics.
GFramework.SourceGenerators.Tests/Config/snapshots/SchemaConfigGenerator/MonsterConfig.g.txt Snapshot updated to include const = 10 before existing numeric constraints; trailing newline added; change is correct and minimal.
docs/zh-CN/game/config-system.md Documents const support in the runtime violation list and the shared-keyword table; wording correctly describes object-field-order-independence and array-element-order-preservation.
AGENTS.md Adds two WSL-path clarification bullets; administrative doc change with no code impact.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Schema JSON loaded] --> B[ParseConstantValue]
    B --> C{const declared?}
    C -->|No| D[ConstantValue is null - skip]
    C -->|Yes| E[BuildComparableConstantValue]
    E --> F{Node type?}
    F -->|scalar| G[NormalizeKeywordScalarValue - format: type-len-value]
    F -->|array| H[Ordered item list - format: bracket-len-item-comma]
    F -->|object| I[Sort keys by CompareOrdinal - format: keyLen-key-valueLen-value pipe-sep]
    G --> J[YamlConfigConstantValue stored on SchemaNode]
    H --> J
    I --> J
    J --> L[YAML file loaded for validation]
    L --> M[Type and structural checks run first]
    M -->|type mismatch| N[Early return - const check skipped]
    M -->|type ok| P[ValidateConstantValue called]
    P --> Q[BuildComparableNodeValue on YAML node]
    Q --> R{Ordinal equals ComparableValue?}
    R -->|Yes| S[Validation passes]
    R -->|No| T[Throw ConstraintViolation with DisplayValue]
Loading

Reviews (3): Last reviewed commit: "docs(config): 添加AI代理编码行为规范和配置验证工具测试" | Re-trigger Greptile

Comment thread tools/gframework-config-tool/src/configValidation.js Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

🧹 Nitpick comments (1)
GFramework.Game.Tests/Config/YamlConfigLoaderTests.cs (1)

366-410: 补齐 Diagnostic 断言,避免只测消息文本。

这三组 const 用例现在主要校验 Message 子串;如果后续仍然抛出 ConfigLoadException,但 FailureKindDisplayPathRawValue 回归,测试还是会通过。建议像同文件其它约束测试一样,把这些结构化诊断字段也断言住,这样 const 的错误契约才算真正被固定下来。
Based on learnings Public API changes must be covered by unit or integration tests.

Also applies to: 1247-1297, 1349-1404

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@GFramework.Game.Tests/Config/YamlConfigLoaderTests.cs` around lines 366 -
410, The test
LoadAsync_Should_Throw_When_Scalar_Value_Does_Not_Match_Schema_Const only
asserts exception message substrings; update it to also assert the structured
Diagnostic fields on the thrown ConfigLoadException (e.g. check
exception.Diagnostics or the Diagnostic object for FailureKind, DisplayPath and
RawValue) so the contract for const failures is fixed; locate the assertion
block after Assert.ThrowsAsync for ConfigLoadException and add assertions that
FailureKind equals the expected kind (e.g. ConstantMismatch), DisplayPath points
to "monster/rarity" (or the schema path used), and RawValue equals "rare" (the
actual bad value) and still assert registry.Count == 0; apply the same pattern
to the other const-related tests mentioned.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@GFramework.Game/Config/YamlConfigSchemaValidator.cs`:
- Around line 2924-2931: The constructor YamlConfigConstantValue(string
comparableValue, string displayValue) rejects empty strings via
ArgumentException.ThrowIfNullOrWhiteSpace, which fails for legal JSON Schema
const: {} that yields an empty comparable/display value; change the validation
to only guard against null (e.g., use ArgumentNullException.ThrowIfNull or
ArgumentException.ThrowIfNull) for both comparableValue and displayValue so
empty strings are accepted, leaving the assignments to ComparableValue and
DisplayValue unchanged.
- Around line 991-995: The sorting of object property keys in
YamlConfigSchemaValidator currently uses string.CompareOrdinal, which can
produce different orders than the JS toolchain's localeCompare; to ensure
deterministic, cross-platform comparable keys, change the sort to use
StringComparer.Ordinal explicitly (e.g., objectEntries.Sort((l,r) =>
StringComparer.Ordinal.Compare(l.Key, r.Key)) ) and add a validation step in
YamlConfigSchemaValidator that rejects or normalizes non-ASCII/non-normalized
property names (or emit a clear error) so runtime C# ordering always matches the
expected ordinal ordering used by the tooling.

In `@GFramework.SourceGenerators/Config/SchemaConfigGenerator.cs`:
- Around line 2455-2458: The code in SchemaConfigGenerator.cs currently skips
adding the const constraint when constDocumentation is an empty or whitespace
string because it uses string.IsNullOrWhiteSpace; update the check to only test
for null (e.g., constDocumentation != null) so an explicit empty string is
preserved, and adjust the appended text added to parts (the parts.Add call that
references constDocumentation) so the generated doc clearly represents
empty-string constants (for example include quotes around the value when
building the "const = ..." entry) — locate the constDocumentation variable and
the parts.Add(...) call in the SchemaConfigGenerator class and change the
condition and formatting accordingly.

In `@tools/gframework-config-tool/src/configValidation.js`:
- Around line 464-505: formatSchemaConstValue currently returns raw string
values (String(value)), causing diagnostic displays to lose JSON quoting for
string consts; update formatSchemaConstValue so that string consts are
JSON-serialized (return JSON.stringify(value) for typeof value === "string") so
that applyConstMetadata's constValue preserves JSON-style representation, while
constComparableValue continues to be produced by
buildSchemaConstComparableValue; adjust only formatSchemaConstValue (referenced
by applyConstMetadata, constValue, and buildSchemaConstComparableValue) to
ensure string consts are shown as quoted JSON in diagnostics.
- Around line 551-571: The comparator uses String.prototype.localeCompare which
yields culture-dependent ordering; change it to an ordinal (code-unit)
comparison so ordering matches the C# runtime. In
buildSchemaConstObjectComparableValue replace
objectEntries.sort((left,right)=>left[0].localeCompare(right[0])) with an
ordinal comparator such as objectEntries.sort((l,r)=> l[0] === r[0] ? 0 : l[0] <
r[0] ? -1 : 1). Make the same change in buildComparableNodeValue and
buildSchemaPropertiesComparable where keys are sorted so all JS sorts use the
same ordinal (a<b ? -1 : a> b ? 1 : 0) semantics as C# string.CompareOrdinal.

In `@tools/gframework-config-tool/src/extension.js`:
- Line 1375: The code uses truthy checks and || fallbacks that treat
empty-string const values as absent; update usages around
getScalarFieldValue(propertyValue, propertySchema.constValue ||
propertySchema.defaultValue) and other spots referencing
propertySchema.constValue or constValue to use nullish coalescing (??) instead
of ||, and replace truthy checks like if (constValue) with explicit !==
undefined checks (or constValue !== undefined && constValue !== null where
appropriate) so that const: "" is preserved for initial values and validation;
apply these fixes to the occurrences noted (around getScalarFieldValue, and the
blocks at the other listed lines).

---

Nitpick comments:
In `@GFramework.Game.Tests/Config/YamlConfigLoaderTests.cs`:
- Around line 366-410: The test
LoadAsync_Should_Throw_When_Scalar_Value_Does_Not_Match_Schema_Const only
asserts exception message substrings; update it to also assert the structured
Diagnostic fields on the thrown ConfigLoadException (e.g. check
exception.Diagnostics or the Diagnostic object for FailureKind, DisplayPath and
RawValue) so the contract for const failures is fixed; locate the assertion
block after Assert.ThrowsAsync for ConfigLoadException and add assertions that
FailureKind equals the expected kind (e.g. ConstantMismatch), DisplayPath points
to "monster/rarity" (or the schema path used), and RawValue equals "rare" (the
actual bad value) and still assert registry.Count == 0; apply the same pattern
to the other const-related tests mentioned.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 12010b93-35f2-4c33-a00a-33be48311b49

📥 Commits

Reviewing files that changed from the base of the PR and between 50161a2 and 0320404.

📒 Files selected for processing (11)
  • GFramework.Game.Tests/Config/YamlConfigLoaderTests.cs
  • GFramework.Game/Config/YamlConfigSchemaValidator.cs
  • GFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorSnapshotTests.cs
  • GFramework.SourceGenerators.Tests/Config/snapshots/SchemaConfigGenerator/MonsterConfig.g.txt
  • GFramework.SourceGenerators/Config/SchemaConfigGenerator.cs
  • docs/zh-CN/game/config-system.md
  • tools/gframework-config-tool/src/configValidation.js
  • tools/gframework-config-tool/src/extension.js
  • tools/gframework-config-tool/src/localization.js
  • tools/gframework-config-tool/src/localizationKeys.js
  • tools/gframework-config-tool/test/configValidation.test.js
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Sourcery review
  • GitHub Check: Code Quality & Security
  • GitHub Check: Build and Test
  • GitHub Check: Analyze (C#)
🧰 Additional context used
📓 Path-based instructions (7)
**/*.cs

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.cs: LoggerGenerator must automatically generate log fields and logging helper methods for classes decorated with [Log] attribute
PriorityGenerator must generate priority comparison implementations for classes decorated with [Priority] attribute
EnumExtensionsGenerator must generate enum extension capabilities for enums decorated with [GenerateEnumExtensions] attribute
ContextAwareGenerator must automatically implement IContextAware boilerplate logic for classes decorated with [ContextAware] attribute

**/*.cs: All public, protected, and internal types and members MUST include XML documentation comments (///) with <summary>, <param>, <returns>, <exception>, and <remarks> tags where applicable
Add inline comments for non-trivial logic, concurrency or threading behavior, performance-sensitive paths, workarounds, compatibility constraints, or edge cases in C# code
Core framework components such as Architecture, Module, System, Context, Registry, Service Module, and Lifecycle types MUST include high-level explanations of responsibilities, lifecycle, interaction with other components, why the abstraction exists, and when to use it instead of alternatives
Generated logic and generator pipelines MUST include comments explaining what is generated, why it is generated, the semantic assumptions the generator relies on, and any diagnostics or fallback behavior
Methods with non-trivial logic MUST document the core idea, key decisions, and edge case handling in C# code
Do not rely on implicit imports; declare every required using explicitly in C# files
Write null-safe code that respects nullable annotations instead of suppressing warnings by default in C# files
Use the namespace pattern GFramework.{Module}.{Feature} with PascalCase segments in C# code
Follow standard C# naming: Types, methods, properties, events, and constants use PascalCase; Interfaces use I prefix; Parameters and locals use camelCase; Private fields use _camelCase
Use 4 spaces for i...

Files:

  • GFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorSnapshotTests.cs
  • GFramework.SourceGenerators/Config/SchemaConfigGenerator.cs
  • GFramework.Game.Tests/Config/YamlConfigLoaderTests.cs
  • GFramework.Game/Config/YamlConfigSchemaValidator.cs
**/*.Tests/**/*.cs

📄 CodeRabbit inference engine (AGENTS.md)

**/*.Tests/**/*.cs: Every non-trivial feature, bug fix, or behavior change MUST include tests or an explicit justification for why a test is not practical
Public API changes must be covered by unit or integration tests
When a public API defines multiple contract branches, tests MUST cover the meaningful variants, including null, empty, default, and filtered inputs when those branches change behavior
Regression fixes should include a test that fails before the fix and passes after it
Mirror the source structure in test projects whenever practical
Reuse existing architecture test infrastructure when relevant: ArchitectureTestsBase<T>, SyncTestArchitecture, AsyncTestArchitecture
Keep tests focused on observable behavior, not implementation trivia

Files:

  • GFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorSnapshotTests.cs
  • GFramework.Game.Tests/Config/YamlConfigLoaderTests.cs
**/*.SourceGenerators.Tests/**/*.cs

📄 CodeRabbit inference engine (AGENTS.md)

**/*.SourceGenerators.Tests/**/*.cs: Source generator changes MUST be covered by generator tests
Preserve snapshot-based verification patterns already used in the repository for source generator tests
When generator behavior changes intentionally, update snapshots together with the implementation in source generator tests

Files:

  • GFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorSnapshotTests.cs
docs/**/*

📄 CodeRabbit inference engine (CLAUDE.md)

Documentation must be located in docs/ directory with Chinese content in docs/zh-CN/

Files:

  • docs/zh-CN/game/config-system.md
{README.md,docs/**/*.md}

📄 CodeRabbit inference engine (AGENTS.md)

Update the relevant README.md or docs/ page when behavior, setup steps, architecture guidance, or user-facing examples change

Files:

  • docs/zh-CN/game/config-system.md
docs/**/*.md

📄 CodeRabbit inference engine (AGENTS.md)

docs/**/*.md: Keep code samples, package names, and command examples in documentation aligned with the current repository state
Prefer documenting behavior and design intent, not only API surface, in repository documentation
For integration-oriented features such as the AI-First config system, documentation MUST cover project directory layout and file conventions, required project or package wiring, minimal working usage example, and migration or compatibility notes when behavior changes
If an existing documentation page no longer reflects the current implementation, updating the documentation is part of fixing the code and cannot be deferred
Do not rely on 'the code is self-explanatory' for framework features that consumers need to adopt; write the adoption path down so future users do not need to rediscover it from source

Files:

  • docs/zh-CN/game/config-system.md
docs/zh-CN/**/*.md

📄 CodeRabbit inference engine (AGENTS.md)

When a feature is added, removed, renamed, or substantially refactored, contributors MUST update or create the corresponding user-facing integration documentation in docs/zh-CN/ in the same change

Files:

  • docs/zh-CN/game/config-system.md
🧠 Learnings (11)
📓 Common learnings
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-09T12:37:37.585Z
Learning: Applies to docs/zh-CN/**/*.md : When a feature is added, removed, renamed, or substantially refactored, contributors MUST update or create the corresponding user-facing integration documentation in `docs/zh-CN/` in the same change
📚 Learning: 2026-04-09T12:37:37.585Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-09T12:37:37.585Z
Learning: Applies to **/*.SourceGenerators.Tests/**/*.cs : When generator behavior changes intentionally, update snapshots together with the implementation in source generator tests

Applied to files:

  • GFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorSnapshotTests.cs
  • GFramework.SourceGenerators/Config/SchemaConfigGenerator.cs
📚 Learning: 2026-04-09T12:37:37.585Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-09T12:37:37.585Z
Learning: Applies to **/*.SourceGenerators.Tests/**/*.cs : Source generator changes MUST be covered by generator tests

Applied to files:

  • GFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorSnapshotTests.cs
  • GFramework.SourceGenerators/Config/SchemaConfigGenerator.cs
📚 Learning: 2026-04-09T12:37:37.585Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-09T12:37:37.585Z
Learning: Applies to **/*.SourceGenerators.Tests/**/*.cs : Preserve snapshot-based verification patterns already used in the repository for source generator tests

Applied to files:

  • GFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorSnapshotTests.cs
📚 Learning: 2026-04-09T12:37:37.585Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-09T12:37:37.585Z
Learning: Applies to **/*.Tests/**/*.cs : Public API changes must be covered by unit or integration tests

Applied to files:

  • GFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorSnapshotTests.cs
  • GFramework.Game.Tests/Config/YamlConfigLoaderTests.cs
📚 Learning: 2026-04-06T12:45:43.921Z
Learnt from: GeWuYou
Repo: GeWuYou/GFramework PR: 190
File: GFramework.Game/Config/GameConfigBootstrap.cs:1-3
Timestamp: 2026-04-06T12:45:43.921Z
Learning: In the GeWuYou/GFramework repository, C# files may omit explicit `using System*` imports because the project-wide `GlobalUsings.cs` (referenced via manual global `using` directives) supplies common namespaces (e.g., `System`, `System.Threading`, `System.Threading.Tasks`). During code review, do not flag missing `using System...` directives in `.cs` files as long as `GlobalUsings.cs` is present/used to provide those namespaces.

Applied to files:

  • GFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorSnapshotTests.cs
  • GFramework.SourceGenerators/Config/SchemaConfigGenerator.cs
  • GFramework.Game.Tests/Config/YamlConfigLoaderTests.cs
  • GFramework.Game/Config/YamlConfigSchemaValidator.cs
📚 Learning: 2026-04-09T12:37:37.585Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-09T12:37:37.585Z
Learning: Applies to **/*.cs : Any change to public API, lifecycle semantics, module behavior, or extension points MUST update the related XML docs

Applied to files:

  • GFramework.SourceGenerators.Tests/Config/snapshots/SchemaConfigGenerator/MonsterConfig.g.txt
  • GFramework.SourceGenerators/Config/SchemaConfigGenerator.cs
📚 Learning: 2026-04-09T12:37:37.585Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-09T12:37:37.585Z
Learning: Applies to docs/zh-CN/**/*.md : When a feature is added, removed, renamed, or substantially refactored, contributors MUST update or create the corresponding user-facing integration documentation in `docs/zh-CN/` in the same change

Applied to files:

  • docs/zh-CN/game/config-system.md
📚 Learning: 2026-04-09T12:37:37.585Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-09T12:37:37.585Z
Learning: Applies to docs/**/*.md : For integration-oriented features such as the AI-First config system, documentation MUST cover project directory layout and file conventions, required project or package wiring, minimal working usage example, and migration or compatibility notes when behavior changes

Applied to files:

  • docs/zh-CN/game/config-system.md
📚 Learning: 2026-04-05T15:30:46.211Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-05T15:30:46.211Z
Learning: Applies to **/*.cs : EnumExtensionsGenerator must generate enum extension capabilities for enums decorated with [GenerateEnumExtensions] attribute

Applied to files:

  • GFramework.SourceGenerators/Config/SchemaConfigGenerator.cs
📚 Learning: 2026-04-09T12:37:37.585Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-09T12:37:37.585Z
Learning: Applies to **/*.Tests/**/*.cs : Regression fixes should include a test that fails before the fix and passes after it

Applied to files:

  • GFramework.Game.Tests/Config/YamlConfigLoaderTests.cs
🔇 Additional comments (11)
GFramework.Game/Config/YamlConfigSchemaValidator.cs (3)

841-866: const 约束解析逻辑实现正确。

ParseConstantValue 方法与 JS 工具链保持一致的 comparable key 构建策略,在 schema 解析阶段完成预归一化,避免运行时重复解释 JSON 常量。实现清晰、符合预期。


1679-1719: 常量校验逻辑实现正确。

ValidateConstantValue 复用了 BuildComparableNodeValue 构建的稳定比较键,与 uniqueItems 使用相同的归一化策略,确保对象字段顺序、数字字面量格式等不会导致伪差异。错误消息包含 DisplayValue 便于用户定位问题。


325-331: 节点创建后附加常量约束的模式一致且清晰。

三类节点(对象、数组、标量)都采用先创建再 WithConstantValue 的模式,保持了代码一致性,便于后续扩展其他约束类型。

Also applies to: 391-396, 418-425

tools/gframework-config-tool/src/localizationKeys.js (1)

1-3: LGTM!

新增的 constMismatch 本地化键遵循现有命名模式,与 localization.js 中的消息条目配合使用。

GFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorSnapshotTests.cs (1)

91-100: 测试用例覆盖了 const 约束场景。

hp 属性同时声明了 const: 10 和其他数值约束,能够有效验证生成器在多约束共存时的文档输出行为。基于 learnings,源代码生成器更改必须有测试覆盖,此处符合要求。

GFramework.SourceGenerators.Tests/Config/snapshots/SchemaConfigGenerator/MonsterConfig.g.txt (1)

38-43: 快照正确反映了 const 约束的文档输出。

Hp 属性的 <remarks> 块现在包含 const = 10,约束顺序与 SchemaConfigGenerator.TryBuildConstraintDocumentation 的实现一致。快照与测试输入的 schema 变更同步更新,符合仓库的快照测试规范。

tools/gframework-config-tool/src/localization.js (2)

107-107: 英文本地化条目正确且一致。

新增的 webview.hint.constwebview.hint.itemConstconstMismatch 消息遵循现有模式,与其他约束提示(如 minimum、maximum)保持格式统一。

Also applies to: 121-121, 136-136


217-217: 中文本地化翻译准确。

"固定值"准确传达了 const 约束的语义,与 default(默认值)形成清晰区分。校验消息 属性"{displayPath}"必须匹配固定值 {value} 表述清晰,符合中文用户习惯。

Also applies to: 231-231, 246-246

tools/gframework-config-tool/test/configValidation.test.js (2)

68-102: const 元数据解析覆盖面不错

这段新增测试把 scalar/object/array 三类节点都覆盖到了,能有效防止 constValue 提取回归。


229-291: const 失配诊断测试设计合理

同时覆盖了标量和复合结构失配,能验证校验器在多节点场景下的诊断输出稳定性。

docs/zh-CN/game/config-system.md (1)

15-15: 文档与 const 新能力对齐完整

约束清单、运行时失败语义、轻量元数据和 VS Code 展示入口都同步到了同一页,集成信息完整且一致。

Based on learnings: When a feature is added, removed, renamed, or substantially refactored, contributors MUST update or create the corresponding user-facing integration documentation in docs/zh-CN/ in the same change.

Also applies to: 661-662, 708-709, 814-815

Comment thread GFramework.Game/Config/YamlConfigSchemaValidator.cs
Comment thread GFramework.Game/Config/YamlConfigSchemaValidator.cs
Comment thread GFramework.SourceGenerators/Config/SchemaConfigGenerator.cs Outdated
Comment thread tools/gframework-config-tool/src/configValidation.js
Comment thread tools/gframework-config-tool/src/configValidation.js
Comment thread tools/gframework-config-tool/src/extension.js Outdated
- 实现配置架构解析器,支持JSON架构到递归树的转换
- 添加YAML解析器,支持根映射、缩进嵌套对象和数组结构
- 实现配置验证诊断功能,提供架构和YAML解析验证
- 添加表单更新应用功能,支持将表单更改安全写回YAML
- 实现批编辑器字段提取,支持可编辑标量类型的识别
- 添加配置注释提取功能,将注释映射到逻辑字段路径
- 实现示例配置YAML生成功能,包含架构描述作为注释
- 添加精确十进制算术运算,用于multipleOf约束检查
- 实现标量类型兼容性验证,包括整数、数字、布尔值模式匹配
- 添加常量值元数据处理,支持工具比较对齐运行时行为
coderabbitai[bot]
coderabbitai Bot previously approved these changes Apr 10, 2026
- 定义了代码风格、注释规则和文档要求
- 规定了测试覆盖范围和安全编码准则
- 实现了配置模式解析和验证功能
- 添加了常量值比较和枚举校验逻辑
- 集成了数字范围和字符串长度验证
- 支持对象数组和嵌套结构验证

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - 我已经审查了你的修改,看起来非常好!


Sourcery 对开源项目是免费的——如果你觉得我们的评审有帮助,请考虑分享给更多人 ✨
帮我变得更有用!请在每条评论上点 👍 或 👎,我会根据你的反馈改进后续评审。
Original comment in English

Hey - I've reviewed your changes and they look great!


Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant