@dongmingzhixiu/vuexir-compiler 0.3.16 → 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.
- package/dist/codegen/compose.js +28 -4
- package/dist/codegen/swiftui.js +17 -0
- package/dist/transform/vue2ir.js +9 -1
- package/package.json +1 -1
package/dist/codegen/compose.js
CHANGED
|
@@ -434,11 +434,35 @@ 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
|
+
}
|
|
452
|
+
// R111:Kotlin 不接受 String/Int 当条件 → 统一判真
|
|
453
|
+
const neg = s.match(/^!([A-Za-z_$][\w$]*)(?:\.length)?$/);
|
|
454
|
+
if (neg)
|
|
455
|
+
return `vrnTruthy(${neg[1]}.toString()).not()`;
|
|
456
|
+
if (/^[A-Za-z_$][\w$]*\.length$/.test(s))
|
|
457
|
+
return `${s} > 0`;
|
|
458
|
+
if (/^[A-Za-z_$][\w$]*$/.test(s) && !['true', 'false'].includes(s))
|
|
459
|
+
return `vrnTruthy(${s}.toString())`;
|
|
437
460
|
return s;
|
|
438
461
|
}
|
|
439
462
|
/** Swift 风格字符串表达式 → Kotlin(三元 c ? a : b → if (c) a else b;引号归一双引号) */
|
|
440
463
|
function kotlinStringExpr(expr) {
|
|
441
|
-
let
|
|
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, '\\"') + '"');
|
|
442
466
|
const ternary = s.match(/^([^?]+)\?([^:]+):(.+)$/);
|
|
443
467
|
if (ternary) {
|
|
444
468
|
return `if (${ternary[1].trim()}) ${ternary[2].trim()} else ${ternary[3].trim()}`;
|
|
@@ -1034,10 +1058,10 @@ function emitNodeInner(node, ctx, depth, loop, useParamModifier = false, parentS
|
|
|
1034
1058
|
pre += cpad + 'Spacer(\n' + cpad + ' modifier = Modifier.width(' + dp(cp.marginLeft) + '),\n' + cpad + ')\n';
|
|
1035
1059
|
}
|
|
1036
1060
|
if (kind === 'Row' && cp.marginRight !== undefined) {
|
|
1037
|
-
post = post + cpad + 'Spacer(\n' + cpad + ' modifier = Modifier.width(' + dp(cp.marginRight) + '),\n' + cpad + ')\n';
|
|
1061
|
+
post = post + '\n' + cpad + 'Spacer(\n' + cpad + ' modifier = Modifier.width(' + dp(cp.marginRight) + '),\n' + cpad + ')\n';
|
|
1038
1062
|
}
|
|
1039
1063
|
if (kind === 'Column' && cp.marginBottom !== undefined) {
|
|
1040
|
-
post = post + cpad + 'Spacer(\n' + cpad + ' modifier = Modifier.height(' + dp(cp.marginBottom) + '),\n' + cpad + ')\n';
|
|
1064
|
+
post = post + '\n' + cpad + 'Spacer(\n' + cpad + ' modifier = Modifier.height(' + dp(cp.marginBottom) + '),\n' + cpad + ')\n';
|
|
1041
1065
|
}
|
|
1042
1066
|
const stretch = kind === 'Column' && cp.width === undefined && cp.flex === undefined && cp.position !== 'absolute' && !cp.marginLeftAuto;
|
|
1043
1067
|
return pre + emitNode(c, ctx, d, undefined, false, stretch) + post;
|
|
@@ -1188,7 +1212,7 @@ function emitNodeInner(node, ctx, depth, loop, useParamModifier = false, parentS
|
|
|
1188
1212
|
case 'button': {
|
|
1189
1213
|
const chain = modChain([...stretchModifiers(parentStretch, node), ...sizeModifiers(p), ...absModifiers(p), ...clipModifiers(p), ...visualModifiers(p), ...borderModifiers(p), ...paddingModifiers(p), ...alphaArr, ...transformModifiers(p)], pad + ' ');
|
|
1190
1214
|
// R108:动态按钮文案(props.bind)优先;Kotlin 里用字符串模板插值
|
|
1191
|
-
const label = p.bind !== undefined ?
|
|
1215
|
+
const label = p.bind !== undefined ? String(p.bind) : (p.label ?? '');
|
|
1192
1216
|
const click = kotlinClickAction(p, ctx, loop);
|
|
1193
1217
|
const labelStyle = [];
|
|
1194
1218
|
if (p.fontSize !== undefined)
|
package/dist/codegen/swiftui.js
CHANGED
|
@@ -527,9 +527,26 @@ 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}))`;
|
|
544
|
+
// R112:循环项字段的 && 组合(item && item.cd)→ 判真
|
|
545
|
+
const andExpr = s.match(/^([A-Za-z_$][\w$.]*)\s*&&\s*([A-Za-z_$][\w$.]*)$/);
|
|
546
|
+
if (andExpr) {
|
|
547
|
+
const truthy = (v) => (v.includes('.') ? `!vrnField(${v.split('.')[0]}, "${v.split('.').slice(1).join('.')}").isEmpty` : `vrnTruthy(String(${v}))`);
|
|
548
|
+
return `${truthy(andExpr[1])} && ${truthy(andExpr[2])}`;
|
|
549
|
+
}
|
|
533
550
|
return s;
|
|
534
551
|
}
|
|
535
552
|
function emitNodeInner(node, ctx) {
|
package/dist/transform/vue2ir.js
CHANGED
|
@@ -1413,12 +1413,20 @@ 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;
|
|
1419
|
-
|
|
1423
|
+
let cond = swiftExpr(m[1]);
|
|
1420
1424
|
if (cond === null)
|
|
1421
1425
|
return null;
|
|
1426
|
+
// R112:三元条件里的字符串/数字状态要判真(Swift/Kotlin 不接受非 Bool 条件)
|
|
1427
|
+
if (/^[A-Za-z_$][\w$]*$/.test(cond) && !['true', 'false'].includes(cond)) {
|
|
1428
|
+
cond = `vrnTruthy(String(${cond}))`;
|
|
1429
|
+
}
|
|
1422
1430
|
return `${cond} ? "${m[2]}" : "${m[3]}"`;
|
|
1423
1431
|
}
|
|
1424
1432
|
/**
|