@dongmingzhixiu/vuexir-compiler 0.3.17 → 0.3.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -434,6 +434,21 @@ function kotlinCondExpr(expr) {
434
434
  return `vrnField(${f[1]}, "${f[2]}").isNotEmpty()`;
435
435
  let s = expr.replace(/!==/g, '!=').replace(/===/g, '==');
436
436
  s = s.replace(/'(\\[^]|[^'\\])*'/g, (m) => '"' + m.slice(1, -1).replace(/"/g, '\\"') + '"');
437
+ // R113:对象字段条件 → vrnField 取值判空
438
+ const negField = s.match(/^!([A-Za-z_$][\w$]*)\.([A-Za-z_$][\w$]*)$/);
439
+ if (negField)
440
+ return `vrnField(${negField[1]}, "${negField[2]}").isEmpty()`;
441
+ const posField = s.match(/^([A-Za-z_$][\w$]*)\.([A-Za-z_$][\w$]*)$/);
442
+ if (posField)
443
+ return `vrnField(${posField[1]}, "${posField[2]}").isNotEmpty()`;
444
+ const cmpField = s.match(/^([A-Za-z_$][\w$]*)\.([A-Za-z_$][\w$]*)\s*(==|!=)\s*(.+)$/);
445
+ if (cmpField)
446
+ return `vrnField(${cmpField[1]}, "${cmpField[2]}") ${cmpField[3]} ${cmpField[4]}`;
447
+ const andExpr = s.match(/^([A-Za-z_$][\w$.]*)\s*&&\s*([A-Za-z_$][\w$.]*)$/);
448
+ if (andExpr) {
449
+ const truthy = (v) => v.includes('.') ? `vrnField(${v.split('.')[0]}, "${v.split('.').slice(1).join('.')}").isNotEmpty()` : `${v}.toString().isNotEmpty()`;
450
+ return `${truthy(andExpr[1])} && ${truthy(andExpr[2])}`;
451
+ }
437
452
  // R111:Kotlin 不接受 String/Int 当条件 → 统一判真
438
453
  const neg = s.match(/^!([A-Za-z_$][\w$]*)(?:\.length)?$/);
439
454
  if (neg)
@@ -446,7 +461,8 @@ function kotlinCondExpr(expr) {
446
461
  }
447
462
  /** Swift 风格字符串表达式 → Kotlin(三元 c ? a : b → if (c) a else b;引号归一双引号) */
448
463
  function kotlinStringExpr(expr) {
449
- let s = expr.replace(/'(\\[^]|[^'\\])*'/g, (m) => '"' + m.slice(1, -1).replace(/"/g, '\\"') + '"');
464
+ let s0 = expr.replace(/vrnTruthy\(String\(([A-Za-z_$][\w$]*)\)\)/g, (_m, id) => `vrnTruthy(${id}.toString())`);
465
+ let s = s0.replace(/'(\\[^]|[^'\\])*'/g, (m) => '"' + m.slice(1, -1).replace(/"/g, '\\"') + '"');
450
466
  const ternary = s.match(/^([^?]+)\?([^:]+):(.+)$/);
451
467
  if (ternary) {
452
468
  return `if (${ternary[1].trim()}) ${ternary[2].trim()} else ${ternary[3].trim()}`;
@@ -1196,7 +1212,7 @@ function emitNodeInner(node, ctx, depth, loop, useParamModifier = false, parentS
1196
1212
  case 'button': {
1197
1213
  const chain = modChain([...stretchModifiers(parentStretch, node), ...sizeModifiers(p), ...absModifiers(p), ...clipModifiers(p), ...visualModifiers(p), ...borderModifiers(p), ...paddingModifiers(p), ...alphaArr, ...transformModifiers(p)], pad + ' ');
1198
1214
  // R108:动态按钮文案(props.bind)优先;Kotlin 里用字符串模板插值
1199
- const label = p.bind !== undefined ? '"${' + String(p.bind) + '}"' : (p.label ?? '');
1215
+ const label = p.bind !== undefined ? String(p.bind) : (p.label ?? '');
1200
1216
  const click = kotlinClickAction(p, ctx, loop);
1201
1217
  const labelStyle = [];
1202
1218
  if (p.fontSize !== undefined)
@@ -527,6 +527,17 @@ function swiftCondExpr(expr) {
527
527
  // R110:数值状态直接当条件(Swift 不接受 Int 当 Bool)
528
528
  if (/^[A-Za-z_$][\w$]*$/.test(s))
529
529
  return `vrnTruthy(String(${s}))`;
530
+ // R113:对象字段条件(form.avatarData)→ 走 vrnField 取 JSON 字段
531
+ const negField = s.match(/^!([A-Za-z_$][\w$]*)\.([A-Za-z_$][\w$]*)$/);
532
+ if (negField)
533
+ return `vrnField(${negField[1]}, "${negField[2]}").isEmpty`;
534
+ const posField = s.match(/^([A-Za-z_$][\w$]*)\.([A-Za-z_$][\w$]*)$/);
535
+ if (posField)
536
+ return `!vrnField(${posField[1]}, "${posField[2]}").isEmpty`;
537
+ // R113:对象字段比较(form.calendar == "gregorian")→ vrnField 取值后比较
538
+ const cmpField = s.match(/^([A-Za-z_$][\w$]*)\.([A-Za-z_$][\w$]*)\s*(==|!=)\s*(.+)$/);
539
+ if (cmpField)
540
+ return `vrnField(${cmpField[1]}, "${cmpField[2]}") ${cmpField[3]} ${cmpField[4]}`;
530
541
  // R110:裸标识符条件(状态可能是字符串/对象/布尔)→ 统一走判真
531
542
  if (/^[A-Za-z_$][\w$]*$/.test(s) && !['true', 'false'].includes(s))
532
543
  return `vrnTruthy(String(${s}))`;
@@ -1413,6 +1413,10 @@ function matchFieldPath(name) {
1413
1413
  }
1414
1414
  function parseTernaryExpr(exp) {
1415
1415
  const t = exp.trim();
1416
+ // R113:三元里出现对象字段访问(form.avatarData)时,静态翻译做不到 →
1417
+ // 直接返回 null,交给表达式下沉在 JS 运行时求值(结果一致且两端都能用)
1418
+ if (/[A-Za-z_$][\w$]*\.[A-Za-z_$][\w$]*/.test(t))
1419
+ return null;
1416
1420
  const m = t.match(/^(.+?)\s*\?\s*'([^']+)'\s*:\s*'([^']+)'$/);
1417
1421
  if (!m)
1418
1422
  return null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dongmingzhixiu/vuexir-compiler",
3
- "version": "0.3.17",
3
+ "version": "0.3.18",
4
4
  "description": "Vue SFC → IR → 原生源码(SwiftUI / Compose)编译器核心:纯函数、零 IO",
5
5
  "type": "module",
6
6
  "license": "MIT",