@dongmingzhixiu/vuexir-compiler 0.4.2 → 0.4.4

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.
@@ -439,6 +439,10 @@ function safeBind(name, ctx, loop) {
439
439
  return '""';
440
440
  }
441
441
  function kotlinCondExpr(expr, ctx, loop) {
442
+ // R128:下沉的条件状态 → 判真
443
+ const sunk = expr.match(/^__vrnCond:(\w+)$/);
444
+ if (sunk)
445
+ return `vrnTruthy(${sunk[1]}.toString())`;
442
446
  // R114:条件里引用了原生端不存在的标识符 → 回退为 true(保留内容)并告警,避免整页编译失败
443
447
  {
444
448
  // 先剥掉字符串字面量,避免把 "success" 之类当成标识符
@@ -511,6 +511,10 @@ function emitNode(node, ctx) {
511
511
  }
512
512
  /** JS 条件表达式 → Swift 兼容:===/!== 为 JS 严格比较,Swift 用 ==/!=;字符串字面量单引号 → 双引号 */
513
513
  function swiftCondExpr(expr, known) {
514
+ // R128:下沉的条件状态 → 判真
515
+ const sunk = expr.match(/^__vrnCond:(\w+)$/);
516
+ if (sunk)
517
+ return `vrnTruthy(${sunk[1]})`;
514
518
  // R114:条件引用原生端不存在的标识符 → true(保留内容),避免整页编译失败
515
519
  const knownSet = known && known.size > 0 ? known : currentStateNames;
516
520
  if (knownSet && knownSet.size > 0) {
@@ -499,6 +499,12 @@ function __vrnSyncPage() {
499
499
  try {
500
500
  var page = typeof __vrnPage !== "undefined" ? __vrnPage : (typeof globalThis !== "undefined" ? globalThis.__vrnPage : undefined);
501
501
  if (!page) return;
502
+ // R129:页面脚本的函数/常量也提到全局,模板里的 {{ greet() }} 类表达式才能求值
503
+ for (var fk in page) {
504
+ try {
505
+ if (typeof globalThis[fk] === "undefined" && typeof page[fk] === "function") globalThis[fk] = page[fk];
506
+ } catch (e) {}
507
+ }
502
508
  for (var k in page) {
503
509
  try {
504
510
  var v = page[k];
@@ -1997,6 +2003,7 @@ function walkElement(node, classProps, comboRules, scopedRules, pseudoRules, war
1997
2003
  // 组件 View 内 {{ prop }}(propRefs)→ 单插值时可整体作为 text ref(Text(prop))
1998
2004
  // - 其余(group/image):递归 walk
1999
2005
  const children = [];
2006
+ let prevCondExpr;
2000
2007
  if (mapping.type === 'text') {
2001
2008
  let text = '';
2002
2009
  let refOnly;
@@ -2177,7 +2184,30 @@ function walkElement(node, classProps, comboRules, scopedRules, pseudoRules, war
2177
2184
  }
2178
2185
  continue;
2179
2186
  }
2180
- children.push(...walk(child, classProps, comboRules, scopedRules, pseudoRules, warnings, state, compTable, propRefs, loopScope, [...ancestorClasses, ...elementClasses]));
2187
+ // R128:v-else / v-else-if 与前一兄弟互补(此前无条件渲染,空状态块常显)
2188
+ const __kids = walk(child, classProps, comboRules, scopedRules, pseudoRules, warnings, state, compTable, propRefs, loopScope, [
2189
+ ...ancestorClasses,
2190
+ ...elementClasses,
2191
+ ]);
2192
+ if (child.type === NodeTypes.ELEMENT) {
2193
+ const dirs = child.props.filter((p2) => p2.type === NodeTypes.DIRECTIVE);
2194
+ const isElse = dirs.some((d) => d.name === 'else');
2195
+ const elseIf = dirs.find((d) => d.name === 'else-if');
2196
+ if (isElse || elseIf) {
2197
+ const prev = prevCondExpr;
2198
+ const own = elseIf?.exp?.content?.trim();
2199
+ if (prev) {
2200
+ const condExpr = own ? `(${prev}) && (${own})` : `!(${prev})`;
2201
+ const stName = addJsExprState(`String(${condExpr})`);
2202
+ for (const k of __kids)
2203
+ k.condition = `__vrnCond:${stName}`;
2204
+ }
2205
+ }
2206
+ const ifDir = dirs.find((d) => d.name === 'if');
2207
+ if (ifDir?.exp?.content)
2208
+ prevCondExpr = ifDir.exp.content.trim();
2209
+ }
2210
+ children.push(...__kids);
2181
2211
  }
2182
2212
  }
2183
2213
  // R108:文本节点丢弃布局类属性(原生端 width/height/flexDirection 只对容器有意义)
@@ -2239,7 +2269,19 @@ function walkElement(node, classProps, comboRules, scopedRules, pseudoRules, war
2239
2269
  const mCond = nc.match(/^([A-Za-z_$][\w$]*)\.([A-Za-z_$][\w$]*)$/);
2240
2270
  const ownerKnown = mCond !== null &&
2241
2271
  ((state?.states ?? []).some((st) => st.name === mCond[1]) || (propRefs?.has(mCond[1]) ?? false));
2242
- irNode.condition = ownerKnown && mCond ? `__vrnField__:${mCond[1]}:${mCond[2]}` : nc;
2272
+ // R128:条件里的复杂表达式(含 || && 比较、对象字段组合)统一下沉给 JS 运行时求值,
2273
+ // 生成 `__vrnCond:<state>`,两端只判真——不再往条件翻译器里堆规则
2274
+ const simpleCond = /^[A-Za-z_$][\w$]*(\.[A-Za-z_$][\w$]*)?$/.test(nc) ||
2275
+ /^![A-Za-z_$][\w$]*(\.[A-Za-z_$][\w$]*)?$/.test(nc) ||
2276
+ /^[A-Za-z_$][\w$]*(\.length)?\s*(==|!=|>|<|>=|<=)\s*('.*'|".*"|-?\d+)$/.test(nc);
2277
+ const usesLoopVar = activeLoops.some((l) => new RegExp(`\\b${l.itemKey}\\b`).test(nc));
2278
+ if (!simpleCond && !usesLoopVar) {
2279
+ const stName = addJsExprState(`String(${nc})`);
2280
+ irNode.condition = `__vrnCond:${stName}`;
2281
+ }
2282
+ else {
2283
+ irNode.condition = ownerKnown && mCond ? `__vrnField__:${mCond[1]}:${mCond[2]}` : nc;
2284
+ }
2243
2285
  }
2244
2286
  if (activeWhen && activeProps) {
2245
2287
  irNode.active = { when: activeWhen, props: activeProps };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dongmingzhixiu/vuexir-compiler",
3
- "version": "0.4.2",
3
+ "version": "0.4.4",
4
4
  "description": "Vue SFC → IR → 原生源码(SwiftUI / Compose)编译器核心:纯函数、零 IO",
5
5
  "type": "module",
6
6
  "license": "MIT",