From 594dffdd505131c8274e30b9edbec8b35d1eccf8 Mon Sep 17 00:00:00 2001
From: GeWuYou <95328647+GeWuYou@users.noreply.github.com>
Date: Thu, 16 Apr 2026 17:34:24 +0800
Subject: [PATCH] =?UTF-8?q?feat(config):=20=E6=B7=BB=E5=8A=A0=E9=85=8D?=
=?UTF-8?q?=E7=BD=AE=20schema=20=E8=AF=8A=E6=96=AD=E5=92=8C=20VS=20Code=20?=
=?UTF-8?q?=E6=89=A9=E5=B1=95=E5=B7=A5=E5=85=B7?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- 实现了配置 schema 代码生成相关的诊断功能
- 添加了 VS Code 扩展工具用于配置文件管理和验证
- 提供配置文件树视图和表单预览功能
- 实现配置文件的批量编辑功能
- 集成 schema 验证和错误提示机制
- 支持配置文件的引用导航和快速访问
- 添加多语言本地化支持
---
.../Diagnostics/ConfigSchemaDiagnostics.cs | 11 +++++++++++
tools/gframework-config-tool/src/extension.js | 17 ++++++++++++++++-
.../gframework-config-tool/src/localization.js | 2 ++
3 files changed, 29 insertions(+), 1 deletion(-)
diff --git a/GFramework.SourceGenerators/Diagnostics/ConfigSchemaDiagnostics.cs b/GFramework.SourceGenerators/Diagnostics/ConfigSchemaDiagnostics.cs
index 3162bb6a..115ecea2 100644
--- a/GFramework.SourceGenerators/Diagnostics/ConfigSchemaDiagnostics.cs
+++ b/GFramework.SourceGenerators/Diagnostics/ConfigSchemaDiagnostics.cs
@@ -107,4 +107,15 @@ public static class ConfigSchemaDiagnostics
SourceGeneratorsConfigCategory,
DiagnosticSeverity.Error,
true);
+
+ ///
+ /// schema 对象节点的 dependentRequired 元数据无效。
+ ///
+ public static readonly DiagnosticDescriptor InvalidDependentRequiredMetadata = new(
+ "GF_ConfigSchema_010",
+ "Config schema uses invalid dependentRequired metadata",
+ "Property '{1}' in schema file '{0}' uses invalid 'dependentRequired' metadata: {2}",
+ SourceGeneratorsConfigCategory,
+ DiagnosticSeverity.Error,
+ true);
}
diff --git a/tools/gframework-config-tool/src/extension.js b/tools/gframework-config-tool/src/extension.js
index d750b04d..6f7ae9df 100644
--- a/tools/gframework-config-tool/src/extension.js
+++ b/tools/gframework-config-tool/src/extension.js
@@ -1578,7 +1578,7 @@ function getScalarArrayValue(yamlNode) {
/**
* Render human-facing metadata hints for one schema field.
*
- * @param {{type?: string, description?: string, defaultValue?: string, constValue?: string, constDisplayValue?: string, minimum?: number, exclusiveMinimum?: number, maximum?: number, exclusiveMaximum?: number, multipleOf?: number, minLength?: number, maxLength?: number, pattern?: string, format?: string, minItems?: number, maxItems?: number, minContains?: number, maxContains?: number, minProperties?: number, maxProperties?: number, uniqueItems?: boolean, enumValues?: string[], contains?: {type?: string, enumValues?: string[], constValue?: string, constDisplayValue?: string, pattern?: string, format?: string, refTable?: string}, items?: {enumValues?: string[], constValue?: string, constDisplayValue?: string, minimum?: number, exclusiveMinimum?: number, maximum?: number, exclusiveMaximum?: number, multipleOf?: number, minLength?: number, maxLength?: number, pattern?: string, format?: string}, refTable?: string}} propertySchema Property schema metadata.
+ * @param {{type?: string, description?: string, defaultValue?: string, constValue?: string, constDisplayValue?: string, minimum?: number, exclusiveMinimum?: number, maximum?: number, exclusiveMaximum?: number, multipleOf?: number, minLength?: number, maxLength?: number, pattern?: string, format?: string, minItems?: number, maxItems?: number, minContains?: number, maxContains?: number, minProperties?: number, maxProperties?: number, dependentRequired?: Record, uniqueItems?: boolean, enumValues?: string[], contains?: {type?: string, enumValues?: string[], constValue?: string, constDisplayValue?: string, pattern?: string, format?: string, refTable?: string}, items?: {enumValues?: string[], constValue?: string, constDisplayValue?: string, minimum?: number, exclusiveMinimum?: number, maximum?: number, exclusiveMaximum?: number, multipleOf?: number, minLength?: number, maxLength?: number, pattern?: string, format?: string}, refTable?: string}} propertySchema Property schema metadata.
* @param {boolean} isArrayField Whether the field is an array.
* @param {boolean} includeDescription Whether description text should be included in the hint output.
* @returns {string} HTML fragment.
@@ -1653,6 +1653,21 @@ function renderFieldHint(propertySchema, isArrayField, includeDescription = true
hints.push(escapeHtml(localizer.t("webview.hint.maxProperties", {value: propertySchema.maxProperties})));
}
+ if (propertySchema.type === "object" &&
+ propertySchema.dependentRequired &&
+ typeof propertySchema.dependentRequired === "object") {
+ for (const [trigger, dependencies] of Object.entries(propertySchema.dependentRequired)) {
+ if (!Array.isArray(dependencies) || dependencies.length === 0) {
+ continue;
+ }
+
+ hints.push(escapeHtml(localizer.t("webview.hint.dependentRequired", {
+ trigger,
+ dependencies: dependencies.join(", ")
+ })));
+ }
+ }
+
if (isArrayField && typeof propertySchema.minItems === "number") {
hints.push(escapeHtml(localizer.t("webview.hint.minItems", {value: propertySchema.minItems})));
}
diff --git a/tools/gframework-config-tool/src/localization.js b/tools/gframework-config-tool/src/localization.js
index 3cbbb26d..ad4edfe3 100644
--- a/tools/gframework-config-tool/src/localization.js
+++ b/tools/gframework-config-tool/src/localization.js
@@ -139,6 +139,7 @@ const enMessages = {
"webview.unsupported.objectArrayMixed": "Object-array items must be mappings. Use raw YAML if the current file mixes scalar and object items.",
"webview.unsupported.nestedObjectArray": "Nested object-array fields are currently raw-YAML-only inside the object-array editor.",
[ValidationMessageKeys.constMismatch]: "Property '{displayPath}' must match constant value {value}.",
+ [ValidationMessageKeys.dependentRequiredViolation]: "Property '{displayPath}' is required when sibling property '{triggerProperty}' is present.",
[ValidationMessageKeys.exclusiveMaximumViolation]: "Property '{displayPath}' must be less than {value}.",
[ValidationMessageKeys.exclusiveMinimumViolation]: "Property '{displayPath}' must be greater than {value}.",
[ValidationMessageKeys.maximumViolation]: "Property '{displayPath}' must be less than or equal to {value}.",
@@ -258,6 +259,7 @@ const zhCnMessages = {
"webview.unsupported.objectArrayMixed": "对象数组中的每一项都必须是映射对象。如果当前文件混用了标量项和对象项,请改用原始 YAML。",
"webview.unsupported.nestedObjectArray": "对象数组编辑器内暂不支持更深层的对象数组字段,请改用原始 YAML。",
[ValidationMessageKeys.constMismatch]: "属性“{displayPath}”必须匹配固定值 {value}。",
+ [ValidationMessageKeys.dependentRequiredViolation]: "属性“{triggerProperty}”存在时,必须同时声明属性“{displayPath}”。",
[ValidationMessageKeys.exclusiveMaximumViolation]: "属性“{displayPath}”必须小于 {value}。",
[ValidationMessageKeys.exclusiveMinimumViolation]: "属性“{displayPath}”必须大于 {value}。",
[ValidationMessageKeys.maximumViolation]: "属性“{displayPath}”必须小于或等于 {value}。",