@fictjs/compiler 0.2.2 → 0.2.3
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/index.cjs +795 -204
- package/dist/index.d.cts +41 -1
- package/dist/index.d.ts +41 -1
- package/dist/index.js +791 -203
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -185,7 +185,7 @@ var require_generated = __commonJS({
|
|
|
185
185
|
exports2.isExpression = isExpression2;
|
|
186
186
|
exports2.isExpressionStatement = isExpressionStatement2;
|
|
187
187
|
exports2.isExpressionWrapper = isExpressionWrapper;
|
|
188
|
-
exports2.isFile =
|
|
188
|
+
exports2.isFile = isFile2;
|
|
189
189
|
exports2.isFlow = isFlow;
|
|
190
190
|
exports2.isFlowBaseAnnotation = isFlowBaseAnnotation;
|
|
191
191
|
exports2.isFlowDeclaration = isFlowDeclaration;
|
|
@@ -495,7 +495,7 @@ var require_generated = __commonJS({
|
|
|
495
495
|
if (node.type !== "ExpressionStatement") return false;
|
|
496
496
|
return opts == null || (0, _shallowEqual.default)(node, opts);
|
|
497
497
|
}
|
|
498
|
-
function
|
|
498
|
+
function isFile2(node, opts) {
|
|
499
499
|
if (!node) return false;
|
|
500
500
|
if (node.type !== "File") return false;
|
|
501
501
|
return opts == null || (0, _shallowEqual.default)(node, opts);
|
|
@@ -7328,7 +7328,7 @@ var require_lowercase = __commonJS({
|
|
|
7328
7328
|
exports2.restElement = restElement;
|
|
7329
7329
|
exports2.restProperty = RestProperty;
|
|
7330
7330
|
exports2.returnStatement = returnStatement2;
|
|
7331
|
-
exports2.sequenceExpression =
|
|
7331
|
+
exports2.sequenceExpression = sequenceExpression2;
|
|
7332
7332
|
exports2.spreadElement = spreadElement;
|
|
7333
7333
|
exports2.spreadProperty = SpreadProperty;
|
|
7334
7334
|
exports2.staticBlock = staticBlock;
|
|
@@ -7882,7 +7882,7 @@ var require_lowercase = __commonJS({
|
|
|
7882
7882
|
validate(defs.argument, node, "argument", argument, 1);
|
|
7883
7883
|
return node;
|
|
7884
7884
|
}
|
|
7885
|
-
function
|
|
7885
|
+
function sequenceExpression2(expressions) {
|
|
7886
7886
|
const node = {
|
|
7887
7887
|
type: "SequenceExpression",
|
|
7888
7888
|
expressions
|
|
@@ -11976,7 +11976,7 @@ var require_cloneNode = __commonJS({
|
|
|
11976
11976
|
Object.defineProperty(exports2, "__esModule", {
|
|
11977
11977
|
value: true
|
|
11978
11978
|
});
|
|
11979
|
-
exports2.default =
|
|
11979
|
+
exports2.default = cloneNode2;
|
|
11980
11980
|
var _index = require_definitions();
|
|
11981
11981
|
var _index2 = require_generated();
|
|
11982
11982
|
var {
|
|
@@ -11996,7 +11996,7 @@ var require_cloneNode = __commonJS({
|
|
|
11996
11996
|
}
|
|
11997
11997
|
return cloneIfNode(obj, deep, withoutLoc, commentsCache);
|
|
11998
11998
|
}
|
|
11999
|
-
function
|
|
11999
|
+
function cloneNode2(node, deep = true, withoutLoc = false) {
|
|
12000
12000
|
return cloneNodeInternal(node, deep, withoutLoc, /* @__PURE__ */ new Map());
|
|
12001
12001
|
}
|
|
12002
12002
|
function cloneNodeInternal(node, deep = true, withoutLoc = false, commentsCache) {
|
|
@@ -14115,8 +14115,11 @@ var require_lib3 = __commonJS({
|
|
|
14115
14115
|
// src/index.ts
|
|
14116
14116
|
var index_exports = {};
|
|
14117
14117
|
__export(index_exports, {
|
|
14118
|
+
clearModuleMetadata: () => clearModuleMetadata,
|
|
14118
14119
|
createFictPlugin: () => createFictPlugin,
|
|
14119
|
-
default: () => index_default
|
|
14120
|
+
default: () => index_default,
|
|
14121
|
+
resolveModuleMetadata: () => resolveModuleMetadata,
|
|
14122
|
+
setModuleMetadata: () => setModuleMetadata
|
|
14120
14123
|
});
|
|
14121
14124
|
module.exports = __toCommonJS(index_exports);
|
|
14122
14125
|
var import_helper_plugin_utils = require("@babel/helper-plugin-utils");
|
|
@@ -14319,6 +14322,7 @@ function debugWarn(flag, message, data) {
|
|
|
14319
14322
|
// src/ir/build-hir.ts
|
|
14320
14323
|
var import_core = require("@babel/core");
|
|
14321
14324
|
var import_plugin_transform_destructuring = __toESM(require("@babel/plugin-transform-destructuring"), 1);
|
|
14325
|
+
var import_traverse = __toESM(require("@babel/traverse"), 1);
|
|
14322
14326
|
var t = __toESM(require_lib3(), 1);
|
|
14323
14327
|
|
|
14324
14328
|
// src/ir/hir.ts
|
|
@@ -14405,9 +14409,9 @@ function extractDependencyPath(expr) {
|
|
|
14405
14409
|
}
|
|
14406
14410
|
return void 0;
|
|
14407
14411
|
}
|
|
14408
|
-
function pathToString(
|
|
14409
|
-
let result =
|
|
14410
|
-
for (const seg of
|
|
14412
|
+
function pathToString(path2) {
|
|
14413
|
+
let result = path2.base;
|
|
14414
|
+
for (const seg of path2.segments) {
|
|
14411
14415
|
if (seg.optional) {
|
|
14412
14416
|
result += "?.";
|
|
14413
14417
|
} else {
|
|
@@ -14432,42 +14436,56 @@ var resolveDestructuringPlugin = () => {
|
|
|
14432
14436
|
const mod = import_plugin_transform_destructuring.default;
|
|
14433
14437
|
return mod?.default ?? mod;
|
|
14434
14438
|
};
|
|
14435
|
-
var
|
|
14436
|
-
const
|
|
14437
|
-
|
|
14438
|
-
|
|
14439
|
-
|
|
14440
|
-
|
|
14441
|
-
|
|
14442
|
-
|
|
14443
|
-
|
|
14444
|
-
|
|
14445
|
-
|
|
14446
|
-
|
|
14447
|
-
|
|
14448
|
-
|
|
14449
|
-
|
|
14450
|
-
|
|
14451
|
-
|
|
14452
|
-
|
|
14453
|
-
|
|
14454
|
-
|
|
14455
|
-
const
|
|
14456
|
-
if (
|
|
14457
|
-
|
|
14439
|
+
var resolveTraverse = () => {
|
|
14440
|
+
const mod = import_traverse.default;
|
|
14441
|
+
return mod?.default ?? mod;
|
|
14442
|
+
};
|
|
14443
|
+
var OBJECT_REST_HELPERS = /* @__PURE__ */ new Set(["_objectWithoutProperties", "_objectWithoutPropertiesLoose"]);
|
|
14444
|
+
var OBJECT_DESTRUCTURING_EMPTY_HELPER = "_objectDestructuringEmpty";
|
|
14445
|
+
var EXTENDS_HELPER = "_extends";
|
|
14446
|
+
var isSameIdentifier = (left, right) => {
|
|
14447
|
+
return t.isIdentifier(left) && t.isIdentifier(right) && left.name === right.name;
|
|
14448
|
+
};
|
|
14449
|
+
var rewriteObjectRestHelpers = (ast) => {
|
|
14450
|
+
const traverse = resolveTraverse();
|
|
14451
|
+
traverse(ast, {
|
|
14452
|
+
CallExpression(path2) {
|
|
14453
|
+
const { callee, arguments: args } = path2.node;
|
|
14454
|
+
if (t.isIdentifier(callee) && OBJECT_REST_HELPERS.has(callee.name)) {
|
|
14455
|
+
path2.node.callee = t.identifier("__fictPropsRest");
|
|
14456
|
+
return;
|
|
14457
|
+
}
|
|
14458
|
+
if (t.isIdentifier(callee) && callee.name === EXTENDS_HELPER && args.length === 2 && t.isObjectExpression(args[0]) && args[0].properties.length === 0 && t.isSequenceExpression(args[1]) && args[1].expressions.length === 2) {
|
|
14459
|
+
const [checkExpr, sourceExpr] = args[1].expressions;
|
|
14460
|
+
if (t.isCallExpression(checkExpr) && t.isIdentifier(checkExpr.callee) && checkExpr.callee.name === OBJECT_DESTRUCTURING_EMPTY_HELPER && checkExpr.arguments.length === 1) {
|
|
14461
|
+
const [checkArg] = checkExpr.arguments;
|
|
14462
|
+
if (checkArg && isSameIdentifier(checkArg, sourceExpr)) {
|
|
14463
|
+
const restCall = t.callExpression(t.identifier("__fictPropsRest"), [
|
|
14464
|
+
t.cloneNode(sourceExpr, true),
|
|
14465
|
+
t.arrayExpression([])
|
|
14466
|
+
]);
|
|
14467
|
+
path2.replaceWith(t.sequenceExpression([checkExpr, restCall]));
|
|
14468
|
+
}
|
|
14469
|
+
}
|
|
14458
14470
|
}
|
|
14459
14471
|
}
|
|
14460
|
-
};
|
|
14472
|
+
});
|
|
14461
14473
|
};
|
|
14462
14474
|
var expandDestructuringAssignments = (ast) => {
|
|
14475
|
+
const pluginFactory = resolveDestructuringPlugin();
|
|
14476
|
+
if (typeof pluginFactory !== "function") {
|
|
14477
|
+
throw new Error("Expected @babel/plugin-transform-destructuring to export a function");
|
|
14478
|
+
}
|
|
14463
14479
|
const result = (0, import_core.transformFromAstSync)(ast, void 0, {
|
|
14464
14480
|
configFile: false,
|
|
14465
14481
|
babelrc: false,
|
|
14466
14482
|
ast: true,
|
|
14467
14483
|
code: false,
|
|
14468
|
-
plugins: [
|
|
14484
|
+
plugins: [pluginFactory]
|
|
14469
14485
|
});
|
|
14470
|
-
|
|
14486
|
+
const expanded = result?.ast ?? ast;
|
|
14487
|
+
rewriteObjectRestHelpers(expanded);
|
|
14488
|
+
return expanded;
|
|
14471
14489
|
};
|
|
14472
14490
|
var reportUnsupportedExpression = (node, overrideMessage) => {
|
|
14473
14491
|
const loc = getLoc(node);
|
|
@@ -16377,6 +16395,70 @@ function shouldMemoizeRegion(region) {
|
|
|
16377
16395
|
return false;
|
|
16378
16396
|
}
|
|
16379
16397
|
|
|
16398
|
+
// src/module-metadata.ts
|
|
16399
|
+
var import_node_path = __toESM(require("path"), 1);
|
|
16400
|
+
var import_node_fs = require("fs");
|
|
16401
|
+
var globalMetadata = /* @__PURE__ */ new Map();
|
|
16402
|
+
var MODULE_EXTENSIONS = [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs", ".mts", ".cts"];
|
|
16403
|
+
function normalizeFileName(fileName) {
|
|
16404
|
+
return import_node_path.default.resolve(fileName);
|
|
16405
|
+
}
|
|
16406
|
+
function getMetadataStore(options) {
|
|
16407
|
+
return options?.moduleMetadata ?? globalMetadata;
|
|
16408
|
+
}
|
|
16409
|
+
function isFile(pathName) {
|
|
16410
|
+
try {
|
|
16411
|
+
return (0, import_node_fs.statSync)(pathName).isFile();
|
|
16412
|
+
} catch {
|
|
16413
|
+
return false;
|
|
16414
|
+
}
|
|
16415
|
+
}
|
|
16416
|
+
function resolveImportSource(source, importer, store) {
|
|
16417
|
+
if (!importer) return void 0;
|
|
16418
|
+
const isAbsolute = import_node_path.default.isAbsolute(source);
|
|
16419
|
+
if (!isAbsolute && !source.startsWith(".")) return void 0;
|
|
16420
|
+
const base = isAbsolute ? source : import_node_path.default.resolve(import_node_path.default.dirname(importer), source);
|
|
16421
|
+
const normalized = normalizeFileName(base);
|
|
16422
|
+
if (store.has(normalized)) return normalized;
|
|
16423
|
+
if ((0, import_node_fs.existsSync)(normalized) && isFile(normalized)) return normalized;
|
|
16424
|
+
const ext = import_node_path.default.extname(normalized);
|
|
16425
|
+
if (!ext) {
|
|
16426
|
+
for (const suffix of MODULE_EXTENSIONS) {
|
|
16427
|
+
const candidate = `${normalized}${suffix}`;
|
|
16428
|
+
if (store.has(candidate)) return candidate;
|
|
16429
|
+
if ((0, import_node_fs.existsSync)(candidate) && isFile(candidate)) return candidate;
|
|
16430
|
+
}
|
|
16431
|
+
}
|
|
16432
|
+
for (const suffix of MODULE_EXTENSIONS) {
|
|
16433
|
+
const candidate = import_node_path.default.join(normalized, `index${suffix}`);
|
|
16434
|
+
if (store.has(candidate)) return candidate;
|
|
16435
|
+
if ((0, import_node_fs.existsSync)(candidate) && isFile(candidate)) return candidate;
|
|
16436
|
+
}
|
|
16437
|
+
return void 0;
|
|
16438
|
+
}
|
|
16439
|
+
function resolveModuleMetadata(source, importer, options) {
|
|
16440
|
+
if (options?.resolveModuleMetadata) {
|
|
16441
|
+
const resolved = options.resolveModuleMetadata(source, importer);
|
|
16442
|
+
if (resolved) return resolved;
|
|
16443
|
+
}
|
|
16444
|
+
const store = getMetadataStore(options);
|
|
16445
|
+
const resolvedKey = resolveImportSource(source, importer, store);
|
|
16446
|
+
if (resolvedKey) {
|
|
16447
|
+
return store.get(resolvedKey);
|
|
16448
|
+
}
|
|
16449
|
+
if (store.has(source)) return store.get(source);
|
|
16450
|
+
return void 0;
|
|
16451
|
+
}
|
|
16452
|
+
function setModuleMetadata(fileName, metadata, options) {
|
|
16453
|
+
if (!fileName) return;
|
|
16454
|
+
const store = getMetadataStore(options);
|
|
16455
|
+
store.set(normalizeFileName(fileName), metadata);
|
|
16456
|
+
}
|
|
16457
|
+
function clearModuleMetadata(options) {
|
|
16458
|
+
const store = getMetadataStore(options);
|
|
16459
|
+
store.clear();
|
|
16460
|
+
}
|
|
16461
|
+
|
|
16380
16462
|
// src/validation.ts
|
|
16381
16463
|
var DiagnosticMessages = {
|
|
16382
16464
|
["FICT-P001" /* FICT_P001 */]: "Props destructuring falls back to non-reactive binding.",
|
|
@@ -16569,6 +16651,23 @@ function buildPropsPlan(attributes, children, ctx, helpers) {
|
|
|
16569
16651
|
}
|
|
16570
16652
|
return false;
|
|
16571
16653
|
};
|
|
16654
|
+
const getBaseIdentifier2 = (expr) => {
|
|
16655
|
+
if (expr.kind === "Identifier") return expr.name;
|
|
16656
|
+
if (expr.kind === "MemberExpression" || expr.kind === "OptionalMemberExpression") {
|
|
16657
|
+
return getBaseIdentifier2(expr.object);
|
|
16658
|
+
}
|
|
16659
|
+
return null;
|
|
16660
|
+
};
|
|
16661
|
+
const isDynamicStoreMember = (expr) => {
|
|
16662
|
+
if (expr.kind !== "MemberExpression" && expr.kind !== "OptionalMemberExpression") return false;
|
|
16663
|
+
if (!expr.computed) return false;
|
|
16664
|
+
if (expr.property.kind === "Literal" && (typeof expr.property.value === "string" || typeof expr.property.value === "number")) {
|
|
16665
|
+
return false;
|
|
16666
|
+
}
|
|
16667
|
+
const base = getBaseIdentifier2(expr.object);
|
|
16668
|
+
if (!base) return false;
|
|
16669
|
+
return ctx.storeVars?.has(helpers.deSSAVarName(base)) ?? false;
|
|
16670
|
+
};
|
|
16572
16671
|
const flushBucket = () => {
|
|
16573
16672
|
if (bucket.length === 0) return;
|
|
16574
16673
|
segments.push({ kind: "object", properties: bucket });
|
|
@@ -16640,13 +16739,15 @@ function buildPropsPlan(attributes, children, ctx, helpers) {
|
|
|
16640
16739
|
ctx
|
|
16641
16740
|
) : null;
|
|
16642
16741
|
const useMemoProp = usesTracked && trackedExpr && t4.isExpression(trackedExpr) && !t4.isIdentifier(trackedExpr) && !t4.isMemberExpression(trackedExpr) && !t4.isLiteral(trackedExpr);
|
|
16742
|
+
const forceMemoProp = usesTracked && isDynamicStoreMember(attr.value);
|
|
16743
|
+
const shouldMemoProp = useMemoProp || forceMemoProp;
|
|
16643
16744
|
const valueExpr = !isFunctionLike && isAccessorBase && baseIdent ? (() => {
|
|
16644
16745
|
ctx.helpersUsed.add("propGetter");
|
|
16645
16746
|
return t4.callExpression(t4.identifier(RUNTIME_ALIASES.propGetter), [
|
|
16646
16747
|
t4.arrowFunctionExpression([], t4.callExpression(t4.identifier(baseIdent), []))
|
|
16647
16748
|
]);
|
|
16648
16749
|
})() : usesTracked && t4.isExpression(lowered) ? (() => {
|
|
16649
|
-
if (
|
|
16750
|
+
if (shouldMemoProp) {
|
|
16650
16751
|
ctx.helpersUsed.add("prop");
|
|
16651
16752
|
return t4.callExpression(t4.identifier(RUNTIME_ALIASES.prop), [
|
|
16652
16753
|
t4.arrowFunctionExpression([], trackedExpr ?? lowered)
|
|
@@ -16839,7 +16940,13 @@ function rewriteExprWithMap(expr, rewrites) {
|
|
|
16839
16940
|
return {
|
|
16840
16941
|
...expr,
|
|
16841
16942
|
object: rewriteExprWithMap(expr.object, rewrites),
|
|
16842
|
-
property: rewriteExprWithMap(expr.property, rewrites)
|
|
16943
|
+
property: expr.computed ? rewriteExprWithMap(expr.property, rewrites) : expr.property
|
|
16944
|
+
};
|
|
16945
|
+
case "OptionalMemberExpression":
|
|
16946
|
+
return {
|
|
16947
|
+
...expr,
|
|
16948
|
+
object: rewriteExprWithMap(expr.object, rewrites),
|
|
16949
|
+
property: expr.computed ? rewriteExprWithMap(expr.property, rewrites) : expr.property
|
|
16843
16950
|
};
|
|
16844
16951
|
case "BinaryExpression":
|
|
16845
16952
|
case "LogicalExpression":
|
|
@@ -16862,11 +16969,12 @@ function rewriteExprWithMap(expr, rewrites) {
|
|
|
16862
16969
|
case "ObjectExpression":
|
|
16863
16970
|
return {
|
|
16864
16971
|
...expr,
|
|
16865
|
-
properties: expr.properties.map((p) =>
|
|
16866
|
-
|
|
16867
|
-
|
|
16868
|
-
|
|
16869
|
-
|
|
16972
|
+
properties: expr.properties.map((p) => {
|
|
16973
|
+
if (p.kind === "SpreadElement") {
|
|
16974
|
+
return { ...p, argument: rewriteExprWithMap(p.argument, rewrites) };
|
|
16975
|
+
}
|
|
16976
|
+
return { ...p, value: rewriteExprWithMap(p.value, rewrites) };
|
|
16977
|
+
})
|
|
16870
16978
|
};
|
|
16871
16979
|
case "ImportExpression":
|
|
16872
16980
|
return {
|
|
@@ -16980,7 +17088,17 @@ function toSSA(fn) {
|
|
|
16980
17088
|
arguments: expr.arguments.map((a) => renameExpr(a))
|
|
16981
17089
|
};
|
|
16982
17090
|
case "MemberExpression":
|
|
16983
|
-
return {
|
|
17091
|
+
return {
|
|
17092
|
+
...expr,
|
|
17093
|
+
object: renameExpr(expr.object),
|
|
17094
|
+
property: expr.computed ? renameExpr(expr.property) : expr.property
|
|
17095
|
+
};
|
|
17096
|
+
case "OptionalMemberExpression":
|
|
17097
|
+
return {
|
|
17098
|
+
...expr,
|
|
17099
|
+
object: renameExpr(expr.object),
|
|
17100
|
+
property: expr.computed ? renameExpr(expr.property) : expr.property
|
|
17101
|
+
};
|
|
16984
17102
|
case "BinaryExpression":
|
|
16985
17103
|
case "LogicalExpression":
|
|
16986
17104
|
return { ...expr, left: renameExpr(expr.left), right: renameExpr(expr.right) };
|
|
@@ -16998,11 +17116,12 @@ function toSSA(fn) {
|
|
|
16998
17116
|
case "ObjectExpression":
|
|
16999
17117
|
return {
|
|
17000
17118
|
...expr,
|
|
17001
|
-
properties: expr.properties.map((p) =>
|
|
17002
|
-
|
|
17003
|
-
|
|
17004
|
-
|
|
17005
|
-
|
|
17119
|
+
properties: expr.properties.map((p) => {
|
|
17120
|
+
if (p.kind === "SpreadElement") {
|
|
17121
|
+
return { ...p, argument: renameExpr(p.argument) };
|
|
17122
|
+
}
|
|
17123
|
+
return { ...p, value: renameExpr(p.value) };
|
|
17124
|
+
})
|
|
17006
17125
|
};
|
|
17007
17126
|
default:
|
|
17008
17127
|
return expr;
|
|
@@ -17497,8 +17616,8 @@ function mergeOverlappingScopes(scopes, _byName) {
|
|
|
17497
17616
|
scope.blocks.forEach((b) => merged.blocks.add(b));
|
|
17498
17617
|
scope.dependencies.forEach((d) => merged.dependencies.add(d));
|
|
17499
17618
|
for (const [base, paths] of scope.dependencyPaths) {
|
|
17500
|
-
for (const
|
|
17501
|
-
addPath(merged.dependencyPaths, base,
|
|
17619
|
+
for (const path2 of paths) {
|
|
17620
|
+
addPath(merged.dependencyPaths, base, path2);
|
|
17502
17621
|
}
|
|
17503
17622
|
}
|
|
17504
17623
|
merged.hasExternalEffect = merged.hasExternalEffect || scope.hasExternalEffect;
|
|
@@ -17592,12 +17711,12 @@ function collectExprReads(expr, into, paths, bound = /* @__PURE__ */ new Set(),
|
|
|
17592
17711
|
if (bound.has(baseName(expr.name))) return;
|
|
17593
17712
|
into.add(expr.name);
|
|
17594
17713
|
if (paths) {
|
|
17595
|
-
const
|
|
17714
|
+
const path2 = {
|
|
17596
17715
|
base: expr.name,
|
|
17597
17716
|
segments: [],
|
|
17598
17717
|
hasOptional: false
|
|
17599
17718
|
};
|
|
17600
|
-
addPath(paths, expr.name,
|
|
17719
|
+
addPath(paths, expr.name, path2);
|
|
17601
17720
|
}
|
|
17602
17721
|
return;
|
|
17603
17722
|
case "CallExpression": {
|
|
@@ -17753,11 +17872,11 @@ function collectExprReads(expr, into, paths, bound = /* @__PURE__ */ new Set(),
|
|
|
17753
17872
|
return;
|
|
17754
17873
|
}
|
|
17755
17874
|
}
|
|
17756
|
-
function addPath(paths, base,
|
|
17875
|
+
function addPath(paths, base, path2) {
|
|
17757
17876
|
const existing = paths.get(base) ?? [];
|
|
17758
|
-
const pathStr = pathToString(
|
|
17877
|
+
const pathStr = pathToString(path2);
|
|
17759
17878
|
if (!existing.some((p) => pathToString(p) === pathStr)) {
|
|
17760
|
-
existing.push(
|
|
17879
|
+
existing.push(path2);
|
|
17761
17880
|
paths.set(base, existing);
|
|
17762
17881
|
}
|
|
17763
17882
|
}
|
|
@@ -17776,11 +17895,11 @@ function analyzeOptionalChainDependencies(scope) {
|
|
|
17776
17895
|
} else {
|
|
17777
17896
|
let hasRequiredPath = false;
|
|
17778
17897
|
let hasOptionalOnlyPath = false;
|
|
17779
|
-
for (const
|
|
17780
|
-
if (!
|
|
17898
|
+
for (const path2 of paths) {
|
|
17899
|
+
if (!path2.hasOptional) {
|
|
17781
17900
|
hasRequiredPath = true;
|
|
17782
17901
|
} else {
|
|
17783
|
-
const firstOptionalIndex =
|
|
17902
|
+
const firstOptionalIndex = path2.segments.findIndex((s) => s.optional);
|
|
17784
17903
|
if (firstOptionalIndex === 0) {
|
|
17785
17904
|
hasOptionalOnlyPath = true;
|
|
17786
17905
|
} else if (firstOptionalIndex > 0) {
|
|
@@ -18531,12 +18650,23 @@ function createPropsShape() {
|
|
|
18531
18650
|
};
|
|
18532
18651
|
}
|
|
18533
18652
|
function cloneKeyContext(ctx) {
|
|
18534
|
-
|
|
18653
|
+
const cloneMap = (map) => {
|
|
18654
|
+
const next = /* @__PURE__ */ new Map();
|
|
18655
|
+
for (const [key, value] of map.entries()) {
|
|
18656
|
+
next.set(key, new Set(value));
|
|
18657
|
+
}
|
|
18658
|
+
return next;
|
|
18659
|
+
};
|
|
18660
|
+
return {
|
|
18661
|
+
values: cloneMap(ctx.values),
|
|
18662
|
+
keySets: cloneMap(ctx.keySets)
|
|
18663
|
+
};
|
|
18535
18664
|
}
|
|
18536
18665
|
function clearPatternBindings(pattern, ctx) {
|
|
18537
18666
|
if (!pattern || typeof pattern !== "object") return;
|
|
18538
18667
|
if (t2.isIdentifier(pattern)) {
|
|
18539
|
-
ctx.delete(pattern.name);
|
|
18668
|
+
ctx.values.delete(pattern.name);
|
|
18669
|
+
ctx.keySets.delete(pattern.name);
|
|
18540
18670
|
return;
|
|
18541
18671
|
}
|
|
18542
18672
|
if (t2.isRestElement(pattern)) {
|
|
@@ -18563,19 +18693,106 @@ function clearPatternBindings(pattern, ctx) {
|
|
|
18563
18693
|
}
|
|
18564
18694
|
}
|
|
18565
18695
|
}
|
|
18566
|
-
function
|
|
18696
|
+
function resolveNarrowedKeys(expr, ctx) {
|
|
18567
18697
|
if (expr.kind === "Literal") {
|
|
18568
18698
|
if (typeof expr.value === "string" || typeof expr.value === "number") {
|
|
18569
|
-
return expr.value;
|
|
18699
|
+
return /* @__PURE__ */ new Set([expr.value]);
|
|
18570
18700
|
}
|
|
18571
18701
|
return null;
|
|
18572
18702
|
}
|
|
18573
18703
|
if (expr.kind === "Identifier") {
|
|
18574
|
-
|
|
18704
|
+
const value = ctx.values.get(expr.name);
|
|
18705
|
+
return value ? new Set(value) : null;
|
|
18706
|
+
}
|
|
18707
|
+
if (expr.kind === "ConditionalExpression") {
|
|
18708
|
+
const consequent = resolveNarrowedKeys(expr.consequent, ctx);
|
|
18709
|
+
const alternate = resolveNarrowedKeys(expr.alternate, ctx);
|
|
18710
|
+
if (consequent && alternate) {
|
|
18711
|
+
return /* @__PURE__ */ new Set([...consequent, ...alternate]);
|
|
18712
|
+
}
|
|
18713
|
+
return null;
|
|
18714
|
+
}
|
|
18715
|
+
if (expr.kind === "SequenceExpression" && expr.expressions.length > 0) {
|
|
18716
|
+
const last = expr.expressions[expr.expressions.length - 1];
|
|
18717
|
+
return resolveNarrowedKeys(last, ctx);
|
|
18718
|
+
}
|
|
18719
|
+
if (expr.kind === "MemberExpression" || expr.kind === "OptionalMemberExpression") {
|
|
18720
|
+
if (expr.computed && expr.object.kind === "Identifier") {
|
|
18721
|
+
const keySet = ctx.keySets.get(expr.object.name);
|
|
18722
|
+
if (keySet && keySet.size > 0) {
|
|
18723
|
+
return new Set(keySet);
|
|
18724
|
+
}
|
|
18725
|
+
}
|
|
18726
|
+
}
|
|
18727
|
+
return null;
|
|
18728
|
+
}
|
|
18729
|
+
function resolveKeySet(expr, ctx) {
|
|
18730
|
+
if (expr.kind === "Identifier") {
|
|
18731
|
+
const set = ctx.keySets.get(expr.name);
|
|
18732
|
+
return set ? new Set(set) : null;
|
|
18733
|
+
}
|
|
18734
|
+
if (expr.kind === "ArrayExpression") {
|
|
18735
|
+
const values = [];
|
|
18736
|
+
for (const el of expr.elements) {
|
|
18737
|
+
if (!el) return null;
|
|
18738
|
+
if (el.kind !== "Literal") return null;
|
|
18739
|
+
if (typeof el.value !== "string" && typeof el.value !== "number") return null;
|
|
18740
|
+
values.push(el.value);
|
|
18741
|
+
}
|
|
18742
|
+
return values.length > 0 ? new Set(values) : null;
|
|
18743
|
+
}
|
|
18744
|
+
if (expr.kind === "CallExpression") {
|
|
18745
|
+
if (expr.callee.kind === "MemberExpression") {
|
|
18746
|
+
const object = expr.callee.object;
|
|
18747
|
+
const property = expr.callee.property;
|
|
18748
|
+
if (object.kind === "Identifier" && object.name === "Object" && !expr.callee.computed && property.kind === "Identifier" && property.name === "keys" && expr.arguments.length === 1) {
|
|
18749
|
+
const arg = expr.arguments[0];
|
|
18750
|
+
if (arg.kind === "ObjectExpression") {
|
|
18751
|
+
const values = [];
|
|
18752
|
+
for (const prop of arg.properties) {
|
|
18753
|
+
if (prop.kind !== "Property") return null;
|
|
18754
|
+
if (prop.key.kind === "Identifier") {
|
|
18755
|
+
values.push(prop.key.name);
|
|
18756
|
+
} else if (prop.key.kind === "Literal") {
|
|
18757
|
+
if (typeof prop.key.value !== "string" && typeof prop.key.value !== "number") {
|
|
18758
|
+
return null;
|
|
18759
|
+
}
|
|
18760
|
+
values.push(prop.key.value);
|
|
18761
|
+
} else {
|
|
18762
|
+
return null;
|
|
18763
|
+
}
|
|
18764
|
+
}
|
|
18765
|
+
return values.length > 0 ? new Set(values) : null;
|
|
18766
|
+
}
|
|
18767
|
+
}
|
|
18768
|
+
}
|
|
18769
|
+
}
|
|
18770
|
+
if (expr.kind === "ConditionalExpression") {
|
|
18771
|
+
const consequent = resolveKeySet(expr.consequent, ctx);
|
|
18772
|
+
const alternate = resolveKeySet(expr.alternate, ctx);
|
|
18773
|
+
if (consequent && alternate) {
|
|
18774
|
+
return /* @__PURE__ */ new Set([...consequent, ...alternate]);
|
|
18775
|
+
}
|
|
18776
|
+
return null;
|
|
18777
|
+
}
|
|
18778
|
+
if (expr.kind === "SequenceExpression" && expr.expressions.length > 0) {
|
|
18779
|
+
const last = expr.expressions[expr.expressions.length - 1];
|
|
18780
|
+
return resolveKeySet(last, ctx);
|
|
18575
18781
|
}
|
|
18576
18782
|
return null;
|
|
18577
18783
|
}
|
|
18578
18784
|
function extractEqualityNarrowing(expr) {
|
|
18785
|
+
if (expr.kind === "LogicalExpression" && expr.operator === "||") {
|
|
18786
|
+
const left = extractEqualityNarrowing(expr.left);
|
|
18787
|
+
const right = extractEqualityNarrowing(expr.right);
|
|
18788
|
+
if (left && right && left.kind === "eq" && right.kind === "eq" && left.name === right.name) {
|
|
18789
|
+
return {
|
|
18790
|
+
name: left.name,
|
|
18791
|
+
values: /* @__PURE__ */ new Set([...left.values, ...right.values]),
|
|
18792
|
+
kind: "eq"
|
|
18793
|
+
};
|
|
18794
|
+
}
|
|
18795
|
+
}
|
|
18579
18796
|
if (expr.kind !== "BinaryExpression") return null;
|
|
18580
18797
|
const isEq = expr.operator === "===";
|
|
18581
18798
|
const isNeq = expr.operator === "!==";
|
|
@@ -18590,17 +18807,55 @@ function extractEqualityNarrowing(expr) {
|
|
|
18590
18807
|
if (expr.left.kind === "Identifier") {
|
|
18591
18808
|
const value = literalValue(expr.right);
|
|
18592
18809
|
if (value !== null) {
|
|
18593
|
-
return { name: expr.left.name, value, kind: isEq ? "eq" : "neq" };
|
|
18810
|
+
return { name: expr.left.name, values: /* @__PURE__ */ new Set([value]), kind: isEq ? "eq" : "neq" };
|
|
18594
18811
|
}
|
|
18595
18812
|
}
|
|
18596
18813
|
if (expr.right.kind === "Identifier") {
|
|
18597
18814
|
const value = literalValue(expr.left);
|
|
18598
18815
|
if (value !== null) {
|
|
18599
|
-
return { name: expr.right.name, value, kind: isEq ? "eq" : "neq" };
|
|
18816
|
+
return { name: expr.right.name, values: /* @__PURE__ */ new Set([value]), kind: isEq ? "eq" : "neq" };
|
|
18600
18817
|
}
|
|
18601
18818
|
}
|
|
18602
18819
|
return null;
|
|
18603
18820
|
}
|
|
18821
|
+
function applyNarrowing(ctx, name, values) {
|
|
18822
|
+
const existing = ctx.values.get(name);
|
|
18823
|
+
if (!existing) {
|
|
18824
|
+
ctx.values.set(name, new Set(values));
|
|
18825
|
+
return;
|
|
18826
|
+
}
|
|
18827
|
+
const intersection = /* @__PURE__ */ new Set();
|
|
18828
|
+
for (const value of existing) {
|
|
18829
|
+
if (values.has(value)) intersection.add(value);
|
|
18830
|
+
}
|
|
18831
|
+
if (intersection.size > 0) {
|
|
18832
|
+
ctx.values.set(name, intersection);
|
|
18833
|
+
} else {
|
|
18834
|
+
ctx.values.delete(name);
|
|
18835
|
+
}
|
|
18836
|
+
}
|
|
18837
|
+
function applyKeyAssignment(ctx, name, expr) {
|
|
18838
|
+
ctx.values.delete(name);
|
|
18839
|
+
ctx.keySets.delete(name);
|
|
18840
|
+
let assignedKeys = null;
|
|
18841
|
+
let keySet = null;
|
|
18842
|
+
if (expr.kind === "Identifier") {
|
|
18843
|
+
assignedKeys = resolveNarrowedKeys(expr, ctx);
|
|
18844
|
+
keySet = resolveKeySet(expr, ctx);
|
|
18845
|
+
if (ctx.keySets.has(expr.name)) {
|
|
18846
|
+
ctx.keySets.delete(expr.name);
|
|
18847
|
+
}
|
|
18848
|
+
} else {
|
|
18849
|
+
assignedKeys = resolveNarrowedKeys(expr, ctx);
|
|
18850
|
+
keySet = resolveKeySet(expr, ctx);
|
|
18851
|
+
}
|
|
18852
|
+
if (assignedKeys && assignedKeys.size > 0) {
|
|
18853
|
+
ctx.values.set(name, new Set(assignedKeys));
|
|
18854
|
+
}
|
|
18855
|
+
if (keySet && keySet.size > 0) {
|
|
18856
|
+
ctx.keySets.set(name, new Set(keySet));
|
|
18857
|
+
}
|
|
18858
|
+
}
|
|
18604
18859
|
function mergeShapes(a, b) {
|
|
18605
18860
|
return {
|
|
18606
18861
|
knownKeys: /* @__PURE__ */ new Set([...a.knownKeys, ...b.knownKeys]),
|
|
@@ -18622,7 +18877,7 @@ function analyzeObjectShapes(fn) {
|
|
|
18622
18877
|
shapes.set(param.name, createUnknownShape({ kind: "param", name: param.name }));
|
|
18623
18878
|
}
|
|
18624
18879
|
}
|
|
18625
|
-
const baseCtx = /* @__PURE__ */ new Map();
|
|
18880
|
+
const baseCtx = { values: /* @__PURE__ */ new Map(), keySets: /* @__PURE__ */ new Map() };
|
|
18626
18881
|
let structured = null;
|
|
18627
18882
|
try {
|
|
18628
18883
|
structured = structurizeCFG(fn, {
|
|
@@ -18709,9 +18964,9 @@ function analyzeStructuredNode(node, shapes, propertyReads, ctx) {
|
|
|
18709
18964
|
const alternateCtx = cloneKeyContext(ctx);
|
|
18710
18965
|
if (narrowing) {
|
|
18711
18966
|
if (narrowing.kind === "eq") {
|
|
18712
|
-
consequentCtx
|
|
18967
|
+
applyNarrowing(consequentCtx, narrowing.name, narrowing.values);
|
|
18713
18968
|
} else {
|
|
18714
|
-
alternateCtx
|
|
18969
|
+
applyNarrowing(alternateCtx, narrowing.name, narrowing.values);
|
|
18715
18970
|
}
|
|
18716
18971
|
}
|
|
18717
18972
|
analyzeStructuredNode(node.consequent, shapes, propertyReads, consequentCtx);
|
|
@@ -18726,7 +18981,7 @@ function analyzeStructuredNode(node, shapes, propertyReads, ctx) {
|
|
|
18726
18981
|
for (const caseNode of node.cases) {
|
|
18727
18982
|
const caseCtx = cloneKeyContext(ctx);
|
|
18728
18983
|
if (discriminant && caseNode.test?.kind === "Literal" && (typeof caseNode.test.value === "string" || typeof caseNode.test.value === "number")) {
|
|
18729
|
-
caseCtx
|
|
18984
|
+
applyNarrowing(caseCtx, discriminant, /* @__PURE__ */ new Set([caseNode.test.value]));
|
|
18730
18985
|
}
|
|
18731
18986
|
analyzeStructuredNode(caseNode.body, shapes, propertyReads, caseCtx);
|
|
18732
18987
|
}
|
|
@@ -18757,7 +19012,8 @@ function analyzeStructuredNode(node, shapes, propertyReads, ctx) {
|
|
|
18757
19012
|
analyzeExpression(node.iterable, shapes, propertyReads, ctx);
|
|
18758
19013
|
{
|
|
18759
19014
|
const bodyCtx = cloneKeyContext(ctx);
|
|
18760
|
-
bodyCtx.delete(node.variable);
|
|
19015
|
+
bodyCtx.values.delete(node.variable);
|
|
19016
|
+
bodyCtx.keySets.delete(node.variable);
|
|
18761
19017
|
if (node.pattern) {
|
|
18762
19018
|
clearPatternBindings(node.pattern, bodyCtx);
|
|
18763
19019
|
}
|
|
@@ -18768,7 +19024,8 @@ function analyzeStructuredNode(node, shapes, propertyReads, ctx) {
|
|
|
18768
19024
|
analyzeExpression(node.object, shapes, propertyReads, ctx);
|
|
18769
19025
|
{
|
|
18770
19026
|
const bodyCtx = cloneKeyContext(ctx);
|
|
18771
|
-
bodyCtx.delete(node.variable);
|
|
19027
|
+
bodyCtx.values.delete(node.variable);
|
|
19028
|
+
bodyCtx.keySets.delete(node.variable);
|
|
18772
19029
|
if (node.pattern) {
|
|
18773
19030
|
clearPatternBindings(node.pattern, bodyCtx);
|
|
18774
19031
|
}
|
|
@@ -18780,7 +19037,8 @@ function analyzeStructuredNode(node, shapes, propertyReads, ctx) {
|
|
|
18780
19037
|
if (node.handler) {
|
|
18781
19038
|
const handlerCtx = cloneKeyContext(ctx);
|
|
18782
19039
|
if (node.handler.param) {
|
|
18783
|
-
handlerCtx.delete(node.handler.param);
|
|
19040
|
+
handlerCtx.values.delete(node.handler.param);
|
|
19041
|
+
handlerCtx.keySets.delete(node.handler.param);
|
|
18784
19042
|
}
|
|
18785
19043
|
analyzeStructuredNode(node.handler.body, shapes, propertyReads, handlerCtx);
|
|
18786
19044
|
}
|
|
@@ -18806,9 +19064,7 @@ function analyzeStructuredNode(node, shapes, propertyReads, ctx) {
|
|
|
18806
19064
|
}
|
|
18807
19065
|
function analyzeInstruction(instr, shapes, propertyReads, ctx) {
|
|
18808
19066
|
if (instr.kind === "Assign") {
|
|
18809
|
-
|
|
18810
|
-
ctx.delete(instr.target.name);
|
|
18811
|
-
}
|
|
19067
|
+
applyKeyAssignment(ctx, instr.target.name, instr.value);
|
|
18812
19068
|
const valueShape = analyzeExpression(instr.value, shapes, propertyReads, ctx);
|
|
18813
19069
|
if (valueShape) {
|
|
18814
19070
|
const existing = shapes.get(instr.target.name);
|
|
@@ -18865,12 +19121,14 @@ function analyzeExpression(expr, shapes, propertyReads, ctx) {
|
|
|
18865
19121
|
const reads = propertyReads.get(base) ?? /* @__PURE__ */ new Set();
|
|
18866
19122
|
const baseShape = shapes.get(base);
|
|
18867
19123
|
if (directMember.computed) {
|
|
18868
|
-
const resolved =
|
|
18869
|
-
if (resolved
|
|
18870
|
-
const
|
|
18871
|
-
|
|
18872
|
-
|
|
18873
|
-
baseShape
|
|
19124
|
+
const resolved = resolveNarrowedKeys(directMember.property, ctx);
|
|
19125
|
+
if (resolved && resolved.size > 0) {
|
|
19126
|
+
for (const value of resolved) {
|
|
19127
|
+
const key = String(value);
|
|
19128
|
+
reads.add(key);
|
|
19129
|
+
if (baseShape) {
|
|
19130
|
+
baseShape.knownKeys.add(key);
|
|
19131
|
+
}
|
|
18874
19132
|
}
|
|
18875
19133
|
} else if (baseShape) {
|
|
18876
19134
|
baseShape.dynamicAccess = true;
|
|
@@ -18892,6 +19150,34 @@ function analyzeExpression(expr, shapes, propertyReads, ctx) {
|
|
|
18892
19150
|
return null;
|
|
18893
19151
|
}
|
|
18894
19152
|
case "CallExpression": {
|
|
19153
|
+
if (expr.callee.kind === "MemberExpression") {
|
|
19154
|
+
if (expr.callee.object.kind === "Identifier") {
|
|
19155
|
+
const baseName2 = expr.callee.object.name;
|
|
19156
|
+
const propName = !expr.callee.computed && expr.callee.property.kind === "Identifier" ? expr.callee.property.name : expr.callee.property.kind === "Literal" && typeof expr.callee.property.value === "string" ? expr.callee.property.value : null;
|
|
19157
|
+
if (propName && ctx.keySets.has(baseName2) && [
|
|
19158
|
+
"push",
|
|
19159
|
+
"pop",
|
|
19160
|
+
"shift",
|
|
19161
|
+
"unshift",
|
|
19162
|
+
"splice",
|
|
19163
|
+
"sort",
|
|
19164
|
+
"reverse",
|
|
19165
|
+
"copyWithin",
|
|
19166
|
+
"fill"
|
|
19167
|
+
].includes(propName)) {
|
|
19168
|
+
ctx.keySets.delete(baseName2);
|
|
19169
|
+
}
|
|
19170
|
+
}
|
|
19171
|
+
}
|
|
19172
|
+
for (const arg of expr.arguments) {
|
|
19173
|
+
if (arg.kind === "Identifier" && ctx.keySets.has(arg.name)) {
|
|
19174
|
+
ctx.keySets.delete(arg.name);
|
|
19175
|
+
} else if (arg.kind === "SpreadElement" && arg.argument.kind === "Identifier") {
|
|
19176
|
+
if (ctx.keySets.has(arg.argument.name)) {
|
|
19177
|
+
ctx.keySets.delete(arg.argument.name);
|
|
19178
|
+
}
|
|
19179
|
+
}
|
|
19180
|
+
}
|
|
18895
19181
|
for (const arg of expr.arguments) {
|
|
18896
19182
|
markEscaping(arg, shapes);
|
|
18897
19183
|
}
|
|
@@ -18943,9 +19229,7 @@ function analyzeExpression(expr, shapes, propertyReads, ctx) {
|
|
|
18943
19229
|
}
|
|
18944
19230
|
case "AssignmentExpression": {
|
|
18945
19231
|
if (expr.left.kind === "Identifier") {
|
|
18946
|
-
|
|
18947
|
-
ctx.delete(expr.left.name);
|
|
18948
|
-
}
|
|
19232
|
+
applyKeyAssignment(ctx, expr.left.name, expr.right);
|
|
18949
19233
|
}
|
|
18950
19234
|
if (expr.left.kind === "MemberExpression") {
|
|
18951
19235
|
const base = getBaseIdentifier(expr.left.object);
|
|
@@ -18957,14 +19241,19 @@ function analyzeExpression(expr, shapes, propertyReads, ctx) {
|
|
|
18957
19241
|
} else if (expr.left.property.kind === "Literal" && typeof expr.left.property.value === "string") {
|
|
18958
19242
|
shape.mutableKeys.add(expr.left.property.value);
|
|
18959
19243
|
} else {
|
|
18960
|
-
const resolved =
|
|
18961
|
-
if (resolved
|
|
18962
|
-
|
|
19244
|
+
const resolved = resolveNarrowedKeys(expr.left.property, ctx);
|
|
19245
|
+
if (resolved && resolved.size > 0) {
|
|
19246
|
+
for (const value of resolved) {
|
|
19247
|
+
shape.mutableKeys.add(String(value));
|
|
19248
|
+
}
|
|
18963
19249
|
} else {
|
|
18964
19250
|
shape.dynamicAccess = true;
|
|
18965
19251
|
}
|
|
18966
19252
|
}
|
|
18967
19253
|
}
|
|
19254
|
+
if (ctx.keySets.has(base)) {
|
|
19255
|
+
ctx.keySets.delete(base);
|
|
19256
|
+
}
|
|
18968
19257
|
}
|
|
18969
19258
|
}
|
|
18970
19259
|
analyzeExpression(expr.right, shapes, propertyReads, ctx);
|
|
@@ -18972,8 +19261,13 @@ function analyzeExpression(expr, shapes, propertyReads, ctx) {
|
|
|
18972
19261
|
}
|
|
18973
19262
|
case "UpdateExpression": {
|
|
18974
19263
|
if (expr.argument.kind === "Identifier") {
|
|
18975
|
-
|
|
18976
|
-
|
|
19264
|
+
ctx.values.delete(expr.argument.name);
|
|
19265
|
+
ctx.keySets.delete(expr.argument.name);
|
|
19266
|
+
}
|
|
19267
|
+
if (expr.argument.kind === "MemberExpression") {
|
|
19268
|
+
const base = getBaseIdentifier(expr.argument.object);
|
|
19269
|
+
if (base) {
|
|
19270
|
+
ctx.keySets.delete(base);
|
|
18977
19271
|
}
|
|
18978
19272
|
}
|
|
18979
19273
|
analyzeExpression(expr.argument, shapes, propertyReads, ctx);
|
|
@@ -19405,7 +19699,11 @@ function expressionUsesTracked(expr, ctx) {
|
|
|
19405
19699
|
return ctx.trackedVars.has(deSSAVarName(expr.name)) || (ctx.externalTracked?.has(deSSAVarName(expr.name)) ?? false) || (ctx.memoVars?.has(deSSAVarName(expr.name)) ?? false) || (ctx.aliasVars?.has(deSSAVarName(expr.name)) ?? false);
|
|
19406
19700
|
case "MemberExpression":
|
|
19407
19701
|
case "OptionalMemberExpression":
|
|
19408
|
-
|
|
19702
|
+
if (expressionUsesTracked(expr.object, ctx)) return true;
|
|
19703
|
+
if (expr.computed && expr.property.kind !== "Literal") {
|
|
19704
|
+
return expressionUsesTracked(expr.property, ctx);
|
|
19705
|
+
}
|
|
19706
|
+
return false;
|
|
19409
19707
|
case "CallExpression":
|
|
19410
19708
|
case "OptionalCallExpression":
|
|
19411
19709
|
if (expressionUsesTracked(expr.callee, ctx)) return true;
|
|
@@ -21213,6 +21511,24 @@ function setNodeLoc(node, loc) {
|
|
|
21213
21511
|
node.loc = cloneLoc(loc) ?? null;
|
|
21214
21512
|
return node;
|
|
21215
21513
|
}
|
|
21514
|
+
function serializeHookReturnInfo(info) {
|
|
21515
|
+
const objectProps = info.objectProps ? Object.fromEntries(info.objectProps.entries()) : void 0;
|
|
21516
|
+
const arrayProps = info.arrayProps ? Object.fromEntries(Array.from(info.arrayProps.entries()).map(([k, v]) => [String(k), v])) : void 0;
|
|
21517
|
+
return {
|
|
21518
|
+
objectProps,
|
|
21519
|
+
arrayProps,
|
|
21520
|
+
directAccessor: info.directAccessor
|
|
21521
|
+
};
|
|
21522
|
+
}
|
|
21523
|
+
function deserializeHookReturnInfo(info) {
|
|
21524
|
+
const objectProps = info.objectProps ? new Map(Object.entries(info.objectProps)) : void 0;
|
|
21525
|
+
const arrayProps = info.arrayProps ? new Map(Object.entries(info.arrayProps).map(([k, v]) => [Number.parseInt(k, 10), v])) : void 0;
|
|
21526
|
+
return {
|
|
21527
|
+
objectProps,
|
|
21528
|
+
arrayProps,
|
|
21529
|
+
directAccessor: info.directAccessor
|
|
21530
|
+
};
|
|
21531
|
+
}
|
|
21216
21532
|
function propagateHookResultAlias(targetBase, value, ctx) {
|
|
21217
21533
|
const mapSource = (source) => {
|
|
21218
21534
|
const hookName = ctx.hookResultVarMap?.get(source);
|
|
@@ -21236,6 +21552,15 @@ function propagateHookResultAlias(targetBase, value, ctx) {
|
|
|
21236
21552
|
mapSource(deSSAVarName(firstArg.name));
|
|
21237
21553
|
}
|
|
21238
21554
|
}
|
|
21555
|
+
if (value.kind === "SequenceExpression" && value.expressions.length > 0) {
|
|
21556
|
+
const last = value.expressions[value.expressions.length - 1];
|
|
21557
|
+
if (last && last.kind === "CallExpression" && last.callee.kind === "Identifier" && last.callee.name === "__fictPropsRest") {
|
|
21558
|
+
const firstArg = last.arguments[0];
|
|
21559
|
+
if (firstArg && firstArg.kind === "Identifier") {
|
|
21560
|
+
mapSource(deSSAVarName(firstArg.name));
|
|
21561
|
+
}
|
|
21562
|
+
}
|
|
21563
|
+
}
|
|
21239
21564
|
}
|
|
21240
21565
|
function applyRegionToContext(ctx, region) {
|
|
21241
21566
|
const prevRegion = ctx.currentRegion;
|
|
@@ -21542,6 +21867,7 @@ function createCodegenContext(t4) {
|
|
|
21542
21867
|
aliasVars: /* @__PURE__ */ new Set(),
|
|
21543
21868
|
externalTracked: /* @__PURE__ */ new Set(),
|
|
21544
21869
|
storeVars: /* @__PURE__ */ new Set(),
|
|
21870
|
+
importedNamespaces: /* @__PURE__ */ new Map(),
|
|
21545
21871
|
signalVars: /* @__PURE__ */ new Set(),
|
|
21546
21872
|
functionVars: /* @__PURE__ */ new Set(),
|
|
21547
21873
|
memoVars: /* @__PURE__ */ new Set(),
|
|
@@ -22489,6 +22815,12 @@ function extractKeyFromMapCallback(callback) {
|
|
|
22489
22815
|
if (!jsx) return void 0;
|
|
22490
22816
|
return extractKeyFromAttributes(jsx.attributes);
|
|
22491
22817
|
}
|
|
22818
|
+
function buildOutputParams(fn, t4) {
|
|
22819
|
+
if (fn.rawParams && fn.rawParams.length > 0) {
|
|
22820
|
+
return fn.rawParams.map((param) => t4.cloneNode(param, true));
|
|
22821
|
+
}
|
|
22822
|
+
return fn.params.map((p) => t4.identifier(deSSAVarName(p.name)));
|
|
22823
|
+
}
|
|
22492
22824
|
function lowerTrackedExpression(expr, ctx) {
|
|
22493
22825
|
const regionOverride = ctx.inReturn && ctx.currentFnIsHook ? null : ctx.currentRegion ?? (ctx.trackedVars.size ? {
|
|
22494
22826
|
id: -1,
|
|
@@ -22782,6 +23114,171 @@ function collectRuntimeImportNames(body, t4) {
|
|
|
22782
23114
|
}
|
|
22783
23115
|
return imported;
|
|
22784
23116
|
}
|
|
23117
|
+
function addImportedReactiveBinding(name, kind, ctx) {
|
|
23118
|
+
const base = deSSAVarName(name);
|
|
23119
|
+
if (kind === "signal") {
|
|
23120
|
+
ctx.signalVars?.add(base);
|
|
23121
|
+
} else if (kind === "store") {
|
|
23122
|
+
ctx.storeVars?.add(base);
|
|
23123
|
+
} else if (kind === "memo") {
|
|
23124
|
+
ctx.memoVars?.add(base);
|
|
23125
|
+
}
|
|
23126
|
+
ctx.trackedVars.add(base);
|
|
23127
|
+
}
|
|
23128
|
+
function applyImportedReactiveMetadata(body, ctx, t4, options) {
|
|
23129
|
+
const importer = options?.filename;
|
|
23130
|
+
const namespaces = /* @__PURE__ */ new Map();
|
|
23131
|
+
for (const stmt of body) {
|
|
23132
|
+
if (!t4.isImportDeclaration(stmt)) continue;
|
|
23133
|
+
const meta = resolveModuleMetadata(stmt.source.value, importer, options);
|
|
23134
|
+
if (!meta) continue;
|
|
23135
|
+
for (const spec of stmt.specifiers) {
|
|
23136
|
+
if (t4.isImportSpecifier(spec)) {
|
|
23137
|
+
const importedName = t4.isIdentifier(spec.imported) ? spec.imported.name : String(spec.imported.value);
|
|
23138
|
+
const localName = spec.local.name;
|
|
23139
|
+
const kind = meta.exports[importedName];
|
|
23140
|
+
if (kind) {
|
|
23141
|
+
addImportedReactiveBinding(localName, kind, ctx);
|
|
23142
|
+
}
|
|
23143
|
+
const hookInfo = meta.hooks?.[importedName];
|
|
23144
|
+
if (hookInfo) {
|
|
23145
|
+
ctx.hookReturnInfo = ctx.hookReturnInfo ?? /* @__PURE__ */ new Map();
|
|
23146
|
+
ctx.hookReturnInfo.set(localName, deserializeHookReturnInfo(hookInfo));
|
|
23147
|
+
}
|
|
23148
|
+
continue;
|
|
23149
|
+
}
|
|
23150
|
+
if (t4.isImportDefaultSpecifier(spec)) {
|
|
23151
|
+
const localName = spec.local.name;
|
|
23152
|
+
const kind = meta.exports.default;
|
|
23153
|
+
if (kind) {
|
|
23154
|
+
addImportedReactiveBinding(localName, kind, ctx);
|
|
23155
|
+
}
|
|
23156
|
+
const hookInfo = meta.hooks?.default;
|
|
23157
|
+
if (hookInfo) {
|
|
23158
|
+
ctx.hookReturnInfo = ctx.hookReturnInfo ?? /* @__PURE__ */ new Map();
|
|
23159
|
+
ctx.hookReturnInfo.set(localName, deserializeHookReturnInfo(hookInfo));
|
|
23160
|
+
}
|
|
23161
|
+
continue;
|
|
23162
|
+
}
|
|
23163
|
+
if (t4.isImportNamespaceSpecifier(spec)) {
|
|
23164
|
+
namespaces.set(spec.local.name, meta);
|
|
23165
|
+
}
|
|
23166
|
+
}
|
|
23167
|
+
}
|
|
23168
|
+
if (namespaces.size > 0) {
|
|
23169
|
+
ctx.importedNamespaces = namespaces;
|
|
23170
|
+
}
|
|
23171
|
+
}
|
|
23172
|
+
function classifyReactiveExport(name, ctx) {
|
|
23173
|
+
const base = deSSAVarName(name);
|
|
23174
|
+
if (ctx.storeVars?.has(base)) return "store";
|
|
23175
|
+
if (ctx.signalVars?.has(base)) return "signal";
|
|
23176
|
+
if (ctx.aliasVars?.has(base)) return "signal";
|
|
23177
|
+
if (ctx.memoVars?.has(base)) return "memo";
|
|
23178
|
+
return null;
|
|
23179
|
+
}
|
|
23180
|
+
function buildModuleReactiveMetadata(body, ctx, t4, options, stateMacroNames, memoMacroNames) {
|
|
23181
|
+
const metadata = { exports: {} };
|
|
23182
|
+
const hookExports = {};
|
|
23183
|
+
const addExport = (exportName, localName) => {
|
|
23184
|
+
const kind = classifyReactiveExport(localName, ctx);
|
|
23185
|
+
if (kind) {
|
|
23186
|
+
metadata.exports[exportName] = kind;
|
|
23187
|
+
}
|
|
23188
|
+
const hookInfo = getHookReturnInfo(localName, ctx);
|
|
23189
|
+
if (hookInfo) {
|
|
23190
|
+
hookExports[exportName] = serializeHookReturnInfo(hookInfo);
|
|
23191
|
+
}
|
|
23192
|
+
};
|
|
23193
|
+
const addExportFromSource = (source, importedName, exportName) => {
|
|
23194
|
+
const sourceMeta = resolveModuleMetadata(source, options?.filename, options);
|
|
23195
|
+
if (!sourceMeta) return;
|
|
23196
|
+
const kind = sourceMeta.exports[importedName];
|
|
23197
|
+
if (kind) {
|
|
23198
|
+
metadata.exports[exportName] = kind;
|
|
23199
|
+
}
|
|
23200
|
+
const hookInfo = sourceMeta.hooks?.[importedName];
|
|
23201
|
+
if (hookInfo) {
|
|
23202
|
+
hookExports[exportName] = hookInfo;
|
|
23203
|
+
}
|
|
23204
|
+
};
|
|
23205
|
+
const addDefaultExportKind = (kind) => {
|
|
23206
|
+
if (kind) {
|
|
23207
|
+
metadata.exports.default = kind;
|
|
23208
|
+
}
|
|
23209
|
+
};
|
|
23210
|
+
for (const stmt of body) {
|
|
23211
|
+
if (t4.isExportNamedDeclaration(stmt)) {
|
|
23212
|
+
if (stmt.source && stmt.specifiers.length > 0) {
|
|
23213
|
+
for (const spec of stmt.specifiers) {
|
|
23214
|
+
if (!t4.isExportSpecifier(spec)) continue;
|
|
23215
|
+
const importedName = spec.local.name;
|
|
23216
|
+
const exportName = t4.isIdentifier(spec.exported) ? spec.exported.name : t4.isStringLiteral(spec.exported) ? spec.exported.value : String(spec.exported);
|
|
23217
|
+
addExportFromSource(stmt.source.value, importedName, exportName);
|
|
23218
|
+
}
|
|
23219
|
+
continue;
|
|
23220
|
+
}
|
|
23221
|
+
if (stmt.declaration) {
|
|
23222
|
+
const decl = stmt.declaration;
|
|
23223
|
+
if (t4.isFunctionDeclaration(decl) && decl.id) {
|
|
23224
|
+
addExport(decl.id.name, decl.id.name);
|
|
23225
|
+
} else if (t4.isClassDeclaration(decl) && decl.id) {
|
|
23226
|
+
addExport(decl.id.name, decl.id.name);
|
|
23227
|
+
} else if (t4.isVariableDeclaration(decl)) {
|
|
23228
|
+
for (const v of decl.declarations) {
|
|
23229
|
+
if (t4.isIdentifier(v.id)) {
|
|
23230
|
+
addExport(v.id.name, v.id.name);
|
|
23231
|
+
}
|
|
23232
|
+
}
|
|
23233
|
+
}
|
|
23234
|
+
} else {
|
|
23235
|
+
for (const spec of stmt.specifiers) {
|
|
23236
|
+
if (!t4.isExportSpecifier(spec)) continue;
|
|
23237
|
+
const localName = spec.local.name;
|
|
23238
|
+
const exportName = t4.isIdentifier(spec.exported) ? spec.exported.name : t4.isStringLiteral(spec.exported) ? spec.exported.value : String(spec.exported);
|
|
23239
|
+
addExport(exportName, localName);
|
|
23240
|
+
}
|
|
23241
|
+
}
|
|
23242
|
+
continue;
|
|
23243
|
+
}
|
|
23244
|
+
if (t4.isExportAllDeclaration(stmt)) {
|
|
23245
|
+
const sourceMeta = resolveModuleMetadata(stmt.source.value, options?.filename, options);
|
|
23246
|
+
if (!sourceMeta) continue;
|
|
23247
|
+
for (const [exportName, kind] of Object.entries(sourceMeta.exports)) {
|
|
23248
|
+
if (exportName === "default") continue;
|
|
23249
|
+
metadata.exports[exportName] = kind;
|
|
23250
|
+
}
|
|
23251
|
+
if (sourceMeta.hooks) {
|
|
23252
|
+
for (const [exportName, info] of Object.entries(sourceMeta.hooks)) {
|
|
23253
|
+
if (exportName === "default") continue;
|
|
23254
|
+
hookExports[exportName] = info;
|
|
23255
|
+
}
|
|
23256
|
+
}
|
|
23257
|
+
continue;
|
|
23258
|
+
}
|
|
23259
|
+
if (t4.isExportDefaultDeclaration(stmt)) {
|
|
23260
|
+
const decl = stmt.declaration;
|
|
23261
|
+
if (t4.isIdentifier(decl)) {
|
|
23262
|
+
addExport("default", decl.name);
|
|
23263
|
+
} else if (t4.isFunctionDeclaration(decl) && decl.id) {
|
|
23264
|
+
addExport("default", decl.id.name);
|
|
23265
|
+
} else if (t4.isClassDeclaration(decl) && decl.id) {
|
|
23266
|
+
addExport("default", decl.id.name);
|
|
23267
|
+
} else if (t4.isCallExpression(decl) && t4.isIdentifier(decl.callee)) {
|
|
23268
|
+
const callee = decl.callee.name;
|
|
23269
|
+
if (stateMacroNames.has(callee) || callee === "$store") {
|
|
23270
|
+
addDefaultExportKind(callee === "$store" ? "store" : "signal");
|
|
23271
|
+
} else if (memoMacroNames.has(callee)) {
|
|
23272
|
+
addDefaultExportKind("memo");
|
|
23273
|
+
}
|
|
23274
|
+
}
|
|
23275
|
+
}
|
|
23276
|
+
}
|
|
23277
|
+
if (Object.keys(hookExports).length > 0) {
|
|
23278
|
+
metadata.hooks = hookExports;
|
|
23279
|
+
}
|
|
23280
|
+
return metadata;
|
|
23281
|
+
}
|
|
22785
23282
|
function collectLocalDeclaredNames(params, blocks, t4) {
|
|
22786
23283
|
const declared = /* @__PURE__ */ new Set();
|
|
22787
23284
|
const addPatternNames = (pattern) => {
|
|
@@ -23090,6 +23587,24 @@ function lowerExpressionImpl(expr, ctx, _isAssigned = false) {
|
|
|
23090
23587
|
if (matchesListKeyPattern(expr, ctx)) {
|
|
23091
23588
|
return t4.identifier(ctx.listKeyParamName);
|
|
23092
23589
|
}
|
|
23590
|
+
if (expr.object.kind === "Identifier") {
|
|
23591
|
+
const nsMeta = ctx.importedNamespaces?.get(deSSAVarName(expr.object.name));
|
|
23592
|
+
if (nsMeta) {
|
|
23593
|
+
const propName = getStaticPropName(expr.property, expr.computed);
|
|
23594
|
+
if (typeof propName === "string") {
|
|
23595
|
+
const kind = nsMeta.exports[propName];
|
|
23596
|
+
if (kind === "signal" || kind === "memo") {
|
|
23597
|
+
const member = t4.memberExpression(
|
|
23598
|
+
t4.identifier(deSSAVarName(expr.object.name)),
|
|
23599
|
+
expr.computed ? t4.stringLiteral(propName) : t4.identifier(propName),
|
|
23600
|
+
expr.computed,
|
|
23601
|
+
expr.optional
|
|
23602
|
+
);
|
|
23603
|
+
return t4.callExpression(member, []);
|
|
23604
|
+
}
|
|
23605
|
+
}
|
|
23606
|
+
}
|
|
23607
|
+
}
|
|
23093
23608
|
if (expr.object.kind === "Identifier" && ctx.hookResultVarMap?.has(deSSAVarName(expr.object.name))) {
|
|
23094
23609
|
const hookName = ctx.hookResultVarMap.get(deSSAVarName(expr.object.name));
|
|
23095
23610
|
const info = getHookReturnInfo(hookName, ctx);
|
|
@@ -23581,8 +24096,8 @@ function collectExpressionDependencies(expr, deps) {
|
|
|
23581
24096
|
return;
|
|
23582
24097
|
}
|
|
23583
24098
|
if (expr.kind === "MemberExpression") {
|
|
23584
|
-
const
|
|
23585
|
-
if (
|
|
24099
|
+
const path2 = getMemberDependencyPath(expr);
|
|
24100
|
+
if (path2) deps.add(path2);
|
|
23586
24101
|
collectExpressionDependencies(expr.object, deps);
|
|
23587
24102
|
if (expr.computed && expr.property.kind !== "Literal") {
|
|
23588
24103
|
collectExpressionDependencies(expr.property, deps);
|
|
@@ -23767,9 +24282,9 @@ function replaceIdentifiersWithOverrides(node, overrides, t4, parentKind, parent
|
|
|
23767
24282
|
if (!skipCurrentNode && (t4.isMemberExpression(node) || t4.isOptionalMemberExpression(node))) {
|
|
23768
24283
|
const propertyNode = node.property;
|
|
23769
24284
|
const isDynamicComputed = (node.computed ?? false) && !t4.isStringLiteral(propertyNode) && !t4.isNumericLiteral(propertyNode);
|
|
23770
|
-
const
|
|
23771
|
-
const normalized =
|
|
23772
|
-
const override = normalized && overrides[normalized] || (
|
|
24285
|
+
const path2 = getDependencyPathFromNode(node, t4);
|
|
24286
|
+
const normalized = path2 ? normalizeDependencyKey2(path2) : null;
|
|
24287
|
+
const override = normalized && overrides[normalized] || (path2 ? overrides[path2] : void 0);
|
|
23773
24288
|
if (override && !isCallTarget && !isDynamicComputed) {
|
|
23774
24289
|
const replacement = override();
|
|
23775
24290
|
Object.assign(node, replacement);
|
|
@@ -24500,11 +25015,11 @@ function lowerIntrinsicElement(jsx, ctx) {
|
|
|
24500
25015
|
}
|
|
24501
25016
|
return t4.callExpression(t4.arrowFunctionExpression([], body), []);
|
|
24502
25017
|
}
|
|
24503
|
-
function resolveHIRBindingPath(
|
|
24504
|
-
const key =
|
|
25018
|
+
function resolveHIRBindingPath(path2, cache, statements, ctx) {
|
|
25019
|
+
const key = path2.join(",");
|
|
24505
25020
|
if (cache.has(key)) return cache.get(key);
|
|
24506
25021
|
const { t: t4 } = ctx;
|
|
24507
|
-
const ancestorPath = [...
|
|
25022
|
+
const ancestorPath = [...path2];
|
|
24508
25023
|
let ancestorId;
|
|
24509
25024
|
let relativePath = [];
|
|
24510
25025
|
while (ancestorPath.length > 0) {
|
|
@@ -24512,13 +25027,13 @@ function resolveHIRBindingPath(path, cache, statements, ctx) {
|
|
|
24512
25027
|
const ancestorKey = ancestorPath.join(",");
|
|
24513
25028
|
if (cache.has(ancestorKey)) {
|
|
24514
25029
|
ancestorId = cache.get(ancestorKey);
|
|
24515
|
-
relativePath =
|
|
25030
|
+
relativePath = path2.slice(ancestorPath.length);
|
|
24516
25031
|
break;
|
|
24517
25032
|
}
|
|
24518
25033
|
}
|
|
24519
25034
|
if (!ancestorId) {
|
|
24520
25035
|
ancestorId = cache.get("");
|
|
24521
|
-
relativePath =
|
|
25036
|
+
relativePath = path2;
|
|
24522
25037
|
}
|
|
24523
25038
|
let currentExpr = ancestorId;
|
|
24524
25039
|
for (const index of relativePath) {
|
|
@@ -25327,6 +25842,7 @@ function lowerHIRWithRegions(program, t4, options, macroAliases) {
|
|
|
25327
25842
|
const originalBody = program.originalBody ?? [];
|
|
25328
25843
|
ctx.moduleDeclaredNames = collectDeclaredNames(originalBody, t4);
|
|
25329
25844
|
ctx.moduleRuntimeNames = collectRuntimeImportNames(originalBody, t4);
|
|
25845
|
+
applyImportedReactiveMetadata(originalBody, ctx, t4, options);
|
|
25330
25846
|
const stateMacroNames = /* @__PURE__ */ new Set(["$state", ...macroAliases?.state ?? []]);
|
|
25331
25847
|
const memoMacroNames = new Set(macroAliases?.memo ?? ctx.memoMacroNames ?? []);
|
|
25332
25848
|
if (!memoMacroNames.has("$memo")) memoMacroNames.add("$memo");
|
|
@@ -25566,6 +26082,15 @@ function lowerHIRWithRegions(program, t4, options, macroAliases) {
|
|
|
25566
26082
|
ctx.helpersUsed.add("popContext");
|
|
25567
26083
|
body.push(t4.expressionStatement(t4.callExpression(t4.identifier(RUNTIME_ALIASES.popContext), [])));
|
|
25568
26084
|
}
|
|
26085
|
+
const moduleMeta = buildModuleReactiveMetadata(
|
|
26086
|
+
originalBody,
|
|
26087
|
+
ctx,
|
|
26088
|
+
t4,
|
|
26089
|
+
options,
|
|
26090
|
+
stateMacroNames,
|
|
26091
|
+
memoMacroNames
|
|
26092
|
+
);
|
|
26093
|
+
setModuleMetadata(options?.filename, moduleMeta, options);
|
|
25569
26094
|
return t4.file(t4.program(attachHelperImports(ctx, body, t4)));
|
|
25570
26095
|
}
|
|
25571
26096
|
function lowerTopLevelStatementBlock(statements, ctx, t4, name = "__module_segment", existingAliases) {
|
|
@@ -26046,7 +26571,7 @@ function lowerFunctionWithRegions(fn, ctx) {
|
|
|
26046
26571
|
if (!hasComplexControlFlow && !isAsync) {
|
|
26047
26572
|
const pureDeclaredVars = /* @__PURE__ */ new Set();
|
|
26048
26573
|
const pureStatements = lowerStructuredNodeWithoutRegions(structured, t4, ctx, pureDeclaredVars);
|
|
26049
|
-
const params2 = fn
|
|
26574
|
+
const params2 = buildOutputParams(fn, t4);
|
|
26050
26575
|
const funcDecl2 = setNodeLoc(
|
|
26051
26576
|
t4.functionDeclaration(
|
|
26052
26577
|
t4.identifier(fn.name ?? "fn"),
|
|
@@ -26121,13 +26646,31 @@ function lowerFunctionWithRegions(fn, ctx) {
|
|
|
26121
26646
|
)
|
|
26122
26647
|
);
|
|
26123
26648
|
}
|
|
26124
|
-
let finalParams = fn
|
|
26649
|
+
let finalParams = buildOutputParams(fn, t4);
|
|
26125
26650
|
const propsDestructuring = [];
|
|
26126
26651
|
if (isComponent && fn.rawParams && fn.rawParams.length === 1) {
|
|
26127
26652
|
const rawParam = fn.rawParams[0];
|
|
26128
26653
|
if (rawParam && (rawParam.type === "ObjectPattern" || rawParam.type === "AssignmentPattern" && rawParam.left?.type === "ObjectPattern")) {
|
|
26129
|
-
finalParams = [t4.identifier("__props")];
|
|
26130
26654
|
const pattern = rawParam.type === "AssignmentPattern" ? rawParam.left : rawParam;
|
|
26655
|
+
const defaultExpr = rawParam.type === "AssignmentPattern" ? rawParam.right : null;
|
|
26656
|
+
if (defaultExpr) {
|
|
26657
|
+
const propsParamName = "__propsParam";
|
|
26658
|
+
finalParams = [t4.identifier(propsParamName)];
|
|
26659
|
+
propsDestructuring.push(
|
|
26660
|
+
t4.variableDeclaration("const", [
|
|
26661
|
+
t4.variableDeclarator(
|
|
26662
|
+
t4.identifier("__props"),
|
|
26663
|
+
t4.conditionalExpression(
|
|
26664
|
+
t4.binaryExpression("===", t4.identifier(propsParamName), t4.identifier("undefined")),
|
|
26665
|
+
t4.cloneNode(defaultExpr, true),
|
|
26666
|
+
t4.identifier(propsParamName)
|
|
26667
|
+
)
|
|
26668
|
+
)
|
|
26669
|
+
])
|
|
26670
|
+
);
|
|
26671
|
+
} else {
|
|
26672
|
+
finalParams = [t4.identifier("__props")];
|
|
26673
|
+
}
|
|
26131
26674
|
if (propsDestructurePlan) {
|
|
26132
26675
|
if (propsDestructurePlan.usesProp) {
|
|
26133
26676
|
ctx.helpersUsed.add("prop");
|
|
@@ -26285,7 +26828,7 @@ function optimizeHIR(program, options = {}) {
|
|
|
26285
26828
|
originalBody: []
|
|
26286
26829
|
});
|
|
26287
26830
|
const ssaFn = ssaProgram.functions[0];
|
|
26288
|
-
return ssaFn ? optimizeSSAFunction(ssaFn) : fn;
|
|
26831
|
+
return ssaFn ? optimizeSSAFunction(ssaFn, options) : fn;
|
|
26289
26832
|
}
|
|
26290
26833
|
if (isReactiveOptimizationCandidate(fn)) {
|
|
26291
26834
|
return optimizeReactiveFunction(fn, exportedNames, options);
|
|
@@ -26297,9 +26840,9 @@ function optimizeHIR(program, options = {}) {
|
|
|
26297
26840
|
functions
|
|
26298
26841
|
};
|
|
26299
26842
|
}
|
|
26300
|
-
function optimizeSSAFunction(fn) {
|
|
26843
|
+
function optimizeSSAFunction(fn, options) {
|
|
26301
26844
|
let current = fn;
|
|
26302
|
-
current = propagateConstants(current);
|
|
26845
|
+
current = propagateConstants(current, options);
|
|
26303
26846
|
const purity = buildPurityContext(current);
|
|
26304
26847
|
current = eliminateCommonSubexpressions(current, purity);
|
|
26305
26848
|
current = inlineSingleUse(current, purity);
|
|
@@ -26924,7 +27467,9 @@ function optimizeReactiveFunction(fn, exportedNames, options) {
|
|
|
26924
27467
|
const reactive = buildReactiveContext(fn);
|
|
26925
27468
|
const purity = buildPurityContext(fn);
|
|
26926
27469
|
const hookLike = isHookLikeFunction(fn);
|
|
26927
|
-
const transformedBlocks = fn.blocks.map(
|
|
27470
|
+
const transformedBlocks = fn.blocks.map(
|
|
27471
|
+
(block) => optimizeReactiveBlock(block, reactive, purity, options)
|
|
27472
|
+
);
|
|
26928
27473
|
let transformed = { ...fn, blocks: transformedBlocks };
|
|
26929
27474
|
if (isCrossBlockConstPropagationEnabled()) {
|
|
26930
27475
|
transformed = propagateCrossBlockConstants(transformed, reactive, purity, scopeResult);
|
|
@@ -26959,7 +27504,7 @@ function optimizeReactiveFunction(fn, exportedNames, options) {
|
|
|
26959
27504
|
});
|
|
26960
27505
|
return { ...transformed, blocks };
|
|
26961
27506
|
}
|
|
26962
|
-
function optimizeReactiveBlock(block, reactive, purity) {
|
|
27507
|
+
function optimizeReactiveBlock(block, reactive, purity, options) {
|
|
26963
27508
|
const constants = /* @__PURE__ */ new Map();
|
|
26964
27509
|
const constObjects = /* @__PURE__ */ new Map();
|
|
26965
27510
|
const constArrays = /* @__PURE__ */ new Map();
|
|
@@ -26997,7 +27542,7 @@ function optimizeReactiveBlock(block, reactive, purity) {
|
|
|
26997
27542
|
constArrays.delete(name);
|
|
26998
27543
|
}
|
|
26999
27544
|
const dependsOnReactiveValue = expressionDependsOnReactive(instr.value, reactive);
|
|
27000
|
-
let value = dependsOnReactiveValue ? instr.value : foldExpressionWithConstants(instr.value, constants, constObjects, constArrays);
|
|
27545
|
+
let value = dependsOnReactiveValue ? instr.value : foldExpressionWithConstants(instr.value, constants, options, constObjects, constArrays);
|
|
27001
27546
|
const allowCSE = isCompilerGeneratedName(target) && (!declKind || declKind === "const");
|
|
27002
27547
|
if (allowCSE && isPureExpression(value, purity) && !isExplicitMemoCall(value, purity) && !dependsOnReactiveValue && isCSESafeExpression(value, purity)) {
|
|
27003
27548
|
const deps = collectExpressionIdentifiers2(value, true);
|
|
@@ -27045,7 +27590,7 @@ function optimizeReactiveBlock(block, reactive, purity) {
|
|
|
27045
27590
|
constArrays.delete(name);
|
|
27046
27591
|
}
|
|
27047
27592
|
const dependsOnReactiveValue = expressionDependsOnReactive(instr.value, reactive);
|
|
27048
|
-
const value = dependsOnReactiveValue ? instr.value : foldExpressionWithConstants(instr.value, constants, constObjects, constArrays);
|
|
27593
|
+
const value = dependsOnReactiveValue ? instr.value : foldExpressionWithConstants(instr.value, constants, options, constObjects, constArrays);
|
|
27049
27594
|
instructions.push(value === instr.value ? instr : { ...instr, value });
|
|
27050
27595
|
continue;
|
|
27051
27596
|
}
|
|
@@ -27054,6 +27599,7 @@ function optimizeReactiveBlock(block, reactive, purity) {
|
|
|
27054
27599
|
const terminator = foldTerminatorWithConstants(
|
|
27055
27600
|
block.terminator,
|
|
27056
27601
|
constants,
|
|
27602
|
+
options,
|
|
27057
27603
|
reactive,
|
|
27058
27604
|
constObjects,
|
|
27059
27605
|
constArrays
|
|
@@ -27985,7 +28531,7 @@ function blocksContainImpureMarkers(blocks) {
|
|
|
27985
28531
|
}
|
|
27986
28532
|
return false;
|
|
27987
28533
|
}
|
|
27988
|
-
function propagateConstants(fn) {
|
|
28534
|
+
function propagateConstants(fn, options) {
|
|
27989
28535
|
const constants = computeConstantMap(fn);
|
|
27990
28536
|
if (constants.size === 0) return fn;
|
|
27991
28537
|
const blocks = fn.blocks.map((block) => ({
|
|
@@ -27993,12 +28539,12 @@ function propagateConstants(fn) {
|
|
|
27993
28539
|
instructions: block.instructions.map((instr) => {
|
|
27994
28540
|
if (instr.kind === "Assign") {
|
|
27995
28541
|
const replaced = replaceIdentifiersWithConstants(instr.value, constants);
|
|
27996
|
-
const folded = foldExpression(replaced, constants);
|
|
28542
|
+
const folded = foldExpression(replaced, constants, options);
|
|
27997
28543
|
return { ...instr, value: folded };
|
|
27998
28544
|
}
|
|
27999
28545
|
if (instr.kind === "Expression") {
|
|
28000
28546
|
const replaced = replaceIdentifiersWithConstants(instr.value, constants);
|
|
28001
|
-
const folded = foldExpression(replaced, constants);
|
|
28547
|
+
const folded = foldExpression(replaced, constants, options);
|
|
28002
28548
|
return { ...instr, value: folded };
|
|
28003
28549
|
}
|
|
28004
28550
|
if (instr.kind === "Phi") {
|
|
@@ -28398,15 +28944,18 @@ function evaluateBinary(operator, left, right) {
|
|
|
28398
28944
|
return UNKNOWN_CONST;
|
|
28399
28945
|
}
|
|
28400
28946
|
}
|
|
28401
|
-
function foldExpression(expr, constants) {
|
|
28947
|
+
function foldExpression(expr, constants, options) {
|
|
28402
28948
|
const value = evaluateConstant(expr, constants);
|
|
28403
28949
|
if (value === UNKNOWN_CONST) {
|
|
28404
|
-
return simplifyAlgebraically(expr, constants);
|
|
28950
|
+
return simplifyAlgebraically(expr, constants, options);
|
|
28405
28951
|
}
|
|
28406
28952
|
return { kind: "Literal", value, loc: expr.loc };
|
|
28407
28953
|
}
|
|
28408
|
-
function simplifyAlgebraically(expr, constants) {
|
|
28409
|
-
const simplified = simplifyChildren(expr, constants);
|
|
28954
|
+
function simplifyAlgebraically(expr, constants, options) {
|
|
28955
|
+
const simplified = simplifyChildren(expr, constants, options);
|
|
28956
|
+
if (options.optimizeLevel === "safe") {
|
|
28957
|
+
return simplified;
|
|
28958
|
+
}
|
|
28410
28959
|
if (simplified.kind === "BinaryExpression") {
|
|
28411
28960
|
const { operator, left, right, loc } = simplified;
|
|
28412
28961
|
switch (operator) {
|
|
@@ -28485,37 +29034,37 @@ function simplifyAlgebraically(expr, constants) {
|
|
|
28485
29034
|
}
|
|
28486
29035
|
return simplified;
|
|
28487
29036
|
}
|
|
28488
|
-
function simplifyChildren(expr, constants) {
|
|
29037
|
+
function simplifyChildren(expr, constants, options) {
|
|
28489
29038
|
switch (expr.kind) {
|
|
28490
29039
|
case "BinaryExpression":
|
|
28491
29040
|
return {
|
|
28492
29041
|
...expr,
|
|
28493
|
-
left: simplifyAlgebraically(expr.left, constants),
|
|
28494
|
-
right: simplifyAlgebraically(expr.right, constants)
|
|
29042
|
+
left: simplifyAlgebraically(expr.left, constants, options),
|
|
29043
|
+
right: simplifyAlgebraically(expr.right, constants, options)
|
|
28495
29044
|
};
|
|
28496
29045
|
case "LogicalExpression":
|
|
28497
29046
|
return {
|
|
28498
29047
|
...expr,
|
|
28499
|
-
left: simplifyAlgebraically(expr.left, constants),
|
|
28500
|
-
right: simplifyAlgebraically(expr.right, constants)
|
|
29048
|
+
left: simplifyAlgebraically(expr.left, constants, options),
|
|
29049
|
+
right: simplifyAlgebraically(expr.right, constants, options)
|
|
28501
29050
|
};
|
|
28502
29051
|
case "UnaryExpression":
|
|
28503
29052
|
return {
|
|
28504
29053
|
...expr,
|
|
28505
|
-
argument: simplifyAlgebraically(expr.argument, constants)
|
|
29054
|
+
argument: simplifyAlgebraically(expr.argument, constants, options)
|
|
28506
29055
|
};
|
|
28507
29056
|
case "ConditionalExpression":
|
|
28508
29057
|
return {
|
|
28509
29058
|
...expr,
|
|
28510
|
-
test: simplifyAlgebraically(expr.test, constants),
|
|
28511
|
-
consequent: simplifyAlgebraically(expr.consequent, constants),
|
|
28512
|
-
alternate: simplifyAlgebraically(expr.alternate, constants)
|
|
29059
|
+
test: simplifyAlgebraically(expr.test, constants, options),
|
|
29060
|
+
consequent: simplifyAlgebraically(expr.consequent, constants, options),
|
|
29061
|
+
alternate: simplifyAlgebraically(expr.alternate, constants, options)
|
|
28513
29062
|
};
|
|
28514
29063
|
case "ArrayExpression":
|
|
28515
29064
|
return {
|
|
28516
29065
|
...expr,
|
|
28517
29066
|
elements: expr.elements.map(
|
|
28518
|
-
(el) => el ? simplifyAlgebraically(el, constants) : el
|
|
29067
|
+
(el) => el ? simplifyAlgebraically(el, constants, options) : el
|
|
28519
29068
|
)
|
|
28520
29069
|
};
|
|
28521
29070
|
case "ObjectExpression":
|
|
@@ -28525,13 +29074,13 @@ function simplifyChildren(expr, constants) {
|
|
|
28525
29074
|
if (prop.kind === "Property") {
|
|
28526
29075
|
return {
|
|
28527
29076
|
...prop,
|
|
28528
|
-
value: simplifyAlgebraically(prop.value, constants)
|
|
29077
|
+
value: simplifyAlgebraically(prop.value, constants, options)
|
|
28529
29078
|
};
|
|
28530
29079
|
}
|
|
28531
29080
|
if (prop.kind === "SpreadElement") {
|
|
28532
29081
|
return {
|
|
28533
29082
|
...prop,
|
|
28534
|
-
argument: simplifyAlgebraically(prop.argument, constants)
|
|
29083
|
+
argument: simplifyAlgebraically(prop.argument, constants, options)
|
|
28535
29084
|
};
|
|
28536
29085
|
}
|
|
28537
29086
|
return prop;
|
|
@@ -28541,35 +29090,35 @@ function simplifyChildren(expr, constants) {
|
|
|
28541
29090
|
case "OptionalCallExpression":
|
|
28542
29091
|
return {
|
|
28543
29092
|
...expr,
|
|
28544
|
-
arguments: expr.arguments.map((arg) => simplifyAlgebraically(arg, constants))
|
|
29093
|
+
arguments: expr.arguments.map((arg) => simplifyAlgebraically(arg, constants, options))
|
|
28545
29094
|
};
|
|
28546
29095
|
case "ImportExpression":
|
|
28547
29096
|
return {
|
|
28548
29097
|
...expr,
|
|
28549
|
-
source: simplifyAlgebraically(expr.source, constants)
|
|
29098
|
+
source: simplifyAlgebraically(expr.source, constants, options)
|
|
28550
29099
|
};
|
|
28551
29100
|
case "MemberExpression":
|
|
28552
29101
|
case "OptionalMemberExpression":
|
|
28553
29102
|
return {
|
|
28554
29103
|
...expr,
|
|
28555
|
-
object: simplifyAlgebraically(expr.object, constants),
|
|
28556
|
-
property: expr.computed ? simplifyAlgebraically(expr.property, constants) : expr.property
|
|
29104
|
+
object: simplifyAlgebraically(expr.object, constants, options),
|
|
29105
|
+
property: expr.computed ? simplifyAlgebraically(expr.property, constants, options) : expr.property
|
|
28557
29106
|
};
|
|
28558
29107
|
default:
|
|
28559
29108
|
return expr;
|
|
28560
29109
|
}
|
|
28561
29110
|
}
|
|
28562
|
-
function foldExpressionWithConstants(expr, constants, constObjects, constArrays) {
|
|
29111
|
+
function foldExpressionWithConstants(expr, constants, options, constObjects, constArrays) {
|
|
28563
29112
|
const replaced = replaceIdentifiersWithConstants(expr, constants);
|
|
28564
29113
|
if (!constObjects && !constArrays) {
|
|
28565
|
-
return foldExpression(replaced, constants);
|
|
29114
|
+
return foldExpression(replaced, constants, options);
|
|
28566
29115
|
}
|
|
28567
29116
|
const memberReplaced = replaceConstMemberExpressions(
|
|
28568
29117
|
replaced,
|
|
28569
29118
|
constObjects ?? /* @__PURE__ */ new Map(),
|
|
28570
29119
|
constArrays ?? /* @__PURE__ */ new Map()
|
|
28571
29120
|
);
|
|
28572
|
-
return foldExpression(memberReplaced, constants);
|
|
29121
|
+
return foldExpression(memberReplaced, constants, options);
|
|
28573
29122
|
}
|
|
28574
29123
|
function replaceIdentifiersWithConstants(expr, constants, context = {}) {
|
|
28575
29124
|
switch (expr.kind) {
|
|
@@ -28731,10 +29280,10 @@ function replaceConstantsInTerminator(term, constants) {
|
|
|
28731
29280
|
return term;
|
|
28732
29281
|
}
|
|
28733
29282
|
}
|
|
28734
|
-
function foldTerminatorWithConstants(term, constants, reactive, constObjects, constArrays) {
|
|
29283
|
+
function foldTerminatorWithConstants(term, constants, options, reactive, constObjects, constArrays) {
|
|
28735
29284
|
const fold = (expr) => {
|
|
28736
29285
|
if (reactive && expressionDependsOnReactive(expr, reactive)) return expr;
|
|
28737
|
-
return foldExpressionWithConstants(expr, constants, constObjects, constArrays);
|
|
29286
|
+
return foldExpressionWithConstants(expr, constants, options, constObjects, constArrays);
|
|
28738
29287
|
};
|
|
28739
29288
|
switch (term.kind) {
|
|
28740
29289
|
case "Return":
|
|
@@ -28851,11 +29400,14 @@ function hasSideEffectsBetween(instructions, start, end, purity) {
|
|
|
28851
29400
|
function eliminateDeadCode(fn, purity) {
|
|
28852
29401
|
const depsByVar = buildDependencyGraph(fn);
|
|
28853
29402
|
const live = computeLiveVariables(fn, depsByVar, purity);
|
|
29403
|
+
const baseLive = /* @__PURE__ */ new Set();
|
|
29404
|
+
live.forEach((name) => baseLive.add(getSSABaseName(name)));
|
|
28854
29405
|
const blocks = fn.blocks.map((block) => {
|
|
28855
29406
|
const instructions = block.instructions.filter((instr) => {
|
|
28856
29407
|
if (instr.kind === "Assign") {
|
|
28857
29408
|
const name = instr.target.name;
|
|
28858
29409
|
if (live.has(name)) return true;
|
|
29410
|
+
if (instr.declarationKind && baseLive.has(getSSABaseName(name))) return true;
|
|
28859
29411
|
return !isPureExpression(instr.value, purity) || isExplicitMemoCall(instr.value, purity);
|
|
28860
29412
|
}
|
|
28861
29413
|
if (instr.kind === "Phi") {
|
|
@@ -29867,8 +30419,8 @@ function getRootIdentifier(expr, t4) {
|
|
|
29867
30419
|
}
|
|
29868
30420
|
|
|
29869
30421
|
// src/index.ts
|
|
29870
|
-
function stripMacroImports(
|
|
29871
|
-
|
|
30422
|
+
function stripMacroImports(path2, t4) {
|
|
30423
|
+
path2.traverse({
|
|
29872
30424
|
ImportDeclaration(importPath) {
|
|
29873
30425
|
if (importPath.node.source.value !== "fict" && importPath.node.source.value !== "fict/slim")
|
|
29874
30426
|
return;
|
|
@@ -29886,19 +30438,19 @@ function stripMacroImports(path, t4) {
|
|
|
29886
30438
|
}
|
|
29887
30439
|
});
|
|
29888
30440
|
}
|
|
29889
|
-
function isInsideLoop(
|
|
29890
|
-
return !!
|
|
30441
|
+
function isInsideLoop(path2) {
|
|
30442
|
+
return !!path2.findParent(
|
|
29891
30443
|
(p) => p.isForStatement?.() || p.isWhileStatement?.() || p.isDoWhileStatement?.() || p.isForInStatement?.() || p.isForOfStatement?.()
|
|
29892
30444
|
);
|
|
29893
30445
|
}
|
|
29894
|
-
function isInsideConditional(
|
|
29895
|
-
return !!
|
|
30446
|
+
function isInsideConditional(path2) {
|
|
30447
|
+
return !!path2.findParent(
|
|
29896
30448
|
(p) => p.isIfStatement?.() || p.isConditionalExpression?.() || p.isSwitchCase?.()
|
|
29897
30449
|
);
|
|
29898
30450
|
}
|
|
29899
|
-
function isInsideNestedFunction(
|
|
30451
|
+
function isInsideNestedFunction(path2) {
|
|
29900
30452
|
let depth = 0;
|
|
29901
|
-
let current =
|
|
30453
|
+
let current = path2;
|
|
29902
30454
|
while (current) {
|
|
29903
30455
|
if (current.isFunction?.()) {
|
|
29904
30456
|
depth++;
|
|
@@ -29908,8 +30460,8 @@ function isInsideNestedFunction(path) {
|
|
|
29908
30460
|
}
|
|
29909
30461
|
return false;
|
|
29910
30462
|
}
|
|
29911
|
-
function isInsideJSX(
|
|
29912
|
-
return !!
|
|
30463
|
+
function isInsideJSX(path2) {
|
|
30464
|
+
return !!path2.findParent((p) => p.isJSXElement?.() || p.isJSXFragment?.());
|
|
29913
30465
|
}
|
|
29914
30466
|
function parseSuppressionCodes(raw) {
|
|
29915
30467
|
if (!raw) return void 0;
|
|
@@ -29938,12 +30490,42 @@ function shouldSuppressWarning(suppressions, code, line) {
|
|
|
29938
30490
|
return entry.codes.has(code);
|
|
29939
30491
|
});
|
|
29940
30492
|
}
|
|
29941
|
-
function
|
|
29942
|
-
if (
|
|
30493
|
+
function hasErrorEscalation(options) {
|
|
30494
|
+
if (options.warningsAsErrors === true) return true;
|
|
30495
|
+
if (Array.isArray(options.warningsAsErrors) && options.warningsAsErrors.length > 0) return true;
|
|
30496
|
+
if (options.warningLevels) {
|
|
30497
|
+
return Object.values(options.warningLevels).some((level) => level === "error");
|
|
30498
|
+
}
|
|
30499
|
+
return false;
|
|
30500
|
+
}
|
|
30501
|
+
function resolveWarningLevel(code, options) {
|
|
30502
|
+
const override = options.warningLevels?.[code];
|
|
30503
|
+
if (override) return override;
|
|
30504
|
+
if (options.warningsAsErrors === true) return "error";
|
|
30505
|
+
if (Array.isArray(options.warningsAsErrors) && options.warningsAsErrors.includes(code)) {
|
|
30506
|
+
return "error";
|
|
30507
|
+
}
|
|
30508
|
+
return "warn";
|
|
30509
|
+
}
|
|
30510
|
+
function formatWarningAsError(warning) {
|
|
30511
|
+
const location = warning.line > 0 ? `${warning.fileName}:${warning.line}:${warning.column}` : warning.fileName;
|
|
30512
|
+
return `Fict warning treated as error (${warning.code}): ${warning.message}
|
|
30513
|
+
at ${location}`;
|
|
30514
|
+
}
|
|
30515
|
+
function createWarningDispatcher(onWarn, suppressions, options, dev) {
|
|
30516
|
+
const hasEscalation = hasErrorEscalation(options);
|
|
30517
|
+
if (!dev && !hasEscalation) return () => {
|
|
29943
30518
|
};
|
|
29944
30519
|
return (warning) => {
|
|
29945
30520
|
if (shouldSuppressWarning(suppressions, warning.code, warning.line)) return;
|
|
29946
|
-
|
|
30521
|
+
const level = resolveWarningLevel(warning.code, options);
|
|
30522
|
+
if (level === "off") return;
|
|
30523
|
+
if (level === "error") {
|
|
30524
|
+
throw new Error(formatWarningAsError(warning));
|
|
30525
|
+
}
|
|
30526
|
+
if (dev && onWarn) {
|
|
30527
|
+
onWarn(warning);
|
|
30528
|
+
}
|
|
29947
30529
|
};
|
|
29948
30530
|
}
|
|
29949
30531
|
function emitWarning(node, code, message, warn, fileName) {
|
|
@@ -30043,13 +30625,13 @@ function runWarningPass(programPath, stateVars, derivedVars, warn, fileName, t4)
|
|
|
30043
30625
|
};
|
|
30044
30626
|
const reactiveNames = /* @__PURE__ */ new Set([...stateVars, ...derivedVars]);
|
|
30045
30627
|
programPath.traverse({
|
|
30046
|
-
AssignmentExpression(
|
|
30047
|
-
const { left } =
|
|
30628
|
+
AssignmentExpression(path2) {
|
|
30629
|
+
const { left } = path2.node;
|
|
30048
30630
|
if (t4.isIdentifier(left)) return;
|
|
30049
30631
|
if (t4.isMemberExpression(left) || t4.isOptionalMemberExpression(left)) {
|
|
30050
30632
|
if (isStateRoot(left.object)) {
|
|
30051
30633
|
emitWarning(
|
|
30052
|
-
|
|
30634
|
+
path2.node,
|
|
30053
30635
|
"FICT-M",
|
|
30054
30636
|
"Direct mutation of nested property detected; use immutable update or $store helpers",
|
|
30055
30637
|
warn,
|
|
@@ -30057,7 +30639,7 @@ function runWarningPass(programPath, stateVars, derivedVars, warn, fileName, t4)
|
|
|
30057
30639
|
);
|
|
30058
30640
|
if (isDynamicPropertyAccess(left, t4)) {
|
|
30059
30641
|
emitWarning(
|
|
30060
|
-
|
|
30642
|
+
path2.node,
|
|
30061
30643
|
"FICT-H",
|
|
30062
30644
|
"Dynamic property access widens dependency tracking",
|
|
30063
30645
|
warn,
|
|
@@ -30067,12 +30649,12 @@ function runWarningPass(programPath, stateVars, derivedVars, warn, fileName, t4)
|
|
|
30067
30649
|
}
|
|
30068
30650
|
}
|
|
30069
30651
|
},
|
|
30070
|
-
UpdateExpression(
|
|
30071
|
-
const arg =
|
|
30652
|
+
UpdateExpression(path2) {
|
|
30653
|
+
const arg = path2.node.argument;
|
|
30072
30654
|
if (t4.isMemberExpression(arg) || t4.isOptionalMemberExpression(arg)) {
|
|
30073
30655
|
if (isStateRoot(arg.object)) {
|
|
30074
30656
|
emitWarning(
|
|
30075
|
-
|
|
30657
|
+
path2.node,
|
|
30076
30658
|
"FICT-M",
|
|
30077
30659
|
"Direct mutation of nested property detected; use immutable update or $store helpers",
|
|
30078
30660
|
warn,
|
|
@@ -30080,7 +30662,7 @@ function runWarningPass(programPath, stateVars, derivedVars, warn, fileName, t4)
|
|
|
30080
30662
|
);
|
|
30081
30663
|
if (isDynamicPropertyAccess(arg, t4)) {
|
|
30082
30664
|
emitWarning(
|
|
30083
|
-
|
|
30665
|
+
path2.node,
|
|
30084
30666
|
"FICT-H",
|
|
30085
30667
|
"Dynamic property access widens dependency tracking",
|
|
30086
30668
|
warn,
|
|
@@ -30090,13 +30672,13 @@ function runWarningPass(programPath, stateVars, derivedVars, warn, fileName, t4)
|
|
|
30090
30672
|
}
|
|
30091
30673
|
}
|
|
30092
30674
|
},
|
|
30093
|
-
MemberExpression(
|
|
30094
|
-
if (!
|
|
30095
|
-
if (
|
|
30096
|
-
if (
|
|
30097
|
-
if (isDynamicPropertyAccess(
|
|
30675
|
+
MemberExpression(path2) {
|
|
30676
|
+
if (!path2.node.computed) return;
|
|
30677
|
+
if (path2.parentPath.isAssignmentExpression({ left: path2.node })) return;
|
|
30678
|
+
if (path2.parentPath.isUpdateExpression({ argument: path2.node })) return;
|
|
30679
|
+
if (isDynamicPropertyAccess(path2.node, t4) && isStateRoot(path2.node.object)) {
|
|
30098
30680
|
emitWarning(
|
|
30099
|
-
|
|
30681
|
+
path2.node,
|
|
30100
30682
|
"FICT-H",
|
|
30101
30683
|
"Dynamic property access widens dependency tracking",
|
|
30102
30684
|
warn,
|
|
@@ -30104,12 +30686,12 @@ function runWarningPass(programPath, stateVars, derivedVars, warn, fileName, t4)
|
|
|
30104
30686
|
);
|
|
30105
30687
|
}
|
|
30106
30688
|
},
|
|
30107
|
-
Function(
|
|
30689
|
+
Function(path2) {
|
|
30108
30690
|
const captured = /* @__PURE__ */ new Set();
|
|
30109
|
-
|
|
30691
|
+
path2.traverse(
|
|
30110
30692
|
{
|
|
30111
30693
|
Function(inner) {
|
|
30112
|
-
if (inner ===
|
|
30694
|
+
if (inner === path2) return;
|
|
30113
30695
|
inner.skip();
|
|
30114
30696
|
},
|
|
30115
30697
|
Identifier(idPath) {
|
|
@@ -30117,7 +30699,7 @@ function runWarningPass(programPath, stateVars, derivedVars, warn, fileName, t4)
|
|
|
30117
30699
|
if (!reactiveNames.has(name)) return;
|
|
30118
30700
|
const binding = idPath.scope.getBinding(name);
|
|
30119
30701
|
if (!binding) return;
|
|
30120
|
-
if (binding.scope === idPath.scope || binding.scope ===
|
|
30702
|
+
if (binding.scope === idPath.scope || binding.scope === path2.scope) return;
|
|
30121
30703
|
captured.add(name);
|
|
30122
30704
|
}
|
|
30123
30705
|
},
|
|
@@ -30125,7 +30707,7 @@ function runWarningPass(programPath, stateVars, derivedVars, warn, fileName, t4)
|
|
|
30125
30707
|
);
|
|
30126
30708
|
if (captured.size > 0) {
|
|
30127
30709
|
emitWarning(
|
|
30128
|
-
|
|
30710
|
+
path2.node,
|
|
30129
30711
|
"FICT-R005",
|
|
30130
30712
|
`Function captures reactive variable(s): ${Array.from(captured).join(", ")}. Pass them as parameters or memoize explicitly to avoid hidden dependencies.`,
|
|
30131
30713
|
warn,
|
|
@@ -30133,9 +30715,9 @@ function runWarningPass(programPath, stateVars, derivedVars, warn, fileName, t4)
|
|
|
30133
30715
|
);
|
|
30134
30716
|
}
|
|
30135
30717
|
},
|
|
30136
|
-
CallExpression(
|
|
30137
|
-
if (t4.isIdentifier(
|
|
30138
|
-
const argPath =
|
|
30718
|
+
CallExpression(path2) {
|
|
30719
|
+
if (t4.isIdentifier(path2.node.callee, { name: "$effect" })) {
|
|
30720
|
+
const argPath = path2.get("arguments.0");
|
|
30139
30721
|
if (argPath?.isFunctionExpression() || argPath?.isArrowFunctionExpression()) {
|
|
30140
30722
|
let hasReactiveDependency = false;
|
|
30141
30723
|
argPath.traverse({
|
|
@@ -30156,7 +30738,7 @@ function runWarningPass(programPath, stateVars, derivedVars, warn, fileName, t4)
|
|
|
30156
30738
|
});
|
|
30157
30739
|
if (!hasReactiveDependency) {
|
|
30158
30740
|
emitWarning(
|
|
30159
|
-
|
|
30741
|
+
path2.node,
|
|
30160
30742
|
"FICT-E001",
|
|
30161
30743
|
"Effect has no reactive reads; it will run once. Consider removing $effect or adding dependencies.",
|
|
30162
30744
|
warn,
|
|
@@ -30166,7 +30748,7 @@ function runWarningPass(programPath, stateVars, derivedVars, warn, fileName, t4)
|
|
|
30166
30748
|
}
|
|
30167
30749
|
return;
|
|
30168
30750
|
}
|
|
30169
|
-
const callee =
|
|
30751
|
+
const callee = path2.node.callee;
|
|
30170
30752
|
let calleeName = "";
|
|
30171
30753
|
if (t4.isIdentifier(callee)) {
|
|
30172
30754
|
calleeName = callee.name;
|
|
@@ -30178,7 +30760,7 @@ function runWarningPass(programPath, stateVars, derivedVars, warn, fileName, t4)
|
|
|
30178
30760
|
}
|
|
30179
30761
|
const isSafe = calleeName && SAFE_FUNCTIONS.has(calleeName);
|
|
30180
30762
|
if (isSafe) return;
|
|
30181
|
-
for (const arg of
|
|
30763
|
+
for (const arg of path2.node.arguments) {
|
|
30182
30764
|
if (!t4.isExpression(arg)) continue;
|
|
30183
30765
|
if (isStateRoot(arg)) {
|
|
30184
30766
|
emitWarning(
|
|
@@ -30192,13 +30774,13 @@ function runWarningPass(programPath, stateVars, derivedVars, warn, fileName, t4)
|
|
|
30192
30774
|
}
|
|
30193
30775
|
}
|
|
30194
30776
|
},
|
|
30195
|
-
OptionalMemberExpression(
|
|
30196
|
-
if (!
|
|
30197
|
-
if (
|
|
30198
|
-
if (
|
|
30199
|
-
if (isDynamicPropertyAccess(
|
|
30777
|
+
OptionalMemberExpression(path2) {
|
|
30778
|
+
if (!path2.node.computed) return;
|
|
30779
|
+
if (path2.parentPath.isAssignmentExpression({ left: path2.node })) return;
|
|
30780
|
+
if (path2.parentPath.isUpdateExpression({ argument: path2.node })) return;
|
|
30781
|
+
if (isDynamicPropertyAccess(path2.node, t4) && isStateRoot(path2.node.object)) {
|
|
30200
30782
|
emitWarning(
|
|
30201
|
-
|
|
30783
|
+
path2.node,
|
|
30202
30784
|
"FICT-H",
|
|
30203
30785
|
"Dynamic property access widens dependency tracking",
|
|
30204
30786
|
warn,
|
|
@@ -30249,14 +30831,17 @@ function createHIREntrypointVisitor(t4, options) {
|
|
|
30249
30831
|
};
|
|
30250
30832
|
return {
|
|
30251
30833
|
Program: {
|
|
30252
|
-
exit(
|
|
30253
|
-
const fileName =
|
|
30254
|
-
const comments =
|
|
30834
|
+
exit(path2) {
|
|
30835
|
+
const fileName = path2.hub?.file?.opts?.filename || "<unknown>";
|
|
30836
|
+
const comments = path2.hub?.file?.ast?.comments || [];
|
|
30255
30837
|
const suppressions = parseSuppressions(comments);
|
|
30256
30838
|
const dev = options.dev !== false;
|
|
30257
|
-
const warn =
|
|
30839
|
+
const warn = createWarningDispatcher(options.onWarn, suppressions, options, dev);
|
|
30840
|
+
const optionsWithWarnings = {
|
|
30841
|
+
...options,
|
|
30842
|
+
onWarn: warn,
|
|
30843
|
+
filename: fileName
|
|
30258
30844
|
};
|
|
30259
|
-
const optionsWithWarnings = dev ? { ...options, onWarn: warn } : { ...options, onWarn: void 0 };
|
|
30260
30845
|
const isHookName2 = (name) => !!name && /^use[A-Z]/.test(name);
|
|
30261
30846
|
const getFunctionName = (fnPath) => {
|
|
30262
30847
|
return fnPath.isFunctionDeclaration() && fnPath.node.id ? fnPath.node.id.name : fnPath.isFunctionExpression() && fnPath.node.id ? fnPath.node.id.name : fnPath.parentPath.isVariableDeclarator() && t4.isIdentifier(fnPath.parentPath.node.id) && fnPath.parentPath.node.init === fnPath.node ? fnPath.parentPath.node.id.name : void 0;
|
|
@@ -30357,7 +30942,7 @@ function createHIREntrypointVisitor(t4, options) {
|
|
|
30357
30942
|
};
|
|
30358
30943
|
return checkNode(fn.body);
|
|
30359
30944
|
};
|
|
30360
|
-
|
|
30945
|
+
path2.traverse({
|
|
30361
30946
|
FunctionDeclaration(fnPath) {
|
|
30362
30947
|
const name = fnPath.node.id?.name;
|
|
30363
30948
|
if (!isComponentName2(name)) return;
|
|
@@ -30394,7 +30979,7 @@ function createHIREntrypointVisitor(t4, options) {
|
|
|
30394
30979
|
const stateMacroNames = /* @__PURE__ */ new Set(["$state"]);
|
|
30395
30980
|
const effectMacroNames = /* @__PURE__ */ new Set(["$effect"]);
|
|
30396
30981
|
const memoMacroNames = /* @__PURE__ */ new Set(["$memo", "createMemo"]);
|
|
30397
|
-
|
|
30982
|
+
path2.traverse({
|
|
30398
30983
|
ImportDeclaration(importPath) {
|
|
30399
30984
|
if (importPath.node.source.value !== "fict" && importPath.node.source.value !== "fict/slim")
|
|
30400
30985
|
return;
|
|
@@ -30414,7 +30999,7 @@ function createHIREntrypointVisitor(t4, options) {
|
|
|
30414
30999
|
}
|
|
30415
31000
|
}
|
|
30416
31001
|
});
|
|
30417
|
-
|
|
31002
|
+
path2.traverse({
|
|
30418
31003
|
JSXExpressionContainer(exprPath) {
|
|
30419
31004
|
const expr = exprPath.node.expression;
|
|
30420
31005
|
if (!t4.isCallExpression(expr)) return;
|
|
@@ -30459,7 +31044,7 @@ function createHIREntrypointVisitor(t4, options) {
|
|
|
30459
31044
|
const stateVars = /* @__PURE__ */ new Set();
|
|
30460
31045
|
const derivedVars = /* @__PURE__ */ new Set();
|
|
30461
31046
|
const destructuredAliases = /* @__PURE__ */ new Set();
|
|
30462
|
-
|
|
31047
|
+
path2.traverse({
|
|
30463
31048
|
VariableDeclarator(varPath) {
|
|
30464
31049
|
const init = varPath.node.init;
|
|
30465
31050
|
if (!init) return;
|
|
@@ -30708,7 +31293,7 @@ or extract the nested logic into a custom hook (useXxx).`
|
|
|
30708
31293
|
return usesState;
|
|
30709
31294
|
};
|
|
30710
31295
|
debugLog("alias", "state vars", Array.from(stateVars));
|
|
30711
|
-
|
|
31296
|
+
path2.traverse({
|
|
30712
31297
|
Function: {
|
|
30713
31298
|
enter() {
|
|
30714
31299
|
aliasStack.push(/* @__PURE__ */ new Set());
|
|
@@ -30766,7 +31351,7 @@ or extract the nested logic into a custom hook (useXxx).`
|
|
|
30766
31351
|
}
|
|
30767
31352
|
});
|
|
30768
31353
|
if (derivedVars.size > 0) {
|
|
30769
|
-
|
|
31354
|
+
path2.traverse({
|
|
30770
31355
|
AssignmentExpression(assignPath) {
|
|
30771
31356
|
const { left } = assignPath.node;
|
|
30772
31357
|
if (t4.isIdentifier(left) && derivedVars.has(left.name)) {
|
|
@@ -30787,7 +31372,7 @@ or extract the nested logic into a custom hook (useXxx).`
|
|
|
30787
31372
|
});
|
|
30788
31373
|
}
|
|
30789
31374
|
if (destructuredAliases.size > 0) {
|
|
30790
|
-
|
|
31375
|
+
path2.traverse({
|
|
30791
31376
|
AssignmentExpression(assignPath) {
|
|
30792
31377
|
const { left } = assignPath.node;
|
|
30793
31378
|
if (t4.isIdentifier(left) && destructuredAliases.has(left.name)) {
|
|
@@ -30815,10 +31400,11 @@ or extract the nested logic into a custom hook (useXxx).`
|
|
|
30815
31400
|
}
|
|
30816
31401
|
});
|
|
30817
31402
|
}
|
|
30818
|
-
|
|
30819
|
-
|
|
31403
|
+
const shouldRunWarnings = dev || hasErrorEscalation(options);
|
|
31404
|
+
if (shouldRunWarnings) {
|
|
31405
|
+
runWarningPass(path2, stateVars, derivedVars, warn, fileName, t4);
|
|
30820
31406
|
}
|
|
30821
|
-
const fileAst = t4.file(
|
|
31407
|
+
const fileAst = t4.file(path2.node);
|
|
30822
31408
|
const hir = buildHIR(
|
|
30823
31409
|
fileAst,
|
|
30824
31410
|
{
|
|
@@ -30833,19 +31419,20 @@ or extract the nested logic into a custom hook (useXxx).`
|
|
|
30833
31419
|
);
|
|
30834
31420
|
const optimized = optionsWithWarnings.optimize ? optimizeHIR(hir, {
|
|
30835
31421
|
memoMacroNames,
|
|
30836
|
-
inlineDerivedMemos: optionsWithWarnings.inlineDerivedMemos ?? true
|
|
31422
|
+
inlineDerivedMemos: optionsWithWarnings.inlineDerivedMemos ?? true,
|
|
31423
|
+
optimizeLevel: optionsWithWarnings.optimizeLevel ?? "safe"
|
|
30837
31424
|
}) : hir;
|
|
30838
31425
|
const lowered = lowerHIRWithRegions(optimized, t4, optionsWithWarnings, {
|
|
30839
31426
|
state: stateMacroNames,
|
|
30840
31427
|
effect: effectMacroNames,
|
|
30841
31428
|
memo: memoMacroNames
|
|
30842
31429
|
});
|
|
30843
|
-
|
|
30844
|
-
|
|
31430
|
+
path2.node.body = lowered.program.body;
|
|
31431
|
+
path2.node.directives = lowered.program.directives;
|
|
30845
31432
|
if (!process.env.FICT_SKIP_SCOPE_CRAWL) {
|
|
30846
|
-
|
|
31433
|
+
path2.scope.crawl();
|
|
30847
31434
|
}
|
|
30848
|
-
stripMacroImports(
|
|
31435
|
+
stripMacroImports(path2, t4);
|
|
30849
31436
|
}
|
|
30850
31437
|
}
|
|
30851
31438
|
};
|
|
@@ -30858,6 +31445,7 @@ var createFictPlugin = (0, import_helper_plugin_utils.declare)(
|
|
|
30858
31445
|
...options,
|
|
30859
31446
|
fineGrainedDom: options.fineGrainedDom ?? true,
|
|
30860
31447
|
optimize: options.optimize ?? true,
|
|
31448
|
+
optimizeLevel: options.optimizeLevel ?? "safe",
|
|
30861
31449
|
inlineDerivedMemos: options.inlineDerivedMemos ?? true,
|
|
30862
31450
|
dev: options.dev ?? (process.env.NODE_ENV !== "production" && process.env.NODE_ENV !== "test")
|
|
30863
31451
|
};
|
|
@@ -30870,5 +31458,8 @@ var createFictPlugin = (0, import_helper_plugin_utils.declare)(
|
|
|
30870
31458
|
var index_default = createFictPlugin;
|
|
30871
31459
|
// Annotate the CommonJS export names for ESM import in node:
|
|
30872
31460
|
0 && (module.exports = {
|
|
30873
|
-
|
|
31461
|
+
clearModuleMetadata,
|
|
31462
|
+
createFictPlugin,
|
|
31463
|
+
resolveModuleMetadata,
|
|
31464
|
+
setModuleMetadata
|
|
30874
31465
|
});
|