@dongmingzhixiu/vuexir-compiler 0.3.14 → 0.3.15
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
CHANGED
|
@@ -150,6 +150,8 @@ const RUNTIME_KT = (bundleId) => `package ${bundleId}
|
|
|
150
150
|
/** R73 持久化桥:对位 iOS runtime 的 localStorage(UserDefaults)—— SharedPreferences 同步读写 */
|
|
151
151
|
/** R78 对象字段取值:状态里存 JSON 字符串时按 key 取值 */
|
|
152
152
|
// R85 点路径取值:path 支持 "a.b.c",末段可为 length/size(数组/对象/字符串长度)
|
|
153
|
+
fun vrnTruthy(v: String): Boolean = v.isNotEmpty() && v != "false" && v != "0" && v != "null" && v != "undefined"
|
|
154
|
+
|
|
153
155
|
fun vrnField(json: String, path: String, fallback: String = ""): String {
|
|
154
156
|
val raw = vrnFieldRaw(json, path)
|
|
155
157
|
return if (raw.isEmpty()) fallback else raw
|
|
@@ -840,6 +842,10 @@ function asyncLineKotlin(line, ctx) {
|
|
|
840
842
|
return arg === null ? null : `VrnBridge.${bm[1]}(${arg})`;
|
|
841
843
|
}
|
|
842
844
|
// G15 router 语句:router.push('x') / router.back() → Runtime.push / Runtime.back
|
|
845
|
+
// router.push({ name: 'x' }) → Runtime.push("x")(对象参数取 name/path)
|
|
846
|
+
const rpObj = line.match(/^router\.push\(\s*\{\s*(?:name|path)\s*:\s*'([^']+)'[^}]*\}\s*\);?$/);
|
|
847
|
+
if (rpObj)
|
|
848
|
+
return `Runtime.push("${rpObj[1]}")`;
|
|
843
849
|
const rp = line.match(/^router\.push\((.+)\);?$/);
|
|
844
850
|
if (rp) {
|
|
845
851
|
const a = jsExprToKotlin(rp[1].trim());
|
|
@@ -36,7 +36,7 @@ export declare function buildTheme(tokens: {
|
|
|
36
36
|
fontNames: Map<string, string>;
|
|
37
37
|
};
|
|
38
38
|
/** R42 生成 Theme.swift(颜色/字体去重常量) */
|
|
39
|
-
export declare const VRN_HELPERS_SWIFT = "import Foundation\n\n// vuexir \u8FD0\u884C\u65F6\u8F85\u52A9\uFF08R78 \u5BF9\u8C61\u5B57\u6BB5\u53D6\u503C\uFF09\n/// R78 \u5BF9\u8C61\u5B57\u6BB5\u53D6\u503C\uFF1A\u72B6\u6001\u91CC\u5B58 JSON \u5B57\u7B26\u4E32\u65F6\u6309 key \u53D6\u503C\uFF08\u975E JSON \u2192 \u8FD4\u56DE\u7A7A\u4E32\uFF09\n/// R85 \u70B9\u8DEF\u5F84\u53D6\u503C\uFF1Akey \u652F\u6301 \"a.b.c\" \u4E0E\u672B\u6BB5 \".length\"\uFF08\u6570\u7EC4/\u5B57\u5178/\u5B57\u7B26\u4E32\u957F\u5EA6\uFF09\nfunc vrnField(_ json: String, _ path: String, _ fallback: String = \"\") -> String {\n let raw = vrnFieldRaw(json, path)\n return raw.isEmpty ? fallback : raw\n}\n\n/// \u539F\u59CB\u53D6\u503C\uFF08\u4E0D\u5957\u515C\u5E95\uFF09\uFF1A\u70B9\u8DEF\u5F84\u4E0B\u94BB\uFF0C\u7F3A\u5931\u8FD4\u56DE\u7A7A\u4E32\nprivate func vrnFieldRaw(_ json: String, _ path: String) -> String {\n guard let data = json.data(using: .utf8),\n let root = try? JSONSerialization.jsonObject(with: data, options: [.fragmentsAllowed]) else { return \"\" }\n var cur: Any = root\n for seg in path.split(separator: \".\").map(String.init) {\n if seg == \"length\" || seg == \"size\" {\n if let a = cur as? [Any] { cur = a.count }\n else if let d = cur as? [String: Any] { cur = d.count }\n else if let s = cur as? String { cur = s.count }\n else { return \"\" }\n continue\n }\n if let d = cur as? [String: Any], let next = d[seg] { cur = next } else { return \"\" }\n }\n if let s = cur as? String { return s }\n if let b = cur as? Bool { return b ? \"true\" : \"false\" }\n if let n = cur as? NSNumber { return n.stringValue }\n return String(describing: cur)\n}\n";
|
|
39
|
+
export declare const VRN_HELPERS_SWIFT = "import Foundation\n\n// vuexir \u8FD0\u884C\u65F6\u8F85\u52A9\uFF08R78 \u5BF9\u8C61\u5B57\u6BB5\u53D6\u503C\uFF09\n/// R78 \u5BF9\u8C61\u5B57\u6BB5\u53D6\u503C\uFF1A\u72B6\u6001\u91CC\u5B58 JSON \u5B57\u7B26\u4E32\u65F6\u6309 key \u53D6\u503C\uFF08\u975E JSON \u2192 \u8FD4\u56DE\u7A7A\u4E32\uFF09\n/// R85 \u70B9\u8DEF\u5F84\u53D6\u503C\uFF1Akey \u652F\u6301 \"a.b.c\" \u4E0E\u672B\u6BB5 \".length\"\uFF08\u6570\u7EC4/\u5B57\u5178/\u5B57\u7B26\u4E32\u957F\u5EA6\uFF09\n/// R110 \u5224\u771F\uFF1AJS \u91CC\u7684 truthiness \u8FD1\u4F3C\uFF08\u7A7A\u4E32/\"false\"/\"0\"/\"null\" \u4E3A\u5047\uFF09\nfunc vrnTruthy(_ v: String) -> Bool {\n if v.isEmpty { return false }\n if v == \"false\" || v == \"0\" || v == \"null\" || v == \"undefined\" { return false }\n return true\n}\n\nfunc vrnField(_ json: String, _ path: String, _ fallback: String = \"\") -> String {\n let raw = vrnFieldRaw(json, path)\n return raw.isEmpty ? fallback : raw\n}\n\n/// \u539F\u59CB\u53D6\u503C\uFF08\u4E0D\u5957\u515C\u5E95\uFF09\uFF1A\u70B9\u8DEF\u5F84\u4E0B\u94BB\uFF0C\u7F3A\u5931\u8FD4\u56DE\u7A7A\u4E32\nprivate func vrnFieldRaw(_ json: String, _ path: String) -> String {\n guard let data = json.data(using: .utf8),\n let root = try? JSONSerialization.jsonObject(with: data, options: [.fragmentsAllowed]) else { return \"\" }\n var cur: Any = root\n for seg in path.split(separator: \".\").map(String.init) {\n if seg == \"length\" || seg == \"size\" {\n if let a = cur as? [Any] { cur = a.count }\n else if let d = cur as? [String: Any] { cur = d.count }\n else if let s = cur as? String { cur = s.count }\n else { return \"\" }\n continue\n }\n if let d = cur as? [String: Any], let next = d[seg] { cur = next } else { return \"\" }\n }\n if let s = cur as? String { return s }\n if let b = cur as? Bool { return b ? \"true\" : \"false\" }\n if let n = cur as? NSNumber { return n.stringValue }\n return String(describing: cur)\n}\n";
|
|
40
40
|
export declare function generateThemeSource(palette: {
|
|
41
41
|
colorNames: Map<string, string>;
|
|
42
42
|
fontNames: Map<string, string>;
|
package/dist/codegen/swiftui.js
CHANGED
|
@@ -121,6 +121,13 @@ export const VRN_HELPERS_SWIFT = `import Foundation
|
|
|
121
121
|
// vuexir 运行时辅助(R78 对象字段取值)
|
|
122
122
|
/// R78 对象字段取值:状态里存 JSON 字符串时按 key 取值(非 JSON → 返回空串)
|
|
123
123
|
/// R85 点路径取值:key 支持 "a.b.c" 与末段 ".length"(数组/字典/字符串长度)
|
|
124
|
+
/// R110 判真:JS 里的 truthiness 近似(空串/"false"/"0"/"null" 为假)
|
|
125
|
+
func vrnTruthy(_ v: String) -> Bool {
|
|
126
|
+
if v.isEmpty { return false }
|
|
127
|
+
if v == "false" || v == "0" || v == "null" || v == "undefined" { return false }
|
|
128
|
+
return true
|
|
129
|
+
}
|
|
130
|
+
|
|
124
131
|
func vrnField(_ json: String, _ path: String, _ fallback: String = "") -> String {
|
|
125
132
|
let raw = vrnFieldRaw(json, path)
|
|
126
133
|
return raw.isEmpty ? fallback : raw
|
|
@@ -507,7 +514,22 @@ function swiftCondExpr(expr) {
|
|
|
507
514
|
if (f)
|
|
508
515
|
return `!vrnField(${f[1]}, "${f[2]}").isEmpty`;
|
|
509
516
|
let s = expr.replace(/!==/g, '!=').replace(/===/g, '==');
|
|
510
|
-
s = s.replace(/'(
|
|
517
|
+
s = s.replace(/'(\[^]|[^'\\])*'/g, (m) => '"' + m.slice(1, -1).replace(/"/g, '\\"') + '"');
|
|
518
|
+
// R110:`.length` → Swift `.count`
|
|
519
|
+
s = s.replace(/\.length\b/g, '.count');
|
|
520
|
+
// R110:非布尔条件(字符串/数量)→ 真值比较
|
|
521
|
+
if (/^[A-Za-z_$][\w$]*\.count$/.test(s))
|
|
522
|
+
return `${s} > 0`;
|
|
523
|
+
// R110:取反的长度条件 → == 0
|
|
524
|
+
const neg = s.match(/^!([A-Za-z_$][\w$]*)\.count$/);
|
|
525
|
+
if (neg)
|
|
526
|
+
return `${neg[1]}.count == 0`;
|
|
527
|
+
// R110:数值状态直接当条件(Swift 不接受 Int 当 Bool)
|
|
528
|
+
if (/^[A-Za-z_$][\w$]*$/.test(s))
|
|
529
|
+
return `vrnTruthy(String(${s}))`;
|
|
530
|
+
// R110:裸标识符条件(状态可能是字符串/对象/布尔)→ 统一走判真
|
|
531
|
+
if (/^[A-Za-z_$][\w$]*$/.test(s) && !['true', 'false'].includes(s))
|
|
532
|
+
return `vrnTruthy(String(${s}))`;
|
|
511
533
|
return s;
|
|
512
534
|
}
|
|
513
535
|
function emitNodeInner(node, ctx) {
|
package/dist/transform/vue2ir.js
CHANGED
|
@@ -154,7 +154,7 @@ export function extractScreenState(script) {
|
|
|
154
154
|
}
|
|
155
155
|
// R85 对象态:const board = ref({ month: { label: '10 月' }, tags: '生日' })
|
|
156
156
|
// init 存规范化 JSON 字符串(双端一致:Swift/Compose 交给 vrnField 点路径解析,JS 侧解析为对象)
|
|
157
|
-
for (const m of script.matchAll(/const\s+(\w+)\s*=\s*ref(?:<[^>]*>)?\(\s*\{/g)) {
|
|
157
|
+
for (const m of script.matchAll(/const\s+(\w+)\s*=\s*(?:ref|reactive)(?:<[^>]*>)?\(\s*\{/g)) {
|
|
158
158
|
const start = (m.index ?? 0) + m[0].length - 1;
|
|
159
159
|
let depth = 0;
|
|
160
160
|
let end = -1;
|