@fictjs/compiler 0.14.0 → 0.15.0
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/README.md +3 -0
- package/dist/index.cjs +276 -159
- package/dist/index.js +276 -159
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -56,6 +56,9 @@ createFictPlugin({
|
|
|
56
56
|
- `'auto'` (default): writes metadata to cache directory (not source tree) only when no external metadata store/resolver is provided.
|
|
57
57
|
- `moduleMetadataCacheDir` (default: `<cwd>/.fict-cache/metadata`): cache directory used by `emitModuleMetadata: 'auto'`.
|
|
58
58
|
- `moduleMetadata` / `resolveModuleMetadata`: external metadata integration hooks. When provided, `'auto'` does not write metadata files.
|
|
59
|
+
- Built-in metadata resolution only covers local filesystem modules (relative/absolute paths + configured alias/ts resolution from the caller).
|
|
60
|
+
- Bare package imports are treated as opaque unless your `resolveModuleMetadata` hook provides metadata.
|
|
61
|
+
- Cross-module metadata lookup does not perform cycle detection; cyclical hook metadata chains should be handled by a custom resolver if needed.
|
|
59
62
|
- `reactiveScopes`: function names whose **first callback argument** is treated as a component-like reactive scope.
|
|
60
63
|
- Only **direct calls** are recognized (e.g., `renderHook(() => ...)` or `utils.renderHook(() => ...)`).
|
|
61
64
|
- **Aliases/indirect calls** are not recognized (e.g., `const rh = renderHook; rh(() => ...)`).
|
package/dist/index.cjs
CHANGED
|
@@ -14174,6 +14174,7 @@ var RUNTIME_HELPERS = {
|
|
|
14174
14174
|
bindEvent: "bindEvent",
|
|
14175
14175
|
callEventHandler: "callEventHandler",
|
|
14176
14176
|
bindRef: "bindRef",
|
|
14177
|
+
spread: "spread",
|
|
14177
14178
|
nonReactive: "nonReactive",
|
|
14178
14179
|
toNodeArray: "toNodeArray",
|
|
14179
14180
|
template: "template",
|
|
@@ -14231,6 +14232,7 @@ var RUNTIME_ALIASES = {
|
|
|
14231
14232
|
bindEvent: "bindEvent",
|
|
14232
14233
|
callEventHandler: "callEventHandler",
|
|
14233
14234
|
bindRef: "bindRef",
|
|
14235
|
+
spread: "spread",
|
|
14234
14236
|
nonReactive: "nonReactive",
|
|
14235
14237
|
toNodeArray: "toNodeArray",
|
|
14236
14238
|
template: "template",
|
|
@@ -22616,138 +22618,212 @@ function emitConditionalChild(startMarkerId, endMarkerId, expr, statements, ctx,
|
|
|
22616
22618
|
);
|
|
22617
22619
|
}
|
|
22618
22620
|
|
|
22619
|
-
// src/ir/
|
|
22620
|
-
function
|
|
22621
|
-
|
|
22622
|
-
|
|
22623
|
-
|
|
22624
|
-
|
|
22625
|
-
|
|
22626
|
-
|
|
22627
|
-
|
|
22628
|
-
|
|
22629
|
-
|
|
22630
|
-
|
|
22631
|
-
|
|
22632
|
-
|
|
22633
|
-
|
|
22634
|
-
|
|
22635
|
-
|
|
22636
|
-
|
|
22637
|
-
|
|
22621
|
+
// src/ir/walk-expression.ts
|
|
22622
|
+
function assertNever(value) {
|
|
22623
|
+
throw new Error(`Unhandled node in walkExpression: ${JSON.stringify(value)}`);
|
|
22624
|
+
}
|
|
22625
|
+
function walkTerminator(term, visitNode, inFunctionBody) {
|
|
22626
|
+
switch (term.kind) {
|
|
22627
|
+
case "Return":
|
|
22628
|
+
if (term.argument) visitNode(term.argument, null, inFunctionBody);
|
|
22629
|
+
return;
|
|
22630
|
+
case "Throw":
|
|
22631
|
+
visitNode(term.argument, null, inFunctionBody);
|
|
22632
|
+
return;
|
|
22633
|
+
case "Branch":
|
|
22634
|
+
visitNode(term.test, null, inFunctionBody);
|
|
22635
|
+
return;
|
|
22636
|
+
case "Switch":
|
|
22637
|
+
visitNode(term.discriminant, null, inFunctionBody);
|
|
22638
|
+
term.cases.forEach((c) => {
|
|
22639
|
+
if (c.test) visitNode(c.test, null, inFunctionBody);
|
|
22640
|
+
});
|
|
22641
|
+
return;
|
|
22642
|
+
case "ForOf":
|
|
22643
|
+
visitNode(term.iterable, null, inFunctionBody);
|
|
22644
|
+
return;
|
|
22645
|
+
case "ForIn":
|
|
22646
|
+
visitNode(term.object, null, inFunctionBody);
|
|
22647
|
+
return;
|
|
22648
|
+
case "Jump":
|
|
22649
|
+
case "Unreachable":
|
|
22650
|
+
case "Break":
|
|
22651
|
+
case "Continue":
|
|
22652
|
+
case "Try":
|
|
22653
|
+
return;
|
|
22654
|
+
default:
|
|
22655
|
+
assertNever(term);
|
|
22638
22656
|
}
|
|
22639
|
-
return void 0;
|
|
22640
22657
|
}
|
|
22641
|
-
function
|
|
22658
|
+
function walkInstruction(instr, visitNode, inFunctionBody) {
|
|
22659
|
+
switch (instr.kind) {
|
|
22660
|
+
case "Assign":
|
|
22661
|
+
case "Expression":
|
|
22662
|
+
visitNode(instr.value, null, inFunctionBody);
|
|
22663
|
+
return;
|
|
22664
|
+
case "Phi":
|
|
22665
|
+
instr.sources.forEach((source) => visitNode(source.id, null, inFunctionBody));
|
|
22666
|
+
return;
|
|
22667
|
+
default:
|
|
22668
|
+
assertNever(instr);
|
|
22669
|
+
}
|
|
22670
|
+
}
|
|
22671
|
+
function walkBlocks(blocks, visitNode, inFunctionBody) {
|
|
22642
22672
|
for (const block of blocks) {
|
|
22643
|
-
|
|
22644
|
-
|
|
22645
|
-
|
|
22646
|
-
|
|
22647
|
-
|
|
22648
|
-
|
|
22649
|
-
|
|
22650
|
-
|
|
22651
|
-
|
|
22673
|
+
block.instructions.forEach((instr) => walkInstruction(instr, visitNode, inFunctionBody));
|
|
22674
|
+
walkTerminator(block.terminator, visitNode, inFunctionBody);
|
|
22675
|
+
}
|
|
22676
|
+
}
|
|
22677
|
+
function walkExpression(expr, visit, options = {}) {
|
|
22678
|
+
const includeFunctionBodies = options.includeFunctionBodies ?? true;
|
|
22679
|
+
const visitNode = (node, parent, inFunctionBody) => {
|
|
22680
|
+
visit(node, { parent, inFunctionBody });
|
|
22681
|
+
switch (node.kind) {
|
|
22682
|
+
case "Identifier":
|
|
22683
|
+
case "Literal":
|
|
22684
|
+
case "MetaProperty":
|
|
22685
|
+
case "ThisExpression":
|
|
22686
|
+
case "SuperExpression":
|
|
22687
|
+
return;
|
|
22688
|
+
case "ImportExpression":
|
|
22689
|
+
visitNode(node.source, node, inFunctionBody);
|
|
22690
|
+
return;
|
|
22691
|
+
case "CallExpression":
|
|
22692
|
+
case "OptionalCallExpression":
|
|
22693
|
+
visitNode(node.callee, node, inFunctionBody);
|
|
22694
|
+
node.arguments.forEach((arg) => visitNode(arg, node, inFunctionBody));
|
|
22695
|
+
return;
|
|
22696
|
+
case "MemberExpression":
|
|
22697
|
+
case "OptionalMemberExpression":
|
|
22698
|
+
visitNode(node.object, node, inFunctionBody);
|
|
22699
|
+
if (node.computed) {
|
|
22700
|
+
visitNode(node.property, node, inFunctionBody);
|
|
22701
|
+
}
|
|
22702
|
+
return;
|
|
22703
|
+
case "BinaryExpression":
|
|
22704
|
+
case "LogicalExpression":
|
|
22705
|
+
visitNode(node.left, node, inFunctionBody);
|
|
22706
|
+
visitNode(node.right, node, inFunctionBody);
|
|
22707
|
+
return;
|
|
22708
|
+
case "UnaryExpression":
|
|
22709
|
+
case "AwaitExpression":
|
|
22710
|
+
visitNode(node.argument, node, inFunctionBody);
|
|
22711
|
+
return;
|
|
22712
|
+
case "ConditionalExpression":
|
|
22713
|
+
visitNode(node.test, node, inFunctionBody);
|
|
22714
|
+
visitNode(node.consequent, node, inFunctionBody);
|
|
22715
|
+
visitNode(node.alternate, node, inFunctionBody);
|
|
22716
|
+
return;
|
|
22717
|
+
case "ArrayExpression":
|
|
22718
|
+
node.elements.forEach((el) => visitNode(el, node, inFunctionBody));
|
|
22719
|
+
return;
|
|
22720
|
+
case "ObjectExpression":
|
|
22721
|
+
node.properties.forEach((prop) => {
|
|
22722
|
+
if (prop.kind === "SpreadElement") {
|
|
22723
|
+
visitNode(prop.argument, node, inFunctionBody);
|
|
22724
|
+
} else {
|
|
22725
|
+
if (prop.computed) {
|
|
22726
|
+
visitNode(prop.key, node, inFunctionBody);
|
|
22727
|
+
}
|
|
22728
|
+
visitNode(prop.value, node, inFunctionBody);
|
|
22652
22729
|
}
|
|
22653
|
-
|
|
22654
|
-
|
|
22655
|
-
|
|
22656
|
-
|
|
22657
|
-
|
|
22658
|
-
const term = block.terminator;
|
|
22659
|
-
switch (term.kind) {
|
|
22660
|
-
case "Return":
|
|
22661
|
-
if (term.argument) collectExpressionDependencies(term.argument, deps);
|
|
22662
|
-
break;
|
|
22663
|
-
case "Throw":
|
|
22664
|
-
collectExpressionDependencies(term.argument, deps);
|
|
22665
|
-
break;
|
|
22666
|
-
case "Branch":
|
|
22667
|
-
collectExpressionDependencies(term.test, deps);
|
|
22668
|
-
break;
|
|
22669
|
-
case "Switch":
|
|
22670
|
-
collectExpressionDependencies(term.discriminant, deps);
|
|
22671
|
-
for (const c of term.cases) {
|
|
22672
|
-
if (c.test) collectExpressionDependencies(c.test, deps);
|
|
22730
|
+
});
|
|
22731
|
+
return;
|
|
22732
|
+
case "JSXElement":
|
|
22733
|
+
if (typeof node.tagName !== "string") {
|
|
22734
|
+
visitNode(node.tagName, node, inFunctionBody);
|
|
22673
22735
|
}
|
|
22674
|
-
|
|
22675
|
-
|
|
22676
|
-
|
|
22677
|
-
|
|
22678
|
-
|
|
22679
|
-
|
|
22680
|
-
|
|
22736
|
+
node.attributes.forEach((attr) => {
|
|
22737
|
+
if (attr.isSpread && attr.spreadExpr) {
|
|
22738
|
+
visitNode(attr.spreadExpr, node, inFunctionBody);
|
|
22739
|
+
} else if (attr.value) {
|
|
22740
|
+
visitNode(attr.value, node, inFunctionBody);
|
|
22741
|
+
}
|
|
22742
|
+
});
|
|
22743
|
+
node.children.forEach((child) => {
|
|
22744
|
+
if (child.kind === "expression") {
|
|
22745
|
+
visitNode(child.value, node, inFunctionBody);
|
|
22746
|
+
} else if (child.kind === "element") {
|
|
22747
|
+
visitNode(child.value, node, inFunctionBody);
|
|
22748
|
+
}
|
|
22749
|
+
});
|
|
22750
|
+
return;
|
|
22751
|
+
case "ArrowFunction":
|
|
22752
|
+
if (!includeFunctionBodies) return;
|
|
22753
|
+
if (node.isExpression && !Array.isArray(node.body)) {
|
|
22754
|
+
visitNode(node.body, node, true);
|
|
22755
|
+
} else if (Array.isArray(node.body)) {
|
|
22756
|
+
walkBlocks(node.body, visitNode, true);
|
|
22757
|
+
}
|
|
22758
|
+
return;
|
|
22759
|
+
case "FunctionExpression":
|
|
22760
|
+
if (!includeFunctionBodies) return;
|
|
22761
|
+
walkBlocks(node.body, visitNode, true);
|
|
22762
|
+
return;
|
|
22763
|
+
case "AssignmentExpression":
|
|
22764
|
+
visitNode(node.left, node, inFunctionBody);
|
|
22765
|
+
visitNode(node.right, node, inFunctionBody);
|
|
22766
|
+
return;
|
|
22767
|
+
case "UpdateExpression":
|
|
22768
|
+
visitNode(node.argument, node, inFunctionBody);
|
|
22769
|
+
return;
|
|
22770
|
+
case "TemplateLiteral":
|
|
22771
|
+
node.expressions.forEach((item) => visitNode(item, node, inFunctionBody));
|
|
22772
|
+
return;
|
|
22773
|
+
case "SpreadElement":
|
|
22774
|
+
visitNode(node.argument, node, inFunctionBody);
|
|
22775
|
+
return;
|
|
22776
|
+
case "NewExpression":
|
|
22777
|
+
visitNode(node.callee, node, inFunctionBody);
|
|
22778
|
+
node.arguments.forEach((arg) => visitNode(arg, node, inFunctionBody));
|
|
22779
|
+
return;
|
|
22780
|
+
case "SequenceExpression":
|
|
22781
|
+
node.expressions.forEach((item) => visitNode(item, node, inFunctionBody));
|
|
22782
|
+
return;
|
|
22783
|
+
case "YieldExpression":
|
|
22784
|
+
if (node.argument) {
|
|
22785
|
+
visitNode(node.argument, node, inFunctionBody);
|
|
22786
|
+
}
|
|
22787
|
+
return;
|
|
22788
|
+
case "TaggedTemplateExpression":
|
|
22789
|
+
visitNode(node.tag, node, inFunctionBody);
|
|
22790
|
+
node.quasi.expressions.forEach((item) => visitNode(item, node, inFunctionBody));
|
|
22791
|
+
return;
|
|
22792
|
+
case "ClassExpression":
|
|
22793
|
+
if (node.superClass) {
|
|
22794
|
+
visitNode(node.superClass, node, inFunctionBody);
|
|
22795
|
+
}
|
|
22796
|
+
return;
|
|
22681
22797
|
default:
|
|
22682
|
-
|
|
22798
|
+
assertNever(node);
|
|
22683
22799
|
}
|
|
22800
|
+
};
|
|
22801
|
+
visitNode(expr, null, false);
|
|
22802
|
+
}
|
|
22803
|
+
|
|
22804
|
+
// src/ir/codegen-expression-deps.ts
|
|
22805
|
+
function getMemberDependencyPath(expr) {
|
|
22806
|
+
if (expr.kind !== "MemberExpression" && expr.kind !== "OptionalMemberExpression") return void 0;
|
|
22807
|
+
const depPath = extractDependencyPath(expr);
|
|
22808
|
+
if (!depPath || depPath.segments.length === 0) return void 0;
|
|
22809
|
+
const base = deSSAVarName(depPath.base);
|
|
22810
|
+
if (depPath.segments.some((segment) => segment.computed)) {
|
|
22811
|
+
return base;
|
|
22684
22812
|
}
|
|
22813
|
+
const tail = depPath.segments.map((segment) => segment.property).join(".");
|
|
22814
|
+
return tail ? `${base}.${tail}` : void 0;
|
|
22685
22815
|
}
|
|
22686
22816
|
function collectExpressionDependencies(expr, deps) {
|
|
22687
|
-
|
|
22688
|
-
|
|
22689
|
-
|
|
22690
|
-
|
|
22691
|
-
if (expr.kind === "ArrowFunction") {
|
|
22692
|
-
if (expr.isExpression && !Array.isArray(expr.body)) {
|
|
22693
|
-
collectExpressionDependencies(expr.body, deps);
|
|
22694
|
-
} else if (Array.isArray(expr.body)) {
|
|
22695
|
-
collectBlockDependencies(expr.body, deps);
|
|
22817
|
+
walkExpression(expr, (node) => {
|
|
22818
|
+
if (node.kind === "Identifier") {
|
|
22819
|
+
deps.add(deSSAVarName(node.name));
|
|
22820
|
+
return;
|
|
22696
22821
|
}
|
|
22697
|
-
|
|
22698
|
-
|
|
22699
|
-
|
|
22700
|
-
collectBlockDependencies(expr.body, deps);
|
|
22701
|
-
return;
|
|
22702
|
-
}
|
|
22703
|
-
if (expr.kind === "MemberExpression") {
|
|
22704
|
-
const path2 = getMemberDependencyPath(expr);
|
|
22705
|
-
if (path2) deps.add(path2);
|
|
22706
|
-
collectExpressionDependencies(expr.object, deps);
|
|
22707
|
-
if (expr.computed && expr.property.kind !== "Literal") {
|
|
22708
|
-
collectExpressionDependencies(expr.property, deps);
|
|
22822
|
+
const path2 = getMemberDependencyPath(node);
|
|
22823
|
+
if (path2) {
|
|
22824
|
+
deps.add(path2);
|
|
22709
22825
|
}
|
|
22710
|
-
|
|
22711
|
-
}
|
|
22712
|
-
if (expr.kind === "CallExpression") {
|
|
22713
|
-
collectExpressionDependencies(expr.callee, deps);
|
|
22714
|
-
expr.arguments.forEach((a) => collectExpressionDependencies(a, deps));
|
|
22715
|
-
return;
|
|
22716
|
-
}
|
|
22717
|
-
if (expr.kind === "BinaryExpression" || expr.kind === "LogicalExpression") {
|
|
22718
|
-
collectExpressionDependencies(expr.left, deps);
|
|
22719
|
-
collectExpressionDependencies(expr.right, deps);
|
|
22720
|
-
return;
|
|
22721
|
-
}
|
|
22722
|
-
if (expr.kind === "ConditionalExpression") {
|
|
22723
|
-
collectExpressionDependencies(expr.test, deps);
|
|
22724
|
-
collectExpressionDependencies(expr.consequent, deps);
|
|
22725
|
-
collectExpressionDependencies(expr.alternate, deps);
|
|
22726
|
-
return;
|
|
22727
|
-
}
|
|
22728
|
-
if (expr.kind === "UnaryExpression") {
|
|
22729
|
-
collectExpressionDependencies(expr.argument, deps);
|
|
22730
|
-
return;
|
|
22731
|
-
}
|
|
22732
|
-
if (expr.kind === "ArrayExpression") {
|
|
22733
|
-
expr.elements.forEach((el) => collectExpressionDependencies(el, deps));
|
|
22734
|
-
return;
|
|
22735
|
-
}
|
|
22736
|
-
if (expr.kind === "ObjectExpression") {
|
|
22737
|
-
expr.properties.forEach((p) => {
|
|
22738
|
-
if (p.kind === "SpreadElement") {
|
|
22739
|
-
collectExpressionDependencies(p.argument, deps);
|
|
22740
|
-
} else {
|
|
22741
|
-
if (p.computed) collectExpressionDependencies(p.key, deps);
|
|
22742
|
-
collectExpressionDependencies(p.value, deps);
|
|
22743
|
-
}
|
|
22744
|
-
});
|
|
22745
|
-
return;
|
|
22746
|
-
}
|
|
22747
|
-
if (expr.kind === "TemplateLiteral") {
|
|
22748
|
-
expr.expressions.forEach((e) => collectExpressionDependencies(e, deps));
|
|
22749
|
-
return;
|
|
22750
|
-
}
|
|
22826
|
+
});
|
|
22751
22827
|
}
|
|
22752
22828
|
|
|
22753
22829
|
// src/ir/codegen-reactive-kind.ts
|
|
@@ -26125,8 +26201,31 @@ function extractHIRStaticHtml(jsx, ctx, ops, parentPath = [], namespace = null)
|
|
|
26125
26201
|
const resolvedNamespace = resolveNamespaceContext(tagName, namespace);
|
|
26126
26202
|
let html = `<${tagName}`;
|
|
26127
26203
|
const bindings = [];
|
|
26128
|
-
for (
|
|
26204
|
+
for (let attrIndex = 0; attrIndex < jsx.attributes.length; attrIndex++) {
|
|
26205
|
+
const attr = jsx.attributes[attrIndex];
|
|
26129
26206
|
if (attr.isSpread) {
|
|
26207
|
+
if (attr.spreadExpr) {
|
|
26208
|
+
const excluded = /* @__PURE__ */ new Set();
|
|
26209
|
+
for (let nextIndex = attrIndex + 1; nextIndex < jsx.attributes.length; nextIndex++) {
|
|
26210
|
+
const nextAttr = jsx.attributes[nextIndex];
|
|
26211
|
+
if (nextAttr.isSpread) continue;
|
|
26212
|
+
let nextName = normalizeHIRAttrName(nextAttr.name);
|
|
26213
|
+
if (nextName.endsWith("$")) {
|
|
26214
|
+
nextName = nextName.slice(0, -1);
|
|
26215
|
+
}
|
|
26216
|
+
if (nextName === "key") continue;
|
|
26217
|
+
excluded.add(nextName);
|
|
26218
|
+
if (nextName !== nextAttr.name) {
|
|
26219
|
+
excluded.add(nextAttr.name);
|
|
26220
|
+
}
|
|
26221
|
+
}
|
|
26222
|
+
bindings.push({
|
|
26223
|
+
type: "spread",
|
|
26224
|
+
path: [...parentPath],
|
|
26225
|
+
expr: attr.spreadExpr,
|
|
26226
|
+
exclude: excluded.size > 0 ? Array.from(excluded) : void 0
|
|
26227
|
+
});
|
|
26228
|
+
}
|
|
26130
26229
|
continue;
|
|
26131
26230
|
}
|
|
26132
26231
|
let name = normalizeHIRAttrName(attr.name);
|
|
@@ -28311,10 +28410,28 @@ function lowerIntrinsicElement(jsx, ctx) {
|
|
|
28311
28410
|
)
|
|
28312
28411
|
);
|
|
28313
28412
|
}
|
|
28413
|
+
fusedPatchGroups.clear();
|
|
28314
28414
|
};
|
|
28315
28415
|
for (const binding of bindings) {
|
|
28316
28416
|
const targetId = resolveHIRBindingPath(binding.path, nodeCache, statements, ctx, genTemp3);
|
|
28317
|
-
if (binding.type === "
|
|
28417
|
+
if (binding.type === "spread" && binding.expr) {
|
|
28418
|
+
flushFusedPatchGroups();
|
|
28419
|
+
ctx.helpersUsed.add("spread");
|
|
28420
|
+
const spreadValueExpr = lowerDomExpression(binding.expr, ctx, containingRegion);
|
|
28421
|
+
const spreadGetter = t4.arrowFunctionExpression([], spreadValueExpr);
|
|
28422
|
+
const spreadArgs = [
|
|
28423
|
+
targetId,
|
|
28424
|
+
spreadGetter,
|
|
28425
|
+
t4.booleanLiteral(Boolean(isSVG || isMathML)),
|
|
28426
|
+
t4.booleanLiteral(true)
|
|
28427
|
+
];
|
|
28428
|
+
if (binding.exclude && binding.exclude.length > 0) {
|
|
28429
|
+
spreadArgs.push(t4.arrayExpression(binding.exclude.map((name) => t4.stringLiteral(name))));
|
|
28430
|
+
}
|
|
28431
|
+
statements.push(
|
|
28432
|
+
t4.expressionStatement(t4.callExpression(t4.identifier(RUNTIME_ALIASES.spread), spreadArgs))
|
|
28433
|
+
);
|
|
28434
|
+
} else if (binding.type === "event" && binding.expr && binding.name) {
|
|
28318
28435
|
const eventName = binding.name;
|
|
28319
28436
|
const hasEventOptions = binding.eventOptions && (binding.eventOptions.capture || binding.eventOptions.passive || binding.eventOptions.once);
|
|
28320
28437
|
const isDelegated = DelegatedEvents.has(eventName) && !hasEventOptions;
|
|
@@ -33102,106 +33219,106 @@ function collectUsesFromTerminator(term, add, inFunctionBody = false) {
|
|
|
33102
33219
|
}
|
|
33103
33220
|
}
|
|
33104
33221
|
function collectUsesFromExpression(expr, add, inFunctionBody = false) {
|
|
33105
|
-
|
|
33222
|
+
walkExpression2(expr, add, { inFunctionBody, shadowed: /* @__PURE__ */ new Set() });
|
|
33106
33223
|
}
|
|
33107
|
-
function
|
|
33224
|
+
function walkExpression2(expr, add, ctx) {
|
|
33108
33225
|
switch (expr.kind) {
|
|
33109
33226
|
case "Identifier":
|
|
33110
33227
|
if (!ctx.shadowed.has(expr.name)) add(expr.name, ctx.inFunctionBody);
|
|
33111
33228
|
return;
|
|
33112
33229
|
case "CallExpression":
|
|
33113
33230
|
case "OptionalCallExpression":
|
|
33114
|
-
|
|
33115
|
-
expr.arguments.forEach((arg) =>
|
|
33231
|
+
walkExpression2(expr.callee, add, ctx);
|
|
33232
|
+
expr.arguments.forEach((arg) => walkExpression2(arg, add, ctx));
|
|
33116
33233
|
return;
|
|
33117
33234
|
case "MemberExpression":
|
|
33118
33235
|
case "OptionalMemberExpression":
|
|
33119
|
-
|
|
33120
|
-
if (expr.computed)
|
|
33236
|
+
walkExpression2(expr.object, add, ctx);
|
|
33237
|
+
if (expr.computed) walkExpression2(expr.property, add, ctx);
|
|
33121
33238
|
return;
|
|
33122
33239
|
case "BinaryExpression":
|
|
33123
33240
|
case "LogicalExpression":
|
|
33124
|
-
|
|
33125
|
-
|
|
33241
|
+
walkExpression2(expr.left, add, ctx);
|
|
33242
|
+
walkExpression2(expr.right, add, ctx);
|
|
33126
33243
|
return;
|
|
33127
33244
|
case "UnaryExpression":
|
|
33128
|
-
|
|
33245
|
+
walkExpression2(expr.argument, add, ctx);
|
|
33129
33246
|
return;
|
|
33130
33247
|
case "ConditionalExpression":
|
|
33131
|
-
|
|
33132
|
-
|
|
33133
|
-
|
|
33248
|
+
walkExpression2(expr.test, add, ctx);
|
|
33249
|
+
walkExpression2(expr.consequent, add, ctx);
|
|
33250
|
+
walkExpression2(expr.alternate, add, ctx);
|
|
33134
33251
|
return;
|
|
33135
33252
|
case "ArrayExpression":
|
|
33136
33253
|
expr.elements.forEach((el) => {
|
|
33137
|
-
if (el)
|
|
33254
|
+
if (el) walkExpression2(el, add, ctx);
|
|
33138
33255
|
});
|
|
33139
33256
|
return;
|
|
33140
33257
|
case "ObjectExpression":
|
|
33141
33258
|
expr.properties.forEach((prop) => {
|
|
33142
33259
|
if (prop.kind === "SpreadElement") {
|
|
33143
|
-
|
|
33260
|
+
walkExpression2(prop.argument, add, ctx);
|
|
33144
33261
|
} else {
|
|
33145
|
-
if (prop.computed)
|
|
33146
|
-
|
|
33262
|
+
if (prop.computed) walkExpression2(prop.key, add, ctx);
|
|
33263
|
+
walkExpression2(prop.value, add, ctx);
|
|
33147
33264
|
}
|
|
33148
33265
|
});
|
|
33149
33266
|
return;
|
|
33150
33267
|
case "TemplateLiteral":
|
|
33151
|
-
expr.expressions.forEach((e) =>
|
|
33268
|
+
expr.expressions.forEach((e) => walkExpression2(e, add, ctx));
|
|
33152
33269
|
return;
|
|
33153
33270
|
case "SpreadElement":
|
|
33154
|
-
|
|
33271
|
+
walkExpression2(expr.argument, add, ctx);
|
|
33155
33272
|
return;
|
|
33156
33273
|
case "SequenceExpression":
|
|
33157
|
-
expr.expressions.forEach((e) =>
|
|
33274
|
+
expr.expressions.forEach((e) => walkExpression2(e, add, ctx));
|
|
33158
33275
|
return;
|
|
33159
33276
|
case "AwaitExpression":
|
|
33160
|
-
|
|
33277
|
+
walkExpression2(expr.argument, add, ctx);
|
|
33161
33278
|
return;
|
|
33162
33279
|
case "NewExpression":
|
|
33163
|
-
|
|
33164
|
-
expr.arguments.forEach((arg) =>
|
|
33280
|
+
walkExpression2(expr.callee, add, ctx);
|
|
33281
|
+
expr.arguments.forEach((arg) => walkExpression2(arg, add, ctx));
|
|
33165
33282
|
return;
|
|
33166
33283
|
case "ArrowFunction": {
|
|
33167
33284
|
const shadowed = new Set(ctx.shadowed);
|
|
33168
33285
|
expr.params.forEach((p) => shadowed.add(p.name));
|
|
33169
33286
|
if (expr.isExpression) {
|
|
33170
|
-
|
|
33287
|
+
walkExpression2(expr.body, add, { inFunctionBody: true, shadowed });
|
|
33171
33288
|
return;
|
|
33172
33289
|
}
|
|
33173
|
-
|
|
33290
|
+
walkBlocks2(expr.body, add, { inFunctionBody: true, shadowed });
|
|
33174
33291
|
return;
|
|
33175
33292
|
}
|
|
33176
33293
|
case "FunctionExpression": {
|
|
33177
33294
|
const shadowed = new Set(ctx.shadowed);
|
|
33178
33295
|
expr.params.forEach((p) => shadowed.add(p.name));
|
|
33179
|
-
|
|
33296
|
+
walkBlocks2(expr.body, add, { inFunctionBody: true, shadowed });
|
|
33180
33297
|
return;
|
|
33181
33298
|
}
|
|
33182
33299
|
case "AssignmentExpression":
|
|
33183
|
-
|
|
33184
|
-
|
|
33300
|
+
walkExpression2(expr.left, add, ctx);
|
|
33301
|
+
walkExpression2(expr.right, add, ctx);
|
|
33185
33302
|
return;
|
|
33186
33303
|
case "UpdateExpression":
|
|
33187
|
-
|
|
33304
|
+
walkExpression2(expr.argument, add, ctx);
|
|
33188
33305
|
return;
|
|
33189
33306
|
case "JSXElement":
|
|
33190
33307
|
if (typeof expr.tagName !== "string") {
|
|
33191
|
-
|
|
33308
|
+
walkExpression2(expr.tagName, add, ctx);
|
|
33192
33309
|
}
|
|
33193
33310
|
expr.attributes.forEach((attr) => {
|
|
33194
33311
|
if (attr.isSpread && attr.spreadExpr) {
|
|
33195
|
-
|
|
33312
|
+
walkExpression2(attr.spreadExpr, add, ctx);
|
|
33196
33313
|
} else if (attr.value) {
|
|
33197
|
-
|
|
33314
|
+
walkExpression2(attr.value, add, ctx);
|
|
33198
33315
|
}
|
|
33199
33316
|
});
|
|
33200
33317
|
expr.children.forEach((child) => {
|
|
33201
33318
|
if (child.kind === "expression") {
|
|
33202
|
-
|
|
33319
|
+
walkExpression2(child.value, add, ctx);
|
|
33203
33320
|
} else if (child.kind === "element") {
|
|
33204
|
-
|
|
33321
|
+
walkExpression2(child.value, add, ctx);
|
|
33205
33322
|
}
|
|
33206
33323
|
});
|
|
33207
33324
|
return;
|
|
@@ -33209,16 +33326,16 @@ function walkExpression(expr, add, ctx) {
|
|
|
33209
33326
|
return;
|
|
33210
33327
|
}
|
|
33211
33328
|
}
|
|
33212
|
-
function
|
|
33329
|
+
function walkBlocks2(blocks, add, ctx) {
|
|
33213
33330
|
for (const block of blocks) {
|
|
33214
33331
|
for (const instr of block.instructions) {
|
|
33215
33332
|
if (instr.kind === "Assign") {
|
|
33216
|
-
|
|
33333
|
+
walkExpression2(instr.value, add, ctx);
|
|
33217
33334
|
if (instr.declarationKind) {
|
|
33218
33335
|
ctx.shadowed.add(instr.target.name);
|
|
33219
33336
|
}
|
|
33220
33337
|
} else if (instr.kind === "Expression") {
|
|
33221
|
-
|
|
33338
|
+
walkExpression2(instr.value, add, ctx);
|
|
33222
33339
|
} else if (instr.kind === "Phi") {
|
|
33223
33340
|
instr.sources.forEach((src) => {
|
|
33224
33341
|
if (!ctx.shadowed.has(src.id.name)) add(src.id.name, ctx.inFunctionBody);
|
|
@@ -33237,7 +33354,7 @@ function walkBlocks(blocks, add, ctx) {
|
|
|
33237
33354
|
function collectExpressionIdentifiers2(expr, deep = false) {
|
|
33238
33355
|
const deps = /* @__PURE__ */ new Set();
|
|
33239
33356
|
const collect = (name) => deps.add(name);
|
|
33240
|
-
|
|
33357
|
+
walkExpression2(expr, (name, _inFunctionBody) => collect(name), {
|
|
33241
33358
|
inFunctionBody: deep,
|
|
33242
33359
|
shadowed: /* @__PURE__ */ new Set()
|
|
33243
33360
|
});
|
package/dist/index.js
CHANGED
|
@@ -14159,6 +14159,7 @@ var RUNTIME_HELPERS = {
|
|
|
14159
14159
|
bindEvent: "bindEvent",
|
|
14160
14160
|
callEventHandler: "callEventHandler",
|
|
14161
14161
|
bindRef: "bindRef",
|
|
14162
|
+
spread: "spread",
|
|
14162
14163
|
nonReactive: "nonReactive",
|
|
14163
14164
|
toNodeArray: "toNodeArray",
|
|
14164
14165
|
template: "template",
|
|
@@ -14216,6 +14217,7 @@ var RUNTIME_ALIASES = {
|
|
|
14216
14217
|
bindEvent: "bindEvent",
|
|
14217
14218
|
callEventHandler: "callEventHandler",
|
|
14218
14219
|
bindRef: "bindRef",
|
|
14220
|
+
spread: "spread",
|
|
14219
14221
|
nonReactive: "nonReactive",
|
|
14220
14222
|
toNodeArray: "toNodeArray",
|
|
14221
14223
|
template: "template",
|
|
@@ -22601,138 +22603,212 @@ function emitConditionalChild(startMarkerId, endMarkerId, expr, statements, ctx,
|
|
|
22601
22603
|
);
|
|
22602
22604
|
}
|
|
22603
22605
|
|
|
22604
|
-
// src/ir/
|
|
22605
|
-
function
|
|
22606
|
-
|
|
22607
|
-
|
|
22608
|
-
|
|
22609
|
-
|
|
22610
|
-
|
|
22611
|
-
|
|
22612
|
-
|
|
22613
|
-
|
|
22614
|
-
|
|
22615
|
-
|
|
22616
|
-
|
|
22617
|
-
|
|
22618
|
-
|
|
22619
|
-
|
|
22620
|
-
|
|
22621
|
-
|
|
22622
|
-
|
|
22606
|
+
// src/ir/walk-expression.ts
|
|
22607
|
+
function assertNever(value) {
|
|
22608
|
+
throw new Error(`Unhandled node in walkExpression: ${JSON.stringify(value)}`);
|
|
22609
|
+
}
|
|
22610
|
+
function walkTerminator(term, visitNode, inFunctionBody) {
|
|
22611
|
+
switch (term.kind) {
|
|
22612
|
+
case "Return":
|
|
22613
|
+
if (term.argument) visitNode(term.argument, null, inFunctionBody);
|
|
22614
|
+
return;
|
|
22615
|
+
case "Throw":
|
|
22616
|
+
visitNode(term.argument, null, inFunctionBody);
|
|
22617
|
+
return;
|
|
22618
|
+
case "Branch":
|
|
22619
|
+
visitNode(term.test, null, inFunctionBody);
|
|
22620
|
+
return;
|
|
22621
|
+
case "Switch":
|
|
22622
|
+
visitNode(term.discriminant, null, inFunctionBody);
|
|
22623
|
+
term.cases.forEach((c) => {
|
|
22624
|
+
if (c.test) visitNode(c.test, null, inFunctionBody);
|
|
22625
|
+
});
|
|
22626
|
+
return;
|
|
22627
|
+
case "ForOf":
|
|
22628
|
+
visitNode(term.iterable, null, inFunctionBody);
|
|
22629
|
+
return;
|
|
22630
|
+
case "ForIn":
|
|
22631
|
+
visitNode(term.object, null, inFunctionBody);
|
|
22632
|
+
return;
|
|
22633
|
+
case "Jump":
|
|
22634
|
+
case "Unreachable":
|
|
22635
|
+
case "Break":
|
|
22636
|
+
case "Continue":
|
|
22637
|
+
case "Try":
|
|
22638
|
+
return;
|
|
22639
|
+
default:
|
|
22640
|
+
assertNever(term);
|
|
22623
22641
|
}
|
|
22624
|
-
return void 0;
|
|
22625
22642
|
}
|
|
22626
|
-
function
|
|
22643
|
+
function walkInstruction(instr, visitNode, inFunctionBody) {
|
|
22644
|
+
switch (instr.kind) {
|
|
22645
|
+
case "Assign":
|
|
22646
|
+
case "Expression":
|
|
22647
|
+
visitNode(instr.value, null, inFunctionBody);
|
|
22648
|
+
return;
|
|
22649
|
+
case "Phi":
|
|
22650
|
+
instr.sources.forEach((source) => visitNode(source.id, null, inFunctionBody));
|
|
22651
|
+
return;
|
|
22652
|
+
default:
|
|
22653
|
+
assertNever(instr);
|
|
22654
|
+
}
|
|
22655
|
+
}
|
|
22656
|
+
function walkBlocks(blocks, visitNode, inFunctionBody) {
|
|
22627
22657
|
for (const block of blocks) {
|
|
22628
|
-
|
|
22629
|
-
|
|
22630
|
-
|
|
22631
|
-
|
|
22632
|
-
|
|
22633
|
-
|
|
22634
|
-
|
|
22635
|
-
|
|
22636
|
-
|
|
22658
|
+
block.instructions.forEach((instr) => walkInstruction(instr, visitNode, inFunctionBody));
|
|
22659
|
+
walkTerminator(block.terminator, visitNode, inFunctionBody);
|
|
22660
|
+
}
|
|
22661
|
+
}
|
|
22662
|
+
function walkExpression(expr, visit, options = {}) {
|
|
22663
|
+
const includeFunctionBodies = options.includeFunctionBodies ?? true;
|
|
22664
|
+
const visitNode = (node, parent, inFunctionBody) => {
|
|
22665
|
+
visit(node, { parent, inFunctionBody });
|
|
22666
|
+
switch (node.kind) {
|
|
22667
|
+
case "Identifier":
|
|
22668
|
+
case "Literal":
|
|
22669
|
+
case "MetaProperty":
|
|
22670
|
+
case "ThisExpression":
|
|
22671
|
+
case "SuperExpression":
|
|
22672
|
+
return;
|
|
22673
|
+
case "ImportExpression":
|
|
22674
|
+
visitNode(node.source, node, inFunctionBody);
|
|
22675
|
+
return;
|
|
22676
|
+
case "CallExpression":
|
|
22677
|
+
case "OptionalCallExpression":
|
|
22678
|
+
visitNode(node.callee, node, inFunctionBody);
|
|
22679
|
+
node.arguments.forEach((arg) => visitNode(arg, node, inFunctionBody));
|
|
22680
|
+
return;
|
|
22681
|
+
case "MemberExpression":
|
|
22682
|
+
case "OptionalMemberExpression":
|
|
22683
|
+
visitNode(node.object, node, inFunctionBody);
|
|
22684
|
+
if (node.computed) {
|
|
22685
|
+
visitNode(node.property, node, inFunctionBody);
|
|
22686
|
+
}
|
|
22687
|
+
return;
|
|
22688
|
+
case "BinaryExpression":
|
|
22689
|
+
case "LogicalExpression":
|
|
22690
|
+
visitNode(node.left, node, inFunctionBody);
|
|
22691
|
+
visitNode(node.right, node, inFunctionBody);
|
|
22692
|
+
return;
|
|
22693
|
+
case "UnaryExpression":
|
|
22694
|
+
case "AwaitExpression":
|
|
22695
|
+
visitNode(node.argument, node, inFunctionBody);
|
|
22696
|
+
return;
|
|
22697
|
+
case "ConditionalExpression":
|
|
22698
|
+
visitNode(node.test, node, inFunctionBody);
|
|
22699
|
+
visitNode(node.consequent, node, inFunctionBody);
|
|
22700
|
+
visitNode(node.alternate, node, inFunctionBody);
|
|
22701
|
+
return;
|
|
22702
|
+
case "ArrayExpression":
|
|
22703
|
+
node.elements.forEach((el) => visitNode(el, node, inFunctionBody));
|
|
22704
|
+
return;
|
|
22705
|
+
case "ObjectExpression":
|
|
22706
|
+
node.properties.forEach((prop) => {
|
|
22707
|
+
if (prop.kind === "SpreadElement") {
|
|
22708
|
+
visitNode(prop.argument, node, inFunctionBody);
|
|
22709
|
+
} else {
|
|
22710
|
+
if (prop.computed) {
|
|
22711
|
+
visitNode(prop.key, node, inFunctionBody);
|
|
22712
|
+
}
|
|
22713
|
+
visitNode(prop.value, node, inFunctionBody);
|
|
22637
22714
|
}
|
|
22638
|
-
|
|
22639
|
-
|
|
22640
|
-
|
|
22641
|
-
|
|
22642
|
-
|
|
22643
|
-
const term = block.terminator;
|
|
22644
|
-
switch (term.kind) {
|
|
22645
|
-
case "Return":
|
|
22646
|
-
if (term.argument) collectExpressionDependencies(term.argument, deps);
|
|
22647
|
-
break;
|
|
22648
|
-
case "Throw":
|
|
22649
|
-
collectExpressionDependencies(term.argument, deps);
|
|
22650
|
-
break;
|
|
22651
|
-
case "Branch":
|
|
22652
|
-
collectExpressionDependencies(term.test, deps);
|
|
22653
|
-
break;
|
|
22654
|
-
case "Switch":
|
|
22655
|
-
collectExpressionDependencies(term.discriminant, deps);
|
|
22656
|
-
for (const c of term.cases) {
|
|
22657
|
-
if (c.test) collectExpressionDependencies(c.test, deps);
|
|
22715
|
+
});
|
|
22716
|
+
return;
|
|
22717
|
+
case "JSXElement":
|
|
22718
|
+
if (typeof node.tagName !== "string") {
|
|
22719
|
+
visitNode(node.tagName, node, inFunctionBody);
|
|
22658
22720
|
}
|
|
22659
|
-
|
|
22660
|
-
|
|
22661
|
-
|
|
22662
|
-
|
|
22663
|
-
|
|
22664
|
-
|
|
22665
|
-
|
|
22721
|
+
node.attributes.forEach((attr) => {
|
|
22722
|
+
if (attr.isSpread && attr.spreadExpr) {
|
|
22723
|
+
visitNode(attr.spreadExpr, node, inFunctionBody);
|
|
22724
|
+
} else if (attr.value) {
|
|
22725
|
+
visitNode(attr.value, node, inFunctionBody);
|
|
22726
|
+
}
|
|
22727
|
+
});
|
|
22728
|
+
node.children.forEach((child) => {
|
|
22729
|
+
if (child.kind === "expression") {
|
|
22730
|
+
visitNode(child.value, node, inFunctionBody);
|
|
22731
|
+
} else if (child.kind === "element") {
|
|
22732
|
+
visitNode(child.value, node, inFunctionBody);
|
|
22733
|
+
}
|
|
22734
|
+
});
|
|
22735
|
+
return;
|
|
22736
|
+
case "ArrowFunction":
|
|
22737
|
+
if (!includeFunctionBodies) return;
|
|
22738
|
+
if (node.isExpression && !Array.isArray(node.body)) {
|
|
22739
|
+
visitNode(node.body, node, true);
|
|
22740
|
+
} else if (Array.isArray(node.body)) {
|
|
22741
|
+
walkBlocks(node.body, visitNode, true);
|
|
22742
|
+
}
|
|
22743
|
+
return;
|
|
22744
|
+
case "FunctionExpression":
|
|
22745
|
+
if (!includeFunctionBodies) return;
|
|
22746
|
+
walkBlocks(node.body, visitNode, true);
|
|
22747
|
+
return;
|
|
22748
|
+
case "AssignmentExpression":
|
|
22749
|
+
visitNode(node.left, node, inFunctionBody);
|
|
22750
|
+
visitNode(node.right, node, inFunctionBody);
|
|
22751
|
+
return;
|
|
22752
|
+
case "UpdateExpression":
|
|
22753
|
+
visitNode(node.argument, node, inFunctionBody);
|
|
22754
|
+
return;
|
|
22755
|
+
case "TemplateLiteral":
|
|
22756
|
+
node.expressions.forEach((item) => visitNode(item, node, inFunctionBody));
|
|
22757
|
+
return;
|
|
22758
|
+
case "SpreadElement":
|
|
22759
|
+
visitNode(node.argument, node, inFunctionBody);
|
|
22760
|
+
return;
|
|
22761
|
+
case "NewExpression":
|
|
22762
|
+
visitNode(node.callee, node, inFunctionBody);
|
|
22763
|
+
node.arguments.forEach((arg) => visitNode(arg, node, inFunctionBody));
|
|
22764
|
+
return;
|
|
22765
|
+
case "SequenceExpression":
|
|
22766
|
+
node.expressions.forEach((item) => visitNode(item, node, inFunctionBody));
|
|
22767
|
+
return;
|
|
22768
|
+
case "YieldExpression":
|
|
22769
|
+
if (node.argument) {
|
|
22770
|
+
visitNode(node.argument, node, inFunctionBody);
|
|
22771
|
+
}
|
|
22772
|
+
return;
|
|
22773
|
+
case "TaggedTemplateExpression":
|
|
22774
|
+
visitNode(node.tag, node, inFunctionBody);
|
|
22775
|
+
node.quasi.expressions.forEach((item) => visitNode(item, node, inFunctionBody));
|
|
22776
|
+
return;
|
|
22777
|
+
case "ClassExpression":
|
|
22778
|
+
if (node.superClass) {
|
|
22779
|
+
visitNode(node.superClass, node, inFunctionBody);
|
|
22780
|
+
}
|
|
22781
|
+
return;
|
|
22666
22782
|
default:
|
|
22667
|
-
|
|
22783
|
+
assertNever(node);
|
|
22668
22784
|
}
|
|
22785
|
+
};
|
|
22786
|
+
visitNode(expr, null, false);
|
|
22787
|
+
}
|
|
22788
|
+
|
|
22789
|
+
// src/ir/codegen-expression-deps.ts
|
|
22790
|
+
function getMemberDependencyPath(expr) {
|
|
22791
|
+
if (expr.kind !== "MemberExpression" && expr.kind !== "OptionalMemberExpression") return void 0;
|
|
22792
|
+
const depPath = extractDependencyPath(expr);
|
|
22793
|
+
if (!depPath || depPath.segments.length === 0) return void 0;
|
|
22794
|
+
const base = deSSAVarName(depPath.base);
|
|
22795
|
+
if (depPath.segments.some((segment) => segment.computed)) {
|
|
22796
|
+
return base;
|
|
22669
22797
|
}
|
|
22798
|
+
const tail = depPath.segments.map((segment) => segment.property).join(".");
|
|
22799
|
+
return tail ? `${base}.${tail}` : void 0;
|
|
22670
22800
|
}
|
|
22671
22801
|
function collectExpressionDependencies(expr, deps) {
|
|
22672
|
-
|
|
22673
|
-
|
|
22674
|
-
|
|
22675
|
-
|
|
22676
|
-
if (expr.kind === "ArrowFunction") {
|
|
22677
|
-
if (expr.isExpression && !Array.isArray(expr.body)) {
|
|
22678
|
-
collectExpressionDependencies(expr.body, deps);
|
|
22679
|
-
} else if (Array.isArray(expr.body)) {
|
|
22680
|
-
collectBlockDependencies(expr.body, deps);
|
|
22802
|
+
walkExpression(expr, (node) => {
|
|
22803
|
+
if (node.kind === "Identifier") {
|
|
22804
|
+
deps.add(deSSAVarName(node.name));
|
|
22805
|
+
return;
|
|
22681
22806
|
}
|
|
22682
|
-
|
|
22683
|
-
|
|
22684
|
-
|
|
22685
|
-
collectBlockDependencies(expr.body, deps);
|
|
22686
|
-
return;
|
|
22687
|
-
}
|
|
22688
|
-
if (expr.kind === "MemberExpression") {
|
|
22689
|
-
const path2 = getMemberDependencyPath(expr);
|
|
22690
|
-
if (path2) deps.add(path2);
|
|
22691
|
-
collectExpressionDependencies(expr.object, deps);
|
|
22692
|
-
if (expr.computed && expr.property.kind !== "Literal") {
|
|
22693
|
-
collectExpressionDependencies(expr.property, deps);
|
|
22807
|
+
const path2 = getMemberDependencyPath(node);
|
|
22808
|
+
if (path2) {
|
|
22809
|
+
deps.add(path2);
|
|
22694
22810
|
}
|
|
22695
|
-
|
|
22696
|
-
}
|
|
22697
|
-
if (expr.kind === "CallExpression") {
|
|
22698
|
-
collectExpressionDependencies(expr.callee, deps);
|
|
22699
|
-
expr.arguments.forEach((a) => collectExpressionDependencies(a, deps));
|
|
22700
|
-
return;
|
|
22701
|
-
}
|
|
22702
|
-
if (expr.kind === "BinaryExpression" || expr.kind === "LogicalExpression") {
|
|
22703
|
-
collectExpressionDependencies(expr.left, deps);
|
|
22704
|
-
collectExpressionDependencies(expr.right, deps);
|
|
22705
|
-
return;
|
|
22706
|
-
}
|
|
22707
|
-
if (expr.kind === "ConditionalExpression") {
|
|
22708
|
-
collectExpressionDependencies(expr.test, deps);
|
|
22709
|
-
collectExpressionDependencies(expr.consequent, deps);
|
|
22710
|
-
collectExpressionDependencies(expr.alternate, deps);
|
|
22711
|
-
return;
|
|
22712
|
-
}
|
|
22713
|
-
if (expr.kind === "UnaryExpression") {
|
|
22714
|
-
collectExpressionDependencies(expr.argument, deps);
|
|
22715
|
-
return;
|
|
22716
|
-
}
|
|
22717
|
-
if (expr.kind === "ArrayExpression") {
|
|
22718
|
-
expr.elements.forEach((el) => collectExpressionDependencies(el, deps));
|
|
22719
|
-
return;
|
|
22720
|
-
}
|
|
22721
|
-
if (expr.kind === "ObjectExpression") {
|
|
22722
|
-
expr.properties.forEach((p) => {
|
|
22723
|
-
if (p.kind === "SpreadElement") {
|
|
22724
|
-
collectExpressionDependencies(p.argument, deps);
|
|
22725
|
-
} else {
|
|
22726
|
-
if (p.computed) collectExpressionDependencies(p.key, deps);
|
|
22727
|
-
collectExpressionDependencies(p.value, deps);
|
|
22728
|
-
}
|
|
22729
|
-
});
|
|
22730
|
-
return;
|
|
22731
|
-
}
|
|
22732
|
-
if (expr.kind === "TemplateLiteral") {
|
|
22733
|
-
expr.expressions.forEach((e) => collectExpressionDependencies(e, deps));
|
|
22734
|
-
return;
|
|
22735
|
-
}
|
|
22811
|
+
});
|
|
22736
22812
|
}
|
|
22737
22813
|
|
|
22738
22814
|
// src/ir/codegen-reactive-kind.ts
|
|
@@ -26110,8 +26186,31 @@ function extractHIRStaticHtml(jsx, ctx, ops, parentPath = [], namespace = null)
|
|
|
26110
26186
|
const resolvedNamespace = resolveNamespaceContext(tagName, namespace);
|
|
26111
26187
|
let html = `<${tagName}`;
|
|
26112
26188
|
const bindings = [];
|
|
26113
|
-
for (
|
|
26189
|
+
for (let attrIndex = 0; attrIndex < jsx.attributes.length; attrIndex++) {
|
|
26190
|
+
const attr = jsx.attributes[attrIndex];
|
|
26114
26191
|
if (attr.isSpread) {
|
|
26192
|
+
if (attr.spreadExpr) {
|
|
26193
|
+
const excluded = /* @__PURE__ */ new Set();
|
|
26194
|
+
for (let nextIndex = attrIndex + 1; nextIndex < jsx.attributes.length; nextIndex++) {
|
|
26195
|
+
const nextAttr = jsx.attributes[nextIndex];
|
|
26196
|
+
if (nextAttr.isSpread) continue;
|
|
26197
|
+
let nextName = normalizeHIRAttrName(nextAttr.name);
|
|
26198
|
+
if (nextName.endsWith("$")) {
|
|
26199
|
+
nextName = nextName.slice(0, -1);
|
|
26200
|
+
}
|
|
26201
|
+
if (nextName === "key") continue;
|
|
26202
|
+
excluded.add(nextName);
|
|
26203
|
+
if (nextName !== nextAttr.name) {
|
|
26204
|
+
excluded.add(nextAttr.name);
|
|
26205
|
+
}
|
|
26206
|
+
}
|
|
26207
|
+
bindings.push({
|
|
26208
|
+
type: "spread",
|
|
26209
|
+
path: [...parentPath],
|
|
26210
|
+
expr: attr.spreadExpr,
|
|
26211
|
+
exclude: excluded.size > 0 ? Array.from(excluded) : void 0
|
|
26212
|
+
});
|
|
26213
|
+
}
|
|
26115
26214
|
continue;
|
|
26116
26215
|
}
|
|
26117
26216
|
let name = normalizeHIRAttrName(attr.name);
|
|
@@ -28296,10 +28395,28 @@ function lowerIntrinsicElement(jsx, ctx) {
|
|
|
28296
28395
|
)
|
|
28297
28396
|
);
|
|
28298
28397
|
}
|
|
28398
|
+
fusedPatchGroups.clear();
|
|
28299
28399
|
};
|
|
28300
28400
|
for (const binding of bindings) {
|
|
28301
28401
|
const targetId = resolveHIRBindingPath(binding.path, nodeCache, statements, ctx, genTemp3);
|
|
28302
|
-
if (binding.type === "
|
|
28402
|
+
if (binding.type === "spread" && binding.expr) {
|
|
28403
|
+
flushFusedPatchGroups();
|
|
28404
|
+
ctx.helpersUsed.add("spread");
|
|
28405
|
+
const spreadValueExpr = lowerDomExpression(binding.expr, ctx, containingRegion);
|
|
28406
|
+
const spreadGetter = t4.arrowFunctionExpression([], spreadValueExpr);
|
|
28407
|
+
const spreadArgs = [
|
|
28408
|
+
targetId,
|
|
28409
|
+
spreadGetter,
|
|
28410
|
+
t4.booleanLiteral(Boolean(isSVG || isMathML)),
|
|
28411
|
+
t4.booleanLiteral(true)
|
|
28412
|
+
];
|
|
28413
|
+
if (binding.exclude && binding.exclude.length > 0) {
|
|
28414
|
+
spreadArgs.push(t4.arrayExpression(binding.exclude.map((name) => t4.stringLiteral(name))));
|
|
28415
|
+
}
|
|
28416
|
+
statements.push(
|
|
28417
|
+
t4.expressionStatement(t4.callExpression(t4.identifier(RUNTIME_ALIASES.spread), spreadArgs))
|
|
28418
|
+
);
|
|
28419
|
+
} else if (binding.type === "event" && binding.expr && binding.name) {
|
|
28303
28420
|
const eventName = binding.name;
|
|
28304
28421
|
const hasEventOptions = binding.eventOptions && (binding.eventOptions.capture || binding.eventOptions.passive || binding.eventOptions.once);
|
|
28305
28422
|
const isDelegated = DelegatedEvents.has(eventName) && !hasEventOptions;
|
|
@@ -33087,106 +33204,106 @@ function collectUsesFromTerminator(term, add, inFunctionBody = false) {
|
|
|
33087
33204
|
}
|
|
33088
33205
|
}
|
|
33089
33206
|
function collectUsesFromExpression(expr, add, inFunctionBody = false) {
|
|
33090
|
-
|
|
33207
|
+
walkExpression2(expr, add, { inFunctionBody, shadowed: /* @__PURE__ */ new Set() });
|
|
33091
33208
|
}
|
|
33092
|
-
function
|
|
33209
|
+
function walkExpression2(expr, add, ctx) {
|
|
33093
33210
|
switch (expr.kind) {
|
|
33094
33211
|
case "Identifier":
|
|
33095
33212
|
if (!ctx.shadowed.has(expr.name)) add(expr.name, ctx.inFunctionBody);
|
|
33096
33213
|
return;
|
|
33097
33214
|
case "CallExpression":
|
|
33098
33215
|
case "OptionalCallExpression":
|
|
33099
|
-
|
|
33100
|
-
expr.arguments.forEach((arg) =>
|
|
33216
|
+
walkExpression2(expr.callee, add, ctx);
|
|
33217
|
+
expr.arguments.forEach((arg) => walkExpression2(arg, add, ctx));
|
|
33101
33218
|
return;
|
|
33102
33219
|
case "MemberExpression":
|
|
33103
33220
|
case "OptionalMemberExpression":
|
|
33104
|
-
|
|
33105
|
-
if (expr.computed)
|
|
33221
|
+
walkExpression2(expr.object, add, ctx);
|
|
33222
|
+
if (expr.computed) walkExpression2(expr.property, add, ctx);
|
|
33106
33223
|
return;
|
|
33107
33224
|
case "BinaryExpression":
|
|
33108
33225
|
case "LogicalExpression":
|
|
33109
|
-
|
|
33110
|
-
|
|
33226
|
+
walkExpression2(expr.left, add, ctx);
|
|
33227
|
+
walkExpression2(expr.right, add, ctx);
|
|
33111
33228
|
return;
|
|
33112
33229
|
case "UnaryExpression":
|
|
33113
|
-
|
|
33230
|
+
walkExpression2(expr.argument, add, ctx);
|
|
33114
33231
|
return;
|
|
33115
33232
|
case "ConditionalExpression":
|
|
33116
|
-
|
|
33117
|
-
|
|
33118
|
-
|
|
33233
|
+
walkExpression2(expr.test, add, ctx);
|
|
33234
|
+
walkExpression2(expr.consequent, add, ctx);
|
|
33235
|
+
walkExpression2(expr.alternate, add, ctx);
|
|
33119
33236
|
return;
|
|
33120
33237
|
case "ArrayExpression":
|
|
33121
33238
|
expr.elements.forEach((el) => {
|
|
33122
|
-
if (el)
|
|
33239
|
+
if (el) walkExpression2(el, add, ctx);
|
|
33123
33240
|
});
|
|
33124
33241
|
return;
|
|
33125
33242
|
case "ObjectExpression":
|
|
33126
33243
|
expr.properties.forEach((prop) => {
|
|
33127
33244
|
if (prop.kind === "SpreadElement") {
|
|
33128
|
-
|
|
33245
|
+
walkExpression2(prop.argument, add, ctx);
|
|
33129
33246
|
} else {
|
|
33130
|
-
if (prop.computed)
|
|
33131
|
-
|
|
33247
|
+
if (prop.computed) walkExpression2(prop.key, add, ctx);
|
|
33248
|
+
walkExpression2(prop.value, add, ctx);
|
|
33132
33249
|
}
|
|
33133
33250
|
});
|
|
33134
33251
|
return;
|
|
33135
33252
|
case "TemplateLiteral":
|
|
33136
|
-
expr.expressions.forEach((e) =>
|
|
33253
|
+
expr.expressions.forEach((e) => walkExpression2(e, add, ctx));
|
|
33137
33254
|
return;
|
|
33138
33255
|
case "SpreadElement":
|
|
33139
|
-
|
|
33256
|
+
walkExpression2(expr.argument, add, ctx);
|
|
33140
33257
|
return;
|
|
33141
33258
|
case "SequenceExpression":
|
|
33142
|
-
expr.expressions.forEach((e) =>
|
|
33259
|
+
expr.expressions.forEach((e) => walkExpression2(e, add, ctx));
|
|
33143
33260
|
return;
|
|
33144
33261
|
case "AwaitExpression":
|
|
33145
|
-
|
|
33262
|
+
walkExpression2(expr.argument, add, ctx);
|
|
33146
33263
|
return;
|
|
33147
33264
|
case "NewExpression":
|
|
33148
|
-
|
|
33149
|
-
expr.arguments.forEach((arg) =>
|
|
33265
|
+
walkExpression2(expr.callee, add, ctx);
|
|
33266
|
+
expr.arguments.forEach((arg) => walkExpression2(arg, add, ctx));
|
|
33150
33267
|
return;
|
|
33151
33268
|
case "ArrowFunction": {
|
|
33152
33269
|
const shadowed = new Set(ctx.shadowed);
|
|
33153
33270
|
expr.params.forEach((p) => shadowed.add(p.name));
|
|
33154
33271
|
if (expr.isExpression) {
|
|
33155
|
-
|
|
33272
|
+
walkExpression2(expr.body, add, { inFunctionBody: true, shadowed });
|
|
33156
33273
|
return;
|
|
33157
33274
|
}
|
|
33158
|
-
|
|
33275
|
+
walkBlocks2(expr.body, add, { inFunctionBody: true, shadowed });
|
|
33159
33276
|
return;
|
|
33160
33277
|
}
|
|
33161
33278
|
case "FunctionExpression": {
|
|
33162
33279
|
const shadowed = new Set(ctx.shadowed);
|
|
33163
33280
|
expr.params.forEach((p) => shadowed.add(p.name));
|
|
33164
|
-
|
|
33281
|
+
walkBlocks2(expr.body, add, { inFunctionBody: true, shadowed });
|
|
33165
33282
|
return;
|
|
33166
33283
|
}
|
|
33167
33284
|
case "AssignmentExpression":
|
|
33168
|
-
|
|
33169
|
-
|
|
33285
|
+
walkExpression2(expr.left, add, ctx);
|
|
33286
|
+
walkExpression2(expr.right, add, ctx);
|
|
33170
33287
|
return;
|
|
33171
33288
|
case "UpdateExpression":
|
|
33172
|
-
|
|
33289
|
+
walkExpression2(expr.argument, add, ctx);
|
|
33173
33290
|
return;
|
|
33174
33291
|
case "JSXElement":
|
|
33175
33292
|
if (typeof expr.tagName !== "string") {
|
|
33176
|
-
|
|
33293
|
+
walkExpression2(expr.tagName, add, ctx);
|
|
33177
33294
|
}
|
|
33178
33295
|
expr.attributes.forEach((attr) => {
|
|
33179
33296
|
if (attr.isSpread && attr.spreadExpr) {
|
|
33180
|
-
|
|
33297
|
+
walkExpression2(attr.spreadExpr, add, ctx);
|
|
33181
33298
|
} else if (attr.value) {
|
|
33182
|
-
|
|
33299
|
+
walkExpression2(attr.value, add, ctx);
|
|
33183
33300
|
}
|
|
33184
33301
|
});
|
|
33185
33302
|
expr.children.forEach((child) => {
|
|
33186
33303
|
if (child.kind === "expression") {
|
|
33187
|
-
|
|
33304
|
+
walkExpression2(child.value, add, ctx);
|
|
33188
33305
|
} else if (child.kind === "element") {
|
|
33189
|
-
|
|
33306
|
+
walkExpression2(child.value, add, ctx);
|
|
33190
33307
|
}
|
|
33191
33308
|
});
|
|
33192
33309
|
return;
|
|
@@ -33194,16 +33311,16 @@ function walkExpression(expr, add, ctx) {
|
|
|
33194
33311
|
return;
|
|
33195
33312
|
}
|
|
33196
33313
|
}
|
|
33197
|
-
function
|
|
33314
|
+
function walkBlocks2(blocks, add, ctx) {
|
|
33198
33315
|
for (const block of blocks) {
|
|
33199
33316
|
for (const instr of block.instructions) {
|
|
33200
33317
|
if (instr.kind === "Assign") {
|
|
33201
|
-
|
|
33318
|
+
walkExpression2(instr.value, add, ctx);
|
|
33202
33319
|
if (instr.declarationKind) {
|
|
33203
33320
|
ctx.shadowed.add(instr.target.name);
|
|
33204
33321
|
}
|
|
33205
33322
|
} else if (instr.kind === "Expression") {
|
|
33206
|
-
|
|
33323
|
+
walkExpression2(instr.value, add, ctx);
|
|
33207
33324
|
} else if (instr.kind === "Phi") {
|
|
33208
33325
|
instr.sources.forEach((src) => {
|
|
33209
33326
|
if (!ctx.shadowed.has(src.id.name)) add(src.id.name, ctx.inFunctionBody);
|
|
@@ -33222,7 +33339,7 @@ function walkBlocks(blocks, add, ctx) {
|
|
|
33222
33339
|
function collectExpressionIdentifiers2(expr, deep = false) {
|
|
33223
33340
|
const deps = /* @__PURE__ */ new Set();
|
|
33224
33341
|
const collect = (name) => deps.add(name);
|
|
33225
|
-
|
|
33342
|
+
walkExpression2(expr, (name, _inFunctionBody) => collect(name), {
|
|
33226
33343
|
inFunctionBody: deep,
|
|
33227
33344
|
shadowed: /* @__PURE__ */ new Set()
|
|
33228
33345
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fictjs/compiler",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.15.0",
|
|
4
4
|
"description": "Babel plugin for Fict Compiler",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public",
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
"@types/babel__helper-plugin-utils": "^7.10.3",
|
|
49
49
|
"@types/babel__traverse": "^7.28.0",
|
|
50
50
|
"tsup": "^8.5.1",
|
|
51
|
-
"@fictjs/runtime": "0.
|
|
51
|
+
"@fictjs/runtime": "0.15.0"
|
|
52
52
|
},
|
|
53
53
|
"scripts": {
|
|
54
54
|
"build": "tsup src/index.ts --format cjs,esm --dts",
|