@dongmingzhixiu/vuexir-compiler 0.3.11 → 0.3.12

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.
@@ -1587,6 +1587,10 @@ function buildComponentTree(comp, warnings) {
1587
1587
  }
1588
1588
  function walkElement(node, classProps, comboRules, scopedRules, pseudoRules, warnings, state, compTable = [], propRefs, loopScope = [], ancestorClasses = []) {
1589
1589
  let elementClasses = []; // M5 后代选择器:本元素 class 清单(子节点递归传祖先链)
1590
+ // R107:SVG 图标(svg/path/circle/line/rect/polygon/g/defs/use)纯装饰 → 忽略,不阻断编译
1591
+ if (['svg', 'path', 'circle', 'line', 'rect', 'polygon', 'polyline', 'g', 'defs', 'use', 'text', 'ellipse'].includes(node.tag) && node.tag !== 'text') {
1592
+ return { type: 'spacer', props: { height: 0 } };
1593
+ }
1590
1594
  // R104:<br> 换行 → 占位间距(原生端没有行内换行语义)
1591
1595
  if (node.tag === 'br') {
1592
1596
  return { type: 'spacer', props: { height: 8 } };
@@ -1905,6 +1909,10 @@ function walkElement(node, classProps, comboRules, scopedRules, pseudoRules, war
1905
1909
  refOnly = name;
1906
1910
  parts.push({ bind: name });
1907
1911
  }
1912
+ else if (scriptDeclaredNames.has(name)) {
1913
+ // R106:computed / 普通 const / 解构值 → 运行时求值
1914
+ parts.push({ bind: addJsExprState(textOf(child.content).trim()) });
1915
+ }
1908
1916
  else {
1909
1917
  throw new VueCompileError(`插值 {{ ${name} }}:未在 <script setup> 中声明为 ref 状态(M1 白名单:仅支持已声明状态)`);
1910
1918
  }
@@ -1959,6 +1967,16 @@ function walkElement(node, classProps, comboRules, scopedRules, pseudoRules, war
1959
1967
  else if (child.type === NodeTypes.COMMENT) {
1960
1968
  // 忽略注释
1961
1969
  }
1970
+ else if (child.type === NodeTypes.ELEMENT && mapping.type === 'text') {
1971
+ // R107:行内嵌套(<b>光<b/></b>、<span><svg/></span>)→ 有文字并入,纯图标忽略
1972
+ const innerText = elementInnerText(child).trim();
1973
+ if (innerText) {
1974
+ text += innerText;
1975
+ parts.push({ text: innerText }); // 同步进 parts,避免只走 bindParts 时丢失
1976
+ }
1977
+ else
1978
+ warnings.push(`<${node.tag}> 内嵌图标元素 <${child.tag}> 已忽略(R107)`);
1979
+ }
1962
1980
  else {
1963
1981
  throw new VueCompileError(`<${node.tag}> 内嵌子元素(行内混合)暂不支持(text 节点仅文本/插值)`);
1964
1982
  }
@@ -1985,14 +2003,20 @@ function walkElement(node, classProps, comboRules, scopedRules, pseudoRules, war
1985
2003
  else {
1986
2004
  const t = text.trim();
1987
2005
  if (!t) {
1988
- throw new VueCompileError(`<${node.tag}> 无文本内容`);
2006
+ // R106:空的行内元素(图标占位 <i></i>)→ 空文本,内容不丢但也不阻断编译
2007
+ warnings.push(`<${node.tag}> 无文本内容 → 已降级为空占位(R106)`);
2008
+ props.text = ' ';
2009
+ }
2010
+ else {
2011
+ props.text = t;
1989
2012
  }
1990
- props.text = t;
1991
2013
  }
1992
2014
  }
1993
2015
  else {
1994
2016
  for (const child of node.children) {
1995
2017
  if (mapping.type === 'button') {
2018
+ if (child.type === NodeTypes.ELEMENT && (child.tag === 'br' || !elementInnerText(child).trim()))
2019
+ continue; // R106/R107:按钮内换行/纯图标忽略
1996
2020
  if (child.type === NodeTypes.TEXT && child.content.trim()) {
1997
2021
  props.label = ((props.label ?? '') + child.content.trim()).trim();
1998
2022
  continue;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dongmingzhixiu/vuexir-compiler",
3
- "version": "0.3.11",
3
+ "version": "0.3.12",
4
4
  "description": "Vue SFC → IR → 原生源码(SwiftUI / Compose)编译器核心:纯函数、零 IO",
5
5
  "type": "module",
6
6
  "license": "MIT",