From 6ef079365a88dd1edc29770bfb6a2152c493f2b4 Mon Sep 17 00:00:00 2001 From: JianFeeeee Date: Sun, 20 Sep 2026 13:42:51 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B7=A8=E7=AB=AF:=20=E4=BF=AE=E3=80=8C?= =?UTF-8?q?=E4=B8=A4=E4=B8=AA=E5=8A=A8=E4=BD=9C=E7=90=83=E4=B8=8D=E8=83=BD?= =?UTF-8?q?=E9=87=8D=E5=8F=A0=E3=80=8D=E9=82=A3=E6=9D=A1=E5=88=A4=E6=8D=AE?= =?UTF-8?q?=E8=87=AA=E8=BA=AB=EF=BC=88=E5=AE=83=E7=9A=84=E7=BB=93=E6=9D=9F?= =?UTF-8?q?=E8=BE=B9=E7=95=8C=E6=8A=8A=E5=87=A0=E5=8D=81=E8=A1=8C=E5=A4=96?= =?UTF-8?q?=E7=9A=84=E4=B8=9C=E8=A5=BF=E4=B9=9F=E5=90=83=E8=BF=9B=E6=9D=A5?= =?UTF-8?q?=E4=BA=86=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 上一步扩 Unicode 图标扫描面时,这条判据立刻报: MailDetailPage.ets:664(Stack 里有 2 个圆角元素且没有 Row 包住) 而 L664 那个 `Stack` 是**新加的返回键**,里面**只有一个子元素**(chevron 图标)。 查清根因(判据自身两个缺陷): ① **结束边界靠猜缩进**:原来写 `\n\s{8}\}` —— "8 空格 + 右括号"。 而那个 Stack 的 `}` 缩进是 10 空格、它下面还有一整段同缩进的兄弟节点 ⇒ 非贪婪匹配一路吃到**下一个** 8 空格的 `}`, 把几十行外两行的**小徽标**(权限/未读,`.borderRadius(4)`)也算了进来。 ⇒ 改成**按大括号配平**取块。缩进是可变的,配平是语法事实。 ② **"圆角"被当成"圆球"**:原判据数的是所有 `.borderRadius(\d+)`。 而 `borderRadius(4)` 是**圆角方**(徽标),根本不是球。 本判据要防的是"两个**球**叠在同一个角",不是"任何带圆角的东西"。 ⇒ 只认 `borderRadius(N)` 且 **N ≥ 16** 的(动作球是 24/28 那一档)。 ★ 改完做了**变异验证**(判据自己的要求:必须"在变异下咬得住"): 把包着两个球的 `Row({ space: 12 })` 拆掉、让它们直接待在 `Stack` 里 —— 判据**立刻转红**(30→29 pass/1 fail);还原后 30 pass。 这说明它测的还是原来那件事,只是不再误伤。 --- client/electron/test/harmony-admin.test.mjs | 48 ++++++++++++++++++--- 1 file changed, 42 insertions(+), 6 deletions(-) diff --git a/client/electron/test/harmony-admin.test.mjs b/client/electron/test/harmony-admin.test.mjs index 1c28af4..7f09f4a 100644 --- a/client/electron/test/harmony-admin.test.mjs +++ b/client/electron/test/harmony-admin.test.mjs @@ -760,14 +760,50 @@ test('★ 详情页的两个动作球必须**分开摆**(Stack 的同一个角 * 简化判定:在同一个 Stack 块内出现 ≥2 处 `.borderRadius(` + 各自 `.margin(` * 而没有包在 Row 里。 */ - const stackBlocks = [...src.matchAll(/Stack\(\{[^}]*alignContent[^}]*\}\)\s*\{([\s\S]*?)\n\s{8}\}/g)]; + /* + * ★★ 2026-09-20 修(判据自身的缺陷,扩展扫描面时暴露出来的)。 + * + * 原来的结束边界写的是 `\n\s{8}\}` —— "8 个空格 + 右括号"。 + * 这个边界**远早于** Stack 真正的收尾(那个 Stack 的 `}` 只有 10 空格缩进, + * 但它下面还有一整段同缩进的兄弟节点)⇒ 非贪婪匹配会一路吃到**下一个** + * 缩进 8 空格的 `}`,把几十行不相干的内容(权限/未读**徽标**的 + * `.borderRadius(4)`)也算成"Stack 里的圆形按钮"。 + * + * 实测后果:我在返回键那里新加了一个 `Stack({ alignContent: Center })` + * (**只有一个子元素**:chevron 图标),判据立刻报 + * 「Stack 里有 2 个圆角元素且没有 Row 包住」—— 那 2 个是页面下方两行的 + * 小徽标(`borderRadius(4)`,圆角方,根本不是圆球)。 + * + * 两处修: + * ① **按大括号配平**取块,而不是猜缩进 —— 缩进是可变的,配平是语法事实。 + * ② 只在**直接子元素**层找圆球(`borderRadius(N)` 且 N 足够大、是圆角)。 + * 徽标那种 `borderRadius(4)` 的圆角方不该算进来:本判据要防的是 + * "两个**圆球**叠在同一个角",不是"任何带圆角的东西"。 + */ + const blockOf = (from) => { + let depth = 0, started = false; + for (let i = from; i < src.length; i++) { + const ch = src[i]; + if (ch === '{') { depth++; started = true; } + else if (ch === '}') { + depth--; + if (started && depth === 0) return src.slice(from, i + 1); + } + } + return ''; + }; const bad = []; - for (const m of stackBlocks) { - const body = m[1]; - const circles = (body.match(/\.borderRadius\(\d+\)/g) ?? []).length; - if (circles >= 2 && !/Row\(\{\s*space:/.test(body)) { + for (const m of src.matchAll(/Stack\(\{[^}]*alignContent[^}]*\}\)\s*\{/g)) { + const body = blockOf(m.index + m[0].length - 1); + /* + * 只认**圆**:`.borderRadius(N)` 的 N ≥ 16(动作球是 24/28 这一档)。 + * 小徽标的 `borderRadius(4)` 是圆角方,不是"球",不能算。 + */ + const radii = [...body.matchAll(/\.borderRadius\((\d+)\)/g)].map(x => Number(x[1])); + const balls = radii.filter(r => r >= 16).length; + if (balls >= 2 && !/Row\(\{\s*space:/.test(body)) { const line = src.slice(0, m.index).split('\n').length; - bad.push(`MailDetailPage.ets:${line}(Stack 里有 ${circles} 个圆角元素且没有 Row 包住)`); + bad.push(`MailDetailPage.ets:${line}(Stack 里有 ${balls} 个圆角球且没有 Row 包住)`); } } assert.deepEqual(bad, [],